Skip to main content
Terence D
Associate III
October 10, 2017
Question

Configuring I2S Clock on STM32F4?

  • October 10, 2017
  • 6 replies
  • 3515 views
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

    This topic has been closed for replies.

    6 replies

    waclawek.jan
    Super User
    October 11, 2017
    Posted on October 11, 2017 at 08:23

    I'm simply sending

    How simply?

    JW

    Terence D
    Terence DAuthor
    Associate III
    October 11, 2017
    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
    waclawek.jan
    Super User
    October 12, 2017
    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

    Terence D
    Terence DAuthor
    Associate III
    October 13, 2017
    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

    waclawek.jan
    Super User
    October 15, 2017
    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