From 973fcf00fb3ccf0b4c1f4eae8b32f432b2d28ef7 Mon Sep 17 00:00:00 2001
From: me-no-dev <hristo@espressif.com>
Date: Mon, 8 Nov 2021 15:56:34 +0200
Subject: [PATCH] Add basic analogWrite support

---
 cores/esp32/esp32-hal-ledc.c | 19 +++++++++++++++++++
 cores/esp32/esp32-hal.h      |  2 ++
 2 files changed, 21 insertions(+)

diff --git a/cores/esp32/esp32-hal-ledc.c b/cores/esp32/esp32-hal-ledc.c
index 102e5bbb0e2..4e20e7b8bd4 100644
--- a/cores/esp32/esp32-hal-ledc.c
+++ b/cores/esp32/esp32-hal-ledc.c
@@ -17,6 +17,7 @@
 #include "freertos/task.h"
 #include "freertos/semphr.h"
 #include "esp32-hal-matrix.h"
+#include "soc/soc_caps.h"
 #include "soc/ledc_reg.h"
 #include "soc/ledc_struct.h"
 #include "driver/periph_ctrl.h"
@@ -331,3 +332,21 @@ double ledcChangeFrequency(uint8_t chan, double freq, uint8_t bit_num)
     double res_freq = _ledcSetupTimerFreq(chan, freq, bit_num);
     return res_freq;
 }
+
+static int8_t pin_to_channel[SOC_GPIO_PIN_COUNT] = { 0 };
+static int cnt_channel = SOC_LEDC_CHANNEL_NUM;
+void analogWrite(uint8_t pin, int value) {
+  // Use ledc hardware for internal pins
+  if (pin < SOC_GPIO_PIN_COUNT) {
+    if (pin_to_channel[pin] == 0) {
+      if (!cnt_channel) {
+          log_e("No more analogWrite channels available! You can have maximum %u", SOC_LEDC_CHANNEL_NUM);
+          return;
+      }
+      pin_to_channel[pin] = cnt_channel--;
+      ledcAttachPin(pin, cnt_channel);
+      ledcSetup(cnt_channel, 1000, 8);
+    }
+    ledcWrite(pin_to_channel[pin] - 1, value);
+  }
+}
diff --git a/cores/esp32/esp32-hal.h b/cores/esp32/esp32-hal.h
index 3efead522dd..115a050b172 100644
--- a/cores/esp32/esp32-hal.h
+++ b/cores/esp32/esp32-hal.h
@@ -90,6 +90,8 @@ void yield(void);
 #include "esp32-hal-psram.h"
 #include "esp32-hal-cpu.h"
 
+void analogWrite(uint8_t pin, int value);
+
 //returns chip temperature in Celsius
 float temperatureRead();