cancel
Showing results for 
Search instead for 
Did you mean: 

I2S Master has Full Duplex DMA L/R Swapped after Restart

john gassel
Associate III
Posted on January 02, 2018 at 22:53

I have an application using an STM32F429ZI processor and I'm seeing a strange problem where the L/R audio output gets swapped after changing I2S frequencies.

My procedure to change frequencies is as follows:

HAL_I2S_DMAStop(&hi2s3);

HAL_I2S_DeInit(&hi2s3);

hi2s3.Init.AudioFreq = sampling_rate;

HAL_StatusTypeDef result = HAL_I2S_Init( &hi2s3);

I2SEx_TransmitReceive_DMA_DB();

//my own function above is called, which is similar to the following but instead has call to 

//HAL_DMAEx_MultiBufferStart_IT(&hi2s3, &DummyAudioOutBuf, &DummyAudioOutBuf, AUDIO_OUT_BUF_SIZE);

It doesn't always happen.  I'd say that it gets swapped about 10% of the time.  I've seen people who have similar problems when running a slave, but with the ST configured as the master, I'm surprised to see this.

Here is my I2S3 configuration:

hi2s3.Instance = SPI3;

hi2s3.Init.Mode = I2S_MODE_MASTER_TX;

hi2s3.Init.Standard = I2S_STANDARD_PHILIPS;

hi2s3.Init.DataFormat = I2S_DATAFORMAT_16B;

hi2s3.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;

hi2s3.Init.AudioFreq = I2S_AUDIOFREQ_16K;

hi2s3.Init.CPOL = I2S_CPOL_LOW;

hi2s3.Init.ClockSource = I2S_CLOCK_PLL;

hi2s3.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_ENABLE;

#swap #stm32f4 #i2s #dma
20 REPLIES 20
Posted on January 02, 2018 at 23:27

hi2s3.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_ENABLE;

I've seen people who have similar problems when running a slave,

There's no duplex I2S module in STM32; it's two simplex modules tied together internally. Thus, there's always at least one slave.

I wonder whether Cube/HAL deinits/inits both I2S and I2SExt.

Which one of them is the receiver, btw?

JW

john gassel
Associate III
Posted on January 03, 2018 at 03:55

Waclawek.Jan

‌ that's an interesting idea! You might be onto something there.

I2S3_SD (PC12) = TX

I2S3_ext_SD (PB4) = RX

What should I look for in the de-init HAL routine?

Posted on January 03, 2018 at 10:15

Well... You say that output data are swapped. That won't indicate problems with the slave restart as the Ext unit is always the slave and you use it as Rx, so input data corruption would indicate problems of that nature.

Basically, you want to get things onto the starting point. You perhaps also may want to reset the codec or whatever is on the other side, although normally codecs are 'self-correcting' as they normally do follow correctly the LRCK (aka WS) signal.

At this point I'd look at your transmit function and/or the function called from there. Does it start from the correct point in the buffers (including the indicator of the current buffer in DMA)?

Disclaimer (although it's obvious): I don't Cube.

JW

Posted on January 03, 2018 at 15:33

Basically, you want to get things onto the starting point. You perhaps also may want to reset the codec or whatever is on the other side, although normally codecs are 'self-correcting' as they normally do follow correctly the LRCK (aka WS) signal.

Yeah, I've already looked into that.  I make sure that the codec is in shutdown before making any changes to the I²S configuration in the STM.  Once all is configured, I re-enable the codec.  It's running in PLL mode and should auto-sync to the incoming I²S stream.

At this point I'd look at your transmit function and/or the function called from there. Does it start from the correct point in the buffers (including the indicator of the current buffer in DMA)?

Yeah, I believe it does.  I'll review it again today.  Interestingly, when I look at the DMA output buffers in the Live Watch view of IAR the data is always oriented properly.  That is, LRLRLR starting from address 0 of the buffer.  This is true in both cases: swapped and correct.  So it's behaving as if the WS output from the processor is wrong.

I really wish I had access to probe the I²S lines on my board, but unfortunately, they're buried (BGA to BGA) so I'm running a bit blind in this case.  

john gassel
Associate III
Posted on January 03, 2018 at 22:16

HAL aside, does anyone know what should be shut down/reset to get a clean starting point?

Posted on January 03, 2018 at 23:04

It should be enough to disable both I2S and I2SExt (in ), and both DMA channels tied to them.

You may want to try that on a Discovery or similar board, where the signals are exposed.

JW

john gassel
Associate III
Posted on January 09, 2018 at 15:53

Waclawek.Jan

‌ and others:

I was able to remove the codec off a board sucessfully. This confirmed my suspicion that the problem is in the ST microcontroller, not the codec.

See two screen captures below. I'm playing the exact same tone in both cases with left audio only.

In this case, data output when WS=1

0690X00000609OaQAI.png

In this case, data output when WS=0

0690X00000609OuQAI.png

The data in my output buffers never changes. I always observe that the even indices of the buffer have non-zero values and the odd bits are zero.

I also found out something very interesting...the RX data has the same swapping issue!

I'm still stumped, but happy to be ruling some things out. If you have any input or suggestions to try, please let me know.

Cheers,

John

Posted on January 09, 2018 at 16:32

even bits of the buffer have non-zero values and the odd bits are zero.

bits? or did you mean words?

Posted on January 09, 2018 at 16:56

Correct.  What I actually meant are 

indices, not bits, but words are also true as it's a int array.