23
23
#include "pinmap.h"
24
24
#include "PeripheralPins.h"
25
25
#include "nu_bitutil.h"
26
+ #include "mbed_assert.h"
26
27
27
28
#define NU_MAX_PIN_PER_PORT 16
28
29
@@ -76,14 +77,15 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
76
77
if (pin == NC ) {
77
78
return -1 ;
78
79
}
79
-
80
+
80
81
uint32_t pin_index = NU_PINNAME_TO_PIN (pin );
81
82
uint32_t port_index = NU_PINNAME_TO_PORT (pin );
82
83
if (pin_index >= NU_MAX_PIN_PER_PORT || port_index >= NU_MAX_PORT ) {
83
84
return -1 ;
84
85
}
85
-
86
+
86
87
obj -> pin = pin ;
88
+ obj -> irq_types = 0 ;
87
89
obj -> irq_handler = (uint32_t ) handler ;
88
90
obj -> irq_id = id ;
89
91
@@ -101,16 +103,16 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
101
103
GPIO_ENABLE_DEBOUNCE (gpio_base , 1 << pin_index );
102
104
#else
103
105
// Enable de-bounce if the pin is in the de-bounce enable list
104
-
106
+
105
107
// De-bounce defaults to disabled.
106
108
GPIO_DISABLE_DEBOUNCE (gpio_base , 1 << pin_index );
107
-
109
+
108
110
PinName * debounce_pos = gpio_irq_debounce_arr ;
109
111
PinName * debounce_end = gpio_irq_debounce_arr + sizeof (gpio_irq_debounce_arr ) / sizeof (gpio_irq_debounce_arr [0 ]);
110
112
for (; debounce_pos != debounce_end && * debounce_pos != NC ; debounce_pos ++ ) {
111
113
uint32_t pin_index_debunce = NU_PINNAME_TO_PIN (* debounce_pos );
112
114
uint32_t port_index_debounce = NU_PINNAME_TO_PORT (* debounce_pos );
113
-
115
+
114
116
if (pin_index == pin_index_debunce &&
115
117
port_index == port_index_debounce ) {
116
118
// Configure de-bounce clock source and sampling cycle time
@@ -121,14 +123,14 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32
121
123
}
122
124
#endif
123
125
}
124
-
126
+
125
127
struct nu_gpio_irq_var * var = gpio_irq_var_arr + port_index ;
126
128
127
129
var -> obj_arr [pin_index ] = obj ;
128
-
130
+
129
131
// NOTE: InterruptIn requires IRQ enabled by default.
130
132
gpio_irq_enable (obj );
131
-
133
+
132
134
return 0 ;
133
135
}
134
136
@@ -137,10 +139,10 @@ void gpio_irq_free(gpio_irq_t *obj)
137
139
uint32_t pin_index = NU_PINNAME_TO_PIN (obj -> pin );
138
140
uint32_t port_index = NU_PINNAME_TO_PORT (obj -> pin );
139
141
struct nu_gpio_irq_var * var = gpio_irq_var_arr + port_index ;
140
-
142
+
141
143
NVIC_DisableIRQ (var -> irq_n );
142
144
NU_PORT_BASE (port_index )-> INTEN = 0 ;
143
-
145
+
144
146
MBED_ASSERT (pin_index < NU_MAX_PIN_PER_PORT );
145
147
var -> obj_arr [pin_index ] = NULL ;
146
148
}
@@ -150,34 +152,47 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
150
152
uint32_t pin_index = NU_PINNAME_TO_PIN (obj -> pin );
151
153
uint32_t port_index = NU_PINNAME_TO_PORT (obj -> pin );
152
154
GPIO_T * gpio_base = NU_PORT_BASE (port_index );
153
-
155
+
156
+ /* We assume BSP has such coding so that we can easily add/remove either irq type. */
157
+ MBED_STATIC_ASSERT (GPIO_INT_BOTH_EDGE == (GPIO_INT_RISING | GPIO_INT_FALLING ),
158
+ "GPIO_INT_BOTH_EDGE must be bitwise OR of GPIO_INT_RISING and GPIO_INT_FALLING" );
159
+ uint32_t irq_type ;
154
160
switch (event ) {
155
161
case IRQ_RISE :
156
- if (enable ) {
157
- GPIO_EnableInt (gpio_base , pin_index , GPIO_INT_RISING );
158
- }
159
- else {
160
- gpio_base -> INTEN &= ~(GPIO_INT_RISING << pin_index );
161
- }
162
+ irq_type = GPIO_INT_RISING ;
162
163
break ;
163
-
164
+
164
165
case IRQ_FALL :
165
- if (enable ) {
166
- GPIO_EnableInt (gpio_base , pin_index , GPIO_INT_FALLING );
167
- }
168
- else {
169
- gpio_base -> INTEN &= ~(GPIO_INT_FALLING << pin_index );
170
- }
166
+ irq_type = GPIO_INT_FALLING ;
171
167
break ;
168
+
169
+ default :
170
+ irq_type = 0 ;
171
+ }
172
+
173
+ /* We can handle invalid/null irq type. */
174
+ if (enable ) {
175
+ obj -> irq_types |= irq_type ;
176
+ } else {
177
+ obj -> irq_types &= ~irq_type ;
172
178
}
179
+
180
+ /* Update irq types:
181
+ *
182
+ * Implementations of GPIO_EnableInt(...) are inconsistent: disable or not irq type not enabled.
183
+ * For consistency, disable GPIO_INT_BOTH_EDGE and then enable OR'ed irq types, GPIO_INT_RISING,
184
+ * GPIO_INT_FALLING, or both.
185
+ */
186
+ GPIO_DisableInt (gpio_base , pin_index );
187
+ GPIO_EnableInt (gpio_base , pin_index , obj -> irq_types );
173
188
}
174
189
175
190
void gpio_irq_enable (gpio_irq_t * obj )
176
191
{
177
192
//uint32_t pin_index = NU_PINNAME_TO_PIN(obj->pin);
178
193
uint32_t port_index = NU_PINNAME_TO_PORT (obj -> pin );
179
194
struct nu_gpio_irq_var * var = gpio_irq_var_arr + port_index ;
180
-
195
+
181
196
NVIC_SetVector (var -> irq_n , (uint32_t ) var -> vec );
182
197
NVIC_EnableIRQ (var -> irq_n );
183
198
}
@@ -187,7 +202,7 @@ void gpio_irq_disable(gpio_irq_t *obj)
187
202
//uint32_t pin_index = NU_PINNAME_TO_PIN(obj->pin);
188
203
uint32_t port_index = NU_PINNAME_TO_PORT (obj -> pin );
189
204
struct nu_gpio_irq_var * var = gpio_irq_var_arr + port_index ;
190
-
205
+
191
206
NVIC_DisableIRQ (var -> irq_n );
192
207
}
193
208
@@ -220,7 +235,7 @@ static void gpio_irq(struct nu_gpio_irq_var *var)
220
235
{
221
236
uint32_t port_index = var -> irq_n - GPA_IRQn ;
222
237
GPIO_T * gpio_base = NU_PORT_BASE (port_index );
223
-
238
+
224
239
uint32_t intsrc = gpio_base -> INTSRC ;
225
240
uint32_t inten = gpio_base -> INTEN ;
226
241
while (intsrc ) {
@@ -233,15 +248,15 @@ static void gpio_irq(struct nu_gpio_irq_var *var)
233
248
}
234
249
}
235
250
}
236
-
251
+
237
252
if (inten & (GPIO_INT_FALLING << pin_index )) {
238
253
if (! GPIO_PIN_DATA (port_index , pin_index )) {
239
254
if (obj -> irq_handler ) {
240
255
((gpio_irq_handler ) obj -> irq_handler )(obj -> irq_id , IRQ_FALL );
241
256
}
242
257
}
243
258
}
244
-
259
+
245
260
intsrc &= ~(1 << pin_index );
246
261
}
247
262
// Clear all interrupt flags
0 commit comments