Skip to content

Commit 4312adf

Browse files
committed
Improve code efficiency.
1 parent 09debed commit 4312adf

File tree

1 file changed

+15
-16
lines changed

1 file changed

+15
-16
lines changed

cores/esp8266/core_esp8266_waveform.cpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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

263263
static 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

Comments
 (0)