mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/i2s_support_etm' into 'master'
feat(i2s): support i2s etm event and task Closes IDF-10509 and IDF-6359 See merge request espressif/esp-idf!32013
This commit is contained in:
commit
ed91305d6a
@ -18,6 +18,9 @@ if(CONFIG_SOC_I2S_SUPPORTED)
|
|||||||
if(CONFIG_SOC_I2S_SUPPORTS_TDM)
|
if(CONFIG_SOC_I2S_SUPPORTS_TDM)
|
||||||
list(APPEND srcs "i2s_tdm.c")
|
list(APPEND srcs "i2s_tdm.c")
|
||||||
endif()
|
endif()
|
||||||
|
if(CONFIG_SOC_I2S_SUPPORTS_ETM)
|
||||||
|
list(APPEND srcs "i2s_etm.c")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
|
81
components/esp_driver_i2s/i2s_etm.c
Normal file
81
components/esp_driver_i2s/i2s_etm.c
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
// #define LOG_LOCAL_LEVEL ESP_LOG_DEBUG
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_check.h"
|
||||||
|
#include "esp_heap_caps.h"
|
||||||
|
#include "driver/i2s_etm.h"
|
||||||
|
#include "i2s_private.h"
|
||||||
|
#include "hal/i2s_ll.h"
|
||||||
|
#include "esp_private/etm_interface.h"
|
||||||
|
|
||||||
|
#define ETM_MEM_ALLOC_CAPS MALLOC_CAP_DEFAULT
|
||||||
|
|
||||||
|
static const char *TAG = "i2s-etm";
|
||||||
|
|
||||||
|
static esp_err_t i2s_del_etm_event(esp_etm_event_t *event)
|
||||||
|
{
|
||||||
|
free(event);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t i2s_del_etm_task(esp_etm_task_t *task)
|
||||||
|
{
|
||||||
|
free(task);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t i2s_new_etm_event(i2s_chan_handle_t handle, const i2s_etm_event_config_t *config, esp_etm_event_handle_t *out_event)
|
||||||
|
{
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
ESP_RETURN_ON_FALSE(handle && config && out_event, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||||
|
ESP_RETURN_ON_FALSE(config->event_type < I2S_ETM_EVENT_MAX, ESP_ERR_INVALID_ARG, TAG, "invalid event type");
|
||||||
|
esp_etm_event_t *event = heap_caps_calloc(1, sizeof(esp_etm_event_t), ETM_MEM_ALLOC_CAPS);
|
||||||
|
ESP_RETURN_ON_FALSE(event, ESP_ERR_NO_MEM, TAG, "no memory for ETM event");
|
||||||
|
|
||||||
|
uint32_t event_id = I2S_LL_ETM_EVENT_TABLE(handle->controller->id, handle->dir, config->event_type);
|
||||||
|
if (config->event_type == I2S_ETM_EVENT_REACH_THRESH) {
|
||||||
|
ESP_GOTO_ON_FALSE(config->threshold <= I2S_LL_ETM_MAX_THRESH_NUM, ESP_ERR_INVALID_ARG, err, TAG,
|
||||||
|
"exceed the max threshold %"PRIu32, (uint32_t)I2S_LL_ETM_MAX_THRESH_NUM);
|
||||||
|
if (handle->dir == I2S_DIR_TX) {
|
||||||
|
i2s_ll_tx_set_etm_threshold(handle->controller->hal.dev, config->threshold);
|
||||||
|
} else {
|
||||||
|
i2s_ll_rx_set_etm_threshold(handle->controller->hal.dev, config->threshold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fill the ETM event object
|
||||||
|
event->event_id = event_id;
|
||||||
|
event->trig_periph = ETM_TRIG_PERIPH_I2S;
|
||||||
|
event->del = i2s_del_etm_event;
|
||||||
|
*out_event = event;
|
||||||
|
return ret;
|
||||||
|
err:
|
||||||
|
free(event);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_err_t i2s_new_etm_task(i2s_chan_handle_t handle, const i2s_etm_task_config_t *config, esp_etm_task_handle_t *out_task)
|
||||||
|
{
|
||||||
|
ESP_RETURN_ON_FALSE(handle && config && out_task, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||||
|
ESP_RETURN_ON_FALSE(config->task_type < I2S_ETM_TASK_MAX, ESP_ERR_INVALID_ARG, TAG, "invalid task type");
|
||||||
|
esp_etm_task_t *task = heap_caps_calloc(1, sizeof(esp_etm_task_t), ETM_MEM_ALLOC_CAPS);
|
||||||
|
ESP_RETURN_ON_FALSE(task, ESP_ERR_NO_MEM, TAG, "no memory for ETM task");
|
||||||
|
|
||||||
|
uint32_t task_id = I2S_LL_ETM_TASK_TABLE(handle->controller->id, handle->dir, config->task_type);
|
||||||
|
|
||||||
|
// fill the ETM task object
|
||||||
|
task->task_id = task_id;
|
||||||
|
task->trig_periph = ETM_TRIG_PERIPH_I2S;
|
||||||
|
task->del = i2s_del_etm_task;
|
||||||
|
*out_task = task;
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
72
components/esp_driver_i2s/include/driver/i2s_etm.h
Normal file
72
components/esp_driver_i2s/include/driver/i2s_etm.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "driver/i2s_types.h"
|
||||||
|
#include "hal/i2s_types.h"
|
||||||
|
|
||||||
|
#include "esp_etm.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SOC_I2S_SUPPORTS_ETM
|
||||||
|
/**
|
||||||
|
* @brief I2S ETM event configuration
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
i2s_etm_event_type_t event_type; /*!< I2S ETM event type */
|
||||||
|
uint32_t threshold; /*!< The threshold word number that triggers `I2S_ETM_EVENT_REACH_THRESH` event,
|
||||||
|
only take effect when the event type is `I2S_ETM_EVENT_REACH_THRESH`
|
||||||
|
Unit is in word (4 bytes) */
|
||||||
|
} i2s_etm_event_config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Register the ETM event for I2S channel
|
||||||
|
*
|
||||||
|
* @note The created ETM event object can be deleted later by calling `esp_etm_del_event`
|
||||||
|
*
|
||||||
|
* @param[in] handle I2S channel handle, allocated by `i2s_new_channel`
|
||||||
|
* @param[in] config I2S ETM event configuration
|
||||||
|
* @param[out] out_event Returned ETM event handle
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: Get ETM event successfully
|
||||||
|
* - ESP_ERR_INVALID_ARG: Get ETM event failed because of invalid argument
|
||||||
|
* - ESP_ERR_NOT_SUPPORTED: Get ETM event failed because the I2S hardware doesn't support ETM event
|
||||||
|
* - ESP_FAIL: Get ETM event failed because of other error
|
||||||
|
*/
|
||||||
|
esp_err_t i2s_new_etm_event(i2s_chan_handle_t handle, const i2s_etm_event_config_t *config, esp_etm_event_handle_t *out_event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2S ETM task configuration
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
i2s_etm_task_type_t task_type; /*!< I2S ETM task type */
|
||||||
|
} i2s_etm_task_config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Register the ETM task for I2S channel
|
||||||
|
*
|
||||||
|
* @note The created ETM task object can be deleted later by calling `esp_etm_del_task`
|
||||||
|
*
|
||||||
|
* @param[in] handle I2S channel handle, allocated by `i2s_new_channel`
|
||||||
|
* @param[in] config I2S ETM task configuration
|
||||||
|
* @param[out] out_task Returned ETM task handle
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: Get ETM task successfully
|
||||||
|
* - ESP_ERR_INVALID_ARG: Get ETM task failed because of invalid argument
|
||||||
|
* - ESP_ERR_NOT_SUPPORTED: Get ETM task failed because the i2s hardware doesn't support ETM task
|
||||||
|
* - ESP_FAIL: Get ETM task failed because of other error
|
||||||
|
*/
|
||||||
|
esp_err_t i2s_new_etm_task(i2s_chan_handle_t handle, const i2s_etm_task_config_t *config, esp_etm_task_handle_t *out_task);
|
||||||
|
|
||||||
|
#endif // SOC_I2S_SUPPORTS_ETM
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@ -2,6 +2,10 @@ set(srcs "test_app_main.c"
|
|||||||
"test_i2s.c"
|
"test_i2s.c"
|
||||||
"test_i2s_iram.c")
|
"test_i2s_iram.c")
|
||||||
|
|
||||||
|
if(CONFIG_SOC_I2S_SUPPORTS_ETM AND CONFIG_SOC_GPIO_SUPPORT_ETM)
|
||||||
|
set(srcs ${srcs} "test_i2s_etm.c")
|
||||||
|
endif()
|
||||||
|
|
||||||
idf_component_register(SRCS ${srcs}
|
idf_component_register(SRCS ${srcs}
|
||||||
PRIV_REQUIRES unity esp_driver_pcnt driver spi_flash
|
PRIV_REQUIRES unity esp_driver_pcnt driver spi_flash esp_driver_gpio
|
||||||
WHOLE_ARCHIVE)
|
WHOLE_ARCHIVE)
|
||||||
|
@ -41,32 +41,6 @@
|
|||||||
#define I2S_TEST_MODE_MASTER_TO_SLAVE 1
|
#define I2S_TEST_MODE_MASTER_TO_SLAVE 1
|
||||||
#define I2S_TEST_MODE_LOOPBACK 2
|
#define I2S_TEST_MODE_LOOPBACK 2
|
||||||
|
|
||||||
#define I2S_TEST_MASTER_DEFAULT_PIN { \
|
|
||||||
.mclk = MASTER_MCK_IO, \
|
|
||||||
.bclk = MASTER_BCK_IO, \
|
|
||||||
.ws = MASTER_WS_IO, \
|
|
||||||
.dout = DATA_OUT_IO, \
|
|
||||||
.din = DATA_IN_IO, \
|
|
||||||
.invert_flags = { \
|
|
||||||
.mclk_inv = false, \
|
|
||||||
.bclk_inv = false, \
|
|
||||||
.ws_inv = false, \
|
|
||||||
}, \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define I2S_TEST_SLAVE_DEFAULT_PIN { \
|
|
||||||
.mclk = -1, \
|
|
||||||
.bclk = SLAVE_BCK_IO, \
|
|
||||||
.ws = SLAVE_WS_IO, \
|
|
||||||
.dout = DATA_OUT_IO, \
|
|
||||||
.din = DATA_IN_IO, \
|
|
||||||
.invert_flags = { \
|
|
||||||
.mclk_inv = false, \
|
|
||||||
.bclk_inv = false, \
|
|
||||||
.ws_inv = false, \
|
|
||||||
}, \
|
|
||||||
}
|
|
||||||
|
|
||||||
// mode: 0, master rx, slave tx. mode: 1, master tx, slave rx. mode: 2, master tx rx loop-back
|
// mode: 0, master rx, slave tx. mode: 1, master tx, slave rx. mode: 2, master tx rx loop-back
|
||||||
// Since ESP32-S2 has only one I2S, only loop back test can be tested.
|
// Since ESP32-S2 has only one I2S, only loop back test can be tested.
|
||||||
static void i2s_test_io_config(int mode)
|
static void i2s_test_io_config(int mode)
|
||||||
|
215
components/esp_driver_i2s/test_apps/i2s/main/test_i2s_etm.c
Normal file
215
components/esp_driver_i2s/test_apps/i2s/main/test_i2s_etm.c
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "unity.h"
|
||||||
|
#include "unity_test_utils.h"
|
||||||
|
#include "esp_attr.h"
|
||||||
|
#include "driver/gpio_etm.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "driver/i2s_std.h"
|
||||||
|
#include "driver/i2s_etm.h"
|
||||||
|
#include "hal/i2s_ll.h"
|
||||||
|
#include "hal/etm_ll.h"
|
||||||
|
#include "../../test_inc/test_i2s.h"
|
||||||
|
|
||||||
|
#include "soc/soc_etm_struct.h"
|
||||||
|
|
||||||
|
#define TEST_DESC_NUM 4
|
||||||
|
#define TEST_FRAME_NUM 256
|
||||||
|
#define TEST_BUFF_SIZE (TEST_DESC_NUM * TEST_FRAME_NUM)
|
||||||
|
|
||||||
|
#define TEST_GPIO_ETM_NUM DATA_IN_IO
|
||||||
|
|
||||||
|
static i2s_chan_handle_t s_tx_handle = NULL;
|
||||||
|
static i2s_chan_handle_t s_rx_handle = NULL;
|
||||||
|
|
||||||
|
#if ETM_LL_SUPPORT_STATUS
|
||||||
|
static void s_i2s_etm_check_status(void)
|
||||||
|
{
|
||||||
|
i2s_dev_t *hw = I2S_LL_GET_HW(0);
|
||||||
|
bool is_tx_done = i2s_ll_get_etm_tx_done_event_status(hw);
|
||||||
|
bool is_rx_done = i2s_ll_get_etm_rx_done_event_status(hw);
|
||||||
|
bool is_tx_reach_thresh = i2s_ll_get_etm_tx_threshold_event_status(hw);
|
||||||
|
bool is_rx_reach_thresh = i2s_ll_get_etm_rx_threshold_event_status(hw);
|
||||||
|
printf("tx done st %d, rx done st %d, tx x st %d, rx x st %d\n",
|
||||||
|
is_tx_done, is_rx_done, is_tx_reach_thresh, is_rx_reach_thresh);
|
||||||
|
// TODO: IDF-10512 enable the TX_DONE and RX_DONE check after refactor. Currently not support
|
||||||
|
// TEST_ASSERT(is_tx_done);
|
||||||
|
// TEST_ASSERT(is_rx_done);
|
||||||
|
TEST_ASSERT(is_tx_reach_thresh);
|
||||||
|
TEST_ASSERT(is_rx_reach_thresh);
|
||||||
|
}
|
||||||
|
#endif // ETM_LL_SUPPORT_STATUS
|
||||||
|
|
||||||
|
static void s_i2s_init(uint8_t *buf)
|
||||||
|
{
|
||||||
|
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
|
||||||
|
chan_cfg.dma_desc_num = TEST_DESC_NUM;
|
||||||
|
chan_cfg.dma_frame_num = TEST_FRAME_NUM;
|
||||||
|
i2s_std_config_t std_cfg = {
|
||||||
|
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000),
|
||||||
|
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(32, I2S_SLOT_MODE_STEREO),
|
||||||
|
.gpio_cfg = I2S_TEST_MASTER_DEFAULT_PIN,
|
||||||
|
};
|
||||||
|
std_cfg.gpio_cfg.mclk = -1; // no need mclk
|
||||||
|
std_cfg.gpio_cfg.din = DATA_OUT_IO; // data loopback
|
||||||
|
|
||||||
|
/* I2S channels init */
|
||||||
|
TEST_ESP_OK(i2s_new_channel(&chan_cfg, &s_tx_handle, &s_rx_handle));
|
||||||
|
TEST_ESP_OK(i2s_channel_init_std_mode(s_tx_handle, &std_cfg));
|
||||||
|
TEST_ESP_OK(i2s_channel_init_std_mode(s_rx_handle, &std_cfg));
|
||||||
|
// TODO: IDF-10512 rx_stop_mode is necessary for rx_done event, enable it when supported
|
||||||
|
// I2S0.rx_conf.rx_stop_mode = 1;
|
||||||
|
|
||||||
|
size_t w_bytes = TEST_BUFF_SIZE;
|
||||||
|
while (w_bytes == TEST_BUFF_SIZE) {
|
||||||
|
TEST_ESP_OK(i2s_channel_preload_data(s_tx_handle, buf, TEST_BUFF_SIZE, &w_bytes));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void s_i2s_deinit(void)
|
||||||
|
{
|
||||||
|
TEST_ESP_OK(i2s_del_channel(s_rx_handle));
|
||||||
|
TEST_ESP_OK(i2s_del_channel(s_tx_handle));
|
||||||
|
s_tx_handle = NULL;
|
||||||
|
s_rx_handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void s_gpio_init(void)
|
||||||
|
{
|
||||||
|
gpio_config_t gpio_cfg = {
|
||||||
|
.mode = GPIO_MODE_INPUT_OUTPUT,
|
||||||
|
.pin_bit_mask = (1ULL << TEST_GPIO_ETM_NUM),
|
||||||
|
};
|
||||||
|
TEST_ESP_OK(gpio_config(&gpio_cfg));
|
||||||
|
TEST_ESP_OK(gpio_set_level(TEST_GPIO_ETM_NUM, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("i2s_etm_event_test", "[etm]")
|
||||||
|
{
|
||||||
|
uint8_t *buf = calloc(1, TEST_BUFF_SIZE);
|
||||||
|
assert(buf);
|
||||||
|
memset(buf, 0x3C, TEST_BUFF_SIZE);
|
||||||
|
|
||||||
|
/* I2S init */
|
||||||
|
s_i2s_init(buf);
|
||||||
|
|
||||||
|
/* GPIO init */
|
||||||
|
s_gpio_init();
|
||||||
|
|
||||||
|
/* GPIO ETM task */
|
||||||
|
gpio_etm_task_config_t gpio_task_cfg = {
|
||||||
|
.action = GPIO_ETM_TASK_ACTION_SET,
|
||||||
|
};
|
||||||
|
esp_etm_task_handle_t gpio_task_handle;
|
||||||
|
TEST_ESP_OK(gpio_new_etm_task(&gpio_task_cfg, &gpio_task_handle));
|
||||||
|
TEST_ESP_OK(gpio_etm_task_add_gpio(gpio_task_handle, TEST_GPIO_ETM_NUM));
|
||||||
|
|
||||||
|
/* I2S Event init */
|
||||||
|
i2s_etm_event_config_t i2s_evt_cfg = {
|
||||||
|
.event_type = I2S_ETM_EVENT_REACH_THRESH,
|
||||||
|
.threshold = 64,
|
||||||
|
};
|
||||||
|
esp_etm_event_handle_t i2s_evt_handle;
|
||||||
|
TEST_ESP_OK(i2s_new_etm_event(s_rx_handle, &i2s_evt_cfg, &i2s_evt_handle));
|
||||||
|
|
||||||
|
/* ETM connect */
|
||||||
|
esp_etm_channel_config_t etm_config = {};
|
||||||
|
esp_etm_channel_handle_t etm_channel = NULL;
|
||||||
|
TEST_ESP_OK(esp_etm_new_channel(&etm_config, &etm_channel));
|
||||||
|
TEST_ESP_OK(esp_etm_channel_connect(etm_channel, i2s_evt_handle, gpio_task_handle));
|
||||||
|
TEST_ESP_OK(esp_etm_channel_enable(etm_channel));
|
||||||
|
esp_etm_dump(stdout);
|
||||||
|
|
||||||
|
TEST_ESP_OK(i2s_channel_enable(s_tx_handle));
|
||||||
|
TEST_ESP_OK(i2s_channel_enable(s_rx_handle));
|
||||||
|
|
||||||
|
TEST_ESP_OK(i2s_channel_read(s_rx_handle, buf, TEST_BUFF_SIZE, NULL, portMAX_DELAY));
|
||||||
|
|
||||||
|
#if ETM_LL_SUPPORT_STATUS
|
||||||
|
s_i2s_etm_check_status();
|
||||||
|
#else
|
||||||
|
TEST_ASSERT(gpio_get_level(TEST_GPIO_ETM_NUM));
|
||||||
|
#endif // ETM_LL_SUPPORT_STATUS
|
||||||
|
|
||||||
|
/* Test finished, free the resources */
|
||||||
|
TEST_ESP_OK(i2s_channel_disable(s_rx_handle));
|
||||||
|
TEST_ESP_OK(i2s_channel_disable(s_tx_handle));
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
TEST_ESP_OK(esp_etm_channel_disable(etm_channel));
|
||||||
|
TEST_ESP_OK(esp_etm_del_event(i2s_evt_handle));
|
||||||
|
TEST_ESP_OK(gpio_etm_task_rm_gpio(gpio_task_handle, TEST_GPIO_ETM_NUM));
|
||||||
|
TEST_ESP_OK(esp_etm_del_task(gpio_task_handle));
|
||||||
|
TEST_ESP_OK(esp_etm_del_channel(etm_channel));
|
||||||
|
|
||||||
|
s_i2s_deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("i2s_etm_task_test", "[etm]")
|
||||||
|
{
|
||||||
|
uint8_t *buf = calloc(1, TEST_BUFF_SIZE);
|
||||||
|
assert(buf);
|
||||||
|
memset(buf, 0x3C, TEST_BUFF_SIZE);
|
||||||
|
|
||||||
|
/* I2S init */
|
||||||
|
s_i2s_init(buf);
|
||||||
|
|
||||||
|
/* GPIO init */
|
||||||
|
s_gpio_init();
|
||||||
|
|
||||||
|
/* GPIO ETM event */
|
||||||
|
gpio_etm_event_config_t gpio_event_cfg = {
|
||||||
|
.edge = GPIO_ETM_EVENT_EDGE_POS,
|
||||||
|
};
|
||||||
|
esp_etm_event_handle_t gpio_event_handle;
|
||||||
|
TEST_ESP_OK(gpio_new_etm_event(&gpio_event_cfg, &gpio_event_handle));
|
||||||
|
TEST_ESP_OK(gpio_etm_event_bind_gpio(gpio_event_handle, TEST_GPIO_ETM_NUM));
|
||||||
|
|
||||||
|
/* I2S Task init */
|
||||||
|
i2s_etm_task_config_t i2s_task_cfg = {
|
||||||
|
.task_type = I2S_ETM_TASK_STOP,
|
||||||
|
};
|
||||||
|
esp_etm_task_handle_t i2s_task_handle;
|
||||||
|
TEST_ESP_OK(i2s_new_etm_task(s_tx_handle, &i2s_task_cfg, &i2s_task_handle));
|
||||||
|
|
||||||
|
/* ETM connect */
|
||||||
|
esp_etm_channel_config_t etm_config = {};
|
||||||
|
esp_etm_channel_handle_t etm_channel = NULL;
|
||||||
|
TEST_ESP_OK(esp_etm_new_channel(&etm_config, &etm_channel));
|
||||||
|
TEST_ESP_OK(esp_etm_channel_connect(etm_channel, gpio_event_handle, i2s_task_handle));
|
||||||
|
TEST_ESP_OK(esp_etm_channel_enable(etm_channel));
|
||||||
|
esp_etm_dump(stdout);
|
||||||
|
|
||||||
|
TEST_ESP_OK(i2s_channel_enable(s_tx_handle));
|
||||||
|
TEST_ESP_OK(i2s_channel_enable(s_rx_handle));
|
||||||
|
|
||||||
|
/* Test */
|
||||||
|
// receive normally
|
||||||
|
i2s_channel_read(s_rx_handle, buf, TEST_BUFF_SIZE, NULL, portMAX_DELAY);
|
||||||
|
// Set the GPIO to stop the I2S TX via ETM
|
||||||
|
TEST_ESP_OK(gpio_set_level(TEST_GPIO_ETM_NUM, 1));
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
// Receive will timeout after TX stopped
|
||||||
|
for (int i = 0; i < 20 && ret == ESP_OK; i++) {
|
||||||
|
ret = i2s_channel_read(s_rx_handle, buf, TEST_BUFF_SIZE, NULL, 1000);
|
||||||
|
}
|
||||||
|
TEST_ESP_ERR(ESP_ERR_TIMEOUT, ret);
|
||||||
|
|
||||||
|
/* Test finished, free the resources */
|
||||||
|
TEST_ESP_OK(i2s_channel_disable(s_rx_handle));
|
||||||
|
TEST_ESP_OK(i2s_channel_disable(s_tx_handle));
|
||||||
|
free(buf);
|
||||||
|
|
||||||
|
TEST_ESP_OK(esp_etm_channel_disable(etm_channel));
|
||||||
|
TEST_ESP_OK(esp_etm_del_event(gpio_event_handle));
|
||||||
|
TEST_ESP_OK(esp_etm_del_task(i2s_task_handle));
|
||||||
|
TEST_ESP_OK(esp_etm_del_channel(etm_channel));
|
||||||
|
|
||||||
|
s_i2s_deinit();
|
||||||
|
}
|
@ -72,6 +72,32 @@ extern "C" {
|
|||||||
#define DATA_OUT_IO 7
|
#define DATA_OUT_IO 7
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define I2S_TEST_MASTER_DEFAULT_PIN { \
|
||||||
|
.mclk = MASTER_MCK_IO, \
|
||||||
|
.bclk = MASTER_BCK_IO, \
|
||||||
|
.ws = MASTER_WS_IO, \
|
||||||
|
.dout = DATA_OUT_IO, \
|
||||||
|
.din = DATA_IN_IO, \
|
||||||
|
.invert_flags = { \
|
||||||
|
.mclk_inv = false, \
|
||||||
|
.bclk_inv = false, \
|
||||||
|
.ws_inv = false, \
|
||||||
|
}, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define I2S_TEST_SLAVE_DEFAULT_PIN { \
|
||||||
|
.mclk = -1, \
|
||||||
|
.bclk = SLAVE_BCK_IO, \
|
||||||
|
.ws = SLAVE_WS_IO, \
|
||||||
|
.dout = DATA_OUT_IO, \
|
||||||
|
.din = DATA_IN_IO, \
|
||||||
|
.invert_flags = { \
|
||||||
|
.mclk_inv = false, \
|
||||||
|
.bclk_inv = false, \
|
||||||
|
.ws_inv = false, \
|
||||||
|
}, \
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,6 +27,7 @@ typedef enum {
|
|||||||
ETM_TRIG_PERIPH_MCPWM, /*!< ETM trigger source: MCPWM */
|
ETM_TRIG_PERIPH_MCPWM, /*!< ETM trigger source: MCPWM */
|
||||||
ETM_TRIG_PERIPH_ANA_CMPR, /*!< ETM trigger source: Analog Comparator */
|
ETM_TRIG_PERIPH_ANA_CMPR, /*!< ETM trigger source: Analog Comparator */
|
||||||
ETM_TRIG_PERIPH_TSENS, /*!< ETM trigger source: Temperature Sensor */
|
ETM_TRIG_PERIPH_TSENS, /*!< ETM trigger source: Temperature Sensor */
|
||||||
|
ETM_TRIG_PERIPH_I2S, /*!< ETM trigger source: I2S */
|
||||||
ETM_TRIG_PERIPH_LP_CORE, /*!< ETM trigger source: Low-Power Core */
|
ETM_TRIG_PERIPH_LP_CORE, /*!< ETM trigger source: Low-Power Core */
|
||||||
} etm_trigger_peripheral_t;
|
} etm_trigger_peripheral_t;
|
||||||
|
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ETM_LL_SUPPORT_STATUS 1 // Support to get and clear the status of the ETM event and task
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable the clock for ETM register
|
* @brief Enable the clock for ETM register
|
||||||
*
|
*
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#include "soc/i2s_periph.h"
|
#include "soc/i2s_periph.h"
|
||||||
#include "soc/i2s_struct.h"
|
#include "soc/i2s_struct.h"
|
||||||
#include "soc/pcr_struct.h"
|
#include "soc/pcr_struct.h"
|
||||||
|
#include "soc/soc_etm_struct.h"
|
||||||
|
#include "soc/soc_etm_source.h"
|
||||||
#include "hal/i2s_types.h"
|
#include "hal/i2s_types.h"
|
||||||
#include "hal/hal_utils.h"
|
#include "hal/hal_utils.h"
|
||||||
|
|
||||||
@ -28,6 +30,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define I2S_LL_GET_HW(num) (((num) == 0)? (&I2S0) : NULL)
|
#define I2S_LL_GET_HW(num) (((num) == 0)? (&I2S0) : NULL)
|
||||||
|
#define I2S_LL_GET_ID(hw) (((hw) == &I2S0)? 0 : -1)
|
||||||
|
|
||||||
#define I2S_LL_TDM_CH_MASK (0xffff)
|
#define I2S_LL_TDM_CH_MASK (0xffff)
|
||||||
#define I2S_LL_PDM_BCK_FACTOR (64)
|
#define I2S_LL_PDM_BCK_FACTOR (64)
|
||||||
@ -38,6 +41,30 @@ extern "C" {
|
|||||||
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
|
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
|
||||||
#define I2S_LL_DEFAULT_CLK_FREQ I2S_LL_PLL_F160M_CLK_FREQ // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT
|
#define I2S_LL_DEFAULT_CLK_FREQ I2S_LL_PLL_F160M_CLK_FREQ // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT
|
||||||
|
|
||||||
|
#define I2S_LL_ETM_EVENT_TABLE(i2s_port, chan_dir, event) \
|
||||||
|
(uint32_t[SOC_I2S_NUM][2][I2S_ETM_EVENT_MAX]){{ \
|
||||||
|
[I2S_DIR_RX - 1] = { \
|
||||||
|
[I2S_ETM_EVENT_DONE] = I2S0_EVT_RX_DONE, \
|
||||||
|
[I2S_ETM_EVENT_REACH_THRESH] = I2S0_EVT_X_WORDS_RECEIVED, \
|
||||||
|
}, \
|
||||||
|
[I2S_DIR_TX - 1] = { \
|
||||||
|
[I2S_ETM_EVENT_DONE] = I2S0_EVT_TX_DONE, \
|
||||||
|
[I2S_ETM_EVENT_REACH_THRESH] = I2S0_EVT_X_WORDS_SENT, \
|
||||||
|
}}}[i2s_port][(chan_dir) - 1][event]
|
||||||
|
|
||||||
|
|
||||||
|
#define I2S_LL_ETM_TASK_TABLE(i2s_port, chan_dir, task) \
|
||||||
|
(uint32_t[SOC_I2S_NUM][2][I2S_ETM_TASK_MAX]){{ \
|
||||||
|
[I2S_DIR_RX - 1] = { \
|
||||||
|
[I2S_ETM_TASK_START] = I2S0_TASK_START_RX, \
|
||||||
|
[I2S_ETM_TASK_STOP] = I2S0_TASK_STOP_RX, \
|
||||||
|
}, \
|
||||||
|
[I2S_DIR_TX - 1] = { \
|
||||||
|
[I2S_ETM_TASK_START] = I2S0_TASK_START_TX, \
|
||||||
|
[I2S_ETM_TASK_STOP] = I2S0_TASK_STOP_TX, \
|
||||||
|
}}}[i2s_port][(chan_dir) - 1][task]
|
||||||
|
#define I2S_LL_ETM_MAX_THRESH_NUM (0x3FFFUL)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable the bus clock for I2S module
|
* @brief Enable the bus clock for I2S module
|
||||||
*
|
*
|
||||||
@ -1191,6 +1218,104 @@ static inline uint32_t i2s_ll_tx_get_bclk_sync_count(i2s_dev_t *hw)
|
|||||||
return hw->bck_cnt.tx_bck_cnt;
|
return hw->bck_cnt.tx_bck_cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the TX ETM threshold of REACH_THRESH event
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @param thresh The threshold that send, in words (4 bytes)
|
||||||
|
*/
|
||||||
|
static inline void i2s_ll_tx_set_etm_threshold(i2s_dev_t *hw, uint32_t thresh)
|
||||||
|
{
|
||||||
|
hw->etm_conf.etm_tx_send_word_num = thresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the RX ETM threshold of REACH_THRESH event
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @param thresh The threshold that received, in words (4 bytes)
|
||||||
|
*/
|
||||||
|
static inline void i2s_ll_rx_set_etm_threshold(i2s_dev_t *hw, uint32_t thresh)
|
||||||
|
{
|
||||||
|
hw->etm_conf.etm_rx_receive_word_num = thresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get I2S ETM TX done event status
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @return
|
||||||
|
* - true TX done event triggered
|
||||||
|
* - false TX done event not triggered
|
||||||
|
*/
|
||||||
|
static inline bool i2s_ll_get_etm_tx_done_event_status(i2s_dev_t *hw)
|
||||||
|
{
|
||||||
|
uint32_t i2s_id = I2S_LL_GET_ID(hw);
|
||||||
|
switch (i2s_id) {
|
||||||
|
case 0:
|
||||||
|
return SOC_ETM.evt_st3.i2s0_evt_tx_done_st;
|
||||||
|
default:
|
||||||
|
HAL_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get I2S ETM TX done event status
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @return
|
||||||
|
* - true TX done event triggered
|
||||||
|
* - false TX done event not triggered
|
||||||
|
*/
|
||||||
|
static inline bool i2s_ll_get_etm_rx_done_event_status(i2s_dev_t *hw)
|
||||||
|
{
|
||||||
|
uint32_t i2s_id = I2S_LL_GET_ID(hw);
|
||||||
|
switch (i2s_id) {
|
||||||
|
case 0:
|
||||||
|
return SOC_ETM.evt_st3.i2s0_evt_rx_done_st;
|
||||||
|
default:
|
||||||
|
HAL_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get I2S ETM TX done event status
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @return
|
||||||
|
* - true TX done event triggered
|
||||||
|
* - false TX done event not triggered
|
||||||
|
*/
|
||||||
|
static inline bool i2s_ll_get_etm_tx_threshold_event_status(i2s_dev_t *hw)
|
||||||
|
{
|
||||||
|
uint32_t i2s_id = I2S_LL_GET_ID(hw);
|
||||||
|
switch (i2s_id) {
|
||||||
|
case 0:
|
||||||
|
return SOC_ETM.evt_st3.i2s0_evt_x_words_sent_st;
|
||||||
|
default:
|
||||||
|
HAL_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get I2S ETM TX done event status
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @return
|
||||||
|
* - true TX done event triggered
|
||||||
|
* - false TX done event not triggered
|
||||||
|
*/
|
||||||
|
static inline bool i2s_ll_get_etm_rx_threshold_event_status(i2s_dev_t *hw)
|
||||||
|
{
|
||||||
|
uint32_t i2s_id = I2S_LL_GET_ID(hw);
|
||||||
|
switch (i2s_id) {
|
||||||
|
case 0:
|
||||||
|
return SOC_ETM.evt_st3.i2s0_evt_x_words_received_st;
|
||||||
|
default:
|
||||||
|
HAL_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -18,6 +18,7 @@
|
|||||||
#include "soc/i2s_periph.h"
|
#include "soc/i2s_periph.h"
|
||||||
#include "soc/i2s_struct.h"
|
#include "soc/i2s_struct.h"
|
||||||
#include "soc/pcr_struct.h"
|
#include "soc/pcr_struct.h"
|
||||||
|
#include "soc/soc_etm_source.h"
|
||||||
#include "hal/i2s_types.h"
|
#include "hal/i2s_types.h"
|
||||||
#include "hal/hal_utils.h"
|
#include "hal/hal_utils.h"
|
||||||
|
|
||||||
@ -37,6 +38,30 @@ extern "C" {
|
|||||||
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
|
#define I2S_LL_PLL_F160M_CLK_FREQ (160 * 1000000) // PLL_F160M_CLK: 160MHz
|
||||||
#define I2S_LL_DEFAULT_CLK_FREQ I2S_LL_PLL_F160M_CLK_FREQ // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT
|
#define I2S_LL_DEFAULT_CLK_FREQ I2S_LL_PLL_F160M_CLK_FREQ // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT
|
||||||
|
|
||||||
|
#define I2S_LL_ETM_EVENT_TABLE(i2s_port, chan_dir, event) \
|
||||||
|
(uint32_t[SOC_I2S_NUM][2][I2S_ETM_EVENT_MAX]){{ \
|
||||||
|
[I2S_DIR_RX - 1] = { \
|
||||||
|
[I2S_ETM_EVENT_DONE] = I2S_EVT_RX_DONE, \
|
||||||
|
[I2S_ETM_EVENT_REACH_THRESH] = I2S_EVT_X_WORDS_RECEIVED, \
|
||||||
|
}, \
|
||||||
|
[I2S_DIR_TX - 1] = { \
|
||||||
|
[I2S_ETM_EVENT_DONE] = I2S_EVT_TX_DONE, \
|
||||||
|
[I2S_ETM_EVENT_REACH_THRESH] = I2S_EVT_X_WORDS_SENT, \
|
||||||
|
}}}[i2s_port][(chan_dir) - 1][event]
|
||||||
|
|
||||||
|
|
||||||
|
#define I2S_LL_ETM_TASK_TABLE(i2s_port, chan_dir, task) \
|
||||||
|
(uint32_t[SOC_I2S_NUM][2][I2S_ETM_TASK_MAX]){{ \
|
||||||
|
[I2S_DIR_RX - 1] = { \
|
||||||
|
[I2S_ETM_TASK_START] = I2S_TASK_START_RX, \
|
||||||
|
[I2S_ETM_TASK_STOP] = I2S_TASK_STOP_RX, \
|
||||||
|
}, \
|
||||||
|
[I2S_DIR_TX - 1] = { \
|
||||||
|
[I2S_ETM_TASK_START] = I2S_TASK_START_TX, \
|
||||||
|
[I2S_ETM_TASK_STOP] = I2S_TASK_STOP_TX, \
|
||||||
|
}}}[i2s_port][(chan_dir) - 1][task]
|
||||||
|
#define I2S_LL_ETM_MAX_THRESH_NUM (0x3FFUL)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param i2s_id The port id of I2S
|
* @param i2s_id The port id of I2S
|
||||||
@ -460,7 +485,7 @@ static inline void i2s_ll_rx_set_eof_num(i2s_dev_t *hw, int eof_num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Congfigure TX chan bit and audio data bit
|
* @brief Configure TX chan bit and audio data bit
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @param chan_bit The chan bit width
|
* @param chan_bit The chan bit width
|
||||||
@ -473,7 +498,7 @@ static inline void i2s_ll_tx_set_sample_bit(i2s_dev_t *hw, uint8_t chan_bit, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Congfigure RX chan bit and audio data bit
|
* @brief Configure RX chan bit and audio data bit
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @param chan_bit The chan bit width
|
* @param chan_bit The chan bit width
|
||||||
@ -873,11 +898,11 @@ static inline void i2s_ll_tx_set_pdm_fpfs(i2s_dev_t *hw, uint32_t fp, uint32_t f
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get I2S TX PDM fp configuration paramater
|
* @brief Get I2S TX PDM fp configuration parameter
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @return
|
* @return
|
||||||
* - fp configuration paramater
|
* - fp configuration parameter
|
||||||
*/
|
*/
|
||||||
static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
|
static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
@ -885,11 +910,11 @@ static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get I2S TX PDM fs configuration paramater
|
* @brief Get I2S TX PDM fs configuration parameter
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @return
|
* @return
|
||||||
* - fs configuration paramater
|
* - fs configuration parameter
|
||||||
*/
|
*/
|
||||||
static inline uint32_t i2s_ll_tx_get_pdm_fs(i2s_dev_t *hw)
|
static inline uint32_t i2s_ll_tx_get_pdm_fs(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
@ -915,7 +940,7 @@ static inline void i2s_ll_rx_enable_pdm(i2s_dev_t *hw, bool pdm_enable)
|
|||||||
* @brief Configura TX a/u-law decompress or compress
|
* @brief Configura TX a/u-law decompress or compress
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @param pcm_cfg PCM configuration paramater
|
* @param pcm_cfg PCM configuration parameter
|
||||||
*/
|
*/
|
||||||
static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
||||||
{
|
{
|
||||||
@ -927,7 +952,7 @@ static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_
|
|||||||
* @brief Configure RX a/u-law decompress or compress
|
* @brief Configure RX a/u-law decompress or compress
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @param pcm_cfg PCM configuration paramater
|
* @param pcm_cfg PCM configuration parameter
|
||||||
*/
|
*/
|
||||||
static inline void i2s_ll_rx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
static inline void i2s_ll_rx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
||||||
{
|
{
|
||||||
@ -1099,7 +1124,7 @@ static inline void i2s_ll_tx_pdm_dma_take_mode(i2s_dev_t *hw, bool is_mono, bool
|
|||||||
* @param is_mono The DMA data only has one slot (mono) or contains two slots (stereo)
|
* @param is_mono The DMA data only has one slot (mono) or contains two slots (stereo)
|
||||||
* @param is_copy Whether the un-selected slot copies the data from the selected one
|
* @param is_copy Whether the un-selected slot copies the data from the selected one
|
||||||
* If not, the un-selected slot will transmit the data from 'conf_single_data'
|
* If not, the un-selected slot will transmit the data from 'conf_single_data'
|
||||||
* @param mask The slot mask to selet the slot
|
* @param mask The slot mask to select the slot
|
||||||
*/
|
*/
|
||||||
static inline void i2s_ll_tx_pdm_slot_mode(i2s_dev_t *hw, bool is_mono, bool is_copy, i2s_pdm_slot_mask_t mask)
|
static inline void i2s_ll_tx_pdm_slot_mode(i2s_dev_t *hw, bool is_mono, bool is_copy, i2s_pdm_slot_mask_t mask)
|
||||||
{
|
{
|
||||||
@ -1132,6 +1157,28 @@ static inline void i2s_ll_tx_pdm_line_mode(i2s_dev_t *hw, i2s_pdm_tx_line_mode_t
|
|||||||
hw->tx_pcm2pdm_conf.tx_pdm_dac_2out_en = line_mode != I2S_PDM_TX_ONE_LINE_DAC;
|
hw->tx_pcm2pdm_conf.tx_pdm_dac_2out_en = line_mode != I2S_PDM_TX_ONE_LINE_DAC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the TX ETM threshold of REACH_THRESH event
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @param thresh The threshold that send
|
||||||
|
*/
|
||||||
|
static inline void i2s_ll_tx_set_etm_threshold(i2s_dev_t *hw, uint32_t thresh)
|
||||||
|
{
|
||||||
|
hw->etm_conf.etm_tx_send_word_num = thresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the RX ETM threshold of REACH_THRESH event
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @param thresh The threshold that received
|
||||||
|
*/
|
||||||
|
static inline void i2s_ll_rx_set_etm_threshold(i2s_dev_t *hw, uint32_t thresh)
|
||||||
|
{
|
||||||
|
hw->etm_conf.etm_rx_receive_word_num = thresh;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -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
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -18,6 +18,7 @@
|
|||||||
#include "soc/i2s_periph.h"
|
#include "soc/i2s_periph.h"
|
||||||
#include "soc/i2s_struct.h"
|
#include "soc/i2s_struct.h"
|
||||||
#include "soc/pcr_struct.h"
|
#include "soc/pcr_struct.h"
|
||||||
|
#include "soc/soc_etm_source.h"
|
||||||
#include "hal/i2s_types.h"
|
#include "hal/i2s_types.h"
|
||||||
#include "hal/hal_utils.h"
|
#include "hal/hal_utils.h"
|
||||||
|
|
||||||
@ -38,6 +39,30 @@ extern "C" {
|
|||||||
#define I2S_LL_PLL_F64M_CLK_FREQ (64 * 1000000) // PLL_F64M_CLK: 64MHz
|
#define I2S_LL_PLL_F64M_CLK_FREQ (64 * 1000000) // PLL_F64M_CLK: 64MHz
|
||||||
#define I2S_LL_DEFAULT_CLK_FREQ I2S_LL_PLL_F96M_CLK_FREQ // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT
|
#define I2S_LL_DEFAULT_CLK_FREQ I2S_LL_PLL_F96M_CLK_FREQ // The default PLL clock frequency while using I2S_CLK_SRC_DEFAULT
|
||||||
|
|
||||||
|
#define I2S_LL_ETM_EVENT_TABLE(i2s_port, chan_dir, event) \
|
||||||
|
(uint32_t[SOC_I2S_NUM][2][I2S_ETM_EVENT_MAX]){{ \
|
||||||
|
[I2S_DIR_RX - 1] = { \
|
||||||
|
[I2S_ETM_EVENT_DONE] = I2S_EVT_RX_DONE, \
|
||||||
|
[I2S_ETM_EVENT_REACH_THRESH] = I2S_EVT_X_WORDS_RECEIVED, \
|
||||||
|
}, \
|
||||||
|
[I2S_DIR_TX - 1] = { \
|
||||||
|
[I2S_ETM_EVENT_DONE] = I2S_EVT_TX_DONE, \
|
||||||
|
[I2S_ETM_EVENT_REACH_THRESH] = I2S_EVT_X_WORDS_SENT, \
|
||||||
|
}}}[i2s_port][(chan_dir) - 1][event]
|
||||||
|
|
||||||
|
|
||||||
|
#define I2S_LL_ETM_TASK_TABLE(i2s_port, chan_dir, task) \
|
||||||
|
(uint32_t[SOC_I2S_NUM][2][I2S_ETM_TASK_MAX]){{ \
|
||||||
|
[I2S_DIR_RX - 1] = { \
|
||||||
|
[I2S_ETM_TASK_START] = I2S_TASK_START_RX, \
|
||||||
|
[I2S_ETM_TASK_STOP] = I2S_TASK_STOP_RX, \
|
||||||
|
}, \
|
||||||
|
[I2S_DIR_TX - 1] = { \
|
||||||
|
[I2S_ETM_TASK_START] = I2S_TASK_START_TX, \
|
||||||
|
[I2S_ETM_TASK_STOP] = I2S_TASK_STOP_TX, \
|
||||||
|
}}}[i2s_port][(chan_dir) - 1][task]
|
||||||
|
#define I2S_LL_ETM_MAX_THRESH_NUM (0x3FFUL)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param i2s_id The port id of I2S
|
* @param i2s_id The port id of I2S
|
||||||
@ -467,7 +492,7 @@ static inline void i2s_ll_rx_set_eof_num(i2s_dev_t *hw, int eof_num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Congfigure TX chan bit and audio data bit
|
* @brief Configure TX chan bit and audio data bit
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @param chan_bit The chan bit width
|
* @param chan_bit The chan bit width
|
||||||
@ -480,7 +505,7 @@ static inline void i2s_ll_tx_set_sample_bit(i2s_dev_t *hw, uint8_t chan_bit, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Congfigure RX chan bit and audio data bit
|
* @brief Configure RX chan bit and audio data bit
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @param chan_bit The chan bit width
|
* @param chan_bit The chan bit width
|
||||||
@ -880,11 +905,11 @@ static inline void i2s_ll_tx_set_pdm_fpfs(i2s_dev_t *hw, uint32_t fp, uint32_t f
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get I2S TX PDM fp configuration paramater
|
* @brief Get I2S TX PDM fp configuration parameter
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @return
|
* @return
|
||||||
* - fp configuration paramater
|
* - fp configuration parameter
|
||||||
*/
|
*/
|
||||||
static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
|
static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
@ -892,11 +917,11 @@ static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get I2S TX PDM fs configuration paramater
|
* @brief Get I2S TX PDM fs configuration parameter
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @return
|
* @return
|
||||||
* - fs configuration paramater
|
* - fs configuration parameter
|
||||||
*/
|
*/
|
||||||
static inline uint32_t i2s_ll_tx_get_pdm_fs(i2s_dev_t *hw)
|
static inline uint32_t i2s_ll_tx_get_pdm_fs(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
@ -922,7 +947,7 @@ static inline void i2s_ll_rx_enable_pdm(i2s_dev_t *hw, bool pdm_enable)
|
|||||||
* @brief Configura TX a/u-law decompress or compress
|
* @brief Configura TX a/u-law decompress or compress
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @param pcm_cfg PCM configuration paramater
|
* @param pcm_cfg PCM configuration parameter
|
||||||
*/
|
*/
|
||||||
static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
||||||
{
|
{
|
||||||
@ -934,7 +959,7 @@ static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_
|
|||||||
* @brief Configure RX a/u-law decompress or compress
|
* @brief Configure RX a/u-law decompress or compress
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @param pcm_cfg PCM configuration paramater
|
* @param pcm_cfg PCM configuration parameter
|
||||||
*/
|
*/
|
||||||
static inline void i2s_ll_rx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
static inline void i2s_ll_rx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
||||||
{
|
{
|
||||||
@ -1106,7 +1131,7 @@ static inline void i2s_ll_tx_pdm_dma_take_mode(i2s_dev_t *hw, bool is_mono, bool
|
|||||||
* @param is_mono The DMA data only has one slot (mono) or contains two slots (stereo)
|
* @param is_mono The DMA data only has one slot (mono) or contains two slots (stereo)
|
||||||
* @param is_copy Whether the un-selected slot copies the data from the selected one
|
* @param is_copy Whether the un-selected slot copies the data from the selected one
|
||||||
* If not, the un-selected slot will transmit the data from 'conf_single_data'
|
* If not, the un-selected slot will transmit the data from 'conf_single_data'
|
||||||
* @param mask The slot mask to selet the slot
|
* @param mask The slot mask to select the slot
|
||||||
*/
|
*/
|
||||||
static inline void i2s_ll_tx_pdm_slot_mode(i2s_dev_t *hw, bool is_mono, bool is_copy, i2s_pdm_slot_mask_t mask)
|
static inline void i2s_ll_tx_pdm_slot_mode(i2s_dev_t *hw, bool is_mono, bool is_copy, i2s_pdm_slot_mask_t mask)
|
||||||
{
|
{
|
||||||
@ -1139,6 +1164,28 @@ static inline void i2s_ll_tx_pdm_line_mode(i2s_dev_t *hw, i2s_pdm_tx_line_mode_t
|
|||||||
hw->tx_pcm2pdm_conf.tx_pdm_dac_2out_en = line_mode != I2S_PDM_TX_ONE_LINE_DAC;
|
hw->tx_pcm2pdm_conf.tx_pdm_dac_2out_en = line_mode != I2S_PDM_TX_ONE_LINE_DAC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the TX ETM threshold of REACH_THRESH event
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @param thresh The threshold that send
|
||||||
|
*/
|
||||||
|
static inline void i2s_ll_tx_set_etm_threshold(i2s_dev_t *hw, uint32_t thresh)
|
||||||
|
{
|
||||||
|
hw->etm_conf.etm_tx_send_word_num = thresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the RX ETM threshold of REACH_THRESH event
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @param thresh The threshold that received
|
||||||
|
*/
|
||||||
|
static inline void i2s_ll_rx_set_etm_threshold(i2s_dev_t *hw, uint32_t thresh)
|
||||||
|
{
|
||||||
|
hw->etm_conf.etm_rx_receive_word_num = thresh;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define ETM_LL_SUPPORT_STATUS 1 // Support to get and clear the status of the ETM event and task
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable the bus clock for ETM module
|
* @brief Enable the bus clock for ETM module
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -17,7 +17,9 @@
|
|||||||
#include "hal/assert.h"
|
#include "hal/assert.h"
|
||||||
#include "soc/i2s_periph.h"
|
#include "soc/i2s_periph.h"
|
||||||
#include "soc/i2s_struct.h"
|
#include "soc/i2s_struct.h"
|
||||||
|
#include "soc/soc_etm_struct.h"
|
||||||
#include "soc/hp_sys_clkrst_struct.h"
|
#include "soc/hp_sys_clkrst_struct.h"
|
||||||
|
#include "soc/soc_etm_source.h"
|
||||||
#include "hal/i2s_types.h"
|
#include "hal/i2s_types.h"
|
||||||
#include "hal/hal_utils.h"
|
#include "hal/hal_utils.h"
|
||||||
|
|
||||||
@ -38,6 +40,77 @@ extern "C" {
|
|||||||
#define I2S_LL_XTAL_CLK_FREQ (40 * 1000000) // XTAL_CLK: 40MHz
|
#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
|
#define I2S_LL_DEFAULT_CLK_FREQ I2S_LL_XTAL_CLK_FREQ // No PLL clock source on P4, use XTAL as default
|
||||||
|
|
||||||
|
#define I2S_LL_ETM_EVENT_TABLE(i2s_port, chan_dir, event) \
|
||||||
|
(uint32_t[SOC_I2S_NUM][2][I2S_ETM_EVENT_MAX]){ \
|
||||||
|
[0] = { \
|
||||||
|
[I2S_DIR_RX - 1] = { \
|
||||||
|
[I2S_ETM_EVENT_DONE] = I2S0_EVT_RX_DONE, \
|
||||||
|
[I2S_ETM_EVENT_REACH_THRESH] = I2S0_EVT_X_WORDS_RECEIVED, \
|
||||||
|
}, \
|
||||||
|
[I2S_DIR_TX - 1] = { \
|
||||||
|
[I2S_ETM_EVENT_DONE] = I2S0_EVT_TX_DONE, \
|
||||||
|
[I2S_ETM_EVENT_REACH_THRESH] = I2S0_EVT_X_WORDS_SENT, \
|
||||||
|
}, \
|
||||||
|
}, \
|
||||||
|
[1] = { \
|
||||||
|
[I2S_DIR_RX - 1] = { \
|
||||||
|
[I2S_ETM_EVENT_DONE] = I2S1_EVT_RX_DONE, \
|
||||||
|
[I2S_ETM_EVENT_REACH_THRESH] = I2S1_EVT_X_WORDS_RECEIVED, \
|
||||||
|
}, \
|
||||||
|
[I2S_DIR_TX - 1] = { \
|
||||||
|
[I2S_ETM_EVENT_DONE] = I2S1_EVT_TX_DONE, \
|
||||||
|
[I2S_ETM_EVENT_REACH_THRESH] = I2S1_EVT_X_WORDS_SENT, \
|
||||||
|
}, \
|
||||||
|
}, \
|
||||||
|
[2] = { \
|
||||||
|
[I2S_DIR_RX - 1] = { \
|
||||||
|
[I2S_ETM_EVENT_DONE] = I2S2_EVT_RX_DONE, \
|
||||||
|
[I2S_ETM_EVENT_REACH_THRESH] = I2S2_EVT_X_WORDS_RECEIVED, \
|
||||||
|
}, \
|
||||||
|
[I2S_DIR_TX - 1] = { \
|
||||||
|
[I2S_ETM_EVENT_DONE] = I2S2_EVT_TX_DONE, \
|
||||||
|
[I2S_ETM_EVENT_REACH_THRESH] = I2S2_EVT_X_WORDS_SENT, \
|
||||||
|
}, \
|
||||||
|
}, \
|
||||||
|
}[i2s_port][(chan_dir) - 1][event]
|
||||||
|
|
||||||
|
|
||||||
|
#define I2S_LL_ETM_TASK_TABLE(i2s_port, chan_dir, task) \
|
||||||
|
(uint32_t[SOC_I2S_NUM][2][I2S_ETM_TASK_MAX]){ \
|
||||||
|
[0] = { \
|
||||||
|
[I2S_DIR_RX - 1] = { \
|
||||||
|
[I2S_ETM_TASK_START] = I2S0_TASK_START_RX, \
|
||||||
|
[I2S_ETM_TASK_STOP] = I2S0_TASK_STOP_RX, \
|
||||||
|
}, \
|
||||||
|
[I2S_DIR_TX - 1] = { \
|
||||||
|
[I2S_ETM_TASK_START] = I2S0_TASK_START_TX, \
|
||||||
|
[I2S_ETM_TASK_STOP] = I2S0_TASK_STOP_TX, \
|
||||||
|
}, \
|
||||||
|
}, \
|
||||||
|
[1] = { \
|
||||||
|
[I2S_DIR_RX - 1] = { \
|
||||||
|
[I2S_ETM_TASK_START] = I2S1_TASK_START_RX, \
|
||||||
|
[I2S_ETM_TASK_STOP] = I2S1_TASK_STOP_RX, \
|
||||||
|
}, \
|
||||||
|
[I2S_DIR_TX - 1] = { \
|
||||||
|
[I2S_ETM_TASK_START] = I2S1_TASK_START_TX, \
|
||||||
|
[I2S_ETM_TASK_STOP] = I2S1_TASK_STOP_TX, \
|
||||||
|
}, \
|
||||||
|
}, \
|
||||||
|
[2] = { \
|
||||||
|
[I2S_DIR_RX - 1] = { \
|
||||||
|
[I2S_ETM_TASK_START] = I2S2_TASK_START_RX, \
|
||||||
|
[I2S_ETM_TASK_STOP] = I2S2_TASK_STOP_RX, \
|
||||||
|
}, \
|
||||||
|
[I2S_DIR_TX - 1] = { \
|
||||||
|
[I2S_ETM_TASK_START] = I2S2_TASK_START_TX, \
|
||||||
|
[I2S_ETM_TASK_STOP] = I2S2_TASK_STOP_TX, \
|
||||||
|
}, \
|
||||||
|
}, \
|
||||||
|
}[i2s_port][(chan_dir) - 1][task]
|
||||||
|
|
||||||
|
#define I2S_LL_ETM_MAX_THRESH_NUM (0x3FFFUL)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable the bus clock for I2S module
|
* @brief Enable the bus clock for I2S module
|
||||||
*
|
*
|
||||||
@ -638,7 +711,7 @@ static inline void i2s_ll_rx_set_eof_num(i2s_dev_t *hw, int eof_num)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Congfigure TX chan bit and audio data bit
|
* @brief Configure TX chan bit and audio data bit
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @param chan_bit The chan bit width
|
* @param chan_bit The chan bit width
|
||||||
@ -651,7 +724,7 @@ static inline void i2s_ll_tx_set_sample_bit(i2s_dev_t *hw, uint8_t chan_bit, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Congfigure RX chan bit and audio data bit
|
* @brief Configure RX chan bit and audio data bit
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @param chan_bit The chan bit width
|
* @param chan_bit The chan bit width
|
||||||
@ -1052,11 +1125,11 @@ static inline void i2s_ll_tx_set_pdm_fpfs(i2s_dev_t *hw, uint32_t fp, uint32_t f
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get I2S TX PDM fp configuration paramater
|
* @brief Get I2S TX PDM fp configuration parameter
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @return
|
* @return
|
||||||
* - fp configuration paramater
|
* - fp configuration parameter
|
||||||
*/
|
*/
|
||||||
static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
|
static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
@ -1064,11 +1137,11 @@ static inline uint32_t i2s_ll_tx_get_pdm_fp(i2s_dev_t *hw)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get I2S TX PDM fs configuration paramater
|
* @brief Get I2S TX PDM fs configuration parameter
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @return
|
* @return
|
||||||
* - fs configuration paramater
|
* - fs configuration parameter
|
||||||
*/
|
*/
|
||||||
static inline uint32_t i2s_ll_tx_get_pdm_fs(i2s_dev_t *hw)
|
static inline uint32_t i2s_ll_tx_get_pdm_fs(i2s_dev_t *hw)
|
||||||
{
|
{
|
||||||
@ -1091,7 +1164,7 @@ static inline void i2s_ll_rx_enable_pdm(i2s_dev_t *hw)
|
|||||||
* @brief Configure RX PDM downsample
|
* @brief Configure RX PDM downsample
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @param dsr PDM downsample configuration paramater
|
* @param dsr PDM downsample configuration parameter
|
||||||
*/
|
*/
|
||||||
static inline void i2s_ll_rx_set_pdm_dsr(i2s_dev_t *hw, i2s_pdm_dsr_t dsr)
|
static inline void i2s_ll_rx_set_pdm_dsr(i2s_dev_t *hw, i2s_pdm_dsr_t dsr)
|
||||||
{
|
{
|
||||||
@ -1164,7 +1237,7 @@ static inline void i2s_ll_rx_enable_pdm_hp_filter(i2s_dev_t *hw, bool enable)
|
|||||||
* @brief Configura TX a/u-law decompress or compress
|
* @brief Configura TX a/u-law decompress or compress
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @param pcm_cfg PCM configuration paramater
|
* @param pcm_cfg PCM configuration parameter
|
||||||
*/
|
*/
|
||||||
static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
||||||
{
|
{
|
||||||
@ -1176,7 +1249,7 @@ static inline void i2s_ll_tx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_
|
|||||||
* @brief Configure RX a/u-law decompress or compress
|
* @brief Configure RX a/u-law decompress or compress
|
||||||
*
|
*
|
||||||
* @param hw Peripheral I2S hardware instance address.
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
* @param pcm_cfg PCM configuration paramater
|
* @param pcm_cfg PCM configuration parameter
|
||||||
*/
|
*/
|
||||||
static inline void i2s_ll_rx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
static inline void i2s_ll_rx_set_pcm_type(i2s_dev_t *hw, i2s_pcm_compress_t pcm_cfg)
|
||||||
{
|
{
|
||||||
@ -1348,7 +1421,7 @@ static inline void i2s_ll_tx_pdm_dma_take_mode(i2s_dev_t *hw, bool is_mono, bool
|
|||||||
* @param is_mono The DMA data only has one slot (mono) or contains two slots (stereo)
|
* @param is_mono The DMA data only has one slot (mono) or contains two slots (stereo)
|
||||||
* @param is_copy Whether the un-selected slot copies the data from the selected one
|
* @param is_copy Whether the un-selected slot copies the data from the selected one
|
||||||
* If not, the un-selected slot will transmit the data from 'conf_single_data'
|
* If not, the un-selected slot will transmit the data from 'conf_single_data'
|
||||||
* @param mask The slot mask to selet the slot
|
* @param mask The slot mask to select the slot
|
||||||
*/
|
*/
|
||||||
static inline void i2s_ll_tx_pdm_slot_mode(i2s_dev_t *hw, bool is_mono, bool is_copy, i2s_pdm_slot_mask_t mask)
|
static inline void i2s_ll_tx_pdm_slot_mode(i2s_dev_t *hw, bool is_mono, bool is_copy, i2s_pdm_slot_mask_t mask)
|
||||||
{
|
{
|
||||||
@ -1431,6 +1504,120 @@ static inline uint32_t i2s_ll_tx_get_bclk_sync_count(i2s_dev_t *hw)
|
|||||||
return hw->bck_cnt.tx_bck_cnt;
|
return hw->bck_cnt.tx_bck_cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the TX ETM threshold of REACH_THRESH event
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @param thresh The threshold that send
|
||||||
|
*/
|
||||||
|
static inline void i2s_ll_tx_set_etm_threshold(i2s_dev_t *hw, uint32_t thresh)
|
||||||
|
{
|
||||||
|
hw->etm_conf.etm_tx_send_word_num = thresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set the RX ETM threshold of REACH_THRESH event
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @param thresh The threshold that received
|
||||||
|
*/
|
||||||
|
static inline void i2s_ll_rx_set_etm_threshold(i2s_dev_t *hw, uint32_t thresh)
|
||||||
|
{
|
||||||
|
hw->etm_conf.etm_rx_receive_word_num = thresh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get I2S ETM TX done event status
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @return
|
||||||
|
* - true TX done event triggered
|
||||||
|
* - false TX done event not triggered
|
||||||
|
*/
|
||||||
|
static inline bool i2s_ll_get_etm_tx_done_event_status(i2s_dev_t *hw)
|
||||||
|
{
|
||||||
|
uint32_t i2s_id = I2S_LL_GET_ID(hw);
|
||||||
|
switch (i2s_id) {
|
||||||
|
case 0:
|
||||||
|
return SOC_ETM.evt_st4.i2s0_evt_tx_done_st;
|
||||||
|
case 1:
|
||||||
|
return SOC_ETM.evt_st4.i2s1_evt_tx_done_st;
|
||||||
|
case 2:
|
||||||
|
return SOC_ETM.evt_st4.i2s2_evt_tx_done_st;
|
||||||
|
default:
|
||||||
|
HAL_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get I2S ETM TX done event status
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @return
|
||||||
|
* - true TX done event triggered
|
||||||
|
* - false TX done event not triggered
|
||||||
|
*/
|
||||||
|
static inline bool i2s_ll_get_etm_rx_done_event_status(i2s_dev_t *hw)
|
||||||
|
{
|
||||||
|
uint32_t i2s_id = I2S_LL_GET_ID(hw);
|
||||||
|
switch (i2s_id) {
|
||||||
|
case 0:
|
||||||
|
return SOC_ETM.evt_st4.i2s0_evt_rx_done_st;
|
||||||
|
case 1:
|
||||||
|
return SOC_ETM.evt_st4.i2s1_evt_rx_done_st;
|
||||||
|
case 2:
|
||||||
|
return SOC_ETM.evt_st4.i2s2_evt_rx_done_st;
|
||||||
|
default:
|
||||||
|
HAL_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get I2S ETM TX done event status
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @return
|
||||||
|
* - true TX done event triggered
|
||||||
|
* - false TX done event not triggered
|
||||||
|
*/
|
||||||
|
static inline bool i2s_ll_get_etm_tx_threshold_event_status(i2s_dev_t *hw)
|
||||||
|
{
|
||||||
|
uint32_t i2s_id = I2S_LL_GET_ID(hw);
|
||||||
|
switch (i2s_id) {
|
||||||
|
case 0:
|
||||||
|
return SOC_ETM.evt_st4.i2s0_evt_x_words_sent_st;
|
||||||
|
case 1:
|
||||||
|
return SOC_ETM.evt_st4.i2s1_evt_x_words_sent_st;
|
||||||
|
case 2:
|
||||||
|
return SOC_ETM.evt_st4.i2s2_evt_x_words_sent_st;
|
||||||
|
default:
|
||||||
|
HAL_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get I2S ETM TX done event status
|
||||||
|
*
|
||||||
|
* @param hw Peripheral I2S hardware instance address.
|
||||||
|
* @return
|
||||||
|
* - true TX done event triggered
|
||||||
|
* - false TX done event not triggered
|
||||||
|
*/
|
||||||
|
static inline bool i2s_ll_get_etm_rx_threshold_event_status(i2s_dev_t *hw)
|
||||||
|
{
|
||||||
|
uint32_t i2s_id = I2S_LL_GET_ID(hw);
|
||||||
|
switch (i2s_id) {
|
||||||
|
case 0:
|
||||||
|
return SOC_ETM.evt_st4.i2s0_evt_x_words_received_st;
|
||||||
|
case 1:
|
||||||
|
return SOC_ETM.evt_st4.i2s1_evt_x_words_received_st;
|
||||||
|
case 2:
|
||||||
|
return SOC_ETM.evt_st4.i2s2_evt_x_words_received_st;
|
||||||
|
default:
|
||||||
|
HAL_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -98,7 +98,7 @@ typedef enum {
|
|||||||
|
|
||||||
#if SOC_I2S_SUPPORTS_PDM_TX
|
#if SOC_I2S_SUPPORTS_PDM_TX
|
||||||
/**
|
/**
|
||||||
* @brief pdm tx singnal scaling mode
|
* @brief pdm tx signal scaling mode
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
I2S_PDM_SIG_SCALING_DIV_2 = 0, /*!< I2S TX PDM signal scaling: /2 */
|
I2S_PDM_SIG_SCALING_DIV_2 = 0, /*!< I2S TX PDM signal scaling: /2 */
|
||||||
@ -124,7 +124,7 @@ typedef enum {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief I2S slot select in standard mode
|
* @brief I2S slot select in standard mode
|
||||||
* @note It has different meanings in tx/rx/mono/stereo mode, and it may have differen behaviors on different targets
|
* @note It has different meanings in tx/rx/mono/stereo mode, and it may have different behaviors on different targets
|
||||||
* For the details, please refer to the I2S API reference
|
* For the details, please refer to the I2S API reference
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -184,6 +184,34 @@ typedef enum {
|
|||||||
} i2s_tdm_slot_mask_t;
|
} i2s_tdm_slot_mask_t;
|
||||||
#endif // SOC_I2S_SUPPORTS_TDM
|
#endif // SOC_I2S_SUPPORTS_TDM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2S channel events that supported by the ETM module
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
/** Trigger condition:
|
||||||
|
* TX: no data to send in the TX FIFO, i.e., DMA need to stop (next desc is NULL)
|
||||||
|
* RX: 1. If rx_stop_mode = 0, this event will trigger when DMA is stopped (next desc is NULL)
|
||||||
|
* 2. If rx_stop_mode = 1, this event will trigger when DMA in_suc_eof.
|
||||||
|
* 3. If rx_stop_mode = 2, this event will trigger when RX FIFO is full.
|
||||||
|
*/
|
||||||
|
I2S_ETM_EVENT_DONE, /*!< Event that I2S TX or RX stopped */
|
||||||
|
/** Trigger condition:
|
||||||
|
* TX: the sent words(in 32-bit) number reach the threshold that configured in `etm_tx_send_word_num`
|
||||||
|
* RX: the received words(in 32-bit) number reach the threshold that configured in `etm_rx_receive_word_num`
|
||||||
|
* and `etm_rx_receive_word_num` should be smaller than the size of the DMA buffer in one `in_suc_eof` event.
|
||||||
|
*/
|
||||||
|
I2S_ETM_EVENT_REACH_THRESH, /*!< Event that the I2S sent or received data reached the threshold */
|
||||||
|
I2S_ETM_EVENT_MAX, /*!< Maximum number of events */
|
||||||
|
} i2s_etm_event_type_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2S channel tasks that supported by the ETM module
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
I2S_ETM_TASK_START, /*!< Start the I2S channel */
|
||||||
|
I2S_ETM_TASK_STOP, /*!< Stop the I2S channel */
|
||||||
|
I2S_ETM_TASK_MAX, /*!< Maximum number of tasks */
|
||||||
|
} i2s_etm_task_type_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -555,6 +555,10 @@ config SOC_I2S_HW_VERSION_2
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_I2S_SUPPORTS_ETM
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_I2S_SUPPORTS_TX_SYNC_CNT
|
config SOC_I2S_SUPPORTS_TX_SYNC_CNT
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
@ -269,6 +269,7 @@
|
|||||||
/*-------------------------- I2S CAPS ----------------------------------------*/
|
/*-------------------------- I2S CAPS ----------------------------------------*/
|
||||||
#define SOC_I2S_NUM (1U)
|
#define SOC_I2S_NUM (1U)
|
||||||
#define SOC_I2S_HW_VERSION_2 (1)
|
#define SOC_I2S_HW_VERSION_2 (1)
|
||||||
|
#define SOC_I2S_SUPPORTS_ETM (1)
|
||||||
#define SOC_I2S_SUPPORTS_TX_SYNC_CNT (1)
|
#define SOC_I2S_SUPPORTS_TX_SYNC_CNT (1)
|
||||||
// #define SOC_I2S_SUPPORTS_RX_RECOMB (1) //TODO[C5] IDF-9966
|
// #define SOC_I2S_SUPPORTS_RX_RECOMB (1) //TODO[C5] IDF-9966
|
||||||
#define SOC_I2S_SUPPORTS_XTAL (1)
|
#define SOC_I2S_SUPPORTS_XTAL (1)
|
||||||
|
@ -639,6 +639,10 @@ config SOC_I2S_HW_VERSION_2
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_I2S_SUPPORTS_ETM
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_I2S_SUPPORTS_XTAL
|
config SOC_I2S_SUPPORTS_XTAL
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
@ -264,6 +264,7 @@
|
|||||||
/*-------------------------- I2S CAPS ----------------------------------------*/
|
/*-------------------------- I2S CAPS ----------------------------------------*/
|
||||||
#define SOC_I2S_NUM (1U)
|
#define SOC_I2S_NUM (1U)
|
||||||
#define SOC_I2S_HW_VERSION_2 (1)
|
#define SOC_I2S_HW_VERSION_2 (1)
|
||||||
|
#define SOC_I2S_SUPPORTS_ETM (1)
|
||||||
#define SOC_I2S_SUPPORTS_XTAL (1)
|
#define SOC_I2S_SUPPORTS_XTAL (1)
|
||||||
#define SOC_I2S_SUPPORTS_PLL_F160M (1)
|
#define SOC_I2S_SUPPORTS_PLL_F160M (1)
|
||||||
#define SOC_I2S_SUPPORTS_PCM (1)
|
#define SOC_I2S_SUPPORTS_PCM (1)
|
||||||
|
@ -631,6 +631,10 @@ config SOC_I2S_HW_VERSION_2
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_I2S_SUPPORTS_ETM
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_I2S_SUPPORTS_XTAL
|
config SOC_I2S_SUPPORTS_XTAL
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
@ -262,6 +262,7 @@
|
|||||||
/*-------------------------- I2S CAPS ----------------------------------------*/
|
/*-------------------------- I2S CAPS ----------------------------------------*/
|
||||||
#define SOC_I2S_NUM (1U)
|
#define SOC_I2S_NUM (1U)
|
||||||
#define SOC_I2S_HW_VERSION_2 (1)
|
#define SOC_I2S_HW_VERSION_2 (1)
|
||||||
|
#define SOC_I2S_SUPPORTS_ETM (1)
|
||||||
#define SOC_I2S_SUPPORTS_XTAL (1)
|
#define SOC_I2S_SUPPORTS_XTAL (1)
|
||||||
#define SOC_I2S_SUPPORTS_PLL_F96M (1)
|
#define SOC_I2S_SUPPORTS_PLL_F96M (1)
|
||||||
#define SOC_I2S_SUPPORTS_PLL_F64M (1)
|
#define SOC_I2S_SUPPORTS_PLL_F64M (1)
|
||||||
|
@ -755,6 +755,10 @@ config SOC_I2S_HW_VERSION_2
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config SOC_I2S_SUPPORTS_ETM
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
|
||||||
config SOC_I2S_SUPPORTS_XTAL
|
config SOC_I2S_SUPPORTS_XTAL
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
@ -306,6 +306,7 @@
|
|||||||
/*-------------------------- I2S CAPS ----------------------------------------*/
|
/*-------------------------- I2S CAPS ----------------------------------------*/
|
||||||
#define SOC_I2S_NUM (3U)
|
#define SOC_I2S_NUM (3U)
|
||||||
#define SOC_I2S_HW_VERSION_2 (1)
|
#define SOC_I2S_HW_VERSION_2 (1)
|
||||||
|
#define SOC_I2S_SUPPORTS_ETM (1)
|
||||||
#define SOC_I2S_SUPPORTS_XTAL (1)
|
#define SOC_I2S_SUPPORTS_XTAL (1)
|
||||||
// #define SOC_I2S_SUPPORTS_APLL (1) // TODO: IDF-8884
|
// #define SOC_I2S_SUPPORTS_APLL (1) // TODO: IDF-8884
|
||||||
#define SOC_I2S_SUPPORTS_PCM (1)
|
#define SOC_I2S_SUPPORTS_PCM (1)
|
||||||
|
Loading…
Reference in New Issue
Block a user