ESP32 :: I2S DMA interrupt IN_SUC_EOF problem
Posted: Mon Sep 18, 2023 1:11 pm
Hi everyone,
I'd like to know what is wrong with my approach.
Goal: getting 16384 bytes (16K) buffer filled by camera via I2S->FIFO->DMA
Platform: ESP32 and IDF 5.0.1, FreeRTOS
Problem: can't get IN_SUC_EOF interrupt triggered.
General approach:
After configuring all the I2S/FIFO/DMA control registers and prior to starting off I perfrom the following key steps:
Setting up all 5 in_link descriptors for the maximum size of 4092 bytes:
- in_link[0].length = 4092
- in_link[1].length = 4092
- in_link[2].length = 4092
- in_link[3].length = 4092
- in_link[4].length = 16
FIFO is also configured to a maximum of 64 words (256 bytes):
- I2S0.fifo_conf.rx_data_num = 0b111111
I tell the DMA to read the total of 16384 bytes and fire the IN_SUC_EOF interrupt:
- I2S0.rx_eof_num = 16384
- I2S0.int_ena.in_suc_eof = 1
- in_link[0].eof = 0
- in_link[1].eof = 0
- in_link[2].eof = 0
- in_link[3].eof = 0
- in_link[4].eof = 1
Next, I start off DMA/in_link/FIFO and allow I2S interrupts:
- I2S0.in_link.start = 1
- I2S0.conf.rx_start = 1
- I2S0.fifo_conf.dscr_en = 1
- esp_intr_enable(i2s_handle)
After that the transmission looks to start as I can get all 5 IN_DONE interrupts if I set them appropriately.
However, IN_SUC_EOF interrupt won't ever get fired. I can't figure out why this is happening...
I haven't looked into the data being received yet and cannot say whether I'm receiving garbage or not. Currently, I'm stuck with the interrupt.
Oh yes, IDF is also configured to put I2S stuff into IRAM.
PS. Also, I've noticed a wierd change in "in_link[4].value" AFTER in_link[4] has been processed (IN_DONE triggered): in_link[4].value = 4092 instead of 16! Anyways, it might be an intended behaviour of I2S in_link internals whatsoever... So I don't actually care.
So the question is: how do you get IN_SUC_EOF triggered in this case? Am I missing any key step?
I'd like to know what is wrong with my approach.
Goal: getting 16384 bytes (16K) buffer filled by camera via I2S->FIFO->DMA
Platform: ESP32 and IDF 5.0.1, FreeRTOS
Problem: can't get IN_SUC_EOF interrupt triggered.
General approach:
After configuring all the I2S/FIFO/DMA control registers and prior to starting off I perfrom the following key steps:
Setting up all 5 in_link descriptors for the maximum size of 4092 bytes:
- in_link[0].length = 4092
- in_link[1].length = 4092
- in_link[2].length = 4092
- in_link[3].length = 4092
- in_link[4].length = 16
FIFO is also configured to a maximum of 64 words (256 bytes):
- I2S0.fifo_conf.rx_data_num = 0b111111
I tell the DMA to read the total of 16384 bytes and fire the IN_SUC_EOF interrupt:
- I2S0.rx_eof_num = 16384
- I2S0.int_ena.in_suc_eof = 1
- in_link[0].eof = 0
- in_link[1].eof = 0
- in_link[2].eof = 0
- in_link[3].eof = 0
- in_link[4].eof = 1
Next, I start off DMA/in_link/FIFO and allow I2S interrupts:
- I2S0.in_link.start = 1
- I2S0.conf.rx_start = 1
- I2S0.fifo_conf.dscr_en = 1
- esp_intr_enable(i2s_handle)
After that the transmission looks to start as I can get all 5 IN_DONE interrupts if I set them appropriately.
However, IN_SUC_EOF interrupt won't ever get fired. I can't figure out why this is happening...
I haven't looked into the data being received yet and cannot say whether I'm receiving garbage or not. Currently, I'm stuck with the interrupt.
Oh yes, IDF is also configured to put I2S stuff into IRAM.
PS. Also, I've noticed a wierd change in "in_link[4].value" AFTER in_link[4] has been processed (IN_DONE triggered): in_link[4].value = 4092 instead of 16! Anyways, it might be an intended behaviour of I2S in_link internals whatsoever... So I don't actually care.
So the question is: how do you get IN_SUC_EOF triggered in this case? Am I missing any key step?