Skip to content

Use move based api for I2S #3639

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: main
Choose a base branch
from

Conversation

AstrickHarren
Copy link

@AstrickHarren AstrickHarren commented Jun 14, 2025

This is to fix #3285, as in #3612 @Dominaezzz laid out reasons for a move-based i2s API so I thought I may help a bit about #2269 . Haven't tested or anything, just to put the draft PR here to see if I'm in the right direction. Also I'm very aware of #3219 but it seems to be dormant for a bit. I really need to make i2s working for my little project with mic and speaker so let me know if anyone's already working on this and I'll be glad to close my PR.

  • I2S async works with DmaTxStreamBuf similar to DmaRxStreamBuf, tested on an ESP32-S3 with MAX98357A to output sound
    • Design is similar to its RX counterpart as well, based on a rotating linked list instead of a circular list.
  • Support for resuming I2S when DMA stops. Not sure how to detect DMA stopping. Looks like we don't listen to GDMA_OUT_TOTAL_EOF_CHn_INT, so the other ways around maybe
    1. force check_owner and listen to error
    2. if I find all the descriptors are owned by CPU, then DMA probably already stopped (stopped because reached end of linked list)

@Dominaezzz
Copy link
Collaborator

I'm very glad to see someone else getting the DMA move stuff to the finish line. (I was struggling to find the motivation to touch the I2S driver)

  • Not sure how to detect DMA stopping.

There isn't a one size fits all solution for this one. Some peripherals will tell you when this happens, and other won't.
The DMA interrupts could be used but only if the buffer has been setup to trigger the right interrupt, like you said with the check_owner bit.

There's probably other DMA registers that can be polled to check for this condition but I haven't looked yet.

I'm leaning towards leaving this problem to the user, because regardless of whatever solution you choose here, it is still up to the user to restart the I2S/DMA transfer when it stops.

@AstrickHarren AstrickHarren marked this pull request as ready for review July 21, 2025 15:22
@AstrickHarren
Copy link
Author

AstrickHarren commented Jul 21, 2025

Think this may be ready.

Added the TxStreamBuf that basically works symmetrically with the RxStreamBuf implementation.

A few problems I couldn't get my heads around

  1. I tried to utilize DescriptorEmpty interrupt as a sign for DMA rx completion but I couldn't get the interrupt when the descriptors are used up. Compared to TotalEof which I assume is the counterpart for tx and it works every time when descriptors are used up.
  2. not sure how to detect DMA rx stopping if DescriptorEmpty is not triggered. One way is to listen for I2sInterrupt::RxDone which I'm doing right now, but I don't think it works on every esp device.
  3. I'm not sure what exactly does rx_eof_num do. Looks like it triggers SUC_EOF, but it doesn't make sense to set the number if I2S is meant to be used continuously. But I can't set it to 0 or very small, otherwise dma will only put that many data in each of the descriptors and the linked list is used up every quickly. Also the number can't be a huge arbitrary number too, it seems dma will have the same problem as before, not using up the descriptors entirely. You'd think it will fulfill descriptors until it reaches rx_of_num of data and effectively leave the modulo to the last descriptor but experiments seem to show that it leaves modulo data to every descriptor for some reason. Therefore, I left that as an argument and recommend it to be set as the same size as the descriptors in the list.

I'll fix the docs and also changelog once I get a basic review.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

I2S circular transfers, should be stopable.
2 participants