@@ -378,14 +378,39 @@ void BusDigital::cleanup() {
378378}
379379
380380
381+ #ifdef ESP8266
382+ // 1 MHz clock
383+ #define CLOCK_FREQUENCY 1000000UL
384+ #else
385+ // Use XTAL clock if possible to avoid timer frequency error when setting APB clock < 80 Mhz
386+ // https://github.com/espressif/arduino-esp32/blob/2.0.2/cores/esp32/esp32-hal-ledc.c
387+ #ifdef SOC_LEDC_SUPPORT_XTAL_CLOCK
388+ #define CLOCK_FREQUENCY 40000000UL
389+ #else
390+ #define CLOCK_FREQUENCY 80000000UL
391+ #endif
392+ #endif
393+
394+ #ifdef ESP8266
395+ #define MAX_BIT_WIDTH 10
396+ #else
397+ #ifdef SOC_LEDC_TIMER_BIT_WIDE_NUM
398+ // C6/H2/P4: 20 bit, S2/S3/C2/C3: 14 bit
399+ #define MAX_BIT_WIDTH SOC_LEDC_TIMER_BIT_WIDE_NUM
400+ #else
401+ // ESP32: 20 bit (but in reality we would never go beyond 16 bit as the frequency would be to low)
402+ #define MAX_BIT_WIDTH 20
403+ #endif
404+ #endif
405+
381406BusPwm::BusPwm (BusConfig &bc)
382407: Bus(bc.type, bc.start, bc.autoWhite, 1 , bc.reversed)
383408{
384409 if (!IS_PWM (bc.type )) return ;
385410 unsigned numPins = NUM_PWM_PINS (bc.type );
386411 _frequency = bc.frequency ? bc.frequency : WLED_PWM_FREQ;
387412 // duty cycle resolution (_depth) can be extracted from this formula: CLOCK_FREQUENCY > _frequency * 2^_depth
388- for (_depth= MAX_BIT_WIDTH; _depth> 8 ; _depth--) if (((uint32_t ( CLOCK_FREQUENCY) /_frequency)>> _depth) > 0 ) break ;
413+ for (_depth = MAX_BIT_WIDTH; _depth > 8 ; _depth--) if (((CLOCK_FREQUENCY/_frequency) >> _depth) > 0 ) break ;
389414
390415#ifdef ESP8266
391416 analogWriteRange ((1 <<_depth)-1 );
0 commit comments