22
22
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
23
23
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
24
24
* 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
+ */
26
30
uint32_t pulseIn ( uint32_t pin, uint32_t state, uint32_t timeout )
27
31
{
28
32
// 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 )
47
51
else
48
52
return 0 ;
49
53
}
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