1
1
#include " ap3_gpio.h"
2
2
#include " variant.h"
3
3
4
- typedef struct {
5
- voidFuncPtrArgs callback; // the callback function
6
- void * arg; // argument
7
- uint8_t mode; // Arduino interrupt mode
8
- uint8_t pad; // which apollo3 pad
9
- }ap3_gpio_isr_entry_t ;
10
- ap3_gpio_isr_entry_t gpio_isr_entries[AP3_GPIO_MAX_PADS] = {NULL };
11
- uint8_t gpio_num_isr = 0 ;
4
+ typedef struct
5
+ {
6
+ voidFuncPtrArgs callback; // the callback function
7
+ void *arg; // argument
8
+ uint8_t mode; // Arduino interrupt mode
9
+ uint8_t pad; // which apollo3 pad
10
+ } ap3_gpio_isr_entry_t ;
11
+ ap3_gpio_isr_entry_t gpio_isr_entries[AP3_GPIO_MAX_PADS] = {NULL };
12
+ uint8_t gpio_num_isr = 0 ;
12
13
13
14
// *****************************************************************************
14
15
// Local defines. Copied from am_hal_gpio.c
@@ -26,8 +27,6 @@ uint8_t gpio_num_isr = 0;
26
27
#define GPIOCFG_FLD_OUTCFG_S 1
27
28
#define GPIOCFG_FLD_INCFG_S 0
28
29
29
-
30
-
31
30
ap3_gpio_pad_t ap3_gpio_pin2pad (ap3_gpio_pin_t pin)
32
31
{
33
32
return ap3_variant_pinmap[pin];
@@ -134,21 +133,32 @@ extern "C" void am_gpio_isr(void)
134
133
uint64_t gpio_int_mask = 0x00 ;
135
134
am_hal_gpio_interrupt_status_get (true , &gpio_int_mask);
136
135
137
- for (uint8_t indi = 0 ; indi < gpio_num_isr; indi++){
138
- if ( gpio_isr_entries[indi].callback != NULL ){
139
- if ( gpio_int_mask & AM_HAL_GPIO_BIT (gpio_isr_entries[indi].pad ) ){
136
+ for (uint8_t indi = 0 ; indi < gpio_num_isr; indi++)
137
+ {
138
+ if (gpio_isr_entries[indi].callback != NULL )
139
+ {
140
+ if (gpio_int_mask & AM_HAL_GPIO_BIT (gpio_isr_entries[indi].pad ))
141
+ {
140
142
gpio_isr_entries[indi].callback (gpio_isr_entries[indi].arg );
141
143
}
142
- if ( !((gpio_isr_entries[indi].mode == LOW) || (gpio_isr_entries[indi].mode == HIGH)) ){ // if not a HIGH or LOW interrupt then clear the flag
144
+ if (!((gpio_isr_entries[indi].mode == LOW) || (gpio_isr_entries[indi].mode == HIGH)))
145
+ { // if not a HIGH or LOW interrupt then clear the flag
143
146
am_hal_gpio_interrupt_clear (AM_HAL_GPIO_BIT (gpio_isr_entries[indi].pad ));
144
- }else { // In the case of a HIGH or LOW mode interrupt we need to manually check for the end state
145
- uint8_t val = digitalRead ( gpio_isr_entries[indi].pad );
146
- if ( gpio_isr_entries[indi].mode == LOW ){
147
- if ( val ){
147
+ }
148
+ else
149
+ { // In the case of a HIGH or LOW mode interrupt we need to manually check for the end state
150
+ uint8_t val = digitalRead (gpio_isr_entries[indi].pad );
151
+ if (gpio_isr_entries[indi].mode == LOW)
152
+ {
153
+ if (val)
154
+ {
148
155
am_hal_gpio_interrupt_clear (AM_HAL_GPIO_BIT (gpio_isr_entries[indi].pad ));
149
156
}
150
- }else {
151
- if ( !val ){
157
+ }
158
+ else
159
+ {
160
+ if (!val)
161
+ {
152
162
am_hal_gpio_interrupt_clear (AM_HAL_GPIO_BIT (gpio_isr_entries[indi].pad ));
153
163
}
154
164
}
@@ -157,15 +167,21 @@ extern "C" void am_gpio_isr(void)
157
167
}
158
168
}
159
169
160
- void attachInterruptArg (uint8_t pin, voidFuncPtrArgs callbackArgs, void * arg, int mode)
170
+ void attachInterruptArg (uint8_t pin, voidFuncPtrArgs callbackArgs, void *arg, int mode)
161
171
{
162
172
ap3_gpio_pad_t pad = ap3_gpio_pin2pad (pin);
163
- if ( pad == AP3_GPIO_PAD_UNUSED ){ return ; }
173
+ if (pad == AP3_GPIO_PAD_UNUSED)
174
+ {
175
+ return ;
176
+ }
164
177
165
- if ( gpio_num_isr < AP3_GPIO_MAX_PADS ){
178
+ if (gpio_num_isr < AP3_GPIO_MAX_PADS)
179
+ {
166
180
uint8_t indi = 0 ;
167
- for (indi = 0 ; indi < gpio_num_isr; indi++){
168
- if (gpio_isr_entries[indi].pad == pad){
181
+ for (indi = 0 ; indi < gpio_num_isr; indi++)
182
+ {
183
+ if (gpio_isr_entries[indi].pad == pad)
184
+ {
169
185
break ;
170
186
}
171
187
}
@@ -177,88 +193,83 @@ void attachInterruptArg(uint8_t pin, voidFuncPtrArgs callbackArgs, void * arg, i
177
193
178
194
// enable interrupts for the pad in question (Arduino does this by default when attachInterrupt is called)
179
195
uint8_t eIntDir = 0x00 ;
180
- if (( mode == FALLING ) || ( mode == LOW )){
196
+ if ((mode == FALLING) || (mode == LOW))
197
+ {
181
198
eIntDir = AM_HAL_GPIO_PIN_INTDIR_HI2LO;
182
- }else if (( mode == RISING ) || ( mode == HIGH )){
199
+ }
200
+ else if ((mode == RISING) || (mode == HIGH))
201
+ {
183
202
eIntDir = AM_HAL_GPIO_PIN_INTDIR_LO2HI;
184
- }else {
185
- eIntDir = AM_HAL_GPIO_PIN_INTDIR_BOTH;
186
203
}
187
- ap3_gpio_enable_interrupts ( pad, eIntDir);
204
+ else
205
+ {
206
+ eIntDir = AM_HAL_GPIO_PIN_INTDIR_BOTH;
207
+ }
208
+ ap3_gpio_enable_interrupts (pad, eIntDir);
188
209
189
- // clear the flag and enable the interrupt in the NVIC
210
+ // clear the flag and enable the interrupt in the NVIC
190
211
am_hal_gpio_interrupt_clear (AM_HAL_GPIO_BIT (pad));
191
212
am_hal_gpio_interrupt_enable (AM_HAL_GPIO_BIT (pad));
192
213
NVIC_EnableIRQ (GPIO_IRQn);
193
214
194
- if ( indi == gpio_num_isr ){
215
+ if (indi == gpio_num_isr)
216
+ {
195
217
gpio_num_isr++;
196
218
}
197
219
}
198
220
}
199
221
200
222
void attachInterrupt (uint8_t pin, voidFuncPtr callback, int mode)
201
223
{
202
- attachInterruptArg ( pin, (voidFuncPtrArgs)callback, NULL , mode );
224
+ attachInterruptArg (pin, (voidFuncPtrArgs)callback, NULL , mode);
203
225
}
204
226
205
227
extern void detachInterrupt (uint8_t pin)
206
228
{
207
229
ap3_gpio_pad_t pad = ap3_gpio_pin2pad (pin);
208
- if ( pad == AP3_GPIO_PAD_UNUSED ){ return ; }
230
+ if (pad == AP3_GPIO_PAD_UNUSED)
231
+ {
232
+ return ;
233
+ }
209
234
210
235
uint8_t indi = 0 ;
211
236
212
237
// Look for an entry that matches the pad
213
- for (indi = 0 ; indi < gpio_num_isr; indi++){
214
- if (gpio_isr_entries[indi].pad == pad){
238
+ for (indi = 0 ; indi < gpio_num_isr; indi++)
239
+ {
240
+ if (gpio_isr_entries[indi].pad == pad)
241
+ {
215
242
break ;
216
243
}
217
244
}
218
245
219
246
// return if it was not found (prevent changes to the isr entry list)
220
- if ( indi == gpio_num_isr ){
247
+ if (indi == gpio_num_isr)
248
+ {
221
249
return ;
222
250
}
223
251
224
252
// disable the interrupt in the NVIC
225
253
am_hal_gpio_interrupt_disable (AM_HAL_GPIO_BIT (pad));
226
254
am_hal_gpio_interrupt_clear (AM_HAL_GPIO_BIT (pad));
227
255
228
- // disable interrupts for the given pad without blasting the configuration
229
- ap3_gpio_enable_interrupts ( pad, AM_HAL_GPIO_PIN_INTDIR_NONE);
256
+ // disable interrupts for the given pad without blasting the configuration
257
+ ap3_gpio_enable_interrupts (pad, AM_HAL_GPIO_PIN_INTDIR_NONE);
230
258
231
259
// Shift down the remaining interrupt entries
232
- for (indi; indi < gpio_num_isr-1 ; indi++){
233
- gpio_isr_entries[indi] = gpio_isr_entries[indi+1 ];
260
+ for (indi; indi < gpio_num_isr - 1 ; indi++)
261
+ {
262
+ gpio_isr_entries[indi] = gpio_isr_entries[indi + 1 ];
234
263
}
235
-
264
+
236
265
// Clear out the last entry
237
266
gpio_isr_entries[gpio_num_isr].pad = 0 ;
238
267
gpio_isr_entries[gpio_num_isr].callback = NULL ;
239
268
gpio_isr_entries[gpio_num_isr].mode = LOW;
240
269
gpio_isr_entries[gpio_num_isr].arg = NULL ;
241
-
242
270
}
243
271
244
-
245
-
246
-
247
-
248
-
249
-
250
-
251
-
252
-
253
-
254
-
255
-
256
-
257
-
258
-
259
-
260
-
261
- uint32_t ap3_gpio_enable_interrupts (uint32_t ui32Pin, uint32_t eIntDir )
272
+ uint32_t ap3_gpio_enable_interrupts (uint32_t ui32Pin, uint32_t eIntDir)
262
273
{
263
274
uint32_t ui32Padreg, ui32AltPadCfg, ui32GPCfg;
264
275
uint32_t ui32Funcsel, ui32PowerSw;
@@ -276,7 +287,6 @@ uint32_t ap3_gpio_enable_interrupts(uint32_t ui32Pin, uint32_t eIntDir )
276
287
//
277
288
ui32GPCfg = ui32Padreg = ui32AltPadCfg = 0 ;
278
289
279
-
280
290
//
281
291
// Map the requested interrupt direction settings into the Apollo3
282
292
// GPIOCFG register field, which is a 4-bit field:
@@ -286,7 +296,6 @@ uint32_t ap3_gpio_enable_interrupts(uint32_t ui32Pin, uint32_t eIntDir )
286
296
//
287
297
ui32GPCfg |= (((eIntDir >> 0 ) & 0x1 ) << GPIOCFG_FLD_INTD_S) | (((eIntDir >> 1 ) & 0x1 ) << GPIOCFG_FLD_INCFG_S);
288
298
289
-
290
299
//
291
300
// At this point, the configuration variable, ui32GpioCfg
292
301
// value is set (at bit position 0) and ready to write
@@ -326,4 +335,65 @@ uint32_t ap3_gpio_enable_interrupts(uint32_t ui32Pin, uint32_t eIntDir )
326
335
327
336
return AM_HAL_STATUS_SUCCESS;
328
337
329
- } // am_hal_gpio_pinconfig()
338
+ } // am_hal_gpio_pinconfig()
339
+
340
+ /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
341
+ or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
342
+ to 3 minutes in length, but must be called at least a few dozen microseconds
343
+ before the start of the pulse.
344
+
345
+ Original Arduino function could operate in noInterrupt() context. This
346
+ function cannot.
347
+ */
348
+ unsigned long pulseIn (uint8_t pinNumber, uint8_t state, unsigned long timeout)
349
+ {
350
+ return (pulseInLong (pinNumber, state, timeout));
351
+ }
352
+
353
+ /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
354
+ or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
355
+ to 3 minutes in length, but must be called at least a few dozen microseconds
356
+ before the start of the pulse.
357
+
358
+ ATTENTION: This function relies on micros() so cannot be used in noInterrupt() context
359
+ */
360
+ unsigned long pulseInLong (uint8_t pinNumber, uint8_t state, unsigned long timeout)
361
+ {
362
+ uint8_t padNumber = ap3_gpio_pin2pad (pinNumber);
363
+
364
+ if (timeout > 3 * 60 * 1000000L )
365
+ timeout = 3 * 60 * 1000000L ; // Limit timeout to 3 minutes
366
+
367
+ // Enable fast GPIO for this pad
368
+ am_hal_gpio_fastgpio_disable (padNumber);
369
+ am_hal_gpio_fastgpio_clr (padNumber);
370
+ am_hal_gpio_fast_pinconfig ((uint64_t )0x1 << padNumber, g_AM_HAL_GPIO_OUTPUT_WITH_READ, 0 );
371
+
372
+ uint32_t startMicros = micros ();
373
+
374
+ while (am_hal_gpio_fastgpio_read (padNumber) == state) // Wait for previous pulse to end
375
+ {
376
+ if (micros () - startMicros > timeout)
377
+ return (0 ); // Pulse did not end
378
+ }
379
+
380
+ while (am_hal_gpio_fastgpio_read (padNumber) != state) // Wait for pin to change state
381
+ {
382
+ if (micros () - startMicros > timeout)
383
+ return (0 ); // Pulse did not start
384
+ }
385
+
386
+ startMicros = micros (); // Restart time
387
+
388
+ while (am_hal_gpio_fastgpio_read (padNumber) == state) // Wait for pin to exit sought state
389
+ {
390
+ if (micros () - startMicros > timeout)
391
+ return (0 ); // Pulse did not end
392
+ }
393
+
394
+ uint32_t stopMicros = micros ();
395
+
396
+ am_hal_gpio_fastgpio_disable (padNumber);
397
+
398
+ return (stopMicros - startMicros);
399
+ }
0 commit comments