forked from espressif/esp-idf
feat(i2s): support sleep retention
This commit is contained in:
committed by
Kevin (Lao Kaiyao)
parent
b835986b62
commit
0cb4bdc54e
@@ -41,6 +41,7 @@
|
||||
|
||||
#include "esp_private/i2s_platform.h"
|
||||
#include "esp_private/esp_clk.h"
|
||||
#include "esp_private/sleep_retention.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_private/gpio.h"
|
||||
@@ -85,6 +86,34 @@ inline void *i2s_dma_calloc(i2s_chan_handle_t handle, size_t num, size_t size)
|
||||
Scope: This file only
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#if I2S_USE_RETENTION_LINK
|
||||
static esp_err_t s_i2s_create_sleep_retention_link_cb(void *arg)
|
||||
{
|
||||
i2s_controller_t *i2s_obj = (i2s_controller_t *)arg;
|
||||
ESP_RETURN_ON_ERROR(sleep_retention_entries_create(i2s_reg_retention_info[i2s_obj->id].entry_array,
|
||||
i2s_reg_retention_info[i2s_obj->id].array_size,
|
||||
REGDMA_LINK_PRI_I2S, i2s_obj->slp_retention_mod),
|
||||
TAG, "create retention link failed");
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void s_i2s_create_retention_module(i2s_controller_t *i2s_obj)
|
||||
{
|
||||
sleep_retention_module_t module = i2s_obj->slp_retention_mod;
|
||||
|
||||
_lock_acquire(&i2s_obj->mutex);
|
||||
if (i2s_obj->retention_link_created == false) {
|
||||
if (sleep_retention_module_allocate(module) != ESP_OK) {
|
||||
// even though the sleep retention module create failed, I2S driver should still work, so just warning here
|
||||
ESP_LOGW(TAG, "create retention module failed, power domain can't turn off");
|
||||
} else {
|
||||
i2s_obj->retention_link_created = true;
|
||||
}
|
||||
}
|
||||
_lock_release(&i2s_obj->mutex);
|
||||
}
|
||||
#endif // I2S_USE_RETENTION_LINK
|
||||
|
||||
static void i2s_tx_channel_start(i2s_chan_handle_t handle)
|
||||
{
|
||||
i2s_hal_tx_reset(&(handle->controller->hal));
|
||||
@@ -175,6 +204,14 @@ static esp_err_t i2s_destroy_controller_obj(i2s_controller_t **i2s_obj)
|
||||
#if SOC_I2S_HW_VERSION_1
|
||||
i2s_ll_enable_dma((*i2s_obj)->hal.dev, false);
|
||||
#endif
|
||||
#if I2S_USE_RETENTION_LINK
|
||||
if ((*i2s_obj)->slp_retention_mod) {
|
||||
if ((*i2s_obj)->retention_link_created) {
|
||||
sleep_retention_module_free((*i2s_obj)->slp_retention_mod);
|
||||
}
|
||||
sleep_retention_module_deinit((*i2s_obj)->slp_retention_mod);
|
||||
}
|
||||
#endif // I2S_USE_RETENTION_LINK
|
||||
free(*i2s_obj);
|
||||
*i2s_obj = NULL;
|
||||
return i2s_platform_release_occupation(I2S_CTLR_HP, id);
|
||||
@@ -219,6 +256,25 @@ static i2s_controller_t *i2s_acquire_controller_obj(int id)
|
||||
adc_ll_digi_set_data_source(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if I2S_USE_RETENTION_LINK
|
||||
sleep_retention_module_t module = i2s_periph_signal[id].retention_module;
|
||||
sleep_retention_module_init_param_t init_param = {
|
||||
.cbs = {
|
||||
.create = {
|
||||
.handle = s_i2s_create_sleep_retention_link_cb,
|
||||
.arg = i2s_obj,
|
||||
},
|
||||
},
|
||||
.depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM)
|
||||
};
|
||||
if (sleep_retention_module_init(module, &init_param) == ESP_OK) {
|
||||
i2s_obj->slp_retention_mod = module;
|
||||
} else {
|
||||
// even the sleep retention module init failed, I2S driver should still work, so just warning here
|
||||
ESP_LOGW(TAG, "init sleep retention failed for I2S%d, power domain may be turned off during sleep", id);
|
||||
}
|
||||
#endif // I2S_USE_RETENTION_LINK
|
||||
} else {
|
||||
free(pre_alloc);
|
||||
portENTER_CRITICAL(&g_i2s.spinlock);
|
||||
@@ -879,6 +935,9 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *
|
||||
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");
|
||||
#if !SOC_I2S_SUPPORT_SLEEP_RETENTION
|
||||
ESP_RETURN_ON_FALSE(!chan_cfg->backup_before_sleep, ESP_ERR_NOT_SUPPORTED, TAG, "register back up is not supported");
|
||||
#endif
|
||||
|
||||
esp_err_t ret = ESP_OK;
|
||||
i2s_controller_t *i2s_obj = NULL;
|
||||
@@ -937,6 +996,11 @@ esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *
|
||||
if ((tx_handle != NULL) && (rx_handle != NULL)) {
|
||||
i2s_obj->full_duplex = true;
|
||||
}
|
||||
#if I2S_USE_RETENTION_LINK
|
||||
if (chan_cfg->backup_before_sleep) {
|
||||
s_i2s_create_retention_module(i2s_obj);
|
||||
}
|
||||
#endif
|
||||
|
||||
return ESP_OK;
|
||||
/* i2s_obj allocated but register channel failed */
|
||||
|
@@ -6,6 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sys/lock.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
@@ -25,6 +26,7 @@
|
||||
#endif
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "esp_private/esp_gpio_reserve.h"
|
||||
#include "esp_private/sleep_retention.h"
|
||||
#include "esp_pm.h"
|
||||
#include "esp_err.h"
|
||||
#include "sdkconfig.h"
|
||||
@@ -56,6 +58,8 @@ extern "C" {
|
||||
#define I2S_RCC_ATOMIC()
|
||||
#endif
|
||||
|
||||
#define I2S_USE_RETENTION_LINK (SOC_I2S_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP)
|
||||
|
||||
#define I2S_NULL_POINTER_CHECK(tag, p) ESP_RETURN_ON_FALSE((p), ESP_ERR_INVALID_ARG, tag, "input parameter '"#p"' is NULL")
|
||||
|
||||
/**
|
||||
@@ -130,6 +134,9 @@ typedef struct {
|
||||
bool full_duplex; /*!< is full_duplex */
|
||||
i2s_chan_handle_t tx_chan; /*!< tx channel handler */
|
||||
i2s_chan_handle_t rx_chan; /*!< rx channel handler */
|
||||
_lock_t mutex; /*!< mutex for controller */
|
||||
sleep_retention_module_t slp_retention_mod; /*!< Sleep retention module */
|
||||
bool retention_link_created; /*!< Whether the retention link is created */
|
||||
int mclk; /*!< MCK out pin, shared by tx/rx*/
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_clock_output_mapping_handle_t mclk_out_hdl; /*!< The handle of MCLK output signal */
|
||||
|
@@ -26,6 +26,7 @@ extern "C" {
|
||||
.dma_frame_num = 240, \
|
||||
.auto_clear_after_cb = false, \
|
||||
.auto_clear_before_cb = false, \
|
||||
.backup_before_sleep = false, \
|
||||
.intr_priority = 0, \
|
||||
}
|
||||
|
||||
@@ -73,6 +74,9 @@ typedef struct {
|
||||
bool auto_clear_before_cb; /*!< Set to auto clear DMA TX buffer before `on_sent` callback, I2S will always send zero automatically if no data to send
|
||||
* So that user can access data in the callback that just finished to send.
|
||||
*/
|
||||
bool backup_before_sleep; /*!< If set, the driver will backup/restore the I2S registers before/after entering/exist sleep mode.
|
||||
By this approach, the system can power off I2S's power domain.
|
||||
This can save power, but at the expense of more RAM being consumed */
|
||||
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;
|
||||
|
||||
|
@@ -6,6 +6,10 @@ if(CONFIG_SOC_I2S_SUPPORTS_ETM AND CONFIG_SOC_GPIO_SUPPORT_ETM)
|
||||
set(srcs ${srcs} "test_i2s_etm.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_I2S_SUPPORT_SLEEP_RETENTION)
|
||||
list(APPEND srcs "test_i2s_slp_retention.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
PRIV_REQUIRES unity esp_driver_pcnt spi_flash esp_driver_gpio esp_driver_i2s
|
||||
PRIV_REQUIRES unity esp_driver_pcnt spi_flash esp_driver_gpio esp_driver_i2s esp_driver_uart
|
||||
WHOLE_ARCHIVE)
|
||||
|
@@ -94,7 +94,7 @@ static void i2s_test_io_config(int mode)
|
||||
}
|
||||
}
|
||||
|
||||
static void i2s_read_write_test(i2s_chan_handle_t tx_chan, i2s_chan_handle_t rx_chan)
|
||||
void i2s_read_write_test(i2s_chan_handle_t tx_chan, i2s_chan_handle_t rx_chan)
|
||||
{
|
||||
#define I2S_SEND_BUF_LEN 100
|
||||
#define I2S_RECV_BUF_LEN 10000
|
||||
|
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "unity.h"
|
||||
#include "unity_test_utils.h"
|
||||
#include "driver/i2s_std.h"
|
||||
#include "driver/uart.h"
|
||||
#include "soc/i2s_struct.h"
|
||||
#include "esp_sleep.h"
|
||||
#include "esp_private/sleep_cpu.h"
|
||||
#include "esp_private/esp_sleep_internal.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
#include "../../test_inc/test_i2s.h"
|
||||
|
||||
#if SOC_I2S_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||
|
||||
extern void i2s_read_write_test(i2s_chan_handle_t tx_chan, i2s_chan_handle_t rx_chan);
|
||||
|
||||
static void test_i2s_enter_light_sleep(int sec)
|
||||
{
|
||||
esp_sleep_context_t sleep_ctx;
|
||||
esp_sleep_set_sleep_context(&sleep_ctx);
|
||||
printf("Entering light sleep for %d seconds\n", sec);
|
||||
#if ESP_SLEEP_POWER_DOWN_CPU
|
||||
printf("Enable CPU power down\n");
|
||||
TEST_ESP_OK(sleep_cpu_configure(true));
|
||||
#endif
|
||||
uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM);
|
||||
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(sec * 1000 * 1000));
|
||||
TEST_ESP_OK(esp_light_sleep_start());
|
||||
|
||||
#if ESP_SLEEP_POWER_DOWN_CPU
|
||||
TEST_ESP_OK(sleep_cpu_configure(false));
|
||||
#endif
|
||||
printf("Woke up from light sleep\n");
|
||||
|
||||
TEST_ASSERT_EQUAL(0, sleep_ctx.sleep_request_result);
|
||||
TEST_ASSERT_EQUAL(PMU_SLEEP_PD_TOP, sleep_ctx.sleep_flags & PMU_SLEEP_PD_TOP);
|
||||
esp_sleep_set_sleep_context(NULL);
|
||||
}
|
||||
|
||||
TEST_CASE("I2S_sleep_retention_test", "[i2s]")
|
||||
{
|
||||
i2s_chan_handle_t tx_handle;
|
||||
i2s_chan_handle_t rx_handle;
|
||||
|
||||
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
|
||||
chan_cfg.backup_before_sleep = true;
|
||||
i2s_std_config_t std_cfg = {
|
||||
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(SAMPLE_RATE),
|
||||
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(SAMPLE_BITS, I2S_SLOT_MODE_STEREO),
|
||||
.gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN,
|
||||
};
|
||||
std_cfg.gpio_cfg.din = std_cfg.gpio_cfg.dout;
|
||||
TEST_ESP_OK(i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle));
|
||||
TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &std_cfg));
|
||||
TEST_ESP_OK(i2s_channel_init_std_mode(rx_handle, &std_cfg));
|
||||
|
||||
/* I2S retention is depended on GDMA retention.
|
||||
* Only take two registers as sample to check the I2S retention when GDMA retention has not been supported. */
|
||||
#if !SOC_GDMA_SUPPORT_SLEEP_RETENTION
|
||||
i2s_tx_conf_reg_t tx_reg_before_slp = I2S0.tx_conf;
|
||||
i2s_rx_conf_reg_t rx_reg_before_slp = I2S0.rx_conf;
|
||||
#endif
|
||||
|
||||
/* Enter light sleep and wake up after 1 second */
|
||||
test_i2s_enter_light_sleep(1);
|
||||
|
||||
#if SOC_GDMA_SUPPORT_SLEEP_RETENTION
|
||||
/* Check whether I2S can work correctly after light sleep */
|
||||
TEST_ESP_OK(i2s_channel_enable(tx_handle));
|
||||
TEST_ESP_OK(i2s_channel_enable(rx_handle));
|
||||
i2s_read_write_test(tx_handle, rx_handle);
|
||||
#else
|
||||
/* Only check whether the register values are restored if GDMA retention has not been supported */
|
||||
i2s_tx_conf_reg_t tx_reg_after_slp = I2S0.tx_conf;
|
||||
i2s_rx_conf_reg_t rx_reg_after_slp = I2S0.rx_conf;
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT32(tx_reg_before_slp.val, tx_reg_after_slp.val);
|
||||
TEST_ASSERT_EQUAL_UINT32(rx_reg_before_slp.val, rx_reg_after_slp.val);
|
||||
|
||||
TEST_ESP_OK(i2s_channel_enable(tx_handle));
|
||||
TEST_ESP_OK(i2s_channel_enable(rx_handle));
|
||||
#endif
|
||||
|
||||
printf("I2S works as expected after light sleep\n");
|
||||
|
||||
TEST_ESP_OK(i2s_channel_disable(tx_handle));
|
||||
TEST_ESP_OK(i2s_channel_disable(rx_handle));
|
||||
TEST_ESP_OK(i2s_del_channel(tx_handle));
|
||||
TEST_ESP_OK(i2s_del_channel(rx_handle));
|
||||
}
|
||||
|
||||
#endif // SOC_I2S_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
@@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
@@ -3,3 +3,4 @@ CONFIG_FREERTOS_USE_TICKLESS_IDLE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
|
||||
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
||||
CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP=y
|
||||
|
@@ -1,2 +1,4 @@
|
||||
CONFIG_I2S_ENABLE_DEBUG_LOG=y
|
||||
CONFIG_ESP_TASK_WDT_EN=n
|
||||
# primitives for checking sleep internal state
|
||||
CONFIG_ESP_SLEEP_DEBUG=y
|
||||
|
@@ -29,7 +29,6 @@ const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
|
||||
.data_in_sig = I2S0I_DATA_IN15_IDX,
|
||||
|
||||
.irq = ETS_I2S0_INTR_SOURCE,
|
||||
.module = PERIPH_I2S0_MODULE,
|
||||
},
|
||||
{
|
||||
.mck_out_sig = -1, // Unavailable
|
||||
@@ -49,6 +48,5 @@ const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
|
||||
.data_in_sig = I2S1I_DATA_IN15_IDX,
|
||||
|
||||
.irq = ETS_I2S1_INTR_SOURCE,
|
||||
.module = PERIPH_I2S1_MODULE,
|
||||
}
|
||||
};
|
||||
|
@@ -30,6 +30,5 @@ const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
|
||||
.data_in_sig = I2SI_SD_IN_IDX,
|
||||
|
||||
.irq = ETS_I2S1_INTR_SOURCE,
|
||||
.module = PERIPH_I2S1_MODULE,
|
||||
}
|
||||
};
|
||||
|
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "soc/i2s_periph.h"
|
||||
#include "soc/i2s_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
/*
|
||||
@@ -30,6 +31,48 @@ const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
|
||||
.data_in_sig = I2SI_SD_IN_IDX,
|
||||
|
||||
.irq = ETS_I2S1_INTR_SOURCE,
|
||||
.module = -1,
|
||||
.retention_module = SLEEP_RETENTION_MODULE_I2S0,
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* I2S Registers to be saved during sleep retention
|
||||
* - I2S_RX_CONF_REG
|
||||
* - I2S_TX_CONF_REG
|
||||
* - I2S_RX_CONF1_REG
|
||||
* - I2S_TX_CONF1_REG
|
||||
* - I2S_TX_PCM2PDM_CONF_REG
|
||||
* - I2S_TX_PCM2PDM_CONF1_REG
|
||||
* - I2S_RX_TDM_CTRL_REG
|
||||
* - I2S_TX_TDM_CTRL_REG
|
||||
* - I2S_RXEOF_NUM_REG
|
||||
* - I2S_ETM_CONF_REG
|
||||
*/
|
||||
#define I2S_RETENTION_REGS_CNT 10
|
||||
#define I2S_RETENTION_REGS_BASE(i) I2S_RX_CONF_REG(i)
|
||||
static const uint32_t i2s_regs_map[4] = {0x12360f, 0x0, 0x0, 0x0};
|
||||
#define I2S_SLEEP_RETENTION_ENTRIES(i2s_port) { \
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT( \
|
||||
REGDMA_I2S_LINK(0x00), \
|
||||
I2S_RETENTION_REGS_BASE(i2s_port), \
|
||||
I2S_RETENTION_REGS_BASE(i2s_port), \
|
||||
I2S_RETENTION_REGS_CNT, 0, 0, \
|
||||
i2s_regs_map[0], i2s_regs_map[1], \
|
||||
i2s_regs_map[2], i2s_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2)}, \
|
||||
[1] = { .config = REGDMA_LINK_WRITE_INIT( \
|
||||
REGDMA_I2S_LINK(0x01), I2S_RX_CONF_REG(i2s_port), I2S_RX_UPDATE, I2S_RX_UPDATE_M, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2)}, \
|
||||
[2] = { .config = REGDMA_LINK_WRITE_INIT( \
|
||||
REGDMA_I2S_LINK(0x02), I2S_TX_CONF_REG(i2s_port), I2S_TX_UPDATE, I2S_TX_UPDATE_M, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2)} \
|
||||
};
|
||||
|
||||
static const regdma_entries_config_t i2s0_regs_retention[] = I2S_SLEEP_RETENTION_ENTRIES(0);
|
||||
|
||||
const i2s_reg_retention_info_t i2s_reg_retention_info[SOC_I2S_NUM] = {
|
||||
[0] = {
|
||||
.entry_array = i2s0_regs_retention,
|
||||
.array_size = ARRAY_SIZE(i2s0_regs_retention)
|
||||
},
|
||||
};
|
||||
|
@@ -675,6 +675,10 @@ config SOC_I2S_TDM_FULL_DATA_WIDTH
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
|
||||
bool
|
||||
default y
|
||||
|
@@ -36,6 +36,7 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_RMT0 = 13,
|
||||
SLEEP_RETENTION_MODULE_UART0 = 14,
|
||||
SLEEP_RETENTION_MODULE_UART1 = 15,
|
||||
SLEEP_RETENTION_MODULE_I2S0 = 16,
|
||||
|
||||
/* modem module, which includes WiFi, BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_WIFI_MAC = 26,
|
||||
@@ -74,6 +75,7 @@ typedef enum periph_retention_module_bitmap {
|
||||
SLEEP_RETENTION_MODULE_BM_RMT0 = BIT(SLEEP_RETENTION_MODULE_RMT0),
|
||||
SLEEP_RETENTION_MODULE_BM_UART0 = BIT(SLEEP_RETENTION_MODULE_UART0),
|
||||
SLEEP_RETENTION_MODULE_BM_UART1 = BIT(SLEEP_RETENTION_MODULE_UART1),
|
||||
SLEEP_RETENTION_MODULE_BM_I2S0 = BIT(SLEEP_RETENTION_MODULE_I2S0),
|
||||
|
||||
SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0),
|
||||
SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1),
|
||||
@@ -94,6 +96,7 @@ typedef enum periph_retention_module_bitmap {
|
||||
| SLEEP_RETENTION_MODULE_BM_RMT0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_UART0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_UART1 \
|
||||
| SLEEP_RETENTION_MODULE_BM_I2S0 \
|
||||
)
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -288,6 +288,7 @@
|
||||
#define SOC_I2S_PDM_MAX_TX_LINES (2)
|
||||
#define SOC_I2S_SUPPORTS_TDM (1)
|
||||
#define SOC_I2S_TDM_FULL_DATA_WIDTH (1) /*!< No limitation to data bit width when using multiple slots */
|
||||
#define SOC_I2S_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up I2S registers before sleep */
|
||||
|
||||
/*-------------------------- LEDC CAPS ---------------------------------------*/
|
||||
#define SOC_LEDC_SUPPORT_PLL_DIV_CLOCK (1)
|
||||
|
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/i2s_periph.h"
|
||||
#include "soc/i2s_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
/*
|
||||
@@ -30,6 +31,48 @@ const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
|
||||
.data_in_sig = I2SI_SD_IN_IDX,
|
||||
|
||||
.irq = ETS_I2S1_INTR_SOURCE,
|
||||
.module = PERIPH_I2S1_MODULE,
|
||||
.retention_module = SLEEP_RETENTION_MODULE_I2S0,
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* I2S Registers to be saved during sleep retention
|
||||
* - I2S_RX_CONF_REG
|
||||
* - I2S_TX_CONF_REG
|
||||
* - I2S_RX_CONF1_REG
|
||||
* - I2S_TX_CONF1_REG
|
||||
* - I2S_TX_PCM2PDM_CONF_REG
|
||||
* - I2S_TX_PCM2PDM_CONF1_REG
|
||||
* - I2S_RX_TDM_CTRL_REG
|
||||
* - I2S_TX_TDM_CTRL_REG
|
||||
* - I2S_RXEOF_NUM_REG
|
||||
* - I2S_ETM_CONF_REG
|
||||
*/
|
||||
#define I2S_RETENTION_REGS_CNT 10
|
||||
#define I2S_RETENTION_REGS_BASE(i) I2S_RX_CONF_REG(i)
|
||||
static const uint32_t i2s_regs_map[4] = {0x12330f, 0x0, 0x0, 0x0};
|
||||
#define I2S_SLEEP_RETENTION_ENTRIES(i2s_port) { \
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT( \
|
||||
REGDMA_I2S_LINK(0x00), \
|
||||
I2S_RETENTION_REGS_BASE(i2s_port), \
|
||||
I2S_RETENTION_REGS_BASE(i2s_port), \
|
||||
I2S_RETENTION_REGS_CNT, 0, 0, \
|
||||
i2s_regs_map[0], i2s_regs_map[1], \
|
||||
i2s_regs_map[2], i2s_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2)}, \
|
||||
[1] = { .config = REGDMA_LINK_WRITE_INIT( \
|
||||
REGDMA_I2S_LINK(0x01), I2S_RX_CONF_REG(i2s_port), I2S_RX_UPDATE, I2S_RX_UPDATE_M, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2)}, \
|
||||
[2] = { .config = REGDMA_LINK_WRITE_INIT( \
|
||||
REGDMA_I2S_LINK(0x02), I2S_TX_CONF_REG(i2s_port), I2S_TX_UPDATE, I2S_TX_UPDATE_M, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2)} \
|
||||
};
|
||||
|
||||
static const regdma_entries_config_t i2s0_regs_retention[] = I2S_SLEEP_RETENTION_ENTRIES(0);
|
||||
|
||||
const i2s_reg_retention_info_t i2s_reg_retention_info[SOC_I2S_NUM] = {
|
||||
[0] = {
|
||||
.entry_array = i2s0_regs_retention,
|
||||
.array_size = ARRAY_SIZE(i2s0_regs_retention)
|
||||
},
|
||||
};
|
||||
|
@@ -671,6 +671,10 @@ config SOC_I2S_SUPPORTS_TDM
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
|
||||
bool
|
||||
default y
|
||||
|
@@ -36,6 +36,7 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_RMT0 = 13,
|
||||
SLEEP_RETENTION_MODULE_UART0 = 14,
|
||||
SLEEP_RETENTION_MODULE_UART1 = 15,
|
||||
SLEEP_RETENTION_MODULE_I2S0 = 16,
|
||||
|
||||
/* Modem module, which includes WiFi, BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_WIFI_MAC = 26,
|
||||
@@ -68,6 +69,7 @@ typedef enum periph_retention_module_bitmap {
|
||||
SLEEP_RETENTION_MODULE_BM_RMT0 = BIT(SLEEP_RETENTION_MODULE_RMT0),
|
||||
SLEEP_RETENTION_MODULE_BM_UART0 = BIT(SLEEP_RETENTION_MODULE_UART0),
|
||||
SLEEP_RETENTION_MODULE_BM_UART1 = BIT(SLEEP_RETENTION_MODULE_UART1),
|
||||
SLEEP_RETENTION_MODULE_BM_I2S0 = BIT(SLEEP_RETENTION_MODULE_I2S0),
|
||||
/* modem module, which includes WiFi, BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_BM_WIFI_MAC = BIT(SLEEP_RETENTION_MODULE_WIFI_MAC),
|
||||
SLEEP_RETENTION_MODULE_BM_WIFI_BB = BIT(SLEEP_RETENTION_MODULE_WIFI_BB),
|
||||
@@ -90,6 +92,7 @@ typedef enum periph_retention_module_bitmap {
|
||||
| SLEEP_RETENTION_MODULE_BM_RMT0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_UART0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_UART1 \
|
||||
| SLEEP_RETENTION_MODULE_BM_I2S0 \
|
||||
)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -273,6 +273,7 @@
|
||||
#define SOC_I2S_SUPPORTS_PDM_TX (1)
|
||||
#define SOC_I2S_PDM_MAX_TX_LINES (2)
|
||||
#define SOC_I2S_SUPPORTS_TDM (1)
|
||||
#define SOC_I2S_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up I2S registers before sleep */
|
||||
|
||||
/*-------------------------- LEDC CAPS ---------------------------------------*/
|
||||
#define SOC_LEDC_SUPPORT_PLL_DIV_CLOCK (1)
|
||||
|
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "soc/i2s_periph.h"
|
||||
#include "soc/i2s_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
||||
/*
|
||||
@@ -29,6 +30,48 @@ const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
|
||||
.data_in_sig = I2SI_SD_IN_IDX,
|
||||
|
||||
.irq = ETS_I2S1_INTR_SOURCE,
|
||||
.module = PERIPH_I2S1_MODULE,
|
||||
.retention_module = SLEEP_RETENTION_MODULE_I2S0,
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* I2S Registers to be saved during sleep retention
|
||||
* - I2S_RX_CONF_REG
|
||||
* - I2S_TX_CONF_REG
|
||||
* - I2S_RX_CONF1_REG
|
||||
* - I2S_TX_CONF1_REG
|
||||
* - I2S_TX_PCM2PDM_CONF_REG
|
||||
* - I2S_TX_PCM2PDM_CONF1_REG
|
||||
* - I2S_RX_TDM_CTRL_REG
|
||||
* - I2S_TX_TDM_CTRL_REG
|
||||
* - I2S_RXEOF_NUM_REG
|
||||
* - I2S_ETM_CONF_REG
|
||||
*/
|
||||
#define I2S_RETENTION_REGS_CNT 10
|
||||
#define I2S_RETENTION_REGS_BASE(i) I2S_RX_CONF_REG
|
||||
static const uint32_t i2s_regs_map[4] = {0x12330f, 0x0, 0x0, 0x0};
|
||||
#define I2S_SLEEP_RETENTION_ENTRIES(i2s_port) { \
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT( \
|
||||
REGDMA_I2S_LINK(0x00), \
|
||||
I2S_RETENTION_REGS_BASE(i2s_port), \
|
||||
I2S_RETENTION_REGS_BASE(i2s_port), \
|
||||
I2S_RETENTION_REGS_CNT, 0, 0, \
|
||||
i2s_regs_map[0], i2s_regs_map[1], \
|
||||
i2s_regs_map[2], i2s_regs_map[3]), \
|
||||
.owner = ENTRY(0) | ENTRY(2)}, \
|
||||
[1] = { .config = REGDMA_LINK_WRITE_INIT( \
|
||||
REGDMA_I2S_LINK(0x01), I2S_RX_CONF_REG(i2s_port), I2S_RX_UPDATE, I2S_RX_UPDATE_M, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2)}, \
|
||||
[2] = { .config = REGDMA_LINK_WRITE_INIT( \
|
||||
REGDMA_I2S_LINK(0x02), I2S_TX_CONF_REG(i2s_port), I2S_TX_UPDATE, I2S_TX_UPDATE_M, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2)} \
|
||||
};
|
||||
|
||||
static const regdma_entries_config_t i2s0_regs_retention[] = I2S_SLEEP_RETENTION_ENTRIES(0);
|
||||
|
||||
const i2s_reg_retention_info_t i2s_reg_retention_info[SOC_I2S_NUM] = {
|
||||
[0] = {
|
||||
.entry_array = i2s0_regs_retention,
|
||||
.array_size = ARRAY_SIZE(i2s0_regs_retention)
|
||||
},
|
||||
};
|
||||
|
@@ -675,6 +675,10 @@ config SOC_I2S_TDM_FULL_DATA_WIDTH
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LEDC_SUPPORT_PLL_DIV_CLOCK
|
||||
bool
|
||||
default y
|
||||
|
@@ -37,6 +37,7 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_RMT0 = 14,
|
||||
SLEEP_RETENTION_MODULE_UART0 = 15,
|
||||
SLEEP_RETENTION_MODULE_UART1 = 16,
|
||||
SLEEP_RETENTION_MODULE_I2S0 = 17,
|
||||
|
||||
/* Modem module, which includes BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_BLE_MAC = 28,
|
||||
@@ -68,6 +69,7 @@ typedef enum periph_retention_module_bitmap {
|
||||
SLEEP_RETENTION_MODULE_BM_RMT0 = BIT(SLEEP_RETENTION_MODULE_RMT0),
|
||||
SLEEP_RETENTION_MODULE_BM_UART0 = BIT(SLEEP_RETENTION_MODULE_UART0),
|
||||
SLEEP_RETENTION_MODULE_BM_UART1 = BIT(SLEEP_RETENTION_MODULE_UART1),
|
||||
SLEEP_RETENTION_MODULE_BM_I2S0 = BIT(SLEEP_RETENTION_MODULE_I2S0),
|
||||
/* modem module, which includes BLE and 802.15.4 */
|
||||
SLEEP_RETENTION_MODULE_BM_BLE_MAC = BIT(SLEEP_RETENTION_MODULE_BLE_MAC),
|
||||
SLEEP_RETENTION_MODULE_BM_BT_BB = BIT(SLEEP_RETENTION_MODULE_BT_BB),
|
||||
@@ -89,6 +91,7 @@ typedef enum periph_retention_module_bitmap {
|
||||
| SLEEP_RETENTION_MODULE_BM_RMT0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_UART0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_UART1 \
|
||||
| SLEEP_RETENTION_MODULE_BM_I2S0 \
|
||||
)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -274,6 +274,7 @@
|
||||
#define SOC_I2S_PDM_MAX_TX_LINES (2)
|
||||
#define SOC_I2S_SUPPORTS_TDM (1)
|
||||
#define SOC_I2S_TDM_FULL_DATA_WIDTH (1) /*!< No limitation to data bit width when using multiple slots */
|
||||
#define SOC_I2S_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up I2S registers before sleep */
|
||||
|
||||
/*-------------------------- LEDC CAPS ---------------------------------------*/
|
||||
#define SOC_LEDC_SUPPORT_PLL_DIV_CLOCK (1)
|
||||
|
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include "soc/i2s_periph.h"
|
||||
#include "soc/i2s_reg.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "soc/lp_gpio_sig_map.h"
|
||||
|
||||
@@ -34,7 +35,7 @@ const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
|
||||
.data_in_sigs[3] = I2S0_I_SD3_PAD_IN_IDX,
|
||||
|
||||
.irq = ETS_I2S0_INTR_SOURCE,
|
||||
.module = PERIPH_I2S0_MODULE,
|
||||
.retention_module = SLEEP_RETENTION_MODULE_I2S0,
|
||||
},
|
||||
[1] = {
|
||||
.mck_out_sig = I2S1_MCLK_PAD_OUT_IDX,
|
||||
@@ -58,7 +59,7 @@ const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
|
||||
.data_in_sigs[3] = -1,
|
||||
|
||||
.irq = ETS_I2S1_INTR_SOURCE,
|
||||
.module = PERIPH_I2S1_MODULE,
|
||||
.retention_module = SLEEP_RETENTION_MODULE_I2S1,
|
||||
},
|
||||
[2] = {
|
||||
.mck_out_sig = I2S2_MCLK_PAD_OUT_IDX,
|
||||
@@ -82,7 +83,7 @@ const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
|
||||
.data_in_sigs[3] = -1,
|
||||
|
||||
.irq = ETS_I2S2_INTR_SOURCE,
|
||||
.module = PERIPH_I2S2_MODULE,
|
||||
.retention_module = SLEEP_RETENTION_MODULE_I2S2,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -111,3 +112,56 @@ const i2s_signal_conn_t lp_i2s_periph_signal[SOC_LP_I2S_NUM] = {
|
||||
.irq = ETS_LP_I2S_INTR_SOURCE,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* I2S Registers to be saved during sleep retention
|
||||
* - I2S_RX_CONF_REG
|
||||
* - I2S_TX_CONF_REG
|
||||
* - I2S_RX_CONF1_REG
|
||||
* - I2S_TX_CONF1_REG
|
||||
* - I2S_TX_PCM2PDM_CONF_REG
|
||||
* - I2S_TX_PCM2PDM_CONF1_REG
|
||||
* - I2S_RX_PDM2PCM_CONF_REG
|
||||
* - I2S_RX_TDM_CTRL_REG
|
||||
* - I2S_TX_TDM_CTRL_REG
|
||||
* - I2S_RXEOF_NUM_REG
|
||||
* - I2S_ETM_CONF_REG
|
||||
*/
|
||||
#define I2S_RETENTION_REGS_CNT 11
|
||||
#define I2S_RETENTION_REGS_BASE(i) I2S_RX_CONF_REG(i)
|
||||
static const uint32_t i2s_regs_map[4] = {0x12370f, 0x0, 0x0, 0x0};
|
||||
#define I2S_SLEEP_RETENTION_ENTRIES(i2s_port) { \
|
||||
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT( \
|
||||
REGDMA_I2S_LINK(0x00), \
|
||||
I2S_RETENTION_REGS_BASE(i2s_port), \
|
||||
I2S_RETENTION_REGS_BASE(i2s_port), \
|
||||
I2S_RETENTION_REGS_CNT, 0, 0, \
|
||||
i2s_regs_map[0], i2s_regs_map[1], \
|
||||
i2s_regs_map[2], i2s_regs_map[3]), \
|
||||
.owner = ENTRY(0)}, \
|
||||
[1] = { .config = REGDMA_LINK_WRITE_INIT( \
|
||||
REGDMA_I2S_LINK(0x01), I2S_RX_CONF_REG(i2s_port), I2S_RX_UPDATE, I2S_RX_UPDATE_M, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2)}, \
|
||||
[2] = { .config = REGDMA_LINK_WRITE_INIT( \
|
||||
REGDMA_I2S_LINK(0x02), I2S_TX_CONF_REG(i2s_port), I2S_TX_UPDATE, I2S_TX_UPDATE_M, 1, 0), \
|
||||
.owner = ENTRY(0) | ENTRY(2)} \
|
||||
};
|
||||
|
||||
static const regdma_entries_config_t i2s0_regs_retention[] = I2S_SLEEP_RETENTION_ENTRIES(0);
|
||||
static const regdma_entries_config_t i2s1_regs_retention[] = I2S_SLEEP_RETENTION_ENTRIES(1);
|
||||
static const regdma_entries_config_t i2s2_regs_retention[] = I2S_SLEEP_RETENTION_ENTRIES(2);
|
||||
|
||||
const i2s_reg_retention_info_t i2s_reg_retention_info[SOC_I2S_NUM] = {
|
||||
[0] = {
|
||||
.entry_array = i2s0_regs_retention,
|
||||
.array_size = ARRAY_SIZE(i2s0_regs_retention)
|
||||
},
|
||||
[1] = {
|
||||
.entry_array = i2s1_regs_retention,
|
||||
.array_size = ARRAY_SIZE(i2s1_regs_retention)
|
||||
},
|
||||
[2] = {
|
||||
.entry_array = i2s2_regs_retention,
|
||||
.array_size = ARRAY_SIZE(i2s2_regs_retention)
|
||||
},
|
||||
};
|
||||
|
@@ -843,6 +843,10 @@ config SOC_I2S_TDM_FULL_DATA_WIDTH
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_I2S_SUPPORT_SLEEP_RETENTION
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_LP_I2S_NUM
|
||||
int
|
||||
default 1
|
||||
|
@@ -41,6 +41,10 @@ typedef enum periph_retention_module {
|
||||
SLEEP_RETENTION_MODULE_AXI_DMA_CH1 = 17,
|
||||
SLEEP_RETENTION_MODULE_AXI_DMA_CH2 = 18,
|
||||
|
||||
SLEEP_RETENTION_MODULE_I2S0 = 19,
|
||||
SLEEP_RETENTION_MODULE_I2S1 = 20,
|
||||
SLEEP_RETENTION_MODULE_I2S2 = 21,
|
||||
|
||||
SLEEP_RETENTION_MODULE_MAX = 31
|
||||
} periph_retention_module_t;
|
||||
|
||||
@@ -70,6 +74,9 @@ typedef enum periph_retention_module_bitmap {
|
||||
SLEEP_RETENTION_MODULE_BM_UART3 = BIT(SLEEP_RETENTION_MODULE_UART3),
|
||||
SLEEP_RETENTION_MODULE_BM_UART4 = BIT(SLEEP_RETENTION_MODULE_UART4),
|
||||
SLEEP_RETENTION_MODULE_BM_RMT0 = BIT(SLEEP_RETENTION_MODULE_RMT0),
|
||||
SLEEP_RETENTION_MODULE_BM_I2S0 = BIT(SLEEP_RETENTION_MODULE_I2S0),
|
||||
SLEEP_RETENTION_MODULE_BM_I2S1 = BIT(SLEEP_RETENTION_MODULE_I2S1),
|
||||
SLEEP_RETENTION_MODULE_BM_I2S2 = BIT(SLEEP_RETENTION_MODULE_I2S2),
|
||||
|
||||
SLEEP_RETENTION_MODULE_BM_ALL = (uint32_t)-1
|
||||
} periph_retention_module_bitmap_t;
|
||||
@@ -91,6 +98,9 @@ typedef enum periph_retention_module_bitmap {
|
||||
| SLEEP_RETENTION_MODULE_BM_UART3 \
|
||||
| SLEEP_RETENTION_MODULE_BM_UART4 \
|
||||
| SLEEP_RETENTION_MODULE_BM_RMT0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_I2S0 \
|
||||
| SLEEP_RETENTION_MODULE_BM_I2S1 \
|
||||
| SLEEP_RETENTION_MODULE_BM_I2S2 \
|
||||
)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -328,6 +328,7 @@
|
||||
#define SOC_I2S_PDM_MAX_TX_LINES (2) // On I2S0
|
||||
#define SOC_I2S_PDM_MAX_RX_LINES (4) // On I2S0
|
||||
#define SOC_I2S_TDM_FULL_DATA_WIDTH (1) /*!< No limitation to data bit width when using multiple slots */
|
||||
#define SOC_I2S_SUPPORT_SLEEP_RETENTION 1 /*!< The sleep retention feature can help back up I2S registers before sleep */
|
||||
|
||||
/*-------------------------- LP_I2S CAPS -------------------------------------*/
|
||||
#define SOC_LP_I2S_NUM (1U)
|
||||
|
@@ -29,6 +29,5 @@ const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
|
||||
.data_in_sig = I2S0I_DATA_IN15_IDX,
|
||||
|
||||
.irq = ETS_I2S0_INTR_SOURCE,
|
||||
.module = PERIPH_I2S0_MODULE,
|
||||
}
|
||||
};
|
||||
|
@@ -33,7 +33,6 @@ const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
|
||||
.data_in_sigs[3] = I2S0I_SD3_IN_IDX,
|
||||
|
||||
.irq = ETS_I2S0_INTR_SOURCE,
|
||||
.module = PERIPH_I2S0_MODULE,
|
||||
},
|
||||
{
|
||||
.mck_out_sig = I2S1_MCLK_OUT_IDX,
|
||||
@@ -57,6 +56,5 @@ const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM] = {
|
||||
.data_in_sigs[3] = -1,
|
||||
|
||||
.irq = ETS_I2S1_INTR_SOURCE,
|
||||
.module = PERIPH_I2S1_MODULE,
|
||||
}
|
||||
};
|
||||
|
@@ -1,13 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "soc/soc.h"
|
||||
#include "soc/periph_defs.h"
|
||||
#include "soc/retention_periph_defs.h"
|
||||
#include "soc/interrupts.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "soc/regdma.h"
|
||||
|
||||
#if SOC_I2S_SUPPORTED
|
||||
#include "soc/i2s_struct.h"
|
||||
@@ -51,7 +53,9 @@ typedef struct {
|
||||
};
|
||||
|
||||
const uint8_t irq;
|
||||
const periph_module_t module;
|
||||
#if SOC_I2S_SUPPORT_SLEEP_RETENTION
|
||||
const periph_retention_module_t retention_module;
|
||||
#endif
|
||||
} i2s_signal_conn_t;
|
||||
|
||||
extern const i2s_signal_conn_t i2s_periph_signal[SOC_I2S_NUM];
|
||||
@@ -62,6 +66,15 @@ extern const i2s_signal_conn_t lp_i2s_periph_signal[SOC_LP_I2S_NUM];
|
||||
|
||||
#endif // SOC_I2S_SUPPORTED
|
||||
|
||||
#if SOC_I2S_SUPPORT_SLEEP_RETENTION
|
||||
typedef struct {
|
||||
const regdma_entries_config_t *entry_array;
|
||||
uint32_t array_size;
|
||||
} i2s_reg_retention_info_t;
|
||||
|
||||
extern const i2s_reg_retention_info_t i2s_reg_retention_info[SOC_I2S_NUM];
|
||||
#endif // SOC_I2S_SUPPORT_SLEEP_RETENTION
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -53,6 +53,7 @@ extern "C" {
|
||||
#define REGDMA_TG1_WDT_LINK(_pri) ((0x1B << 8) | _pri)
|
||||
#define REGDMA_TG0_TIMER_LINK(_pri) ((0x1C << 8) | _pri)
|
||||
#define REGDMA_TG1_TIMER_LINK(_pri) ((0x1D << 8) | _pri)
|
||||
#define REGDMA_I2S_LINK(_pri) ((0x1E << 8) | _pri)
|
||||
#define REGDMA_MODEM_FE_LINK(_pri) ((0xFF << 8) | _pri)
|
||||
|
||||
#define REGDMA_LINK_PRI_SYS_CLK REGDMA_LINK_PRI_0
|
||||
@@ -69,6 +70,7 @@ extern "C" {
|
||||
#define REGDMA_LINK_PRI_RMT REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_GPTIMER REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_I2C REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_I2S REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
#define REGDMA_LINK_PRI_UART REGDMA_LINK_PRI_GENERAL_PERIPH
|
||||
|
||||
typedef enum {
|
||||
|
@@ -153,6 +153,7 @@ The following peripheral drivers are not aware of DFS yet. Applications need to
|
||||
- SYSTIMER
|
||||
:SOC_RMT_SUPPORT_SLEEP_RETENTION: - RMT
|
||||
:SOC_I2C_SUPPORT_SLEEP_RETENTION: - I2C
|
||||
:SOC_I2S_SUPPORT_SLEEP_RETENTION: - I2S
|
||||
:SOC_UART_SUPPORT_SLEEP_RETENTION: - All UARTs
|
||||
|
||||
The following peripherals are not yet supported:
|
||||
@@ -164,7 +165,6 @@ The following peripheral drivers are not aware of DFS yet. Applications need to
|
||||
- Trace
|
||||
- Crypto: AES/ECC/HMAC/RSA/SHA/DS/XTA_AES/ECDSA
|
||||
- SPI2
|
||||
- I2S
|
||||
- PCNT
|
||||
- USB-Serial-JTAG
|
||||
- TWAI
|
||||
|
@@ -152,7 +152,8 @@ ESP-IDF 中集成的电源管理算法可以根据应用程序组件的需求,
|
||||
- SPI0/1
|
||||
- SYSTIMER
|
||||
:SOC_RMT_SUPPORT_SLEEP_RETENTION: - RMT
|
||||
:SOC_I2C_SUPPORT_SLEEP_RETENTION:- I2C
|
||||
:SOC_I2C_SUPPORT_SLEEP_RETENTION: - I2C
|
||||
:SOC_I2S_SUPPORT_SLEEP_RETENTION: - I2S
|
||||
:SOC_UART_SUPPORT_SLEEP_RETENTION: - All UARTs
|
||||
|
||||
以下外设尚未支持:
|
||||
@@ -164,7 +165,6 @@ ESP-IDF 中集成的电源管理算法可以根据应用程序组件的需求,
|
||||
- Trace
|
||||
- Crypto: AES/ECC/HMAC/RSA/SHA/DS/XTA_AES/ECDSA
|
||||
- SPI2
|
||||
- I2S
|
||||
- PCNT
|
||||
- USB-Serial-JTAG
|
||||
- TWAI
|
||||
|
Reference in New Issue
Block a user