This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC1352R: I2S Clock Jitter

Part Number: CC1352R

Hello,

Currently I am using the I2S driver to drive the BCLK and WS PCM clocks for a third party chip.

Using the settings below, I observe quite a substantial clock deviation.

  // Initialize the I2S bus for the PCM
  I2S_init();

  I2S_Params i2sParams;
  I2S_Params_init(&i2sParams);
  i2sParams.trueI2sFormat     = true;
  i2sParams.invertWS          = true;
  i2sParams.bitsPerWord       = 8;
  i2sParams.samplingFrequency = 8 * 1e3;
  i2sParams.samplingEdge      = I2S_SAMPLING_EDGE_FALLING;
  i2sParams.phaseType         = I2S_PHASE_TYPE_SINGLE;
  i2sParams.SD0Use            = I2S_SD0_OUTPUT;
  i2sParams.SD0Channels       = I2S_8_CHANNELS;
  i2sParams.SD1Use            = I2S_SD1_INPUT;
  i2sParams.SD1Channels       = I2S_8_CHANNELS;

The third party chip indicates that its internal Phase-Locked Loop cannot lock on to the clock signals.
I contacted the manufacturers' support, and they say that the clock jitter is likely the problem.

Using a logic analyzer I have observed:

  • WS is quite high, 8.236 kHz, but this is within the jitter spec.
  • BCLK is 510.2 kHz, but 512.8 kHz every 6th period (Odd?)
  • WS and BCLK start simultaneously
  • WS is high for 20ns after BCLK's period has ended, but this is within the jitter spec.

What can be done to make these clock signals more precise?

  • Hi,

    Bear with me, I am connecting you with an appropriate expert who can help you on this matter.

  • Hi,

    First of all, the setting you are using is a bit unusual. You are using a "trueI2SFormat" with 8 channels. Is it done on purpose?

    The BCLK clock is obtained by dividing the 48MHz system clock. Only integer divisors are allowed. To obtain a 512kHz BCLK clock, you have to divide 48MHz by exactly 93.75... The divider used is 94 which is giving an exact clock of 510.6kHz. The difference seen on every 6th period might probably be explained by some limitation of the logic analyzer. (Side note, (510.2*6 + 512.8)/7 = 510.6kHz, so we are pretty good here).

    WS is obtained dividing the BCLK by the number of clock cycles required. In your case, I would have expected 64 (for a frequency of 7.98kHz). Apparently the number of BCLK cycles is not correct (I would say it is around 62 and not 64).

    You can have a look to the TRM of the device for more details (I guess the paragraph dealing with Clock Configuration [24.4.8] will particularly interest you).

    In summary can you do the following:

    - verify if you really need this trueI2S - 8 channels setting. If not, we can work together to find better settings.

    - take a logic trace of your I2S lines and count the number of BCLK clocks periods per WS period.

    I hope this will help,

    Best regards,

  • Hi Clément,

    Thank you for your thorough response.

    Clément said:

    First of all, the setting you are using is a bit unusual. You are using a "trueI2SFormat" with 8 channels. Is it done on purpose?


    The "trueI2SFormat" was not set on purpose, currently the I2S driver is only used to generate the BCLK and WS lines, so this setting was not paid a lot of attention.

    Clément said:

    The BCLK clock is obtained by dividing the 48MHz system clock. Only integer divisors are allowed. To obtain a 512kHz BCLK clock, you have to divide 48MHz by exactly 93.75... The divider used is 94 which is giving an exact clock of 510.6kHz. The difference seen on every 6th period might probably be explained by some limitation of the logic analyzer. (Side note, (510.2*6 + 512.8)/7 = 510.6kHz, so we are pretty good here).


    We were afraid this was the case, perhaps we should try with an external source then, or I am missing some combinations of settings.

    Clément said:

    In summary can you do the following:
    - verify if you really need this trueI2S - 8 channels setting. If not, we can work together to find better settings.
    - take a logic trace of your I2S lines and count the number of BCLK clocks periods per WS period.

    - I do not think I need the trueI2S setting. However, I configured the use of 8 channels (or 4), to get the combination of 8 kHz sampling WS with 512 kHz (8 channels) / 256 kHz (4 channels) BCLK. Is there another way to get 8 kHz sampling with 256 kHz / 512 kHz BCLK?
    - There are 62 (8 channels) / 31 (4 channels) BCLK periods per WS period, which indicates that indeed the number of BCLK cycles is incorrect.

    So I see two options:

    1. Is there another configuration that could provide us with 8 kHz sampling and 256 / 512 kHz BCLK?
    2. Use an external clock source?
  • Hi,

    You can use the following settings:

    // Initialize the I2S bus for the PCM
    I2S_init();
    
     
    I2S_Params i2sParams;
    I2S_Params_init(&i2sParams);
    i2sParams.trueI2sFormat     = true;
    i2sParams.invertWS          = true;
    i2sParams.bitsPerWord       = 16;
    i2sParams.afterWordPadding  = 16;
    i2sParams.samplingFrequency = 8 * 1e3;
    i2sParams.samplingEdge      = I2S_SAMPLING_EDGE_FALLING;
    i2sParams.SD0Use            = I2S_SD0_OUTPUT;
    i2sParams.SD0Channels       = I2S_CHANNELS_STEREO;
    i2sParams.SD1Use            = I2S_SD1_INPUT;
    i2sParams.SD1Channels       = I2S_CHANNELS_STEREO;

    Using an external clock is also a valid option. In this case you can set the I2S driver in slave mode.

    Best regards,

  • Hi Clément,

    Thank you for your quick response. You are a legend, the third party chip works now!

    Indeed now there are 32 / 64 BCLK periods in the WS period.
    Though, I am a little worried for the future. In a few weeks we will have to implement PCM communication.
    The third party chip uses 4 8-bit u/A-Law channels at 256 kHz BCLK / 8 kHz WS. (And 8 at 512 kHz)

    Will these settings support that?

    PS: For any one reading this post and wishing to use Clément his settings: I2S settings require that the callbacks parameters are filled in.

  • Hi,

    The settings I gave you will provide the right frequencies but you will only sample the first 16 bits of each WS half-period (good in some cases but not in you case). The data received during the 16 last BCLK period of each WS half period will be thrown away.

    The solution for you consists in keeping you original setting and patching the I2S driver :)

    1) Add the file I2SCC26XX.c (it is stored in your SDK in source\ti\drivers\i2s) to your project

    2) In I2SCC26XX.c: (from line 777, in configClocks()), modify the code as following:

            case(I2S_PHASE_TYPE_SINGLE) :
                /* WS is high for 1 SCK period and low for WDIV[9:0] (1 to 1023) SCK periods.
                 * WS frequency = SCK frequency / (1 + PRCM:I2SWCLKDIV.WDIV[9:0])
                 */
                *result = numOfSCKCyles;
    

    (Before the modification, result was equal to numOfSCKCyles-1).

    3) Re-build and test.

    Please give it a try and let me know your results.

    Best regards,

  • Hi Clément,

    Thank you for your response

    This indeed works, thank you.