Merge branch 'feat/i2s_duplex_update_v5.5' into 'release/v5.5'

feat(i2s): allow full duplex mode in less strict condition (v5.5)

See merge request espressif/esp-idf!50867
This commit is contained in:
morris
2026-07-18 15:57:50 +08:00
10 changed files with 395 additions and 127 deletions

View File

@@ -920,6 +920,10 @@ Full-duplex mode registers TX and RX channel in an I2S port at the same time, an
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.
.. note::
In full-duplex mode, only one channel can work as the master that generates BCLK and WS. If both paired handles are configured as ``I2S_ROLE_MASTER``, the handle initialized later is automatically switched to ``I2S_ROLE_SLAVE``.
There are two methods to allocate a pair of full-duplex channels:
1. Allocate both TX and RX handles in a single call of :cpp:func:`i2s_new_channel`.
@@ -937,7 +941,7 @@ There are two methods to allocate a pair of full-duplex channels:
/* 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 */
/* Set the configurations for both channels. BCLK/WS and frame timing must match 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),
@@ -962,7 +966,7 @@ There are two methods to allocate a pair of full-duplex channels:
...
2. Allocate TX and RX handles separately, and initialize them with the same configuration.
2. Allocate TX and RX handles separately, and initialize them with compatible configurations.
.. code-block:: c
@@ -977,7 +981,7 @@ There are two methods to allocate a pair of full-duplex channels:
/* Allocate for TX and RX channel separately, they are not full-duplex yet */
ESP_ERROR_CHECK(i2s_new_channel(&chan_cfg, &tx_handle, NULL));
/* Set the configurations for BOTH TWO channels, they will constitute in full-duplex mode automatically */
/* Set compatible configurations for both channels, then they will constitute in full-duplex mode automatically */
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),
@@ -1003,6 +1007,15 @@ There are two methods to allocate a pair of full-duplex channels:
...
.. only:: SOC_I2S_HW_VERSION_2
When the TX and RX channels are allocated separately (the second method above), they do not have to be configured exactly the same to constitute full-duplex. The driver lets them share the BCLK and WS lines as long as:
- both channels use the same valid ``bclk`` and ``ws`` pins;
- both channels use the same BCLK/WS inversion settings;
- both channels produce the same frame timing, i.e. the same ``sample_rate_hz`` and the same total bits per frame (``total_slot * slot_bit_width``).
The clock source, external clock frequency (``ext_clk_freq_hz``), and MCLK-related configuration, including the ``mclk`` pin, ``mclk_multiple``, and MCLK inversion setting, are not used as conditions for constituting full-duplex. The slot layout itself may also differ. For example, an STD channel and a TDM channel, or a 2-slot/32-bit channel paired with a 4-slot/16-bit channel, can still constitute full-duplex because the number of bits per frame is the same. Once a pair of full-duplex channels is established, the paired channel handle can be retrieved from :cpp:type:`i2s_chan_info_t`::pair_chan returned by :cpp:func:`i2s_channel_get_info`.
.. only:: SOC_I2S_HW_VERSION_1