Using LEDC to generate 4M clock failed. Any advice?

Haruka
Posts: 2
Joined: Fri May 26, 2023 1:50 pm

Using LEDC to generate 4M clock failed. Any advice?

Postby Haruka » Sat May 27, 2023 3:05 am

Hello everyone!
I'm using ESP32-S2 with esp-idf v5.0.2 and trying to generate clock signal for external device. So I wrote the following code, basically modified from example code:

Code: Select all

void PWM_Init(){
    // Prepare and then apply the LEDC PWM timer configuration
    ledc_timer_config_t ledc_timer = {
        .speed_mode       = LEDC_LOW_SPEED_MODE,
        .timer_num        = LEDC_TIMER_0,
        .duty_resolution  = LEDC_TIMER_1_BIT,
        .freq_hz          = 1000,
        .clk_cfg          = LEDC_AUTO_CLK
    };
    esp_err_t ret = ledc_timer_config(&ledc_timer);
    if(ret != ESP_OK){
        printf("err=%d\n", ret);
    }

    // Prepare and then apply the LEDC PWM channel configuration
    ledc_channel_config_t ledc_channel = {
        .speed_mode     = LEDC_LOW_SPEED_MODE,
        .channel        = LEDC_CHANNEL_0,
        .timer_sel      = LEDC_TIMER_0,
        .intr_type      = LEDC_INTR_DISABLE,
        .gpio_num       = GPIO_PWM,
        .duty           = 1,
        .hpoint         = 0
    };
    ret = ledc_channel_config(&ledc_channel);
    if(ret != ESP_OK){
        printf("err=%d\n", ret);
    }
}

void PWM_Start(uint32_t freq){
    esp_err_t ret = ledc_set_freq(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, freq);
    if(ret != ESP_OK){
        printf("err=%d\n", ret);
    }
}
And in the main.c:

Code: Select all

void app_main(void){
    //Blink_Init();
    //ST7789_Init();
    PWM_Init();
    //ST7789_FillColor(0xFFFFFFFF);

    //Blink_Start(1000);
    PWM_Start(4194304);
    while(1){
        //for(int i = 0; i < 160 * 144; ++i){
        //    pixelData[i] = (uint16_t)rand();
        //}
        //ST7789_Flush((uint8_t*)pixelData, (240 - 160) >> 1, (240 - 144) >> 1, 160, 144);

        vTaskDelay(100 / portTICK_PERIOD_MS);
        //printf("counter=%ld.\n", counter);
        //counter++;
    }
}
But when running I got error message on the console:

Code: Select all

E (1555) ledc: requested frequency and duty resolution can not be achieved, try reducing freq_hz or duty_resolution. div_param=0
I am confused. According to the doc:
The LEDC can be used for generating signals at much higher frequencies that are sufficient enough to clock other devices, e.g., a digital camera module. In this case, the maximum available frequency is 40 MHz with duty resolution of 1 bit. This means that the duty cycle is fixed at 50% and cannot be adjusted.

The LEDC API is designed to report an error when trying to set a frequency and a duty resolution that exceed the range of LEDC’s hardware. For example, an attempt to set the frequency to 20 MHz and the duty resolution to 3 bits will result in the following error reported on a serial monitor:

E (196) ledc: requested frequency and duty resolution cannot be achieved, try reducing freq_hz or duty_resolution. div_param=128
In such a situation, either the duty resolution or the frequency must be reduced. For example, setting the duty resolution to 2 will resolve this issue and will make it possible to set the duty cycle at 25% steps, i.e., at 25%, 50% or 75%.
I only need freq @ 4MHz with duty @ 50%. Why I got this error?

Any advice is much apprecicated!

MicroController
Posts: 1136
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Using LEDC to generate 4M clock failed. Any advice?

Postby MicroController » Sun May 28, 2023 11:08 am

It's probably your timer configuration:

Code: Select all

        .speed_mode       = LEDC_LOW_SPEED_MODE,
...
        .freq_hz          = 1000,
        .clk_cfg          = LEDC_AUTO_CLK
Try using high speed mode and APB clock:

Code: Select all

        .speed_mode       = LEDC_HIGH_SPEED_MODE,
...
        .freq_hz          = 4000000,
        .clk_cfg          = LEDC_USE_APB_CLK
and

Code: Select all

esp_err_t ret = ledc_set_freq(LEDC_HIGH_SPEED_MODE, LEDC_CHANNEL_0, freq);
Btw, as the timer clock is derived from the source clock (e.g. APB clock) by a divider, you'll not get a frequency of 4194304Hz. You can get 80/20 = 4Mhz or 80/19 ~ 4.21Mhz.

Haruka
Posts: 2
Joined: Fri May 26, 2023 1:50 pm

Re: Using LEDC to generate 4M clock failed. Any advice?

Postby Haruka » Mon May 29, 2023 1:29 am

Thank you for your reply! Unfortunately ESP32-S2 does not support high speed mode, and I changed the clock source to APB clock, still failed with the same error message. But this time a panic was triggered, causing reboot:

Code: Select all

I (111) spi_flash: detected chip: generic
I (112) spi_flash: flash io: dio
I (112) cpu_start: Starting scheduler on PRO CPU.
I (113) gpio: GPIO[15]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
E (223) ledc: requested frequency and duty resolution can not be achieved, try reducing freq_hz or duty_resolution. div_param=0
err=-1

abort() was called at PC 0x40089f02 on core 0
ClearCommError failed (PermissionError(13, '???????????????????????????', None, 22))
Waiting for the device to reconnect0x40089f02: ledc_ll_get_slow_clk_sel at C:/esp-idf-v5.0.2/components/hal/esp32s2/include/hal/ledc_ll.h:81
 (inlined by) ledc_hal_get_slow_clock_helper at C:/esp-idf-v5.0.2/components/hal/ledc_hal.c:24
 (inlined by) ledc_hal_get_clk_cfg at C:/esp-idf-v5.0.2/components/hal/ledc_hal.c:74



Backtrace: 0x400235d2:0x3ffcdbb0 0x40026f79:0x3ffcdbd0 0x4002c4a5:0x3ffcdbf0 0x40089f02:0x3ffcdc60 0x400878ed:0x3ffcdc80 0x400858bc:0x3ffcdcc0 0x400857b0:0x3ffcdce0 0x400959ce:0x3ffcdd00  
0x400235d2: panic_abort at C:/esp-idf-v5.0.2/components/esp_system/panic.c:423

0x40026f79: esp_system_abort at C:/esp-idf-v5.0.2/components/esp_system/esp_system.c:153

0x4002c4a5: abort at C:/esp-idf-v5.0.2/components/newlib/abort.c:38

0x40089f02: ledc_hal_get_slow_clock_helper at C:/esp-idf-v5.0.2/components/hal/esp32s2/include/hal/ledc_ll.h:81
 (inlined by) ledc_hal_get_clk_cfg at C:/esp-idf-v5.0.2/components/hal/ledc_hal.c:74

0x400878ed: ledc_set_freq at C:/esp-idf-v5.0.2/components/driver/ledc.c:819 (discriminator 2)

0x400858bc: PWM_Start at C:/SuperGameBoy/Client/esp32-s2/components/PWM/PWM.c:58
I assume this chip has no ability to generate high frequency signal through LEDC? I wonder if there are any other ways to generate accurate 4M clock @ 50% duty without involving CPU processing(ie. no direct GPIO toggling in a task)?

Who is online

Users browsing this forum: ericchile and 117 guests