cancel
Showing results for 
Search instead for 
Did you mean: 

Using STM32H7 SAI Slave Mode for USB Audio (UAC2.0) with DSD Format

Cirno
Associate

Hello, I am currently working on an audio project involving an STM32-based audio player and sound card, utilizing the STM32H723ZGT6 microcontroller, USB3320 USB PHY, and ES9039Q2M DAC. Inspired by impressive projects seen on DiyAudio and GitHub, such as OpenUAC2, and finding a wealth of useful information within the STM32 community, I still have some questions that I hope someone can help answer.

 

To implement the UAC 2.0 protocol, I need to calculate the asynchronous feedback endpoint. Based on my research, this can be done by monitoring the remaining capacity of the FIFO buffer (as TinyUSB does) or by using a timer peripheral in conjunction with the USB_SOF signal. Specifically, a common approach is to connect the external ETR pin of the timer to the WS (FS/LRCK) or audio clock source/MCLK and then calculate the time difference between the SOF and ETR signals.

 

After reviewing the STM32H723ZGT6 reference manual, I found that the USB_SOF signal is an internal interrupt for TIM2 and TIM5. Additionally, SAI1_FS_A, SAI1_FS_B are internally connected as ETR sources for TIM2, and SAI4_FS_A, SAI4_FS_B connected to TIM5. 

屏幕截图 2024-10-30 100315.png

This seems to be a deliberate design by ST to facilitate asynchronous feedback endpoint calculation. If using I2S instead of SAI, such connections typically require an external Timer ETR pin. In PCM mode, this setup works well whether in master or slave mode.

 

However, the challenge arises when working in DSD mode. The STM32 reference manual does not explicitly mention DSD, but from practical implementations online, it seems that DSD can be achieved using two synchronized I2S or SAI channels. This allows the use of two serial data output pins, and since SAI has an internal synchronization mechanism, it is better suited for this task.

 

Based on my understanding, the following configuration should be feasible in STM32 CubeMX:

  • Configure SAI1_A as Master mode
  • Configure SAI1_B as Synchronous slave mode

 

Many DACs, including the ES9039Q2M and AK4493, share pins between DSD and PCM modes. For ESS DACs, the I2S WS pin is shared with DSD channel 1 (Left Channel).

屏幕截图 2024-10-30 100436.png屏幕截图 2024-10-30 100446.png

 

To handle this, I need to switch between these pins. This can be done by directly connecting SAI1_B_SD to SAI1_A_FS (and configuring the GPIO mode) or using a signal switch.

 

However, in this scenario, if I need to handle UAC 2.0, can I still use the internally connected ETR to calculate the feedback endpoint? Specifically, can I still use SAI1_FS_A ETR?

 

Additionally, to reduce clock jitter's impact on the DAC, I prefer using SAI slave mode rather than master mode (STM32 in SAI slave mode, DAC in master mode). This way, the clock will be provided by the DAC.

 

In STM32 CubeMX:

  • Configure SAI1_A as asynchronous slave mode
  • Configure SAI1_B as Synchronous slave mode

 

The STM32 manual states that the difference between master and slave modes lies in whether SAI_SCK and SAI_FS are generated by STM32 or come from an external source.

 

If the DAC is in DSD master mode, there will be no SAI_FS (LRCLK).

屏幕截图 2024-10-30 100929.png

 

so, for STM32, if SAI_FS have no input in asynchronous salve mode, with only DSD DATA_CLK(SAI_SCK) input,  can the STM32 SAI still transmit data correctly?

 

My idea is to configure STM32 as SAI slave mode. When the DAC switches to DSD mode, I will use a signal switch to disconnect SAI_FS from the DAC and connect it to SAI_SCK (allowing the use of internally connected ETR). However, I am unsure if this is feasible.

 

Alternatively, am I left with no choice but to add an external TIM2 ETR1 pin to DAC's audio oscillator?

 

I would greatly appreciate any insights or suggestions the community can offer on these matters.

Thank you in advance for your help.

0 REPLIES 0