2018-01-02 01:53 PM
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 #dma2018-01-02 02:27 PM
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
2018-01-02 06:55 PM
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?
2018-01-03 02:15 AM
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
2018-01-03 07:33 AM
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.
2018-01-03 01:16 PM
HAL aside, does anyone know what should be shut down/reset to get a clean starting point?
2018-01-03 03:04 PM
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
2018-01-09 06:53 AM
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
In this case, data output when WS=0
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
2018-01-09 08:32 AM
even bits of the buffer have non-zero values and the odd bits are zero.
bits? or did you mean words?
2018-01-09 08:56 AM
Correct. What I actually meant are
indices, not bits, but words are also true as it's a int array.