Page 1 of 1

Restarting an I2S DMA read

Posted: Mon May 28, 2018 7:32 pm
by kolban
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.

Re: Restarting an I2S DMA read

Posted: Fri Mar 31, 2023 7:17 pm
by fdibac
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.

Re: Restarting an I2S DMA read

Posted: Mon Apr 03, 2023 12:15 pm
by ESP-Kevin
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