mirror of
https://github.com/espressif/esp-idf.git
synced 2024-09-19 14:26:01 -04:00
fix(i2s_platform): merge the i2s platform acquire API
This commit is contained in:
parent
72a0746e62
commit
e1039f9ce2
@ -111,6 +111,7 @@ endif()
|
||||
# I2S related source files
|
||||
if(CONFIG_SOC_I2S_SUPPORTED)
|
||||
list(APPEND srcs "i2s/i2s_common.c"
|
||||
"i2s/i2s_platform.c"
|
||||
"i2s/i2s_std.c"
|
||||
"deprecated/i2s_legacy.c")
|
||||
if(CONFIG_SOC_I2S_SUPPORTS_PDM)
|
||||
@ -236,7 +237,7 @@ else()
|
||||
# Can be removed together with legacy drivers)
|
||||
idf_component_register(SRCS "${srcs}"
|
||||
INCLUDE_DIRS ${includes}
|
||||
PRIV_REQUIRES efuse esp_timer
|
||||
PRIV_REQUIRES efuse esp_timer esp_mm
|
||||
REQUIRES esp_pm esp_ringbuf freertos soc hal esp_hw_support
|
||||
LDFRAGMENTS ${ldfragments}
|
||||
)
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include "esp_pm.h"
|
||||
#include "esp_efuse.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_private/i2s_platform.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/esp_clk.h"
|
||||
|
||||
@ -62,7 +63,7 @@ static const char *TAG = "i2s(legacy)";
|
||||
#define I2S_ENTER_CRITICAL(i2s_num) portENTER_CRITICAL(&i2s_spinlock[i2s_num])
|
||||
#define I2S_EXIT_CRITICAL(i2s_num) portEXIT_CRITICAL(&i2s_spinlock[i2s_num])
|
||||
|
||||
#if SOC_SYS_DIGI_CLKRST_REG_SHARED
|
||||
#if SOC_PERIPH_CLK_CTRL_SHARED
|
||||
#define I2S_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC()
|
||||
#else
|
||||
#define I2S_CLOCK_SRC_ATOMIC()
|
||||
@ -150,9 +151,6 @@ typedef struct {
|
||||
uint32_t total_slot; /*!< Total slot number */
|
||||
} i2s_obj_t;
|
||||
|
||||
// Record the component name that using I2S peripheral
|
||||
static const char *comp_using_i2s[SOC_I2S_NUM] = {[0 ... SOC_I2S_NUM - 1] = NULL};
|
||||
|
||||
// Global I2S object pointer
|
||||
static i2s_obj_t *p_i2s[SOC_I2S_NUM] = {
|
||||
[0 ... SOC_I2S_NUM - 1] = NULL,
|
||||
@ -163,11 +161,6 @@ static portMUX_TYPE i2s_spinlock[SOC_I2S_NUM] = {
|
||||
[0 ... SOC_I2S_NUM - 1] = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED,
|
||||
};
|
||||
|
||||
|
||||
__attribute__((weak)) esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name);
|
||||
|
||||
__attribute__((weak)) esp_err_t i2s_platform_release_occupation(int id);
|
||||
|
||||
/*-------------------------------------------------------------
|
||||
I2S DMA operation
|
||||
-------------------------------------------------------------*/
|
||||
@ -1907,42 +1900,6 @@ esp_err_t i2s_set_pin(i2s_port_t i2s_num, const i2s_pin_config_t *pin)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name)
|
||||
{
|
||||
esp_err_t ret = ESP_ERR_NOT_FOUND;
|
||||
ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id");
|
||||
portENTER_CRITICAL(&i2s_spinlock[id]);
|
||||
if (!comp_using_i2s[id]) {
|
||||
ret = ESP_OK;
|
||||
comp_using_i2s[id] = comp_name;
|
||||
I2S_RCC_ATOMIC() {
|
||||
i2s_ll_enable_bus_clock(id, true);
|
||||
i2s_ll_reset_register(id);
|
||||
i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), true);
|
||||
}
|
||||
}
|
||||
portEXIT_CRITICAL(&i2s_spinlock[id]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t i2s_platform_release_occupation(int id)
|
||||
{
|
||||
esp_err_t ret = ESP_ERR_INVALID_STATE;
|
||||
ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id");
|
||||
portENTER_CRITICAL(&i2s_spinlock[id]);
|
||||
if (comp_using_i2s[id]) {
|
||||
ret = ESP_OK;
|
||||
comp_using_i2s[id] = NULL;
|
||||
/* Disable module clock */
|
||||
I2S_RCC_ATOMIC() {
|
||||
i2s_ll_enable_bus_clock(id, false);
|
||||
i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), false);
|
||||
}
|
||||
}
|
||||
portEXIT_CRITICAL(&i2s_spinlock[id]);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function will be called during start up, to check that the new i2s driver is not running along with the legacy i2s driver
|
||||
*/
|
||||
|
@ -25,10 +25,9 @@
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "hal/i2s_hal.h"
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
#include "hal/cache_hal.h"
|
||||
#include "hal/cache_ll.h"
|
||||
#include "rom/cache.h"
|
||||
#endif
|
||||
|
||||
#if SOC_I2S_SUPPORTS_ADC_DAC
|
||||
@ -52,6 +51,10 @@
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_check.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_dma_utils.h"
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
#include "esp_cache.h"
|
||||
#endif
|
||||
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_memory_utils.h"
|
||||
@ -60,18 +63,15 @@
|
||||
* Set 4092 here to align with 4-byte, so that the position of the slot data in the buffer will be relatively fixed */
|
||||
#define I2S_DMA_BUFFER_MAX_SIZE (4092)
|
||||
|
||||
/**
|
||||
* @brief Global i2s platform object
|
||||
* @note For saving all the I2S related information
|
||||
*/
|
||||
i2s_platform_t g_i2s = {
|
||||
.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED,
|
||||
.controller[0 ... (SOC_I2S_NUM - 1)] = NULL, // groups will be lazy installed
|
||||
.comp_name[0 ... (SOC_I2S_NUM - 1)] = NULL,
|
||||
};
|
||||
|
||||
static const char *TAG = "i2s_common";
|
||||
|
||||
__attribute__((always_inline))
|
||||
inline void *i2s_dma_calloc(size_t num, size_t size, uint32_t caps, size_t *actual_size) {
|
||||
void *ptr = NULL;
|
||||
esp_dma_calloc(num, size, caps, &ptr, actual_size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
I2S Static APIs
|
||||
----------------------------------------------------------------------------
|
||||
@ -298,6 +298,11 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef __cplusplus
|
||||
/* To make sure the i2s_event_callbacks_t is same size as i2s_event_callbacks_internal_t */
|
||||
_Static_assert(sizeof(i2s_event_callbacks_t) == sizeof(i2s_event_callbacks_internal_t), "Invalid size of i2s_event_callbacks_t structure");
|
||||
#endif
|
||||
|
||||
esp_err_t i2s_channel_register_event_callback(i2s_chan_handle_t handle, const i2s_event_callbacks_t *callbacks, void *user_data)
|
||||
{
|
||||
I2S_NULL_POINTER_CHECK(TAG, handle);
|
||||
@ -336,9 +341,9 @@ uint32_t i2s_get_buf_size(i2s_chan_handle_t handle, uint32_t data_bit_width, uin
|
||||
uint32_t bytes_per_sample = ((data_bit_width + 15) / 16) * 2;
|
||||
uint32_t bytes_per_frame = bytes_per_sample * active_chan;
|
||||
uint32_t bufsize = dma_frame_num * bytes_per_frame;
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
/* bufsize need to align with cache line size */
|
||||
uint32_t alignment = cache_hal_get_cache_line_size(CACHE_TYPE_DATA);
|
||||
uint32_t alignment = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA);
|
||||
uint32_t aligned_frame_num = dma_frame_num;
|
||||
/* To make the buffer aligned with the cache line size, search for the ceil aligned size first,
|
||||
If the buffer size exceed the max DMA buffer size, toggle the sign to search for the floor aligned size */
|
||||
@ -401,20 +406,14 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu
|
||||
handle->dma.desc_num = num;
|
||||
handle->dma.buf_size = bufsize;
|
||||
|
||||
#if SOC_GDMA_TRIG_PERIPH_I2S0_BUS == SOC_GDMA_BUS_AHB
|
||||
uint32_t alignment = 64;
|
||||
uint32_t desc_size = alignment;
|
||||
#else
|
||||
uint32_t alignment = 4;
|
||||
uint32_t desc_size = sizeof(lldesc_t);
|
||||
#endif
|
||||
/* Descriptors must be in the internal RAM */
|
||||
handle->dma.desc = (lldesc_t **)heap_caps_calloc(num, sizeof(lldesc_t *), I2S_MEM_ALLOC_CAPS);
|
||||
ESP_GOTO_ON_FALSE(handle->dma.desc, ESP_ERR_NO_MEM, err, TAG, "create I2S DMA decriptor array failed");
|
||||
handle->dma.bufs = (uint8_t **)heap_caps_calloc(num, sizeof(uint8_t *), I2S_MEM_ALLOC_CAPS);
|
||||
size_t desc_size = 0;
|
||||
for (int i = 0; i < num; i++) {
|
||||
/* Allocate DMA descriptor */
|
||||
handle->dma.desc[i] = (lldesc_t *) heap_caps_aligned_calloc(alignment, 1, desc_size, I2S_DMA_ALLOC_CAPS);
|
||||
handle->dma.desc[i] = (lldesc_t *) i2s_dma_calloc(1, sizeof(lldesc_t), I2S_DMA_ALLOC_CAPS, &desc_size);
|
||||
ESP_GOTO_ON_FALSE(handle->dma.desc[i], ESP_ERR_NO_MEM, err, TAG, "allocate DMA description failed");
|
||||
handle->dma.desc[i]->owner = 1;
|
||||
handle->dma.desc[i]->eof = 1;
|
||||
@ -422,7 +421,7 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu
|
||||
handle->dma.desc[i]->length = bufsize;
|
||||
handle->dma.desc[i]->size = bufsize;
|
||||
handle->dma.desc[i]->offset = 0;
|
||||
handle->dma.bufs[i] = (uint8_t *) heap_caps_aligned_calloc(alignment, 1, bufsize * sizeof(uint8_t), I2S_DMA_ALLOC_CAPS);
|
||||
handle->dma.bufs[i] = (uint8_t *) i2s_dma_calloc(1, bufsize * sizeof(uint8_t), I2S_DMA_ALLOC_CAPS, NULL);
|
||||
ESP_GOTO_ON_FALSE(handle->dma.bufs[i], ESP_ERR_NO_MEM, err, TAG, "allocate DMA buffer failed");
|
||||
handle->dma.desc[i]->buf = handle->dma.bufs[i];
|
||||
ESP_LOGV(TAG, "desc addr: %8p\tbuffer addr:%8p", handle->dma.desc[i], handle->dma.bufs[i]);
|
||||
@ -431,8 +430,8 @@ esp_err_t i2s_alloc_dma_desc(i2s_chan_handle_t handle, uint32_t num, uint32_t bu
|
||||
for (int i = 0; i < num; i++) {
|
||||
/* Link to the next descriptor */
|
||||
STAILQ_NEXT(handle->dma.desc[i], qe) = (i < (num - 1)) ? (handle->dma.desc[i + 1]) : handle->dma.desc[0];
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_WriteBack_Addr(CACHE_MAP_L1_DCACHE, (uint32_t)(handle->dma.desc[i]), desc_size);
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
esp_cache_msync(handle->dma.desc[i], desc_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
|
||||
#endif
|
||||
}
|
||||
if (handle->dir == I2S_DIR_RX) {
|
||||
@ -498,8 +497,8 @@ static bool IRAM_ATTR i2s_dma_rx_callback(gdma_channel_handle_t dma_chan, gdma_e
|
||||
uint32_t dummy;
|
||||
|
||||
finish_desc = (lldesc_t *)event_data->rx_eof_desc_addr;
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_Invalidate_Addr(CACHE_MAP_L1_DCACHE, (uint32_t)finish_desc->buf, handle->dma.buf_size);
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
esp_cache_msync((void *)finish_desc->buf, handle->dma.buf_size, ESP_CACHE_MSYNC_FLAG_INVALIDATE);
|
||||
#endif
|
||||
i2s_event_data_t evt = {
|
||||
.data = &(finish_desc->buf),
|
||||
@ -547,8 +546,8 @@ static bool IRAM_ATTR i2s_dma_tx_callback(gdma_channel_handle_t dma_chan, gdma_e
|
||||
if (handle->dma.auto_clear) {
|
||||
uint8_t *sent_buf = (uint8_t *)finish_desc->buf;
|
||||
memset(sent_buf, 0, handle->dma.buf_size);
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_WriteBack_Addr(CACHE_MAP_L1_DCACHE, (uint32_t)sent_buf, handle->dma.buf_size);
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
esp_cache_msync(sent_buf, handle->dma.buf_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
|
||||
#endif
|
||||
}
|
||||
xQueueSendFromISR(handle->msg_queue, &(finish_desc->buf), &need_yield2);
|
||||
@ -691,7 +690,7 @@ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag)
|
||||
gdma_register_rx_event_callbacks(handle->dma.dma_chan, &cb, handle);
|
||||
}
|
||||
#else
|
||||
intr_flag |= handle->intr_flags ? handle->intr_flags : ESP_INTR_FLAG_LOWMED;
|
||||
intr_flag |= handle->intr_prio_flags;
|
||||
/* Initialize I2S module interrupt */
|
||||
if (handle->dir == I2S_DIR_TX) {
|
||||
esp_intr_alloc_intrstatus(i2s_periph_signal[port_id].irq, intr_flag,
|
||||
@ -708,10 +707,10 @@ esp_err_t i2s_init_dma_intr(i2s_chan_handle_t handle, int intr_flag)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void i2s_gpio_check_and_set(gpio_num_t gpio, uint32_t signal_idx, bool is_input, bool is_invert)
|
||||
void i2s_gpio_check_and_set(int gpio, uint32_t signal_idx, bool is_input, bool is_invert)
|
||||
{
|
||||
/* Ignore the pin if pin = I2S_GPIO_UNUSED */
|
||||
if (gpio != I2S_GPIO_UNUSED) {
|
||||
if (gpio != (int)I2S_GPIO_UNUSED) {
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO);
|
||||
if (is_input) {
|
||||
/* Set direction, for some GPIOs, the input function are not enabled as default */
|
||||
@ -724,9 +723,9 @@ void i2s_gpio_check_and_set(gpio_num_t gpio, uint32_t signal_idx, bool is_input,
|
||||
}
|
||||
}
|
||||
|
||||
void i2s_gpio_loopback_set(gpio_num_t gpio, uint32_t out_sig_idx, uint32_t in_sig_idx)
|
||||
void i2s_gpio_loopback_set(int gpio, uint32_t out_sig_idx, uint32_t in_sig_idx)
|
||||
{
|
||||
if (gpio != I2S_GPIO_UNUSED) {
|
||||
if (gpio != (int)I2S_GPIO_UNUSED) {
|
||||
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);
|
||||
@ -734,9 +733,9 @@ void i2s_gpio_loopback_set(gpio_num_t gpio, uint32_t out_sig_idx, uint32_t in_si
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num, i2s_clock_src_t clk_src, bool is_invert)
|
||||
esp_err_t i2s_check_set_mclk(i2s_port_t id, int gpio_num, i2s_clock_src_t clk_src, bool is_invert)
|
||||
{
|
||||
if (gpio_num == I2S_GPIO_UNUSED) {
|
||||
if (gpio_num == (int)I2S_GPIO_UNUSED) {
|
||||
return ESP_OK;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
@ -785,6 +784,7 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *
|
||||
I2S_NULL_POINTER_CHECK(TAG, tx_handle || rx_handle);
|
||||
ESP_RETURN_ON_FALSE(chan_cfg->id < SOC_I2S_NUM || chan_cfg->id == I2S_NUM_AUTO, ESP_ERR_INVALID_ARG, TAG, "invalid I2S port id");
|
||||
ESP_RETURN_ON_FALSE(chan_cfg->dma_desc_num >= 2, ESP_ERR_INVALID_ARG, TAG, "there should be at least 2 DMA buffers");
|
||||
ESP_RETURN_ON_FALSE(chan_cfg->intr_priority >= 0 && chan_cfg->intr_priority <= 7, ESP_ERR_INVALID_ARG, TAG, "intr_priority should be within 0~7");
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
i2s_controller_t *i2s_obj = NULL;
|
||||
@ -816,7 +816,7 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *
|
||||
ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_TX, chan_cfg->dma_desc_num),
|
||||
err, TAG, "register I2S tx channel failed");
|
||||
i2s_obj->tx_chan->role = chan_cfg->role;
|
||||
i2s_obj->tx_chan->intr_flags = chan_cfg->intr_flags;
|
||||
i2s_obj->tx_chan->intr_prio_flags = chan_cfg->intr_priority ? BIT(chan_cfg->intr_priority) : ESP_INTR_FLAG_LOWMED;
|
||||
i2s_obj->tx_chan->dma.auto_clear = chan_cfg->auto_clear;
|
||||
i2s_obj->tx_chan->dma.desc_num = chan_cfg->dma_desc_num;
|
||||
i2s_obj->tx_chan->dma.frame_num = chan_cfg->dma_frame_num;
|
||||
@ -830,7 +830,7 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *
|
||||
ESP_GOTO_ON_ERROR(i2s_register_channel(i2s_obj, I2S_DIR_RX, chan_cfg->dma_desc_num),
|
||||
err, TAG, "register I2S rx channel failed");
|
||||
i2s_obj->rx_chan->role = chan_cfg->role;
|
||||
i2s_obj->rx_chan->intr_flags = chan_cfg->intr_flags;
|
||||
i2s_obj->rx_chan->intr_prio_flags = chan_cfg->intr_priority ? BIT(chan_cfg->intr_priority) : ESP_INTR_FLAG_LOWMED;
|
||||
i2s_obj->rx_chan->dma.desc_num = chan_cfg->dma_desc_num;
|
||||
i2s_obj->rx_chan->dma.frame_num = chan_cfg->dma_frame_num;
|
||||
i2s_obj->rx_chan->start = i2s_rx_channel_start;
|
||||
@ -1071,8 +1071,8 @@ esp_err_t i2s_channel_preload_data(i2s_chan_handle_t tx_handle, const void *src,
|
||||
}
|
||||
/* Load the data from the last loaded position */
|
||||
memcpy((uint8_t *)(tx_handle->dma.curr_ptr + tx_handle->dma.rw_pos), data_ptr, bytes_can_load);
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_WriteBack_Addr(CACHE_MAP_L1_DCACHE, (uint32_t)(tx_handle->dma.curr_ptr + tx_handle->dma.rw_pos), (uint32_t)bytes_can_load);
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
esp_cache_msync(tx_handle->dma.curr_ptr + tx_handle->dma.rw_pos, bytes_can_load, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
|
||||
#endif
|
||||
data_ptr += bytes_can_load; // Move forward the data pointer
|
||||
total_loaded_bytes += bytes_can_load; // Add to the total loaded bytes
|
||||
@ -1130,8 +1130,8 @@ esp_err_t i2s_channel_write(i2s_chan_handle_t handle, const void *src, size_t si
|
||||
bytes_can_write = size;
|
||||
}
|
||||
memcpy(data_ptr, src_byte, bytes_can_write);
|
||||
#if CONFIG_IDF_TARGET_ESP32P4
|
||||
Cache_WriteBack_Addr(CACHE_MAP_L1_DCACHE, (uint32_t)data_ptr, (uint32_t)bytes_can_write);
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
esp_cache_msync(data_ptr, bytes_can_write, ESP_CACHE_MSYNC_FLAG_DIR_C2M);
|
||||
#endif
|
||||
size -= bytes_can_write;
|
||||
src_byte += bytes_can_write;
|
||||
@ -1187,64 +1187,6 @@ esp_err_t i2s_channel_read(i2s_chan_handle_t handle, void *dest, size_t size, si
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
I2S Platform APIs
|
||||
----------------------------------------------------------------------------
|
||||
Scope: This file and ADC/DAC/LCD driver
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
const char *occupied_comp = NULL;
|
||||
ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id");
|
||||
portENTER_CRITICAL(&g_i2s.spinlock);
|
||||
if ((!g_i2s.controller[id]) && (g_i2s.comp_name[id] == NULL)) {
|
||||
g_i2s.comp_name[id] = comp_name;
|
||||
/* Enable module clock */
|
||||
I2S_RCC_ATOMIC() {
|
||||
i2s_ll_enable_bus_clock(id, true);
|
||||
i2s_ll_reset_register(id);
|
||||
i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), true);
|
||||
}
|
||||
} else {
|
||||
occupied_comp = g_i2s.comp_name[id];
|
||||
ret = ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
portEXIT_CRITICAL(&g_i2s.spinlock);
|
||||
if (occupied_comp != NULL) {
|
||||
ESP_LOGW(TAG, "i2s controller %d has been occupied by %s", id, occupied_comp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t i2s_platform_release_occupation(int id)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id");
|
||||
portENTER_CRITICAL(&g_i2s.spinlock);
|
||||
if (!g_i2s.controller[id]) {
|
||||
g_i2s.comp_name[id] = NULL;
|
||||
/* Disable module clock */
|
||||
I2S_RCC_ATOMIC() {
|
||||
i2s_ll_enable_bus_clock(id, false);
|
||||
i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), false);
|
||||
}
|
||||
} else {
|
||||
ret = ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
portEXIT_CRITICAL(&g_i2s.spinlock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Only used in `test_i2s_iram.c` to write DMA buffer directly
|
||||
size_t inline i2s_platform_get_dma_buffer_offset(void)
|
||||
{
|
||||
/* Force to transfer address '0' into 'i2s_chan_handle_t' type,
|
||||
* then find the corresponding field , the address of this field is the offset of this type */
|
||||
return (size_t)&(((i2s_chan_handle_t)0)->dma.bufs);
|
||||
}
|
||||
|
||||
#if SOC_I2S_SUPPORTS_TX_SYNC_CNT
|
||||
uint32_t i2s_sync_get_bclk_count(i2s_chan_handle_t tx_handle)
|
||||
{
|
||||
|
78
components/driver/i2s/i2s_platform.c
Normal file
78
components/driver/i2s/i2s_platform.c
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_check.h"
|
||||
#include "i2s_private.h"
|
||||
|
||||
static const char *TAG = "i2s_platform";
|
||||
|
||||
/**
|
||||
* @brief Global i2s platform object
|
||||
* @note For saving all the I2S related information
|
||||
*/
|
||||
i2s_platform_t g_i2s = {
|
||||
.spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED,
|
||||
.controller[0 ... (SOC_I2S_NUM - 1)] = NULL, // groups will be lazy installed
|
||||
.comp_name[0 ... (SOC_I2S_NUM - 1)] = NULL,
|
||||
};
|
||||
|
||||
/*---------------------------------------------------------------------------
|
||||
I2S Platform APIs
|
||||
----------------------------------------------------------------------------
|
||||
Scope: This file and ADC/DAC/LCD driver
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
esp_err_t i2s_platform_acquire_occupation(int id, const char *comp_name)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
const char *occupied_comp = NULL;
|
||||
ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id");
|
||||
portENTER_CRITICAL(&g_i2s.spinlock);
|
||||
if ((!g_i2s.controller[id]) && (g_i2s.comp_name[id] == NULL)) {
|
||||
g_i2s.comp_name[id] = comp_name;
|
||||
/* Enable module clock */
|
||||
I2S_RCC_ATOMIC() {
|
||||
i2s_ll_enable_bus_clock(id, true);
|
||||
i2s_ll_reset_register(id);
|
||||
i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), true);
|
||||
}
|
||||
} else {
|
||||
occupied_comp = g_i2s.comp_name[id];
|
||||
ret = ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
portEXIT_CRITICAL(&g_i2s.spinlock);
|
||||
if (occupied_comp != NULL) {
|
||||
ESP_LOGW(TAG, "i2s controller %d has been occupied by %s", id, occupied_comp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t i2s_platform_release_occupation(int id)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
ESP_RETURN_ON_FALSE(id < SOC_I2S_NUM, ESP_ERR_INVALID_ARG, TAG, "invalid i2s port id");
|
||||
portENTER_CRITICAL(&g_i2s.spinlock);
|
||||
if (!g_i2s.controller[id]) {
|
||||
g_i2s.comp_name[id] = NULL;
|
||||
/* Disable module clock */
|
||||
I2S_RCC_ATOMIC() {
|
||||
i2s_ll_enable_bus_clock(id, false);
|
||||
i2s_ll_enable_core_clock(I2S_LL_GET_HW(id), false);
|
||||
}
|
||||
} else {
|
||||
ret = ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
portEXIT_CRITICAL(&g_i2s.spinlock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Only used in `test_i2s_iram.c` to write DMA buffer directly
|
||||
size_t i2s_platform_get_dma_buffer_offset(void)
|
||||
{
|
||||
/* Force to transfer address '0' into 'i2s_chan_handle_t' type,
|
||||
* then find the corresponding field , the address of this field is the offset of this type */
|
||||
return (size_t)&(((i2s_chan_handle_t)0)->dma.bufs);
|
||||
}
|
@ -9,7 +9,7 @@
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "soc/lldesc.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/i2s_types.h"
|
||||
#include "hal/i2s_hal.h"
|
||||
#include "driver/i2s_types.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
@ -36,7 +36,7 @@ extern "C" {
|
||||
#endif //CONFIG_I2S_ISR_IRAM_SAFE
|
||||
#define I2S_DMA_ALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_DMA)
|
||||
|
||||
#if SOC_SYS_DIGI_CLKRST_REG_SHARED
|
||||
#if SOC_PERIPH_CLK_CTRL_SHARED
|
||||
#define I2S_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC()
|
||||
#else
|
||||
#define I2S_CLOCK_SRC_ATOMIC()
|
||||
@ -59,6 +59,28 @@ typedef enum {
|
||||
I2S_CHAN_STATE_RUNNING, /*!< i2s channel is idling (initialized and enabled) */
|
||||
} i2s_state_t;
|
||||
|
||||
/**
|
||||
* @brief Group of I2S callbacks
|
||||
* @note The callbacks are all running under ISR environment
|
||||
* @note When CONFIG_I2S_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM.
|
||||
* The variables used in the function should be in the SRAM as well.
|
||||
* @note Declare the internal type to remove the dependency of `i2s_common.h`
|
||||
*/
|
||||
typedef struct {
|
||||
i2s_isr_callback_t on_recv; /**< Callback of data received event, only for rx channel
|
||||
* The event data includes DMA buffer address and size that just finished receiving data
|
||||
*/
|
||||
i2s_isr_callback_t on_recv_q_ovf; /**< Callback of receiving queue overflowed event, only for rx channel
|
||||
* The event data includes buffer size that has been overwritten
|
||||
*/
|
||||
i2s_isr_callback_t on_sent; /**< Callback of data sent event, only for tx channel
|
||||
* The event data includes DMA buffer address and size that just finished sending data
|
||||
*/
|
||||
i2s_isr_callback_t on_send_q_ovf; /**< Callback of sending queue overflowed event, only for tx channel
|
||||
* The event data includes buffer size that has been overwritten
|
||||
*/
|
||||
} i2s_event_callbacks_internal_t;
|
||||
|
||||
/**
|
||||
* @brief i2s channel level configurations
|
||||
* @note It performs as channel handle
|
||||
@ -103,7 +125,7 @@ struct i2s_channel_obj_t {
|
||||
i2s_dma_t dma; /*!< i2s dma object */
|
||||
i2s_state_t state; /*!< i2s driver state. Ensuring the driver working in a correct sequence */
|
||||
/* Stored configurations */
|
||||
int intr_flags;
|
||||
int intr_prio_flags;/*!< i2s interrupt priority flags */
|
||||
void *mode_info; /*!< Slot, clock and gpio information of each mode */
|
||||
#if SOC_I2S_SUPPORTS_APLL
|
||||
bool apll_en; /*!< Flag of wether APLL enabled */
|
||||
@ -117,7 +139,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 */
|
||||
i2s_event_callbacks_t callbacks; /*!< Callback functions */
|
||||
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 */
|
||||
void (*stop)(i2s_chan_handle_t); /*!< stop tx/rx channel */
|
||||
@ -133,7 +155,7 @@ typedef struct {
|
||||
const char *comp_name[SOC_I2S_NUM]; /*!< The component name that occupied i2s controller */
|
||||
} i2s_platform_t;
|
||||
|
||||
extern i2s_platform_t g_i2s;
|
||||
extern i2s_platform_t g_i2s; /*!< Global i2s instance for driver internal use */
|
||||
|
||||
/**
|
||||
* @brief Initialize I2S DMA interrupt
|
||||
@ -200,7 +222,7 @@ uint32_t i2s_get_source_clk_freq(i2s_clock_src_t clk_src, uint32_t mclk_freq_hz)
|
||||
* @param is_input Is input gpio
|
||||
* @param is_invert Is invert gpio
|
||||
*/
|
||||
void i2s_gpio_check_and_set(gpio_num_t gpio, uint32_t signal_idx, bool is_input, bool is_invert);
|
||||
void i2s_gpio_check_and_set(int gpio, uint32_t signal_idx, bool is_input, bool is_invert);
|
||||
|
||||
/**
|
||||
* @brief Check gpio validity and output mclk signal
|
||||
@ -213,7 +235,7 @@ void i2s_gpio_check_and_set(gpio_num_t gpio, uint32_t signal_idx, bool is_input,
|
||||
* - 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, gpio_num_t gpio_num, i2s_clock_src_t clk_src, bool is_invert);
|
||||
esp_err_t i2s_check_set_mclk(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
|
||||
@ -222,7 +244,7 @@ esp_err_t i2s_check_set_mclk(i2s_port_t id, gpio_num_t gpio_num, i2s_clock_src_t
|
||||
* @param out_sig_idx Data out signal index
|
||||
* @param in_sig_idx Data in signal index
|
||||
*/
|
||||
void i2s_gpio_loopback_set(gpio_num_t gpio, uint32_t out_sig_idx, uint32_t in_sig_idx);
|
||||
void i2s_gpio_loopback_set(int gpio, uint32_t out_sig_idx, uint32_t in_sig_idx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ extern "C" {
|
||||
.dma_desc_num = 6, \
|
||||
.dma_frame_num = 240, \
|
||||
.auto_clear = false, \
|
||||
.intr_flags = 0, \
|
||||
.intr_priority = 0, \
|
||||
}
|
||||
|
||||
#define I2S_GPIO_UNUSED GPIO_NUM_NC /*!< Used in i2s_gpio_config_t for signals which are not used */
|
||||
@ -64,7 +64,7 @@ typedef struct {
|
||||
* it should be the multiple of '3' when the data bit width is 24.
|
||||
*/
|
||||
bool auto_clear; /*!< Set to auto clear DMA TX buffer, i2s will always send zero automatically if no data to send */
|
||||
int intr_flags; /*!< Flags used to allocate the interrupt. One or multiple (ORred) ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info */
|
||||
int intr_priority; /*!< I2S interrupt priority, range [0, 7], if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) */
|
||||
} i2s_chan_config_t;
|
||||
|
||||
/**
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "soc/i2s_struct.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "hal/i2s_types.h"
|
||||
#include "hal/hal_utils.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -31,22 +32,12 @@ extern "C" {
|
||||
#define I2S_LL_TDM_CH_MASK (0xffff)
|
||||
#define I2S_LL_PDM_BCK_FACTOR (64)
|
||||
|
||||
#define I2S_LL_MCLK_DIVIDER_BIT_WIDTH (9)
|
||||
#define I2S_LL_MCLK_DIVIDER_MAX ((1 << I2S_LL_MCLK_DIVIDER_BIT_WIDTH) - 1)
|
||||
#define I2S_LL_CLK_FRAC_DIV_N_MAX 256 // I2S_MCLK = I2S_SRC_CLK / (N + b/a), the N register is 8 bit-width
|
||||
#define I2S_LL_CLK_FRAC_DIV_AB_MAX 512 // I2S_MCLK = I2S_SRC_CLK / (N + b/a), the a/b register is 9 bit-width
|
||||
|
||||
#define I2S_LL_XTAL_CLK_FREQ (40 * 1000000) // XTAL_CLK: 40MHz
|
||||
#define I2S_LL_DEFAULT_CLK_FREQ I2S_LL_XTAL_CLK_FREQ // No PLL clock source on P4, use XTAL as default
|
||||
|
||||
/**
|
||||
* @brief I2S clock configuration structure
|
||||
* @note Fmclk = Fsclk /(integ+numer/denom)
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t integ; // Integer part of I2S module clock divider
|
||||
uint16_t denom; // Denominator part of I2S module clock divider
|
||||
uint16_t numer; // Numerator part of I2S module clock divider
|
||||
} i2s_ll_mclk_div_t;
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for I2S module
|
||||
*
|
||||
@ -328,7 +319,7 @@ static inline uint32_t i2s_ll_get_clk_src(i2s_clock_src_t src)
|
||||
return 2;
|
||||
default:
|
||||
HAL_ASSERT(false && "unsupported clock source");
|
||||
break;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -471,7 +462,7 @@ static inline void i2s_ll_rx_set_raw_clk_div(i2s_dev_t *hw, uint32_t div_int, ui
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param mclk_div The mclk division coefficients
|
||||
*/
|
||||
static inline void i2s_ll_tx_set_mclk(i2s_dev_t *hw, const i2s_ll_mclk_div_t *mclk_div)
|
||||
static inline void i2s_ll_tx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
@ -484,13 +475,13 @@ static inline void i2s_ll_tx_set_mclk(i2s_dev_t *hw, const i2s_ll_mclk_div_t *mc
|
||||
uint32_t div_z = 0;
|
||||
uint32_t div_yn1 = 0;
|
||||
/* If any of denominator and numerator is 0, set all the coefficients to 0 */
|
||||
if (mclk_div->denom && mclk_div->numer) {
|
||||
div_yn1 = mclk_div->numer * 2 > mclk_div->denom;
|
||||
div_z = div_yn1 ? mclk_div->denom - mclk_div->numer : mclk_div->numer;
|
||||
div_x = mclk_div->denom / div_z - 1;
|
||||
div_y = mclk_div->denom % div_z;
|
||||
if (mclk_div->denominator && mclk_div->numerator) {
|
||||
div_yn1 = mclk_div->numerator * 2 > mclk_div->denominator;
|
||||
div_z = div_yn1 ? mclk_div->denominator - mclk_div->numerator : mclk_div->numerator;
|
||||
div_x = mclk_div->denominator / div_z - 1;
|
||||
div_y = mclk_div->denominator % div_z;
|
||||
}
|
||||
i2s_ll_tx_set_raw_clk_div(hw, mclk_div->integ, div_x, div_y, div_z, div_yn1);
|
||||
i2s_ll_tx_set_raw_clk_div(hw, mclk_div->integer, div_x, div_y, div_z, div_yn1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -511,7 +502,7 @@ static inline void i2s_ll_rx_set_bck_div_num(i2s_dev_t *hw, uint32_t val)
|
||||
* @param hw Peripheral I2S hardware instance address.
|
||||
* @param mclk_div The mclk division coefficients
|
||||
*/
|
||||
static inline void i2s_ll_rx_set_mclk(i2s_dev_t *hw, const i2s_ll_mclk_div_t *mclk_div)
|
||||
static inline void i2s_ll_rx_set_mclk(i2s_dev_t *hw, const hal_utils_clk_div_t *mclk_div)
|
||||
{
|
||||
/* Workaround for inaccurate clock while switching from a relatively low sample rate to a high sample rate
|
||||
* Set to particular coefficients first then update to the target coefficients,
|
||||
@ -524,13 +515,13 @@ static inline void i2s_ll_rx_set_mclk(i2s_dev_t *hw, const i2s_ll_mclk_div_t *mc
|
||||
uint32_t div_z = 0;
|
||||
uint32_t div_yn1 = 0;
|
||||
/* If any of denominator and numerator is 0, set all the coefficients to 0 */
|
||||
if (mclk_div->denom && mclk_div->numer) {
|
||||
div_yn1 = mclk_div->numer * 2 > mclk_div->denom;
|
||||
div_z = div_yn1 ? mclk_div->denom - mclk_div->numer : mclk_div->numer;
|
||||
div_x = mclk_div->denom / div_z - 1;
|
||||
div_y = mclk_div->denom % div_z;
|
||||
if (mclk_div->denominator && mclk_div->numerator) {
|
||||
div_yn1 = mclk_div->numerator * 2 > mclk_div->denominator;
|
||||
div_z = div_yn1 ? mclk_div->denominator - mclk_div->numerator : mclk_div->numerator;
|
||||
div_x = mclk_div->denominator / div_z - 1;
|
||||
div_y = mclk_div->denominator % div_z;
|
||||
}
|
||||
i2s_ll_rx_set_raw_clk_div(hw, mclk_div->integ, div_x, div_y, div_z, div_yn1);
|
||||
i2s_ll_rx_set_raw_clk_div(hw, mclk_div->integer, div_x, div_y, div_z, div_yn1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,7 +147,7 @@ void i2s_hal_calc_mclk_precise_division(uint32_t sclk, uint32_t mclk, hal_utils_
|
||||
*/
|
||||
void _i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src);
|
||||
|
||||
#if SOC_SYS_DIGI_CLKRST_REG_SHARED
|
||||
#if SOC_PERIPH_CLK_CTRL_SHARED
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define i2s_hal_set_tx_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _i2s_hal_set_tx_clock(__VA_ARGS__)
|
||||
@ -164,7 +164,7 @@ void _i2s_hal_set_tx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *c
|
||||
*/
|
||||
void _i2s_hal_set_rx_clock(i2s_hal_context_t *hal, const i2s_hal_clock_info_t *clk_info, i2s_clock_src_t clk_src);
|
||||
|
||||
#if SOC_SYS_DIGI_CLKRST_REG_SHARED
|
||||
#if SOC_PERIPH_CLK_CTRL_SHARED
|
||||
/// use a macro to wrap the function, force the caller to use it in a critical section
|
||||
/// the critical section needs to declare the __DECLARE_RCC_ATOMIC_ENV variable in advance
|
||||
#define i2s_hal_set_rx_clock(...) (void)__DECLARE_RCC_ATOMIC_ENV; _i2s_hal_set_rx_clock(__VA_ARGS__)
|
||||
|
@ -1123,10 +1123,6 @@ config SOC_PM_PAU_LINK_NUM
|
||||
int
|
||||
default 4
|
||||
|
||||
config SOC_SYS_DIGI_CLKRST_REG_SHARED
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
|
||||
bool
|
||||
default n
|
||||
|
@ -48,7 +48,6 @@
|
||||
// #define SOC_EFUSE_SUPPORTED 1 //TODO: IDF-7512
|
||||
#define SOC_RTC_FAST_MEM_SUPPORTED 1
|
||||
#define SOC_RTC_MEM_SUPPORTED 1
|
||||
// #define SOC_I2S_SUPPORTED 1 //TODO: IDF-6508
|
||||
#define SOC_RMT_SUPPORTED 1
|
||||
#define SOC_I2S_SUPPORTED 1
|
||||
// #define SOC_RMT_SUPPORTED 1 //TODO: IDF-7476
|
||||
@ -154,7 +153,6 @@
|
||||
#define SOC_CPU_HAS_PMA 1
|
||||
#define SOC_CPU_IDRAM_SPLIT_USING_PMP 1
|
||||
|
||||
// TODO: IDF-5360 (Copy from esp32c3, need check)
|
||||
/*-------------------------- DIGITAL SIGNATURE CAPS ----------------------------------------*/
|
||||
/** The maximum length of a Digital Signature in bits. */
|
||||
#define SOC_DS_SIGNATURE_MAX_BIT_LEN (4096)
|
||||
@ -514,7 +512,6 @@
|
||||
#define SOC_PM_PAU_LINK_NUM (4)
|
||||
|
||||
/*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
|
||||
#define SOC_SYS_DIGI_CLKRST_REG_SHARED (1)
|
||||
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (0)
|
||||
#define SOC_MODEM_CLOCK_IS_INDEPENDENT (0)
|
||||
|
||||
|
@ -3,7 +3,6 @@ api-guides/coexist
|
||||
api-guides/cplusplus
|
||||
api-guides/dfu
|
||||
api-guides/index
|
||||
api-reference/peripherals/i2s
|
||||
api-reference/peripherals/spi_features
|
||||
api-reference/peripherals/sdio_slave
|
||||
api-reference/peripherals/adc_calibration
|
||||
|
@ -111,7 +111,6 @@ api-reference/peripherals/gpio.rst
|
||||
api-reference/peripherals/sdspi_host.rst
|
||||
api-reference/peripherals/dac.rst
|
||||
api-reference/peripherals/spi_slave.rst
|
||||
api-reference/peripherals/i2s.rst
|
||||
api-reference/peripherals/touch_element.rst
|
||||
api-reference/peripherals/lcd.rst
|
||||
api-reference/peripherals/ana_cmpr.rst
|
||||
|
@ -116,6 +116,7 @@ ESP32-C3 I2S 0 I2S 0 none I2S 0 none none
|
||||
ESP32-C6 I2S 0 I2S 0 none I2S 0 none none
|
||||
ESP32-S3 I2S 0/1 I2S 0 I2S 0 I2S 0/1 none none
|
||||
ESP32-H2 I2S 0 I2S 0 none I2S 0 none none
|
||||
ESP32-P4 I2S 0~2 I2S 0 I2S 0 I2S 0~2 none none
|
||||
========= ======== ======== ======== ======== ======== ==========
|
||||
|
||||
Standard Mode
|
||||
|
Loading…
Reference in New Issue
Block a user