mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(esp_hw_support): support one-to-many signal-gpio mapping output
This commit is contained in:
parent
6a436286dc
commit
7195bf19df
@ -4,6 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <sys/queue.h>
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
@ -16,139 +17,194 @@
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
|
||||
typedef struct gpio_clock_out_ctx {
|
||||
typedef struct clkout_channel_handle {
|
||||
bool is_mapped;
|
||||
uint8_t ref_cnt;
|
||||
clock_out_channel_t clk_out;
|
||||
gpio_num_t mapped_io;
|
||||
soc_clkout_sig_id_t mapped_clock;
|
||||
} gpio_clock_out_ctx_t;
|
||||
uint8_t channel_id;
|
||||
uint8_t ref_cnt;
|
||||
uint64_t mapped_io_bmap;
|
||||
portMUX_TYPE clkout_channel_lock;
|
||||
} clkout_channel_handle_t;
|
||||
|
||||
static const char *TAG = "gpio_output_clk";
|
||||
typedef struct esp_clock_output_mapping {
|
||||
gpio_num_t mapped_io;
|
||||
clkout_channel_handle_t* clkout_channel_hdl;
|
||||
uint8_t ref_cnt;
|
||||
portMUX_TYPE clkout_mapping_lock;
|
||||
SLIST_ENTRY(esp_clock_output_mapping) next;
|
||||
} esp_clock_output_mapping_t;
|
||||
|
||||
static portMUX_TYPE s_clkout_channel_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
static const char *TAG = "esp_clock_output";
|
||||
|
||||
static gpio_clock_out_ctx_t s_pin_ctrl_clk_out[CLKOUT_CHANNEL_MAX] = {
|
||||
static SLIST_HEAD(esp_clock_output_mapping_head, esp_clock_output_mapping) s_mapping_list = SLIST_HEAD_INITIALIZER(s_mapping_list_head);
|
||||
static portMUX_TYPE s_mapping_list_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
static portMUX_TYPE s_clkout_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static clkout_channel_handle_t s_clkout_handle[CLKOUT_CHANNEL_MAX] = {
|
||||
[0 ... CLKOUT_CHANNEL_MAX - 1] = {
|
||||
.is_mapped = false,
|
||||
.ref_cnt = 0,
|
||||
.mapped_io_bmap = 0,
|
||||
.clkout_channel_lock = portMUX_INITIALIZER_UNLOCKED,
|
||||
}
|
||||
};
|
||||
|
||||
static gpio_clock_out_ctx_t* io_mux_pin_ctrl_clk_out_alloc(soc_clkout_sig_id_t clk_sig, gpio_num_t gpio_num)
|
||||
static clkout_channel_handle_t* clkout_channel_alloc(soc_clkout_sig_id_t clk_sig, gpio_num_t gpio_num)
|
||||
{
|
||||
gpio_clock_out_ctx_t *allocated_clk_out = NULL;
|
||||
clkout_channel_handle_t *allocated_channel = NULL;
|
||||
|
||||
#if SOC_GPIO_CLOCKOUT_BY_IO_MUX
|
||||
portENTER_CRITICAL(&s_clkout_channel_lock);
|
||||
if (!s_pin_ctrl_clk_out[IONUM_TO_CLKOUT(gpio_num)].is_mapped) {
|
||||
s_pin_ctrl_clk_out[IONUM_TO_CLKOUT(gpio_num)].is_mapped = true;
|
||||
s_pin_ctrl_clk_out[IONUM_TO_CLKOUT(gpio_num)].clk_out = IONUM_TO_CLKOUT(gpio_num);
|
||||
allocated_clk_out = &s_pin_ctrl_clk_out[IONUM_TO_CLKOUT(gpio_num)];
|
||||
} else if ((s_pin_ctrl_clk_out[IONUM_TO_CLKOUT(gpio_num)].mapped_io == gpio_num) &&
|
||||
(s_pin_ctrl_clk_out[IONUM_TO_CLKOUT(gpio_num)].mapped_clock == clk_sig)) {
|
||||
allocated_clk_out = &s_pin_ctrl_clk_out[IONUM_TO_CLKOUT(gpio_num)];
|
||||
portENTER_CRITICAL(&s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].clkout_channel_lock);
|
||||
if (!s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].is_mapped) {
|
||||
s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].is_mapped = true;
|
||||
allocated_channel = &s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)];
|
||||
} else if ((s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].mapped_io_bmap & BIT(gpio_num)) &&
|
||||
(s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].mapped_clock == clk_sig)) {
|
||||
allocated_channel = &s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)];
|
||||
}
|
||||
portEXIT_CRITICAL(&s_clkout_channel_lock);
|
||||
allocated_channel->channel_id = (clock_out_channel_t)IONUM_TO_CLKOUT_CHANNEL(gpio_num);
|
||||
portEXIT_CRITICAL(&s_clkout_handle[IONUM_TO_CLKOUT_CHANNEL(gpio_num)].clkout_channel_lock);
|
||||
#elif SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX
|
||||
for(uint32_t i = 0; i < CLKOUT_CHANNEL_MAX; i++) {
|
||||
portENTER_CRITICAL(&s_clkout_channel_lock);
|
||||
if (!s_pin_ctrl_clk_out[i].is_mapped) {
|
||||
s_pin_ctrl_clk_out[i].is_mapped = true;
|
||||
s_pin_ctrl_clk_out[i].clk_out = (clock_out_channel_t)i;
|
||||
allocated_clk_out = &s_pin_ctrl_clk_out[i];
|
||||
portEXIT_CRITICAL(&s_clkout_channel_lock);
|
||||
for(uint32_t channel = 0; channel < CLKOUT_CHANNEL_MAX; channel++) {
|
||||
portENTER_CRITICAL(&s_clkout_handle[channel].clkout_channel_lock);
|
||||
if (!s_clkout_handle[channel].is_mapped) {
|
||||
s_clkout_handle[channel].is_mapped = true;
|
||||
allocated_channel = &s_clkout_handle[channel];
|
||||
allocated_channel->channel_id = (clock_out_channel_t)channel;
|
||||
portEXIT_CRITICAL(&s_clkout_handle[channel].clkout_channel_lock);
|
||||
break;
|
||||
} else if ((s_pin_ctrl_clk_out[i].mapped_io == gpio_num) &&
|
||||
(s_pin_ctrl_clk_out[i].mapped_clock == clk_sig)) {
|
||||
allocated_clk_out = &s_pin_ctrl_clk_out[i];
|
||||
portEXIT_CRITICAL(&s_clkout_channel_lock);
|
||||
} else if (s_clkout_handle[channel].mapped_clock == clk_sig) {
|
||||
allocated_channel = &s_clkout_handle[channel];
|
||||
portEXIT_CRITICAL(&s_clkout_handle[channel].clkout_channel_lock);
|
||||
break;
|
||||
}
|
||||
portEXIT_CRITICAL(&s_clkout_channel_lock);
|
||||
portEXIT_CRITICAL(&s_clkout_handle[channel].clkout_channel_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (allocated_clk_out != NULL) {
|
||||
portENTER_CRITICAL(&s_clkout_channel_lock);
|
||||
allocated_clk_out->mapped_io = gpio_num;
|
||||
allocated_clk_out->mapped_clock = clk_sig;
|
||||
allocated_clk_out->ref_cnt++;
|
||||
portEXIT_CRITICAL(&s_clkout_channel_lock);
|
||||
if (allocated_channel != NULL) {
|
||||
portENTER_CRITICAL(&allocated_channel->clkout_channel_lock);
|
||||
allocated_channel->mapped_io_bmap |= BIT(gpio_num);
|
||||
allocated_channel->mapped_clock = clk_sig;
|
||||
allocated_channel->ref_cnt++;
|
||||
|
||||
if (allocated_channel->ref_cnt == 1) {
|
||||
portENTER_CRITICAL(&s_clkout_lock);
|
||||
gpio_ll_set_pin_ctrl(clk_sig, CLKOUT_CHANNEL_MASK(allocated_channel->channel_id), CLKOUT_CHANNEL_SHIFT(allocated_channel->channel_id));
|
||||
portEXIT_CRITICAL(&s_clkout_lock);
|
||||
}
|
||||
portEXIT_CRITICAL(&allocated_channel->clkout_channel_lock);
|
||||
}
|
||||
|
||||
return allocated_clk_out;
|
||||
return allocated_channel;
|
||||
}
|
||||
|
||||
static bool io_mux_pin_ctrl_clk_out_sig_try_free(gpio_clock_out_handle_t clk_out_hdl)
|
||||
static esp_clock_output_mapping_t* clkout_mapping_alloc(clkout_channel_handle_t* channel_hdl, gpio_num_t gpio_num)
|
||||
{
|
||||
bool do_free = false;
|
||||
portENTER_CRITICAL(&s_clkout_channel_lock);
|
||||
if (--clk_out_hdl->ref_cnt == 0) {
|
||||
do_free = true;
|
||||
clk_out_hdl->is_mapped = false;
|
||||
esp_clock_output_mapping_t *allocated_mapping = NULL;
|
||||
|
||||
portENTER_CRITICAL(&s_mapping_list_lock);
|
||||
esp_clock_output_mapping_t *hdl;
|
||||
SLIST_FOREACH(hdl, &s_mapping_list, next) {
|
||||
if ((hdl->clkout_channel_hdl == channel_hdl) && (hdl->mapped_io == gpio_num)) {
|
||||
allocated_mapping = hdl;
|
||||
}
|
||||
}
|
||||
portEXIT_CRITICAL(&s_clkout_channel_lock);
|
||||
return do_free;
|
||||
}
|
||||
portEXIT_CRITICAL(&s_mapping_list_lock);
|
||||
|
||||
esp_err_t esp_clock_output_start(soc_clkout_sig_id_t clk_sig, gpio_num_t gpio_num, gpio_clock_out_handle_t *clk_out_hdl)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE((clk_out_hdl != NULL), ESP_ERR_INVALID_ARG, TAG, "Clock out handle passed in is invalid");
|
||||
|
||||
ESP_RETURN_ON_FALSE(IS_VALID_CLKOUT_IO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "%s", "Output GPIO number error");
|
||||
|
||||
gpio_clock_out_ctx_t* new_hdl= io_mux_pin_ctrl_clk_out_alloc(clk_sig, gpio_num);
|
||||
if (allocated_mapping == NULL) {
|
||||
allocated_mapping = (esp_clock_output_mapping_t *)malloc(sizeof(esp_clock_output_mapping_t));
|
||||
allocated_mapping->mapped_io = gpio_num;
|
||||
allocated_mapping->clkout_channel_hdl = channel_hdl;
|
||||
allocated_mapping->ref_cnt = 0;
|
||||
portMUX_INITIALIZE(&allocated_mapping->clkout_mapping_lock);
|
||||
portENTER_CRITICAL(&s_mapping_list_lock);
|
||||
SLIST_INSERT_HEAD(&s_mapping_list, allocated_mapping, next);
|
||||
portEXIT_CRITICAL(&s_mapping_list_lock);
|
||||
}
|
||||
|
||||
portENTER_CRITICAL(&allocated_mapping->clkout_mapping_lock);
|
||||
allocated_mapping->ref_cnt++;
|
||||
if (allocated_mapping->ref_cnt == 1) {
|
||||
#if SOC_GPIO_CLOCKOUT_BY_IO_MUX
|
||||
ESP_RETURN_ON_FALSE((new_hdl != NULL), ESP_ERR_INVALID_ARG, TAG, "Selected clock out IO is already mapped to other internal clock source");
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], CLKOUT_CHANNEL_TO_IOMUX_FUNC(allocated_mapping->clkout_channel_hdl->channel_id));
|
||||
#elif SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX
|
||||
ESP_RETURN_ON_FALSE((new_hdl != NULL), ESP_FAIL, TAG, "Maximum support for %d output clock signals, no available clock_out channel for assignment", CLKOUT_CHANNEL_MAX);
|
||||
#endif
|
||||
|
||||
if (new_hdl->ref_cnt == 1) {
|
||||
uint32_t clk_out_mask = (new_hdl->clk_out == CLKOUT_CHANNEL_1) ? CLK_OUT1 :
|
||||
(new_hdl->clk_out == CLKOUT_CHANNEL_2) ? CLK_OUT2 :
|
||||
(new_hdl->clk_out == CLKOUT_CHANNEL_3) ? CLK_OUT3 : 0;
|
||||
uint32_t clk_out_shift = (new_hdl->clk_out == CLKOUT_CHANNEL_1) ? CLK_OUT1_S :
|
||||
(new_hdl->clk_out == CLKOUT_CHANNEL_2) ? CLK_OUT2_S :
|
||||
(new_hdl->clk_out == CLKOUT_CHANNEL_3) ? CLK_OUT3_S : 0;
|
||||
|
||||
portENTER_CRITICAL(&s_clkout_channel_lock);
|
||||
gpio_ll_set_pin_ctrl(clk_sig, clk_out_mask, clk_out_shift);
|
||||
portEXIT_CRITICAL(&s_clkout_channel_lock);
|
||||
|
||||
#if SOC_GPIO_CLOCKOUT_BY_IO_MUX
|
||||
uint32_t clk_out_func = (new_hdl->clk_out == CLKOUT_CHANNEL_1) ? FUNC_CLK_OUT1 :
|
||||
(new_hdl->clk_out == CLKOUT_CHANNEL_2) ? FUNC_CLK_OUT2 :
|
||||
(new_hdl->clk_out == CLKOUT_CHANNEL_3) ? FUNC_CLK_OUT3 : 0;
|
||||
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], clk_out_func);
|
||||
#elif SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX
|
||||
uint32_t gpio_clk_out_sig_idx = (new_hdl->clk_out == CLKOUT_CHANNEL_1) ? CLK_OUT_OUT1_IDX :
|
||||
(new_hdl->clk_out == CLKOUT_CHANNEL_2) ? CLK_OUT_OUT2_IDX :
|
||||
(new_hdl->clk_out == CLKOUT_CHANNEL_3) ? CLK_OUT_OUT3_IDX : SIG_GPIO_OUT_IDX;
|
||||
|
||||
gpio_set_pull_mode(gpio_num, GPIO_FLOATING);
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO);
|
||||
gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
|
||||
esp_rom_gpio_connect_out_signal(gpio_num, gpio_clk_out_sig_idx, false, false);
|
||||
esp_rom_gpio_connect_out_signal(gpio_num, CLKOUT_CHANNEL_TO_GPIO_SIG_ID(allocated_mapping->clkout_channel_hdl->channel_id), false, false);
|
||||
#endif
|
||||
}
|
||||
portEXIT_CRITICAL(&allocated_mapping->clkout_mapping_lock);
|
||||
return allocated_mapping;
|
||||
}
|
||||
|
||||
static void clkout_channel_free(clkout_channel_handle_t *channel_hdl)
|
||||
{
|
||||
portENTER_CRITICAL(&channel_hdl->clkout_channel_lock);
|
||||
if (--channel_hdl->ref_cnt == 0) {
|
||||
channel_hdl->mapped_clock = CLKOUT_SIG_INVALID;
|
||||
portENTER_CRITICAL(&s_clkout_lock);
|
||||
gpio_ll_set_pin_ctrl(0, CLKOUT_CHANNEL_MASK(channel_hdl->channel_id), CLKOUT_CHANNEL_SHIFT(channel_hdl->channel_id));
|
||||
portEXIT_CRITICAL(&s_clkout_lock);
|
||||
channel_hdl->is_mapped = false;
|
||||
}
|
||||
portEXIT_CRITICAL(&channel_hdl->clkout_channel_lock);
|
||||
}
|
||||
|
||||
static void clkout_mapping_free(esp_clock_output_mapping_t *mapping_hdl)
|
||||
{
|
||||
portENTER_CRITICAL(&mapping_hdl->clkout_mapping_lock);
|
||||
clkout_channel_free(mapping_hdl->clkout_channel_hdl);
|
||||
bool do_free_mapping_hdl = false;
|
||||
if (--mapping_hdl->ref_cnt == 0) {
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[mapping_hdl->mapped_io], PIN_FUNC_GPIO);
|
||||
esp_rom_gpio_connect_out_signal(mapping_hdl->mapped_io, SIG_GPIO_OUT_IDX, false, false);
|
||||
gpio_set_direction(mapping_hdl->mapped_io, GPIO_MODE_DISABLE);
|
||||
|
||||
portENTER_CRITICAL(&mapping_hdl->clkout_channel_hdl->clkout_channel_lock);
|
||||
mapping_hdl->clkout_channel_hdl->mapped_io_bmap &= ~BIT(mapping_hdl->mapped_io);
|
||||
portEXIT_CRITICAL(&mapping_hdl->clkout_channel_hdl->clkout_channel_lock);
|
||||
|
||||
portENTER_CRITICAL(&s_mapping_list_lock);
|
||||
SLIST_REMOVE(&s_mapping_list, mapping_hdl, esp_clock_output_mapping, next);
|
||||
portEXIT_CRITICAL(&s_mapping_list_lock);
|
||||
do_free_mapping_hdl = true;
|
||||
}
|
||||
portEXIT_CRITICAL(&mapping_hdl->clkout_mapping_lock);
|
||||
|
||||
if (do_free_mapping_hdl) {
|
||||
free(mapping_hdl);
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t esp_clock_output_start(soc_clkout_sig_id_t clk_sig, gpio_num_t gpio_num, esp_clock_output_mapping_handle_t *clkout_mapping_ret_hdl)
|
||||
{
|
||||
ESP_RETURN_ON_FALSE((clkout_mapping_ret_hdl != NULL), ESP_ERR_INVALID_ARG, TAG, "Clock out mapping handle passed in is invalid");
|
||||
ESP_RETURN_ON_FALSE(IS_VALID_CLKOUT_IO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "%s", "Output GPIO number error");
|
||||
|
||||
esp_clock_output_mapping_t *hdl;
|
||||
SLIST_FOREACH(hdl, &s_mapping_list, next) {
|
||||
ESP_RETURN_ON_FALSE(!((hdl->mapped_io == gpio_num) && (hdl->clkout_channel_hdl->mapped_clock != clk_sig)), ESP_ERR_INVALID_ARG, TAG, "Selected io is already mapped by another signal");
|
||||
}
|
||||
|
||||
clkout_channel_handle_t *channel_hdl = clkout_channel_alloc(clk_sig, gpio_num);
|
||||
#if SOC_GPIO_CLOCKOUT_BY_IO_MUX
|
||||
ESP_RETURN_ON_FALSE((channel_hdl != NULL), ESP_ERR_INVALID_ARG, TAG, "Selected clock out IO is already mapped to other internal clock source");
|
||||
#elif SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX
|
||||
ESP_RETURN_ON_FALSE((channel_hdl != NULL), ESP_FAIL, TAG, "Maximum support for %d output clock signals, no available clock_out channel for assignment", CLKOUT_CHANNEL_MAX);
|
||||
#endif
|
||||
|
||||
*clkout_mapping_ret_hdl = clkout_mapping_alloc(channel_hdl, gpio_num);
|
||||
|
||||
*clk_out_hdl = new_hdl;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_clock_output_stop(gpio_clock_out_handle_t clk_out_hdl)
|
||||
esp_err_t esp_clock_output_stop(esp_clock_output_mapping_handle_t clkout_mapping_hdl)
|
||||
{
|
||||
assert(clk_out_hdl != NULL);
|
||||
ESP_RETURN_ON_FALSE(clk_out_hdl->is_mapped, ESP_ERR_INVALID_STATE, TAG, "%s", "Clock outputting is already disabled");
|
||||
if (io_mux_pin_ctrl_clk_out_sig_try_free(clk_out_hdl)) {
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[clk_out_hdl->mapped_io], PIN_FUNC_GPIO);
|
||||
esp_rom_gpio_connect_out_signal(clk_out_hdl->mapped_io, SIG_GPIO_OUT_IDX, false, false);
|
||||
gpio_set_direction(clk_out_hdl->mapped_io, GPIO_MODE_DISABLE);
|
||||
}
|
||||
ESP_RETURN_ON_FALSE((clkout_mapping_hdl != NULL), ESP_ERR_INVALID_ARG, TAG, "Clock out mapping handle passed in is invalid");
|
||||
ESP_RETURN_ON_FALSE(clkout_mapping_hdl->ref_cnt > 0, ESP_ERR_INVALID_STATE, TAG, "%s", "Clock outputting is already disabled");
|
||||
clkout_mapping_free(clkout_mapping_hdl);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
@ -21,31 +21,31 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#if SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX || SOC_GPIO_CLOCKOUT_BY_IO_MUX
|
||||
typedef struct gpio_clock_out_ctx* gpio_clock_out_handle_t;
|
||||
typedef struct esp_clock_output_mapping *esp_clock_output_mapping_handle_t;
|
||||
|
||||
/**
|
||||
* @brief Start output specified clock signal to specified GPIO, will also
|
||||
* initialize the clk_out_hdl.
|
||||
* initialize the clkout_mapping_ret_hdl.
|
||||
*
|
||||
* @param[in] clk_src The clock signal source to be mapped to GPIOs
|
||||
* @param[in] gpio_num GPIO number to be mapped soc_root_clk signal source
|
||||
* @param[out] clk_out_hdl Clock output controll handler
|
||||
* @param[out] clkout_mapping_ret_hdl Clock output controll handler
|
||||
* @return
|
||||
* - ESP_OK: Output specified clock signal to specified GPIO successfully
|
||||
* - ESP_ERR_INVALID_ARG: Specified GPIO not supported to output internal clock
|
||||
* or specified GPIO is already mapped to other internal clock source.
|
||||
* - ESP_FAIL: There are no clock out signals that can be allocated.
|
||||
*/
|
||||
esp_err_t esp_clock_output_start(soc_clkout_sig_id_t clk_sig, gpio_num_t gpio_num, gpio_clock_out_handle_t *clk_out_hdl);
|
||||
esp_err_t esp_clock_output_start(soc_clkout_sig_id_t clk_sig, gpio_num_t gpio_num, esp_clock_output_mapping_handle_t *clkout_mapping_ret_hdl);
|
||||
|
||||
/**
|
||||
* @brief Stop clock signal to GPIO outputting
|
||||
* @param[in] clk_out_hdl Clock output controll handle
|
||||
* @param[in] clkout_mapping_hdl Clock output mapping controll handle
|
||||
* @return
|
||||
* - ESP_OK: Disable the clock output on GPIO successfully
|
||||
* - ESP_ERR_INVALID_STATE The clock in handle is already in the disabled state
|
||||
*/
|
||||
esp_err_t esp_clock_output_stop(gpio_clock_out_handle_t clk_out_hdl);
|
||||
esp_err_t esp_clock_output_stop(esp_clock_output_mapping_handle_t clkout_mapping_hdl);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -34,14 +34,27 @@ typedef enum clock_out_channel {
|
||||
#define FUNC_CLK_OUT2 FUNC_GPIO19_CLK_OUT2
|
||||
#define FUNC_CLK_OUT3 FUNC_DAC_2_CLK_OUT3
|
||||
#endif
|
||||
#define IONUM_TO_CLKOUT_CHANNEL(gpio_num) ((gpio_num == CLKOUT_CHANNEL1_GPIO) ? CLKOUT_CHANNEL_1 : \
|
||||
(gpio_num == CLKOUT_CHANNEL2_GPIO) ? CLKOUT_CHANNEL_2 : \
|
||||
(gpio_num == CLKOUT_CHANNEL3_GPIO) ? CLKOUT_CHANNEL_3 : 0)
|
||||
#define CLKOUT_CHANNEL_TO_IOMUX_FUNC(channel) ((channel == CLKOUT_CHANNEL_1) ? FUNC_CLK_OUT1 : \
|
||||
(channel == CLKOUT_CHANNEL_2) ? FUNC_CLK_OUT2 : \
|
||||
(channel == CLKOUT_CHANNEL_3) ? FUNC_CLK_OUT3 : 0)
|
||||
#define IS_VALID_CLKOUT_IO(gpio_num) ((gpio_num == CLKOUT_CHANNEL1_GPIO) || (gpio_num == CLKOUT_CHANNEL2_GPIO) || (gpio_num == CLKOUT_CHANNEL3_GPIO))
|
||||
#elif SOC_GPIO_CLOCKOUT_BY_GPIO_MATRIX
|
||||
#define CLKOUT_CHANNEL_TO_GPIO_SIG_ID(channel) ((channel == CLKOUT_CHANNEL_1) ? CLK_OUT_OUT1_IDX : \
|
||||
(channel == CLKOUT_CHANNEL_2) ? CLK_OUT_OUT2_IDX : \
|
||||
(channel == CLKOUT_CHANNEL_3) ? CLK_OUT_OUT3_IDX : SIG_GPIO_OUT_IDX)
|
||||
#define IS_VALID_CLKOUT_IO(gpio_num) GPIO_IS_VALID_GPIO(gpio_num)
|
||||
#endif
|
||||
|
||||
#define IONUM_TO_CLKOUT(gpio_num) ((gpio_num == CLKOUT_CHANNEL1_GPIO) ? CLKOUT_CHANNEL_1 : \
|
||||
(gpio_num == CLKOUT_CHANNEL2_GPIO) ? CLKOUT_CHANNEL_2 : \
|
||||
(gpio_num == CLKOUT_CHANNEL3_GPIO) ? CLKOUT_CHANNEL_3 : 0)
|
||||
#define CLKOUT_CHANNEL_MASK(channel) ((channel == CLKOUT_CHANNEL_1) ? CLK_OUT1 : \
|
||||
(channel == CLKOUT_CHANNEL_2) ? CLK_OUT2 : \
|
||||
(channel == CLKOUT_CHANNEL_3) ? CLK_OUT3 : 0)
|
||||
|
||||
#define CLKOUT_CHANNEL_SHIFT(channel) ((channel == CLKOUT_CHANNEL_1) ? CLK_OUT1_S : \
|
||||
(channel == CLKOUT_CHANNEL_2) ? CLK_OUT2_S : \
|
||||
(channel == CLKOUT_CHANNEL_3) ? CLK_OUT3_S : 0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user