• Welcome to ASR. There are many reviews of audio hardware and expert members to help answer your questions. Click here to have your audio equipment measured for free!

the new ESP32-C5 and P4 support 16 channel 32 bit TDM in full duplex

IIUC the maximum APLL is 160MHz, while :

Due to hardware limitation, when setting the clock configuration for a slave role, please be aware that <span>i2s_tdm_clk_config_t::bclk_div</span> should not be smaller than 8
IIUC that would mean max bclk of 20MHz - which would be quite slow. 20MHz / 32 bits / 48kHz = 13 channels 32bit TDM max at 48kHz. There are 3 I2S interfaces, but I would be cautious about overall performance of the DMA to fetch so much data.
 
  • Like
Reactions: MCH
Thanks for the input. Seems still quite reasonable for a chip normally well documented, cheap, and easy to implement. I would be already very happy if it allows to build a simple usb multichannel DDC/DAC, and seems that someone was already working on it:

 
seems that someone was already working on i
IMHO that code seem quite incomplete - e.g. all out endpoints define async mode, yet I could not find any corresponding async feedback endpoint and its handling.
 
Hi,
I discovered some weeks ago that the ESP32-P4 had an integrated USB HS phy. I found some simple ESP32-P4 modules on Aliexpress, with the USB HS and sufficient pins. I have one on my desk and will try to give it a try for a USB to I2S multichannel bridge (even if I failed to finalize my stm32 one).

Espressif relies on the TinyUSB stack, which has a UAC2.0 audio class. It seems "maintained" as there are several updates over the last years/month. Could be more mature than the stm32 one. Seems there are some examples with Feedback (not clear how mature they are).

The I2S peripheral seems less versatile than the stm32 one. At least you can't sync the I2S0, I2S1 and I2S2 like possible to do on the stm32. I have seen that there were limitations on the C3 and S3 to TDM 8*16bits or 4*32bits... I hope @MCH that your statement that it is solved will be confirmed
:) . MCH: you are just once again paving the way ;-)

At least a potential good pair with my other project of ES9080 DAC. The ES9080 DAC would be the master with a good audio freq crystal.

JMF
 
  • Like
Reactions: MCH
Hi,
I discovered some weeks ago that the ESP32-P4 had an integrated USB HS phy. I found some simple ESP32-P4 modules on Aliexpress, with the USB HS and sufficient pins. I have one on my desk and will try to give it a try for a USB to I2S multichannel bridge (even if I failed to finalize my stm32 one).

Espressif relies on the TinyUSB stack, which has a UAC2.0 audio class. It seems "maintained" as there are several updates over the last years/month. Could be more mature than the stm32 one. Seems there are some examples with Feedback (not clear how mature they are).

The I2S peripheral seems less versatile than the stm32 one. At least you can't sync the I2S0, I2S1 and I2S2 like possible to do on the stm32. I have seen that there were limitations on the C3 and S3 to TDM 8*16bits or 4*32bits... I hope @MCH that your statement that it is solved will be confirmed
:) . MCH: you are just once again paving the way ;-)

At least a potential good pair with my other project of ES9080 DAC. The ES9080 DAC would be the master with a good audio freq crystal.

JMF
good luck and keep us posted!
 
Hello,
I started to experiment with a ESP32-S3 to discover the ESP environment. It is limited first of all by the USB Full Speed, so you can't go very far as of number of channels and bandwith. I have a working example with 2 channels driving my CODEC and playing music on a MAX98357 driven in I2S. Volume and mute are working. Next step is to experiment with TDM... and then jump to the ESP32-P4 and the USB HS.

Overall, I find that the documentation is OK, the libraries look well designed. I find it more mature than on the stm32 chips for this specific audio topic.

Paying attention to phofman warning, I wanted to assess the max performance. From the ESP32-P4 reference manual, it seems that the Audio PLL (APLL) and I understand the I2S external clock can reach 240 MHz. In the manual, they develop the analysis for the slave mode, which seems to be the limiting one. They indicate up to 15MHz for the BCLK. This would correspond to 8 channels 16bits 96k or 8 channels 32 bits 48k. Not perfect but OK. Adding other I2S in parallel could possibly be a way to increase the channel number, but there is no synch mecanism between the I2S (which exist for the stm32 SAI).

In Master mode, it could generate from the APLL (or the external I2Sn_MCLK_in) a 120 MHz MCLK.

I tried to compare those limits to a stm32H7 SAI, and the MCLK seems limited to about 50 MHz. Nt sure about how the stm32 clock scheme would be favorable, and if in some cases the stm32 would run ahead of the ESP.

I would be interested by information about the I2S_TDM limits of the RPI5 (could not find those yet).

The MCLK of the ES9080 seems limited to 49 MHz. This could be a very limiting factor in a schenario with ES9080 as master and ESP32-P4 as slave.

Feedbacks warmly welcomed, to confirm if the ESP32-P4 is a promising platform or not compared to competitors.
 

Attachments

  • ESP FS analysis.jpg
    ESP FS analysis.jpg
    90.6 KB · Views: 89
  • Like
Reactions: MCH
@phofman : you have done some experiments with SBC on Linux like the radxa boards. Which type of performance do they achieve with I2s TDM outputs, let's say wit 8 channels and 32 bits?

Which sampling rates can they achieve in Master and slave modes?

I see in datasheet 8ch*48khz but not clear if it is for 16 bits or 32 bits bit depth.

I would be really interested to know:-)

Jmf
 
Last edited:
I have only tested mch I2S, not TDM as I had no need for it. In fact I got stuck with TDM first and had to fight back to I2S in DTS.

But the PCM interfaces of several Rockchip SoCs I played with (all use the same rockchip PCM interface IP and the same pl330 DMA controller IP) did run fine at 384kHz 32 bit (i.e. bclk=64fs) at 8ch. At 768kHz the DMA was already dropping frames and also the skew of data line vs. bclk was getting too large, causing imprecise reading (the reading edge of bclk was not well within the stable data part).

So I would assume you can do 384/4 = 96kHz @ 32 bits with 8ch TDM.


I see in datasheet 8ch*48khz

That makes sense - the I2S is specced at 192kHz 32bit max which means 48kHz for 8ch TDM (both modes yield the same bclk). But IME the HW can run twice as fast reliably (with the recently fixed pl330 driver, of course).

I have not tested slave mode but would assume to be the same. In fact in the 16ch sync mode I2S0 + I2S1 of RK3308 in Pi S the I2S1 interface runs slaved to the other interface and the combined device runs fine at 384kHz.
 
Update:
After preliminary tests with Esp32-S3, I moved to Esp32-P4 with this board https://shop.wireless-tag.com/produ...hip-dual-core-risc-v-mipi-dsi-csi-support-lcd

I purchased it on Aliexpress for about 7€ and it has the interface for USB HS. I interfaced it to a MAX98357 for tests, which can decode I2S_TDM 8 channels up to 96K.

I work on a first configuration 16bits x 8 channels 48k.

On Linux, I can see the board as a 8 channels board and can play a multichannel track using VLC. I have to investigate a bit as I get the sound from 2 tracks where I would expect having only one. I need to use the logic analyzer to investigate.

On Windows, I have a yellow triangle for the device some value is out of the expected range. I need to install the Windows tracing tools to investigate (hoping they will still work on Windows 11).

Once it will work on Windows, I will play a bit with the clocking scheme to see which MCLK ratios are accepted.
 
  • Like
Reactions: MCH
Thanks for reporting. I have that exact module, but made the mistake of buying only the module (without connectors and supplies) aiming for custom PCBs and as a result, I never did anything with them. But seeing your progress I might get a module like yours. Thanks.
 
Hi, I supply it from USB (can be both from the programming one or the USB HS). Rest is only standard pin headers. Except if you mean the bare WT0132P4-A1 module, which don't seem that easy to find (the Waveshare one seems more available).
 
I have posted some elements in Espressif and TinyUSB forums. I complement here in case someone would identify something not normal and could provide ideas...

I use the Espressif esp_device_uac component from ESP IoT Solutions (https://components.espressif.com/components/espressif/usb_device_uac), which relies on TinyUSB ^0.17.0~2 (TinyUSB last native version is 20.0

The application appear to work when plugged in a Linux Host. I can play a 8 channel audio track. But it doesn't work when plugged in a windows host. There seems to be an out of range value.

I activated the TinyUSB debug. I got also information from the Windows side using their tracing tool. Both are attached.

The issue seems related to the setting of the sampling frequency/clock. Windows seems to stop progress on "Supported sampling frequencies:" log.

On the Tiny USB side:

USBD Setup Received A1 02 00 01 00 04 00 01
AUDIO control request
Clock get 1 freq ranges
Range 0 (48000, 48000, 0)
Queue EP 80 with 14 bytes ...
USBD Xfer Complete on EP 80 with 14 bytes
AUDIO control complete
Queue EP 00 with 0 bytes ...
USBD Xfer Complete on EP 00 with 0 bytes


USBD Setup Received 80 06 05 03 09 04 02 00
Get Descriptor String[5]
Queue EP 80 with 2 bytes ...
USBD Xfer Complete on EP 80 with 2 bytes
Queue EP 00 with 0 bytes ...
USBD Xfer Complete on EP 00 with 0 bytes


USBD Setup Received 80 06 05 03 09 04 10 00
Get Descriptor String[5]
Queue EP 80 with 16 bytes ...
USBD Xfer Complete on EP 80 with 16 bytes
Queue EP 00 with 0 bytes ...
USBD Xfer Complete on EP 00 with 0 bytes
I (13338) i2s_usb: MCLK: 18432000, delta: 0, buffer water mark: 0%
USBD Suspend : Remote Wakeup = 0
I (13827) usbd_uac: USB suspended


And Stereo was working... but more is not.

For completeness, I also add the descriptors as seen by Linux host.

Help would be very welcomed :)
 

Attachments

IMO the device returns incorrect data on some usb control messages


Code:
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2]CTOR this=0xFFFF990A2E348880
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2]returning <NULL> {b4c90a31-5791-11d0-86f9-00a0c911b544} 0xFFFF990A2E3488B8
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2][
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2]]
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2]returning 0xFFFF990A2E348760
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2]<NULL> iid={5dadb7dc-a2cb-4540-a4a8-425ee4ae9051} is not supported
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2]<NULL> iid={29cc9ab1-e89d-413c-b6b2-f6d50005d063} is not supported
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2]CTOR this=0xFFFF990A4207A580
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2]returning <NULL> {0f9fc4d6-6061-4f3c-b1fc-075e35f7960a} 0xFFFF990A4207A5B8
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2][
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2]]
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2]MiniportWave: FFFF990A4207A580
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2]returning 0xFFFF990A2E347440
Unknown( 25): GUID=3ae904fe-e5cd-3eb3-07fc-0a427c5df63b (No Format Information found).
Unknown( 20): GUID=3ae904fe-e5cd-3eb3-07fc-0a427c5df63b (No Format Information found).
Unknown( 25): GUID=57baf86b-aff4-3baa-ea30-5759928dae9a (No Format Information found).
[0]0004.4868::03/18/2026-19:40:02.402 [USBAudio2]StartAdapter() failed 0xc000028c(STATUS_RANGE_NOT_FOUND)
[0]0004.5794::03/18/2026-19:40:02.402 [USBAudio2][ 0x02 <NULL>
 
Thanks phofman,
Sure that the probability that the issue is on my devise side is high ;-) Looking at logs on the device side, would you have an idea about what is expecting the Windows host with " Get Descriptor String[5]" after "AUDIO control request ; Clock get 1 freq ranges ; Range 0 (48000, 48000, 0)"?

USBD Setup Received A1 02 08 02 00 02 08 00
AUDIO control request
Get channel 8 volume range (-50, 0, 1) dB
Queue EP 80 with 8 bytes ...
USBD Xfer Complete on EP 80 with 8 bytes
AUDIO control complete
Queue EP 00 with 0 bytes ...
USBD Xfer Complete on EP 00 with 0 bytes

USBD Setup Received A1 02 00 01 00 04 00 01
AUDIO control request
Clock get 1 freq ranges
Range 0 (48000, 48000, 0)
Queue EP 80 with 14 bytes ...
USBD Xfer Complete on EP 80 with 14 bytes
AUDIO control complete
Queue EP 00 with 0 bytes ...
USBD Xfer Complete on EP 00 with 0 bytes

USBD Setup Received 80 06 05 03 09 04 02 00
Get Descriptor String[5]
Queue EP 80 with 2 bytes ...
USBD Xfer Complete on EP 80 with 2 bytes
Queue EP 00 with 0 bytes ...
USBD Xfer Complete on EP 00 with 0 bytes

USBD Setup Received 80 06 05 03 09 04 10 00
Get Descriptor String[5]
Queue EP 80 with 16 bytes ...
USBD Xfer Complete on EP 80 with 16 bytes
Queue EP 00 with 0 bytes ...
USBD Xfer Complete on EP 00 with 0 bytes
 
Good news ! The TinyUSB community pointed out the issue. An hard coded value if the esp layer code, which was OK for stereo but not for more channels. Linux seems to accommodate with that issue, but Windows wasn't. Now I have a first thing working with 8 channels in windows.

Honestly, this looks like a good platform to work with. To be continued
:)
 
  • Like
Reactions: MCH
I'm progressing slowly. The configuration with 8ch 16bits 48k is working, which is already not that bad. But I struggle to reach 96k. Various elements coded in the esp_device_uac code hard coded for lower bandwidth and I try to address those. But there may be performance limits related to the chip itself.

Some elements seem better performing for our scope on the stm32 SAI compared to the esp32 i2s peripheral:
- synchro between the SAI,
- less contraints on the slave mode,
- DMA data source.

And the example applications relies on FreeRTOS tasks handling, which may not be compatible with the expected high bandwidth. Something nearer from bare metal could be necessary.

For such a bridge relevance, It would be good to support 8ch 32 bits 96k.

By the way, the Audio Class of TinyUSB seems to me very complete, which makes a big difference with the ST one. And it can be used on a large list of MCUs (including stm32).

Let's see if this can be achieved.

JMF
 
@jmf11 are you documenting, or plan to, a tutorial or similar? I would be very interested.
 
Back
Top Bottom