Code snippets to dig into the internals of the ESP32 I2S. The objective is to gain a hardware level understanding of it.
The folders are structured per I2S mode of operation. Each folder holds a set of projects, each project working on a lower level.
The recommended order of browsing them:
-
TX Master mode Easiest kick-off is with trying to produce an output.
-
TX Slave mode Next step is to try produce the output with an external bit clock.
-
RX Slave mode Final step is to try read the output with an external bit clock.
RX Master mode hasn't been implemented. But that should be rather straightforward using the examples here.
It's recommended to use a scope, to be able to see and debug the signals. Otherwise it would be like a sight-seeing tour with eyes closed.
All pins should produce output.
Kick-off with a minimalistic configuration, using the I2S high-level API. Verify the I2S TX transmitter produces output as Master.
Expanded configurations, with the high-level API. Observing how different parameters affect the output.
Switch to a low-level API, using direct register access. FIFO mode, with also GPIO Mux configured on lower level.
Switch to FIFO DMA (burst) mode. Single DMA descriptor and buffer.
Use FIFO DMA with linked buffers. Use an interrupt routine to handle TX EOF.
Both BCK and WS should be taken as input from the I2S Master.
Kick-off with a minimalistic configuration, using the I2S high-level API. Verify the I2S TX transmitter produces output in Slave mode.
Switch Gpio configuration to a low-level API. Verify the GPIO Mux configuration for BCK and WS.
Switch transmit to a low-level API. FIFO DMA mode, with interrupt routine to handle TX EOF.
Configure also Clock and Channel with the low-level API. Otherwise, similar mode of operation.
All pins should be read as input.
Kick-off with a minimalistic configuration, using the I2S high-level API. Verify data can be received in RX Slave mode.
Switch Gpio configuration to a low-level API. Verify the GPIO Mux configuration for all pins.
Configure clock, channel, and DMA with the low-level API. FIFO DMA mode, with interrupt routine to handle RX EOF.
To flash the built project to ESP32:
> esptool.py --chip esp32 --port /dev/ttyUSB0 write_flash -z
> 0x1000 bootloader.bin
> 0x8000 partitions.bin
> 0x10000 firmware.bin