From d488bb7bacca80e6089bdf070bb1e10324d31dbb Mon Sep 17 00:00:00 2001 From: krzychb Date: Mon, 23 Oct 2017 05:32:47 +0200 Subject: [PATCH] Provided more meaningful parameter names by renaming 'bit_num' to 'duty_resolution' and 'div_num' to 'clock_divider' --- components/driver/include/driver/ledc.h | 105 +++++++++--------- components/driver/ledc.c | 56 +++++----- .../soc/esp32/include/soc/ledc_struct.h | 12 +- docs/_static/ledc-api-settings.jpg | Bin 28623 -> 28910 bytes docs/api-reference/peripherals/ledc.rst | 28 ++--- .../peripherals/ledc/main/ledc_example_main.c | 8 +- .../peripherals/pcnt/main/pcnt_example_main.c | 8 +- 7 files changed, 109 insertions(+), 108 deletions(-) diff --git a/components/driver/include/driver/ledc.h b/components/driver/include/driver/ledc.h index 55c0c8d2ac..f004ae64a9 100644 --- a/components/driver/include/driver/ledc.h +++ b/components/driver/include/driver/ledc.h @@ -30,7 +30,7 @@ extern "C" { typedef enum { LEDC_HIGH_SPEED_MODE = 0, /*!< LEDC high speed speed_mode */ - LEDC_LOW_SPEED_MODE, /*!< LEDC low speed speed_mode */ + LEDC_LOW_SPEED_MODE, /*!< LEDC low speed speed_mode */ LEDC_SPEED_MODE_MAX, /*!< LEDC speed limit */ } ledc_mode_t; @@ -45,15 +45,15 @@ typedef enum { } ledc_duty_direction_t; typedef enum { - LEDC_REF_TICK = 0, /*!< LEDC timer clock divided from reference tick(1Mhz) */ - LEDC_APB_CLK, /*!< LEDC timer clock divided from APB clock(80Mhz)*/ + LEDC_REF_TICK = 0, /*!< LEDC timer clock divided from reference tick (1Mhz) */ + LEDC_APB_CLK, /*!< LEDC timer clock divided from APB clock (80Mhz) */ } ledc_clk_src_t; typedef enum { - LEDC_TIMER_0 = 0, /*!< LEDC source timer TIMER0 */ - LEDC_TIMER_1, /*!< LEDC source timer TIMER1 */ - LEDC_TIMER_2, /*!< LEDC source timer TIMER2 */ - LEDC_TIMER_3, /*!< LEDC source timer TIMER3 */ + LEDC_TIMER_0 = 0, /*!< LEDC timer 0 */ + LEDC_TIMER_1, /*!< LEDC timer 1 */ + LEDC_TIMER_2, /*!< LEDC timer 2 */ + LEDC_TIMER_3, /*!< LEDC timer 3 */ } ledc_timer_t; typedef enum { @@ -69,46 +69,47 @@ typedef enum { } ledc_channel_t; typedef enum { - LEDC_TIMER_10_BIT = 10, /*!< LEDC PWM depth 10Bit */ - LEDC_TIMER_11_BIT = 11, /*!< LEDC PWM depth 11Bit */ - LEDC_TIMER_12_BIT = 12, /*!< LEDC PWM depth 12Bit */ - LEDC_TIMER_13_BIT = 13, /*!< LEDC PWM depth 13Bit */ - LEDC_TIMER_14_BIT = 14, /*!< LEDC PWM depth 14Bit */ - LEDC_TIMER_15_BIT = 15, /*!< LEDC PWM depth 15Bit */ + LEDC_TIMER_10_BIT = 10, /*!< LEDC PWM duty resolution of 10 bits */ + LEDC_TIMER_11_BIT = 11, /*!< LEDC PWM duty resolution of 11 bits */ + LEDC_TIMER_12_BIT = 12, /*!< LEDC PWM duty resolution of 12 bits */ + LEDC_TIMER_13_BIT = 13, /*!< LEDC PWM duty resolution of 13 bits */ + LEDC_TIMER_14_BIT = 14, /*!< LEDC PWM duty resolution of 14 bits */ + LEDC_TIMER_15_BIT = 15, /*!< LEDC PWM duty resolution of 15 bits */ } ledc_timer_bit_t; typedef enum { LEDC_FADE_NO_WAIT = 0, /*!< LEDC fade function will return immediately */ - LEDC_FADE_WAIT_DONE, /*!< LEDC fade function will block until fading to the target duty*/ + LEDC_FADE_WAIT_DONE, /*!< LEDC fade function will block until fading to the target duty */ LEDC_FADE_MAX, } ledc_fade_mode_t; + /** * @brief Configuration parameters of LEDC channel for ledc_channel_config function */ typedef struct { - int gpio_num; /*!< the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16*/ - ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode*/ - ledc_channel_t channel; /*!< LEDC channel(0 - 7)*/ - ledc_intr_type_t intr_type; /*!< configure interrupt, Fade interrupt enable or Fade interrupt disable*/ - ledc_timer_t timer_sel; /*!< Select the timer source of channel (0 - 3)*/ - uint32_t duty; /*!< LEDC channel duty, the duty range is [0, (2**bit_num) - 1], */ + int gpio_num; /*!< the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16 */ + ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode */ + ledc_channel_t channel; /*!< LEDC channel (0 - 7) */ + ledc_intr_type_t intr_type; /*!< configure interrupt, Fade interrupt enable or Fade interrupt disable */ + ledc_timer_t timer_sel; /*!< Select the timer source of channel (0 - 3) */ + uint32_t duty; /*!< LEDC channel duty, the range of duty setting is [0, (2**duty_resolution) - 1] */ } ledc_channel_config_t; /** * @brief Configuration parameters of LEDC Timer timer for ledc_timer_config function */ typedef struct { - ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode*/ - ledc_timer_bit_t bit_num; /*!< LEDC channel duty depth*/ - ledc_timer_t timer_num; /*!< The timer source of channel (0 - 3)*/ - uint32_t freq_hz; /*!< LEDC timer frequency(Hz)*/ + ledc_mode_t speed_mode; /*!< LEDC speed speed_mode, high-speed mode or low-speed mode */ + ledc_timer_bit_t duty_resolution; /*!< LEDC channel duty resolution */ + ledc_timer_t timer_num; /*!< The timer source of channel (0 - 3) */ + uint32_t freq_hz; /*!< LEDC timer frequency (Hz) */ } ledc_timer_config_t; typedef intr_handle_t ledc_isr_handle_t; /** * @brief LEDC channel configuration - * Configure LEDC channel with the given channel/output gpio_num/interrupt/source timer/frequency(Hz)/LEDC depth + * Configure LEDC channel with the given channel/output gpio_num/interrupt/source timer/frequency(Hz)/LEDC duty resolution * * @param ledc_conf Pointer of LEDC channel configure struct * @@ -120,14 +121,14 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t* ledc_conf); /** * @brief LEDC timer configuration - * Configure LEDC timer with the given source timer/frequency(Hz)/bit_num + * Configure LEDC timer with the given source timer/frequency(Hz)/duty_resolution * * @param timer_conf Pointer of LEDC timer configure struct * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error - * - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current bit_num. + * - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current duty_resolution. */ esp_err_t ledc_timer_config(const ledc_timer_config_t* timer_conf); @@ -137,7 +138,7 @@ esp_err_t ledc_timer_config(const ledc_timer_config_t* timer_conf); * After ledc_set_duty, ledc_set_fade, we need to call this function to update the settings. * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, - * @param channel LEDC channel(0-7), select from ledc_channel_t + * @param channel LEDC channel (0-7), select from ledc_channel_t * * @return * - ESP_OK Success @@ -151,7 +152,7 @@ esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel); * Disable LEDC output, and set idle level * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode - * @param channel LEDC channel(0-7), select from ledc_channel_t + * @param channel LEDC channel (0-7), select from ledc_channel_t * @param idle_level Set output idle level after LEDC stops. * * @return @@ -161,24 +162,24 @@ esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel); esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level); /** - * @brief LEDC set channel frequency(Hz) + * @brief LEDC set channel frequency (Hz) * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode - * @param timer_num LEDC timer index(0-3), select from ledc_timer_t + * @param timer_num LEDC timer index (0-3), select from ledc_timer_t * @param freq_hz Set the LEDC frequency * * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error - * - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current bit_num. + * - ESP_FAIL Can not find a proper pre-divider number base on the given frequency and the current duty_resolution. */ esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t freq_hz); /** - * @brief LEDC get channel frequency(Hz) + * @brief LEDC get channel frequency (Hz) * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode - * @param timer_num LEDC timer index(0-3), select from ledc_timer_t + * @param timer_num LEDC timer index (0-3), select from ledc_timer_t * * @return * - 0 error @@ -191,8 +192,8 @@ uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num); * Only after calling ledc_update_duty will the duty update. * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode - * @param channel LEDC channel(0-7), select from ledc_channel_t - * @param duty Set the LEDC duty, the duty range is [0, (2**bit_num) - 1] + * @param channel LEDC channel (0-7), select from ledc_channel_t + * @param duty Set the LEDC duty, the range of duty setting is [0, (2**duty_resolution) - 1] * * @return * - ESP_OK Success @@ -204,7 +205,7 @@ esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t * @brief LEDC get duty * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode - * @param channel LEDC channel(0-7), select from ledc_channel_t + * @param channel LEDC channel (0-7), select from ledc_channel_t * * @return * - LEDC_ERR_DUTY if parameter error @@ -217,8 +218,8 @@ uint32_t ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel); * Set LEDC gradient, After the function calls the ledc_update_duty function, the function can take effect. * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode - * @param channel LEDC channel(0-7), select from ledc_channel_t - * @param duty Set the start of the gradient duty, the duty range is [0, (2**bit_num) - 1] + * @param channel LEDC channel (0-7), select from ledc_channel_t + * @param duty Set the start of the gradient duty, the range of duty setting is [0, (2**duty_resolution) - 1] * @param gradule_direction Set the direction of the gradient * @param step_num Set the number of the gradient * @param duty_cyle_num Set how many LEDC tick each time the gradient lasts @@ -253,22 +254,22 @@ esp_err_t ledc_isr_register(void (*fn)(void*), void * arg, int intr_alloc_flags, * @brief Configure LEDC settings * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode - * @param timer_sel Timer index(0-3), there are 4 timers in LEDC module - * @param div_num Timer clock divide number, the timer clock is divided from the selected clock source - * @param bit_num The count number of one period, counter range is 0 ~ ((2 ** bit_num) - 1) + * @param timer_sel Timer index (0-3), there are 4 timers in LEDC module + * @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source + * @param duty_resolution Resolution of duty setting in number of bits. The range of duty values is [0, (2**duty_resolution) - 1] * @param clk_src Select LEDC source clock. * * @return * - (-1) Parameter error * - Other Current LEDC duty */ -esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t div_num, uint32_t bit_num, ledc_clk_src_t clk_src); +esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider, uint32_t duty_resolution, ledc_clk_src_t clk_src); /** * @brief Reset LEDC timer * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode - * @param timer_sel LEDC timer index(0-3), select from ledc_timer_t + * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t * * @return * - ESP_ERR_INVALID_ARG Parameter error @@ -280,7 +281,7 @@ esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel); * @brief Pause LEDC timer counter * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode - * @param timer_sel LEDC timer index(0-3), select from ledc_timer_t + * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t * * @return * - ESP_ERR_INVALID_ARG Parameter error @@ -293,7 +294,7 @@ esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel); * @brief Resume LEDC timer * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode - * @param timer_sel LEDC timer index(0-3), select from ledc_timer_t + * @param timer_sel LEDC timer index (0-3), select from ledc_timer_t * * @return * - ESP_ERR_INVALID_ARG Parameter error @@ -305,8 +306,8 @@ esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel); * @brief Bind LEDC channel with the selected timer * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode - * @param channel LEDC channel index(0-7), select from ledc_channel_t - * @param timer_idx LEDC timer index(0-3), select from ledc_timer_t + * @param channel LEDC channel index (0-7), select from ledc_channel_t + * @param timer_idx LEDC timer index (0-3), select from ledc_timer_t * * @return * - ESP_ERR_INVALID_ARG Parameter error @@ -319,8 +320,8 @@ esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint * Call ledc_fade_start() after this to start fading. * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, - * @param channel LEDC channel index(0-7), select from ledc_channel_t - * @param target_duty Target duty of fading.( 0 - (2 ** bit_num - 1))) + * @param channel LEDC channel index (0-7), select from ledc_channel_t + * @param target_duty Target duty of fading [0, (2**duty_resolution) - 1] * @param scale Controls the increase or decrease step scale. * @param cycle_num increase or decrease the duty every cycle_num cycles * @@ -337,8 +338,8 @@ esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel * Call ledc_fade_start() after this to start fading. * * @param speed_mode Select the LEDC speed_mode, high-speed mode and low-speed mode, - * @param channel LEDC channel index(0-7), select from ledc_channel_t - * @param target_duty Target duty of fading.( 0 - (2 ** bit_num - 1))) + * @param channel LEDC channel index (0-7), select from ledc_channel_t + * @param target_duty Target duty of fading.( 0 - (2 ** duty_resolution - 1))) * @param max_fade_time_ms The maximum time of the fading ( ms ). * * @return diff --git a/components/driver/ledc.c b/components/driver/ledc.c index 309ea63c7c..49b9e1ecf6 100644 --- a/components/driver/ledc.c +++ b/components/driver/ledc.c @@ -74,15 +74,15 @@ static IRAM_ATTR void ledc_ls_channel_update(ledc_mode_t speed_mode, ledc_channe } } -esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t div_num, uint32_t bit_num, +esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider, uint32_t duty_resolution, ledc_clk_src_t clk_src) { LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, LEDC_MODE_ERR_STR, ESP_ERR_INVALID_ARG); LEDC_CHECK(timer_sel <= LEDC_TIMER_3, LEDC_TIMER_ERR_STR, ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); - LEDC.timer_group[speed_mode].timer[timer_sel].conf.div_num = div_num; + LEDC.timer_group[speed_mode].timer[timer_sel].conf.clock_divider = clock_divider; LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel = clk_src; - LEDC.timer_group[speed_mode].timer[timer_sel].conf.bit_num = bit_num; + LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution = duty_resolution; ledc_ls_timer_update(speed_mode, timer_sel); portEXIT_CRITICAL(&ledc_spinlock); return ESP_OK; @@ -183,13 +183,13 @@ esp_err_t ledc_isr_register(void (*fn)(void*), void * arg, int intr_alloc_flags, esp_err_t ledc_timer_config(const ledc_timer_config_t* timer_conf) { int freq_hz = timer_conf->freq_hz; - int bit_num = timer_conf->bit_num; + int duty_resolution = timer_conf->duty_resolution; int timer_num = timer_conf->timer_num; int speed_mode = timer_conf->speed_mode; LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, LEDC_MODE_ERR_STR, ESP_ERR_INVALID_ARG); periph_module_enable(PERIPH_LEDC_MODULE); - if (freq_hz == 0 || bit_num == 0 || bit_num > LEDC_TIMER_15_BIT) { - ESP_LOGE(LEDC_TAG, "freq_hz=%u bit_num=%u", freq_hz, bit_num); + if (freq_hz == 0 || duty_resolution == 0 || duty_resolution > LEDC_TIMER_15_BIT) { + ESP_LOGE(LEDC_TAG, "freq_hz=%u duty_resolution=%u", freq_hz, duty_resolution); return ESP_ERR_INVALID_ARG; } if (timer_num > LEDC_TIMER_3) { @@ -197,14 +197,14 @@ esp_err_t ledc_timer_config(const ledc_timer_config_t* timer_conf) return ESP_ERR_INVALID_ARG; } esp_err_t ret = ESP_OK; - uint32_t precision = ( 0x1 << bit_num ); // 2**depth + uint32_t precision = ( 0x1 << duty_resolution ); // 2**depth // Try calculating divisor based on LEDC_APB_CLK ledc_clk_src_t timer_clk_src = LEDC_APB_CLK; // div_param is a Q10.8 fixed point value uint64_t div_param = ( (uint64_t) LEDC_APB_CLK_HZ << 8 ) / freq_hz / precision; if (div_param < 256) { // divisor is too low - ESP_LOGE(LEDC_TAG, "requested frequency and bit depth can not be achieved, try reducing freq_hz or bit_num. div_param=%d", + ESP_LOGE(LEDC_TAG, "requested frequency and duty resolution can not be achieved, try reducing freq_hz or duty_resolution. div_param=%d", (uint32_t ) div_param); ret = ESP_FAIL; } @@ -213,7 +213,7 @@ esp_err_t ledc_timer_config(const ledc_timer_config_t* timer_conf) timer_clk_src = LEDC_REF_TICK; div_param = ((uint64_t) LEDC_REF_CLK_HZ << 8) / freq_hz / precision; if (div_param < 256 || div_param > LEDC_DIV_NUM_HSTIMER0_V) { - ESP_LOGE(LEDC_TAG, "requested frequency and bit depth can not be achieved, try increasing freq_hz or bit_num. div_param=%d", + ESP_LOGE(LEDC_TAG, "requested frequency and duty resolution can not be achieved, try increasing freq_hz or duty_resolution. div_param=%d", (uint32_t ) div_param); ret = ESP_FAIL; } @@ -224,7 +224,7 @@ esp_err_t ledc_timer_config(const ledc_timer_config_t* timer_conf) } } // set timer parameters - ledc_timer_set(speed_mode, timer_num, div_param, bit_num, timer_clk_src); + ledc_timer_set(speed_mode, timer_num, div_param, duty_resolution, timer_clk_src); // reset timer ledc_timer_rst(speed_mode, timer_num); return ret; @@ -261,7 +261,7 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t* ledc_conf) esp_err_t ret = ESP_OK; /*set channel parameters*/ /* channel parameters decide how the waveform looks like in one period*/ - /* set channel duty, duty range is (0 ~ ((2 ** bit_num) - 1))*/ + /* set channel duty, duty range is (0 ~ ((2 ** duty_resolution) - 1))*/ ledc_set_duty(speed_mode, ledc_channel, duty); /*update duty settings*/ ledc_update_duty(speed_mode, ledc_channel); @@ -364,20 +364,20 @@ esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t LEDC_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, LEDC_MODE_ERR_STR, ESP_ERR_INVALID_ARG); portENTER_CRITICAL(&ledc_spinlock); esp_err_t ret = ESP_OK; - uint32_t div_num = 0; - uint32_t bit_num = LEDC.timer_group[speed_mode].timer[timer_num].conf.bit_num; + uint32_t clock_divider = 0; + uint32_t duty_resolution = LEDC.timer_group[speed_mode].timer[timer_num].conf.duty_resolution; uint32_t timer_source_clk = LEDC.timer_group[speed_mode].timer[timer_num].conf.tick_sel; - uint32_t precision = (0x1 << bit_num); + uint32_t precision = (0x1 << duty_resolution); if (timer_source_clk == LEDC_APB_CLK) { - div_num = ((uint64_t) LEDC_APB_CLK_HZ << 8) / freq_hz / precision; + clock_divider = ((uint64_t) LEDC_APB_CLK_HZ << 8) / freq_hz / precision; } else { - div_num = ((uint64_t) LEDC_REF_CLK_HZ << 8) / freq_hz / precision; + clock_divider = ((uint64_t) LEDC_REF_CLK_HZ << 8) / freq_hz / precision; } - if (div_num <= 256 || div_num > LEDC_DIV_NUM_HSTIMER0) { - ESP_LOGE(LEDC_TAG, "div param err,div_param=%u", div_num); + if (clock_divider <= 256 || clock_divider > LEDC_DIV_NUM_HSTIMER0) { + ESP_LOGE(LEDC_TAG, "div param err,div_param=%u", clock_divider); ret = ESP_FAIL; } - LEDC.timer_group[speed_mode].timer[timer_num].conf.div_num = div_num; + LEDC.timer_group[speed_mode].timer[timer_num].conf.clock_divider = clock_divider; portEXIT_CRITICAL(&ledc_spinlock); return ret; } @@ -388,13 +388,13 @@ uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num) portENTER_CRITICAL(&ledc_spinlock); uint32_t freq = 0; uint32_t timer_source_clk = LEDC.timer_group[speed_mode].timer[timer_num].conf.tick_sel; - uint32_t bit_num = LEDC.timer_group[speed_mode].timer[timer_num].conf.bit_num; - uint32_t div_num = LEDC.timer_group[speed_mode].timer[timer_num].conf.div_num; - uint32_t precision = (0x1 << bit_num); + uint32_t duty_resolution = LEDC.timer_group[speed_mode].timer[timer_num].conf.duty_resolution; + uint32_t clock_divider = LEDC.timer_group[speed_mode].timer[timer_num].conf.clock_divider; + uint32_t precision = (0x1 << duty_resolution); if (timer_source_clk == LEDC_APB_CLK) { - freq = ((uint64_t) LEDC_APB_CLK_HZ << 8) / precision / div_num; + freq = ((uint64_t) LEDC_APB_CLK_HZ << 8) / precision / clock_divider; } else { - freq = ((uint64_t) LEDC_REF_CLK_HZ << 8) / precision / div_num; + freq = ((uint64_t) LEDC_REF_CLK_HZ << 8) / precision / clock_divider; } portEXIT_CRITICAL(&ledc_spinlock); return freq; @@ -504,7 +504,7 @@ esp_err_t ledc_set_fade_with_time(ledc_mode_t speed_mode, ledc_channel_t channel LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK , LEDC_FADE_INIT_ERROR_STR, ESP_FAIL); int timer_sel = LEDC.channel_group[speed_mode].channel[channel].conf0.timer_sel; - uint32_t max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.bit_num)) - 1; + uint32_t max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution)) - 1; LEDC_CHECK(target_duty <= max_duty, LEDC_FADE_TARGET_ERR_STR, ESP_ERR_INVALID_ARG); uint32_t freq = ledc_get_freq(speed_mode, timer_sel); uint32_t duty_cur = LEDC.channel_group[speed_mode].channel[channel].duty_rd.duty_read >> LEDC_DUTY_DECIMAL_BIT_NUM; @@ -535,7 +535,7 @@ esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel LEDC_CHECK(ledc_fade_channel_init_check(speed_mode, channel) == ESP_OK , LEDC_FADE_INIT_ERROR_STR, ESP_FAIL); int timer_sel = LEDC.channel_group[speed_mode].channel[channel].conf0.timer_sel; - uint32_t max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.bit_num)) - 1; + uint32_t max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution)) - 1; LEDC_CHECK(target_duty <= max_duty, LEDC_FADE_TARGET_ERR_STR, ESP_ERR_INVALID_ARG); //disable the interrupt, so the operation will not mess up ledc_enable_intr_type(speed_mode, channel, LEDC_INTR_DISABLE); @@ -579,8 +579,8 @@ esp_err_t ledc_set_fade_with_step(ledc_mode_t speed_mode, ledc_channel_t channel s_ledc_fade_rec[speed_mode][channel]->cycle_num, s_ledc_fade_rec[speed_mode][channel]->scale ); - int bit_num_ch0 = (speed_mode == LEDC_HIGH_SPEED_MODE) ? LEDC_DUTY_CHNG_END_HSCH0_INT_ENA_S : LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S; - LEDC.int_clr.val |= BIT(bit_num_ch0 + channel); + int duty_resolution_ch0 = (speed_mode == LEDC_HIGH_SPEED_MODE) ? LEDC_DUTY_CHNG_END_HSCH0_INT_ENA_S : LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S; + LEDC.int_clr.val |= BIT(duty_resolution_ch0 + channel); ledc_enable_intr_type(speed_mode, channel, LEDC_INTR_FADE_END); return ESP_OK; } diff --git a/components/soc/esp32/include/soc/ledc_struct.h b/components/soc/esp32/include/soc/ledc_struct.h index dd3c364bd4..f90c3cb9d9 100644 --- a/components/soc/esp32/include/soc/ledc_struct.h +++ b/components/soc/esp32/include/soc/ledc_struct.h @@ -69,13 +69,13 @@ typedef volatile struct { struct { union { struct { - uint32_t bit_num: 5; /*This register controls the range of the counter in high speed timer. the counter range is [0 2**reg_hstimer0_lim] the max bit width for counter is 20.*/ - uint32_t div_num: 18; /*This register is used to configure parameter for divider in high speed timer the least significant eight bits represent the decimal part.*/ - uint32_t pause: 1; /*This bit is used to pause the counter in high speed timer*/ - uint32_t rst: 1; /*This bit is used to reset high speed timer the counter will be 0 after reset.*/ - uint32_t tick_sel: 1; /*This bit is used to choose apb_clk or ref_tick for high speed timer. 1'b1:apb_clk 0:ref_tick*/ + uint32_t duty_resolution: 5; /*This register controls resolution of PWN duty by defining the bith width of timer's counter. The max bit width of the counter is 20.*/ + uint32_t clock_divider: 18; /*This register is used to configure the divider of clock at the entry of timer. The least significant eight bits represent the decimal part.*/ + uint32_t pause: 1; /*This bit is used to pause the counter in high speed timer*/ + uint32_t rst: 1; /*This bit is used to reset high speed timer the counter will be 0 after reset.*/ + uint32_t tick_sel: 1; /*This bit is used to choose apb_clk or ref_tick for high speed timer. 1'b1:apb_clk 0:ref_tick*/ uint32_t low_speed_update: 1; /*This bit is only useful for low speed timer channels, reserved for high speed timers*/ - uint32_t reserved26: 5; + uint32_t reserved26: 5; }; uint32_t val; } conf; diff --git a/docs/_static/ledc-api-settings.jpg b/docs/_static/ledc-api-settings.jpg index 06c0b10ad9920f14233f34b47d2e9c117325fcbb..92f0545ab194624bf128a0fa9c7ece27b43c5d2b 100644 GIT binary patch delta 25869 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 delta 25661 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 cB9+4yGgFg3n@F@+sB-Lxv+n=-pW**a0L`_ (PDF). Note that support for ``SLOW_CLOCK`` mentioned in this manual is not implemented in the LEDC API. -.. _ledc-api-supported-range-frequency-bit-number: +.. _ledc-api-supported-range-frequency-duty-resolution: -Supported Range of Frequency and Bit Number -------------------------------------------- +Supported Range of Frequency and Duty Resolution +------------------------------------------------ -The LED PWM Controller is designed primarily to drive LEDs and provides wide resolution of PWM duty settings. The resolution (or granularity) of the PWM duty is determined by the "bit number". For instance for the PWM frequency at 5 kHz, the maximum bit number is 13 bits. It means that the duty may be set anywhere from 0 to 100% with resolution of ~0.012% (13 ** 2 = 8192 discrete levels of the LED intensity). +The LED PWM Controller is designed primarily to drive LEDs and provides wide resolution of PWM duty settings. For instance for the PWM frequency at 5 kHz, the maximum duty resolution is 13 bits. It means that the duty may be set anywhere from 0 to 100% with resolution of ~0.012% (13 ** 2 = 8192 discrete levels of the LED intensity). The LEDC may be used for providing signals at much higher frequencies to clock other devices, e.g. a digital camera module. In such a case the maximum available frequency is 40 MHz with duty resolution of 1 bit. This means that duty is fixed at 50% and cannot be adjusted. -The API is designed to report an error when trying to set a frequency and a bit number that is out of the range of LEDC's hardware. For example, an attempt to set the frequency at 20 MHz and the bit number of 3 bits will result in the following error reported on a serial monitor: +The API is designed to report an error when trying to set a frequency and a duty resolution that is out of the range of LEDC's hardware. For example, an attempt to set the frequency at 20 MHz and the duty resolution of 3 bits will result in the following error reported on a serial monitor: .. highlight:: none :: - E (196) ledc: requested frequency and bit number can not be achieved, try reducing freq_hz or bit_num. div_param=128 + E (196) ledc: requested frequency and duty resolution can not be achieved, try reducing freq_hz or duty_resolution. div_param=128 -In such a case either the bit number or the frequency should be reduced. For example setting the bit number at 2 will resolve this issue and provide possibility to set the duty with 25% steps, i.e. at 25%, 50% or 75%. +In such a case either the duty resolution or the frequency should be reduced. For example setting the duty resolution at 2 will resolve this issue and provide possibility to set the duty with 25% steps, i.e. at 25%, 50% or 75%. -The LEDC API will also capture and report an attempt to configure frequency / bit number combination that is below the supported minimum, e.g.: +The LEDC API will also capture and report an attempt to configure frequency / duty resolution combination that is below the supported minimum, e.g.: :: - E (196) ledc: requested frequency and bit depth can not be achieved, try increasing freq_hz or bit_num. div_param=128000000 + E (196) ledc: requested frequency and duty resolution can not be achieved, try increasing freq_hz or duty_resolution. div_param=128000000 -Setting of the bit number is normally done using :cpp:type:`ledc_timer_bit_t`. This enumeration covers the range from 10 to 15 bits. If a smaller bit number is required (below 10 down to 1), enter the equivalent numeric values directly. +Setting of the duty resolution is normally done using :cpp:type:`ledc_timer_bit_t`. This enumeration covers the range from 10 to 15 bits. If a smaller duty resolution is required (below 10 down to 1), enter the equivalent numeric values directly. Application Example diff --git a/examples/peripherals/ledc/main/ledc_example_main.c b/examples/peripherals/ledc/main/ledc_example_main.c index 9f5def1fd1..05547fb202 100644 --- a/examples/peripherals/ledc/main/ledc_example_main.c +++ b/examples/peripherals/ledc/main/ledc_example_main.c @@ -60,10 +60,10 @@ void app_main() * that will be used by LED Controller */ ledc_timer_config_t ledc_timer = { - .bit_num = LEDC_TIMER_13_BIT, // resolution of PWM duty - .freq_hz = 5000, // frequency of PWM signal - .speed_mode = LEDC_HS_MODE, // timer mode - .timer_num = LEDC_HS_TIMER // timer index + .duty_resolution = LEDC_TIMER_13_BIT, // resolution of PWM duty + .freq_hz = 5000, // frequency of PWM signal + .speed_mode = LEDC_HS_MODE, // timer mode + .timer_num = LEDC_HS_TIMER // timer index }; // Set configuration of timer0 for high speed channels ledc_timer_config(&ledc_timer); diff --git a/examples/peripherals/pcnt/main/pcnt_example_main.c b/examples/peripherals/pcnt/main/pcnt_example_main.c index 68b36e45fa..2a4b3695c7 100644 --- a/examples/peripherals/pcnt/main/pcnt_example_main.c +++ b/examples/peripherals/pcnt/main/pcnt_example_main.c @@ -96,10 +96,10 @@ static void ledc_init(void) { // Prepare and then apply the LEDC PWM timer configuration ledc_timer_config_t ledc_timer; - ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE; - ledc_timer.timer_num = LEDC_TIMER_1; - ledc_timer.bit_num = LEDC_TIMER_10_BIT; - ledc_timer.freq_hz = 1; // set output frequency at 1 Hz + ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE; + ledc_timer.timer_num = LEDC_TIMER_1; + ledc_timer.duty_resolution = LEDC_TIMER_10_BIT; + ledc_timer.freq_hz = 1; // set output frequency at 1 Hz ledc_timer_config(&ledc_timer); // Prepare and then apply the LEDC PWM channel configuration