Need help with audio pinout

Hi everyone, I wanted to ask if it was possible that the pinout diagram is incorrect or if perhaps I am reading/understanding it incorrectly.

I am running the bypass example which I believe should send input on channel 0 out to the output of channel 0. However, when I am sending mono signals in to each channel I am getting the reverse, I am getting input on channel 0 sending out to the output of channel 1.


I have each of these channels wired to the appropriate pin per the pinout and this configuration is how I get input/output with the bypass example

I posed that question also. Here’s what I posted. I never really received any follow up. I’m not the only one who has mentioned it either. Since my project was mono, I just tied both input pins together and used out1. I suggest that you contact tech support and get another opinion. Besides that issue, everything else I have worked on was as expected and as documented.

Assuming all Daisy Seeds are equal I can confirm that on mine Pin 16 is IN 1, pin 17 is IN 2, pin 18 is OUT 1, pin 19 is OUT 2 and the bypass example you can choose from the examples on the upload web page ( works.

However, if you are compiling the bypass example yourself, you may be using other libraries than the example binary was made with and then things may work differently.

I built the Daisydiuno bypass example, on on my Pod, input on the tip comes out on the ring of the output.

Somewhere, something is crossed.

Okay, can confirm there is definitely something wrong.

I have also experienced this inconsistently with libdaisy. (Recently building one project with the Makefiles has the channels in the correct order, but when building in Visual Studio they’re swapped).

I have a feeling there is one register in the SAI that isn’t getting set correctly, or at all, at startup (or perhaps a bug in the HAL).

I have an entirely re-written libdaisy audio class nearly ready to merge (just needs the multi-codec stuff added back in). Which can then be migrated to Arduino as well. If it isn’t a HAL bug then that should resolve it, otherwise I’ll dig in and find whatever is causing it swap the channels.

I’ve noticed that channeled swapping is what you get if you set invalid SAI mode - I2S standard instead of MSB justified.

That’s good to know. Possibly something is overwriting it. I just confirmed my channels in this project are swapped, and it is being initialized as SAI_I2S_MSBJUSTIFIED

Thanks for all the replies everyone! I’ll be looking out for the update to the DaisyDuino library!

Alright. So a little bit of progress has been made on this front.

It seems like its timing related between when the DMA and SAI are enabled.

On page 2291 of the reference manual, the steps for configuring the DMA/SAI interface are listed specifying that the DMA be enabled before the SAI.

In the HAL files (specifically around line 1705 of stm32h7xx_hal_sai.c) within the HAL_SAI_Receive_DMA function the SAI is enabled first, and then the DMA Is enabled.

Simply swapping the order doesn’t fix the channel swap, adding a very short delay (I used a nop loop in the code snippet below) results in the channels going back in the correct order.

I have not tried this on something that has the correct input->output mapping in the first place, and I suspect that this would cause that to flip to the wrong channel.

Here’s the snippet in case its useful for anyone who just needs to hack something together for now.

Inside of HAL_SAI_Receive_DMA() Starting at line 1705:

/* Enable the interrupts for error handling */
__HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
/* Enable SAI Rx DMA Request */
hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
uint32_t foo = 0;
while(foo++ < 35000)

if((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
    /* Enable SAI peripheral */

Also, for what its worth, I verified that the FSPOL bit in the FSCR wasn’t getting flipped or causing this.

I’ll keep updating this thread with anything new I find as well.

FWIW, I didn’t need to edit HAL sources to get both codecs working in sync on OpenWare port. It uses untouched init code generated by CubeMx, later codec reset pins get triggered with 1ms delay, then DMA TX/RX transfers start.

This seems to work without issues, however I’ve noticed that reordering DMA TX/RX calls can lead to codec not working. Currently DMA is started as RX1, TX1, TX2, RX2. Also, it’s running inside RTOS thread, but with cooperative scheduling this probably makes no difference.

Good to know that’s been your experience as well. I keep waiting to have them boot up several samples off from each other or something. I haven’t had any issues getting the two codecs to play nice together either. Since they share a peripheral clock, they’re forced to be at least somewhat in sync. So as long as they’re started together then everything should work out.

My fix above was specifically addressing the issue where the stereo channels for a single were (seemingly randomly) swapped. On a project I’m working on, I was able to build the same source code two different ways (make and vgdb) and have the channels swap on one of them, but not the other. Once I switched the project to 96kHz both builds had swapped channels, and the above was just my cursory exploration looking for the potential cause since it seems to be happening in the Arduino build as well.

I see, if it depends on compilation method, my successful build doesn’t prove anything. Might be some regression in particular compiler used or caused by compiler options. Maybe worth checking disassembly in make/vgdb compiled versions.

Also, I would suggest testing if it can be reproduced with cache disabled - it could be happening due to different execution speed or unexpected side effect from prefetch.

Yeah, I should have a bit more time to look into it next week, and the next step is to get a program that reliably has the issue in one case and not the other so that I can directly compare the disassembly for the DMA Start functions (which seem to be the prime suspect at the moment).

One of the first things I checked was both instruction and data caches, but the problem persisted whether they were enabled or disabled.