1
1
/* *********************************************************************************
2
- AnalogWrite Library for ESP32-ESP32S2 Arduino core - Version 1.1.0
2
+ AnalogWrite Library for ESP32-ESP32S2 Arduino core - Version 2.0.6
3
3
by dlloydev https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite
4
4
This Library is licensed under the MIT License
5
5
**********************************************************************************/
6
6
7
7
#include < Arduino.h>
8
8
#include " analogWrite.h"
9
9
10
+ namespace aw {
11
+
10
12
#if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
11
13
pinStatus_t pinsStatus[8 ] = {
12
- {0 , -1 , 5000 , 13 , 0 }, {2 , -1 , 5000 , 13 , 0 },
13
- {4 , -1 , 5000 , 13 , 0 }, {6 , -1 , 5000 , 13 , 0 },
14
- {1 , -1 , 5000 , 13 , 0 }, {3 , -1 , 5000 , 13 , 0 },
15
- {5 , -1 , 5000 , 13 , 0 }, {7 , -1 , 5000 , 13 , 0 }
14
+ {0 , -1 , 980 , 8 , 0 , 0 }, {2 , -1 , 980 , 8 , 0 , 0 },
15
+ {4 , -1 , 980 , 8 , 0 , 0 }, {6 , -1 , 980 , 8 , 0 , 0 },
16
+ {1 , -1 , 980 , 8 , 0 , 0 }, {3 , -1 , 980 , 8 , 0 , 0 },
17
+ {5 , -1 , 980 , 8 , 0 , 0 }, {7 , -1 , 980 , 8 , 0 , 0 }
16
18
};
17
19
const uint8_t chd = 1 ;
18
20
#else // ESP32
19
21
pinStatus_t pinsStatus[8 ] = {
20
- { 0 , -1 , 5000 , 13 , 0 }, { 2 , -1 , 5000 , 13 , 0 },
21
- { 4 , -1 , 5000 , 13 , 0 }, { 6 , -1 , 5000 , 13 , 0 },
22
- { 8 , -1 , 5000 , 13 , 0 }, {10 , -1 , 5000 , 13 , 0 },
23
- {12 , -1 , 5000 , 13 , 0 }, {14 , -1 , 5000 , 13 , 0 }
22
+ { 0 , -1 , 980 , 8 , 0 , 0 }, { 2 , -1 , 980 , 8 , 0 , 0 },
23
+ { 4 , -1 , 980 , 8 , 0 , 0 }, { 6 , -1 , 980 , 8 , 0 , 0 },
24
+ { 8 , -1 , 980 , 8 , 0 , 0 }, {10 , -1 , 980 , 8 , 0 , 0 },
25
+ {12 , -1 , 980 , 8 , 0 , 0 }, {14 , -1 , 980 , 8 , 0 , 0 }
24
26
};
25
27
const uint8_t chd = 2 ;
26
28
#endif
27
29
28
- void analogWrite (int8_t pin, int32_t value) {
29
- if (pin == DAC1 || pin == DAC2) { // dac
30
- if (value > 255 ) value = 255 ;
31
- dacWrite (pin, value);
32
- } else { // pwm
33
- int8_t ch = getChannel (pin);
34
- if (ch >= 0 ) {
35
- if (value == -1 ) { // detach pin
36
- pinsStatus[ch / chd].pin = -1 ;
37
- pinsStatus[ch / chd].frequency = 5000 ;
38
- pinsStatus[ch / chd].resolution = 13 ;
39
- ledcDetachPin (pinsStatus[ch / chd].pin );
40
- REG_SET_FIELD (GPIO_PIN_MUX_REG[pin], MCU_SEL, GPIO_MODE_DEF_DISABLE);
41
- } else { // attached
42
- int32_t valueMax = (pow (2 , pinsStatus[ch / chd].resolution )) - 1 ;
43
- if (value > valueMax) { // full ON
44
- value = valueMax + 1 ;
45
- ledcDetachPin (pin);
46
- pinMode (pin, OUTPUT);
47
- digitalWrite (pin, HIGH);
48
- } else { // write PWM
49
- ledcSetup (ch, pinsStatus[ch / chd].frequency , pinsStatus[ch / chd].resolution );
50
- ledcWrite (ch, value);
51
- }
52
- pinsStatus[ch / chd].value = value;
53
- }
54
- }
55
- }
30
+ float awLedcSetup (uint8_t ch, double frequency, uint8_t bits) {
31
+ #if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
32
+ frequency *= 80 ; // workaround for issue 5050
33
+ return ledcSetup (ch, frequency, bits) / 80 ;
34
+ #else // ESP32
35
+ return ledcSetup (ch, frequency, bits);
36
+ #endif
56
37
}
57
38
58
- float analogWriteFrequency (int8_t pin, float frequency) {
59
- int8_t ch = getChannel (pin);
60
- if (ch >= 0 ) {
61
- if ((pinsStatus[ch / chd].pin ) > 47 ) return -1 ;
62
- pinsStatus[ch / chd].pin = pin;
63
- pinsStatus[ch / chd].frequency = frequency;
64
- // ledcChangeFrequency(ch, frequency, pinsStatus[ch / chd].resolution);
65
- ledcSetup (ch, frequency, pinsStatus[ch / chd].resolution );
66
- ledcWrite (ch, pinsStatus[ch / chd].value );
67
- }
68
- return ledcReadFreq (ch);
39
+ void awDetachPin (uint8_t pin, uint8_t ch) {
40
+ pinsStatus[ch / chd].pin = -1 ;
41
+ pinsStatus[ch / chd].value = 0 ;
42
+ pinsStatus[ch / chd].frequency = 980 ;
43
+ pinsStatus[ch / chd].resolution = 8 ;
44
+ pinsStatus[ch / chd].phase = 0 ;
45
+ ledcWrite (ch / chd, 0 );
46
+ ledcSetup (ch / chd, 0 , 0 );
47
+ ledcDetachPin (pinsStatus[ch / chd].pin );
48
+ REG_SET_FIELD (GPIO_PIN_MUX_REG[pin], MCU_SEL, GPIO_MODE_DEF_DISABLE);
69
49
}
70
50
71
- int32_t analogWriteResolution (int8_t pin, uint8_t resolution) {
72
- int8_t ch = getChannel (pin);
73
- if (ch >= 0 ) {
74
- if ((pinsStatus[ch / chd].pin ) > 47 ) return -1 ;
75
- pinsStatus[ch / chd].pin = pin;
76
- pinsStatus[ch / chd].resolution = resolution;
77
- ledcSetup (ch, pinsStatus[ch / chd].frequency , resolution);
78
- ledcWrite (ch, pinsStatus[ch / chd].value );
79
- }
80
- return pow (2 , resolution);
51
+ float awLedcReadFreq (uint8_t ch) {
52
+ #if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
53
+ return ledcReadFreq (ch) / 80 ; // workaround for issue 5050
54
+ #else // ESP32
55
+ return ledcReadFreq (ch);
56
+ #endif
81
57
}
82
58
83
- int8_t getChannel (int8_t pin) {
59
+ int8_t awGetChannel (int8_t pin) {
84
60
if (!((pinMask >> pin) & 1 )) return -1 ; // not pwm pin
85
61
for (int8_t i = 0 ; i < 8 ; i++) {
86
62
int8_t ch = pinsStatus[i].channel ;
@@ -95,6 +71,7 @@ int8_t getChannel(int8_t pin) {
95
71
if (pinsStatus[ch / chd].pin == -1 ) { // free channel
96
72
if ((ledcRead (ch) < 1 ) && (ledcReadFreq (ch) < 1 )) { // free timer
97
73
pinsStatus[ch / chd].pin = pin;
74
+ aw::awLedcSetup (ch, pinsStatus[ch / chd].frequency , pinsStatus[ch / chd].resolution );
98
75
ledcAttachPin (pin, ch);
99
76
return ch;
100
77
break ;
@@ -112,38 +89,205 @@ int8_t getChannel(int8_t pin) {
112
89
return -1 ;
113
90
}
114
91
92
+ } // namespace aw
93
+
94
+ float analogWrite (int8_t pin, int32_t value) {
95
+ if (pin == DAC1 || pin == DAC2) { // dac
96
+ if (value > 255 ) value = 255 ;
97
+ dacWrite (pin, value);
98
+ } else {
99
+ int8_t ch = aw::awGetChannel (pin);
100
+ if (ch >= 0 ) {
101
+ if (value == -1 ) aw::awDetachPin (pin, ch);
102
+ else { // write PWM
103
+ uint8_t bits = aw::pinsStatus[ch / aw::chd].resolution ;
104
+ if (value > ((1 << bits) - 1 )) value = (1 << bits); // constrain
105
+ if ((bits > 7 ) && (value == ((1 << bits) - 1 ))) value = (1 << bits); // keep PWM high
106
+ if (ledcRead (ch) != value) ledcWrite (ch, value);
107
+ aw::pinsStatus[ch / aw::chd].value = value;
108
+ }
109
+ }
110
+ return aw::awLedcReadFreq (ch);
111
+ }
112
+ return 0 ;
113
+ }
114
+
115
+ float analogWrite (int8_t pin, int32_t value, float frequency) {
116
+ if (pin == DAC1 || pin == DAC2) { // dac
117
+ if (value > 255 ) value = 255 ;
118
+ dacWrite (pin, value);
119
+ } else {
120
+ int8_t ch = aw::awGetChannel (pin);
121
+ if (ch >= 0 ) {
122
+ if ((aw::pinsStatus[ch / aw::chd].pin ) > 47 ) return -1 ;
123
+ if (value == -1 ) aw::awDetachPin (pin, ch);
124
+ else { // write PWM
125
+ uint8_t bits = aw::pinsStatus[ch / aw::chd].resolution ;
126
+ if (value > ((1 << bits) - 1 )) value = (1 << bits); // constrain
127
+ if ((bits > 7 ) && (value == ((1 << bits) - 1 ))) value = (1 << bits); // keep PWM high
128
+ if (aw::pinsStatus[ch / aw::chd].frequency != frequency) {
129
+ aw::awLedcSetup (ch, frequency, bits);
130
+ ledcWrite (ch, value);
131
+ aw::pinsStatus[ch / aw::chd].frequency = frequency;
132
+ }
133
+ if (aw::pinsStatus[ch / aw::chd].value != value) {
134
+ ledcWrite (ch, value);
135
+ aw::pinsStatus[ch / aw::chd].value = value;
136
+ }
137
+ }
138
+ }
139
+ return aw::awLedcReadFreq (ch);
140
+ }
141
+ return 0 ;
142
+ }
143
+
144
+ float analogWrite (int8_t pin, int32_t value, float frequency, uint8_t resolution) {
145
+ if (pin == DAC1 || pin == DAC2) { // dac
146
+ if (value > 255 ) value = 255 ;
147
+ dacWrite (pin, value);
148
+ } else {
149
+ int8_t ch = aw::awGetChannel (pin);
150
+ if (ch >= 0 ) {
151
+ if ((aw::pinsStatus[ch / aw::chd].pin ) > 47 ) return -1 ;
152
+ if (value == -1 ) aw::awDetachPin (pin, ch);
153
+ else { // write PWM
154
+ uint8_t bits = resolution & 0xF ;
155
+ if (value > ((1 << bits) - 1 )) value = (1 << bits); // constrain
156
+ if ((bits > 7 ) && (value == ((1 << bits) - 1 ))) value = (1 << bits); // keep PWM high
157
+ if ((aw::pinsStatus[ch / aw::chd].frequency != frequency) || (aw::pinsStatus[ch / aw::chd].resolution != bits)) {
158
+ aw::awLedcSetup (ch, frequency, bits);
159
+ ledcWrite (ch, value);
160
+ aw::pinsStatus[ch / aw::chd].frequency = frequency;
161
+ aw::pinsStatus[ch / aw::chd].resolution = bits;
162
+ }
163
+ if (aw::pinsStatus[ch / aw::chd].value != value) {
164
+ ledcWrite (ch, value);
165
+ aw::pinsStatus[ch / aw::chd].value = value;
166
+ }
167
+ }
168
+ }
169
+ return aw::awLedcReadFreq (ch);
170
+ }
171
+ return 0 ;
172
+ }
173
+
174
+ float analogWrite (int8_t pin, int32_t value, float frequency, uint8_t resolution, uint32_t phase) {
175
+ if (pin == DAC1 || pin == DAC2) { // dac
176
+ if (value > 255 ) value = 255 ;
177
+ dacWrite (pin, value);
178
+ } else {
179
+ int8_t ch = aw::awGetChannel (pin);
180
+ if (ch >= 0 ) {
181
+ if ((aw::pinsStatus[ch / aw::chd].pin ) > 47 ) return -1 ;
182
+ if (value == -1 ) aw::awDetachPin (pin, ch);
183
+ else { // write PWM
184
+ uint8_t bits = resolution & 0xF ;
185
+ if (value > ((1 << bits) - 1 )) value = (1 << bits); // constrain
186
+ if ((bits > 7 ) && (value == ((1 << bits) - 1 ))) value = (1 << bits); // keep PWM high
187
+ if ((aw::pinsStatus[ch / aw::chd].frequency != frequency) || (aw::pinsStatus[ch / aw::chd].resolution != bits)) {
188
+ aw::awLedcSetup (ch, frequency, bits);
189
+ ledcWrite (ch, value);
190
+ aw::pinsStatus[ch / aw::chd].frequency = frequency;
191
+ aw::pinsStatus[ch / aw::chd].resolution = bits;
192
+ }
193
+ if (aw::pinsStatus[ch / aw::chd].phase != phase) {
194
+ uint32_t group = (ch / 8 ), timer = ((ch / 2 ) % 4 );
195
+ aw::ledc_channel_config_t ledc_channel {
196
+ (uint8_t )pin,
197
+ (aw::ledc_mode_t )group,
198
+ (aw::ledc_channel_t )ch,
199
+ aw::LEDC_INTR_DISABLE,
200
+ (aw::ledc_timer_t )timer,
201
+ (uint32_t )value,
202
+ (int )phase,
203
+ };
204
+ ledc_channel_config (&ledc_channel);
205
+ ledc_set_duty_with_hpoint ((aw::ledc_mode_t )group, (aw::ledc_channel_t )ch, value, phase);
206
+ aw::pinsStatus[ch / aw::chd].phase = phase;
207
+ }
208
+ if (aw::pinsStatus[ch / aw::chd].value != value) {
209
+ ledcWrite (ch, value);
210
+ aw::pinsStatus[ch / aw::chd].value = value;
211
+ }
212
+ }
213
+ }
214
+ return aw::awLedcReadFreq (ch);
215
+ }
216
+ return 0 ;
217
+ }
218
+
219
+ float analogWriteFrequency (int8_t pin, float frequency) {
220
+ int8_t ch = aw::awGetChannel (pin);
221
+ if (ch >= 0 ) {
222
+ if ((aw::pinsStatus[ch / aw::chd].pin ) > 47 ) return -1 ;
223
+ if (aw::pinsStatus[ch / aw::chd].frequency != frequency) {
224
+ aw::awLedcSetup (ch, frequency, aw::pinsStatus[ch / aw::chd].resolution );
225
+ ledcWrite (ch, aw::pinsStatus[ch / aw::chd].value );
226
+ aw::pinsStatus[ch / aw::chd].frequency = frequency;
227
+ }
228
+ }
229
+ return aw::awLedcReadFreq (ch);
230
+ }
231
+
232
+ int32_t analogWriteResolution (int8_t pin, uint8_t resolution) {
233
+ int8_t ch = aw::awGetChannel (pin);
234
+ if (ch >= 0 ) {
235
+ if ((aw::pinsStatus[ch / aw::chd].pin ) > 47 ) return -1 ;
236
+ if (aw::pinsStatus[ch / aw::chd].resolution != resolution) {
237
+ aw::awLedcSetup (ch, aw::pinsStatus[ch / aw::chd].frequency , resolution & 0xF );
238
+ ledcWrite (ch, aw::pinsStatus[ch / aw::chd].value );
239
+ aw::pinsStatus[ch / aw::chd].resolution = resolution & 0xF ;
240
+ }
241
+ }
242
+ return 1 << resolution & 0xF ;
243
+ }
244
+
245
+ void setPinsStatusDefaults (int32_t value, float frequency, uint8_t resolution, uint32_t phase) {
246
+ for (int8_t i = 0 ; i < 8 ; i++) {
247
+ aw::pinsStatus[i].value = value;
248
+ aw::pinsStatus[i].frequency = frequency;
249
+ aw::pinsStatus[i].resolution = resolution;
250
+ aw::pinsStatus[i].phase = phase;
251
+ }
252
+ }
253
+
115
254
void printPinsStatus () {
116
255
Serial.print (" PWM pins: " );
117
- for (int i = 0 ; i < muxSize; i++) {
118
- if ((pinMask >> i) & 1 ) {
256
+ for (int i = 0 ; i < aw:: muxSize; i++) {
257
+ if ((aw:: pinMask >> i) & 1 ) {
119
258
Serial.print (i); Serial.print (" , " );
120
259
}
121
260
}
122
261
Serial.println ();
123
262
124
263
Serial.println ();
125
264
for (int i = 0 ; i < 8 ; i++) {
126
- int ch = pinsStatus[i].channel ;
265
+ int ch = aw:: pinsStatus[i].channel ;
127
266
Serial.print (" ch: " );
128
267
if (ch < 10 ) Serial.print (" " ); Serial.print (ch); Serial.print (" " );
129
268
Serial.print (" Pin: " );
130
- if ((pinsStatus[ch / chd].pin >= 0 ) && (pinsStatus[ch / chd].pin < 10 )) Serial.print (" " );
131
- Serial.print (pinsStatus[ch / chd].pin ); Serial.print (" " );
269
+ if ((aw:: pinsStatus[ch / aw:: chd].pin >= 0 ) && (aw:: pinsStatus[ch / aw:: chd].pin < 10 )) Serial.print (" " );
270
+ Serial.print (aw:: pinsStatus[ch / aw:: chd].pin ); Serial.print (" " );
132
271
Serial.print (" Hz: " );
133
- if (ledcReadFreq (ch) < 10000 ) Serial.print (" " );
134
- if (ledcReadFreq (ch) < 1000 ) Serial.print (" " );
135
- if (ledcReadFreq (ch) < 100 ) Serial.print (" " );
136
- if (ledcReadFreq (ch) < 10 ) Serial.print (" " );
137
- Serial.print (ledcReadFreq (ch)); Serial.print (" " );
272
+ if (aw::awLedcReadFreq (ch) < 10000 ) Serial.print (" " );
273
+ if (aw::awLedcReadFreq (ch) < 1000 ) Serial.print (" " );
274
+ if (aw::awLedcReadFreq (ch) < 100 ) Serial.print (" " );
275
+ if (aw::awLedcReadFreq (ch) < 10 ) Serial.print (" " );
276
+ Serial.print (aw::awLedcReadFreq (ch)); Serial.print (" " );
138
277
Serial.print (" Bits: " );
139
- if (pinsStatus[ch / chd].resolution < 10 ) Serial.print (" " );
140
- Serial.print (pinsStatus[ch / chd].resolution ); Serial.print (" " );
278
+ if (aw:: pinsStatus[ch / aw:: chd].resolution < 10 ) Serial.print (" " );
279
+ Serial.print (aw:: pinsStatus[ch / aw:: chd].resolution ); Serial.print (" " );
141
280
Serial.print (" Duty: " );
142
- if (pinsStatus[ch / chd].value < 10000 ) Serial.print (" " );
143
- if (pinsStatus[ch / chd].value < 1000 ) Serial.print (" " );
144
- if (pinsStatus[ch / chd].value < 100 ) Serial.print (" " );
145
- if (pinsStatus[ch / chd].value < 10 ) Serial.print (" " );
146
- Serial.print (pinsStatus[ch / chd].value );
281
+ if (aw::pinsStatus[ch / aw::chd].value < 10000 ) Serial.print (" " );
282
+ if (aw::pinsStatus[ch / aw::chd].value < 1000 ) Serial.print (" " );
283
+ if (aw::pinsStatus[ch / aw::chd].value < 100 ) Serial.print (" " );
284
+ if (aw::pinsStatus[ch / aw::chd].value < 10 ) Serial.print (" " );
285
+ Serial.print (aw::pinsStatus[ch / aw::chd].value ); Serial.print (" " );
286
+ Serial.print (" Ø: " );
287
+ if (aw::pinsStatus[ch / aw::chd].phase < 1000 ) Serial.print (" " );
288
+ if (aw::pinsStatus[ch / aw::chd].phase < 100 ) Serial.print (" " );
289
+ if (aw::pinsStatus[ch / aw::chd].phase < 10 ) Serial.print (" " );
290
+ Serial.print (aw::pinsStatus[ch / aw::chd].phase );
147
291
Serial.println ();
148
292
}
149
293
}
0 commit comments