@@ -84,8 +84,8 @@ namespace {
84
84
uint32_t enabled = 0 ; // Is it actively running, updated in NMI so no access outside the NMI code
85
85
86
86
// 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
89
89
90
90
uint32_t (*timer1CB)() = nullptr ;
91
91
@@ -187,7 +187,7 @@ int startWaveformClockCycles(uint8_t pin, uint32_t highCcys, uint32_t lowCcys,
187
187
}
188
188
}
189
189
std::atomic_thread_fence (std::memory_order_release);
190
- waveform.toSet = pin;
190
+ waveform.toSetBits = 1UL << pin;
191
191
std::atomic_thread_fence (std::memory_order_release);
192
192
if (!waveform.timer1Running ) {
193
193
initTimer ();
@@ -204,11 +204,11 @@ int startWaveformClockCycles(uint8_t pin, uint32_t highCcys, uint32_t lowCcys,
204
204
if (runTimeCcys) {
205
205
wave.mode = WaveformMode::UPDATEEXPIRY;
206
206
std::atomic_thread_fence (std::memory_order_release);
207
- waveform.toSet = pin;
207
+ waveform.toSetBits = 1UL << pin;
208
208
}
209
209
}
210
210
std::atomic_thread_fence (std::memory_order_acq_rel);
211
- while (waveform.toSet >= 0 ) {
211
+ while (waveform.toSetBits ) {
212
212
delay (0 ); // Wait for waveform to update
213
213
std::atomic_thread_fence (std::memory_order_acquire);
214
214
}
@@ -226,13 +226,13 @@ int ICACHE_RAM_ATTR stopWaveform(uint8_t pin) {
226
226
std::atomic_thread_fence (std::memory_order_acquire);
227
227
const uint32_t pinBit = 1UL << pin;
228
228
if (waveform.enabled & pinBit) {
229
- waveform.toDisable = pin;
229
+ waveform.toDisableBits = 1UL << pin;
230
230
std::atomic_thread_fence (std::memory_order_release);
231
231
// Must not interfere if Timer is due shortly
232
232
if (T1V > ((clockCyclesPerMicrosecond () == 160 ) ? (IRQLATENCYCCYS + DELTAIRQCCYS) >> 1 : IRQLATENCYCCYS + DELTAIRQCCYS)) {
233
233
timer1_write ((clockCyclesPerMicrosecond () == 160 ) ? microsecondsToClockCycles (1 ) >> 1 : microsecondsToClockCycles (1 ));
234
234
}
235
- while (waveform.toDisable >= 0 ) {
235
+ while (waveform.toDisableBits ) {
236
236
/* no-op */ // Can't delay() since stopWaveform may be called from an IRQ
237
237
std::atomic_thread_fence (std::memory_order_acquire);
238
238
}
@@ -262,23 +262,22 @@ static inline ICACHE_RAM_ATTR int32_t scaleCcys(int32_t ccys) {
262
262
263
263
static ICACHE_RAM_ATTR void timer1Interrupt () {
264
264
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 ) {
268
266
// 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
270
268
// 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)
271
269
waveform.startPin = __builtin_ffs (waveform.enabled ) - 1 ;
272
270
// Find the last bit by subtracting off GCC's count-leading-zeros (no offset in this one)
273
271
waveform.endPin = 32 - __builtin_clz (waveform.enabled );
274
- waveform.toDisable = - 1 ;
272
+ waveform.toDisableBits = 0 ;
275
273
}
276
274
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];
279
278
switch (wave.mode ) {
280
279
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
282
281
if (wave.alignPhase >= 0 && waveform.enabled & (1UL << wave.alignPhase )) {
283
282
wave.nextPeriodCcy = waveform.pins [wave.alignPhase ].nextPeriodCcy + wave.nextPeriodCcy ;
284
283
if (static_cast <int32_t >(waveform.nextEventCcy - wave.nextPeriodCcy ) > 0 ) {
@@ -302,7 +301,7 @@ static ICACHE_RAM_ATTR void timer1Interrupt() {
302
301
default :
303
302
break ;
304
303
}
305
- waveform.toSet = - 1 ;
304
+ waveform.toSetBits = 0 ;
306
305
}
307
306
308
307
// Exit the loop if the next event, if any, is sufficiently distant.
0 commit comments