mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/add_option_to_put_LEDC_into_IRAM' into 'master'
ledc:add option to put LEDC function into IRAM Closes IDFGH-10293 See merge request espressif/esp-idf!24207
This commit is contained in:
commit
2a760522fa
@ -538,4 +538,14 @@ menu "Driver Configurations"
|
||||
|
||||
endmenu # Parallel IO Configuration
|
||||
|
||||
menu "LEDC Configuration"
|
||||
config LEDC_CTRL_FUNC_IN_IRAM
|
||||
bool "Place LEDC control functions into IRAM"
|
||||
default n
|
||||
help
|
||||
Place LEDC control functions (ledc_update_duty and ledc_stop) into IRAM,
|
||||
so that these functions can be IRAM-safe and able to be called in an IRAM context.
|
||||
Enabling this option can improve driver performance as well.
|
||||
endmenu # LEDC Configuration
|
||||
|
||||
endmenu # Driver configurations
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -141,6 +141,9 @@ esp_err_t ledc_timer_config(const ledc_timer_config_t *timer_conf);
|
||||
* @note ledc_set_duty, ledc_set_duty_with_hpoint and ledc_update_duty are not thread-safe, do not call these functions to
|
||||
* control one LEDC channel in different tasks at the same time.
|
||||
* A thread-safe version of API is ledc_set_duty_and_update
|
||||
* @note If `CONFIG_LEDC_CTRL_FUNC_IN_IRAM` is enabled, this function will be placed in the IRAM by linker,
|
||||
* makes it possible to execute even when the Cache is disabled.
|
||||
* @note This function is allowed to run within ISR context.
|
||||
* @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 (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
|
||||
*
|
||||
@ -171,6 +174,9 @@ esp_err_t ledc_set_pin(int gpio_num, ledc_mode_t speed_mode, ledc_channel_t ledc
|
||||
* @brief LEDC stop.
|
||||
* Disable LEDC output, and set idle level
|
||||
*
|
||||
* @note If `CONFIG_LEDC_CTRL_FUNC_IN_IRAM` is enabled, this function will be placed in the IRAM by linker,
|
||||
* makes it possible to execute even when the Cache is disabled.
|
||||
* @note This function is allowed to run within ISR context.
|
||||
* @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 (0 - LEDC_CHANNEL_MAX-1), select from ledc_channel_t
|
||||
* @param idle_level Set output idle level after LEDC stops.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -26,6 +26,8 @@ static __attribute__((unused)) const char *LEDC_TAG = "ledc";
|
||||
|
||||
#define LEDC_CHECK(a, str, ret_val) ESP_RETURN_ON_FALSE(a, ret_val, LEDC_TAG, "%s", str)
|
||||
#define LEDC_ARG_CHECK(a, param) ESP_RETURN_ON_FALSE(a, ESP_ERR_INVALID_ARG, LEDC_TAG, param " argument is invalid")
|
||||
#define LEDC_CHECK_ISR(a, str, ret_val) ESP_RETURN_ON_FALSE_ISR(a, ret_val, LEDC_TAG, "%s", str)
|
||||
#define LEDC_ARG_CHECK_ISR(a, param) ESP_RETURN_ON_FALSE_ISR(a, ESP_ERR_INVALID_ARG, LEDC_TAG, param " argument is invalid")
|
||||
|
||||
#define LEDC_CLK_NOT_FOUND 0
|
||||
#define LEDC_SLOW_CLK_UNINIT -1
|
||||
@ -705,26 +707,26 @@ static void _ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
|
||||
esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC_ARG_CHECK_ISR(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK_ISR(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_CHECK_ISR(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
portENTER_CRITICAL_SAFE(&ledc_spinlock);
|
||||
_ledc_update_duty(speed_mode, channel);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
portEXIT_CRITICAL_SAFE(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level)
|
||||
{
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_CHECK(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC_ARG_CHECK_ISR(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK_ISR(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_CHECK_ISR(p_ledc_obj[speed_mode] != NULL, LEDC_NOT_INIT, ESP_ERR_INVALID_STATE);
|
||||
portENTER_CRITICAL_SAFE(&ledc_spinlock);
|
||||
ledc_hal_set_idle_level(&(p_ledc_obj[speed_mode]->ledc_hal), channel, idle_level);
|
||||
ledc_hal_set_sig_out_en(&(p_ledc_obj[speed_mode]->ledc_hal), channel, false);
|
||||
ledc_hal_set_duty_start(&(p_ledc_obj[speed_mode]->ledc_hal), channel, false);
|
||||
ledc_ls_channel_update(speed_mode, channel);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
portEXIT_CRITICAL_SAFE(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@ -27,3 +27,7 @@ entries:
|
||||
dac_continuous: dac_continuous_write_asynchronously (noflash)
|
||||
if MCPWM_CTRL_FUNC_IN_IRAM = y:
|
||||
mcpwm_cmpr: mcpwm_comparator_set_compare_value (noflash)
|
||||
if LEDC_CTRL_FUNC_IN_IRAM = y:
|
||||
ledc: ledc_stop (noflash)
|
||||
ledc: ledc_update_duty (noflash)
|
||||
ledc: _ledc_update_duty (noflash)
|
||||
|
@ -6,3 +6,4 @@ CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT=y
|
||||
# ledc driver uses assert in the ISR code path
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE=y
|
||||
CONFIG_LEDC_CTRL_FUNC_IN_IRAM=y
|
||||
|
@ -408,6 +408,7 @@ static inline void ledc_ll_set_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
@ -438,6 +439,7 @@ static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
|
@ -393,6 +393,7 @@ static inline void ledc_ll_set_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
@ -423,6 +424,7 @@ static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
|
@ -393,6 +393,7 @@ static inline void ledc_ll_set_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
@ -423,6 +424,7 @@ static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
|
@ -491,6 +491,7 @@ static inline void ledc_ll_get_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
@ -521,6 +522,7 @@ static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
|
@ -489,6 +489,7 @@ static inline void ledc_ll_get_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
@ -519,6 +520,7 @@ static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
|
@ -425,6 +425,7 @@ static inline void ledc_ll_set_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
@ -455,6 +456,7 @@ static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
|
@ -394,6 +394,7 @@ static inline void ledc_ll_set_fade_param(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
@ -424,6 +425,7 @@ static inline void ledc_ll_set_duty_start(ledc_dev_t *hw, ledc_mode_t speed_mode
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user