#include "driver/i2s_std.h"
#include "driver/gpio.h"
i2s_chan_handle_t tx_handle;
/* 通过辅助宏获取默认的通道配置
* 这个辅助宏在 'i2s_common.h' 中定义,由所有 I2S 通信模式共享
* 它可以帮助指定 I2S 角色和端口 ID */
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
/* 分配新的 TX 通道并获取该通道的句柄 */
i2s_new_channel(&chan_cfg, &tx_handle, NULL);
/* 进行配置,可以通过宏生成声道配置和时钟配置
* 这两个辅助宏在 'i2s_std.h' 中定义,只能用于 STD 模式
* 它们可以帮助初始化或更新声道和时钟配置 */
i2s_std_config_t std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000),
.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = GPIO_NUM_4,
.ws = GPIO_NUM_5,
.dout = GPIO_NUM_18,
.din = I2S_GPIO_UNUSED,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
/* 初始化通道 */
i2s_channel_init_std_mode(tx_handle, &std_cfg);
/* 在写入数据之前,先启用 TX 通道 */
i2s_channel_enable(tx_handle);
i2s_channel_write(tx_handle, src_buf, bytes_to_write, bytes_written, ticks_to_wait);
/* 如果需要更新声道或时钟配置
* 需要在更新前先禁用通道 */
// i2s_channel_disable(tx_handle);
// std_cfg.slot_cfg.slot_mode = I2S_SLOT_MODE_MONO; // 默认为立体声
// i2s_channel_reconfig_std_slot(tx_handle, &std_cfg.slot_cfg);
// std_cfg.clk_cfg.sample_rate_hz = 96000;
// i2s_channel_reconfig_std_clock(tx_handle, &std_cfg.clk_cfg);
/* 删除通道之前必须先禁用通道 */
i2s_channel_disable(tx_handle);
/* 如果不再需要句柄,删除该句柄以释放通道资源 */
i2s_del_channel(tx_handle);
ESP32 上的接收有些复杂。首先,当数据位宽为 8 位或 24 位时,接收的数据仍将以 2 个字节或 4 个字节对齐,这意味着有效数据被放在每两个字节的高 8 位和每四个字节的高 24 位。例如,当线路上的数据是 8 位宽度的 0x5A
时,接收的数据将是 0x5A00
;当数据是 0x00 005A
时,则收到 0x0000 5A00
。其次,在 8 位宽和 16 位宽单声道传输中,缓冲区内每两个数据会进行一次数据翻转,因此可能需要手动将顺序回转,以获取正确的数据顺序。
#include "driver/i2s_std.h"
#include "driver/gpio.h"
i2s_chan_handle_t rx_handle;
/* 通过辅助宏获取默认的通道配置
* 这个辅助宏在 'i2s_common.h' 中定义,由所有 I2S 通信模式共享
* 它可以帮助指定 I2S 角色和端口 ID */
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
/* 分配新的 TX 通道并获取该通道的句柄 */
i2s_new_channel(&chan_cfg, NULL, &rx_handle);
/* 进行配置,可以通过宏生成声道配置和时钟配置
* 这两个辅助宏在 'i2s_std.h' 中定义,只能用于 STD 模式
* 它们可以帮助初始化或更新声道和时钟配置 */
i2s_std_config_t std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000),
.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = GPIO_NUM_4,
.ws = GPIO_NUM_5,
.dout = I2S_GPIO_UNUSED,
.din = GPIO_NUM_19,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
/* 初始化通道 */
i2s_channel_init_std_mode(rx_handle, &std_cfg);
/* 在读取数据之前,先启动 RX 通道 */
i2s_channel_enable(rx_handle);
i2s_channel_read(rx_handle, desc_buf, bytes_to_read, bytes_read, ticks_to_wait);
/* 删除通道之前必须先禁用通道 */
i2s_channel_disable(rx_handle);
/* 如果不再需要句柄,删除该句柄以释放通道资源 */
i2s_del_channel(rx_handle);
I2S_PDM_TX_CLK_DEFAULT_CONFIG
PDM TX API 的相关信息,可参考 PDM 模式。更多细节请参阅 driver/i2s/include/driver/i2s_pdm.h。
PDM 数据位宽固定为 16 位。如果 int16_t
写缓冲区中的数据如下:
/* 分配 I2S TX 通道 */
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
i2s_new_channel(&chan_cfg, &tx_handle, NULL);
/* 初始化通道为 PDM TX 模式 */
i2s_pdm_tx_config_t pdm_tx_cfg = {
.clk_cfg = I2S_PDM_TX_CLK_DEFAULT_CONFIG(36000),
.slot_cfg = I2S_PDM_TX_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg = {
.clk = GPIO_NUM_5,
.dout = GPIO_NUM_18,
.invert_flags = {
.clk_inv = false,
i2s_channel_init_pdm_tx_mode(tx_handle, &pdm_tx_cfg);
I2S_PDM_RX_CLK_DEFAULT_CONFIG
PDM RX API 的相关信息,可参考 PDM 模式。更多细节请参阅 driver/i2s/include/driver/i2s_pdm.h。
PDM 数据位宽固定为 16 位。如果线路上的数据如下所示。为方便理解,已将线路上的数据格式由 PDM 转为 PCM。
/* 分配 I2S RX 通道 */
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
i2s_new_channel(&chan_cfg, NULL, &rx_handle);
/* 初始化通道为 PDM RX 模式 */
i2s_pdm_rx_config_t pdm_rx_cfg = {
.clk_cfg = I2S_PDM_RX_CLK_DEFAULT_CONFIG(36000),
.slot_cfg = I2S_PDM_RX_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO),
.gpio_cfg = {
.clk = GPIO_NUM_5,
.din = GPIO_NUM_19,
.invert_flags = {
.clk_inv = false,
i2s_channel_init_pdm_rx_mode(rx_handle, &pdm_rx_cfg);
全双工
全双工模式可以在 I2S 端口中同时注册 TX 和 RX 通道,同时通道共享 BCLK 和 WS 信号。目前,STD 和 TDM 通信模式支持以下方式的全双工通信,但不支持 PDM 全双工模式,因为 PDM 模式下 TX 和 RX 通道的时钟不同。
请注意,一个句柄只能代表一个通道,因此仍然需要对 TX 和 RX 通道逐个进行声道和时钟配置。
以下示例展示了如何分配两个全双工通道:
#include "driver/i2s_std.h"
#include "driver/gpio.h"
i2s_chan_handle_t tx_handle;
i2s_chan_handle_t rx_handle;
/* 分配两个 I2S 通道 */
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
/* 同时分配给 TX 和 RX 通道,使其进入全双工模式。 */
i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle);
/* 配置两个通道,因为在全双工模式下,TX 和 RX 通道必须相同。 */
i2s_std_config_t std_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(32000),
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = GPIO_NUM_4,
.ws = GPIO_NUM_5,
.dout = GPIO_NUM_18,
.din = GPIO_NUM_19,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
i2s_channel_init_std_mode(tx_handle, &std_cfg);
i2s_channel_init_std_mode(rx_handle, &std_cfg);
i2s_channel_enable(tx_handle);
i2s_channel_enable(rx_handle);
单工模式
在单工模式下分配通道句柄,应该为每个通道调用 i2s_new_channel()
。在 ESP32 上,TX/RX 通道的时钟和 GPIO 管脚不是相互独立的,因此在单工模式下,TX 和 RX 通道不能共存于同一个 I2S 端口中。
#include "driver/i2s_std.h"
#include "driver/gpio.h"
i2s_chan_handle_t tx_handle;
i2s_chan_handle_t rx_handle;
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
i2s_new_channel(&chan_cfg, &tx_handle, NULL);
i2s_std_config_t std_tx_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(48000),
.slot_cfg = I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO),
.gpio_cfg = {
.mclk = GPIO_NUM_0,
.bclk = GPIO_NUM_4,
.ws = GPIO_NUM_5,
.dout = GPIO_NUM_18,
.din = I2S_GPIO_UNUSED,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
/* 初始化通道 */
i2s_channel_init_std_mode(tx_handle, &std_tx_cfg);
i2s_channel_enable(tx_handle);
/* 如果没有找到其他可用的 I2S 设备,RX 通道将被注册在另一个 I2S 上
* 并返回 ESP_ERR_NOT_FOUND */
i2s_new_channel(&chan_cfg, NULL, &rx_handle);
i2s_std_config_t std_rx_cfg = {
.clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(16000),
.slot_cfg = I2S_STD_MSB_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_32BIT, I2S_SLOT_MODE_STEREO),
.gpio_cfg = {
.mclk = I2S_GPIO_UNUSED,
.bclk = GPIO_NUM_6,
.ws = GPIO_NUM_7,
.dout = I2S_GPIO_UNUSED,
.din = GPIO_NUM_19,
.invert_flags = {
.mclk_inv = false,
.bclk_inv = false,
.ws_inv = false,
i2s_channel_init_std_mode(rx_handle, &std_rx_cfg);
i2s_channel_enable(rx_handle);
对于需要高频采样率的应用,数据的巨大吞吐量可能会导致数据丢失。用户可以通过注册 ISR 回调函数来接收事件队列中的数据丢失事件:
static IRAM_ATTR bool i2s_rx_queue_overflow_callback(i2s_chan_handle_t handle, i2s_event_data_t *event, void *user_ctx)
// 处理 RX 队列溢出事件 ...
return false;
i2s_event_callbacks_t cbs = {
.on_recv = NULL,
.on_recv_q_ovf = i2s_rx_queue_overflow_callback,
.on_sent = NULL,
.on_send_q_ovf = NULL,
TEST_ESP_OK(i2s_channel_register_event_callback(rx_handle, &cbs, NULL));
请按照以下步骤操作,以防止数据丢失:
确定中断间隔。通常来说,当发生数据丢失时,为减少中断次数,中断间隔应该越久越好。因此,在保证 DMA 缓冲区大小不超过最大值 4092 的前提下,应使 dma_frame_num
尽可能大。具体转换关系如下:
interrupt_interval(unit: sec) = dma_frame_num / sample_rate
dma_buffer_size = dma_frame_num * slot_num * data_bit_width / 8 <= 4092
确定 dma_desc_num
的值。dma_desc_num
由 i2s_channel_read
轮询周期的最大时间决定,所有接收到的数据都应该存储在两个 i2s_channel_read
之间。这个周期可以通过计时器或输出 GPIO 信号来计算。具体转换关系如下:
dma_desc_num > polling_cycle / interrupt_interval
确定接收缓冲区大小。在 i2s_channel_read
中提供的接收缓冲区应当能够容纳所有 DMA 缓冲区中的数据,这意味着它应该大于所有 DMA 缓冲区的总大小:
recv_buffer_size > dma_desc_num * dma_buffer_size
那么可以按照以下公式计算出参数 dma_frame_num
、 dma_desc_num
和 recv_buf_size
:
dma_frame_num * slot_num * data_bit_width / 8 = dma_buffer_size <= 4092
dma_frame_num <= 511
interrupt_interval = dma_frame_num / sample_rate = 511 / 144000 = 0.003549 s = 3.549 ms
dma_desc_num > polling_cycle / interrupt_interval = cell(10 / 3.549) = cell(2.818) = 3
recv_buffer_size > dma_desc_num * dma_buffer_size = 3 * 4092 = 12276 bytes
This header file is a part of the API provided by the driver
component. To declare that your component depends on driver
, add the following to your CMakeLists.txt:
REQUIRES driver
PRIV_REQUIRES driver
esp_err_t i2s_channel_init_std_mode(i2s_chan_handle_t handle, const i2s_std_config_t *std_cfg)
Initialize I2S channel to standard mode.
Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized) and the state will be updated to READY if initialization success, otherwise the state will return to REGISTERED.
handle -- [in] I2S channel handler
std_cfg -- [in] Configurations for standard mode, including clock, slot and GPIO The clock configuration can be generated by the helper macro I2S_STD_CLK_DEFAULT_CONFIG
The slot configuration can be generated by the helper macro I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG
, I2S_STD_PCM_SLOT_DEFAULT_CONFIG
or I2S_STD_MSB_SLOT_DEFAULT_CONFIG
ESP_OK Initialize successfully
ESP_ERR_NO_MEM No memory for storing the channel information
ESP_ERR_INVALID_ARG NULL pointer or invalid configuration
ESP_ERR_INVALID_STATE This channel is not registered
esp_err_t i2s_channel_reconfig_std_clock(i2s_chan_handle_t handle, const i2s_std_clk_config_t *clk_cfg)
Reconfigure the I2S clock for standard mode.
Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started this function won't change the state. i2s_channel_disable
should be called before calling this function if I2S has started.
The input channel handle has to be initialized to standard mode, i.e., i2s_channel_init_std_mode
has been called before reconfiguring
handle -- [in] I2S channel handler
clk_cfg -- [in] Standard mode clock configuration, can be generated by I2S_STD_CLK_DEFAULT_CONFIG
ESP_OK Set clock successfully
ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not standard mode
ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
esp_err_t i2s_channel_reconfig_std_slot(i2s_chan_handle_t handle, const i2s_std_slot_config_t *slot_cfg)
Reconfigure the I2S slot for standard mode.
Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started this function won't change the state. i2s_channel_disable
should be called before calling this function if I2S has started.
The input channel handle has to be initialized to standard mode, i.e., i2s_channel_init_std_mode
has been called before reconfiguring
handle -- [in] I2S channel handler
slot_cfg -- [in] Standard mode slot configuration, can be generated by I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG
, I2S_STD_PCM_SLOT_DEFAULT_CONFIG
and I2S_STD_MSB_SLOT_DEFAULT_CONFIG
.
ESP_OK Set clock successfully
ESP_ERR_NO_MEM No memory for DMA buffer
ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not standard mode
ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
esp_err_t i2s_channel_reconfig_std_gpio(i2s_chan_handle_t handle, const i2s_std_gpio_config_t *gpio_cfg)
Reconfigure the I2S GPIO for standard mode.
Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started this function won't change the state. i2s_channel_disable
should be called before calling this function if I2S has started.
The input channel handle has to be initialized to standard mode, i.e., i2s_channel_init_std_mode
has been called before reconfiguring
handle -- [in] I2S channel handler
gpio_cfg -- [in] Standard mode GPIO configuration, specified by user
ESP_OK Set clock successfully
ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not standard mode
ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
struct i2s_std_config_t
I2S standard mode major configuration that including clock/slot/GPIO configuration.
Public Members
i2s_std_clk_config_t clk_cfg
Standard mode clock configuration, can be generated by macro I2S_STD_CLK_DEFAULT_CONFIG
I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo)
Philips format in 2 slots.
This file is specified for I2S standard communication mode Features:
Philips/MSB/PCM are supported in standard mode
Fixed to 2 slots
bits_per_sample -- I2S data bit width
mono_or_stereo -- I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
I2S_STD_PCM_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo)
PCM(short) format in 2 slots.
PCM(long) is same as Philips in 2 slots
bits_per_sample -- I2S data bit width
mono_or_stereo -- I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
I2S_STD_MSB_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo)
MSB format in 2 slots.
bits_per_sample -- I2S data bit width
mono_or_stereo -- I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
Please set the mclk_multiple to I2S_MCLK_MULTIPLE_384 while using 24 bits data width Otherwise the sample rate might be imprecise since the BCLK division is not a integer
rate -- sample rate
This header file is a part of the API provided by the driver
component. To declare that your component depends on driver
, add the following to your CMakeLists.txt:
REQUIRES driver
PRIV_REQUIRES driver
esp_err_t i2s_channel_init_pdm_rx_mode(i2s_chan_handle_t handle, const i2s_pdm_rx_config_t *pdm_rx_cfg)
Initialize I2S channel to PDM RX mode.
Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized) and the state will be updated to READY if initialization success, otherwise the state will return to REGISTERED.
handle -- [in] I2S RX channel handler
pdm_rx_cfg -- [in] Configurations for PDM RX mode, including clock, slot and GPIO The clock configuration can be generated by the helper macro I2S_PDM_RX_CLK_DEFAULT_CONFIG
The slot configuration can be generated by the helper macro I2S_PDM_RX_SLOT_DEFAULT_CONFIG
ESP_OK Initialize successfully
ESP_ERR_NO_MEM No memory for storing the channel information
ESP_ERR_INVALID_ARG NULL pointer or invalid configuration
ESP_ERR_INVALID_STATE This channel is not registered
esp_err_t i2s_channel_reconfig_pdm_rx_clock(i2s_chan_handle_t handle, const i2s_pdm_rx_clk_config_t *clk_cfg)
Reconfigure the I2S clock for PDM RX mode.
Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started this function won't change the state. i2s_channel_disable
should be called before calling this function if I2S has started.
The input channel handle has to be initialized to PDM RX mode, i.e., i2s_channel_init_pdm_rx_mode
has been called before reconfiguring
handle -- [in] I2S RX channel handler
clk_cfg -- [in] PDM RX mode clock configuration, can be generated by I2S_PDM_RX_CLK_DEFAULT_CONFIG
ESP_OK Set clock successfully
ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not PDM mode
ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
esp_err_t i2s_channel_reconfig_pdm_rx_slot(i2s_chan_handle_t handle, const i2s_pdm_rx_slot_config_t *slot_cfg)
Reconfigure the I2S slot for PDM RX mode.
Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started this function won't change the state. i2s_channel_disable
should be called before calling this function if I2S has started.
The input channel handle has to be initialized to PDM RX mode, i.e., i2s_channel_init_pdm_rx_mode
has been called before reconfiguring
handle -- [in] I2S RX channel handler
slot_cfg -- [in] PDM RX mode slot configuration, can be generated by I2S_PDM_RX_SLOT_DEFAULT_CONFIG
ESP_OK Set clock successfully
ESP_ERR_NO_MEM No memory for DMA buffer
ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not PDM mode
ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
esp_err_t i2s_channel_reconfig_pdm_rx_gpio(i2s_chan_handle_t handle, const i2s_pdm_rx_gpio_config_t *gpio_cfg)
Reconfigure the I2S GPIO for PDM RX mode.
Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started this function won't change the state. i2s_channel_disable
should be called before calling this function if I2S has started.
The input channel handle has to be initialized to PDM RX mode, i.e., i2s_channel_init_pdm_rx_mode
has been called before reconfiguring
handle -- [in] I2S RX channel handler
gpio_cfg -- [in] PDM RX mode GPIO configuration, specified by user
ESP_OK Set clock successfully
ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not PDM mode
ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
esp_err_t i2s_channel_init_pdm_tx_mode(i2s_chan_handle_t handle, const i2s_pdm_tx_config_t *pdm_tx_cfg)
Initialize I2S channel to PDM TX mode.
Only allowed to be called when the channel state is REGISTERED, (i.e., channel has been allocated, but not initialized) and the state will be updated to READY if initialization success, otherwise the state will return to REGISTERED.
handle -- [in] I2S TX channel handler
pdm_tx_cfg -- [in] Configurations for PDM TX mode, including clock, slot and GPIO The clock configuration can be generated by the helper macro I2S_PDM_TX_CLK_DEFAULT_CONFIG
The slot configuration can be generated by the helper macro I2S_PDM_TX_SLOT_DEFAULT_CONFIG
ESP_OK Initialize successfully
ESP_ERR_NO_MEM No memory for storing the channel information
ESP_ERR_INVALID_ARG NULL pointer or invalid configuration
ESP_ERR_INVALID_STATE This channel is not registered
esp_err_t i2s_channel_reconfig_pdm_tx_clock(i2s_chan_handle_t handle, const i2s_pdm_tx_clk_config_t *clk_cfg)
Reconfigure the I2S clock for PDM TX mode.
Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started this function won't change the state. i2s_channel_disable
should be called before calling this function if I2S has started.
The input channel handle has to be initialized to PDM TX mode, i.e., i2s_channel_init_pdm_tx_mode
has been called before reconfiguring
handle -- [in] I2S TX channel handler
clk_cfg -- [in] PDM TX mode clock configuration, can be generated by I2S_PDM_TX_CLK_DEFAULT_CONFIG
ESP_OK Set clock successfully
ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not PDM mode
ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
esp_err_t i2s_channel_reconfig_pdm_tx_slot(i2s_chan_handle_t handle, const i2s_pdm_tx_slot_config_t *slot_cfg)
Reconfigure the I2S slot for PDM TX mode.
Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started this function won't change the state. i2s_channel_disable
should be called before calling this function if I2S has started.
The input channel handle has to be initialized to PDM TX mode, i.e., i2s_channel_init_pdm_tx_mode
has been called before reconfiguring
handle -- [in] I2S TX channel handler
slot_cfg -- [in] PDM TX mode slot configuration, can be generated by I2S_PDM_TX_SLOT_DEFAULT_CONFIG
ESP_OK Set clock successfully
ESP_ERR_NO_MEM No memory for DMA buffer
ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not PDM mode
ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
esp_err_t i2s_channel_reconfig_pdm_tx_gpio(i2s_chan_handle_t handle, const i2s_pdm_tx_gpio_config_t *gpio_cfg)
Reconfigure the I2S GPIO for PDM TX mode.
Only allowed to be called when the channel state is READY, i.e., channel has been initialized, but not started this function won't change the state. i2s_channel_disable
should be called before calling this function if I2S has started.
The input channel handle has to be initialized to PDM TX mode, i.e., i2s_channel_init_pdm_tx_mode
has been called before reconfiguring
handle -- [in] I2S TX channel handler
gpio_cfg -- [in] PDM TX mode GPIO configuration, specified by user
ESP_OK Set clock successfully
ESP_ERR_INVALID_ARG NULL pointer, invalid configuration or not PDM mode
ESP_ERR_INVALID_STATE This channel is not initialized or not stopped
struct i2s_pdm_rx_config_t
I2S PDM RX mode major configuration that including clock/slot/GPIO configuration.
Public Members
i2s_pdm_rx_clk_config_t clk_cfg
PDM RX clock configurations, can be generated by macro I2S_PDM_RX_CLK_DEFAULT_CONFIG
struct i2s_pdm_tx_config_t
I2S PDM TX mode major configuration that including clock/slot/GPIO configuration.
Public Members
i2s_pdm_tx_clk_config_t clk_cfg
PDM TX clock configurations, can be generated by macro I2S_PDM_TX_CLK_DEFAULT_CONFIG
I2S_PDM_RX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo)
PDM format in 2 slots(RX)
This file is specified for I2S PDM communication mode Features:
Only support PDM TX/RX mode
Fixed to 2 slots
Data bit width only support 16 bits
bits_per_sample -- I2S data bit width, only support 16 bits for PDM mode
mono_or_stereo -- I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
I2S_PDM_TX_SLOT_DEFAULT_CONFIG(bits_per_sample, mono_or_stereo)
PDM style in 2 slots(TX) for codec line mode.
bits_per_sample -- I2S data bit width, only support 16 bits for PDM mode
mono_or_stereo -- I2S_SLOT_MODE_MONO or I2S_SLOT_MODE_STEREO
I2S_PDM_TX_CLK_DEFAULT_CONFIG(rate)
I2S default PDM TX clock configuration for codec line mode.
TX PDM can only be set to the following two up-sampling rate configurations: 1: fp = 960, fs = sample_rate_hz / 100, in this case, Fpdm = 128*48000 2: fp = 960, fs = 480, in this case, Fpdm = 128*Fpcm = 128*sample_rate_hz If the PDM receiver do not care the PDM serial clock, it's recommended set Fpdm = 128*48000. Otherwise, the second configuration should be adopted.
rate -- sample rate (not suggest to exceed 48000 Hz, otherwise more glitches and noise may appear)
I2S_PDM_TX_CLK_DAC_DEFAULT_CONFIG(rate)
I2S default PDM TX clock configuration for DAC line mode.
TX PDM can only be set to the following two up-sampling rate configurations: 1: fp = 960, fs = sample_rate_hz / 100, in this case, Fpdm = 128*48000 2: fp = 960, fs = 480, in this case, Fpdm = 128*Fpcm = 128*sample_rate_hz If the PDM receiver do not care the PDM serial clock, it's recommended set Fpdm = 128*48000. Otherwise, the second configuration should be adopted.
The noise might be different with different configurations, this macro provides a set of configurations that have relatively high SNR (Signal Noise Ratio), you can also adjust them to fit your case.
rate -- sample rate (not suggest to exceed 48000 Hz, otherwise more glitches and noise may appear)
This header file is a part of the API provided by the driver
component. To declare that your component depends on driver
, add the following to your CMakeLists.txt:
REQUIRES driver
PRIV_REQUIRES driver
esp_err_t i2s_new_channel(const i2s_chan_config_t *chan_cfg, i2s_chan_handle_t *ret_tx_handle, i2s_chan_handle_t *ret_rx_handle)
Allocate new I2S channel(s)
The new created I2S channel handle will be REGISTERED state after it is allocated successfully.
When the port id in channel configuration is I2S_NUM_AUTO, driver will allocate I2S port automatically on one of the I2S controller, otherwise driver will try to allocate the new channel on the selected port.
If both tx_handle and rx_handle are not NULL, it means this I2S controller will work at full-duplex mode, the RX and TX channels will be allocated on a same I2S port in this case. Note that some configurations of TX/RX channel are shared on ESP32 and ESP32S2, so please make sure they are working at same condition and under same status(start/stop). Currently, full-duplex mode can't guarantee TX/RX channels write/read synchronously, they can only share the clock signals for now.
If tx_handle OR rx_handle is NULL, it means this I2S controller will work at simplex mode. For ESP32 and ESP32S2, the whole I2S controller (i.e. both RX and TX channel) will be occupied, even if only one of RX or TX channel is registered. For the other targets, another channel on this controller will still available.
chan_cfg -- [in] I2S controller channel configurations
ret_tx_handle -- [out] I2S channel handler used for managing the sending channel(optional)
ret_rx_handle -- [out] I2S channel handler used for managing the receiving channel(optional)
ESP_OK Allocate new channel(s) success
ESP_ERR_NOT_SUPPORTED The communication mode is not supported on the current chip
ESP_ERR_INVALID_ARG NULL pointer or illegal parameter in i2s_chan_config_t
ESP_ERR_NOT_FOUND No available I2S channel found
Only allowed to be called when the I2S channel is at REGISTERED or READY state (i.e., it should stop before deleting it).
Resource will be free automatically if all channels in one port are deleted
handle -- [in] I2S channel handler