ledc: Add an all-in-one HAL function to set fade parameters, and refactor ledc_ll_get_max_duty function

This commit is contained in:
Song Ruo Jing 2023-03-28 22:55:18 +08:00
parent 64aec54308
commit fcc6514dde
12 changed files with 320 additions and 240 deletions

View File

@ -459,7 +459,7 @@ esp_err_t ledc_fade_start(ledc_mode_t speed_mode, ledc_channel_t channel, ledc_f
* @brief Stop LEDC fading. The duty of the channel is garanteed to be fixed at most one PWM cycle after the function returns.
* @note This API can be called if a new fixed duty or a new fade want to be set while the last fade operation is still running in progress.
* @note Call this API will abort the fading operation only if it was started by calling ledc_fade_start with LEDC_FADE_NO_WAIT mode.
* @note If a fade was started with LEDC_FADE_WAIT_DONE mode, calling this API afterwards HAS no use in stopping the fade. Fade will continue until it reachs the target duty.
* @note If a fade was started with LEDC_FADE_WAIT_DONE mode, calling this API afterwards has no use in stopping the fade. Fade will continue until it reachs the target duty.
* @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode.
* @param channel LEDC channel number
*

View File

@ -180,8 +180,10 @@ static void _ledc_op_lock_release(ledc_mode_t mode, ledc_channel_t channel)
static uint32_t ledc_get_max_duty(ledc_mode_t speed_mode, ledc_channel_t channel)
{
// The arguments are checked before internally calling this function.
ledc_timer_t timer_sel;
ledc_hal_get_channel_timer(&(p_ledc_obj[speed_mode]->ledc_hal), channel, &timer_sel);
uint32_t max_duty;
ledc_hal_get_max_duty(&(p_ledc_obj[speed_mode]->ledc_hal), channel, &max_duty);
ledc_hal_get_max_duty(&(p_ledc_obj[speed_mode]->ledc_hal), timer_sel, &max_duty);
return max_duty;
}
@ -214,12 +216,8 @@ int duty_val, ledc_duty_direction_t duty_direction, uint32_t duty_num, uint32_t
if (duty_val >= 0) {
ledc_hal_set_duty_int_part(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_val);
}
ledc_hal_set_duty_direction(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_direction);
ledc_hal_set_duty_num(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_num);
ledc_hal_set_duty_cycle(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_cycle);
ledc_hal_set_duty_scale(&(p_ledc_obj[speed_mode]->ledc_hal), channel, duty_scale);
ledc_hal_set_fade_param(&(p_ledc_obj[speed_mode]->ledc_hal), channel, 0, duty_direction, duty_cycle, duty_scale, duty_num);
#if SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
ledc_hal_set_duty_range_wr_addr(&(p_ledc_obj[speed_mode]->ledc_hal), channel, 0);
ledc_hal_set_range_number(&(p_ledc_obj[speed_mode]->ledc_hal), channel, 1);
#endif
return ESP_OK;
@ -853,7 +851,7 @@ uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num)
ESP_LOGW(LEDC_TAG, "LEDC timer not configured, call ledc_timer_config to set timer frequency");
return 0;
}
return ((uint64_t) src_clk_freq << 8) / precision / clock_divider;
return ((uint64_t) src_clk_freq << LEDC_LL_FRACTIONAL_BITS) / precision / clock_divider;
}
static inline void IRAM_ATTR ledc_calc_fade_end_channel(uint32_t *fade_end_status, uint32_t *channel)
@ -1336,11 +1334,7 @@ static esp_err_t _ledc_set_multi_fade(ledc_mode_t speed_mode, ledc_channel_t cha
ledc_hal_set_duty_int_part(&(p_ledc_obj[speed_mode]->ledc_hal), channel, start_duty);
for (int i = 0; i < list_len; i++) {
ledc_fade_param_config_t fade_param = fade_params_list[i];
ledc_hal_set_duty_direction(&(p_ledc_obj[speed_mode]->ledc_hal), channel, fade_param.dir);
ledc_hal_set_duty_cycle(&(p_ledc_obj[speed_mode]->ledc_hal), channel, fade_param.cycle_num);
ledc_hal_set_duty_scale(&(p_ledc_obj[speed_mode]->ledc_hal), channel, fade_param.scale);
ledc_hal_set_duty_num(&(p_ledc_obj[speed_mode]->ledc_hal), channel, fade_param.step_num);
ledc_hal_set_duty_range_wr_addr(&(p_ledc_obj[speed_mode]->ledc_hal), channel, i);
ledc_hal_set_fade_param(&(p_ledc_obj[speed_mode]->ledc_hal), channel, i, fade_param.dir, fade_param.cycle_num, fade_param.scale, fade_param.step_num);
}
ledc_hal_set_range_number(&(p_ledc_obj[speed_mode]->ledc_hal), channel, list_len);
portEXIT_CRITICAL(&ledc_spinlock);

View File

@ -225,6 +225,21 @@ static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed
*duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution;
}
/**
* @brief Get LEDC max duty
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_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_timer_t timer_sel, uint32_t *max_duty)
{
*max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution));
}
/**
* @brief Update channel configure when select low speed mode
*
@ -239,22 +254,6 @@ static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_m
hw->channel_group[speed_mode].channel[channel_num].conf0.low_speed_update = 1;
}
/**
* @brief Get LEDC max duty
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param channel_num LEDC channel index (0-7), 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)
{
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));
}
/**
* @brief Set LEDC hpoint value
*
@ -330,21 +329,6 @@ static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc = duty_direction;
}
/**
* @brief Get LEDC duty change direction
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param channel_num LEDC channel index (0-7), 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 = hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc;
}
/**
* @brief Set the number of increased or decreased times
*
@ -390,6 +374,30 @@ static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_scale = duty_scale;
}
/**
* @brief Function to set fade parameters all-in-one
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
* @param dir LEDC duty change direction, increase or decrease
* @param cycle The duty cycles
* @param scale The step scale
* @param step The number of increased or decreased times
*
* @return None
*/
static inline void ledc_ll_set_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step)
{
typeof(hw->channel_group[speed_mode].channel[channel_num].conf1) conf1_reg;
conf1_reg.val = hw->channel_group[speed_mode].channel[channel_num].conf1.val;
conf1_reg.duty_inc = dir;
conf1_reg.duty_num = step;
conf1_reg.duty_cycle = cycle;
conf1_reg.duty_scale = scale;
hw->channel_group[speed_mode].channel[channel_num].conf1.val = conf1_reg.val;
}
/**
* @brief Set the output enable
*

View File

@ -210,6 +210,21 @@ static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed
*duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_res;
}
/**
* @brief Get LEDC max duty
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_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_timer_t timer_sel, uint32_t *max_duty)
{
*max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_res));
}
/**
* @brief Update channel configure when select low speed mode
*
@ -224,22 +239,6 @@ static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_m
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, high-speed mode or low-speed mode
* @param channel_num LEDC channel index (0-7), 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
*
@ -315,21 +314,6 @@ static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc = duty_direction;
}
/**
* @brief Get LEDC duty change direction
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param channel_num LEDC channel index (0-7), 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 = hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc;
}
/**
* @brief Set the number of increased or decreased times
*
@ -375,6 +359,30 @@ static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_scale = duty_scale;
}
/**
* @brief Function to set fade parameters all-in-one
*
* @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 dir LEDC duty change direction, increase or decrease
* @param cycle The duty cycles
* @param scale The step scale
* @param step The number of increased or decreased times
*
* @return None
*/
static inline void ledc_ll_set_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step)
{
typeof(hw->channel_group[speed_mode].channel[channel_num].conf1) conf1_reg;
conf1_reg.val = hw->channel_group[speed_mode].channel[channel_num].conf1.val;
conf1_reg.duty_inc = dir;
conf1_reg.duty_num = step;
conf1_reg.duty_cycle = cycle;
conf1_reg.duty_scale = scale;
hw->channel_group[speed_mode].channel[channel_num].conf1.val = conf1_reg.val;
}
/**
* @brief Set the output enable
*

View File

@ -210,6 +210,21 @@ static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed
*duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution;
}
/**
* @brief Get LEDC max duty
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_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_timer_t timer_sel, uint32_t *max_duty)
{
*max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution));
}
/**
* @brief Update channel configure when select low speed mode
*
@ -224,22 +239,6 @@ static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_m
hw->channel_group[speed_mode].channel[channel_num].conf0.low_speed_update = 1;
}
/**
* @brief Get LEDC max duty
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param channel_num LEDC channel index (0-7), 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_resolution));
}
/**
* @brief Set LEDC hpoint value
*
@ -315,21 +314,6 @@ static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc = duty_direction;
}
/**
* @brief Get LEDC duty change direction
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param channel_num LEDC channel index (0-7), 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 = hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc;
}
/**
* @brief Set the number of increased or decreased times
*
@ -375,6 +359,30 @@ static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_scale = duty_scale;
}
/**
* @brief Function to set fade parameters all-in-one
*
* @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 dir LEDC duty change direction, increase or decrease
* @param cycle The duty cycles
* @param scale The step scale
* @param step The number of increased or decreased times
*
* @return None
*/
static inline void ledc_ll_set_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step)
{
typeof(hw->channel_group[speed_mode].channel[channel_num].conf1) conf1_reg;
conf1_reg.val = hw->channel_group[speed_mode].channel[channel_num].conf1.val;
conf1_reg.duty_inc = dir;
conf1_reg.duty_num = step;
conf1_reg.duty_cycle = cycle;
conf1_reg.duty_scale = scale;
hw->channel_group[speed_mode].channel[channel_num].conf1.val = conf1_reg.val;
}
/**
* @brief Set the output enable
*

View File

@ -231,6 +231,21 @@ static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed
*duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_res;
}
/**
* @brief Get LEDC max duty
*
* @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 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_timer_t timer_sel, uint32_t *max_duty)
{
*max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_res));
}
/**
* @brief Update channel configure when select low speed mode
*
@ -245,22 +260,6 @@ static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_m
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
*
@ -336,21 +335,6 @@ static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_
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
*
@ -396,6 +380,25 @@ static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode
hw->channel_gamma_group[speed_mode].channel[channel_num].wr.gamma_scale = duty_scale;
}
/**
* @brief Function to set fade parameters all-in-one
*
* @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 dir LEDC duty change direction, increase or decrease
* @param cycle The duty cycles
* @param scale The step scale
* @param step The number of increased or decreased times
*
* @return None
*/
static inline void ledc_ll_set_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step)
{
uint32_t val = (dir << LEDC_CH0_GAMMA_DUTY_INC_S) | (cycle << LEDC_CH0_GAMMA_DUTY_CYCLE_S) | (scale << LEDC_CH0_GAMMA_SCALE_S) | (step << LEDC_CH0_GAMMA_DUTY_NUM_S);
hw->channel_gamma_group[speed_mode].channel[channel_num].wr.val = val;
}
/**
* @brief Set the range number of the specified duty configurations to be written from gamma_wr register to gamma ram
*
@ -469,7 +472,7 @@ static inline void ledc_ll_set_duty_range_rd_addr(ledc_dev_t *hw, ledc_mode_t sp
*
* @return None
*/
static inline void ledc_ll_get_duty_param(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *dir, uint32_t *cycle, uint32_t *scale, uint32_t *step)
static inline void ledc_ll_get_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *dir, uint32_t *cycle, uint32_t *scale, uint32_t *step)
{
uint32_t val = hw->channel_gamma_group[speed_mode].channel[channel_num].rd_data.gamma_rd_data;
*dir = (val & LEDC_CH0_GAMMA_DUTY_INC_M) >> LEDC_CH0_GAMMA_DUTY_INC_S;

View File

@ -229,6 +229,21 @@ static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed
*duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_res;
}
/**
* @brief Get LEDC max duty
*
* @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 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_timer_t timer_sel, uint32_t *max_duty)
{
*max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_res));
}
/**
* @brief Update channel configure when select low speed mode
*
@ -243,22 +258,6 @@ static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_m
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
*
@ -334,21 +333,6 @@ static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_
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
*
@ -394,6 +378,25 @@ static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode
hw->channel_gamma_group[speed_mode].channel[channel_num].wr.gamma_scale = duty_scale;
}
/**
* @brief Function to set fade parameters all-in-one
*
* @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 dir LEDC duty change direction, increase or decrease
* @param cycle The duty cycles
* @param scale The step scale
* @param step The number of increased or decreased times
*
* @return None
*/
static inline void ledc_ll_set_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step)
{
uint32_t val = (dir << LEDC_CH0_GAMMA_DUTY_INC_S) | (cycle << LEDC_CH0_GAMMA_DUTY_CYCLE_S) | (scale << LEDC_CH0_GAMMA_SCALE_S) | (step << LEDC_CH0_GAMMA_DUTY_NUM_S);
hw->channel_gamma_group[speed_mode].channel[channel_num].wr.val = val;
}
/**
* @brief Set the range number of the specified duty configurations to be written from gamma_wr register to gamma ram
*
@ -467,7 +470,7 @@ static inline void ledc_ll_set_duty_range_rd_addr(ledc_dev_t *hw, ledc_mode_t sp
*
* @return None
*/
static inline void ledc_ll_get_duty_param(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *dir, uint32_t *cycle, uint32_t *scale, uint32_t *step)
static inline void ledc_ll_get_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t *dir, uint32_t *cycle, uint32_t *scale, uint32_t *step)
{
uint32_t val = hw->channel_gamma_group[speed_mode].channel[channel_num].rd_data.gamma_rd_data;
*dir = (val & LEDC_CH0_GAMMA_DUTY_INC_M) >> LEDC_CH0_GAMMA_DUTY_INC_S;

View File

@ -242,6 +242,21 @@ static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed
*duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution;
}
/**
* @brief Get LEDC max duty
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_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_timer_t timer_sel, uint32_t *max_duty)
{
*max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution));
}
/**
* @brief Update channel configure when select low speed mode
*
@ -256,22 +271,6 @@ static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_m
hw->channel_group[speed_mode].channel[channel_num].conf0.low_speed_update = 1;
}
/**
* @brief Get LEDC max duty
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param channel_num LEDC channel index (0-7), 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_resolution));
}
/**
* @brief Set LEDC hpoint value
*
@ -347,21 +346,6 @@ static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc = duty_direction;
}
/**
* @brief Get LEDC duty change direction
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param channel_num LEDC channel index (0-7), 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 = hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc;
}
/**
* @brief Set the number of increased or decreased times
*
@ -407,6 +391,30 @@ static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_scale = duty_scale;
}
/**
* @brief Function to set fade parameters all-in-one
*
* @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-7), select from ledc_channel_t
* @param dir LEDC duty change direction, increase or decrease
* @param cycle The duty cycles
* @param scale The step scale
* @param step The number of increased or decreased times
*
* @return None
*/
static inline void ledc_ll_set_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step)
{
typeof(hw->channel_group[speed_mode].channel[channel_num].conf1) conf1_reg;
conf1_reg.val = hw->channel_group[speed_mode].channel[channel_num].conf1.val;
conf1_reg.duty_inc = dir;
conf1_reg.duty_num = step;
conf1_reg.duty_cycle = cycle;
conf1_reg.duty_scale = scale;
hw->channel_group[speed_mode].channel[channel_num].conf1.val = conf1_reg.val;
}
/**
* @brief Set the output enable
*

View File

@ -211,6 +211,21 @@ static inline void ledc_ll_get_duty_resolution(ledc_dev_t *hw, ledc_mode_t speed
*duty_resolution = hw->timer_group[speed_mode].timer[timer_sel].conf.duty_resolution;
}
/**
* @brief Get LEDC max duty
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param timer_sel LEDC timer index (0-3), select from ledc_timer_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_timer_t timer_sel, uint32_t *max_duty)
{
*max_duty = (1 << (LEDC.timer_group[speed_mode].timer[timer_sel].conf.duty_resolution));
}
/**
* @brief Update channel configure when select low speed mode
*
@ -225,22 +240,6 @@ static inline void ledc_ll_ls_channel_update(ledc_dev_t *hw, ledc_mode_t speed_m
hw->channel_group[speed_mode].channel[channel_num].conf0.low_speed_update = 1;
}
/**
* @brief Get LEDC max duty
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param channel_num LEDC channel index (0-7), 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_resolution));
}
/**
* @brief Set LEDC hpoint value
*
@ -316,21 +315,6 @@ static inline void ledc_ll_set_duty_direction(ledc_dev_t *hw, ledc_mode_t speed_
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc = duty_direction;
}
/**
* @brief Get LEDC duty change direction
*
* @param hw Beginning address of the peripheral registers
* @param speed_mode LEDC speed_mode, high-speed mode or low-speed mode
* @param channel_num LEDC channel index (0-7), 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 = hw->channel_group[speed_mode].channel[channel_num].conf1.duty_inc;
}
/**
* @brief Set the number of increased or decreased times
*
@ -376,6 +360,30 @@ static inline void ledc_ll_set_duty_scale(ledc_dev_t *hw, ledc_mode_t speed_mode
hw->channel_group[speed_mode].channel[channel_num].conf1.duty_scale = duty_scale;
}
/**
* @brief Function to set fade parameters all-in-one
*
* @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-7), select from ledc_channel_t
* @param dir LEDC duty change direction, increase or decrease
* @param cycle The duty cycles
* @param scale The step scale
* @param step The number of increased or decreased times
*
* @return None
*/
static inline void ledc_ll_set_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode, ledc_channel_t channel_num, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step)
{
typeof(hw->channel_group[speed_mode].channel[channel_num].conf1) conf1_reg;
conf1_reg.val = hw->channel_group[speed_mode].channel[channel_num].conf1.val;
conf1_reg.duty_inc = dir;
conf1_reg.duty_num = step;
conf1_reg.duty_cycle = cycle;
conf1_reg.duty_scale = scale;
hw->channel_group[speed_mode].channel[channel_num].conf1.val = conf1_reg.val;
}
/**
* @brief Set the output enable
*

View File

@ -157,12 +157,12 @@ typedef struct {
* @brief Get LEDC max duty
*
* @param hal Context of the HAL layer
* @param channel_num LEDC channel index (0-7), select from ledc_channel_t
* @param channel_num LEDC timer index (0-3), select from ledc_timer_t
* @param max_duty Pointer to accept the max duty
*
* @return None
*/
#define ledc_hal_get_max_duty(hal, channel_num, max_duty) ledc_ll_get_max_duty((hal)->dev, (hal)->speed_mode, channel_num, max_duty)
#define ledc_hal_get_max_duty(hal, timer_sel, max_duty) ledc_ll_get_max_duty((hal)->dev, (hal)->speed_mode, timer_sel, max_duty)
/**
* @brief Get LEDC hpoint value
@ -338,6 +338,21 @@ void ledc_hal_set_duty_cycle(ledc_hal_context_t *hal, ledc_channel_t channel_num
*/
void ledc_hal_set_duty_scale(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t duty_scale);
/**
* @brief Function to set fade parameters all-in-one
*
* @param hal Context of the HAL layer
* @param channel_num LEDC channel index, select from ledc_channel_t
* @param range Range index
* @param dir LEDC duty change direction, increase or decrease
* @param cycle The duty cycles
* @param scale The step scale
* @param step The number of increased or decreased times
*
* @return None
*/
void ledc_hal_set_fade_param(const ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t range, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step);
#if SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
/**
* @brief Set the range number of the specified duty configurations to be written from gamma_wr register to gamma ram

View File

@ -6,11 +6,7 @@
// The HAL layer for LEDC (common part)
#include "esp_attr.h"
#include "hal/ledc_hal.h"
#include "soc/soc_caps.h"
#include "sdkconfig.h"
#include "hal/assert.h"
#include "esp_rom_sys.h"
void ledc_hal_init(ledc_hal_context_t *hal, ledc_mode_t speed_mode)
@ -64,9 +60,11 @@ void ledc_hal_get_clk_cfg(ledc_hal_context_t *hal, ledc_timer_t timer_sel, ledc_
void ledc_hal_get_fade_param(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t range, uint32_t *dir, uint32_t *cycle, uint32_t *scale, uint32_t *step)
{
ledc_ll_set_duty_range_rd_addr(hal->dev, hal->speed_mode, channel_num, range);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
// On ESP32C6/H2, gamma ram read/write has the APB and LEDC clock domain sync issue
// To make sure the parameter read is from the correct gamma ram addr, add a delay in between to ensure syncronization
esp_rom_delay_us(5);
ledc_ll_get_duty_param(hal->dev, hal->speed_mode, channel_num, dir, cycle, scale, step);
#endif
ledc_ll_get_fade_param(hal->dev, hal->speed_mode, channel_num, dir, cycle, scale, step);
}
#endif

View File

@ -7,8 +7,9 @@
// The HAL layer for LEDC (common part, in iram)
// make these functions in a seperate file to make sure all LL functions are in the IRAM.
#include "esp_attr.h"
#include "hal/ledc_hal.h"
#include "hal/assert.h"
#include "esp_rom_sys.h"
void ledc_hal_ls_channel_update(ledc_hal_context_t *hal, ledc_channel_t channel_num)
{
@ -55,6 +56,32 @@ void ledc_hal_set_duty_scale(ledc_hal_context_t *hal, ledc_channel_t channel_num
ledc_ll_set_duty_scale(hal->dev, hal->speed_mode, channel_num, duty_scale);
}
void ledc_hal_set_fade_param(const ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t range, uint32_t dir, uint32_t cycle, uint32_t scale, uint32_t step)
{
#if SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
HAL_ASSERT(range < SOC_LEDC_GAMMA_CURVE_FADE_RANGE_MAX);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
// To workaround sync issue (C6, H2)
// This is to ensure the fade param write to the gamma_wr register would not mess up the last wr_addr
ledc_ll_set_duty_range_wr_addr(hal->dev, hal->speed_mode, channel_num, range);
esp_rom_delay_us(5);
#endif
ledc_ll_set_fade_param(hal->dev, hal->speed_mode, channel_num, dir, cycle, scale, step);
ledc_ll_set_duty_range_wr_addr(hal->dev, hal->speed_mode, channel_num, range);
#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
// To workaround sync issue (C6, H2)
// This is to ensure the fade param in gamma_wr register can be written to the correct wr_addr
esp_rom_delay_us(5);
#endif
#else // !SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
HAL_ASSERT(range == 0);
ledc_ll_set_fade_param(hal->dev, hal->speed_mode, channel_num, dir, cycle, scale, step);
#endif // SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
}
#if SOC_LEDC_GAMMA_CURVE_FADE_SUPPORTED
void ledc_hal_set_duty_range_wr_addr(ledc_hal_context_t *hal, ledc_channel_t channel_num, uint32_t duty_range)
{