Skip to content

Commit 8f92812

Browse files
Allow waveforms to be specified in clock cycles
Allow the PWM to specify sub-microsecond waveform edges, as have been proposed by @dok-net and me. No other changes intended. This will increase the linearity at 30 and 40 kHZ PWM rates, but leave most other things unaffected.
1 parent e1789dd commit 8f92812

File tree

3 files changed

+14
-7
lines changed

3 files changed

+14
-7
lines changed

cores/esp8266/core_esp8266_waveform.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,19 @@ void setTimer1Callback(uint32_t (*fn)()) {
112112
// waveform smoothly on next low->high transition. For immediate change, stopWaveform()
113113
// first, then it will immediately begin.
114114
int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t runTimeUS) {
115-
if ((pin > 16) || isFlashInterfacePin(pin)) {
115+
return startWaveformCycles(pin, microsecondsToClockCycles(timeHighUS), microsecondsToClockCycles(timeLowUS), microsecondsToClockCycles(runTimeUS));
116+
}
117+
118+
int startWaveformCycles(uint8_t pin, uint32_t timeHighCycles, uint32_t timeLowCycles, uint32_t runTimeCycles) {
119+
if ((pin > 16) || isFlashInterfacePin(pin)) {
116120
return false;
117121
}
118122
Waveform *wave = &waveform[pin];
119123
// Adjust to shave off some of the IRQ time, approximately
120-
wave->nextTimeHighCycles = microsecondsToClockCycles(timeHighUS);
121-
wave->nextTimeLowCycles = microsecondsToClockCycles(timeLowUS);
122-
wave->expiryCycle = runTimeUS ? GetCycleCount() + microsecondsToClockCycles(runTimeUS) : 0;
123-
if (runTimeUS && !wave->expiryCycle) {
124+
wave->nextTimeHighCycles = timeHighCycles;
125+
wave->nextTimeLowCycles = timeLowCycles;
126+
wave->expiryCycle = runTimeCycles ? GetCycleCount() + runTimeCycles : 0;
127+
if (runTimeCycles && !wave->expiryCycle) {
124128
wave->expiryCycle = 1; // expiryCycle==0 means no timeout, so avoid setting it
125129
}
126130

cores/esp8266/core_esp8266_waveform.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ extern "C" {
5050
// If runtimeUS > 0 then automatically stop it after that many usecs.
5151
// Returns true or false on success or failure.
5252
int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t runTimeUS);
53+
// Same as above, but pass in CPU clock cycles instead of microseconds
54+
int startWaveformCycles(uint8_t pin, uint32_t timeHighCycles, uint32_t timeLowCycles, uint32_t runTimeCycles);
5355
// Stop a waveform, if any, on the specified pin.
5456
// Returns true or false on success or failure.
5557
int stopWaveform(uint8_t pin);

cores/esp8266/core_esp8266_wiring_pwm.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "core_esp8266_waveform.h"
2626

2727
extern "C" {
28+
#include "user_interface.h"
2829

2930
static uint32_t analogMap = 0;
3031
static int32_t analogScale = PWMRANGE;
@@ -50,7 +51,7 @@ extern void __analogWrite(uint8_t pin, int val) {
5051
if (pin > 16) {
5152
return;
5253
}
53-
uint32_t analogPeriod = 1000000L / analogFreq;
54+
uint32_t analogPeriod = (1000000L * system_get_cpu_freq()) / analogFreq;
5455
if (val < 0) {
5556
val = 0;
5657
} else if (val > analogScale) {
@@ -68,7 +69,7 @@ extern void __analogWrite(uint8_t pin, int val) {
6869
stopWaveform(pin);
6970
digitalWrite(pin, LOW);
7071
} else {
71-
if (startWaveform(pin, high, low, 0)) {
72+
if (startWaveformCycles(pin, high, low, 0)) {
7273
analogMap |= (1 << pin);
7374
}
7475
}

0 commit comments

Comments
 (0)