Skip to content

Commit 6bafed4

Browse files
committed
Carry over a few insights from comparing to original waveform (phase-sync) branch.
1 parent 8750088 commit 6bafed4

File tree

3 files changed

+8
-25
lines changed

3 files changed

+8
-25
lines changed

cores/esp8266/core_esp8266_waveform.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141

4242
#include "core_esp8266_waveform.h"
4343
#include <Arduino.h>
44-
#include "debug.h"
4544
#include "ets_sys.h"
4645
#include <atomic>
4746

@@ -150,7 +149,7 @@ static __attribute__((noinline)) void initTimer() {
150149
timer1_write(IRQLATENCYCCYS); // Cause an interrupt post-haste
151150
}
152151

153-
static void IRAM_ATTR deinitIdleTimer() {
152+
static IRAM_ATTR void deinitIdleTimer() {
154153
if (!waveform.timer1Running || waveform.enabled || waveform.timer1CB || pwmState.cnt) {
155154
return;
156155
}
@@ -174,8 +173,9 @@ extern "C" {
174173
// Wait for mailbox to be emptied (either busy or delay() as needed)
175174
static IRAM_ATTR void _notifyPWM(PWMState *p, bool idle) {
176175
p->pwmUpdate = nullptr;
177-
pwmState.pwmUpdate = p;
178176
std::atomic_thread_fence(std::memory_order_release);
177+
pwmState.pwmUpdate = p;
178+
std::atomic_thread_fence(std::memory_order_acq_rel);
179179
if (idle) {
180180
forceTimerTrigger();
181181
}

cores/esp8266/core_esp8266_waveform.h

+4-6
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,8 @@ extern "C" {
5656
// Setting autoPwm to true allows the wave generator to maintain PWM duty to idle cycle ratio
5757
// under load, for applications where frequency or duty cycle must not change, leave false.
5858
// Returns true or false on success or failure.
59-
int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t runTimeUS = 0,
60-
// Following parameters are ignored unless in PhaseLocked mode
61-
int8_t alignPhase = -1, uint32_t phaseOffsetUS = 0, bool autoPwm = false);
59+
int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS,
60+
uint32_t runTimeUS = 0, int8_t alignPhase = -1, uint32_t phaseOffsetUS = 0, bool autoPwm = false);
6261

6362
// Start or change a waveform of the specified high and low CPU clock cycles on specific pin.
6463
// If runtimeCycles > 0 then automatically stop it after that many CPU clock cycles, relative to the next
@@ -68,9 +67,8 @@ int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t
6867
// Setting autoPwm to true allows the wave generator to maintain PWM duty to idle cycle ratio
6968
// under load, for applications where frequency or duty cycle must not change, leave false.
7069
// Returns true or false on success or failure.
71-
int startWaveformClockCycles(uint8_t pin, uint32_t timeHighCcys, uint32_t timeLowCcys, uint32_t runTimeCcys = 0,
72-
// Following parameters are ignored unless in PhaseLocked mode
73-
int8_t alignPhase = -1, uint32_t phaseOffsetCcys = 0, bool autoPwm = false);
70+
int startWaveformClockCycles(uint8_t pin, uint32_t timeHighCcys, uint32_t timeLowCcys,
71+
uint32_t runTimeCcys = 0, int8_t alignPhase = -1, uint32_t phaseOffsetCcys = 0, bool autoPwm = false);
7472

7573
// Stop a waveform, if any, on the specified pin.
7674
// Returns true or false on success or failure.

cores/esp8266/core_esp8266_wiring_pwm.cpp

+1-16
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ extern void __analogWriteMode(uint8_t pin, int val, bool openDrain) {
5858
if (pin > 16) {
5959
return;
6060
}
61-
uint32_t analogPeriod = microsecondsToClockCycles(1000000UL) / analogFreq;
6261
if (val < 0) {
6362
val = 0;
6463
} else if (val > analogScale) {
@@ -75,28 +74,14 @@ extern void __analogWriteMode(uint8_t pin, int val, bool openDrain) {
7574
else {
7675
pinMode(pin, openDrain ? OUTPUT_OPEN_DRAIN : OUTPUT);
7776
}
78-
uint32_t high = (analogPeriod * val) / analogScale;
79-
uint32_t low = analogPeriod - high;
80-
// 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)
81-
int phaseReference = __builtin_ffs(analogMap) - 1;
77+
8278
// Per the Arduino docs at https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/
8379
// val: the duty cycle: between 0 (always off) and 255 (always on).
8480
// So if val = 0 we have digitalWrite(LOW), if we have val==range we have digitalWrite(HIGH)
8581
if (_setPWM(pin, val, analogScale)) {
8682
if (val > 0 && val < analogScale) {
8783
analogMap |= (1 << pin);
8884
}
89-
} else {
90-
const bool detach = (val == 0 || val == analogScale);
91-
// To go steady LOW or HIGH, let the waveform run into next duty cycle, if any. Then stop.
92-
if (startWaveformClockCycles(pin, high, low, static_cast<uint32_t>(detach), phaseReference, 0, true)) {
93-
if (detach) {
94-
delay((1000 + analogFreq) / analogFreq);
95-
stopWaveform(pin);
96-
} else {
97-
analogMap |= (1 << pin);
98-
}
99-
}
10085
}
10186
}
10287

0 commit comments

Comments
 (0)