Contiki 3.x
gpio.c
1 
2 #include "gpio.h"
3 #include "contiki.h"
4 #include "nvic.h"
5 #include "sys/energest.h"
6 #include <string.h>
7 
8 static void (*PortA_Callbacks[32])(void);
9 static void (*PortD_Callbacks[32])(void);
10 
11 
12 void
14 {
15  memset(PortA_Callbacks, 0, sizeof(PortA_Callbacks));
16  memset(PortD_Callbacks, 0, sizeof(PortD_Callbacks));
17  NVIC_CLEAR_PENDING(IRQ_PORTA);
18  NVIC_ENABLE_INT(IRQ_PORTA);
19  NVIC_Set_Priority(IRQ_PORTA, 1);
20 
21  NVIC_CLEAR_PENDING(IRQ_PORTD);
22  NVIC_ENABLE_INT(IRQ_PORTD);
23  NVIC_Set_Priority(IRQ_PORTD, 1);
24 }
25 
26 void
27 port_register_callback(void* f, PORT_Type *port, uint8_t pin)
28 {
29  if(port == PORTA) {
30  PortA_Callbacks[pin] = f;
31  } else if(port == PORTD) {
32  PortD_Callbacks[pin] = f;
33  } else {
34  printf("ERROR: Attempt to register interrupt on un-supported port.\n\r");
35  }
36 }
37 
38 /*---------------------------------------------------------------------------*/
39 void
40 port_conf_pin(PORT_Type *Port, uint8_t Pin, uint32_t PCR)
41 {
42  Port->PCR[Pin] = PCR;
43 }
44 
45 uint32_t
46 port_pin_to_mask(uint8_t pin)
47 {
48  return (1 << pin);
49 }
50 
51 void port_conf_pin_int_disable(PORT_Type *Port, uint8_t Pin)
52 {
53  Port->PCR[Pin] = Port->PCR[Pin] & ~(PORT_PCR_IRQC_MASK); /* Clear interrupt trigger. */
54  Port->PCR[Pin] |= PORT_PCR_ISF_MASK; /* Clear ISF. */
55 }
56 
57 void
58 port_conf_pin_int_zero(PORT_Type *Port, uint8_t Pin)
59 {
60  Port->PCR[Pin] |= PORT_PCR_ISF_MASK; /* Clear ISF. */
61  Port->PCR[Pin] = Port->PCR[Pin] & ~(PORT_PCR_IRQC_MASK); /* Clear interrupt trigger. */
62  Port->PCR[Pin] |= PORT_PCR_IRQC_ZERO; /* Set Interrupt trigger. */
63 }
64 
65 void
66 port_conf_pin_int_rise(PORT_Type *Port, uint8_t Pin)
67 {
68  Port->PCR[Pin] |= PORT_PCR_ISF_MASK; /* Clear ISF. */
69  Port->PCR[Pin] = Port->PCR[Pin] & ~(PORT_PCR_IRQC_MASK); /* Clear interrupt trigger. */
70  Port->PCR[Pin] |= PORT_PCR_IRQC_RISING; /* Set Interrupt trigger. */
71 }
72 
73 void
74 port_conf_pin_int_fall(PORT_Type *Port, uint8_t Pin)
75 {
76  Port->PCR[Pin] |= PORT_PCR_ISF_MASK; /* Clear ISF. */
77  Port->PCR[Pin] = Port->PCR[Pin] & ~(PORT_PCR_IRQC_MASK); /* Clear interrupt trigger. */
78  Port->PCR[Pin] |= PORT_PCR_IRQC_FALLING; /* Set Interrupt trigger. */
79 }
80 
81 void
82 port_conf_pin_int_edge(PORT_Type *Port, uint8_t Pin)
83 {
84  Port->PCR[Pin] |= PORT_PCR_ISF_MASK; /* Clear ISF. */
85  Port->PCR[Pin] = Port->PCR[Pin] & ~(PORT_PCR_IRQC_MASK); /* Clear interrupt trigger. */
86  Port->PCR[Pin] |= PORT_PCR_IRQC_EDGE; /* Set Interrupt trigger. */
87 }
88 
89 void
90 port_conf_pin_int_one(PORT_Type *Port, uint8_t Pin)
91 {
92  Port->PCR[Pin] |= PORT_PCR_ISF_MASK; /* Clear ISF. */
93  Port->PCR[Pin] = Port->PCR[Pin] & ~(PORT_PCR_IRQC_MASK); /* Clear interrupt trigger. */
94  Port->PCR[Pin] |= PORT_PCR_IRQC_ONE; /* Set Interrupt trigger. */
95 }
96 
97 uint32_t
99 {
100  return Port->ISFR;
101 }
102 
103 void
104 port_clr_isf(PORT_Type *Port, uint32_t Pin_Mask)
105 {
106  Port->ISFR = Pin_Mask;
107 }
108 
109 bool
110 port_read_pin_isf(PORT_Type *Port, uint8_t Pin)
111 {
112  if(Port->PCR[Pin] & PORT_PCR_ISF_MASK) {
113  return 1;
114  } else {
115  return 0;
116  }
117 }
118 
119 void
120 port_pin_clr_isf(PORT_Type *Port, uint8_t Pin)
121 {
122  Port->PCR[Pin] |= PORT_PCR_ISF_MASK;
123 }
124 
125 
126 /*---------------------------------------------------------------------------*/
127 
128 void
129 gpio_set_input(GPIO_Type *Port, uint32_t Pin_Mask)
130 {
131  Port->PDDR &= ~(Pin_Mask);
132 }
133 
134 void
135 gpio_set_output(GPIO_Type *Port, uint32_t Pin_Mask)
136 {
137  Port->PDDR |= Pin_Mask;
138 }
139 
140 void
141 gpio_set_pin(GPIO_Type *Port, uint32_t Pin_Mask)
142 {
143  Port->PSOR |= Pin_Mask;
144 }
145 
146 void
147 gpio_clr_pin(GPIO_Type *Port, uint32_t Pin_Mask)
148 {
149  Port->PCOR |= Pin_Mask;
150 }
151 
152 void
153 gpio_tgl_pin(GPIO_Type *Port, uint32_t Pin_Mask)
154 {
155  Port->PTOR |= Pin_Mask;
156 }
157 
158 uint32_t
159 gpio_read_pin(GPIO_Type *Port, uint32_t Pin_Mask)
160 {
161  return (((Port->PDOR & Port->PDDR) | (Port->PDIR & ~(Port->PDDR))) & Pin_Mask);
162 }
163 
164 /*---------------------------------------------------------------------------*/
165 
166 /** \brief Port A Interrupt Handler.
167  */
168 void PORTA_IRQHandler(void)
169 {
170  uint32_t isf;
171  uint8_t i;
172 
173  ENERGEST_ON(ENERGEST_TYPE_IRQ);
174 
175  isf = port_read_isf(PORTA);
176 
177  for(i = 0; i < 32; i++) {
178  if(isf & (1 << i)) { /* Check if pin i has triggered. */
179  if(PortA_Callbacks[i] != NULL) { /* Check if we have a callback registered for pin i. */
180  (*PortA_Callbacks[i])(); /* Call the callback. */
181  port_pin_clr_isf(PORTA, i); /* Clear the interrupt status flags. */
182  }
183  }
184  }
185 
186  NVIC_CLEAR_PENDING(IRQ_PORTA);
187 
188  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
189 }
190 
191 /** \brief Port D Interrupt Handler.
192  */
193 void PORTD_IRQHandler(void)
194 {
195  uint32_t isf;
196  uint8_t i;
197 
198  ENERGEST_ON(ENERGEST_TYPE_IRQ);
199 
200  isf = port_read_isf(PORTA);
201 
202  for(i = 0; i < 32; i++) {
203  if(isf & (1 << i)) { /* Check if pin i has triggered. */
204  if(PortD_Callbacks[i] != NULL) { /* Check if we have a callback registered for pin i. */
205  (*PortD_Callbacks[i])(); /* Call the callback. */
206  port_pin_clr_isf(PORTD, i); /* Clear the interrupt status flags. */
207  }
208  }
209  }
210 
211  NVIC_CLEAR_PENDING(IRQ_PORTD);
212 
213  ENERGEST_OFF(ENERGEST_TYPE_IRQ);
214 }
__O uint32_t PSOR
Port Set Output Register, offset: 0x4.
Definition: MKL25Z4.h:1786
void gpio_init()
Initialise the GPIO module.
Definition: gpio.c:13
__O uint32_t PCOR
Port Clear Output Register, offset: 0x8.
Definition: MKL25Z4.h:1787
__IO uint32_t PDDR
Port Data Direction Register, offset: 0x14.
Definition: MKL25Z4.h:1790
void port_conf_pin_int_rise(PORT_Type *Port, uint8_t Pin)
Configure rising-edge interrupt on the specified Pin of the port with PORTx_BASE_PTR.
Definition: gpio.c:66
__IO uint32_t PDOR
Port Data Output Register, offset: 0x0.
Definition: MKL25Z4.h:1785
void port_conf_pin_int_edge(PORT_Type *Port, uint8_t Pin)
Configure either-edge interrupt on the specified Pin of the port with PORTx_BASE_PTR.
Definition: gpio.c:82
__I uint32_t PDIR
Port Data Input Register, offset: 0x10.
Definition: MKL25Z4.h:1789
void NVIC_Set_Priority(uint32_t IRQ, uint8_t priority)
Set the priority of the specified interrupt in the ARM NVIC.
Definition: nvic.c:142
void gpio_set_output(GPIO_Type *Port, uint32_t Pin_Mask)
Set pins with Pin_Mask of port with GPIOn_BASE_PTR to output.
Definition: gpio.c:135
uint32_t gpio_read_pin(GPIO_Type *Port, uint32_t Pin_Mask)
Read pins with Pin_Mask of port with GPIOn_BASE_PTR.
Definition: gpio.c:159
Header file for the energy estimation mechanism
void NVIC_CLEAR_PENDING(uint32_t IRQ)
Clear a pending interrupt for the specified interrupt in the ARM NVIC.
Definition: nvic.c:124
GPIO - Register Layout Typedef.
Definition: MKL25Z4.h:1784
__IO uint32_t ISFR
Interrupt Status Flag Register, offset: 0xA0.
Definition: MKL25Z4.h:4335
bool port_read_pin_isf(PORT_Type *Port, uint8_t Pin)
Return the Interrupt Status Flags of Pin in port with PORTx_BASE_PTR.
Definition: gpio.c:110
void port_conf_pin_int_one(PORT_Type *Port, uint8_t Pin)
Configure one-level interrupt on the specified Pin of the port with PORTx_BASE_PTR.
Definition: gpio.c:90
void port_conf_pin_int_zero(PORT_Type *Port, uint8_t Pin)
Configure zero-level interrupt on the specified Pin of the port with PORTx_BASE_PTR.
Definition: gpio.c:58
void port_clr_isf(PORT_Type *Port, uint32_t Pin_Mask)
Clear the Interrupt Status Flag of port with PORTx_BASE_PTR.
Definition: gpio.c:104
#define PORTD
Peripheral PORTD base pointer.
Definition: MKL25Z4.h:4450
__IO uint32_t PCR[32]
Pin Control Register n, array offset: 0x0, array step: 0x4.
Definition: MKL25Z4.h:4331
void port_conf_pin_int_fall(PORT_Type *Port, uint8_t Pin)
Configure falling-edge interrupt on the specified Pin of the port with PORTx_BASE_PTR.
Definition: gpio.c:74
#define PORTA
Peripheral PORTA base pointer.
Definition: MKL25Z4.h:4435
#define NULL
The null pointer.
void port_register_callback(void *f, PORT_Type *port, uint8_t pin)
Register Port interrupt callback function.
Definition: gpio.c:27
uint32_t port_read_isf(PORT_Type *Port)
Return the Interrupt Status Flags of port with PORTx_BASE_PTR.
Definition: gpio.c:98
void gpio_clr_pin(GPIO_Type *Port, uint32_t Pin_Mask)
Clear pins with Pin_Mask of port with GPIOn_BASE_PTR low.
Definition: gpio.c:147
void port_conf_pin(PORT_Type *Port, uint8_t Pin, uint32_t PCR)
Configure the specified Pin of the port with PORTx_BASE_PTR with PCR.
Definition: gpio.c:40
PORT - Register Layout Typedef.
Definition: MKL25Z4.h:4330
void gpio_tgl_pin(GPIO_Type *Port, uint32_t Pin_Mask)
Toggle pins with Pin_Mask of port with GPIOn_BASE_PTR low.
Definition: gpio.c:153
__O uint32_t PTOR
Port Toggle Output Register, offset: 0xC.
Definition: MKL25Z4.h:1788
void gpio_set_input(GPIO_Type *Port, uint32_t Pin_Mask)
Set pins with Pin_Mask of port with GPIOn_BASE_PTR to input.
Definition: gpio.c:129
void port_conf_pin_int_disable(PORT_Type *Port, uint8_t Pin)
Disable interrupt on the specified Pin of the port with PORTx_BASE_PTR.
Definition: gpio.c:51
void NVIC_ENABLE_INT(uint32_t IRQ)
Enable specified interrupt in the ARM NVIC.
Definition: nvic.c:80
void port_pin_clr_isf(PORT_Type *Port, uint8_t Pin)
Clear the Interrupt Status Flag of Pin in port with PORTx_BASE_PTR.
Definition: gpio.c:120
void gpio_set_pin(GPIO_Type *Port, uint32_t Pin_Mask)
Set pins with Pin_Mask of port with GPIOn_BASE_PTR high.
Definition: gpio.c:141
uint32_t port_pin_to_mask(uint8_t pin)
Convert a pin number (0 to 31) to a pin mask.
Definition: gpio.c:46