谈吐大方的薯片 · This New This, 2017, ...· 1 月前 · |
从容的炒面 · 在 Linux 上安裝 SQL ...· 1 月前 · |
玉树临风的长颈鹿 · Solved: No module ...· 2 月前 · |
阳刚的玉米 · 分享一些我诚通网盘里的资源!-CD包音乐网· 3 月前 · |
坏坏的投影仪 · 柚子猫刻晴视频完整版_柚子猫刻晴视频完整版. ...· 3 月前 · |
gpio num rx i2s |
https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/peripherals/i2s.html |
任性的鸡蛋
2 月前 |
I2S (Inter-IC Sound) is a synchronous serial communication protocol usually used for transmitting audio data between two digital audio devices.
ESP32 contains two I2S peripheral(s). These peripherals can be configured to input and output sample data via the I2S driver.
An I2S bus that communicates in standard or TDM mode consists of the following lines:
MCLK: Master clock line. It is an optional signal depending on the slave side, mainly used for offering a reference clock to the I2S slave device.
BCLK: Bit clock line. The bit clock for data line.
WS: Word (Slot) select line. It is usually used to identify the vocal tract except PDM mode.
DIN/DOUT: Serial data input/output line. Data will loopback internally if DIN and DOUT are set to a same GPIO.
An I2S bus that communicates in PDM mode consists of the following lines:
CLK: PDM clock line.
DIN/DOUT: Serial data input/output line.
Each I2S controller has the following features that can be configured by the I2S driver:
Operation as system master or slave
Capable of acting as transmitter or receiver
DMA controller that allows stream sampling of data without requiring the CPU to copy each data sample
Each controller supports single RX or TX simplex communication. As RX and TX channels share a clock, they can only be combined with the same configuration to establish a full-duplex communication.
Public headers that need to be included in the I2S application are as follows:
i2s.h
: The header file that provides legacy I2S APIs (for apps using legacy driver).
i2s_std.h
: The header file that provides standard communication mode specific APIs (for apps using new driver with standard mode).
i2s_pdm.h
: The header file that provides PDM communication mode specific APIs (for apps using new driver with PDM mode).
i2s_tdm.h
: The header file that provides TDM communication mode specific APIs (for apps using new driver with TDM mode).
The legacy driver cannot coexist with the new driver. Include
i2s.h
to use the legacy driver, or include the other three headers to use the new driver. The legacy driver might be removed in future.
Public headers that have been included in the headers above are as follows:
i2s_types_legacy.h
: The header file that provides legacy public types that are only used in the legacy driver.
i2s_types.h
: The header file that provides public types.
i2s_common.h
: The header file that provides common APIs for all communication modes.
i2s_clock_src_t::I2S_CLK_SRC_DEFAULT
: Default PLL clock.
i2s_clock_src_t::I2S_CLK_SRC_PLL_160M
: 160 MHz PLL clock.
i2s_clock_src_t::I2S_CLK_SRC_APLL
: Audio PLL clock, which is more precise than
I2S_CLK_SRC_PLL_160M
in high sample rate applications. Its frequency is configurable according to the sample rate. However, if APLL has been occupied by EMAC or other channels, the APLL frequency cannot be changed, and the driver will try to work under this APLL frequency. If this frequency cannot meet the requirements of I2S, the clock configuration will fail.
Sample rate : The number of sampled data in one second per slot.
SCLK : Source clock frequency. It is the frequency of the clock source.
MCLK : Master clock frequency. BCLK is generated from this clock. The MCLK signal usually serves as a reference clock and is mostly needed to synchronize BCLK and WS between I2S master and slave roles.
BCLK
: Bit clock frequency. Every tick of this clock stands for one data bit on data pin. The slot bit width configured in
i2s_std_slot_config_t::slot_bit_width
is equal to the number of BCLK ticks, which means there will be 8/16/24/32 BCLK ticks in one slot.
LRCK / WS : Left/right clock or word select clock. For non-PDM mode, its frequency is equal to the sample rate.
Normally, MCLK should be the multiple of
sample
rate
and BCLK at the same time. The field
i2s_std_clk_config_t::mclk_multiple
indicates the multiple of MCLK to the
sample
rate
. In most cases,
I2S_MCLK_MULTIPLE_256
should be enough. However, if
slot_bit_width
is set to
I2S_SLOT_BIT_WIDTH_24BIT
, to keep MCLK a multiple to the BCLK,
i2s_std_clk_config_t::mclk_multiple
should be set to multiples that are divisible by 3 such as
I2S_MCLK_MULTIPLE_384
. Otherwise, WS will be inaccurate.
In standard mode, there are always two sound channels, i.e., the left and right channels, which are called "slots". These slots support 8/16/24/32-bit width sample data. The communication format for the slots mainly includes the followings:
Philips Format : Data signal has one-bit shift comparing to the WS signal, and the duty of WS signal is 50%.
PDM (Pulse-density Modulation) mode for the TX channel can convert PCM data into PDM format which always has left and right slots. PDM TX is only supported on I2S0 and it only supports 16-bit width sample data. It needs at least a CLK pin for clock signal and a DOUT pin for data signal (i.e., the WS and SD signal in the following figure; the BCK signal is an internal bit sampling clock, which is not needed between PDM devices). This mode allows users to configure the up-sampling parameters
i2s_pdm_tx_clk_config_t::up_sample_fp
and
i2s_pdm_tx_clk_config_t::up_sample_fs
. The up-sampling rate can be calculated by
up_sample_rate
=
i2s_pdm_tx_clk_config_t::up_sample_fp
/
i2s_pdm_tx_clk_config_t::up_sample_fs
. There are two up-sampling modes in PDM TX:
Fixed Clock Frequency
: In this mode, the up-sampling rate changes according to the sample rate. Setting
fp
=
960
and
fs
=
sample_rate
/
100
, then the clock frequency (Fpdm) on CLK pin will be fixed to
128
*
48
KHz
=
6.144
MHz
. Note that this frequency is not equal to the sample rate (Fpcm).
Fixed Up-sampling Rate
: In this mode, the up-sampling rate is fixed to 2. Setting
fp
=
960
and
fs
=
480
, then the clock frequency (Fpdm) on CLK pin will be
128
*
sample_rate
.
PDM (Pulse-density Modulation) mode for RX channel can receive PDM-format data and convert the data into PCM format. PDM RX is only supported on I2S0, and it only supports 16-bit width sample data. PDM RX needs at least a CLK pin for clock signal and a DIN pin for data signal. This mode allows users to configure the down-sampling parameter
i2s_pdm_rx_clk_config_t::dn_sample_mode
. There are two down-sampling modes in PDM RX:
i2s_pdm_dsr_t::I2S_PDM_DSR_8S
: In this mode, the clock frequency (Fpdm) on the WS pin is
sample_rate
(Fpcm)
*
64
.
i2s_pdm_dsr_t::I2S_PDM_DSR_16S
: In this mode, the clock frequency (Fpdm) on the WS pin is
sample_rate
(Fpcm)
*
128
.
LCD/Camera mode is only supported on I2S0 over a parallel bus. For LCD mode, I2S0 should work at master TX mode. For camera mode, I2S0 should work at slave RX mode. These two modes are not implemented by the I2S driver. Please refer to LCD for details about the LCD implementation. For more information, see ESP32 Technical Reference Manual > I2S Controller (I2S) > LCD Mode [ PDF ].
ADC and DAC modes only exist on ESP32 and are only supported on I2S0. Actually, they are two sub-modes of LCD/Camera mode. I2S0 can be routed directly to the internal analog-to-digital converter (ADC) and digital-to-analog converter (DAC). In other words, ADC and DAC peripherals can read or write continuously via I2S0 DMA. As they are not actual communication modes, the I2S driver does not implement them.
The I2S driver offers the following services:
There are three levels of resources in the I2S driver:
platform
level
: Resources of all I2S controllers in the current target.
controller
level
: Resources in one I2S controller.
channel
level
: Resources of TX or RX channel in one I2S controller.
The public APIs are all channel-level APIs. The channel handle
i2s_chan_handle_t
can help users to manage the resources under a specific channel without considering the other two levels. The other two upper levels' resources are private and are managed by the driver automatically. Users can call
i2s_new_channel()
to allocate a channel handle and call
i2s_del_channel()
to delete it.
When the power management is enabled (i.e., CONFIG_PM_ENABLE is on), the system will adjust or stop the source clock of I2S before entering Light-sleep, thus potentially changing the I2S signals and leading to transmitting or receiving invalid data.
The I2S driver can prevent the system from changing or stopping the source clock by acquiring a power management lock. When the source clock is generated from APB, the lock type will be set to
esp_pm_lock_type_t::ESP_PM_APB_FREQ_MAX
and when the source clock is APLL (if supported), it will be set to
esp_pm_lock_type_t::ESP_PM_NO_LIGHT_SLEEP
. Whenever the user is reading or writing via I2S (i.e., calling
i2s_channel_read()
or
i2s_channel_write()
), the driver guarantees that the power management lock is acquired. Likewise, the driver releases the lock after the reading or writing finishes.
There are three states for an I2S channel, namely,
registered
,
ready
, and
running
. Their relationship is shown in the following diagram:
The
<mode>
in the diagram can be replaced by corresponding I2S communication modes, e.g.,
std
for standard two-slot mode. For more information about communication modes, please refer to the
I2S Communication Mode
section.
The data transport of the I2S peripheral, including sending and receiving, is realized by DMA. Before transporting data, please call
i2s_channel_enable()
to enable the specific channel. When the sent or received data reaches the size of one DMA buffer, the
I2S_OUT_EOF
or
I2S_IN_SUC_EOF
interrupt will be triggered. Note that the DMA buffer size is not equal to
i2s_chan_config_t::dma_frame_num
. One frame here refers to all the sampled data in one WS circle. Therefore,
dma_buffer_size
=
dma_frame_num
*
slot_num
*
slot_bit_width
/
8
. For the data transmitting, users can input the data by calling
i2s_channel_write()
. This function helps users to copy the data from the source buffer to the DMA TX buffer and wait for the transmission to finish. Then it will repeat until the sent bytes reach the given size. For the data receiving, the function
i2s_channel_read()
waits to receive the message queue which contains the DMA buffer address. It helps users copy the data from the DMA RX buffer to the destination buffer.
Both
i2s_channel_write()
and
i2s_channel_read()
are blocking functions. They keeps waiting until the whole source buffer is sent or the whole destination buffer is loaded, unless they exceed the max blocking time, where the error code
ESP_ERR_TIMEOUT
returns. To send or receive data asynchronously, callbacks can be registered by
i2s_channel_register_event_callback()
. Users are able to access the DMA buffer directly in the callback function instead of transmitting or receiving by the two blocking functions. However, please be aware that it is an interrupt callback, so do not add complex logic, run floating operation, or call non-reentrant functions in the callback.
Users can initialize a channel by calling corresponding functions (i.e.,
i2s_channel_init_std_mode()
,
i2s_channel_init_pdm_rx_mode()
,
i2s_channel_init_pdm_tx_mode()
, or
i2s_channel_init_tdm_mode()
) to a specific mode. If the configurations need to be updated after initialization, users have to first call
i2s_channel_disable()
to ensure that the channel has stopped, and then call corresponding
reconfig
functions, like
i2s_channel_reconfig_std_slot()
,
i2s_channel_reconfig_std_clock()
, and
i2s_channel_reconfig_std_gpio()
.
By default, the I2S interrupt will be deferred when the cache is disabled for reasons like writing/erasing flash. Thus the EOF interrupt will not get executed in time.
To avoid such case in real-time applications, you can enable the Kconfig option CONFIG_I2S_ISR_IRAM_SAFE that:
Keeps the interrupt being serviced even when the cache is disabled.
Places driver object into DRAM (in case it is linked to PSRAM by accident).
This allows the interrupt to run while the cache is disabled, but comes at the cost of increased IRAM consumption.
All the public I2S APIs are guaranteed to be thread safe by the driver, which means users can call them from different RTOS tasks without protection by extra locks. Notice that the I2S driver uses mutex lock to ensure the thread safety, thus these APIs are not allowed to be used in ISR.
CONFIG_I2S_ISR_IRAM_SAFE controls whether the default ISR handler can work when the cache is disabled. See IRAM Safe for more information.
CONFIG_I2S_SUPPRESS_DEPRECATE_WARN controls whether to suppress the compiling warning message while using the legacy I2S driver.
CONFIG_I2S_ENABLE_DEBUG_LOG is used to enable the debug log output. Enable this option increases the firmware binary size.
The examples of the I2S driver can be found in the directory peripherals/i2s . Here are some simple usages of each mode:
Different slot communication formats can be generated by the following helper macros for standard mode. As described above, there are three formats in standard mode, and their helper macros are:
The clock config helper macro is:
Please refer to Standard Mode for information about STD API. And for more details, please refer to driver/i2s/include/driver/i2s_std.h .
Take 16-bit data width for example. When the data in a
uint16_t
writing buffer are:
It is similar when the data is 32-bit width, but take care when using 8-bit and 24-bit data width. For 8-bit width, the written buffer should still use
uint16_t
(i.e., align with 2 bytes), and only the high 8 bits are valid while the low 8 bits are dropped. For 24-bit width, the buffer is supposed to use
uint32_t
(i.e., align with 4 bytes), and only the high 24 bits are valid while the low 8 bits are dropped.
Besides, for 8-bit and 16-bit mono modes, the real data on the line is swapped. To get the correct data sequence, the writing buffer needs to swap the data every two bytes.
#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:
The clock configuration helper macro is:
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:
The clock configuration helper macro is:
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
ESP_OK Delete successfully
ESP_ERR_INVALID_ARG NULL pointer
esp_err_t i2s_channel_get_info(i2s_chan_handle_t handle, i2s_chan_info_t *chan_info)
Get I2S channel information.
- Parameters
handle -- [in] I2S channel handler
chan_info -- [out] I2S channel basic information
- Returns
ESP_OK Get I2S channel information success
ESP_ERR_NOT_FOUND The input handle doesn't match any registered I2S channels, it may not an I2S channel handle or not available any more
ESP_ERR_INVALID_ARG The input handle or chan_info pointer is NULL
Only allowed to be called when the channel state is READY, (i.e., channel has been initialized, but not started) the channel will enter RUNNING state once it is enabled successfully.
Enable the channel can start the I2S communication on hardware. It will start outputting BCLK and WS signal. For MCLK signal, it will start to output when initialization is finished
- Parameters
handle -- [in] I2S channel handler
ESP_OK Start successfully
ESP_ERR_INVALID_ARG NULL pointer
ESP_ERR_INVALID_STATE This channel has not initialized or already started
Only allowed to be called when the channel state is RUNNING, (i.e., channel has been started) the channel will enter READY state once it is disabled successfully.
Disable the channel can stop the I2S communication on hardware. It will stop BCLK and WS signal but not MCLK signal
- Parameters
handle -- [in] I2S channel handler
- Returns
ESP_OK Stop successfully
ESP_ERR_INVALID_ARG NULL pointer
ESP_ERR_INVALID_STATE This channel has not stated
esp_err_t i2s_channel_preload_data(i2s_chan_handle_t tx_handle, const void *src, size_t size, size_t *bytes_loaded)
Preload the data into TX DMA buffer.
Only allowed to be called when the channel state is READY, (i.e., channel has been initialized, but not started)
As the initial DMA buffer has no data inside, it will transmit the empty buffer after enabled the channel, this function is used to preload the data into the DMA buffer, so that the valid data can be transmitted immediately after the channel is enabled.
This function can be called multiple times before enabling the channel, the buffer that loaded later will be concatenated behind the former loaded buffer. But when all the DMA buffers have been loaded, no more data can be preload then, please check the bytes_loaded
parameter to see how many bytes are loaded successfully, when the bytes_loaded
is smaller than the size
, it means the DMA buffers are full.
- Parameters
tx_handle -- [in] I2S TX channel handler
src -- [in] The pointer of the source buffer to be loaded
size -- [in] The source buffer size
bytes_loaded -- [out] The bytes that successfully been loaded into the TX DMA buffer
- Returns
ESP_OK Load data successful
ESP_ERR_INVALID_ARG NULL pointer or not TX direction
ESP_ERR_INVALID_STATE This channel has not stated
esp_err_t i2s_channel_write(i2s_chan_handle_t handle, const void *src, size_t size, size_t *bytes_written, uint32_t timeout_ms)
I2S write data.
Only allowed to be called when the channel state is RUNNING, (i.e., TX channel has been started and is not writing now) but the RUNNING only stands for the software state, it doesn't mean there is no the signal transporting on line.
- Parameters
handle -- [in] I2S channel handler
src -- [in] The pointer of sent data buffer
size -- [in] Max data buffer length
bytes_written -- [out] Byte number that actually be sent, can be NULL if not needed
timeout_ms -- [in] Max block time
- Returns
ESP_OK Write successfully
ESP_ERR_INVALID_ARG NULL pointer or this handle is not TX handle
ESP_ERR_TIMEOUT Writing timeout, no writing event received from ISR within ticks_to_wait
ESP_ERR_INVALID_STATE I2S is not ready to write
esp_err_t i2s_channel_read(i2s_chan_handle_t handle, void *dest, size_t size, size_t *bytes_read, uint32_t timeout_ms)
I2S read data.
Only allowed to be called when the channel state is RUNNING but the RUNNING only stands for the software state, it doesn't mean there is no the signal transporting on line.
- Parameters
handle -- [in] I2S channel handler
dest -- [in] The pointer of receiving data buffer
size -- [in] Max data buffer length
bytes_read -- [out] Byte number that actually be read, can be NULL if not needed
timeout_ms -- [in] Max block time
- Returns
ESP_OK Read successfully
ESP_ERR_INVALID_ARG NULL pointer or this handle is not RX handle
ESP_ERR_TIMEOUT Reading timeout, no reading event received from ISR within ticks_to_wait
ESP_ERR_INVALID_STATE I2S is not ready to read
esp_err_t i2s_channel_register_event_callback(i2s_chan_handle_t handle, const i2s_event_callbacks_t *callbacks, void *user_data)
Set event callbacks for I2S channel.
Only allowed to be called when the channel state is REGISTERED / READY, (i.e., before channel starts)
User can deregister a previously registered callback by calling this function and setting the callback member in the callbacks
structure to NULL.
When CONFIG_I2S_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. The variables used in the function should be in the SRAM as well. The user_data
should also reside in SRAM or internal RAM as well.
- Parameters
handle -- [in] I2S channel handler
callbacks -- [in] Group of callback functions
user_data -- [in] User data, which will be passed to callback functions directly
- Returns
ESP_OK Set event callbacks successfully
ESP_ERR_INVALID_ARG Set event callbacks failed because of invalid argument
ESP_ERR_INVALID_STATE Set event callbacks failed because the current channel state is not REGISTERED or READY
When CONFIG_I2S_ISR_IRAM_SAFE is enabled, the callback itself and functions called by it should be placed in IRAM. The variables used in the function should be in the SRAM as well.
Public Members
i2s_isr_callback_t on_recv
Callback of data received event, only for RX channel The event data includes DMA buffer address and size that just finished receiving data
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
typedef bool (*i2s_isr_callback_t)(i2s_chan_handle_t handle, i2s_event_data_t *event, void *user_ctx)
I2S event callback.
- Param handle
[in] I2S channel handle, created from i2s_new_channel()
- Param event
[in] I2S event data
- Param user_ctx
[in] User registered context, passed from i2s_channel_register_event_callback()
- Return
Whether a high priority task has been waken up by this callback function
enum i2s_port_t
I2S controller port number, the max port number is (SOC_I2S_NUM -1).
Values:
enumerator I2S_NUM_0
I2S controller port 0
It has different meanings in tx/rx/mono/stereo mode, and it may have differen behaviors on different targets For the details, please refer to the I2S API reference
Values:
enumerator I2S_STD_SLOT_LEFT
I2S transmits or receives left slot
阳刚的玉米 · 分享一些我诚通网盘里的资源!-CD包音乐网 3 月前 |