From e1b825ed75dd7e488fa816a0f68391b29b08b4b8 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 2 Aug 2020 12:40:15 +0200 Subject: [PATCH] Fix ESP32 PWM resolution calculation --- .../src/esp8266toEsp32.h | 64 ++++++++++--------- tasmota/support_tasmota.ino | 8 +-- tasmota/xdrv_04_light.ino | 5 ++ tasmota/xlgt_03_sm16716.ino | 5 ++ 4 files changed, 48 insertions(+), 34 deletions(-) diff --git a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h index 90e2460b3..b9876ac15 100644 --- a/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h +++ b/libesp32/ESP32-to-ESP8266-compat/src/esp8266toEsp32.h @@ -28,16 +28,23 @@ #include +/*********************************************************************************************\ + * ESP32 analogWrite support +\*********************************************************************************************/ -// webcam uses channel 0, so we offset standard PWM -#define PWM_CHANNEL_OFFSET 2 -// Analog +#define PWM_SUPPORTED_CHANNELS 8 +#define PWM_CHANNEL_OFFSET 2 // Webcam uses channel 0, so we offset standard PWM -uint8_t pwm_channel[8]={99,99,99,99,99,99,99,99}; +uint8_t _pwm_channel[PWM_SUPPORTED_CHANNELS] = { 99, 99, 99, 99, 99, 99, 99, 99 }; -inline uint32_t pin2chan(uint32_t pin) { - for (uint32_t cnt=0;cnt<8;cnt++) { - if ((pwm_channel[cnt]<99) && (pwm_channel[cnt]==pin)) { +inline void analogWriteFreq(uint32_t freq) { +} +inline void analogWriteRange(uint32_t range) { +} + +inline uint32_t _analog_pin2chan(uint32_t pin) { + for (uint32_t cnt = 0; cnt < PWM_SUPPORTED_CHANNELS; cnt++) { + if ((_pwm_channel[cnt] < 99) && (_pwm_channel[cnt] == pin)) { return cnt; } } @@ -46,43 +53,40 @@ inline uint32_t pin2chan(uint32_t pin) { inline void analogWrite(uint8_t pin, int val) { - uint32_t channel=pin2chan(pin); - ledcWrite(channel+PWM_CHANNEL_OFFSET,val); - //Serial.printf("write %d - %d\n",channel,val); -} - -inline void analogWriteFreq(uint32_t freq) -{ -} -inline void analogWriteRange(uint32_t range) -{ + uint32_t channel = _analog_pin2chan(pin); + ledcWrite(channel + PWM_CHANNEL_OFFSET, val); +// Serial.printf("write %d - %d\n",channel,val); } inline void analogAttach(uint32_t pin, uint32_t channel) { - pwm_channel[channel&7]=pin; - ledcAttachPin(pin,channel+PWM_CHANNEL_OFFSET); - //Serial.printf("attach %d - %d\n",channel,pin); + _pwm_channel[channel &7] = pin; + ledcAttachPin(pin, channel + PWM_CHANNEL_OFFSET); +// Serial.printf("attach %d - %d\n",channel,pin); } -inline uint32_t pow2(uint32_t x) { -uint32_t power = 1,bits=0; +inline uint32_t _analog_pow2(uint32_t x) { + uint32_t power = 1; + uint32_t bits = 0; while (power < x) { - power*=2; + power *= 2; bits++; } - return bits-1; + return bits; } + // input range is in full range, ledc needs bits -inline void analogWriteFreqRange(uint32_t channel,uint32_t freq, uint32_t irange) { - uint32_t range=pow2(irange); - for (uint32_t cnt=0;cnt<8;cnt++) { - if (pwm_channel[cnt]<99) { - ledcSetup(cnt+PWM_CHANNEL_OFFSET,freq,range); +inline void analogWriteFreqRange(uint32_t channel, uint32_t freq, uint32_t irange) { + uint32_t range = _analog_pow2(irange); + for (uint32_t cnt = 0; cnt < PWM_SUPPORTED_CHANNELS; cnt++) { + if (_pwm_channel[cnt] < 99) { + ledcSetup(cnt + PWM_CHANNEL_OFFSET, freq, range); } } - //Serial.printf("freq - range %d - %d\n",freq,range); +// Serial.printf("freq - range %d - %d\n",freq,range); } +/*********************************************************************************************/ + #define INPUT_PULLDOWN_16 INPUT_PULLUP typedef double real64_t; diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino index 9007d0157..6b0dd6f4e 100644 --- a/tasmota/support_tasmota.ino +++ b/tasmota/support_tasmota.ino @@ -1686,12 +1686,12 @@ void GpioInit(void) for (uint32_t i = 0; i < MAX_PWMS; i++) { // Basic PWM control only if (PinUsed(GPIO_PWM1, i)) { +#ifdef ESP8266 pinMode(Pin(GPIO_PWM1, i), OUTPUT); -#ifdef ESP32 - analogAttach(Pin(GPIO_PWM1, i),i); - analogWriteFreqRange(i,Settings.pwm_frequency,Settings.pwm_range); +#else // ESP32 + analogAttach(Pin(GPIO_PWM1, i), i); + analogWriteFreqRange(i, Settings.pwm_frequency, Settings.pwm_range); #endif - if (light_type) { // force PWM GPIOs to low or high mode, see #7165 analogWrite(Pin(GPIO_PWM1, i), bitRead(pwm_inverted, i) ? Settings.pwm_range : 0); diff --git a/tasmota/xdrv_04_light.ino b/tasmota/xdrv_04_light.ino index 18881d119..97a09a806 100644 --- a/tasmota/xdrv_04_light.ino +++ b/tasmota/xdrv_04_light.ino @@ -1351,7 +1351,12 @@ void LightInit(void) for (uint32_t i = 0; i < light_type; i++) { Settings.pwm_value[i] = 0; // Disable direct PWM control if (PinUsed(GPIO_PWM1, i)) { +#ifdef ESP8266 pinMode(Pin(GPIO_PWM1, i), OUTPUT); +#else // ESP32 + analogAttach(Pin(GPIO_PWM1, i), i); + analogWriteFreqRange(i, Settings.pwm_frequency, Settings.pwm_range); +#endif } } if (PinUsed(GPIO_ARIRFRCV)) { diff --git a/tasmota/xlgt_03_sm16716.ino b/tasmota/xlgt_03_sm16716.ino index 314122a8b..81e38996f 100644 --- a/tasmota/xlgt_03_sm16716.ino +++ b/tasmota/xlgt_03_sm16716.ino @@ -148,7 +148,12 @@ void Sm16716ModuleSelected(void) for (uint32_t i = 0; i < Light.subtype; i++) { Settings.pwm_value[i] = 0; // Disable direct PWM control if (PinUsed(GPIO_PWM1, i)) { +#ifdef ESP8266 pinMode(Pin(GPIO_PWM1, i), OUTPUT); +#else // ESP32 + analogAttach(Pin(GPIO_PWM1, i), i); + analogWriteFreqRange(i, Settings.pwm_frequency, Settings.pwm_range); +#endif } } */