#include "driver/i2s_std.h"
#include "driver/gpio.h"
i2s_chan_handle_t tx_handle;
/* Get the default channel configuration by the helper macro.
* This helper macro is defined in `i2s_common.h` and shared by all the I2S communication modes.
* It can help to specify the I2S role and port ID */
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
/* Allocate a new TX channel and get the handle of this channel */
i2s_new_channel(&chan_cfg, &tx_handle, NULL);
/* Setting the configurations, the slot configuration and clock configuration can be generated by the macros
* These two helper macros are defined in `i2s_std.h` which can only be used in STD mode.
* They can help to specify the slot and clock configurations for initialization or updating */
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,
/* Initialize the channel */
i2s_channel_init_std_mode(tx_handle, &std_cfg);
/* Before writing data, start the TX channel first */
i2s_channel_enable(tx_handle);
i2s_channel_write(tx_handle, src_buf, bytes_to_write, bytes_written, ticks_to_wait);
/* If the configurations of slot or clock need to be updated,
* stop the channel first and then update it */
// i2s_channel_disable(tx_handle);
// std_cfg.slot_cfg.slot_mode = I2S_SLOT_MODE_MONO; // Default is stereo
// 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);
/* Have to stop the channel before deleting it */
i2s_channel_disable(tx_handle);
/* If the handle is not needed any more, delete it to release the channel resources */
i2s_del_channel(tx_handle);
The receive case is a little bit complicated on ESP32. Firstly, when the data width is 8-bit or 24-bit, the received data will still align with two bytes or four bytes, which means that the valid data are put in the high 8 bits in every two bytes and high 24 bits in every four bytes. For example, the received data will be 0x5A00
when the data on the line is 0x5A
in 8-bit width, and 0x0000 5A00
if the data on the line is 0x00 005A
. Secondly, for the 8-bit or 16-bit mono case, the data in buffer is swapped every two data, so it may be necessary to manually swap the data back to the correct order.
#include "driver/i2s_std.h"
#include "driver/gpio.h"
i2s_chan_handle_t rx_handle;
/* Get the default channel configuration by helper macro.
* This helper macro is defined in `i2s_common.h` and shared by all the I2S communication modes.
* It can help to specify the I2S role and port ID */
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
/* Allocate a new RX channel and get the handle of this channel */
i2s_new_channel(&chan_cfg, NULL, &rx_handle);
/* Setting the configurations, the slot configuration and clock configuration can be generated by the macros
* These two helper macros are defined in `i2s_std.h` which can only be used in STD mode.
* They can help to specify the slot and clock configurations for initialization or updating */
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,
/* Initialize the channel */
i2s_channel_init_std_mode(rx_handle, &std_cfg);
/* Before reading data, start the RX channel first */
i2s_channel_enable(rx_handle);
i2s_channel_read(rx_handle, desc_buf, bytes_to_read, bytes_read, ticks_to_wait);
/* Have to stop the channel before deleting it */
i2s_channel_disable(rx_handle);
/* If the handle is not needed any more, delete it to release the channel resources */
i2s_del_channel(rx_handle);
For PDM mode in TX channel, the slot configuration helper macro is:
I2S_PDM_TX_SLOT_DEFAULT_CONFIG
The clock configuration helper macro is:
I2S_PDM_TX_CLK_DEFAULT_CONFIG
Please refer to PDM Mode for information about PDM TX API. And for more details, please refer to driver/i2s/include/driver/i2s_pdm.h.
The PDM data width is fixed to 16-bit. When the data in an int16_t
writing buffer is:
/* Allocate an I2S TX channel */
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
i2s_new_channel(&chan_cfg, &tx_handle, NULL);
/* Init the channel into PDM TX mode */
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);
For PDM mode in RX channel, the slot configuration helper macro is:
I2S_PDM_RX_SLOT_DEFAULT_CONFIG
The clock configuration helper macro is:
I2S_PDM_RX_CLK_DEFAULT_CONFIG
Please refer to PDM Mode for information about PDM RX API. And for more details, please refer to driver/i2s/include/driver/i2s_pdm.h.
The PDM data width is fixed to 16-bit. When the data on the line (The PDM format on the line is transferred to PCM format for easier comprehension) is:
/* Allocate an I2S RX channel */
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER);
i2s_new_channel(&chan_cfg, NULL, &rx_handle);
/* Init the channel into PDM RX mode */
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);
Full-duplex
Full-duplex mode registers TX and RX channel in an I2S port at the same time, and the channels share the BCLK and WS signals. Currently, STD and TDM communication modes supports full-duplex mode in the following way, but PDM full-duplex is not supported because due to different PDM TX and RX clocks.
Note that one handle can only stand for one channel. Therefore, it is still necessary to configure the slot and clock for both TX and RX channels one by one.
Here is an example of how to allocate a pair of full-duplex channels:
#include "driver/i2s_std.h"
#include "driver/gpio.h"
i2s_chan_handle_t tx_handle;
i2s_chan_handle_t rx_handle;
/* Allocate a pair of I2S channel */
i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER);
/* Allocate for TX and RX channel at the same time, then they will work in full-duplex mode */
i2s_new_channel(&chan_cfg, &tx_handle, &rx_handle);
/* Set the configurations for BOTH TWO channels, since TX and RX channel have to be same in full-duplex mode */
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);
Simplex Mode
To allocate a channel handle in simplex mode, i2s_new_channel()
should be called for each channel. The clock and GPIO pins of TX/RX channel on ESP32 are not independent, so the TX and RX channel cannot coexist on the same I2S port in simplex mode.
#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,
/* Initialize the channel */
i2s_channel_init_std_mode(tx_handle, &std_tx_cfg);
i2s_channel_enable(tx_handle);
/* RX channel will be registered on another I2S, if no other available I2S unit found
* it will return 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);
How to Prevent Data Lost
For applications that need a high frequency sample rate, the massive data throughput may cause data lost. Users can receive data lost event by registering the ISR callback function to receive the event queue:
static IRAM_ATTR bool i2s_rx_queue_overflow_callback(i2s_chan_handle_t handle, i2s_event_data_t *event, void *user_ctx)
// handle RX queue overflow event ...
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));
Please follow these steps to prevent data lost:
Determine the interrupt interval. Generally, when data lost happens, the bigger the interval, the better, which helps to reduce the interrupt times. This means dma_frame_num
should be as big as possible while the DMA buffer size is below the maximum value of 4092. The relationships are:
interrupt_interval(unit: sec) = dma_frame_num / sample_rate
dma_buffer_size = dma_frame_num * slot_num * data_bit_width / 8 <= 4092
Determine dma_desc_num
. dma_desc_num
is decided by the maximum time of i2s_channel_read
polling cycle. All the received data is supposed to be stored between two i2s_channel_read
. This cycle can be measured by a timer or an outputting GPIO signal. The relationship is:
dma_desc_num > polling_cycle / interrupt_interval
Determine the receiving buffer size. The receiving buffer offered by users in i2s_channel_read
should be able to take all the data in all DMA buffers, which means that it should be larger than the total size of all the DMA buffers:
recv_buffer_size > dma_desc_num * dma_buffer_size
For example, if there is an I2S application, and the known values are:
sample_rate = 144000 Hz
data_bit_width = 32 bits
slot_num = 2
polling_cycle = 10 ms
Then the parameters dma_frame_num
, dma_desc_num
, and recv_buf_size
can be calculated as follows:
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.
Parameters
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
Returns
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
Parameters
handle -- [in] I2S channel handler
clk_cfg -- [in] Standard mode clock configuration, can be generated by I2S_STD_CLK_DEFAULT_CONFIG
Returns
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
Parameters
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
.
Returns
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
Parameters
handle -- [in] I2S channel handler
gpio_cfg -- [in] Standard mode GPIO configuration, specified by user
Returns
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
- Parameters
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
- Parameters
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.
- Parameters
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
- Parameters
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.
- Parameters
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
- Returns
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
- Parameters
handle -- [in] I2S RX channel handler
clk_cfg -- [in] PDM RX mode clock configuration, can be generated by I2S_PDM_RX_CLK_DEFAULT_CONFIG
- Returns
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
- Parameters
handle -- [in] I2S RX channel handler
slot_cfg -- [in] PDM RX mode slot configuration, can be generated by I2S_PDM_RX_SLOT_DEFAULT_CONFIG
- Returns
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
- Parameters
handle -- [in] I2S RX channel handler
gpio_cfg -- [in] PDM RX mode GPIO configuration, specified by user
- Returns
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.
- Parameters
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
- Returns
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
- Parameters
handle -- [in] I2S TX channel handler
clk_cfg -- [in] PDM TX mode clock configuration, can be generated by I2S_PDM_TX_CLK_DEFAULT_CONFIG
- Returns
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
- Parameters
handle -- [in] I2S TX channel handler
slot_cfg -- [in] PDM TX mode slot configuration, can be generated by I2S_PDM_TX_SLOT_DEFAULT_CONFIG
- Returns
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
- Parameters
handle -- [in] I2S TX channel handler
gpio_cfg -- [in] PDM TX mode GPIO configuration, specified by user
- Returns
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
- Parameters
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.
- Parameters
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.
- Parameters
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.
- Parameters
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.
- Parameters
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)
- Returns
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
- Parameters
handle -- [in] I2S channel handler