From f2273ef63bb97f67871583f8c016bc816fc9f1d3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Procha=CC=81zka?=
 <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Date: Wed, 12 Oct 2022 13:00:06 +0200
Subject: [PATCH 1/5] channel keeps duty after pin attach

---
 cores/esp32/esp32-hal-ledc.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/cores/esp32/esp32-hal-ledc.c b/cores/esp32/esp32-hal-ledc.c
index 014b08125f6..c7566387afa 100644
--- a/cores/esp32/esp32-hal-ledc.c
+++ b/cores/esp32/esp32-hal-ledc.c
@@ -166,14 +166,15 @@ void ledcAttachPin(uint8_t pin, uint8_t chan)
         return;
     }
     uint8_t group=(chan/8), channel=(chan%8), timer=((chan/2)%4);
-    
+    uint32_t duty = ledc_get_duty(group,channel);
+
     ledc_channel_config_t ledc_channel = {
         .speed_mode     = group,
         .channel        = channel,
         .timer_sel      = timer,
         .intr_type      = LEDC_INTR_DISABLE,
         .gpio_num       = pin,
-        .duty           = 0,
+        .duty           = duty,
         .hpoint         = 0
     };
     ledc_channel_config(&ledc_channel);

From e086ce4b6da4ad89cc60691aa27bd90cce216b58 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Procha=CC=81zka?=
 <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Date: Wed, 12 Oct 2022 15:57:52 +0200
Subject: [PATCH 2/5] new analogWrite API for freq and resolution

---
 cores/esp32/esp32-hal-ledc.c | 24 +++++++++++++++++++++++-
 cores/esp32/esp32-hal.h      |  2 ++
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/cores/esp32/esp32-hal-ledc.c b/cores/esp32/esp32-hal-ledc.c
index c7566387afa..2d10a0d5e07 100644
--- a/cores/esp32/esp32-hal-ledc.c
+++ b/cores/esp32/esp32-hal-ledc.c
@@ -212,6 +212,8 @@ uint32_t ledcChangeFrequency(uint8_t chan, uint32_t freq, uint8_t bit_num)
 
 static int8_t pin_to_channel[SOC_GPIO_PIN_COUNT] = { 0 };
 static int cnt_channel = LEDC_CHANNELS;
+static uint8_t analog_resolution = 8;
+static int analog_frequency = 1000;
 void analogWrite(uint8_t pin, int value) {
   // Use ledc hardware for internal pins
   if (pin < SOC_GPIO_PIN_COUNT) {
@@ -221,8 +223,8 @@ void analogWrite(uint8_t pin, int value) {
           return;
       }
       pin_to_channel[pin] = cnt_channel--;
+      ledcSetup(cnt_channel, analog_frequency, analog_resolution);
       ledcAttachPin(pin, cnt_channel);
-      ledcSetup(cnt_channel, 1000, 8);
     }
     ledcWrite(pin_to_channel[pin] - 1, value);
   }
@@ -231,3 +233,23 @@ void analogWrite(uint8_t pin, int value) {
 int8_t analogGetChannel(uint8_t pin) {
     return pin_to_channel[pin] - 1;
 }
+
+void analogWriteFrequency(uint32_t freq) {
+    if (cnt_channel == LEDC_CHANNELS) {
+        return; //No channel used for analogWrite
+    }
+    for (int channel = 15; channel >= cnt_channel; channel--) {
+        ledcChangeFrequency(channel, freq, analog_resolution);
+    }
+    analog_frequency = freq;
+}
+
+void analogWriteResolution(uint8_t bits) {
+    if (cnt_channel == LEDC_CHANNELS) {
+        return; //No channel used for analogWrite
+    }
+    for (int channel = 15; channel >= cnt_channel; channel--) {
+        ledcChangeFrequency(channel, analog_frequency, bits);
+    }
+    analog_resolution = bits;
+}
diff --git a/cores/esp32/esp32-hal.h b/cores/esp32/esp32-hal.h
index 59dca98cbb9..51ecea405df 100644
--- a/cores/esp32/esp32-hal.h
+++ b/cores/esp32/esp32-hal.h
@@ -93,6 +93,8 @@ void yield(void);
 
 void analogWrite(uint8_t pin, int value);
 int8_t analogGetChannel(uint8_t pin);
+void analogWriteFrequency(uint32_t freq);
+void analogWriteResolution(uint8_t bits);
 
 //returns chip temperature in Celsius
 float temperatureRead();

From 397e745bf799b1a9936890142afb8b95e418c6e4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Procha=CC=81zka?=
 <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Date: Wed, 12 Oct 2022 16:06:24 +0200
Subject: [PATCH 3/5] fix ledc channels number

---
 cores/esp32/esp32-hal-ledc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cores/esp32/esp32-hal-ledc.c b/cores/esp32/esp32-hal-ledc.c
index 2d10a0d5e07..ee03a63efad 100644
--- a/cores/esp32/esp32-hal-ledc.c
+++ b/cores/esp32/esp32-hal-ledc.c
@@ -238,7 +238,7 @@ void analogWriteFrequency(uint32_t freq) {
     if (cnt_channel == LEDC_CHANNELS) {
         return; //No channel used for analogWrite
     }
-    for (int channel = 15; channel >= cnt_channel; channel--) {
+    for (int channel = LEDC_CHANNELS - 1; channel >= cnt_channel; channel--) {
         ledcChangeFrequency(channel, freq, analog_resolution);
     }
     analog_frequency = freq;
@@ -248,7 +248,7 @@ void analogWriteResolution(uint8_t bits) {
     if (cnt_channel == LEDC_CHANNELS) {
         return; //No channel used for analogWrite
     }
-    for (int channel = 15; channel >= cnt_channel; channel--) {
+    for (int channel = LEDC_CHANNELS - 1; channel >= cnt_channel; channel--) {
         ledcChangeFrequency(channel, analog_frequency, bits);
     }
     analog_resolution = bits;

From 760b77a4b032cd35eacfa043946c3f13ec6f1088 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Procha=CC=81zka?=
 <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Date: Thu, 10 Nov 2022 14:22:29 +0100
Subject: [PATCH 4/5] Add check for resolution and set if no analogWrite called

---
 cores/esp32/esp32-hal-ledc.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/cores/esp32/esp32-hal-ledc.c b/cores/esp32/esp32-hal-ledc.c
index ee03a63efad..f6d74ba10fe 100644
--- a/cores/esp32/esp32-hal-ledc.c
+++ b/cores/esp32/esp32-hal-ledc.c
@@ -235,21 +235,23 @@ int8_t analogGetChannel(uint8_t pin) {
 }
 
 void analogWriteFrequency(uint32_t freq) {
-    if (cnt_channel == LEDC_CHANNELS) {
-        return; //No channel used for analogWrite
-    }
-    for (int channel = LEDC_CHANNELS - 1; channel >= cnt_channel; channel--) {
-        ledcChangeFrequency(channel, freq, analog_resolution);
+    if (cnt_channel != LEDC_CHANNELS) {
+        for (int channel = LEDC_CHANNELS - 1; channel >= cnt_channel; channel--) {
+            ledcChangeFrequency(channel, freq, analog_resolution);
+        }
     }
     analog_frequency = freq;
 }
 
 void analogWriteResolution(uint8_t bits) {
-    if (cnt_channel == LEDC_CHANNELS) {
-        return; //No channel used for analogWrite
+    if(bits > LEDC_MAX_BIT_WIDTH) {
+        log_e("AnalogWrite resoluion width too big (maximum %u bits)", LEDC_MAX_BIT_WIDTH);
+        return;
     }
-    for (int channel = LEDC_CHANNELS - 1; channel >= cnt_channel; channel--) {
-        ledcChangeFrequency(channel, analog_frequency, bits);
+    if (cnt_channel != LEDC_CHANNELS) {
+        for (int channel = LEDC_CHANNELS - 1; channel >= cnt_channel; channel--) {
+            ledcChangeFrequency(channel, analog_frequency, bits);
+        }
     }
     analog_resolution = bits;
 }

From f5fdda6e2e2ca6827545756526014784a8ee799e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Procha=CC=81zka?=
 <90197375+P-R-O-C-H-Y@users.noreply.github.com>
Date: Thu, 10 Nov 2022 14:27:59 +0100
Subject: [PATCH 5/5] trim bits to maximum

---
 cores/esp32/esp32-hal-ledc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cores/esp32/esp32-hal-ledc.c b/cores/esp32/esp32-hal-ledc.c
index f6d74ba10fe..4b58c1d9a91 100644
--- a/cores/esp32/esp32-hal-ledc.c
+++ b/cores/esp32/esp32-hal-ledc.c
@@ -245,8 +245,8 @@ void analogWriteFrequency(uint32_t freq) {
 
 void analogWriteResolution(uint8_t bits) {
     if(bits > LEDC_MAX_BIT_WIDTH) {
-        log_e("AnalogWrite resoluion width too big (maximum %u bits)", LEDC_MAX_BIT_WIDTH);
-        return;
+        log_w("analogWrite resolution width too big! Setting to maximum %u bits)", LEDC_MAX_BIT_WIDTH);
+        bits = LEDC_MAX_BIT_WIDTH;
     }
     if (cnt_channel != LEDC_CHANNELS) {
         for (int channel = LEDC_CHANNELS - 1; channel >= cnt_channel; channel--) {