cancel
Showing results for 
Search instead for 
Did you mean: 

HAL: STM32F427: Full Duplex I2S problems communicating with Audio Codec

hemogloben
Associate II
Posted on April 06, 2015 at 04:03

I'm using the STM32F427 to communicate with a 

https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CB4QFjAA&url=http://www.cs.columbia.edu/~sedwards/classes/2008/4840/Wolfson-WM8731-audio-CODEC.pdf&ei=feUhVZbgKIWDsAXDsIDIBg&usg=AFQjCNGmWZbgqNnAMErpVnzh4kOPdg2J_Q&sig2=M0ODzYrkL30r8Vyx5gUxcw&bvm=bv.89947451%2cd.b2w

[2] 

. I've hooked the codec into the I2S2 of the STM32f4. I've seen lots of code examples for this around the net, but they all use STM's legacy drivers and for time / technical reasons I've been unable to switch from HAL to Legacy.

I'm trying to get pretty standard I2S Full Duplex audio running between the STM32 and the codec. I thought it would be easiest to have the codec be master in these transactions and tried using a 12MHz ceramic crystal. I got the footprint wrong and was unable to salvage, so I superglued and hacked in a 12MHz crystal oscillator. This also didn't seem to work. The STM32 would completely ignore the word/frame clock and just output every data bit immediately. I found this errata that hinted to a bug in STM's I2S2 and attempted to fix it with the following code. No luck.

I moved to a 24.576MHz crystal (that's DIV2 at the codec's input to 12.288MHz) and things are starting to look up. The STM still doesn't seem to work in 96kHz mode, but in 48kHz mode I can atleast get transmits that follow the word / frame sync.

5 REPLIES 5
hemogloben
Associate II
Posted on April 08, 2015 at 03:15

So after looking into it further, I see that there is Frame Error triggering.

I've tried various changes to the placement of the GPIO initialization etc.

I can't seem to get anything other than what's picture here: 

http://i.imgur.com/y3txJwB.png

Any thoughts?
sal
Associate II
Posted on April 10, 2015 at 20:38

I cannot seem to get the HAL drivers to work with DMA or IT either, only with blocking calls. I'm using a STM32F411 acting a an I2S slave. I have very similar code setup as Benjamin, and I have the same problem with the DMA IRQ handler is not getting called. Any insight would be great.

hemogloben
Associate II
Posted on April 21, 2015 at 20:56

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6qD&d=%2Fa%2F0X0000000bwa%2FVuwm8JF0R8i57tjaQvJEywGJjobCP.QQSe1cX.uLrTU&asPdf=false
sal
Associate II
Posted on April 30, 2015 at 22:57

Check this post

https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/STM32F427VIT%20I2S%20strange%20desync%20problem&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&current...

. He had some other problems but at least got DMA working with HAL. It looks like in his initialization in main he is doing some tweaks (switching DMA channel to channel 0 for Tx and re-initliazing). I followed his code exactly and got DMA working for TX and RX. I'm just not sure why this tweak needs to be made for it to work.

-Sal

hemogloben
Associate II
Posted on May 05, 2015 at 23:39

Sal...

Thank you SO much for replying once you'd found the cause of your issues.  That still doesn't seem to make much sense, but atleast I have everything working out okay now.

For anyone else reading, the modified StartDMA code (rest of the code base is the same as I've previously posted) is below.

Final StartDMA Function:

void Codec::StartDMAs() {

  HAL_I2S_MspInit(&hi2s2);

  MX_I2S2_Init();

  __HAL_I2S_DISABLE(&hi2s2);

  while(HAL_GPIO_ReadPin(GPIOB,1<<12) != GPIO_PIN_RESET);

  while(HAL_GPIO_ReadPin(GPIOB,1<<12) != GPIO_PIN_SET);

  hdma_i2s2_ext_tx.Init.Channel = DMA_CHANNEL_0;

  HAL_DMA_Init(&hdma_i2s2_ext_tx);

  __HAL_LINKDMA(&hi2s2,hdmatx,hdma_i2s2_ext_tx);

  HAL_NVIC_SetPriority(DMA1_Stream4_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);

  HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0, 0);

  HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);

  while(HAL_GPIO_ReadPin(GPIOB,1<<12) != GPIO_PIN_RESET);

  while(HAL_GPIO_ReadPin(GPIOB,1<<12) != GPIO_PIN_SET);

  HAL_StatusTypeDef status = HAL_I2SEx_TransmitReceive_DMA(&hi2s2, (uint16_t*)&TxBuffer[0], (uint16_t*)&RxBuffer[0], SAMPLES_PER_BUFFER * 2);

  assert_param(status == HAL_OK);

  completeDMA();

}