Restarting an I2S DMA read

User avatar
kolban
Posts: 1683
Joined: Mon Nov 16, 2015 4:43 pm
Location: Texas, USA

Restarting an I2S DMA read

Postby kolban » Mon May 28, 2018 7:32 pm

Advanced question
-----------------------

I am studying I2S and DMA. Specifically, the notion of reading incoming data. I have managed to read data into RAM through I2S/DMA however if I want to "restart/reset" the environment such that it will read a second chunk of data, I am stuck. I have written a test harness that allows me to dump the status of the registers after having read the data. Here is a log. The names are the ones used in the Technical Reference Manual and exposed as structure symbols.

Code: Select all

Status
conf
I2S_RX_SLAVE_MOD    : 1
I2S_RX_MSB_RIGHT    : 0
I2S_RX_RIGHT_FIRST  : 0
I2S_RX_START        : 1
I2S_RX_RESET        : 0
-----
conf_chan
I2S_RX_CHAN_MOD     : 1
-----
fifo_conf (I2S_FIFO_CONF_REG)
I2S_RX_FIFO_MOD_FORCE_EN  : 1
I2S_RX_FIFO_MOD           : 2
I2S_RX_DSCR_EN            : 1
I2S_RX_DATA_NUM           : 32
-----
conf2
I2S_CAMERA_EN       : 1
I2S_LCD_EN          : 1
-----
rx_eof_num (I2S_RXEOF_NUM_REG)
I2S_RXEOF_NUM_REG   : 8
-----
in_eof_des_addr (I2S_IN_EOF_DES_ADDR_REG)
I2S_IN_EOF_DES_ADDR_REG: 0x3ffb2590
-----
in_link_dscr (I2S_INLINK_DSCR_REG)
I2S_INLINK_DSCR_REG : 0x0
-----
in_link_dscr_bf0 (I2S_INLINK_DSCR_BF0_REG)
I2S_INLINK_DSCR_BF0_REG: 0x0
-----
in_link_dscr_bf1 (I2S_INLINK_DSCR_BF1_REG)
I2S_INLINK_DSCR_BF1_REG: 0xbffb2a24
-----
int_raw
I2S_IN_DSCR_EMPTY_INT_RAW: 0
I2S_IN_DSCR_ERR_INT_RAW  : 0
I2S_IN_SUC_EOF_INT_RAW   : 1
I2S_IN_ERR_EOF_INT_RAW   : 0
I2S_IN_DONE_INT_RAW      : 1
I2S_RX_HUNG_INT_RAW      : 0
I2S_RX_REMPTY_INT_RAW    : 1
I2S_RX_WFULL_INT_RAW     : 1
I2S_RX_TAKE_DATA_INT_RAW : 1
-----
in_link
I2S_INLINK_PARK     : 0
I2S_INLINK_RESTART  : 0
I2S_INLINK_START    : 0
I2S_INLINK_STOP     : 0
I2S_INLINK_ADDR     : 0xb2590
-----
lldesc 1: 0x3ffb2590
length              : 32
size                : 1024
&buf                : 0x3ffb2a24
Notice that the interrupt flags indicate a previously read descriptor and that the buffer is flagged as full. I then tried to reset the environment by resetting the descriptor in the linked list, resetting flags in the registers and a variety of other techniques but was unable to start receiving more data.

The core question thus boils down to:

What recipe or process should I attempt to follow to perform a reset of the DMA, FIFO, linked list or other flags to achieve a reset and start reading a new chunk of incoming data?

I have tried many different options but am guessing as to their correctness and sequence.
Free book on ESP32 available here: https://leanpub.com/kolban-ESP32

fdibac
Posts: 4
Joined: Fri Apr 17, 2020 3:27 pm

Re: Restarting an I2S DMA read

Postby fdibac » Fri Mar 31, 2023 7:17 pm

I have a similar but not necessarily identical issue related to I2S.
It seems that esp_restart does not truly reset the I2S DMA state machine.
Occasionally, on power up, the I2S state machine does not start correctly and I have tried using esp_restart to reset the system and start over. However, it seems that the only thing that could truly restart the I2S state machine is a power cycle.
Any ideas or clues would be appreciated.

ESP-Kevin
Posts: 9
Joined: Fri Jul 01, 2022 6:10 am

Re: Restarting an I2S DMA read

Postby ESP-Kevin » Mon Apr 03, 2023 12:15 pm

For the sequence of reset, maybe you can refer to the DAC driver (https://github.com/espressif/esp-idf/bl ... #L169-L193), because the DAC on ESP32 relies on the DMA of I2S.

Also, the DAC driver provides three ways to use the DMA, maybe it can help you

Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot] and 233 guests