cancel
Showing results for 
Search instead for 
Did you mean: 

Configuring I2S Clock on STM32F4?

Terence D
Senior
Posted on October 11, 2017 at 00:10

Hi - I'm attempting to interface a

http://store.digilentinc.com/pmod-i2s-stereo-audio-output/

with my STM32F429 dev board.  The PmodI2S has a

https://www.cirrus.com/products/cs4344-45-48/

 DAC on it.  I'm using

http://www.st.com/en/development-tools/sw4stm32.html

for development and use STM32CubeMX to configure the project.

I've configured the STM32F429 I2S as 8 KHz output, using a master clock.  This configuration is shown in the table below:

0690X00000608YtQAI.png

By breaking during running the code, I've confirmed all of the I2S values shown in the table above (PLLI2SN, PLLI2SR, I2SDIV and I2SODD) match what I'm seeing in the RCC-PLLI2SCFGR and SPI-I2SPR registers.

I'm simply sending a single cycle of a sine wave (256 samples) from my STM32F429 to the PmodI2S.  My PmodI2S is connected to some basic PC speakers.  The audio coming from the speakers is good *EXCEPT* for random ''clicks'' that occur in the sine wave sound.

I've hooked the PmodI2S output up to an oscilloscope and see the ''clicks'' as shown in the example below:

0690X00000608Z3QAI.png

The clicks appear to be random - they don't appear at any regular position in the sine wave cycle.

I'm stumped as to what to try next in attempts to get rid of these clicking sounds.  If anyone has any suggestions I would be very appreciative to hear them.  Thanks.

-Terence

6 REPLIES 6
Posted on October 11, 2017 at 08:23

I'm simply sending

How simply?

JW

Posted on October 11, 2017 at 22:49

Waclawek.Jan wrote:

I'm simply sending

How simply?

JW

Ah, great question, Jan. Not sure why I didn't think of this but, if I assume correctly, you're suggesting there is possibly a lag in getting the data into the SPI data register, correct? I'm using a couple of HAL functions inside the program's infinite while loop as follows:

while (1)

{

if (HAL_I2S_GetState(&hi2s2) == HAL_I2S_STATE_READY)

{

HAL_I2S_Transmit(&hi2s2, &SINE_TABLE[index], 1, 0);

if(!channel) channel = 1;

else channel = 0;

if (channel)

{

index++;

index = index % 256;

}

}

}

I've attached the entire code if you're interested in taking a look.

However, I have to say, I'd be surprised if the HAL code was not able to handle transferring the data fast enough. I have no interrupts or any other processing occurring in this program. The while loop just infinitely sends data and the playback sample rate is only 8KHz.

Possibly I need to offload the data transfer duty to DMA? I have not yet done DMA with this development board (STM32F4) I have done it with a different ARM Cortex-M4 board though (the Texas Instruments TM4C123G). I cannot use the TM4C123G for this though as it does not have I2S support. And I prefer this STM32F4 board anyway.

I think my next plans of action are as follows (in order):

  1. Not use the HAL to transfer the audio data but write directly to the SPI data register inside the while loop and see if the issue is resolved.
  2. Attempt to use DMA to transfer the audio data instead of the infinite while loop.

I'd be very eager to hear any thoughts you might have, Jan... Or of course from anyone else as well.

Thanks,

Terence

________________

Attachments :

I2SCode.zip : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006HyNP&d=%2Fa%2F0X0000000b6r%2Fsjr8jnm85hsDT7cA4W6zEioNal_uzFnwof.oFZY9EC4&asPdf=false
Posted on October 12, 2017 at 09:34

I'd be surprised if the HAL code was not able to handle transferring the data fast enough.

Don't be surprised: benchmark (i.e. measure, how long it takes to execute the loop - toggle a GPIO and measure with an oscilloscope or LA).

You run the system clock at a somewhat surprisingly low 25MHz, and you divide it to APB1 by 8. This, together with the lengthy 'library' code and no compiler optimization you might've used, may result in surprisingly long execution times.

I don't say this is it. The codec you're using appears to be a quirky one, with clock autodetection, which may be another source of surprises if not driven in expected way.

JW

Posted on October 13, 2017 at 19:46

Jan - Thanks for the reply.  Good point about the clock speed.  I've tweaked this, increasing the clock speed to the 180MHz max and also reduced the APB1 divider to 4.  This resulted in a much higher pitch tone coming out of the speakers (unfortunately still distorted though).

What surprises and confuses me about the change in pitch is that I DID NOT change the I2S sample rate.  It remains at 8 KHz.  With an increased CPU clock rate I figured transmitting the sample to the SPI DR would just block longer (when checking the SPI SR and seeing the TX buffer was still populated) and the output pitch would not change.

This, along with various other tweaking and trial-and-error I've done - eluded to in my previous post, makes me wonder if I'm missing something about how I2S works on the STM32F4.

I've (just now) managed to get a hold of a similar STM32 board (an STM32F411) that actually has an very similar DAC on the board itself and have an audio example from STM working on this board.  I'm going to dig through the code and fully understand how that works in hopes of it shedding some light on how to get the STM32F429 to work with the Digilent PmodI2S.

I've made myself a reminder (a week out) to return to this thread and post my results.

Jan - Appreciate your suggestions so far in helping me get this figured out.

-Terence

Posted on October 15, 2017 at 11:10

You should observe the data output to I2S with a logic analyzer.

 HAL_I2S_Transmit(&hi2s2, &SINE_TABLE[index], 1, 0);

I don't and won't Cube but IMO the timeout of 0 is not right.

JW

Posted on October 22, 2017 at 19:07

Jan - I believe you're right about the timeout.  Long story short, I've done A LOT of experimenting with this along with analyzing the I2S signals with my logic analyzer without a lot of indication of what exactly is going on so I've moved on to my STM32F411 and got fully working code for the STM32F411 which has a CS43L22 DAC on the board.  This 'working code' plays a 100% correct stereo sine tone at a 44100Hz sample rate.

So, the CS43L22 is not the same as the CS4344 that is on the PmodI2S.  The CS43L22 has a whole set of initialization steps that the CS4344 does not and also does communication with I2C and I2S.  I still want to get the PmodI2S working with my STM32F429.  My next steps are going to likely include:

  1. Comparing my STM32411/CS43L22 code with my STM32F429/CS4344 code and making tweaks to the latter.
  2. Getting DMA to work first with the STM32411/CS43L22 and then hopefully leveraging this information to get DMA to work with the STM32F429/CS4344.

If anyone is interested in my ongoing trials and tribulations with the above please let me know - I'll be happy to post periodic updates to this thread.