Merge branch 'feature/esp32h2_ledc_support' into 'master'

ledc: Add support for ESP32H2

Closes IDF-6235 and IDF-6698

See merge request espressif/esp-idf!22120
This commit is contained in:
Song Ruo Jing 2023-01-31 12:26:30 +08:00
commit 0d07f85916
34 changed files with 1078 additions and 336 deletions

View File

@ -39,9 +39,9 @@ extern "C" {
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_channel_t channel; /*!< LEDC channel (0 - LEDC_CHANNEL_MAX-1) */
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) */
ledc_timer_t timer_sel; /*!< Select the timer source of channel (0 - LEDC_TIMER_MAX-1) */
uint32_t duty; /*!< LEDC channel duty, the range of duty setting is [0, (2**duty_resolution)] */
int hpoint; /*!< LEDC channel hpoint value, the max value is 0xfffff */
struct {
@ -56,12 +56,12 @@ typedef struct {
typedef struct {
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) */
ledc_timer_t timer_num; /*!< The timer source of channel (0 - LEDC_TIMER_MAX-1) */
uint32_t freq_hz; /*!< LEDC timer frequency (Hz) */
ledc_clk_cfg_t clk_cfg; /*!< Configure LEDC source clock from ledc_clk_cfg_t.
Note that LEDC_USE_RTC8M_CLK and LEDC_USE_XTAL_CLK are
Note that LEDC_USE_RC_FAST_CLK and LEDC_USE_XTAL_CLK are
non-timer-specific clock sources. You can not have one LEDC timer uses
RTC8M_CLK as the clock source and have another LEDC timer uses XTAL_CLK
RC_FAST_CLK as the clock source and have another LEDC timer uses XTAL_CLK
as its clock source. All chips except esp32 and esp32s2 do not have
timer-specific clock sources, which means clock source for all timers
must be the same one. */

View File

@ -11,7 +11,7 @@
#include "esp_check.h"
#include "soc/gpio_periph.h"
#include "soc/ledc_periph.h"
#include "esp_private/esp_clk.h"
#include "clk_tree.h"
#include "soc/soc_caps.h"
#include "hal/ledc_hal.h"
#include "hal/gpio_hal.h"
@ -30,6 +30,15 @@ static __attribute__((unused)) const char *LEDC_TAG = "ledc";
#define LEDC_CLK_NOT_FOUND 0
#define LEDC_SLOW_CLK_UNINIT -1
// Precision degree only affects RC_FAST, other clock sources' frequences are fixed values
// For targets that do not support RC_FAST calibration, can only use its approx. value. Precision degree other than
// APPROX will trigger LOGW during the call to `clk_tree_src_get_freq_hz`.
#if SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
#define LEDC_CLK_SRC_FREQ_PRECISION CLK_TREE_SRC_FREQ_PRECISION_CACHED
#else
#define LEDC_CLK_SRC_FREQ_PRECISION CLK_TREE_SRC_FREQ_PRECISION_APPROX
#endif
typedef enum {
LEDC_FSM_IDLE,
LEDC_FSM_HW_FADE,
@ -77,11 +86,11 @@ static __attribute__((unused)) const char *LEDC_FADE_SERVICE_ERR_STR = "LEDC fad
static __attribute__((unused)) const char *LEDC_FADE_INIT_ERROR_STR = "LEDC fade channel init error, not enough memory or service not installed";
//This value will be calibrated when in use.
static uint32_t s_ledc_slow_clk_8M = 0;
static uint32_t s_ledc_slow_clk_rc_fast_freq = 0;
static const ledc_slow_clk_sel_t s_glb_clks[] = LEDC_LL_GLOBAL_CLOCKS;
#if SOC_LEDC_HAS_TIMER_SPECIFIC_MUX
static const struct { ledc_clk_src_t clk; uint32_t freq; } s_timer_specific_clks[] = LEDC_LL_TIMER_SPECIFIC_CLOCKS;
static const ledc_clk_src_t s_timer_specific_clks[] = LEDC_LL_TIMER_SPECIFIC_CLOCKS;
#endif
static void ledc_ls_timer_update(ledc_mode_t speed_mode, ledc_timer_t timer_sel)
@ -98,78 +107,23 @@ static IRAM_ATTR void ledc_ls_channel_update(ledc_mode_t speed_mode, ledc_channe
}
}
//We know that CLK8M is about 8M, but don't know the actual value. So we need to do a calibration.
//We know that RC_FAST is about 8M/20M, but don't know the actual value. So we need to do a calibration.
static bool ledc_slow_clk_calibrate(void)
{
if (periph_rtc_dig_clk8m_enable()) {
s_ledc_slow_clk_8M = periph_rtc_dig_clk8m_get_freq();
s_ledc_slow_clk_rc_fast_freq = periph_rtc_dig_clk8m_get_freq();
#if !SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
/* Workaround: CLK8M calibration cannot be performed, we can only use its theoretic freq */
ESP_LOGD(LEDC_TAG, "Calibration cannot be performed, approximate CLK8M_CLK : %"PRIu32" Hz", s_ledc_slow_clk_8M);
/* Workaround: RC_FAST calibration cannot be performed, we can only use its theoretic freq */
ESP_LOGD(LEDC_TAG, "Calibration cannot be performed, approximate RC_FAST_CLK : %"PRIu32" Hz", s_ledc_slow_clk_rc_fast_freq);
#else
ESP_LOGD(LEDC_TAG, "Calibrate CLK8M_CLK : %"PRIu32" Hz", s_ledc_slow_clk_8M);
ESP_LOGD(LEDC_TAG, "Calibrate RC_FAST_CLK : %"PRIu32" Hz", s_ledc_slow_clk_rc_fast_freq);
#endif
return true;
}
ESP_LOGE(LEDC_TAG, "Calibrate CLK8M_CLK failed");
ESP_LOGE(LEDC_TAG, "Calibrate RC_FAST_CLK failed");
return false;
}
static uint32_t ledc_get_src_clk_freq(ledc_clk_cfg_t clk_cfg)
{
uint32_t src_clk_freq = 0;
if (clk_cfg == LEDC_USE_RTC8M_CLK) {
src_clk_freq = s_ledc_slow_clk_8M;
#if SOC_LEDC_SUPPORT_APB_CLOCK
} else if (clk_cfg == LEDC_USE_APB_CLK) {
src_clk_freq = esp_clk_apb_freq();
#endif
#if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
} else if (clk_cfg == LEDC_USE_PLL_DIV_CLK) {
src_clk_freq = LEDC_LL_PLL_DIV_CLK_FREQ;
#endif
#if SOC_LEDC_SUPPORT_REF_TICK
} else if (clk_cfg == LEDC_USE_REF_TICK) {
src_clk_freq = REF_CLK_FREQ;
#endif
#if SOC_LEDC_SUPPORT_XTAL_CLOCK
} else if (clk_cfg == LEDC_USE_XTAL_CLK) {
src_clk_freq = esp_clk_xtal_freq();
#endif
}
return src_clk_freq;
}
/* Retrieve the clock frequency for global clocks only */
static uint32_t ledc_get_glb_clk_freq(ledc_slow_clk_sel_t clk_cfg)
{
uint32_t src_clk_freq = 0;
switch (clk_cfg) {
#if SOC_LEDC_SUPPORT_APB_CLOCK
case LEDC_SLOW_CLK_APB:
src_clk_freq = esp_clk_apb_freq();
break;
#endif
#if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
case LEDC_SLOW_CLK_PLL_DIV:
src_clk_freq = LEDC_LL_PLL_DIV_CLK_FREQ;
break;
#endif
case LEDC_SLOW_CLK_RTC8M:
src_clk_freq = s_ledc_slow_clk_8M;
break;
#if SOC_LEDC_SUPPORT_XTAL_CLOCK
case LEDC_SLOW_CLK_XTAL:
src_clk_freq = esp_clk_xtal_freq();
break;
#endif
}
return src_clk_freq;
}
static esp_err_t ledc_enable_intr_type(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_intr_type_t type)
{
if (type == LEDC_INTR_FADE_END) {
@ -348,7 +302,7 @@ static inline uint32_t ledc_calculate_divisor(uint32_t src_clk_freq, int freq_hz
/ (freq_hz * precision);
}
static inline uint32_t ledc_auto_global_clk_divisor(int freq_hz, uint32_t precision, ledc_slow_clk_sel_t* clk_target)
static inline uint32_t ledc_auto_global_clk_divisor(int freq_hz, uint32_t precision, ledc_slow_clk_sel_t *clk_target)
{
uint32_t ret = LEDC_CLK_NOT_FOUND;
uint32_t clk_freq = 0;
@ -356,14 +310,14 @@ static inline uint32_t ledc_auto_global_clk_divisor(int freq_hz, uint32_t precis
/* This function will go through all the following clock sources to look
* for a valid divisor which generates the requested frequency. */
for (int i = 0; i < DIM(s_glb_clks); i++) {
/* Before calculating the divisor, we need to have the RTC frequency.
/* Before calculating the divisor, we need to have the RC_FAST frequency.
* If it hasn't been measured yet, try calibrating it now. */
if (s_glb_clks[i] == LEDC_SLOW_CLK_RTC8M && s_ledc_slow_clk_8M == 0 && !ledc_slow_clk_calibrate()) {
ESP_LOGD(LEDC_TAG, "Unable to retrieve RTC clock frequency, skipping it\n");
if (s_glb_clks[i] == LEDC_SLOW_CLK_RC_FAST && s_ledc_slow_clk_rc_fast_freq == 0 && !ledc_slow_clk_calibrate()) {
ESP_LOGD(LEDC_TAG, "Unable to retrieve RC_FAST clock frequency, skipping it\n");
continue;
}
clk_freq = ledc_get_glb_clk_freq(s_glb_clks[i]);
clk_tree_src_get_freq_hz((soc_module_clk_t)s_glb_clks[i], LEDC_CLK_SRC_FREQ_PRECISION, &clk_freq);
uint32_t div_param = ledc_calculate_divisor(clk_freq, freq_hz, precision);
/* If the divisor is valid, we can return this value. */
@ -379,16 +333,18 @@ static inline uint32_t ledc_auto_global_clk_divisor(int freq_hz, uint32_t precis
#if SOC_LEDC_HAS_TIMER_SPECIFIC_MUX
static inline uint32_t ledc_auto_timer_specific_clk_divisor(ledc_mode_t speed_mode, int freq_hz, uint32_t precision,
ledc_clk_src_t* clk_source)
ledc_clk_src_t *clk_source)
{
uint32_t ret = LEDC_CLK_NOT_FOUND;
uint32_t clk_freq = 0;
for (int i = 0; i < DIM(s_timer_specific_clks); i++) {
uint32_t div_param = ledc_calculate_divisor(s_timer_specific_clks[i].freq, freq_hz, precision);
clk_tree_src_get_freq_hz((soc_module_clk_t)s_timer_specific_clks[i], LEDC_CLK_SRC_FREQ_PRECISION, &clk_freq);
uint32_t div_param = ledc_calculate_divisor(clk_freq, freq_hz, precision);
/* If the divisor is valid, we can return this value. */
if (!LEDC_IS_DIV_INVALID(div_param)) {
*clk_source = s_timer_specific_clks[i].clk;
*clk_source = s_timer_specific_clks[i];
ret = div_param;
break;
}
@ -400,7 +356,8 @@ static inline uint32_t ledc_auto_timer_specific_clk_divisor(ledc_mode_t speed_mo
* to test APB. */
if (speed_mode == LEDC_HIGH_SPEED_MODE && ret == LEDC_CLK_NOT_FOUND) {
/* No divider was found yet, try with APB! */
uint32_t div_param = ledc_calculate_divisor(esp_clk_apb_freq(), freq_hz, precision);
clk_tree_src_get_freq_hz((soc_module_clk_t)LEDC_APB_CLK, LEDC_CLK_SRC_FREQ_PRECISION, &clk_freq);
uint32_t div_param = ledc_calculate_divisor(clk_freq, freq_hz, precision);
if (!LEDC_IS_DIV_INVALID(div_param)) {
*clk_source = LEDC_APB_CLK;
@ -418,7 +375,7 @@ static inline uint32_t ledc_auto_timer_specific_clk_divisor(ledc_mode_t speed_mo
* by the caller.
*/
static uint32_t ledc_auto_clk_divisor(ledc_mode_t speed_mode, int freq_hz, uint32_t precision,
ledc_clk_src_t* clk_source, ledc_slow_clk_sel_t* clk_target)
ledc_clk_src_t *clk_source, ledc_slow_clk_sel_t *clk_target)
{
uint32_t ret = LEDC_CLK_NOT_FOUND;
@ -447,41 +404,6 @@ static uint32_t ledc_auto_clk_divisor(ledc_mode_t speed_mode, int freq_hz, uint3
return ret;
}
static ledc_slow_clk_sel_t ledc_clk_cfg_to_global_clk(const ledc_clk_cfg_t clk_cfg)
{
ledc_slow_clk_sel_t glb_clk;
switch (clk_cfg) {
#if SOC_LEDC_SUPPORT_APB_CLOCK
case LEDC_USE_APB_CLK:
glb_clk = LEDC_SLOW_CLK_APB;
break;
#endif
#if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
case LEDC_USE_PLL_DIV_CLK:
glb_clk = LEDC_SLOW_CLK_PLL_DIV;
break;
#endif
case LEDC_USE_RTC8M_CLK:
glb_clk = LEDC_SLOW_CLK_RTC8M;
break;
#if SOC_LEDC_SUPPORT_XTAL_CLOCK
case LEDC_USE_XTAL_CLK:
glb_clk = LEDC_SLOW_CLK_XTAL;
break;
#endif
#if SOC_LEDC_SUPPORT_REF_TICK
case LEDC_USE_REF_TICK:
#endif
default:
/* We should not get here, REF_TICK is NOT a global clock,
* it is a timer-specific clock. */
abort();
}
return glb_clk;
}
extern void esp_sleep_periph_use_8m(bool use_or_not);
/**
@ -503,23 +425,23 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
if (clk_cfg == LEDC_AUTO_CLK) {
/* User hasn't specified the speed, we should try to guess it. */
div_param = ledc_auto_clk_divisor(speed_mode, freq_hz, precision, &timer_clk_src, &glb_clk);
} else if (clk_cfg == LEDC_USE_RTC8M_CLK) {
/* User specified source clock(RTC8M_CLK) for low speed channel.
} else if (clk_cfg == LEDC_USE_RC_FAST_CLK) {
/* User specified source clock(RC_FAST_CLK) for low speed channel.
* Make sure the speed mode is correct. */
ESP_RETURN_ON_FALSE((speed_mode == LEDC_LOW_SPEED_MODE), ESP_ERR_INVALID_ARG, LEDC_TAG, "RTC clock can only be used in low speed mode");
ESP_RETURN_ON_FALSE((speed_mode == LEDC_LOW_SPEED_MODE), ESP_ERR_INVALID_ARG, LEDC_TAG, "RC_FAST clock can only be used in low speed mode");
/* Before calculating the divisor, we need to have the RTC frequency.
/* Before calculating the divisor, we need to have the RC_FAST frequency.
* If it hasn't been measured yet, try calibrating it now. */
if(s_ledc_slow_clk_8M == 0 && ledc_slow_clk_calibrate() == false) {
if(s_ledc_slow_clk_rc_fast_freq == 0 && ledc_slow_clk_calibrate() == false) {
goto error;
}
/* Set the global clock source */
timer_clk_src = LEDC_SCLK;
glb_clk = LEDC_SLOW_CLK_RTC8M;
glb_clk = LEDC_SLOW_CLK_RC_FAST;
/* We have the RTC clock frequency now. */
div_param = ledc_calculate_divisor(s_ledc_slow_clk_8M, freq_hz, precision);
/* We have the RC_FAST clock frequency now. */
div_param = ledc_calculate_divisor(s_ledc_slow_clk_rc_fast_freq, freq_hz, precision);
if (LEDC_IS_DIV_INVALID(div_param)) {
div_param = LEDC_CLK_NOT_FOUND;
}
@ -535,10 +457,14 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
#endif
{
timer_clk_src = LEDC_SCLK;
glb_clk = ledc_clk_cfg_to_global_clk(clk_cfg);
#if SOC_LEDC_SUPPORT_REF_TICK
assert(clk_cfg != LEDC_USE_REF_TICK); // REF_TICK is NOT a global clock, it is a timer-specific clock
#endif
glb_clk = (ledc_slow_clk_sel_t)clk_cfg;
}
uint32_t src_clk_freq = ledc_get_src_clk_freq(clk_cfg);
uint32_t src_clk_freq = 0;
clk_tree_src_get_freq_hz((soc_module_clk_t)clk_cfg, LEDC_CLK_SRC_FREQ_PRECISION, &src_clk_freq);
div_param = ledc_calculate_divisor(src_clk_freq, freq_hz, precision);
if (LEDC_IS_DIV_INVALID(div_param)) {
div_param = LEDC_CLK_NOT_FOUND;
@ -576,7 +502,7 @@ static esp_err_t ledc_set_timer_div(ledc_mode_t speed_mode, ledc_timer_t timer_n
ESP_LOGD(LEDC_TAG, "In slow speed mode, global clk set: %d", glb_clk);
/* keep ESP_PD_DOMAIN_RC_FAST on during light sleep */
esp_sleep_periph_use_8m(glb_clk == LEDC_SLOW_CLK_RTC8M);
esp_sleep_periph_use_8m(glb_clk == LEDC_SLOW_CLK_RC_FAST);
portENTER_CRITICAL(&ledc_spinlock);
ledc_hal_set_slow_clk_sel(&(p_ledc_obj[speed_mode]->ledc_hal), glb_clk);
@ -600,7 +526,7 @@ esp_err_t ledc_timer_config(const ledc_timer_config_t *timer_conf)
uint32_t timer_num = timer_conf->timer_num;
uint32_t speed_mode = timer_conf->speed_mode;
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
LEDC_ARG_CHECK(!((timer_conf->clk_cfg == LEDC_USE_RTC8M_CLK) && (speed_mode != LEDC_LOW_SPEED_MODE)), "Only low speed channel support RTC8M_CLK");
LEDC_ARG_CHECK(!((timer_conf->clk_cfg == LEDC_USE_RC_FAST_CLK) && (speed_mode != LEDC_LOW_SPEED_MODE)), "Only low speed channel support RC_FAST_CLK");
periph_module_enable(PERIPH_LEDC_MODULE);
if (freq_hz == 0 || duty_resolution == 0 || duty_resolution >= LEDC_TIMER_BIT_MAX) {
ESP_LOGE(LEDC_TAG, "freq_hz=%"PRIu32" duty_resolution=%"PRIu32, freq_hz, duty_resolution);
@ -664,8 +590,8 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf)
return ESP_ERR_NO_MEM;
}
ledc_hal_init(&(p_ledc_obj[speed_mode]->ledc_hal), speed_mode);
#if !CONFIG_IDF_TARGET_ESP32
// On targets other than esp32, the default ledc core(global) clock does not connect to any clock source
#if !(CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32H2)
// On such targets, the default ledc core(global) clock does not connect to any clock source
// Set channel configurations and update bits before core clock is on could lead to error
// Therefore, we should connect the core clock to a real clock source to make it on before any ledc register operation
// It can be switched to the other desired clock sources to meet the output pwm freq requirement later at timer configuration
@ -844,7 +770,8 @@ uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num)
ledc_hal_get_duty_resolution(&(p_ledc_obj[speed_mode]->ledc_hal), timer_num, &duty_resolution);
ledc_hal_get_clk_cfg(&(p_ledc_obj[speed_mode]->ledc_hal), timer_num, &clk_cfg);
uint32_t precision = (0x1 << duty_resolution);
uint32_t src_clk_freq = ledc_get_src_clk_freq(clk_cfg);
uint32_t src_clk_freq = 0;
clk_tree_src_get_freq_hz((soc_module_clk_t)clk_cfg, LEDC_CLK_SRC_FREQ_PRECISION, &src_clk_freq);
portEXIT_CRITICAL(&ledc_spinlock);
if (clock_divider == 0) {
ESP_LOGW(LEDC_TAG, "LEDC timer not configured, call ledc_timer_config to set timer frequency");

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |

View File

@ -20,8 +20,9 @@
#include "esp_timer.h"
#include "driver/ledc.h"
#include "soc/ledc_struct.h"
#include "clk_tree.h"
#define PULSE_IO 18
#define PULSE_IO 5
#define TEST_PWM_FREQ 2000
@ -438,13 +439,13 @@ static int wave_count(int last_time)
}
// the PCNT will count the frequency of it
static void frequency_set_get(ledc_mode_t speed_mode, ledc_timer_t timer, uint32_t freq_hz, int16_t real_freq, int16_t error)
static void frequency_set_get(ledc_mode_t speed_mode, ledc_timer_t timer, uint32_t desired_freq, int16_t theoretical_freq, int16_t error)
{
int count;
TEST_ESP_OK(ledc_set_freq(speed_mode, timer, freq_hz));
count = wave_count(1000);
TEST_ASSERT_INT16_WITHIN(error, real_freq, count);
TEST_ASSERT_EQUAL_INT32(real_freq, ledc_get_freq(speed_mode, timer));
int real_freq;
TEST_ESP_OK(ledc_set_freq(speed_mode, timer, desired_freq));
real_freq = wave_count(1000);
TEST_ASSERT_INT16_WITHIN(error, theoretical_freq, real_freq);
TEST_ASSERT_EQUAL_INT32(theoretical_freq, ledc_get_freq(speed_mode, timer));
}
static void timer_frequency_test(ledc_channel_t channel, ledc_timer_bit_t timer_bit, ledc_timer_t timer, ledc_mode_t speed_mode)
@ -469,7 +470,16 @@ static void timer_frequency_test(ledc_channel_t channel, ledc_timer_bit_t timer_
TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 100, 100, 20);
frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 5000, 5000, 50);
frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 9000, 8992, 50);
// Try a frequency that couldn't be exactly achieved, requires rounding
uint32_t theoretical_freq = 9000;
uint32_t clk_src_freq = 0;
clk_tree_src_get_freq_hz((soc_module_clk_t)TEST_DEFAULT_CLK_CFG, CLK_TREE_SRC_FREQ_PRECISION_EXACT, &clk_src_freq);
if (clk_src_freq == 80 * 1000 * 1000) {
theoretical_freq = 8992;
} else if (clk_src_freq == 96 * 1000 * 1000) {
theoretical_freq = 9009;
}
frequency_set_get(ledc_ch_config.speed_mode, ledc_ch_config.timer_sel, 9000, theoretical_freq, 50);
}
TEST_CASE("LEDC set and get frequency", "[ledc][timeout=60]")
@ -500,8 +510,8 @@ static void timer_set_clk_src_and_freq_test(ledc_mode_t speed_mode, ledc_clk_cfg
};
TEST_ESP_OK(ledc_timer_config(&ledc_time_config));
vTaskDelay(100 / portTICK_PERIOD_MS);
if (clk_src == LEDC_USE_RTC8M_CLK) {
// RTC8M_CLK freq is get from calibration, it is reasonable that divider calculation does a rounding
if (clk_src == LEDC_USE_RC_FAST_CLK) {
// RC_FAST_CLK freq is get from calibration, it is reasonable that divider calculation does a rounding
TEST_ASSERT_UINT32_WITHIN(5, freq_hz, ledc_get_freq(speed_mode, LEDC_TIMER_0));
} else {
TEST_ASSERT_EQUAL_INT32(freq_hz, ledc_get_freq(speed_mode, LEDC_TIMER_0));
@ -526,8 +536,10 @@ TEST_CASE("LEDC timer select specific clock source", "[ledc]")
TEST_ESP_OK(ledc_channel_config(&ledc_ch_config));
if (test_speed_mode == LEDC_LOW_SPEED_MODE) {
printf("Check LEDC_USE_RTC8M_CLK for a 100Hz signal\n");
timer_set_clk_src_and_freq_test(test_speed_mode, LEDC_USE_RTC8M_CLK, 10, 100);
#if SOC_CLK_RC_FAST_SUPPORT_CALIBRATION // Otherwise, the frequency of output PWM signal may not be very accurate
printf("Check LEDC_USE_RC_FAST_CLK for a 100Hz signal\n");
timer_set_clk_src_and_freq_test(test_speed_mode, LEDC_USE_RC_FAST_CLK, 10, 100);
#endif
#if SOC_LEDC_SUPPORT_XTAL_CLOCK
printf("Check LEDC_USE_XTAL_CLK for a 400Hz signal\n");
timer_set_clk_src_and_freq_test(test_speed_mode, LEDC_USE_XTAL_CLK, 13, 400);

View File

@ -25,6 +25,12 @@ uint32_t *freq_value)
case SOC_MOD_CLK_XTAL:
clk_src_freq = 32 * MHZ;
break;
case SOC_MOD_CLK_PLL_F96M:
clk_src_freq = 96 * MHZ;
break;
case SOC_MOD_CLK_RC_FAST:
clk_src_freq = SOC_CLK_RC_FAST_FREQ_APPROX;
break;
default:
break;
}

View File

@ -68,3 +68,15 @@ uint32_t rtc_clk_apb_freq_get(void)
// ESP32H2-TODO: IDF-6254
return 0;
}
void rtc_dig_clk8m_enable(void)
{
clk_ll_rc_fast_digi_enable();
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
}
void rtc_dig_clk8m_disable(void)
{
clk_ll_rc_fast_digi_disable();
esp_rom_delay_us(SOC_DELAY_RC_FAST_DIGI_SWITCH);
}

View File

@ -98,7 +98,7 @@ TEST_CASE("Power Test: Lightsleep (8M by digital)", "[pm]")
.duty_resolution = LEDC_TIMER_12_BIT,
.timer_num = 0,
.freq_hz = 2 * 1000,
.clk_cfg = LEDC_USE_RTC8M_CLK,
.clk_cfg = LEDC_USE_RC_FAST_CLK,
};
ledc_timer_config(&config);
test_lightsleep();

View File

@ -13,6 +13,10 @@
#include "soc/ledc_periph.h"
#include "soc/ledc_struct.h"
#ifdef __cplusplus
extern "C" {
#endif
#define LEDC_LL_GET_HW() &LEDC
#define LEDC_LL_DUTY_NUM_MAX (LEDC_DUTY_NUM_LSCH0_V)
@ -24,15 +28,11 @@
#define LEDC_LL_GLOBAL_CLOCKS { \
LEDC_SLOW_CLK_APB, \
LEDC_SLOW_CLK_RTC8M, \
}
#define LEDC_LL_TIMER_SPECIFIC_CLOCKS \
{\
{ \
.clk = LEDC_REF_TICK, \
.freq = REF_CLK_FREQ, \
} \
}
LEDC_SLOW_CLK_RC_FAST, \
}
#define LEDC_LL_TIMER_SPECIFIC_CLOCKS {\
LEDC_REF_TICK, \
}
/* On ESP32, APB clock is a timer-specific clock only in fast clock mode */
#define LEDC_LL_IS_TIMER_SPECIFIC_CLOCK(SPEED, CLK) (\
@ -41,10 +41,6 @@
)
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Set LEDC low speed timer clock
*
@ -53,8 +49,9 @@ extern "C" {
*
* @return None
*/
static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t slow_clk_sel){
hw->conf.slow_clk_sel = slow_clk_sel;
static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t slow_clk_sel)
{
hw->conf.slow_clk_sel = (slow_clk_sel == LEDC_SLOW_CLK_APB);
}
/**
@ -65,8 +62,13 @@ static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
*
* @return None
*/
static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t *slow_clk_sel){
*slow_clk_sel = hw->conf.slow_clk_sel;
static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t *slow_clk_sel)
{
if (hw->conf.slow_clk_sel) {
*slow_clk_sel = LEDC_SLOW_CLK_APB;
} else {
*slow_clk_sel = LEDC_SLOW_CLK_RC_FAST;
}
}
/**
@ -78,7 +80,8 @@ static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
*
* @return None
*/
static inline void ledc_ll_ls_timer_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
static inline void ledc_ll_ls_timer_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.low_speed_update = 1;
}
@ -91,7 +94,8 @@ static inline void ledc_ll_ls_timer_update(ledc_dev_t *hw, ledc_mode_t speed_mod
*
* @return None
*/
static inline void ledc_ll_timer_rst(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
static inline void ledc_ll_timer_rst(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 1;
hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 0;
}
@ -105,7 +109,8 @@ static inline void ledc_ll_timer_rst(ledc_dev_t *hw, ledc_mode_t speed_mode, led
*
* @return None
*/
static inline void ledc_ll_timer_pause(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
static inline void ledc_ll_timer_pause(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 1;
}
@ -118,7 +123,8 @@ static inline void ledc_ll_timer_pause(ledc_dev_t *hw, ledc_mode_t speed_mode, l
*
* @return None
*/
static inline void ledc_ll_timer_resume(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
static inline void ledc_ll_timer_resume(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 0;
}
@ -132,7 +138,8 @@ static inline void ledc_ll_timer_resume(ledc_dev_t *hw, ledc_mode_t speed_mode,
*
* @return None
*/
static inline void ledc_ll_set_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider){
static inline void ledc_ll_set_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider = clock_divider;
}
@ -146,7 +153,8 @@ static inline void ledc_ll_set_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_m
*
* @return None
*/
static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *clock_divider){
static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *clock_divider)
{
*clock_divider = hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider;
}
@ -163,7 +171,8 @@ static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_m
*
* @return None
*/
static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t clk_src){
static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t clk_src)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel = (clk_src == LEDC_APB_CLK);
}
@ -177,7 +186,8 @@ static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mo
*
* @return None
*/
static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src){
static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src)
{
if (hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel) {
*clk_src = LEDC_APB_CLK;
} else {
@ -195,7 +205,8 @@ static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mo
*
* @return None
*/
static inline void ledc_ll_set_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t duty_resolution){
static inline void ledc_ll_set_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t duty_resolution)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution = duty_resolution;
}
@ -209,7 +220,8 @@ static inline void ledc_ll_set_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed
*
* @return None
*/
static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *duty_resolution){
static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *duty_resolution)
{
*duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution;
}
@ -222,7 +234,8 @@ static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed
*
* @return None
*/
static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num){
static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num)
{
hw->channel_group[speed_mode].channel[channel_num].conf0.low_speed_update = 1;
}
@ -236,7 +249,8 @@ static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_m
*
* @return None
*/
static inline void ledc_ll_get_max_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *max_duty){
static inline void ledc_ll_get_max_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *max_duty)
{
int timer_sel = hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel;
*max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution));
}
@ -251,7 +265,8 @@ static inline void ledc_ll_get_max_duty(ledc_dev_t *hw, ledc_mode_t speed_mode,
*
* @return None
*/
static inline void ledc_ll_set_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t hpoint_val){
static inline void ledc_ll_set_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t hpoint_val)
{
hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint = hpoint_val;
}
@ -265,7 +280,8 @@ static inline void ledc_ll_set_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, le
*
* @return None
*/
static inline void ledc_ll_get_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *hpoint_val){
static inline void ledc_ll_get_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *hpoint_val)
{
*hpoint_val = hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint;
}
@ -279,7 +295,8 @@ static inline void ledc_ll_get_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, le
*
* @return None
*/
static inline void ledc_ll_set_duty_int_part(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_val){
static inline void ledc_ll_set_duty_int_part(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_val)
{
hw->channel_group[speed_mode].channel[channel_num].duty.duty = duty_val << 4;
}
@ -293,7 +310,8 @@ static inline void ledc_ll_set_duty_int_part(ledc_dev_t *hw, ledc_mode_t speed_m
*
* @return None
*/
static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *duty_val){
static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *duty_val)
{
*duty_val = (hw->channel_group[speed_mode].channel[channel_num].duty_rd.duty_read >> 4);
}
@ -307,7 +325,8 @@ static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc
*
* @return None
*/
static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t duty_direction){
static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t duty_direction)
{
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc = duty_direction;
}
@ -321,7 +340,8 @@ static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_
*
* @return None
*/
static inline void ledc_ll_get_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t *duty_direction){
static inline void ledc_ll_get_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t *duty_direction)
{
*duty_direction = hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc;
}
@ -335,7 +355,8 @@ static inline void ledc_ll_get_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_
*
* @return None
*/
static inline void ledc_ll_set_duty_num(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_num){
static inline void ledc_ll_set_duty_num(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_num)
{
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_num = duty_num;
}
@ -349,7 +370,8 @@ static inline void ledc_ll_set_duty_num(ledc_dev_t *hw, ledc_mode_t speed_mode,
*
* @return None
*/
static inline void ledc_ll_set_duty_cycle(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_cycle){
static inline void ledc_ll_set_duty_cycle(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_cycle)
{
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_cycle = duty_cycle;
}
@ -363,7 +385,8 @@ static inline void ledc_ll_set_duty_cycle(ledc_dev_t *hw, ledc_mode_t speed_mode
*
* @return None
*/
static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_scale){
static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_scale)
{
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_scale = duty_scale;
}
@ -377,7 +400,8 @@ static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode
*
* @return None
*/
static inline void ledc_ll_set_sig_out_en(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool sig_out_en){
static inline void ledc_ll_set_sig_out_en(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool sig_out_en)
{
hw->channel_group[speed_mode].channel[channel_num].conf0.sig_out_en = sig_out_en;
}
@ -391,7 +415,8 @@ static inline void ledc_ll_set_sig_out_en(ledc_dev_t *hw, ledc_mode_t speed_mode
*
* @return None
*/
static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool duty_start){
static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool duty_start)
{
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_start = duty_start;
}
@ -405,7 +430,8 @@ static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode
*
* @return None
*/
static inline void ledc_ll_set_idle_level(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t idle_level){
static inline void ledc_ll_set_idle_level(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t idle_level)
{
hw->channel_group[speed_mode].channel[channel_num].conf0.idle_lv = idle_level & 0x1;
}
@ -419,7 +445,8 @@ static inline void ledc_ll_set_idle_level(ledc_dev_t *hw, ledc_mode_t speed_mode
*
* @return None
*/
static inline void ledc_ll_set_fade_end_intr(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool fade_end_intr_en){
static inline void ledc_ll_set_fade_end_intr(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool fade_end_intr_en)
{
uint32_t value = hw->int_ena.val;
uint32_t int_en_base = (speed_mode == LEDC_LOW_SPEED_MODE) ? LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S : LEDC_DUTY_CHNG_END_HSCH0_INT_ENA_S;
hw->int_ena.val = fade_end_intr_en ? (value | BIT(int_en_base + channel_num)) : (value & (~(BIT(int_en_base + channel_num))));
@ -435,7 +462,8 @@ static inline void ledc_ll_set_fade_end_intr(ledc_dev_t *hw, ledc_mode_t speed_m
*
* @return None
*/
static inline void ledc_ll_get_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, uint32_t *intr_status){
static inline void ledc_ll_get_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, uint32_t *intr_status)
{
uint32_t value = hw->int_st.val;
uint32_t int_en_base = (speed_mode == LEDC_LOW_SPEED_MODE) ? LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S : LEDC_DUTY_CHNG_END_HSCH0_INT_ENA_S;
*intr_status = (value >> int_en_base) & 0xff;
@ -450,7 +478,8 @@ static inline void ledc_ll_get_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t
*
* @return None
*/
static inline void ledc_ll_clear_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num){
static inline void ledc_ll_clear_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num)
{
uint32_t int_en_base = (speed_mode == LEDC_LOW_SPEED_MODE) ? LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S : LEDC_DUTY_CHNG_END_HSCH0_INT_ENA_S;
hw->int_clr.val = BIT(int_en_base + channel_num);
}
@ -465,7 +494,8 @@ static inline void ledc_ll_clear_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_
*
* @return None
*/
static inline void ledc_ll_bind_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t timer_sel){
static inline void ledc_ll_bind_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t timer_sel)
{
hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel = timer_sel;
}
@ -479,7 +509,8 @@ static inline void ledc_ll_bind_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_
*
* @return None
*/
static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t *timer_sel){
static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t *timer_sel)
{
*timer_sel = hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel;
}

View File

@ -25,12 +25,12 @@ extern "C" {
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_CH0_V)
#define LEDC_LL_FRACTIONAL_BITS (8)
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
#define LEDC_LL_GLOBAL_CLOCKS { \
LEDC_SLOW_CLK_PLL_DIV, \
LEDC_SLOW_CLK_XTAL, \
LEDC_SLOW_CLK_RTC8M, \
LEDC_SLOW_CLK_RC_FAST, \
}
#define LEDC_LL_PLL_DIV_CLK_FREQ (60 * 1000000) // PLL_60M_CLK: 60MHz
/**
@ -46,7 +46,7 @@ static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
uint32_t clk_sel_val = 0;
if (slow_clk_sel == LEDC_SLOW_CLK_PLL_DIV) {
clk_sel_val = 1;
} else if (slow_clk_sel == LEDC_SLOW_CLK_RTC8M) {
} else if (slow_clk_sel == LEDC_SLOW_CLK_RC_FAST) {
clk_sel_val = 2;
} else if (slow_clk_sel == LEDC_SLOW_CLK_XTAL) {
clk_sel_val = 3;
@ -68,7 +68,7 @@ static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
if (clk_sel_val == 1) {
*slow_clk_sel = LEDC_SLOW_CLK_PLL_DIV;
} else if (clk_sel_val == 2) {
*slow_clk_sel = LEDC_SLOW_CLK_RTC8M;
*slow_clk_sel = LEDC_SLOW_CLK_RC_FAST;
} else if (clk_sel_val == 3) {
*slow_clk_sel = LEDC_SLOW_CLK_XTAL;
} else {

View File

@ -26,10 +26,11 @@ extern "C" {
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_LSCH0_V)
#define LEDC_LL_FRACTIONAL_BITS (8)
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
#define LEDC_LL_GLOBAL_CLOCKS { \
LEDC_SLOW_CLK_APB, \
LEDC_SLOW_CLK_XTAL, \
LEDC_SLOW_CLK_RTC8M, \
LEDC_SLOW_CLK_RC_FAST, \
}
/**
@ -45,7 +46,7 @@ static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
uint32_t clk_sel_val = 0;
if (slow_clk_sel == LEDC_SLOW_CLK_APB) {
clk_sel_val = 1;
} else if (slow_clk_sel == LEDC_SLOW_CLK_RTC8M) {
} else if (slow_clk_sel == LEDC_SLOW_CLK_RC_FAST) {
clk_sel_val = 2;
} else if (slow_clk_sel == LEDC_SLOW_CLK_XTAL) {
clk_sel_val = 3;
@ -67,7 +68,7 @@ static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
if (clk_sel_val == 1) {
*slow_clk_sel = LEDC_SLOW_CLK_APB;
} else if (clk_sel_val == 2) {
*slow_clk_sel = LEDC_SLOW_CLK_RTC8M;
*slow_clk_sel = LEDC_SLOW_CLK_RC_FAST;
} else if (clk_sel_val == 3) {
*slow_clk_sel = LEDC_SLOW_CLK_XTAL;
} else {

View File

@ -27,12 +27,12 @@ extern "C" {
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_CH0_V)
#define LEDC_LL_FRACTIONAL_BITS (8)
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
#define LEDC_LL_GLOBAL_CLOCKS { \
LEDC_SLOW_CLK_PLL_DIV, \
LEDC_SLOW_CLK_XTAL, \
LEDC_SLOW_CLK_RTC8M, \
LEDC_SLOW_CLK_RC_FAST, \
}
#define LEDC_LL_PLL_DIV_CLK_FREQ (80 * 1000000) // PLL_80M_CLK: 80MHz
/**
@ -63,7 +63,7 @@ static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
uint32_t clk_sel_val = 0;
if (slow_clk_sel == LEDC_SLOW_CLK_PLL_DIV) {
clk_sel_val = 1;
} else if (slow_clk_sel == LEDC_SLOW_CLK_RTC8M) {
} else if (slow_clk_sel == LEDC_SLOW_CLK_RC_FAST) {
clk_sel_val = 2;
} else if (slow_clk_sel == LEDC_SLOW_CLK_XTAL) {
clk_sel_val = 3;
@ -86,7 +86,7 @@ static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
if (clk_sel_val == 1) {
*slow_clk_sel = LEDC_SLOW_CLK_PLL_DIV;
} else if (clk_sel_val == 2) {
*slow_clk_sel = LEDC_SLOW_CLK_RTC8M;
*slow_clk_sel = LEDC_SLOW_CLK_RC_FAST;
} else if (clk_sel_val == 3) {
*slow_clk_sel = LEDC_SLOW_CLK_XTAL;
} else {

View File

@ -11,6 +11,7 @@
#include "soc/clk_tree_defs.h"
#include "soc/rtc.h"
#include "soc/pcr_reg.h"
#include "soc/lp_clkrst_struct.h"
#include "hal/regi2c_ctrl.h"
#include "soc/regi2c_bbpll.h"
#include "hal/assert.h"
@ -167,7 +168,7 @@ static inline bool clk_ll_rc_fast_d256_is_enabled(void)
*/
static inline void clk_ll_rc_fast_digi_enable(void)
{
// ESP32H2-TODO: IDF-6401
LP_CLKRST.clk_to_hp.icg_hp_fosc = 1;
}
/**
@ -175,7 +176,7 @@ static inline void clk_ll_rc_fast_digi_enable(void)
*/
static inline void clk_ll_rc_fast_digi_disable(void)
{
// ESP32H2-TODO: IDF-6401
LP_CLKRST.clk_to_hp.icg_hp_fosc = 0;
}
/**

View File

@ -0,0 +1,553 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
// The LL layer for LEDC register operations.
// Note that most of the register operations in this layer are non-atomic operations.
#pragma once
#include "hal/ledc_types.h"
#include "soc/ledc_struct.h"
#include "soc/ledc_reg.h"
#include "soc/pcr_struct.h"
#include "hal/assert.h"
#ifdef __cplusplus
extern "C" {
#endif
#define LEDC_LL_GET_HW() &LEDC
#define LEDC_LL_DUTY_NUM_MAX (LEDC_CH0_GAMMA_DUTY_NUM_V)
#define LEDC_LL_DUTY_CYCLE_MAX (LEDC_CH0_GAMMA_DUTY_CYCLE_V)
#define LEDC_LL_DUTY_SCALE_MAX (LEDC_CH0_GAMMA_SCALE_V)
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_CH0_V)
#define LEDC_LL_FRACTIONAL_BITS (8)
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
#define LEDC_LL_GLOBAL_CLOCKS { \
LEDC_SLOW_CLK_PLL_DIV, \
LEDC_SLOW_CLK_XTAL, \
LEDC_SLOW_CLK_RC_FAST, \
}
/**
* @brief Enable LEDC function clock
*
* @param hw Beginning address of the peripheral registers
* @param en True to enable, false to disable
*
* @return None
*/
static inline void ledc_ll_enable_clock(ledc_dev_t *hw, bool en)
{
(void)hw;
PCR.ledc_sclk_conf.ledc_sclk_en = en;
}
/**
* @brief Set LEDC low speed timer clock
*
* @param hw Beginning address of the peripheral registers
* @param slow_clk_sel LEDC low speed timer clock source
*
* @return None
*/
static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t slow_clk_sel)
{
(void)hw;
uint32_t clk_sel_val = 3;
if (slow_clk_sel == LEDC_SLOW_CLK_XTAL) {
clk_sel_val = 0;
} else if (slow_clk_sel == LEDC_SLOW_CLK_RC_FAST) {
clk_sel_val = 1;
} else if (slow_clk_sel == LEDC_SLOW_CLK_PLL_DIV) {
clk_sel_val = 2;
}
PCR.ledc_sclk_conf.ledc_sclk_sel = clk_sel_val;
}
/**
* @brief Get LEDC low speed timer clock
*
* @param hw Beginning address of the peripheral registers
* @param slow_clk_sel LEDC low speed timer clock source
*
* @return None
*/
static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t *slow_clk_sel)
{
(void)hw;
uint32_t clk_sel_val = PCR.ledc_sclk_conf.ledc_sclk_sel;
if (clk_sel_val == 0) {
*slow_clk_sel = LEDC_SLOW_CLK_XTAL;
} else if (clk_sel_val == 1) {
*slow_clk_sel = LEDC_SLOW_CLK_RC_FAST;
} else if (clk_sel_val == 2) {
*slow_clk_sel = LEDC_SLOW_CLK_PLL_DIV;
} else {
abort();
}
}
/**
* @brief Update LEDC low speed timer
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
*
* @return None
*/
static inline void ledc_ll_ls_timer_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.para_up = 1;
// Here, we don't wait for the bit gets cleared since it can take quite long depends on the pwm frequency
}
/**
* @brief Reset LEDC timer
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
*
* @return None
*/
static inline void ledc_ll_timer_rst(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 1;
hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 0;
}
/**
* @brief Pause LEDC timer
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
*
* @return None
*/
static inline void ledc_ll_timer_pause(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 1;
}
/**
* @brief Resume LEDC timer
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
*
* @return None
*/
static inline void ledc_ll_timer_resume(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 0;
}
/**
* @brief Set LEDC timer clock divider
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
* @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source
*
* @return None
*/
static inline void ledc_ll_set_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.clk_div = clock_divider;
}
/**
* @brief Get LEDC timer clock divider
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
* @param clock_divider Timer clock divide value, the timer clock is divided from the selected clock source
*
* @return None
*/
static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *clock_divider)
{
*clock_divider = hw->timer_group[speed_mode].timer[timer_sel].conf.clk_div;
}
/**
* @brief Get LEDC timer clock source
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
* @param clk_src Pointer to accept the timer clock source
*
* @return None
*/
static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src)
{
// The target has no timer-specific clock source option
HAL_ASSERT(hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel == 0);
*clk_src = LEDC_SCLK;
}
/**
* @brief Set LEDC duty resolution
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
* @param duty_resolution Resolution of duty setting in number of bits. The range of duty values is [0, (2**duty_resolution)]
*
* @return None
*/
static inline void ledc_ll_set_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t duty_resolution)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.duty_res = duty_resolution;
}
/**
* @brief Get LEDC duty resolution
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
* @param duty_resolution Pointer to accept the resolution of duty setting in number of bits.
*
* @return None
*/
static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *duty_resolution)
{
*duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_res;
}
/**
* @brief Update channel configure when select low speed mode
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
*
* @return None
*/
static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num)
{
hw->channel_group[speed_mode].channel[channel_num].conf0.para_up = 1;
}
/**
* @brief Get LEDC max duty
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param max_duty Pointer to accept the max duty
*
* @return None
*/
static inline void ledc_ll_get_max_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *max_duty)
{
uint32_t timer_sel = hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel;
*max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_res));
}
/**
* @brief Set LEDC hpoint value
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param hpoint_val LEDC hpoint value(max: 0xfffff)
*
* @return None
*/
static inline void ledc_ll_set_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t hpoint_val)
{
hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint = hpoint_val;
}
/**
* @brief Get LEDC hpoint value
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param hpoint_val Pointer to accept the LEDC hpoint value(max: 0xfffff)
*
* @return None
*/
static inline void ledc_ll_get_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *hpoint_val)
{
*hpoint_val = hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint;
}
/**
* @brief Set LEDC the integer part of duty value
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param duty_val LEDC duty value, the range of duty setting is [0, (2**duty_resolution)]
*
* @return None
*/
static inline void ledc_ll_set_duty_int_part(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_val)
{
hw->channel_group[speed_mode].channel[channel_num].duty.duty = duty_val << 4;
}
/**
* @brief Get LEDC duty value
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param duty_val Pointer to accept the LEDC duty value
*
* @return None
*/
static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *duty_val)
{
*duty_val = (hw->channel_group[speed_mode].channel[channel_num].duty_rd.duty_r >> 4);
}
/**
* @brief Set LEDC duty change direction
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param duty_direction LEDC duty change direction, increase or decrease
*
* @return None
*/
static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t duty_direction)
{
hw->channel_gamma_group[speed_mode].channel[channel_num].wr.gamma_duty_inc = duty_direction;
}
/**
* @brief Get LEDC duty change direction
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param duty_direction Pointer to accept the LEDC duty change direction, increase or decrease
*
* @return None
*/
static inline void ledc_ll_get_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t *duty_direction)
{
*duty_direction = (ledc_duty_direction_t)(hw->channel_gamma_group[speed_mode].channel[channel_num].wr.gamma_duty_inc);
}
/**
* @brief Set the number of increased or decreased times
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param duty_num The number of increased or decreased times
*
* @return None
*/
static inline void ledc_ll_set_duty_num(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_num)
{
hw->channel_gamma_group[speed_mode].channel[channel_num].wr.gamma_duty_num = duty_num;
}
/**
* @brief Set the duty cycles of increase or decrease
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param duty_cycle The duty cycles
*
* @return None
*/
static inline void ledc_ll_set_duty_cycle(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_cycle)
{
hw->channel_gamma_group[speed_mode].channel[channel_num].wr.gamma_duty_cycle = duty_cycle;
}
/**
* @brief Set the step scale of increase or decrease
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param duty_scale The step scale
*
* @return None
*/
static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_scale)
{
hw->channel_gamma_group[speed_mode].channel[channel_num].wr.gamma_scale = duty_scale;
}
/**
* @brief Set the range number of the specified duty configurations written to gamma_wr register
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param duty_range Range index (0 - (SOC_LEDC_GAMMA_FADE_RANGE_MAX-1)), it specifies to which range the configurations in gamma_wr register apply
*
* @return None
*/
static inline void ledc_ll_set_duty_range(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_range)
{
hw->channel_gamma_group[speed_mode].channel[channel_num].wr_addr.gamma_wr_addr = duty_range;
}
/**
* @brief Set the total number of ranges in one fading
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param range_num Total number of ranges (1 - SOC_LEDC_GAMMA_FADE_RANGE_MAX) of the fading configured
*
* @return None
*/
static inline void ledc_ll_set_range_number(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t range_num)
{
hw->channel_gamma_conf_group[speed_mode].gamma_conf[channel_num].gamma_entry_num = range_num;
}
/**
* @brief Set the output enable
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param sig_out_en The output enable status
*
* @return None
*/
static inline void ledc_ll_set_sig_out_en(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool sig_out_en)
{
hw->channel_group[speed_mode].channel[channel_num].conf0.sig_out_en = sig_out_en;
}
/**
* @brief Set the duty start
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param duty_start The duty start
*
* @return None
*/
static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool duty_start)
{
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_start = duty_start;
}
/**
* @brief Set output idle level
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param idle_level The output idle level
*
* @return None
*/
static inline void ledc_ll_set_idle_level(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t idle_level)
{
hw->channel_group[speed_mode].channel[channel_num].conf0.idle_lv = idle_level & 0x1;
}
/**
* @brief Set fade end interrupt enable
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param fade_end_intr_en The fade end interrupt enable status
*
* @return None
*/
static inline void ledc_ll_set_fade_end_intr(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool fade_end_intr_en)
{
uint32_t value = hw->int_ena.val;
uint32_t int_en_base = LEDC_DUTY_CHNG_END_CH0_INT_ENA_S;
hw->int_ena.val = fade_end_intr_en ? (value | BIT(int_en_base + channel_num)) : (value & (~(BIT(int_en_base + channel_num))));
}
/**
* @brief Get fade end interrupt status
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param intr_status The fade end interrupt status
*
* @return None
*/
static inline void ledc_ll_get_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, uint32_t *intr_status)
{
uint32_t value = hw->int_st.val;
uint32_t int_en_base = LEDC_DUTY_CHNG_END_CH0_INT_ENA_S;
*intr_status = (value >> int_en_base) & 0xff;
}
/**
* @brief Clear fade end interrupt status
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
*
* @return None
*/
static inline void ledc_ll_clear_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num)
{
uint32_t int_en_base = LEDC_DUTY_CHNG_END_CH0_INT_ENA_S;
hw->int_clr.val = BIT(int_en_base + channel_num);
}
/**
* @brief Set timer index of the specified channel
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_t
*
* @return None
*/
static inline void ledc_ll_bind_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t timer_sel)
{
hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel = timer_sel;
}
/**
* @brief Get timer index of the specified channel
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, low-speed mode only
* @param channel_num LEDC channel index (0-5), select from ledc_channel_t
* @param timer_sel Pointer to accept the LEDC timer index
*
* @return None
*/
static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t *timer_sel)
{
*timer_sel = (ledc_timer_t)(hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel);
}
#ifdef __cplusplus
}
#endif

View File

@ -26,11 +26,12 @@ extern "C" {
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_LSCH0_V)
#define LEDC_LL_FRACTIONAL_BITS (8)
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
#define LEDC_LL_GLOBAL_CLOCKS { \
LEDC_SLOW_CLK_APB, \
LEDC_SLOW_CLK_XTAL, \
LEDC_SLOW_CLK_RTC8M, \
}
LEDC_SLOW_CLK_RC_FAST, \
}
/**
* @brief Set LEDC low speed timer clock
@ -45,7 +46,7 @@ static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
uint32_t clk_sel_val = 0;
if (slow_clk_sel == LEDC_SLOW_CLK_APB) {
clk_sel_val = 1;
} else if (slow_clk_sel == LEDC_SLOW_CLK_RTC8M) {
} else if (slow_clk_sel == LEDC_SLOW_CLK_RC_FAST) {
clk_sel_val = 2;
} else if (slow_clk_sel == LEDC_SLOW_CLK_XTAL) {
clk_sel_val = 3;
@ -67,7 +68,7 @@ static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
if (clk_sel_val == 1) {
*slow_clk_sel = LEDC_SLOW_CLK_APB;
} else if (clk_sel_val == 2) {
*slow_clk_sel = LEDC_SLOW_CLK_RTC8M;
*slow_clk_sel = LEDC_SLOW_CLK_RC_FAST;
} else if (clk_sel_val == 3) {
*slow_clk_sel = LEDC_SLOW_CLK_XTAL;
} else {

View File

@ -26,18 +26,15 @@ extern "C" {
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_LSCH0_V)
#define LEDC_LL_FRACTIONAL_BITS (8)
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
#define LEDC_LL_GLOBAL_CLOCKS { \
LEDC_SLOW_CLK_APB, \
LEDC_SLOW_CLK_XTAL, \
LEDC_SLOW_CLK_RTC8M, \
LEDC_SLOW_CLK_RC_FAST, \
}
#define LEDC_LL_TIMER_SPECIFIC_CLOCKS \
{\
{ \
.clk = LEDC_REF_TICK, \
.freq = REF_CLK_FREQ, \
} \
}
#define LEDC_LL_TIMER_SPECIFIC_CLOCKS {\
LEDC_REF_TICK, \
}
#define LEDC_LL_IS_TIMER_SPECIFIC_CLOCK(SPEED, CLK) ((CLK) == LEDC_USE_REF_TICK)
@ -49,11 +46,12 @@ extern "C" {
*
* @return None
*/
static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t slow_clk_sel){
static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t slow_clk_sel)
{
uint32_t clk_sel_val = 0;
if (slow_clk_sel == LEDC_SLOW_CLK_APB) {
clk_sel_val = 1;
} else if (slow_clk_sel == LEDC_SLOW_CLK_RTC8M) {
} else if (slow_clk_sel == LEDC_SLOW_CLK_RC_FAST) {
clk_sel_val = 2;
} else if (slow_clk_sel == LEDC_SLOW_CLK_XTAL) {
clk_sel_val = 3;
@ -69,12 +67,13 @@ static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
*
* @return None
*/
static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t *slow_clk_sel){
static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t *slow_clk_sel)
{
uint32_t clk_sel_val = hw->conf.apb_clk_sel;
if (clk_sel_val == 1) {
*slow_clk_sel = LEDC_SLOW_CLK_APB;
} else if (clk_sel_val == 2) {
*slow_clk_sel = LEDC_SLOW_CLK_RTC8M;
*slow_clk_sel = LEDC_SLOW_CLK_RC_FAST;
} else if (clk_sel_val == 3) {
*slow_clk_sel = LEDC_SLOW_CLK_XTAL;
} else {
@ -91,7 +90,8 @@ static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
*
* @return None
*/
static inline void ledc_ll_ls_timer_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
static inline void ledc_ll_ls_timer_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.low_speed_update = 1;
}
@ -104,7 +104,8 @@ static inline void ledc_ll_ls_timer_update(ledc_dev_t *hw, ledc_mode_t speed_mod
*
* @return None
*/
static inline void ledc_ll_timer_rst(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
static inline void ledc_ll_timer_rst(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 1;
hw->timer_group[speed_mode].timer[timer_sel].conf.rst = 0;
}
@ -118,7 +119,8 @@ static inline void ledc_ll_timer_rst(ledc_dev_t *hw, ledc_mode_t speed_mode, led
*
* @return None
*/
static inline void ledc_ll_timer_pause(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
static inline void ledc_ll_timer_pause(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 1;
}
@ -131,7 +133,8 @@ static inline void ledc_ll_timer_pause(ledc_dev_t *hw, ledc_mode_t speed_mode, l
*
* @return None
*/
static inline void ledc_ll_timer_resume(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel){
static inline void ledc_ll_timer_resume(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.pause = 0;
}
@ -145,7 +148,8 @@ static inline void ledc_ll_timer_resume(ledc_dev_t *hw, ledc_mode_t speed_mode,
*
* @return None
*/
static inline void ledc_ll_set_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider){
static inline void ledc_ll_set_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t clock_divider)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider = clock_divider;
}
@ -159,7 +163,8 @@ static inline void ledc_ll_set_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_m
*
* @return None
*/
static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *clock_divider){
static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *clock_divider)
{
*clock_divider = hw->timer_group[speed_mode].timer[timer_sel].conf.clock_divider;
}
@ -176,7 +181,8 @@ static inline void ledc_ll_get_clock_divider(ledc_dev_t *hw, ledc_mode_t speed_m
*
* @return None
*/
static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t clk_src){
static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t clk_src)
{
if (clk_src == LEDC_REF_TICK) {
hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel = 1;
} else {
@ -194,7 +200,8 @@ static inline void ledc_ll_set_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mo
*
* @return None
*/
static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src){
static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, ledc_clk_src_t *clk_src)
{
if (hw->timer_group[speed_mode].timer[timer_sel].conf.tick_sel == 1) {
*clk_src = LEDC_REF_TICK;
} else {
@ -212,7 +219,8 @@ static inline void ledc_ll_get_clock_source(ledc_dev_t *hw, ledc_mode_t speed_mo
*
* @return None
*/
static inline void ledc_ll_set_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t duty_resolution){
static inline void ledc_ll_set_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t duty_resolution)
{
hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution = duty_resolution;
}
@ -226,7 +234,8 @@ static inline void ledc_ll_set_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed
*
* @return None
*/
static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *duty_resolution){
static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t *duty_resolution)
{
*duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution;
}
@ -239,7 +248,8 @@ static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed
*
* @return None
*/
static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num){
static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num)
{
hw->channel_group[speed_mode].channel[channel_num].conf0.low_speed_update = 1;
}
@ -253,7 +263,8 @@ static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_m
*
* @return None
*/
static inline void ledc_ll_get_max_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *max_duty){
static inline void ledc_ll_get_max_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *max_duty)
{
uint32_t timer_sel = hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel;
*max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution));
}
@ -268,7 +279,8 @@ static inline void ledc_ll_get_max_duty(ledc_dev_t *hw, ledc_mode_t speed_mode,
*
* @return None
*/
static inline void ledc_ll_set_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t hpoint_val){
static inline void ledc_ll_set_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t hpoint_val)
{
hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint = hpoint_val;
}
@ -282,7 +294,8 @@ static inline void ledc_ll_set_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, le
*
* @return None
*/
static inline void ledc_ll_get_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *hpoint_val){
static inline void ledc_ll_get_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *hpoint_val)
{
*hpoint_val = hw->channel_group[speed_mode].channel[channel_num].hpoint.hpoint;
}
@ -296,7 +309,8 @@ static inline void ledc_ll_get_hpoint(ledc_dev_t *hw, ledc_mode_t speed_mode, le
*
* @return None
*/
static inline void ledc_ll_set_duty_int_part(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_val){
static inline void ledc_ll_set_duty_int_part(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_val)
{
hw->channel_group[speed_mode].channel[channel_num].duty.duty = duty_val << 4;
}
@ -310,7 +324,8 @@ static inline void ledc_ll_set_duty_int_part(ledc_dev_t *hw, ledc_mode_t speed_m
*
* @return None
*/
static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *duty_val){
static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *duty_val)
{
*duty_val = (hw->channel_group[speed_mode].channel[channel_num].duty_rd.duty_read >> 4);
}
@ -324,7 +339,8 @@ static inline void ledc_ll_get_duty(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc
*
* @return None
*/
static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t duty_direction){
static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t duty_direction)
{
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc = duty_direction;
}
@ -338,7 +354,8 @@ static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_
*
* @return None
*/
static inline void ledc_ll_get_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t *duty_direction){
static inline void ledc_ll_get_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_duty_direction_t *duty_direction)
{
*duty_direction = hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc;
}
@ -352,7 +369,8 @@ static inline void ledc_ll_get_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_
*
* @return None
*/
static inline void ledc_ll_set_duty_num(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_num){
static inline void ledc_ll_set_duty_num(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_num)
{
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_num = duty_num;
}
@ -366,7 +384,8 @@ static inline void ledc_ll_set_duty_num(ledc_dev_t *hw, ledc_mode_t speed_mode,
*
* @return None
*/
static inline void ledc_ll_set_duty_cycle(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_cycle){
static inline void ledc_ll_set_duty_cycle(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_cycle)
{
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_cycle = duty_cycle;
}
@ -380,7 +399,8 @@ static inline void ledc_ll_set_duty_cycle(ledc_dev_t *hw, ledc_mode_t speed_mode
*
* @return None
*/
static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_scale){
static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t duty_scale)
{
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_scale = duty_scale;
}
@ -394,7 +414,8 @@ static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode
*
* @return None
*/
static inline void ledc_ll_set_sig_out_en(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool sig_out_en){
static inline void ledc_ll_set_sig_out_en(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool sig_out_en)
{
hw->channel_group[speed_mode].channel[channel_num].conf0.sig_out_en = sig_out_en;
}
@ -408,7 +429,8 @@ static inline void ledc_ll_set_sig_out_en(ledc_dev_t *hw, ledc_mode_t speed_mode
*
* @return None
*/
static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool duty_start){
static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool duty_start)
{
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_start = duty_start;
}
@ -422,7 +444,8 @@ static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode
*
* @return None
*/
static inline void ledc_ll_set_idle_level(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t idle_level){
static inline void ledc_ll_set_idle_level(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t idle_level)
{
hw->channel_group[speed_mode].channel[channel_num].conf0.idle_lv = idle_level & 0x1;
}
@ -436,7 +459,8 @@ static inline void ledc_ll_set_idle_level(ledc_dev_t *hw, ledc_mode_t speed_mode
*
* @return None
*/
static inline void ledc_ll_set_fade_end_intr(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool fade_end_intr_en){
static inline void ledc_ll_set_fade_end_intr(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, bool fade_end_intr_en)
{
uint32_t value = hw->int_ena.val;
uint32_t int_en_base = LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
hw->int_ena.val = fade_end_intr_en ? (value | BIT(int_en_base + channel_num)) : (value & (~(BIT(int_en_base + channel_num))));
@ -452,7 +476,8 @@ static inline void ledc_ll_set_fade_end_intr(ledc_dev_t *hw, ledc_mode_t speed_m
*
* @return None
*/
static inline void ledc_ll_get_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, uint32_t *intr_status){
static inline void ledc_ll_get_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, uint32_t *intr_status)
{
uint32_t value = hw->int_st.val;
uint32_t int_en_base = LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
*intr_status = (value >> int_en_base) & 0xff;
@ -467,7 +492,8 @@ static inline void ledc_ll_get_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t
*
* @return None
*/
static inline void ledc_ll_clear_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num){
static inline void ledc_ll_clear_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num)
{
uint32_t int_en_base = LEDC_DUTY_CHNG_END_LSCH0_INT_ENA_S;
hw->int_clr.val = BIT(int_en_base + channel_num);
}
@ -482,7 +508,8 @@ static inline void ledc_ll_clear_fade_end_intr_status(ledc_dev_t *hw, ledc_mode_
*
* @return None
*/
static inline void ledc_ll_bind_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t timer_sel){
static inline void ledc_ll_bind_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t timer_sel)
{
hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel = timer_sel;
}
@ -496,7 +523,8 @@ static inline void ledc_ll_bind_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_
*
* @return None
*/
static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t *timer_sel){
static inline void ledc_ll_get_channel_timer(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, ledc_timer_t *timer_sel)
{
*timer_sel = hw->channel_group[speed_mode].channel[channel_num].conf0.timer_sel;
}

View File

@ -26,10 +26,11 @@ extern "C" {
#define LEDC_LL_HPOINT_VAL_MAX (LEDC_HPOINT_LSCH0_V)
#define LEDC_LL_FRACTIONAL_BITS (8)
#define LEDC_LL_FRACTIONAL_MAX ((1 << LEDC_LL_FRACTIONAL_BITS) - 1)
#define LEDC_LL_GLOBAL_CLOCKS { \
LEDC_SLOW_CLK_APB, \
LEDC_SLOW_CLK_XTAL, \
LEDC_SLOW_CLK_RTC8M, \
LEDC_SLOW_CLK_RC_FAST, \
}
/**
@ -45,7 +46,7 @@ static inline void ledc_ll_set_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
uint32_t clk_sel_val = 0;
if (slow_clk_sel == LEDC_SLOW_CLK_APB) {
clk_sel_val = 1;
} else if (slow_clk_sel == LEDC_SLOW_CLK_RTC8M) {
} else if (slow_clk_sel == LEDC_SLOW_CLK_RC_FAST) {
clk_sel_val = 2;
} else if (slow_clk_sel == LEDC_SLOW_CLK_XTAL) {
clk_sel_val = 3;
@ -67,7 +68,7 @@ static inline void ledc_ll_get_slow_clk_sel(ledc_dev_t *hw, ledc_slow_clk_sel_t
if (clk_sel_val == 1) {
*slow_clk_sel = LEDC_SLOW_CLK_APB;
} else if (clk_sel_val == 2) {
*slow_clk_sel = LEDC_SLOW_CLK_RTC8M;
*slow_clk_sel = LEDC_SLOW_CLK_RC_FAST;
} else if (clk_sel_val == 3) {
*slow_clk_sel = LEDC_SLOW_CLK_XTAL;
} else {

View File

@ -13,6 +13,7 @@ extern "C" {
#include <stdint.h>
#include <stdbool.h>
#include "soc/soc_caps.h"
#include "soc/clk_tree_defs.h"
typedef enum {
#if SOC_LEDC_SUPPORT_HS_MODE
@ -34,45 +35,41 @@ typedef enum {
LEDC_DUTY_DIR_MAX,
} ledc_duty_direction_t;
/**
* @brief LEDC global clock sources
*/
typedef enum {
LEDC_SLOW_CLK_RTC8M = 0, /*!< LEDC low speed timer clock source is 8MHz RTC clock*/
LEDC_SLOW_CLK_RC_FAST = LEDC_USE_RC_FAST_CLK, /*!< LEDC low speed timer clock source is RC_FAST clock*/
#if SOC_LEDC_SUPPORT_APB_CLOCK
LEDC_SLOW_CLK_APB, /*!< LEDC low speed timer clock source is 80MHz APB clock*/
LEDC_SLOW_CLK_APB = LEDC_USE_APB_CLK, /*!< LEDC low speed timer clock source is 80MHz APB clock*/
#endif
#if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
LEDC_SLOW_CLK_PLL_DIV, /*!< LEDC low speed timer clock source is a PLL_DIV clock*/
LEDC_SLOW_CLK_PLL_DIV = LEDC_USE_PLL_DIV_CLK, /*!< LEDC low speed timer clock source is a PLL_DIV clock*/
#endif
#if SOC_LEDC_SUPPORT_XTAL_CLOCK
LEDC_SLOW_CLK_XTAL, /*!< LEDC low speed timer clock source XTAL clock*/
LEDC_SLOW_CLK_XTAL = LEDC_USE_XTAL_CLK, /*!< LEDC low speed timer clock source XTAL clock*/
#endif
LEDC_SLOW_CLK_RTC8M __attribute__((deprecated)) = LEDC_SLOW_CLK_RC_FAST, /*!< Alias of 'LEDC_SLOW_CLK_RC_FAST'*/
} ledc_slow_clk_sel_t;
/**
* @brief LEDC clock source configuration struct
*
* In theory, the following enumeration shall be placed in LEDC driver's header.
* However, as the next enumeration, `ledc_clk_src_t`, makes the use of some of
* these values and to avoid mutual inclusion of the headers, we must define it
* here.
*/
typedef enum {
LEDC_AUTO_CLK = 0, /*!< The driver will automatically select the source clock based on the giving resolution and duty parameter when init the timer*/
#if SOC_LEDC_SUPPORT_APB_CLOCK
LEDC_USE_APB_CLK, /*!< LEDC timer select APB clock as source clock*/
#endif
#if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
LEDC_USE_PLL_DIV_CLK, /*!< LEDC timer select the PLL_DIV clock available to LEDC peripheral as source clock*/
#endif
LEDC_USE_RTC8M_CLK, /*!< LEDC timer select RTC8M_CLK (i.e. RC_FAST) as source clock. Only for low speed channels and this parameter must be the same for all low speed channels*/
#if SOC_LEDC_SUPPORT_REF_TICK
LEDC_USE_REF_TICK, /*!< LEDC timer select REF_TICK clock as source clock*/
#endif
#if SOC_LEDC_SUPPORT_XTAL_CLOCK
LEDC_USE_XTAL_CLK, /*!< LEDC timer select XTAL clock as source clock*/
#endif
} ledc_clk_cfg_t;
typedef soc_periph_ledc_clk_src_legacy_t ledc_clk_cfg_t;
/* Note: Setting numeric values to match ledc_clk_cfg_t values are a hack to avoid collision with
LEDC_AUTO_CLK in the driver, as these enums have very similar names and user may pass
one of these by mistake. */
/**
* @brief LEDC timer-specific clock sources
*
* Note: Setting numeric values to match ledc_clk_cfg_t values are a hack to avoid collision with
* LEDC_AUTO_CLK in the driver, as these enums have very similar names and user may pass
* one of these by mistake.
*/
typedef enum {
#if SOC_LEDC_SUPPORT_REF_TICK
LEDC_REF_TICK = LEDC_USE_REF_TICK, /*!< LEDC timer clock divided from reference tick (1Mhz) */

View File

@ -19,33 +19,6 @@ void ledc_hal_init(ledc_hal_context_t *hal, ledc_mode_t speed_mode)
hal->speed_mode = speed_mode;
}
static inline ledc_clk_cfg_t ledc_hal_get_slow_clock_helper(ledc_hal_context_t *hal)
{
ledc_slow_clk_sel_t slow_clk;
ledc_hal_get_slow_clk_sel(hal, &slow_clk);
switch (slow_clk) {
#if SOC_LEDC_SUPPORT_APB_CLOCK
case LEDC_SLOW_CLK_APB:
return LEDC_USE_APB_CLK;
#endif
#if SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
case LEDC_SLOW_CLK_PLL_DIV:
return LEDC_USE_PLL_DIV_CLK;
#endif
case LEDC_SLOW_CLK_RTC8M:
return LEDC_USE_RTC8M_CLK;
#if SOC_LEDC_SUPPORT_XTAL_CLOCK
case LEDC_SLOW_CLK_XTAL:
return LEDC_USE_XTAL_CLK;
#endif
default:
// Should never reach here
HAL_ASSERT(false && "invalid slow clock source");
return LEDC_AUTO_CLK;
}
}
void ledc_hal_get_clk_cfg(ledc_hal_context_t *hal, ledc_timer_t timer_sel, ledc_clk_cfg_t *clk_cfg)
{
/* Use the following variable to retrieve the clock source used by the LEDC
@ -72,7 +45,9 @@ void ledc_hal_get_clk_cfg(ledc_hal_context_t *hal, ledc_timer_t timer_sel, ledc_
if (hal->speed_mode == LEDC_LOW_SPEED_MODE) {
/* If the source clock used by LEDC hardware is not REF_TICK, it is
* necessary to retrieve the global clock source used. */
driver_clk = ledc_hal_get_slow_clock_helper(hal);
ledc_slow_clk_sel_t slow_clk;
ledc_hal_get_slow_clk_sel(hal, &slow_clk);
driver_clk = (ledc_clk_cfg_t)slow_clk;
}
#if SOC_LEDC_SUPPORT_HS_MODE
else {

View File

@ -395,7 +395,24 @@ typedef enum {
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_mwdt_clk_src_t;
//////////////////////////////////////////////////LEDC/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of LEDC
*/
#define SOC_LEDC_CLKS {SOC_MOD_CLK_APB, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_REF_TICK}
/**
* @brief Type of LEDC clock source, reserved for the legacy LEDC driver
*/
typedef enum {
LEDC_AUTO_CLK = 0, /*!< LEDC source clock will be automatically selected based on the giving resolution and duty parameter when init the timer*/
LEDC_USE_APB_CLK = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
LEDC_USE_RC_FAST_CLK = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
LEDC_USE_REF_TICK = SOC_MOD_CLK_REF_TICK, /*!< Select REF_TICK as the source clock */
LEDC_USE_RTC8M_CLK __attribute__((deprecated("please use 'LEDC_USE_RC_FAST_CLK' instead"))) = LEDC_USE_RC_FAST_CLK, /*!< Alias of 'LEDC_USE_RC_FAST_CLK' */
} soc_periph_ledc_clk_src_legacy_t;
#ifdef __cplusplus
}

View File

@ -266,6 +266,24 @@ typedef enum {
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F40M, /*!< Select PLL 40 Mhz as the default clock choice */
} soc_periph_mwdt_clk_src_t;
//////////////////////////////////////////////////LEDC/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of LEDC
*/
#define SOC_LEDC_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F60M, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of LEDC clock source, reserved for the legacy LEDC driver
*/
typedef enum {
LEDC_AUTO_CLK = 0, /*!< LEDC source clock will be automatically selected based on the giving resolution and duty parameter when init the timer*/
LEDC_USE_PLL_DIV_CLK = SOC_MOD_CLK_PLL_F60M, /*!< Select PLL_F60M as the source clock */
LEDC_USE_RC_FAST_CLK = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
LEDC_USE_XTAL_CLK = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
LEDC_USE_RTC8M_CLK __attribute__((deprecated("please use 'LEDC_USE_RC_FAST_CLK' instead"))) = LEDC_USE_RC_FAST_CLK, /*!< Alias of 'LEDC_USE_RC_FAST_CLK' */
} soc_periph_ledc_clk_src_legacy_t;
#ifdef __cplusplus
}

View File

@ -337,6 +337,25 @@ typedef enum {
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_mwdt_clk_src_t;
//////////////////////////////////////////////////LEDC/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of LEDC
*/
#define SOC_LEDC_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_APB, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of LEDC clock source, reserved for the legacy LEDC driver
*/
typedef enum {
LEDC_AUTO_CLK = 0, /*!< LEDC source clock will be automatically selected based on the giving resolution and duty parameter when init the timer*/
LEDC_USE_APB_CLK = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
LEDC_USE_RC_FAST_CLK = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
LEDC_USE_XTAL_CLK = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
LEDC_USE_RTC8M_CLK __attribute__((deprecated("please use 'LEDC_USE_RC_FAST_CLK' instead"))) = LEDC_USE_RC_FAST_CLK, /*!< Alias of 'LEDC_USE_RC_FAST_CLK' */
} soc_periph_ledc_clk_src_legacy_t;
#ifdef __cplusplus
}
#endif

View File

@ -386,6 +386,25 @@ typedef enum {
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL fixed 80 MHz as the default clock choice */
} soc_periph_mwdt_clk_src_t;
//////////////////////////////////////////////////LEDC/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of LEDC
*/
#define SOC_LEDC_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F80M, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of LEDC clock source, reserved for the legacy LEDC driver
*/
typedef enum {
LEDC_AUTO_CLK = 0, /*!< LEDC source clock will be automatically selected based on the giving resolution and duty parameter when init the timer*/
LEDC_USE_PLL_DIV_CLK = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the source clock */
LEDC_USE_RC_FAST_CLK = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
LEDC_USE_XTAL_CLK = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
LEDC_USE_RTC8M_CLK __attribute__((deprecated("please use 'LEDC_USE_RC_FAST_CLK' instead"))) = LEDC_USE_RC_FAST_CLK, /*!< Alias of 'LEDC_USE_RC_FAST_CLK' */
} soc_periph_ledc_clk_src_legacy_t;
#ifdef __cplusplus
}
#endif

View File

@ -51,6 +51,10 @@ config SOC_RMT_SUPPORTED
bool
default y
config SOC_LEDC_SUPPORTED
bool
default y
config SOC_SYSTIMER_SUPPORTED
bool
default y

View File

@ -411,6 +411,8 @@ typedef enum {
#endif
} soc_periph_adc_digi_clk_src_t;
//////////////////////////////////////////////////MWDT/////////////////////////////////////////////////////////////////
/**
* @brief MWDT clock source
*/
@ -422,6 +424,25 @@ typedef enum {
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F96M, /*!< Select PLL as the default clock choice */
} soc_periph_mwdt_clk_src_t;
//////////////////////////////////////////////////LEDC/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of LEDC
*/
#define SOC_LEDC_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F96M, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of LEDC clock source, reserved for the legacy LEDC driver
*/
typedef enum {
LEDC_AUTO_CLK = 0, /*!< LEDC source clock will be automatically selected based on the giving resolution and duty parameter when init the timer*/
LEDC_USE_PLL_DIV_CLK = SOC_MOD_CLK_PLL_F96M, /*!< Select PLL_F96M clock as the source clock */
LEDC_USE_RC_FAST_CLK = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
LEDC_USE_XTAL_CLK = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
LEDC_USE_RTC8M_CLK __attribute__((deprecated("please use 'LEDC_USE_RC_FAST_CLK' instead"))) = LEDC_USE_RC_FAST_CLK, /*!< Alias of 'LEDC_USE_RC_FAST_CLK' */
} soc_periph_ledc_clk_src_legacy_t;
#ifdef __cplusplus
}
#endif

View File

@ -48,6 +48,7 @@
#define SOC_SDM_SUPPORTED 1
#define SOC_RMT_SUPPORTED 1
// #define SOC_GPSPI_SUPPORTED 1 // TODO: IDF-6264
#define SOC_LEDC_SUPPORTED 1
#define SOC_SYSTIMER_SUPPORTED 1
// #define SOC_SUPPORT_COEXISTENCE 1 // TODO: IDF-6416
#define SOC_AES_SUPPORTED 1
@ -195,7 +196,6 @@
#define SOC_I2S_SUPPORTS_TDM (1)
#define SOC_I2S_TDM_FULL_DATA_WIDTH (1) /*!< No limitation to data bit width when using multiple slots */
// TODO: IDF-6235 (Copy from esp32c6, need check)
/*-------------------------- LEDC CAPS ---------------------------------------*/
#define SOC_LEDC_SUPPORT_PLL_DIV_CLOCK (1)
#define SOC_LEDC_SUPPORT_XTAL_CLOCK (1)
@ -263,8 +263,8 @@
#define SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE (SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM * (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3))
/*-------------------------- RTCIO CAPS --------------------------------------*/
/* No dedicated RTCIO subsystem on ESP32-C6. RTC functions are still supported
* for hold, wake & 32kHz crystal functions - via rtc_cntl_reg */
/* No dedicated LP_IO subsystem on ESP32-H2. LP functions are still supported
* for hold, wake & 32kHz crystal functions - via LP_AON registers */
#define SOC_RTCIO_PIN_COUNT (0U)
// TODO: IDF-6284 (Copy from esp32c6, need check)
@ -423,7 +423,7 @@
#define SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY (1) /*!<Supports CRC only the stub code in RTC memory */
/*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
// #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
// #define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1) // TODO: IDF-6265
#define SOC_CLK_XTAL32K_SUPPORTED (1) /*!< Support to connect an external low frequency crystal */
#define SOC_CLK_OSC_SLOW_SUPPORTED (1) /*!< Support to connect an external oscillator, not a crystal */

View File

@ -344,6 +344,24 @@ typedef enum {
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_mwdt_clk_src_t;
//////////////////////////////////////////////////LEDC/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of LEDC
*/
#define SOC_LEDC_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_AHB, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of LEDC clock source, reserved for the legacy LEDC driver
*/
typedef enum {
LEDC_AUTO_CLK = 0, /*!< LEDC source clock will be automatically selected based on the giving resolution and duty parameter when init the timer*/
LEDC_USE_APB_CLK = SOC_MOD_CLK_AHB, /*!< Select APB(=AHB) as the source clock */
LEDC_USE_RC_FAST_CLK = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
LEDC_USE_XTAL_CLK = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
LEDC_USE_RTC8M_CLK __attribute__((deprecated("please use 'LEDC_USE_RC_FAST_CLK' instead"))) = LEDC_USE_RC_FAST_CLK, /*!< Alias of 'LEDC_USE_RC_FAST_CLK' */
} soc_periph_ledc_clk_src_legacy_t;
#ifdef __cplusplus
}

View File

@ -397,6 +397,25 @@ typedef enum {
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_mwdt_clk_src_t;
//////////////////////////////////////////////////LEDC/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of LEDC
*/
#define SOC_LEDC_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_APB, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_REF_TICK}
/**
* @brief Type of LEDC clock source, reserved for the legacy LEDC driver
*/
typedef enum {
LEDC_AUTO_CLK = 0, /*!< LEDC source clock will be automatically selected based on the giving resolution and duty parameter when init the timer*/
LEDC_USE_APB_CLK = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
LEDC_USE_RC_FAST_CLK = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
LEDC_USE_REF_TICK = SOC_MOD_CLK_REF_TICK, /*!< Select REF_TICK as the source clock */
LEDC_USE_XTAL_CLK = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
LEDC_USE_RTC8M_CLK __attribute__((deprecated("please use 'LEDC_USE_RC_FAST_CLK' instead"))) = LEDC_USE_RC_FAST_CLK, /*!< Alias of 'LEDC_USE_RC_FAST_CLK' */
} soc_periph_ledc_clk_src_legacy_t;
#ifdef __cplusplus
}

View File

@ -395,6 +395,24 @@ typedef enum {
MWDT_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */
} soc_periph_mwdt_clk_src_t;
//////////////////////////////////////////////////LEDC/////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of LEDC
*/
#define SOC_LEDC_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_APB, SOC_MOD_CLK_RC_FAST}
/**
* @brief Type of LEDC clock source, reserved for the legacy LEDC driver
*/
typedef enum {
LEDC_AUTO_CLK = 0, /*!< LEDC source clock will be automatically selected based on the giving resolution and duty parameter when init the timer*/
LEDC_USE_APB_CLK = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */
LEDC_USE_RC_FAST_CLK = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */
LEDC_USE_XTAL_CLK = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
LEDC_USE_RTC8M_CLK __attribute__((deprecated("please use 'LEDC_USE_RC_FAST_CLK' instead"))) = LEDC_USE_RC_FAST_CLK, /*!< Alias of 'LEDC_USE_RC_FAST_CLK' */
} soc_periph_ledc_clk_src_legacy_t;
#ifdef __cplusplus
}

View File

@ -84,7 +84,6 @@ api-reference/peripherals/touch_element
api-reference/peripherals/lcd
api-reference/peripherals/mcpwm
api-reference/peripherals/secure_element
api-reference/peripherals/ledc
api-reference/peripherals/temp_sensor
api-reference/peripherals/spi_features
api-reference/peripherals/sdio_slave

View File

@ -85,7 +85,7 @@ The source clock can also limit the PWM frequency. The higher the source clock f
- 1 MHz
- High / Low
- Dynamic Frequency Scaling compatible
* - RTC8M_CLK
* - RC_FAST_CLK
- ~8 MHz
- Low
- Dynamic Frequency Scaling compatible, Light sleep compatible
@ -105,7 +105,7 @@ The source clock can also limit the PWM frequency. The higher the source clock f
* - REF_TICK
- 1 MHz
- Dynamic Frequency Scaling compatible
* - RTC8M_CLK
* - RC_FAST_CLK
- ~8 MHz
- Dynamic Frequency Scaling compatible, Light sleep compatible
* - XTAL_CLK
@ -124,7 +124,7 @@ The source clock can also limit the PWM frequency. The higher the source clock f
* - APB_CLK
- 80 MHz
- /
* - RTC20M_CLK
* - RC_FAST_CLK
- ~20 MHz
- Dynamic Frequency Scaling compatible, Light sleep compatible
* - XTAL_CLK
@ -143,7 +143,7 @@ The source clock can also limit the PWM frequency. The higher the source clock f
* - PLL_60M_CLK
- 60 MHz
- /
* - RTC20M_CLK
* - RC_FAST_CLK
- ~20 MHz
- Dynamic Frequency Scaling compatible, Light sleep compatible
* - XTAL_CLK
@ -162,13 +162,32 @@ The source clock can also limit the PWM frequency. The higher the source clock f
* - PLL_80M_CLK
- 80 MHz
- /
* - RTC20M_CLK
* - RC_FAST_CLK
- ~20 MHz
- Dynamic Frequency Scaling compatible, Light sleep compatible
* - XTAL_CLK
- 40 MHz
- Dynamic Frequency Scaling compatible
.. only:: esp32h2
.. list-table:: Characteristics of {IDF_TARGET_NAME} LEDC source clocks
:widths: 15 15 30
:header-rows: 1
* - Clock name
- Clock freq
- Clock capabilities
* - PLL_96M_CLK
- 96 MHz
- /
* - RC_FAST_CLK
- ~8 MHz
- Dynamic Frequency Scaling compatible, Light sleep compatible
* - XTAL_CLK
- 32 MHz
- Dynamic Frequency Scaling compatible
.. only:: esp32h4
.. list-table:: Characteristics of {IDF_TARGET_NAME} LEDC source clocks
@ -181,7 +200,7 @@ The source clock can also limit the PWM frequency. The higher the source clock f
* - APB_CLK
- 96 MHz
- /
* - RTC8M_CLK
* - RC_FAST_CLK
- ~8 MHz
- Dynamic Frequency Scaling compatible, Light sleep compatible
* - XTAL_CLK
@ -190,13 +209,13 @@ The source clock can also limit the PWM frequency. The higher the source clock f
.. note::
.. only:: not esp32h4
.. only:: SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
1. On {IDF_TARGET_NAME}, if RTCxM_CLK is chosen as the LEDC clock source, an internal calibration will be performed to get the exact frequency of the clock. This ensures the accuracy of output PWM signal frequency.
1. On {IDF_TARGET_NAME}, if RC_FAST_CLK is chosen as the LEDC clock source, an internal calibration will be performed to get the exact frequency of the clock. This ensures the accuracy of output PWM signal frequency.
.. only:: esp32h4
.. only:: not SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
1. On {IDF_TARGET_NAME}, if RTC8M_CLK is chosen as the LEDC clock source, you may see the frequency of output PWM signal is not very accurate. This is because no internal calibration is performed to get the exact frequency of the clock due to hardware limitation, a theoretic frequency value is used.
1. On {IDF_TARGET_NAME}, if RC_FAST_CLK is chosen as the LEDC clock source, you may see the frequency of output PWM signal is not very accurate. This is because no internal calibration is performed to get the exact frequency of the clock due to hardware limitation, a theoretic frequency value is used.
.. only:: not SOC_LEDC_HAS_TIMER_SPECIFIC_MUX

View File

@ -57,3 +57,10 @@ Peripherals
Following items are deprecated. Since IDF v5.1, GPSPI clock source is configurable.
- ``spi_get_actual_clock`` is deprecated, you should use :cpp:func:`spi_device_get_actual_freq` instead.
.. only:: SOC_LEDC_SUPPORTED
LEDC
----
- :cpp:enumerator:`soc_periph_ledc_clk_src_legacy_t::LEDC_USE_RTC8M_CLK` is deprecated. Please use ``LEDC_USE_RC_FAST_CLK`` instead.

View File

@ -85,7 +85,7 @@ LED PWM 控制器可在无需 CPU 干预的情况下自动改变占空比,实
- 1 MHz
- 高速 / 低速
- 支持动态调频DFS功能
* - RTC8M_CLK
* - RC_FAST_CLK
- ~8 MHz
- 低速
- 支持动态调频DFS功能支持Light-sleep模式
@ -105,7 +105,7 @@ LED PWM 控制器可在无需 CPU 干预的情况下自动改变占空比,实
* - REF_TICK
- 1 MHz
- 支持动态调频DFS功能
* - RTC8M_CLK
* - RC_FAST_CLK
- ~8 MHz
- 支持动态调频DFS功能支持Light-sleep模式
* - XTAL_CLK
@ -124,7 +124,7 @@ LED PWM 控制器可在无需 CPU 干预的情况下自动改变占空比,实
* - APB_CLK
- 80 MHz
- /
* - RTC20M_CLK
* - RC_FAST_CLK
- ~20 MHz
- 支持动态调频DFS功能支持Light-sleep模式
* - XTAL_CLK
@ -143,7 +143,7 @@ LED PWM 控制器可在无需 CPU 干预的情况下自动改变占空比,实
* - PLL_60M_CLK
- 60 MHz
- /
* - RTC20M_CLK
* - RC_FAST_CLK
- ~20 MHz
- 支持动态调频DFS功能支持Light-sleep模式
* - XTAL_CLK
@ -162,13 +162,32 @@ LED PWM 控制器可在无需 CPU 干预的情况下自动改变占空比,实
* - PLL_80M_CLK
- 80 MHz
- /
* - RTC20M_CLK
* - RC_FAST_CLK
- ~20 MHz
- 支持动态调频DFS功能支持Light-sleep模式
* - XTAL_CLK
- 40 MHz
- 支持动态调频DFS功能
.. only:: esp32h2
.. list-table:: {IDF_TARGET_NAME} LEDC 时钟源特性
:widths: 10 10 30
:header-rows: 1
* - 时钟名称
- 时钟频率
- 时钟功能
* - PLL_96M_CLK
- 96 MHz
- /
* - RC_FAST_CLK
- ~8 MHz
- 支持动态调频DFS功能支持Light-sleep模式
* - XTAL_CLK
- 32 MHz
- 支持动态调频DFS功能
.. only:: esp32h4
.. list-table:: {IDF_TARGET_NAME} LEDC 时钟源特性
@ -181,7 +200,7 @@ LED PWM 控制器可在无需 CPU 干预的情况下自动改变占空比,实
* - APB_CLK
- 96 MHz
- /
* - RTC8M_CLK
* - RC_FAST_CLK
- ~8 MHz
- 支持动态调频DFS功能支持Light-sleep模式
* - XTAL_CLK
@ -190,13 +209,13 @@ LED PWM 控制器可在无需 CPU 干预的情况下自动改变占空比,实
.. note::
.. only:: not esp32h4
.. only:: SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
1. 如果 {IDF_TARGET_NAME} 的定时器选用了RTCxM_CLK作为其时钟源驱动会通过内部校准来得知这个时钟源的实际频率。这样确保了输出PWM信号频率的精准性。
1. 如果 {IDF_TARGET_NAME} 的定时器选用了RC_FAST_CLK作为其时钟源驱动会通过内部校准来得知这个时钟源的实际频率。这样确保了输出PWM信号频率的精准性。
.. only:: esp32h4
.. only:: not SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
1. 如果 {IDF_TARGET_NAME} 的定时器选用了RTC8M_CLK作为其时钟源LEDC的输出PWM信号频率可能会与设定值有一定偏差。由于{IDF_TARGET_NAME} 的硬件限制,驱动无法通过内部校准得知这个时钟源的实际频率。因此驱动默认使用其理论频率进行计算。
1. 如果 {IDF_TARGET_NAME} 的定时器选用了RC_FAST_CLK作为其时钟源LEDC的输出PWM信号频率可能会与设定值有一定偏差。由于{IDF_TARGET_NAME} 的硬件限制,驱动无法通过内部校准得知这个时钟源的实际频率。因此驱动默认使用其理论频率进行计算。
.. only:: not SOC_LEDC_HAS_TIMER_SPECIFIC_MUX

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
# _LEDC Basic Example_

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
# _LEDC Fade Example_
@ -39,12 +39,12 @@ See the [Getting Started Guide](https://docs.espressif.com/projects/esp-idf/en/l
## Example Output
Running this example, you will see each ledc's brightness changes differently
Running this example, you will see the four LEDs' brightness change repeatedly in the following orders
* LEDC 1: Fade up / increase intensity
* LEDC 2: Fade down / decrease intensity
* LEDC 3: Keep a stable intensity
* LEDC 4: LED is not on
* 1: Fade up / increase intensity on the LEDs connecting to Channel 0/1; Fade down / decrease intensity on the LEDs connecting to Channel 2/3
* 2: Fade down / decrease intensity on the LEDs connecting to Channel 0/1;Fade up / increase intensity on the LEDs connecting to Channel 2/3
* 3: All LEDs keep a stable intensity
* 4: All LEDs are off
you can also see the following output log on the serial monitor: