mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(i2s): support i2s gpio reservation
This commit is contained in:
parent
f1babb9074
commit
e4f28fcb7f
@ -283,6 +283,7 @@ static esp_err_t i2s_register_channel(i2s_controller_t *i2s_obj, i2s_dir_t dir,
|
||||
new_chan->dma.curr_desc = NULL;
|
||||
new_chan->start = NULL;
|
||||
new_chan->stop = NULL;
|
||||
new_chan->reserve_gpio_mask = 0;
|
||||
|
||||
if (dir == I2S_DIR_TX) {
|
||||
if (i2s_obj->tx_chan) {
|
||||
@ -749,7 +750,42 @@ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void i2s_gpio_check_and_set(int gpio, uint32_t signal_idx, bool is_input, bool is_invert)
|
||||
static uint64_t s_i2s_get_pair_chan_gpio_mask(i2s_chan_handle_t handle)
|
||||
{
|
||||
if (handle->dir == I2S_DIR_TX) {
|
||||
return handle->controller->rx_chan ? handle->controller->rx_chan->reserve_gpio_mask : 0;
|
||||
}
|
||||
return handle->controller->tx_chan ? handle->controller->tx_chan->reserve_gpio_mask : 0;
|
||||
}
|
||||
|
||||
void i2s_output_gpio_reserve(i2s_chan_handle_t handle, int gpio_num)
|
||||
{
|
||||
bool used_by_pair_chan = false;
|
||||
/* If the gpio is used by the pair channel do not show warning for this case */
|
||||
if (handle->controller->full_duplex) {
|
||||
used_by_pair_chan = !!(s_i2s_get_pair_chan_gpio_mask(handle) & BIT64(gpio_num));
|
||||
}
|
||||
/* reserve the GPIO output path, because we don't expect another peripheral to signal to the same GPIO */
|
||||
if (!used_by_pair_chan && (esp_gpio_reserve(BIT64(gpio_num)) & BIT64(gpio_num))) {
|
||||
ESP_LOGW(TAG, "GPIO %d is not usable, maybe conflict with others", gpio_num);
|
||||
}
|
||||
handle->reserve_gpio_mask |= BIT64(gpio_num);
|
||||
}
|
||||
|
||||
void i2s_output_gpio_revoke(i2s_chan_handle_t handle, uint64_t gpio_mask)
|
||||
{
|
||||
uint64_t revoke_mask = gpio_mask;
|
||||
/* If the gpio is used by the pair channel do not show warning for this case */
|
||||
if (handle->controller->full_duplex) {
|
||||
uint64_t pair_chan_gpio_mask = s_i2s_get_pair_chan_gpio_mask(handle);
|
||||
/* Only revoke the gpio which is not used by the pair channel */
|
||||
revoke_mask = (pair_chan_gpio_mask ^ gpio_mask) & gpio_mask;
|
||||
}
|
||||
esp_gpio_revoke(revoke_mask);
|
||||
handle->reserve_gpio_mask &= ~gpio_mask;
|
||||
}
|
||||
|
||||
void i2s_gpio_check_and_set(i2s_chan_handle_t handle, int gpio, uint32_t signal_idx, bool is_input, bool is_invert)
|
||||
{
|
||||
/* Ignore the pin if pin = I2S_GPIO_UNUSED */
|
||||
if (gpio != (int)I2S_GPIO_UNUSED) {
|
||||
@ -759,15 +795,17 @@ void i2s_gpio_check_and_set(int gpio, uint32_t signal_idx, bool is_input, bool i
|
||||
gpio_set_direction(gpio, GPIO_MODE_INPUT);
|
||||
esp_rom_gpio_connect_in_signal(gpio, signal_idx, is_invert);
|
||||
} else {
|
||||
i2s_output_gpio_reserve(handle, gpio);
|
||||
gpio_set_direction(gpio, GPIO_MODE_OUTPUT);
|
||||
esp_rom_gpio_connect_out_signal(gpio, signal_idx, is_invert, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void i2s_gpio_loopback_set(int gpio, uint32_t out_sig_idx, uint32_t in_sig_idx)
|
||||
void i2s_gpio_loopback_set(i2s_chan_handle_t handle, int gpio, uint32_t out_sig_idx, uint32_t in_sig_idx)
|
||||
{
|
||||
if (gpio != (int)I2S_GPIO_UNUSED) {
|
||||
i2s_output_gpio_reserve(handle, gpio);
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO);
|
||||
gpio_set_direction(gpio, GPIO_MODE_INPUT_OUTPUT);
|
||||
esp_rom_gpio_connect_out_signal(gpio, out_sig_idx, 0, 0);
|
||||
@ -775,7 +813,7 @@ void i2s_gpio_loopback_set(int gpio, uint32_t out_sig_idx, uint32_t in_sig_idx)
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t i2s_check_set_mclk(i2s_port_t id, int gpio_num, i2s_clock_src_t clk_src, bool is_invert)
|
||||
esp_err_t i2s_check_set_mclk(i2s_chan_handle_t handle, i2s_port_t id, int gpio_num, i2s_clock_src_t clk_src, bool is_invert)
|
||||
{
|
||||
if (gpio_num == (int)I2S_GPIO_UNUSED) {
|
||||
return ESP_OK;
|
||||
@ -784,6 +822,7 @@ esp_err_t i2s_check_set_mclk(i2s_port_t id, int gpio_num, i2s_clock_src_t clk_sr
|
||||
bool is_i2s0 = id == I2S_NUM_0;
|
||||
bool is_apll = clk_src == I2S_CLK_SRC_APLL;
|
||||
if (g_i2s.controller[id]->mclk_out_hdl == NULL) {
|
||||
i2s_output_gpio_reserve(handle, gpio_num);
|
||||
soc_clkout_sig_id_t clkout_sig = is_apll ? CLKOUT_SIG_APLL : (is_i2s0 ? CLKOUT_SIG_I2S0 : CLKOUT_SIG_I2S1);
|
||||
ESP_RETURN_ON_ERROR(esp_clock_output_start(clkout_sig, gpio_num, &(g_i2s.controller[id]->mclk_out_hdl)), TAG, "mclk configure failed");
|
||||
}
|
||||
@ -791,11 +830,11 @@ esp_err_t i2s_check_set_mclk(i2s_port_t id, int gpio_num, i2s_clock_src_t clk_sr
|
||||
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(gpio_num), ESP_ERR_INVALID_ARG, TAG, "mck_io_num invalid");
|
||||
#if SOC_I2S_HW_VERSION_2
|
||||
if (clk_src == I2S_CLK_SRC_EXTERNAL) {
|
||||
i2s_gpio_check_and_set(gpio_num, i2s_periph_signal[id].mck_in_sig, true, is_invert);
|
||||
i2s_gpio_check_and_set(handle, gpio_num, i2s_periph_signal[id].mck_in_sig, true, is_invert);
|
||||
} else
|
||||
#endif // SOC_I2S_HW_VERSION_2
|
||||
{
|
||||
i2s_gpio_check_and_set(gpio_num, i2s_periph_signal[id].mck_out_sig, false, is_invert);
|
||||
i2s_gpio_check_and_set(handle, gpio_num, i2s_periph_signal[id].mck_out_sig, false, is_invert);
|
||||
}
|
||||
#endif // CONFIG_IDF_TARGET_ESP32
|
||||
ESP_LOGD(TAG, "MCLK is pinned to GPIO%d on I2S%d", gpio_num, id);
|
||||
@ -930,6 +969,9 @@ esp_err_t i2s_del_channel(i2s_chan_handle_t handle)
|
||||
esp_pm_lock_delete(handle->pm_lock);
|
||||
}
|
||||
#endif
|
||||
if (handle->reserve_gpio_mask) {
|
||||
i2s_output_gpio_revoke(handle, handle->reserve_gpio_mask);
|
||||
}
|
||||
if (handle->mode_info) {
|
||||
free(handle->mode_info);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -132,23 +132,23 @@ static esp_err_t i2s_pdm_tx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_
|
||||
ESP_ERR_INVALID_ARG, TAG, "dout gpio is invalid");
|
||||
i2s_pdm_tx_config_t *pdm_tx_cfg = (i2s_pdm_tx_config_t *)handle->mode_info;
|
||||
/* Set data output GPIO */
|
||||
i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false, false);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false, false);
|
||||
#if SOC_I2S_PDM_MAX_TX_LINES > 1
|
||||
if (pdm_tx_cfg->slot_cfg.line_mode == I2S_PDM_TX_TWO_LINE_DAC) {
|
||||
i2s_gpio_check_and_set(gpio_cfg->dout2, i2s_periph_signal[id].data_out_sigs[1], false, false);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->dout2, i2s_periph_signal[id].data_out_sigs[1], false, false);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (handle->role == I2S_ROLE_SLAVE) {
|
||||
/* For "tx + slave" mode, select TX signal index for ws and bck */
|
||||
if (!handle->controller->full_duplex) {
|
||||
i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_tx_ws_sig, true, gpio_cfg->invert_flags.clk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->clk, i2s_periph_signal[id].s_tx_ws_sig, true, gpio_cfg->invert_flags.clk_inv);
|
||||
/* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */
|
||||
} else {
|
||||
i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.clk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->clk, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.clk_inv);
|
||||
}
|
||||
} else {
|
||||
i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.clk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->clk, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.clk_inv);
|
||||
}
|
||||
#if SOC_I2S_HW_VERSION_2
|
||||
I2S_CLOCK_SRC_ATOMIC() {
|
||||
@ -311,6 +311,9 @@ esp_err_t i2s_channel_reconfig_pdm_tx_gpio(i2s_chan_handle_t handle, const i2s_p
|
||||
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard mode");
|
||||
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be disabled before reconfiguring the gpio");
|
||||
|
||||
if (handle->reserve_gpio_mask) {
|
||||
i2s_output_gpio_revoke(handle, handle->reserve_gpio_mask);
|
||||
}
|
||||
ESP_GOTO_ON_ERROR(i2s_pdm_tx_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed");
|
||||
xSemaphoreGive(handle->mutex);
|
||||
|
||||
@ -422,21 +425,21 @@ static esp_err_t i2s_pdm_rx_set_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_
|
||||
#if SOC_I2S_PDM_MAX_RX_LINES > 1
|
||||
for (int i = 0; i < SOC_I2S_PDM_MAX_RX_LINES; i++) {
|
||||
if (pdm_rx_cfg->slot_cfg.slot_mask & (0x03 << (i * 2))) {
|
||||
i2s_gpio_check_and_set(gpio_cfg->dins[i], i2s_periph_signal[id].data_in_sigs[i], true, false);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->dins[i], i2s_periph_signal[id].data_in_sigs[i], true, false);
|
||||
}
|
||||
}
|
||||
#else
|
||||
i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true, false);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true, false);
|
||||
#endif
|
||||
|
||||
if (handle->role == I2S_ROLE_SLAVE) {
|
||||
/* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */
|
||||
i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.clk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->clk, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.clk_inv);
|
||||
} else {
|
||||
if (!handle->controller->full_duplex) {
|
||||
i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_rx_ws_sig, false, gpio_cfg->invert_flags.clk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->clk, i2s_periph_signal[id].m_rx_ws_sig, false, gpio_cfg->invert_flags.clk_inv);
|
||||
} else {
|
||||
i2s_gpio_check_and_set(gpio_cfg->clk, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.clk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->clk, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.clk_inv);
|
||||
}
|
||||
}
|
||||
#if SOC_I2S_HW_VERSION_2
|
||||
@ -595,6 +598,9 @@ esp_err_t i2s_channel_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_p
|
||||
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_PDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard mode");
|
||||
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be disabled before reconfiguring the gpio");
|
||||
|
||||
if (handle->reserve_gpio_mask) {
|
||||
i2s_output_gpio_revoke(handle, handle->reserve_gpio_mask);
|
||||
}
|
||||
ESP_GOTO_ON_ERROR(i2s_pdm_rx_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed");
|
||||
xSemaphoreGive(handle->mutex);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -20,6 +20,7 @@
|
||||
#include "esp_private/gdma.h"
|
||||
#endif
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/esp_gpio_reserve.h"
|
||||
#include "esp_pm.h"
|
||||
#include "esp_err.h"
|
||||
#include "sdkconfig.h"
|
||||
@ -146,6 +147,7 @@ struct i2s_channel_obj_t {
|
||||
esp_pm_lock_handle_t pm_lock; /*!< Power management lock, to avoid apb clock frequency changes while i2s is working */
|
||||
#endif
|
||||
QueueHandle_t msg_queue; /*!< Message queue handler, used for transporting data between interrupt and read/write task */
|
||||
uint64_t reserve_gpio_mask; /*!< The gpio mask that has been reserved by I2S */
|
||||
i2s_event_callbacks_internal_t callbacks; /*!< Callback functions */
|
||||
void *user_data; /*!< User data for callback functions */
|
||||
void (*start)(i2s_chan_handle_t); /*!< start tx/rx channel */
|
||||
@ -224,16 +226,18 @@ uint32_t i2s_get_source_clk_freq(i2s_clock_src_t clk_src, uint32_t mclk_freq_hz)
|
||||
/**
|
||||
* @brief Check gpio validity and attach to corresponding signal
|
||||
*
|
||||
* @param handle I2S channel handle
|
||||
* @param gpio GPIO number
|
||||
* @param signal_idx Signal index
|
||||
* @param is_input Is input gpio
|
||||
* @param is_invert Is invert gpio
|
||||
*/
|
||||
void i2s_gpio_check_and_set(int gpio, uint32_t signal_idx, bool is_input, bool is_invert);
|
||||
void i2s_gpio_check_and_set(i2s_chan_handle_t handle, int gpio, uint32_t signal_idx, bool is_input, bool is_invert);
|
||||
|
||||
/**
|
||||
* @brief Check gpio validity and output mclk signal
|
||||
*
|
||||
* @param handle I2S channel handle
|
||||
* @param id I2S port id
|
||||
* @param gpio_num GPIO number
|
||||
* @param clk_src The clock source of this I2S port
|
||||
@ -242,16 +246,33 @@ void i2s_gpio_check_and_set(int gpio, uint32_t signal_idx, bool is_input, bool i
|
||||
* - ESP_OK Set mclk output gpio success
|
||||
* - ESP_ERR_INVALID_ARG Invalid GPIO number
|
||||
*/
|
||||
esp_err_t i2s_check_set_mclk(i2s_port_t id, int gpio_num, i2s_clock_src_t clk_src, bool is_invert);
|
||||
esp_err_t i2s_check_set_mclk(i2s_chan_handle_t handle, i2s_port_t id, int gpio_num, i2s_clock_src_t clk_src, bool is_invert);
|
||||
|
||||
/**
|
||||
* @brief Attach data out signal and data in signal to a same gpio
|
||||
*
|
||||
* @param handle I2S channel handle
|
||||
* @param gpio GPIO number
|
||||
* @param out_sig_idx Data out signal index
|
||||
* @param in_sig_idx Data in signal index
|
||||
*/
|
||||
void i2s_gpio_loopback_set(int gpio, uint32_t out_sig_idx, uint32_t in_sig_idx);
|
||||
void i2s_gpio_loopback_set(i2s_chan_handle_t handle, int gpio, uint32_t out_sig_idx, uint32_t in_sig_idx);
|
||||
|
||||
/**
|
||||
* @brief Reserve the GPIO that configured as I2S output signal
|
||||
*
|
||||
* @param handle I2S channel handle
|
||||
* @param gpio_num The output gpio number to be reserved
|
||||
*/
|
||||
void i2s_output_gpio_reserve(i2s_chan_handle_t handle, int gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Revoke the GPIO that configured as I2S output signal
|
||||
*
|
||||
* @param handle I2S channel handle
|
||||
* @param gpio_mask The output gpio mask to be revoked
|
||||
*/
|
||||
void i2s_output_gpio_revoke(i2s_chan_handle_t handle, uint64_t gpio_mask);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -145,20 +145,19 @@ static esp_err_t i2s_std_set_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_c
|
||||
ESP_RETURN_ON_FALSE((gpio_cfg->ws == -1 || GPIO_IS_VALID_GPIO(gpio_cfg->ws)),
|
||||
ESP_ERR_INVALID_ARG, TAG, "ws invalid");
|
||||
i2s_std_config_t *std_cfg = (i2s_std_config_t *)(handle->mode_info);
|
||||
|
||||
/* Loopback if dout = din */
|
||||
if (gpio_cfg->dout != -1 && gpio_cfg->dout == gpio_cfg->din) {
|
||||
i2s_gpio_loopback_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, i2s_periph_signal[id].data_in_sig);
|
||||
i2s_gpio_loopback_set(handle, gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, i2s_periph_signal[id].data_in_sig);
|
||||
} else if (handle->dir == I2S_DIR_TX) {
|
||||
/* Set data output GPIO */
|
||||
i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false, false);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false, false);
|
||||
} else {
|
||||
/* Set data input GPIO */
|
||||
i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true, false);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true, false);
|
||||
}
|
||||
|
||||
/* Set mclk pin */
|
||||
ESP_RETURN_ON_ERROR(i2s_check_set_mclk(id, gpio_cfg->mclk, std_cfg->clk_cfg.clk_src, gpio_cfg->invert_flags.mclk_inv), TAG, "mclk config failed");
|
||||
ESP_RETURN_ON_ERROR(i2s_check_set_mclk(handle, id, gpio_cfg->mclk, std_cfg->clk_cfg.clk_src, gpio_cfg->invert_flags.mclk_inv), TAG, "mclk config failed");
|
||||
|
||||
if (handle->role == I2S_ROLE_SLAVE) {
|
||||
/* For "tx + slave" mode, select TX signal index for ws and bck */
|
||||
@ -168,12 +167,12 @@ static esp_err_t i2s_std_set_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_c
|
||||
i2s_ll_mclk_bind_to_tx_clk(handle->controller->hal.dev);
|
||||
}
|
||||
#endif
|
||||
i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv);
|
||||
/* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */
|
||||
} else {
|
||||
i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv);
|
||||
}
|
||||
} else {
|
||||
/* For "rx + master" mode, select RX signal index for ws and bck */
|
||||
@ -183,12 +182,12 @@ static esp_err_t i2s_std_set_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_c
|
||||
i2s_ll_mclk_bind_to_rx_clk(handle->controller->hal.dev);
|
||||
}
|
||||
#endif
|
||||
i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv);
|
||||
/* For "tx + rx + master" or "tx + master" mode, select TX signal index for ws and bck */
|
||||
} else {
|
||||
i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv);
|
||||
}
|
||||
}
|
||||
/* Update the mode info: gpio configuration */
|
||||
@ -349,6 +348,9 @@ esp_err_t i2s_channel_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_
|
||||
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_STD, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard mode");
|
||||
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be disabled before reconfiguring the gpio");
|
||||
|
||||
if (handle->reserve_gpio_mask) {
|
||||
i2s_output_gpio_revoke(handle, handle->reserve_gpio_mask);
|
||||
}
|
||||
ESP_GOTO_ON_ERROR(i2s_std_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed");
|
||||
xSemaphoreGive(handle->mutex);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -153,17 +153,17 @@ static esp_err_t i2s_tdm_set_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_c
|
||||
/* Loopback if dout = din */
|
||||
if (gpio_cfg->dout != -1 &&
|
||||
gpio_cfg->dout == gpio_cfg->din) {
|
||||
i2s_gpio_loopback_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, i2s_periph_signal[id].data_in_sig);
|
||||
i2s_gpio_loopback_set(handle, gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, i2s_periph_signal[id].data_in_sig);
|
||||
} else if (handle->dir == I2S_DIR_TX) {
|
||||
/* Set data output GPIO */
|
||||
i2s_gpio_check_and_set(gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false, false);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->dout, i2s_periph_signal[id].data_out_sig, false, false);
|
||||
} else {
|
||||
/* Set data input GPIO */
|
||||
i2s_gpio_check_and_set(gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true, false);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->din, i2s_periph_signal[id].data_in_sig, true, false);
|
||||
}
|
||||
|
||||
/* Set mclk pin */
|
||||
ESP_RETURN_ON_ERROR(i2s_check_set_mclk(id, gpio_cfg->mclk, tdm_cfg->clk_cfg.clk_src, gpio_cfg->invert_flags.mclk_inv), TAG, "mclk config failed");
|
||||
ESP_RETURN_ON_ERROR(i2s_check_set_mclk(handle, id, gpio_cfg->mclk, tdm_cfg->clk_cfg.clk_src, gpio_cfg->invert_flags.mclk_inv), TAG, "mclk config failed");
|
||||
|
||||
if (handle->role == I2S_ROLE_SLAVE) {
|
||||
/* For "tx + slave" mode, select TX signal index for ws and bck */
|
||||
@ -173,12 +173,12 @@ static esp_err_t i2s_tdm_set_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_c
|
||||
i2s_ll_mclk_bind_to_tx_clk(handle->controller->hal.dev);
|
||||
}
|
||||
#endif
|
||||
i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].s_tx_ws_sig, true, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].s_tx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv);
|
||||
/* For "tx + rx + slave" or "rx + slave" mode, select RX signal index for ws and bck */
|
||||
} else {
|
||||
i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].s_rx_ws_sig, true, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].s_rx_bck_sig, true, gpio_cfg->invert_flags.bclk_inv);
|
||||
}
|
||||
} else {
|
||||
/* For "rx + master" mode, select RX signal index for ws and bck */
|
||||
@ -188,12 +188,12 @@ static esp_err_t i2s_tdm_set_gpio(i2s_chan_handle_t handle, const i2s_tdm_gpio_c
|
||||
i2s_ll_mclk_bind_to_rx_clk(handle->controller->hal.dev);
|
||||
}
|
||||
#endif
|
||||
i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].m_rx_ws_sig, false, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].m_rx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv);
|
||||
/* For "tx + rx + master" or "tx + master" mode, select TX signal index for ws and bck */
|
||||
} else {
|
||||
i2s_gpio_check_and_set(gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->ws, i2s_periph_signal[id].m_tx_ws_sig, false, gpio_cfg->invert_flags.ws_inv);
|
||||
i2s_gpio_check_and_set(handle, gpio_cfg->bclk, i2s_periph_signal[id].m_tx_bck_sig, false, gpio_cfg->invert_flags.bclk_inv);
|
||||
}
|
||||
}
|
||||
/* Update the mode info: gpio configuration */
|
||||
@ -357,6 +357,9 @@ esp_err_t i2s_channel_reconfig_tdm_gpio(i2s_chan_handle_t handle, const i2s_tdm_
|
||||
ESP_GOTO_ON_FALSE(handle->mode == I2S_COMM_MODE_TDM, ESP_ERR_INVALID_ARG, err, TAG, "This handle is not working in standard mode");
|
||||
ESP_GOTO_ON_FALSE(handle->state == I2S_CHAN_STATE_READY, ESP_ERR_INVALID_STATE, err, TAG, "Invalid state, I2S should be disabled before reconfiguring the gpio");
|
||||
|
||||
if (handle->reserve_gpio_mask) {
|
||||
i2s_output_gpio_revoke(handle, handle->reserve_gpio_mask);
|
||||
}
|
||||
ESP_GOTO_ON_ERROR(i2s_tdm_set_gpio(handle, gpio_cfg), err, TAG, "set i2s standard slot failed");
|
||||
xSemaphoreGive(handle->mutex);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user