Skip to content

Commit b02e443

Browse files
author
Nathan Seidle
committed
Add support for pulseIn and pulseInLong
Matches the reference. Note: pulseIn uses micros() and therefor will not behave correctly in a noInterrupt() sketch. I don't foresee this as a future issue but it does break slight compatibility.
1 parent b1e5610 commit b02e443

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

cores/arduino/ard_sup/ap3_gpio.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,7 @@ void attachInterrupt(uint8_t pin, voidFuncPtr callback, int mode);
6868
void attachInterruptArg(uint8_t pin, voidFuncPtrArgs callbackArgs, void *arg, int mode);
6969
void detachInterrupt(uint8_t pin);
7070

71+
unsigned long pulseIn(uint8_t pinNumber, uint8_t state, unsigned long timeout = 1000000L);
72+
unsigned long pulseInLong(uint8_t pinNumber, uint8_t state, unsigned long timeout);
73+
7174
#endif //_AP3_GPIO_H_

cores/arduino/ard_sup/gpio/ap3_gpio.cpp

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,4 +335,65 @@ uint32_t ap3_gpio_enable_interrupts(uint32_t ui32Pin, uint32_t eIntDir)
335335

336336
return AM_HAL_STATUS_SUCCESS;
337337

338-
} // 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

Comments
 (0)