Skip to content

Commit 98537bd

Browse files
committed
let analogWrite coexist with open-drain mode
1 parent 2776d16 commit 98537bd

File tree

3 files changed

+18
-13
lines changed

3 files changed

+18
-13
lines changed

cores/esp8266/core_esp8266_wiring_digital.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ extern void __pinMode(uint8_t pin, uint8_t mode) {
8282
}
8383

8484
extern void IRAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) {
85-
stopWaveform(pin); // Disable any Tone or startWaveform on this pin
85+
stopWaveform(pin); // Disable any Tone, startWaveform, or analogWrite on this pin
8686
if(pin < 16){
8787
if(val) GPOS = (1 << pin);
8888
else GPOC = (1 << pin);

cores/esp8266/core_esp8266_wiring_pwm.cpp

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,14 @@ extern void __analogWriteFreq(uint32_t freq) {
4444
}
4545

4646
extern void __analogWrite(uint8_t pin, int val) {
47-
analogWriteMode(pin, val, false);
47+
if (pin > 16) {
48+
return;
49+
}
50+
bool openDrain = false;
51+
if (analogMap & 1UL << pin) {
52+
openDrain = GPC(pin) & (1 << GPCD);
53+
}
54+
analogWriteMode(pin, val, openDrain);
4855
}
4956

5057
extern void __analogWriteMode(uint8_t pin, int val, bool openDrain) {
@@ -59,23 +66,22 @@ extern void __analogWriteMode(uint8_t pin, int val, bool openDrain) {
5966
}
6067

6168
if (analogMap & 1UL << pin) {
62-
// Per the Arduino docs at https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/
63-
// val: the duty cycle: between 0 (always off) and 255 (always on).
64-
// So if val = 0 we have digitalWrite(LOW), if we have val==range we have digitalWrite(HIGH)
65-
6669
analogMap &= ~(1 << pin);
70+
const bool isOpenDrain = GPC(pin) & (1 << GPCD);
71+
if (isOpenDrain != openDrain) {
72+
GPC(pin) ^= (1 << GPCD);
73+
}
6774
}
6875
else {
69-
if(openDrain) {
70-
pinMode(pin, OUTPUT_OPEN_DRAIN);
71-
} else {
72-
pinMode(pin, OUTPUT);
73-
}
76+
pinMode(pin, openDrain ? OUTPUT_OPEN_DRAIN : OUTPUT);
7477
}
7578
uint32_t high = (analogPeriod * val) / analogScale;
7679
uint32_t low = analogPeriod - high;
7780
// 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)
7881
int phaseReference = __builtin_ffs(analogMap) - 1;
82+
// Per the Arduino docs at https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/
83+
// val: the duty cycle: between 0 (always off) and 255 (always on).
84+
// So if val = 0 we have digitalWrite(LOW), if we have val==range we have digitalWrite(HIGH)
7985
if (_setPWM(pin, val, analogScale)) {
8086
analogMap |= (1 << pin);
8187
} else if (startWaveformClockCycles(pin, high, low, 0, phaseReference, 0, true)) {

libraries/Servo/src/Servo.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,7 @@ void Servo::writeMicroseconds(int value)
116116
_servoMap &= ~(1 << _pin);
117117
// 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)
118118
int phaseReference = __builtin_ffs(_servoMap) - 1;
119-
if (startWaveform(_pin, _valueUs, REFRESH_INTERVAL - _valueUs, 0, phaseReference))
120-
{
119+
if (startWaveform(_pin, _valueUs, REFRESH_INTERVAL - _valueUs, 0, phaseReference)) {
121120
_servoMap |= (1 << _pin);
122121
}
123122
}

0 commit comments

Comments
 (0)