2222/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
2323 * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
2424 * to 3 minutes in length, but must be called at least a few dozen microseconds
25- * before the start of the pulse. */
25+ * before the start of the pulse.
26+ *
27+ * ATTENTION:
28+ * This function performs better with short pulses in noInterrupt() context
29+ */
2630uint32_t pulseIn ( uint32_t pin, uint32_t state, uint32_t timeout )
2731{
2832 // cache the port and bit of the pin in order to speed up the
@@ -47,3 +51,43 @@ uint32_t pulseIn( uint32_t pin, uint32_t state, uint32_t timeout )
4751 else
4852 return 0 ;
4953}
54+
55+ /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
56+ * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
57+ * to 3 minutes in length, but must be called at least a few dozen microseconds
58+ * before the start of the pulse.
59+ *
60+ * ATTENTION:
61+ * this function relies on micros() so cannot be used in noInterrupt() context
62+ */
63+ uint32_t pulseInLong (uint8_t pin, uint8_t state, unsigned long timeout)
64+ {
65+ // cache the port and bit of the pin in order to speed up the
66+ // pulse width measuring loop and achieve finer resolution. calling
67+ // digitalRead() instead yields much coarser resolution.
68+ PinDescription p = g_APinDescription[pin];
69+ uint32_t bit = p.ulPin ;
70+ uint32_t stateMask = state ? bit : 0 ;
71+
72+ // convert the timeout from microseconds to a number of times through
73+ // the initial loop; it takes 18 clock cycles per iteration.
74+ unsigned long maxloops = microsecondsToClockCycles (timeout) / 10 ;
75+
76+ // wait for any previous pulse to end
77+ while ((p.pPort ->PIO_PDSR & bit) == stateMask)
78+ if (--maxloops == 0 )
79+ return 0 ;
80+
81+ // wait for the pulse to start
82+ while ((p.pPort ->PIO_PDSR & bit) != stateMask)
83+ if (--maxloops == 0 )
84+ return 0 ;
85+
86+ unsigned long start = micros ();
87+ // wait for the pulse to stop
88+ while ((p.pPort ->PIO_PDSR & bit) == stateMask) {
89+ if (--maxloops == 0 )
90+ return 0 ;
91+ }
92+ return micros () - start;
93+ }
0 commit comments