@@ -44,7 +44,14 @@ extern void __analogWriteFreq(uint32_t freq) {
44
44
}
45
45
46
46
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);
48
55
}
49
56
50
57
extern void __analogWriteMode (uint8_t pin, int val, bool openDrain) {
@@ -59,23 +66,22 @@ extern void __analogWriteMode(uint8_t pin, int val, bool openDrain) {
59
66
}
60
67
61
68
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
-
66
69
analogMap &= ~(1 << pin);
70
+ const bool isOpenDrain = GPC (pin) & (1 << GPCD);
71
+ if (isOpenDrain != openDrain) {
72
+ GPC (pin) ^= (1 << GPCD);
73
+ }
67
74
}
68
75
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);
74
77
}
75
78
uint32_t high = (analogPeriod * val) / analogScale;
76
79
uint32_t low = analogPeriod - high;
77
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)
78
81
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)
79
85
if (_setPWM (pin, val, analogScale)) {
80
86
analogMap |= (1 << pin);
81
87
} else if (startWaveformClockCycles (pin, high, low, 0 , phaseReference, 0 , true )) {
0 commit comments