11/* *********************************************************************************
2- AnalogWrite Library for ESP32-ESP32S2 Arduino core - Version 1.1.0
2+ AnalogWrite Library for ESP32-ESP32S2 Arduino core - Version 2.0.6
33 by dlloydev https://github.com/Dlloydev/ESP32-ESP32S2-AnalogWrite
44 This Library is licensed under the MIT License
55 **********************************************************************************/
66
77#include < Arduino.h>
88#include " analogWrite.h"
99
10+ namespace aw {
11+
1012#if (CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3)
1113pinStatus_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 }
1618};
1719const uint8_t chd = 1 ;
1820#else // ESP32
1921pinStatus_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 }
2426};
2527const uint8_t chd = 2 ;
2628#endif
2729
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
5637}
5738
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);
6949}
7050
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
8157}
8258
83- int8_t getChannel (int8_t pin) {
59+ int8_t awGetChannel (int8_t pin) {
8460 if (!((pinMask >> pin) & 1 )) return -1 ; // not pwm pin
8561 for (int8_t i = 0 ; i < 8 ; i++) {
8662 int8_t ch = pinsStatus[i].channel ;
@@ -95,6 +71,7 @@ int8_t getChannel(int8_t pin) {
9571 if (pinsStatus[ch / chd].pin == -1 ) { // free channel
9672 if ((ledcRead (ch) < 1 ) && (ledcReadFreq (ch) < 1 )) { // free timer
9773 pinsStatus[ch / chd].pin = pin;
74+ aw::awLedcSetup (ch, pinsStatus[ch / chd].frequency , pinsStatus[ch / chd].resolution );
9875 ledcAttachPin (pin, ch);
9976 return ch;
10077 break ;
@@ -112,38 +89,205 @@ int8_t getChannel(int8_t pin) {
11289 return -1 ;
11390}
11491
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+
115254void printPinsStatus () {
116255 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 ) {
119258 Serial.print (i); Serial.print (" , " );
120259 }
121260 }
122261 Serial.println ();
123262
124263 Serial.println ();
125264 for (int i = 0 ; i < 8 ; i++) {
126- int ch = pinsStatus[i].channel ;
265+ int ch = aw:: pinsStatus[i].channel ;
127266 Serial.print (" ch: " );
128267 if (ch < 10 ) Serial.print (" " ); Serial.print (ch); Serial.print (" " );
129268 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 (" " );
132271 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 (" " );
138277 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 (" " );
141280 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 );
147291 Serial.println ();
148292 }
149293}
0 commit comments