29
29
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
30
30
* to 3 minutes in length, but must be called at least a few dozen microseconds
31
31
* before the start of the pulse. */
32
+
33
+ // NOTE: Arduino code now has a wiring_pulse.S that implements this function
34
+ // as assembly code. For now, the C code will stay in the xmega version
35
+ // but at some point the assembly version should be implemented.
36
+
32
37
unsigned long pulseIn (uint8_t pin , uint8_t state , unsigned long timeout )
33
38
{
34
39
// cache the port and bit of the pin in order to speed up the
@@ -45,19 +50,31 @@ unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
45
50
unsigned long maxloops = microsecondsToClockCycles (timeout ) / 16 ;
46
51
47
52
// wait for any previous pulse to end
48
- while ((* portInputRegister (port ) & bit ) == stateMask )
49
- if (numloops ++ == maxloops )
53
+ while ((* portInputRegister (port ) & bit ) == stateMask )
54
+ {
55
+ if (numloops ++ == maxloops )
56
+ {
50
57
return 0 ;
58
+ }
59
+ }
51
60
52
61
// wait for the pulse to start
53
- while ((* portInputRegister (port ) & bit ) != stateMask )
54
- if (numloops ++ == maxloops )
62
+ while ((* portInputRegister (port ) & bit ) != stateMask )
63
+ {
64
+ if (numloops ++ == maxloops )
65
+ {
55
66
return 0 ;
67
+ }
68
+ }
56
69
57
70
// wait for the pulse to stop
58
- while ((* portInputRegister (port ) & bit ) == stateMask ) {
59
- if (numloops ++ == maxloops )
71
+ while ((* portInputRegister (port ) & bit ) == stateMask )
72
+ {
73
+ if (numloops ++ == maxloops )
74
+ {
60
75
return 0 ;
76
+ }
77
+
61
78
width ++ ;
62
79
}
63
80
@@ -67,3 +84,56 @@ unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
67
84
// the interrupt handlers.
68
85
return clockCyclesToMicroseconds (width * 21 + 16 );
69
86
}
87
+
88
+ // Added 11/10/2018 to bring it up to latest Arduino code
89
+
90
+ /* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
91
+ * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
92
+ * to 3 minutes in length, but must be called at least a few dozen microseconds
93
+ * before the start of the pulse.
94
+ *
95
+ * ATTENTION:
96
+ * this function relies on micros() so cannot be used in noInterrupt() context
97
+ */
98
+ unsigned long pulseInLong (uint8_t pin , uint8_t state , unsigned long timeout )
99
+ {
100
+ // cache the port and bit of the pin in order to speed up the
101
+ // pulse width measuring loop and achieve finer resolution. calling
102
+ // digitalRead() instead yields much coarser resolution.
103
+ uint8_t bit = digitalPinToBitMask (pin );
104
+ uint8_t port = digitalPinToPort (pin );
105
+ uint8_t stateMask = (state ? bit : 0 );
106
+
107
+ unsigned long startMicros = micros ();
108
+
109
+ // wait for any previous pulse to end
110
+ while ((* portInputRegister (port ) & bit ) == stateMask )
111
+ {
112
+ if (micros () - startMicros > timeout )
113
+ {
114
+ return 0 ;
115
+ }
116
+ }
117
+
118
+ // wait for the pulse to start
119
+ while ((* portInputRegister (port ) & bit ) != stateMask )
120
+ {
121
+ if (micros () - startMicros > timeout )
122
+ {
123
+ return 0 ;
124
+ }
125
+ }
126
+
127
+ unsigned long start = micros ();
128
+ // wait for the pulse to stop
129
+ while ((* portInputRegister (port ) & bit ) == stateMask )
130
+ {
131
+ if (micros () - startMicros > timeout )
132
+ {
133
+ return 0 ;
134
+ }
135
+ }
136
+
137
+ return micros () - start ;
138
+ }
139
+
0 commit comments