From 5c247d283357895a56e51379eff07dc9a97703bf Mon Sep 17 00:00:00 2001 From: PaoloTK Date: Thu, 1 Aug 2024 20:25:18 +0200 Subject: [PATCH 1/4] first implementation --- wled00/bus_manager.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index 7aa3351cf3..9e16e4458a 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -40,6 +40,19 @@ uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, byte #define DEBUG_PRINTF_P(x...) #endif +// ESP8266 has 1 MHz clock +#ifdef ESP8266 + #define CLOCK_FREQUENCY 1e6f +#else + // Use XTAL clock if possible to avoid timer frequency error when setting APB clock < 80 Mhz + // https://github.com/espressif/arduino-esp32/blob/2.0.2/cores/esp32/esp32-hal-ledc.c + #ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK + #define CLOCK_FREQUENCY 40e6f + #else + #define CLOCK_FREQUENCY 80e6f + #endif +#endif + //color mangling macros #define RGBW32(r,g,b,w) (uint32_t((byte(w) << 24) | (byte(r) << 16) | (byte(g) << 8) | (byte(b)))) #define R(c) (byte((c) >> 16)) @@ -384,12 +397,10 @@ BusPwm::BusPwm(BusConfig &bc) if (!IS_PWM(bc.type)) return; unsigned numPins = NUM_PWM_PINS(bc.type); _frequency = bc.frequency ? bc.frequency : WLED_PWM_FREQ; + // duty cycle resolution (_depth) can be extracted from this formula: CLOCK_FREQUENCY > _frequency * 2^_depth + _depth = uint8_t(log((float)CLOCK_FREQUENCY / (float)_frequency) / log(2.0)); #ifdef ESP8266 - // duty cycle resolution (_depth) can be extracted from this formula: 1MHz > _frequency * 2^_depth - if (_frequency > 1760) _depth = 8; - else if (_frequency > 880) _depth = 9; - else _depth = 10; // WLED_PWM_FREQ <= 880Hz analogWriteRange((1<<_depth)-1); analogWriteFreq(_frequency); #else @@ -397,11 +408,6 @@ BusPwm::BusPwm(BusConfig &bc) if (_ledcStart == 255) { //no more free LEDC channels deallocatePins(); return; } - // duty cycle resolution (_depth) can be extracted from this formula: 80MHz > _frequency * 2^_depth - if (_frequency > 78124) _depth = 9; - else if (_frequency > 39062) _depth = 10; - else if (_frequency > 19531) _depth = 11; - else _depth = 12; // WLED_PWM_FREQ <= 19531Hz #endif for (unsigned i = 0; i < numPins; i++) { @@ -419,7 +425,7 @@ BusPwm::BusPwm(BusConfig &bc) } _data = _pwmdata; // avoid malloc() and use stack _valid = true; - DEBUG_PRINTF_P(PSTR("%successfully inited PWM strip with type %u and pins %u,%u,%u,%u,%u\n"), _valid?"S":"Uns", bc.type, _pins[0], _pins[1], _pins[2], _pins[3], _pins[4]); + DEBUG_PRINTF_P(PSTR("%successfully inited PWM strip with type %u, frequency %u, bit depth %u and pins %u,%u,%u,%u,%u\n"), _valid?"S":"Uns", bc.type, _frequency, _depth, _pins[0], _pins[1], _pins[2], _pins[3], _pins[4]); } void BusPwm::setPixelColor(uint16_t pix, uint32_t c) { From 1123d85fd2f828fdcfe4afc911bd7d0c91ac3249 Mon Sep 17 00:00:00 2001 From: PaoloTK Date: Sat, 3 Aug 2024 15:54:39 +0200 Subject: [PATCH 2/4] removed float math and log(), added max bit width --- wled00/bus_manager.cpp | 15 +-------------- wled00/const.h | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index 9e16e4458a..e626a29629 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -40,19 +40,6 @@ uint8_t realtimeBroadcast(uint8_t type, IPAddress client, uint16_t length, byte #define DEBUG_PRINTF_P(x...) #endif -// ESP8266 has 1 MHz clock -#ifdef ESP8266 - #define CLOCK_FREQUENCY 1e6f -#else - // Use XTAL clock if possible to avoid timer frequency error when setting APB clock < 80 Mhz - // https://github.com/espressif/arduino-esp32/blob/2.0.2/cores/esp32/esp32-hal-ledc.c - #ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK - #define CLOCK_FREQUENCY 40e6f - #else - #define CLOCK_FREQUENCY 80e6f - #endif -#endif - //color mangling macros #define RGBW32(r,g,b,w) (uint32_t((byte(w) << 24) | (byte(r) << 16) | (byte(g) << 8) | (byte(b)))) #define R(c) (byte((c) >> 16)) @@ -398,7 +385,7 @@ BusPwm::BusPwm(BusConfig &bc) unsigned numPins = NUM_PWM_PINS(bc.type); _frequency = bc.frequency ? bc.frequency : WLED_PWM_FREQ; // duty cycle resolution (_depth) can be extracted from this formula: CLOCK_FREQUENCY > _frequency * 2^_depth - _depth = uint8_t(log((float)CLOCK_FREQUENCY / (float)_frequency) / log(2.0)); + for (_depth=MAX_BIT_WIDTH; _depth>8; _depth--) if (((uint32_t(CLOCK_FREQUENCY)/_frequency)>>_depth) > 0) break; #ifdef ESP8266 analogWriteRange((1<<_depth)-1); diff --git a/wled00/const.h b/wled00/const.h index 0ff70e47d5..110ef9f0d5 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -521,6 +521,35 @@ #endif #endif +#ifndef CLOCK_FREQUENCY + #ifdef ESP8266 + // 1 MHz clock + #define CLOCK_FREQUENCY 1e6f + #else + // Use XTAL clock if possible to avoid timer frequency error when setting APB clock < 80 Mhz + // https://github.com/espressif/arduino-esp32/blob/2.0.2/cores/esp32/esp32-hal-ledc.c + #ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK + #define CLOCK_FREQUENCY 40e6f + #else + #define CLOCK_FREQUENCY 80e6f + #endif + #endif +#endif + +#ifndef MAX_BIT_WIDTH + #ifdef ESP8266 + #define MAX_BIT_WIDTH 10 + #else + #ifdef SOC_LEDC_TIMER_BIT_WIDE_NUM + // C6/H2/P4: 20 bit, S2/S3/C2/C3: 14 bit + #define MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM + #else + // ESP32: 32 bit + #define MAX_BIT_WIDTH 20 + #endif + #endif +#endif + #define TOUCH_THRESHOLD 32 // limit to recognize a touch, higher value means more sensitive // Size of buffer for API JSON object (increase for more segments) From 779744bd8e4b8cb851d48dfe4d8164f80ed69af2 Mon Sep 17 00:00:00 2001 From: PaoloTK Date: Sat, 3 Aug 2024 15:56:29 +0200 Subject: [PATCH 3/4] typo in comment --- wled00/const.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wled00/const.h b/wled00/const.h index 110ef9f0d5..d792f592af 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -544,7 +544,7 @@ // C6/H2/P4: 20 bit, S2/S3/C2/C3: 14 bit #define MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM #else - // ESP32: 32 bit + // ESP32: 20 bit #define MAX_BIT_WIDTH 20 #endif #endif From 52548542d2f838208a8cbd05dc3c14dc19a13a31 Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Sun, 4 Aug 2024 17:05:47 +0200 Subject: [PATCH 4/4] Remove clock/max bit overrides Move contants into bus manager --- wled00/bus_manager.cpp | 27 ++++++++++++++++++++++++++- wled00/const.h | 29 ----------------------------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/wled00/bus_manager.cpp b/wled00/bus_manager.cpp index e626a29629..d0e32b2116 100644 --- a/wled00/bus_manager.cpp +++ b/wled00/bus_manager.cpp @@ -378,6 +378,31 @@ void BusDigital::cleanup() { } +#ifdef ESP8266 + // 1 MHz clock + #define CLOCK_FREQUENCY 1000000UL +#else + // Use XTAL clock if possible to avoid timer frequency error when setting APB clock < 80 Mhz + // https://github.com/espressif/arduino-esp32/blob/2.0.2/cores/esp32/esp32-hal-ledc.c + #ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK + #define CLOCK_FREQUENCY 40000000UL + #else + #define CLOCK_FREQUENCY 80000000UL + #endif +#endif + +#ifdef ESP8266 + #define MAX_BIT_WIDTH 10 +#else + #ifdef SOC_LEDC_TIMER_BIT_WIDE_NUM + // C6/H2/P4: 20 bit, S2/S3/C2/C3: 14 bit + #define MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM + #else + // ESP32: 20 bit (but in reality we would never go beyond 16 bit as the frequency would be to low) + #define MAX_BIT_WIDTH 20 + #endif +#endif + BusPwm::BusPwm(BusConfig &bc) : Bus(bc.type, bc.start, bc.autoWhite, 1, bc.reversed) { @@ -385,7 +410,7 @@ BusPwm::BusPwm(BusConfig &bc) unsigned numPins = NUM_PWM_PINS(bc.type); _frequency = bc.frequency ? bc.frequency : WLED_PWM_FREQ; // duty cycle resolution (_depth) can be extracted from this formula: CLOCK_FREQUENCY > _frequency * 2^_depth - for (_depth=MAX_BIT_WIDTH; _depth>8; _depth--) if (((uint32_t(CLOCK_FREQUENCY)/_frequency)>>_depth) > 0) break; + for (_depth = MAX_BIT_WIDTH; _depth > 8; _depth--) if (((CLOCK_FREQUENCY/_frequency) >> _depth) > 0) break; #ifdef ESP8266 analogWriteRange((1<<_depth)-1); diff --git a/wled00/const.h b/wled00/const.h index d792f592af..0ff70e47d5 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -521,35 +521,6 @@ #endif #endif -#ifndef CLOCK_FREQUENCY - #ifdef ESP8266 - // 1 MHz clock - #define CLOCK_FREQUENCY 1e6f - #else - // Use XTAL clock if possible to avoid timer frequency error when setting APB clock < 80 Mhz - // https://github.com/espressif/arduino-esp32/blob/2.0.2/cores/esp32/esp32-hal-ledc.c - #ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK - #define CLOCK_FREQUENCY 40e6f - #else - #define CLOCK_FREQUENCY 80e6f - #endif - #endif -#endif - -#ifndef MAX_BIT_WIDTH - #ifdef ESP8266 - #define MAX_BIT_WIDTH 10 - #else - #ifdef SOC_LEDC_TIMER_BIT_WIDE_NUM - // C6/H2/P4: 20 bit, S2/S3/C2/C3: 14 bit - #define MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM - #else - // ESP32: 20 bit - #define MAX_BIT_WIDTH 20 - #endif - #endif -#endif - #define TOUCH_THRESHOLD 32 // limit to recognize a touch, higher value means more sensitive // Size of buffer for API JSON object (increase for more segments)