@@ -84,8 +84,8 @@ namespace {
8484 uint32_t enabled = 0 ; // Is it actively running, updated in NMI so no access outside the NMI code
8585
8686 // Enable lock-free by only allowing updates to waveform.states and waveform.enabled from IRQ service routine
87- int32_t toSet = - 1 ; // Message to the NMI handler to start/modify exactly one waveform
88- int32_t toDisable = - 1 ; // Message to the NMI handler to disable exactly one pin from waveform generation
87+ int32_t toSetBits = 0 ; // Message to the NMI handler to start/modify exactly one waveform
88+ int32_t toDisableBits = 0 ; // Message to the NMI handler to disable exactly one pin from waveform generation
8989
9090 uint32_t (*timer1CB)() = nullptr ;
9191
@@ -187,7 +187,7 @@ int startWaveformClockCycles(uint8_t pin, uint32_t highCcys, uint32_t lowCcys,
187187 }
188188 }
189189 std::atomic_thread_fence (std::memory_order_release);
190- waveform.toSet = pin;
190+ waveform.toSetBits = 1UL << pin;
191191 std::atomic_thread_fence (std::memory_order_release);
192192 if (!waveform.timer1Running ) {
193193 initTimer ();
@@ -204,11 +204,11 @@ int startWaveformClockCycles(uint8_t pin, uint32_t highCcys, uint32_t lowCcys,
204204 if (runTimeCcys) {
205205 wave.mode = WaveformMode::UPDATEEXPIRY;
206206 std::atomic_thread_fence (std::memory_order_release);
207- waveform.toSet = pin;
207+ waveform.toSetBits = 1UL << pin;
208208 }
209209 }
210210 std::atomic_thread_fence (std::memory_order_acq_rel);
211- while (waveform.toSet >= 0 ) {
211+ while (waveform.toSetBits ) {
212212 delay (0 ); // Wait for waveform to update
213213 std::atomic_thread_fence (std::memory_order_acquire);
214214 }
@@ -226,13 +226,13 @@ int ICACHE_RAM_ATTR stopWaveform(uint8_t pin) {
226226 std::atomic_thread_fence (std::memory_order_acquire);
227227 const uint32_t pinBit = 1UL << pin;
228228 if (waveform.enabled & pinBit) {
229- waveform.toDisable = pin;
229+ waveform.toDisableBits = 1UL << pin;
230230 std::atomic_thread_fence (std::memory_order_release);
231231 // Must not interfere if Timer is due shortly
232232 if (T1V > ((clockCyclesPerMicrosecond () == 160 ) ? (IRQLATENCYCCYS + DELTAIRQCCYS) >> 1 : IRQLATENCYCCYS + DELTAIRQCCYS)) {
233233 timer1_write ((clockCyclesPerMicrosecond () == 160 ) ? microsecondsToClockCycles (1 ) >> 1 : microsecondsToClockCycles (1 ));
234234 }
235- while (waveform.toDisable >= 0 ) {
235+ while (waveform.toDisableBits ) {
236236 /* no-op */ // Can't delay() since stopWaveform may be called from an IRQ
237237 std::atomic_thread_fence (std::memory_order_acquire);
238238 }
@@ -262,23 +262,22 @@ static inline ICACHE_RAM_ATTR int32_t scaleCcys(int32_t ccys) {
262262
263263static ICACHE_RAM_ATTR void timer1Interrupt () {
264264 const uint32_t isrStartCcy = ESP.getCycleCount ();
265- const uint32_t toSetMask = waveform.toSet >= 0 ? 1UL << waveform.toSet : 0 ;
266- const uint32_t toDisableMask = waveform.toDisable >= 0 ? 1UL << waveform.toDisable : 0 ;
267- if ((toSetMask && !(waveform.enabled & toSetMask)) || toDisableMask) {
265+ if ((waveform.toSetBits && !(waveform.enabled & waveform.toSetBits )) || waveform.toDisableBits ) {
268266 // Handle enable/disable requests from main app.
269- waveform.enabled = (waveform.enabled & ~toDisableMask ) | toSetMask ; // Set the requested waveforms on/off
267+ waveform.enabled = (waveform.enabled & ~waveform. toDisableBits ) | waveform. toSetBits ; // Set the requested waveforms on/off
270268 // Find the first GPIO being generated by checking GCC's find-first-set (returns 1 + the bit of the first 1 in an int32_t)
271269 waveform.startPin = __builtin_ffs (waveform.enabled ) - 1 ;
272270 // Find the last bit by subtracting off GCC's count-leading-zeros (no offset in this one)
273271 waveform.endPin = 32 - __builtin_clz (waveform.enabled );
274- waveform.toDisable = - 1 ;
272+ waveform.toDisableBits = 0 ;
275273 }
276274
277- if (toSetMask) {
278- Waveform& wave = waveform.pins [waveform.toSet ];
275+ if (waveform.toSetBits ) {
276+ const int toSetPin = __builtin_ffs (waveform.toSetBits ) - 1 ;
277+ Waveform& wave = waveform.pins [toSetPin];
279278 switch (wave.mode ) {
280279 case WaveformMode::INIT:
281- waveform.states &= ~toSetMask ; // Clear the state of any just started
280+ waveform.states &= ~waveform. toSetBits ; // Clear the state of any just started
282281 if (wave.alignPhase >= 0 && waveform.enabled & (1UL << wave.alignPhase )) {
283282 wave.nextPeriodCcy = waveform.pins [wave.alignPhase ].nextPeriodCcy + wave.nextPeriodCcy ;
284283 if (static_cast <int32_t >(waveform.nextEventCcy - wave.nextPeriodCcy ) > 0 ) {
@@ -302,7 +301,7 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
302301 default :
303302 break ;
304303 }
305- waveform.toSet = - 1 ;
304+ waveform.toSetBits = 0 ;
306305 }
307306
308307 // Exit the loop if the next event, if any, is sufficiently distant.
0 commit comments