11#include " ap3_gpio.h"
22#include " variant.h"
33
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 ;
1213
1314// *****************************************************************************
1415// Local defines. Copied from am_hal_gpio.c
@@ -26,8 +27,6 @@ uint8_t gpio_num_isr = 0;
2627#define GPIOCFG_FLD_OUTCFG_S 1
2728#define GPIOCFG_FLD_INCFG_S 0
2829
29-
30-
3130ap3_gpio_pad_t ap3_gpio_pin2pad (ap3_gpio_pin_t pin)
3231{
3332 return ap3_variant_pinmap[pin];
@@ -134,21 +133,32 @@ extern "C" void am_gpio_isr(void)
134133 uint64_t gpio_int_mask = 0x00 ;
135134 am_hal_gpio_interrupt_status_get (true , &gpio_int_mask);
136135
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+ {
140142 gpio_isr_entries[indi].callback (gpio_isr_entries[indi].arg );
141143 }
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
143146 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+ {
148155 am_hal_gpio_interrupt_clear (AM_HAL_GPIO_BIT (gpio_isr_entries[indi].pad ));
149156 }
150- }else {
151- if ( !val ){
157+ }
158+ else
159+ {
160+ if (!val)
161+ {
152162 am_hal_gpio_interrupt_clear (AM_HAL_GPIO_BIT (gpio_isr_entries[indi].pad ));
153163 }
154164 }
@@ -157,15 +167,21 @@ extern "C" void am_gpio_isr(void)
157167 }
158168}
159169
160- void attachInterruptArg (uint8_t pin, voidFuncPtrArgs callbackArgs, void * arg, int mode)
170+ void attachInterruptArg (uint8_t pin, voidFuncPtrArgs callbackArgs, void *arg, int mode)
161171{
162172 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+ }
164177
165- if ( gpio_num_isr < AP3_GPIO_MAX_PADS ){
178+ if (gpio_num_isr < AP3_GPIO_MAX_PADS)
179+ {
166180 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+ {
169185 break ;
170186 }
171187 }
@@ -177,88 +193,83 @@ void attachInterruptArg(uint8_t pin, voidFuncPtrArgs callbackArgs, void * arg, i
177193
178194 // enable interrupts for the pad in question (Arduino does this by default when attachInterrupt is called)
179195 uint8_t eIntDir = 0x00 ;
180- if (( mode == FALLING ) || ( mode == LOW )){
196+ if ((mode == FALLING) || (mode == LOW))
197+ {
181198 eIntDir = AM_HAL_GPIO_PIN_INTDIR_HI2LO;
182- }else if (( mode == RISING ) || ( mode == HIGH )){
199+ }
200+ else if ((mode == RISING) || (mode == HIGH))
201+ {
183202 eIntDir = AM_HAL_GPIO_PIN_INTDIR_LO2HI;
184- }else {
185- eIntDir = AM_HAL_GPIO_PIN_INTDIR_BOTH;
186203 }
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);
188209
189- // clear the flag and enable the interrupt in the NVIC
210+ // clear the flag and enable the interrupt in the NVIC
190211 am_hal_gpio_interrupt_clear (AM_HAL_GPIO_BIT (pad));
191212 am_hal_gpio_interrupt_enable (AM_HAL_GPIO_BIT (pad));
192213 NVIC_EnableIRQ (GPIO_IRQn);
193214
194- if ( indi == gpio_num_isr ){
215+ if (indi == gpio_num_isr)
216+ {
195217 gpio_num_isr++;
196218 }
197219 }
198220}
199221
200222void attachInterrupt (uint8_t pin, voidFuncPtr callback, int mode)
201223{
202- attachInterruptArg ( pin, (voidFuncPtrArgs)callback, NULL , mode );
224+ attachInterruptArg (pin, (voidFuncPtrArgs)callback, NULL , mode);
203225}
204226
205227extern void detachInterrupt (uint8_t pin)
206228{
207229 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+ }
209234
210235 uint8_t indi = 0 ;
211236
212237 // 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+ {
215242 break ;
216243 }
217244 }
218245
219246 // 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+ {
221249 return ;
222250 }
223251
224252 // disable the interrupt in the NVIC
225253 am_hal_gpio_interrupt_disable (AM_HAL_GPIO_BIT (pad));
226254 am_hal_gpio_interrupt_clear (AM_HAL_GPIO_BIT (pad));
227255
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);
230258
231259 // 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 ];
234263 }
235-
264+
236265 // Clear out the last entry
237266 gpio_isr_entries[gpio_num_isr].pad = 0 ;
238267 gpio_isr_entries[gpio_num_isr].callback = NULL ;
239268 gpio_isr_entries[gpio_num_isr].mode = LOW;
240269 gpio_isr_entries[gpio_num_isr].arg = NULL ;
241-
242270}
243271
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)
262273{
263274 uint32_t ui32Padreg, ui32AltPadCfg, ui32GPCfg;
264275 uint32_t ui32Funcsel, ui32PowerSw;
@@ -276,7 +287,6 @@ uint32_t ap3_gpio_enable_interrupts(uint32_t ui32Pin, uint32_t eIntDir )
276287 //
277288 ui32GPCfg = ui32Padreg = ui32AltPadCfg = 0 ;
278289
279-
280290 //
281291 // Map the requested interrupt direction settings into the Apollo3
282292 // 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 )
286296 //
287297 ui32GPCfg |= (((eIntDir >> 0 ) & 0x1 ) << GPIOCFG_FLD_INTD_S) | (((eIntDir >> 1 ) & 0x1 ) << GPIOCFG_FLD_INCFG_S);
288298
289-
290299 //
291300 // At this point, the configuration variable, ui32GpioCfg
292301 // 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 )
326335
327336 return AM_HAL_STATUS_SUCCESS;
328337
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