Merge branch 'refactor/i2s_driver_rewrite' into 'master'

🔨 i2s: i2s driver-NG

Closes IDF-3714 and IDF-4592

See merge request espressif/esp-idf!15175
This commit is contained in:
Kevin (Lao Kaiyao)
2022-06-15 14:22:58 +08:00
114 changed files with 13307 additions and 2145 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

+47
View File
@@ -0,0 +1,47 @@
{
"head": {
"text": "PDM Timing Diagram"
},
"signal": [
{
"node": ".A.B.C..D.E.F.G.H."
},
{
"name": "CLK",
"wave": "10.1.x|.0.1.0.1.x"
},
{
"name": "DIN / DOUT",
"wave": "x2.2.x|.2.2.2.2.x",
"data": [
"LMSB",
"RMSB",
"LLSB",
"RLSB",
"LMSB",
"RMSB"
],
"node": "...L.M..O.P...R.S."
},
{
"node": ".I..........J"
}
],
"edge": [
"A<->B left",
"B<->C right",
"D<->E left",
"E<->F right",
"F<->G left",
"G<->H right",
"I<->J left slot & right slot",
"A-I",
"B-L",
"C-M",
"D-O",
"E-P",
"F-J",
"G-R",
"H-S"
]
}
+52
View File
@@ -0,0 +1,52 @@
{
"head": {
"text": "Standard MSB Timing Diagram"
},
"signal": [
{
"node": "..C.....D",
"phase": 0.65
},
{
"node": "..A...B",
"phase": 0.65
},
{
"name": "BCLK",
"wave": "p..pd.pd.pd.pd"
},
{
"name": "WS",
"wave": "xx0.d0.d1.u1u10",
"node": ".H.....I......J",
"phase": 0.65
},
{
"name": "DIN / DOUT",
"wave": "xx2x|2x|2x|2x|2",
"data": [
"MSB",
"LSB",
"MSB",
"LSB",
"MSB"
],
"node": "......K",
"phase": 0.65
},
{
"node": "..E.....F.....G",
"phase": 0.65
}
],
"edge": [
"C<->D slot_bit_width",
"A<->B data_bit_width",
"E<->F Left Slot",
"F<->G Right Slot",
"E-C",
"K-B",
"F-D",
"J-G"
]
}
+54
View File
@@ -0,0 +1,54 @@
{
"head": {
"text": "Standard PCM Timing Diagram"
},
"signal": [
{
"node": "...C.....D",
"phase": 0.65
},
{
"node": "...A...B",
"phase": 0.65
},
{
"name": "BCLK",
"wave": "p..dp.dp.dp.dp."
},
{
"name": "WS",
"wave": "x10d0.d10d0.d10",
"node": "..P",
"phase": 0.65
},
{
"name": "DIN / DOUT",
"wave": "xx.2x|2x|2x|2x|2",
"data": [
"MSB",
"LSB",
"MSB",
"LSB",
"MSB"
],
"node": ".......K.......L",
"phase": 0.65
},
{
"node": "..ME.....F.....G",
"phase": 0.65
}
],
"edge": [
"C<->D slot_bit_width",
"A<->B data_bit_width",
"M<->E bit shift",
"E<->F Left Slot",
"F<->G Right Slot",
"P-M",
"E-C",
"K-B",
"F-D",
"G-L"
]
}
+54
View File
@@ -0,0 +1,54 @@
{
"head": {
"text": "Standard Philip Timing Diagram"
},
"signal": [
{
"node": "...C.....D",
"phase": 0.65
},
{
"node": "...A...B",
"phase": 0.65
},
{
"name": "BCLK",
"wave": "p..dp.dp.dp.dp."
},
{
"name": "WS",
"wave": "xx0.d0.d1.u1u10.",
"node": "..P",
"phase": 0.65
},
{
"name": "DIN / DOUT",
"wave": "xx.2x|2x|2x|2x|2",
"data": [
"MSB",
"LSB",
"MSB",
"LSB",
"MSB"
],
"node": ".......K.......L",
"phase": 0.65
},
{
"node": "..ME.....F.....G",
"phase": 0.65
}
],
"edge": [
"C<->D slot_bit_width",
"A<->B data_bit_width",
"M<->E bit shift",
"E<->F Left Slot",
"F<->G Right Slot",
"P-M",
"E-C",
"K-B",
"F-D",
"L-G"
]
}
+60
View File
@@ -0,0 +1,60 @@
{
"head": {
"text": "TDM MSB Timing Diagram"
},
"signal": [
{
"node": ".E.........F.........G",
"phase": -0.35
},
{
"name": "BCLK",
"wave": "p..d.p.d.pd.pd.p.d.pd.p"
},
{
"name": "WS",
"wave": "x0dd0.dd0dd1uu1.uu1uu0",
"node": ".H...................R",
"phase": -0.35
},
{
"name": "DIN / DOUT",
"wave": "x2x|22x|2x|2x|22x|2x|2",
"data": [
"MSB",
"LSB",
"MSB",
"LSB",
"MSB",
"LSB",
"MSB",
"LSB",
"MSB"
],
"node": ".H...K...I.M...N...P.Q",
"phase": -0.35
},
{
"node": ".A...B...C.D...J...L.S",
"phase": -0.35
}
],
"edge": [
"E<->F Left Slots",
"F<->G Right Slots",
"A<->B Slot 1",
"B<->C Slot 2",
"C<->D ...",
"D<->J Slot n",
"J<->L Slot n+1",
"L<->S ...",
"A-E",
"K-B",
"C-I",
"D-F",
"J-N",
"L-P",
"Q-G",
"S-R"
]
}
+57
View File
@@ -0,0 +1,57 @@
{
"head": {
"text": "TDM PCM (long) Timing Diagram"
},
"signal": [
{
"node": ".T...L",
"phase": -0.35
},
{
"node": ".UE.........G",
"phase": -0.35
},
{
"name": "BCLK",
"wave": "p..d.p.d.pd.pd"
},
{
"name": "WS",
"wave": "01u.10d...01u.",
"node": ".NH",
"phase": -0.35
},
{
"name": "DIN / DOUT",
"wave": "xx2x|2x|2x|22x",
"data": [
"MSB",
"LSB",
"MSB",
"LSB",
"MSB"
],
"node": "..H..FK.I...M",
"phase": -0.35
},
{
"node": "..A...B.C...D...J",
"phase": -0.35
}
],
"edge": [
"T<->L one slot pulse",
"U<->E bit shift",
"E<->G Frame",
"A<->B Slot 1",
"B<->C ...",
"C<->D Slot n",
"T-N",
"A-E",
"K-B",
"C-I",
"D-M",
"D-G",
"L-F"
]
}
+52
View File
@@ -0,0 +1,52 @@
{
"head": {
"text": "TDM PCM (short) Timing Diagram"
},
"signal": [
{
"node": ".TE.........G",
"phase": -0.35
},
{
"name": "BCLK",
"wave": "p..d.p.d.pd.pd"
},
{
"name": "WS",
"wave": "010d......010d",
"node": ".NH",
"phase": -0.35
},
{
"name": "DIN / DOUT",
"wave": "xx2x|2x|2x|22x",
"data": [
"MSB",
"LSB",
"MSB",
"LSB",
"MSB"
],
"node": "..H..FK.I...M",
"phase": -0.35
},
{
"node": ".UA...B.C...D...J",
"phase": -0.35
}
],
"edge": [
"T<->E pulse",
"E<->G Frame",
"U<->A bit shift",
"A<->B Slot 1",
"B<->C ...",
"C<->D Slot n",
"T-U",
"A-E",
"K-B",
"C-I",
"D-M",
"D-G"
]
}
+62
View File
@@ -0,0 +1,62 @@
{
"head": {
"text": "TDM Philip Timing Diagram"
},
"signal": [
{
"node": "..E.........F.........G",
"phase": -0.35
},
{
"name": "BCLK",
"wave": "p..d.p.d.pd.pd.p.d.pd.p"
},
{
"name": "WS",
"wave": "x0dd0.dd0dd1uu1.uu1uu0.",
"node": ".TH...................R",
"phase": -0.35
},
{
"name": "DIN / DOUT",
"wave": "xx2x|22x|2x|2x|22x|2x|2",
"data": [
"MSB",
"LSB",
"MSB",
"LSB",
"MSB",
"LSB",
"MSB",
"LSB",
"MSB"
],
"node": "..H...K...I.M...N...P.Q",
"phase": -0.35
},
{
"node": ".UA...B...C.D...J...L.S",
"phase": -0.35
}
],
"edge": [
"E<->F Left Slots",
"F<->G Right Slots",
"U<->A bit shift",
"A<->B Slot 1",
"B<->C Slot 2",
"C<->D ...",
"D<->J Slot n",
"J<->L Slot n+1",
"L<->S ...",
"A-E",
"K-B",
"C-I",
"D-F",
"J-N",
"L-P",
"Q-G",
"S-R",
"T-U"
]
}
-2
View File
@@ -67,7 +67,6 @@ INPUT = \
$(PROJECT_PATH)/components/driver/include/driver/gpio.h \
$(PROJECT_PATH)/components/driver/include/driver/gptimer.h \
$(PROJECT_PATH)/components/driver/include/driver/i2c.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s.h \
$(PROJECT_PATH)/components/driver/include/driver/ledc.h \
$(PROJECT_PATH)/components/driver/include/driver/rtc_io.h \
$(PROJECT_PATH)/components/driver/include/driver/sdio_slave.h \
@@ -156,7 +155,6 @@ INPUT = \
$(PROJECT_PATH)/components/hal/include/hal/esp_flash_err.h \
$(PROJECT_PATH)/components/hal/include/hal/gpio_types.h \
$(PROJECT_PATH)/components/hal/include/hal/i2c_types.h \
$(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \
$(PROJECT_PATH)/components/hal/include/hal/lcd_types.h \
$(PROJECT_PATH)/components/hal/include/hal/ledc_types.h \
$(PROJECT_PATH)/components/hal/include/hal/rtc_io_types.h \
+5
View File
@@ -1,6 +1,10 @@
INPUT += \
$(PROJECT_PATH)/components/driver/$(IDF_TARGET)/include/driver/dac.h \
$(PROJECT_PATH)/components/driver/$(IDF_TARGET)/include/driver/touch_sensor.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_common.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_pdm.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_std.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_types.h \
$(PROJECT_PATH)/components/driver/include/driver/mcpwm.h \
$(PROJECT_PATH)/components/driver/include/driver/pulse_cnt.h \
$(PROJECT_PATH)/components/driver/include/driver/rmt_common.h \
@@ -11,6 +15,7 @@ INPUT += \
$(PROJECT_PATH)/components/esp_hw_support/include/esp_himem.h \
$(PROJECT_PATH)/components/esp_system/include/esp_ipc.h \
$(PROJECT_PATH)/components/esp_system/include/esp_ipc_isr.h \
$(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \
$(PROJECT_PATH)/components/hal/include/hal/mcpwm_types.h \
$(PROJECT_PATH)/components/hal/include/hal/pcnt_types.h \
$(PROJECT_PATH)/components/hal/include/hal/rmt_types.h \
+6
View File
@@ -1,4 +1,9 @@
INPUT += \
$(PROJECT_PATH)/components/driver/include/driver/i2s_common.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_pdm.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_std.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_tdm.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_types.h \
$(PROJECT_PATH)/components/driver/include/driver/rmt_common.h \
$(PROJECT_PATH)/components/driver/include/driver/rmt_encoder.h \
$(PROJECT_PATH)/components/driver/include/driver/rmt_rx.h \
@@ -7,4 +12,5 @@ INPUT += \
$(PROJECT_PATH)/components/driver/include/driver/temperature_sensor.h \
$(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32c3/esp_ds.h \
$(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32c3/esp_hmac.h \
$(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \
$(PROJECT_PATH)/components/hal/include/hal/rmt_types.h \
+5
View File
@@ -1,4 +1,8 @@
INPUT += \
$(PROJECT_PATH)/components/driver/include/driver/i2s_common.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_pdm.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_std.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_types.h \
$(PROJECT_PATH)/components/driver/include/driver/rmt_common.h \
$(PROJECT_PATH)/components/driver/include/driver/rmt_encoder.h \
$(PROJECT_PATH)/components/driver/include/driver/rmt_rx.h \
@@ -7,4 +11,5 @@ INPUT += \
$(PROJECT_PATH)/components/driver/include/driver/temperature_sensor.h \
$(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32h2/esp_ds.h \
$(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32h2/esp_hmac.h \
$(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \
$(PROJECT_PATH)/components/hal/include/hal/rmt_types.h \
+4
View File
@@ -2,6 +2,9 @@ INPUT += \
$(PROJECT_PATH)/components/driver/$(IDF_TARGET)/include/driver/dac.h \
$(PROJECT_PATH)/components/driver/$(IDF_TARGET)/include/driver/touch_sensor.h \
$(PROJECT_PATH)/components/driver/include/driver/pulse_cnt.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_common.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_std.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_types.h \
$(PROJECT_PATH)/components/driver/include/driver/rmt_common.h \
$(PROJECT_PATH)/components/driver/include/driver/rmt_encoder.h \
$(PROJECT_PATH)/components/driver/include/driver/rmt_rx.h \
@@ -10,6 +13,7 @@ INPUT += \
$(PROJECT_PATH)/components/driver/include/driver/temperature_sensor.h \
$(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32s2/esp_ds.h \
$(PROJECT_PATH)/components/esp_hw_support/include/soc/esp32s2/esp_hmac.h \
$(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \
$(PROJECT_PATH)/components/hal/include/hal/pcnt_types.h \
$(PROJECT_PATH)/components/hal/include/hal/rmt_types.h \
$(PROJECT_PATH)/components/soc/$(IDF_TARGET)/include/soc/dac_channel.h \
+6
View File
@@ -1,5 +1,10 @@
INPUT += \
$(PROJECT_PATH)/components/driver/$(IDF_TARGET)/include/driver/touch_sensor.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_common.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_pdm.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_std.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_tdm.h \
$(PROJECT_PATH)/components/driver/include/driver/i2s_types.h \
$(PROJECT_PATH)/components/driver/include/driver/mcpwm.h \
$(PROJECT_PATH)/components/driver/include/driver/pulse_cnt.h \
$(PROJECT_PATH)/components/driver/include/driver/rmt_common.h \
@@ -12,6 +17,7 @@ INPUT += \
$(PROJECT_PATH)/components/esp_hw_support/include/soc/$(IDF_TARGET)/esp_hmac.h \
$(PROJECT_PATH)/components/esp_system/include/esp_ipc.h \
$(PROJECT_PATH)/components/esp_system/include/esp_ipc_isr.h \
$(PROJECT_PATH)/components/hal/include/hal/i2s_types.h \
$(PROJECT_PATH)/components/hal/include/hal/mcpwm_types.h \
$(PROJECT_PATH)/components/hal/include/hal/pcnt_types.h \
$(PROJECT_PATH)/components/hal/include/hal/rmt_types.h \
File diff suppressed because it is too large Load Diff
+65 -1
View File
@@ -254,4 +254,68 @@ LCD
Dedicated GPIO Driver
---------------------
- All of the dedicated GPIO related LL functionsn in ``cpu_ll.h`` have been moved to ``dedic_gpio_cpu_ll.h`` and renamed.
- All of the dedicated GPIO related LL functionsn in ``cpu_ll.h`` have been moved to ``dedic_gpio_cpu_ll.h`` and renamed.
.. only:: SOC_I2S_SUPPORTED
I2S driver
----------
{I2S_DRIVER_HEADERS:default=":component_file:`driver/include/driver/i2s_std.h`, :component_file:`driver/include/driver/i2s_pdm.h` or :component_file:`driver/include/driver/i2s_tdm.h`", esp32=":component_file:`driver/include/driver/i2s_std.h` or :component_file:`driver/include/driver/i2s_pdm.h`", esp32s2=":component_file:`driver/include/driver/i2s_std.h`"}
Shortcomings are exposed when supporting all the new features of ESP32-C3 & ESP32-S3 by the old I2S driver, so it is re-designed to make it more compatible and flexible to all the communication modes. New APIs are available by including corresponding mode header files {I2S_DRIVER_HEADERS}. Meanwhile, the old APIs in :component_file:`driver/deprecated/driver/i2s.h` are still supported for backward compatibility. But there will be warnings if you keep using the old APIs in your project, these warnings can be suppressed by the Kconfig option :ref:`CONFIG_I2S_SUPPRESS_DEPRECATE_WARN`. Here is the general overview of the current I2S files:
.. figure:: ../../_static/diagrams/i2s/i2s_file_structure.png
:align: center
:alt: I2S File Structure
Breaking changes in Concepts
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The minimum control unit in new I2S driver will be tx/rx channel instead of a whole I2S controller.
1. The tx/rx channel in a same I2S controller can be controlled separately, that means they will be initialized, started or stopped separately. Especially for ESP32-C3 and ESP32-S3, tx and rx channels in one controller can be configured to different clocks or modes now, they are able to work in a totally separate way which can help to save the resources of I2S controller. But for ESP32 and ESP32-S2, though their tx/rx can be controlled separately, some hardware resources are still shared by tx and rx, they might affect each other if they are configured to different configurations;
2. The channels can be registered to an available I2S controller automatically by setting :cpp:enumerator:`i2s_port_t::I2S_NUM_AUTO` as I2S port id. The driver will help you to search for the available tx/rx channel. Of cause, driver can still support to be installed by a specific port;
3. :c:type:`i2s_chan_handle_t` is the handle that used for identifying the I2S channels. All the APIs will require the channel handle, users need to maintain the channel handles by themselves;
4. In order to distinguish tx/rx channel and sound channel, now the word 'channel' is only stand for the tx/rx channel in new driver, meanwhile the sound channel will be called 'slot'.
- I2S communication modes are extracted into three modes.
1. **Standard mode**: Standard mode always has two slots, it can support Philip, MSB and PCM(short sync) format, please refer to :component_file:`driver/include/driver/i2s_std.h` for details;
2. **PDM mode**: PDM mode only support two slots with 16 bits data width, but the configurations of PDM TX and PDM RX are little bit different. For PDM TX, the sample rate can be set by :cpp:member:`i2s_pdm_tx_clk_config_t::sample_rate`, and its clock frequency is depended on the up-sampling configuration. For PDM RX, the sample rate can be set by :cpp:member:`i2s_pdm_rx_clk_config_t::sample_rate`, and its clock frequency is depended on the down-sampling configuration. Please refer to :component_file:`driver/include/driver/i2s_pdm.h` for details;
3. **TDM mode**: TDM mode can support upto 16 slots. It can work in Philip, MSB, PCM(short sync) and PCM(long sync) format, please refer to :component_file:`driver/include/driver/i2s_tdm.h` for details;
4. When allocating a new channel in a specific mode, must initialize this channel by corresponding function. It is strongly recommended to use the helper macros to generate the default configurations, in case the default values will be changed one day.
- States and state-machine are adopted in the new I2S driver to avoid APIs called in wrong state.
- The slot configurations and clock configurations can be configured separately.
1. Calling :cpp:func:`i2s_channel_init_std_mode`, :cpp:func:`i2s_channel_init_pdm_rx_mode`, :cpp:func:`i2s_channel_init_pdm_tx_mode` or :cpp:func:`i2s_channel_init_tdm_mode` to initialize the slot/clock/gpio_pin configurations;
2. Calling :cpp:func:`i2s_channel_reconfig_std_slot`, :cpp:func:`i2s_channel_reconfig_pdm_rx_slot`, :cpp:func:`i2s_channel_reconfig_pdm_tx_slot` or :cpp:func:`i2s_channel_reconfig_tdm_slot` can change the slot configurations after initialization;
3. Calling :cpp:func:`i2s_channel_reconfig_std_clock`, :cpp:func:`i2s_channel_reconfig_pdm_rx_clock`, :cpp:func:`i2s_channel_reconfig_pdm_tx_clock` or :cpp:func:`i2s_channel_reconfig_tdm_clock` can change the clock configurations after initialization;
4. Calling :cpp:func:`i2s_channel_reconfig_std_gpio`, :cpp:func:`i2s_channel_reconfig_pdm_rx_gpio`, :cpp:func:`i2s_channel_reconfig_pdm_tx_gpio` or :cpp:func:`i2s_channel_reconfig_tdm_gpio` can change the gpio configurations after initialization.
- ADC and DAC modes are removed. They will only be supported in their own driver and legacy I2S driver.
- :cpp:func:`i2s_channel_write` and :cpp:func:`i2s_channel_read` can be aborted by :cpp:func:`i2s_channel_abort_reading_writing` now.
Breaking Changes in Usage
~~~~~~~~~~~~~~~~~~~~~~~~~
To use the new I2S driver, please follow these steps:
1. Calling :cpp:func:`i2s_new_channel` to aquire the channel handles. We should specify the work role and I2S port in this step. Besides, the tx or rx channel handles will be generated by the driver. Inputting both two tx and rx handles is not necessary but at least one handle is needed. In the case of inputting both two handles, the driver will work at duplex mode, both tx and rx channel will be avaliable on a same port, and they will share the MCLK, BCLK and WS signal. But if only one of the tx or rx handle is inputted, this channel will only work in simplex mode.
2. Calling :func:`i2s_channel_init_std_mode`, :func:`i2s_channel_init_pdm_rx_mode`, :func:`i2s_channel_init_pdm_tx_mode` or :func:`i2s_channel_init_tdm_mode` to initialize the channel to the specified mode. Corresponding slot, clock and gpio configurations are needed in this step.
3. (Optional) Calling :cpp:func:`i2s_channel_register_event_callback` to register the ISR event callback functions. I2S events now can be received by the callback function synchronously, instead of from event queue asynchronously.
4. Calling :cpp:func:`i2s_channel_enable` to start the hardware of I2S channel. In the new driver, I2S won't start automatically after installed anymore, users are supposed to know clearly whether the channel has started or not.
5. Reading or writing data by :cpp:func:`i2s_channel_read` or :cpp:func:`i2s_channel_write`. Certainly, only rx channel handle is suppoesd to be inputted in :cpp:func:`i2s_channel_read` and tx channel handle in :cpp:func:`i2s_channel_write`.
6. (Optional) The slot, clock and gpio configurations can be changed by corresponding 'reconfig' functions, but :cpp:func:`i2s_channel_disable` must be called before updating the configurations.
7. Calling :cpp:func:`i2s_channel_disable` to stop the hardware of I2S channel.
8. Calling :cpp:func:`i2s_del_channel` to delete and release the resources of the channel if it is not needed any more, but the channel must be disabled before deleting it.