Skip to content

i2s: Sleep when TX FIFO fills - #52

Merged
soypat merged 2 commits into
tinygo-org:mainfrom
gbenson:main
Aug 3, 2026
Merged

soypat merged 2 commits into
tinygo-org:mainfrom
gbenson:main

Conversation

@gbenson

@gbenson gbenson commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

i2sWrite spins calling runtime.Gosched in a tight loop if the TX FIFO fills. This pull request makes it precalculate how long the FIFO takes to become writable and time.Sleep for slightly longer than that time instead. It also joins the FIFOs to bump the TX FIFO from 4 to 8 words.

On TinyGo at least, I'm 99% sure that time.Sleep yields the CPU In the same way as runtime.Gosched (i.e. it won't deadlock when running on a single core) and, one core or two, with 44.1kHz audio the sleep time is 3,109 cycles at 133MHz (3,507 at 150MHz) so you get a lot of CPU back (or burn less power, if you just wait it out).

@soypat soypat left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes! Very nice. I've been thinking about how to add precalculated sleep to the rest of these drivers, especially when doing DMA. Might be worth doing something with the dma and deadline abstractions in the future. For now this is an excellent addition. Thank you!

@soypat
soypat merged commit 417f40d into tinygo-org:main Aug 3, 2026
1 check passed
@gbenson

gbenson commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Actually this is causing me problems now :( If two other things are happening when the sleep finishes it isn't coming back to the sleeping routine fast enough to avoid the audio dropping out. Or, at least I think that's what's happening. I have three goroutines: one filling audio buffers, one writing them, and one updating a little I2C screen, and I'm now getting clicks whenever the screen updates. Please could you revert it while I figure things out? Sorry!

@gbenson

gbenson commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

(I added runtime.Gosched() all through the screen updater, so it might be how TinyGo schedules. I want to tell it "the buffer filler and the I2S writer have absolute priority, this other one for the display can run if you have time", but I don't know how:(

soypat added a commit that referenced this pull request Aug 3, 2026
@soypat

soypat commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

OK, changes reverted- If you want strict synchronization you should follow an event-loop architecture or develop a priority thread abstraction over the goroutines. I guess the change maybe does not belong in this repo since audio requires strict timing and the best way to meet strict schedules is to just thrash runtime.Gosched. This topic is worthy of a new discussion on tinygo-org/tinygo

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.

2 participants