mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-19 07:55:54 +00:00
feat(ledc): add esp_gpio_reserve to ledc driver
This commit is contained in:
@@ -11,7 +11,6 @@
|
||||
#include "freertos/idf_additions.h"
|
||||
#include "esp_log.h"
|
||||
#include "esp_check.h"
|
||||
#include "soc/gpio_periph.h"
|
||||
#include "soc/ledc_periph.h"
|
||||
#include "esp_clk_tree.h"
|
||||
#include "soc/soc_caps.h"
|
||||
@@ -19,10 +18,10 @@
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "driver/ledc.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "clk_ctrl_os.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/gpio.h"
|
||||
#include "esp_private/esp_gpio_reserve.h"
|
||||
#include "esp_memory_utils.h"
|
||||
|
||||
static __attribute__((unused)) const char *LEDC_TAG = "ledc";
|
||||
@@ -88,7 +87,9 @@ typedef struct {
|
||||
#endif
|
||||
} ledc_obj_t;
|
||||
|
||||
static ledc_obj_t *p_ledc_obj[LEDC_SPEED_MODE_MAX] = {0};
|
||||
static ledc_obj_t *p_ledc_obj[LEDC_SPEED_MODE_MAX] = {
|
||||
[0 ... LEDC_SPEED_MODE_MAX - 1] = NULL,
|
||||
};
|
||||
static ledc_fade_t *s_ledc_fade_rec[LEDC_SPEED_MODE_MAX][LEDC_CHANNEL_MAX];
|
||||
static ledc_isr_handle_t s_ledc_fade_isr_handle = NULL;
|
||||
static portMUX_TYPE ledc_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
@@ -641,17 +642,30 @@ esp_err_t ledc_timer_config(const ledc_timer_config_t *timer_conf)
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t ledc_set_pin(int gpio_num, ledc_mode_t speed_mode, ledc_channel_t ledc_channel)
|
||||
esp_err_t _ledc_set_pin(int gpio_num, bool out_inv, ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
LEDC_ARG_CHECK(ledc_channel < LEDC_CHANNEL_MAX, "ledc_channel");
|
||||
LEDC_ARG_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "gpio_num");
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
gpio_func_sel(gpio_num, PIN_FUNC_GPIO);
|
||||
gpio_set_level(gpio_num, out_inv);
|
||||
gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
|
||||
esp_rom_gpio_connect_out_signal(gpio_num, ledc_periph_signal[speed_mode].sig_out0_idx + ledc_channel, 0, 0);
|
||||
// reserve the GPIO output path, because we don't expect another peripheral to signal to the same GPIO
|
||||
uint64_t old_gpio_rsv_mask = esp_gpio_reserve(BIT64(gpio_num));
|
||||
// check if the GPIO is already used by others, LEDC signal only uses the output path of the GPIO
|
||||
if (old_gpio_rsv_mask & BIT64(gpio_num)) {
|
||||
ESP_LOGW(LEDC_TAG, "GPIO %d is not usable, maybe conflict with others", gpio_num);
|
||||
}
|
||||
esp_rom_gpio_connect_out_signal(gpio_num, ledc_periph_signal[speed_mode].sig_out0_idx + channel, out_inv, 0);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
// One LEDC channel signal can be directed to multiple IOs as outputs
|
||||
esp_err_t ledc_set_pin(int gpio_num, ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
LEDC_ARG_CHECK(channel < LEDC_CHANNEL_MAX, "channel");
|
||||
LEDC_ARG_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "speed_mode");
|
||||
LEDC_ARG_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(gpio_num), "gpio_num");
|
||||
return _ledc_set_pin(gpio_num, false, speed_mode, channel);
|
||||
}
|
||||
|
||||
esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf)
|
||||
{
|
||||
LEDC_ARG_CHECK(ledc_conf, "ledc_conf");
|
||||
@@ -710,10 +724,7 @@ esp_err_t ledc_channel_config(const ledc_channel_config_t *ledc_conf)
|
||||
ESP_LOGD(LEDC_TAG, "LEDC_PWM CHANNEL %"PRIu32"|GPIO %02u|Duty %04"PRIu32"|Time %"PRIu32,
|
||||
ledc_channel, gpio_num, duty, timer_select);
|
||||
/*set LEDC signal in gpio matrix*/
|
||||
gpio_func_sel(gpio_num, PIN_FUNC_GPIO);
|
||||
gpio_set_level(gpio_num, output_invert);
|
||||
gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
|
||||
esp_rom_gpio_connect_out_signal(gpio_num, ledc_periph_signal[speed_mode].sig_out0_idx + ledc_channel, output_invert, 0);
|
||||
_ledc_set_pin(gpio_num, output_invert, speed_mode, ledc_channel);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user