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.

CC2640R2F: CC2640R2F: Microphone sampling rate

Genius 9345 points
Part Number: CC2640R2F

My customer would like to adjust the microphone clock to be 1.536MHz which is 96x the sampling rate.

I believe the clock adjustment is shown in the TRM as:

The frequency of the three clock signals in the I2S module can be set individually to a ratio of the MCUCLK by using the clock division registers PRCM:I2SMCLKDIV.MDIV, PRCM:I2SBCLKDIV.BDIV, and PRCM:I2SWCLKDIV.WDIV.

To obtain the clock frequency for MCLK and BCLK, the PRCM:I2SBCLKDIV.BDIV and PRCM:I2SWCLKDIV.WDIV bit fields are used directly as the denominators to divide the MCUCLK as in the following:

• MCLK = MCUCLK / MDIV [Hz]

• BCLK = MCUCLK / BDIV [Hz]

so, the closest they can get is BDIV of 31 which gives them 1.548MHz.

I assume this is the closest they can get. Is there anything else they need to twiddle to change the clock besides this?

Thanks!

  • Hi,
    I'm assigning this thread to one of our experts. Stay tuned for a response.
  • Hi,

    I got some feedback from the RnD team;

    To begin, and just to avoid any confusion, I think you made a typo in your question: if you want to set MCLK frequency (which is an optional signal for I2S) you need to modify PRCM:I2SMCLKDIV.MDIV bit field. If you want to set BCLK and WCLK frequency (which are both required for I2S), you have to modify the PRCM:I2SBCLKDIV.BDIV and PRCM:I2SWCLKDIV.WDIV bit fields.

    With that said, to obtain the clock frequency for MCLK and BCLK, the PRCM:I2SBCLKDIV.BDIV and PRCM:I2SMCLKDIV.MDIV bit fields are used directly as the denominators to divide the MCUCLK (48.00Mhz) as in the following:

    • MCLK = MCUCLK / MDIV [Hz]

    • BCLK = MCUCLK / BDIV [Hz]

    So, yes, the closest they can get is BDIV of 31 which gives them 1.548MHz. If they decide to set MDIV to 31 as well, they will also have MCLK frequency at 1.548MHz.

    Now, regarding WCLK clock frequency, the setting is a bit different: it depends on the phase type chosen (i.e. the content of I2SCLKCTL.WCLK_PHASE). The following only concerns dual phase mode (i.e. I2SCLKCTL.WCLK_PHASE = 1): each phase on WCLK (50% duty cycle) is WDIV[9:0] (unsigned, [1-1023]) BCLK periods. In other words:

    • WCLK = MCUCLK / BDIV*(2*WDIV[9:0]) [Hz]

    So if they set 48 into WDIV, they will have WCLK half-period lasting 48 BCLK periods (i.e. WCLK frequency will be 2*48 smaller than BCLK frequency). If BCLK frequency is 1.548MHz, they will get approximately a sampling frequency of 16.4kHz.

    (Don’t forget to write CLKLOADCTL.LOAD for the changes on PRCM:I2SMCLKDIV.MDIV, PRCM:I2SBCLKDIV.BDIV, and PRCM:I2SWCLKDIV.WDIV take effect.)

    To finish, I see one potential caveat: make sure that the data are sent on the right part of the WCLK period. I mean, here you will receive 16 “useful” bits per half-period and 32 “useless” bits (probably set to zero). So it will be maybe required to modify AIFFMTCFG. DATA_DELAY to store the “useful” bits only. (I let you search for “AIFFMTCFG”, “LJF” and “RJF” in the TRM for details)

  • Hi Joakim,

    Thanks for the detailed response.

    The current PDM driver I understand uses BCLK to drive the external microphone right? My understanding is with the BDIV of 47 shown below we derive a clock of 1.021MHz to send to the microphone.

    /* The following are constants that apply to PDM */
        object->sampleRate = -1;                                                  /* If negative then use user configured clock division */
        object->audioClkCfg.wclkDiv = 16;                                            /* I2S Word Clock divider override*/
        object->audioClkCfg.sampleOnPositiveEdge = PDMCC26XX_I2S_SampleEdge_Postive; /* I2S Sample Edge */
        object->audioClkCfg.wclkPhase = PDMCC26XX_I2S_WordClockPhase_Dual;           /* I2S Word Clock Phase */
        object->audioClkCfg.wclkInverted = PDMCC26XX_I2S_ClockSource_Normal;         /* I2S Invert Word Clock */
        object->audioClkCfg.wclkSource = PDMCC26XX_I2S_WordClockSource_Int;          /* I2S Word Clock source */
        object->audioClkCfg.bclkDiv = 47;                                            /* I2S Bit Clock divider override */
        object->audioClkCfg.reserved = 0;
        object->audioClkCfg.bclkSource = PDMCC26XX_I2S_BitClockSource_Int;           /* I2S Bit Clock source */
        object->audioClkCfg.mclkDiv = 6;   

    I figured for the customer to use a 1.536MHz clock this is the bit clock that would need to be altered to 1.536MHz which seems difficult given the granularity of the clock dividers.

    So, I think the BDIV is what needs to be manipulated right?

    I think the MCLK is like a master clock to drive the PDM microphone?

    Please clarify. Thanks for the info on the CLKLOADCTL.LOAD . I will caution the customer to take care of this too.

    There is documentation about changing BCLK (and WCLK) source from internal (using MCU clock) to external. What does flipping that bit really do? Which pin is then used as source of BCLK?

    Thanks!

  • Hey,

    Got some more responses (next round i'm looping in him directly);

    Sorry, but I didn't understand that your goal was to use PDM (I thought you were using the classic I2S). So:

    - Yes, the current PDM driver uses BCLK to provide the clock to the microphone (bit-clock frequency used is 1.021MHz, the closest value to 1.024MHz). So yes, BDIV must be manipulated to change the sampling frequency.

    - I don't know what role MCLK clock is supposed to play (because it is completely dependent on the microphone used). You should take a look at the data sheet of your PDM microphone to see if you need this signal, maybe you don't need it; maybe you need a specific frequency. In any case, you can tweak PRCM:I2SMCLKDIV.MDIV to get the MCLK frequency you want.

    - You do not need to modify PRCM:I2SWCLKDIV.WDIV. The PDM driver is designed to use 16 bits per WCLK half period, regardless of the BCLK frequency chosen.

    I would like to draw your attention to the fact that the decimation filter provided by TI (to decimate PDM data in PCM data) is not adapted to your sampling frequency (the only frequencies available are ~1.024MHz and ~2.048MHz). Using the decimation filter provided by TI with a sampling rate of 1.536MHz could give you poor audio quality and you will probably not get the decimation factor you want.

    Concerning the question of changing the source of I2S clocks to an external source:

    - Generally speaking, yes it is possible (it will be necessary to modify AIFWCLKSRC.WCLK_SRC, I2SBCLKSEL.SRC and configure the I2S pins slightly differently). In this case, data are read/write on the data lines with regard to the provided clocks (i.e. if the external clocks are stopped no data are read/write, if the external WCLK clocks runs at 16kHz, sampling frequency is 16KHz whatever your frequency settings are ==> one caveat exist, the configurations set into I2S:AIFFMTCFG must meet the characteristics of your external clocks)

    - BUT, for the PDM driver, it's a little more delicate. In fact, the driver is only available in "Master" mode (i.e. the clocks are generated internally). If you want to hack the driver and use the CC26XX/CC13XX as a slave, the PDM microphone will have to provide two clocks: BCLK and WCLK (the WCLK signal is 32 times slower than the BCLK clock). In this case, CC26XX/CC13XX does not require the MCLK signal.

    - For your information, the clock source selection is done for all I2S clocks. For example, you cannot generate an internal MCLK clock and rely on externally generated WCLK and BCLK signals.

    Note: On CC26XX/CC13XX, you can use any PIN for I2S pins, regardless of whether you use internal or external clocks.

  • Hi Joakim

    The customer has now decided that they would like a sampling rate of 2.4MHz which is easily supported by setting up BDIV. But as mentioned above the PDM decimation filter does not natively support this rate. They have already observed degradation of audio quality in the test they have run with this case. So, they would like to modify the PDM driver to support their sampling rate.

    There seems to be the following steps needed:

    1. static const int32_t PDMCC26XX_aBqCoeffs[]: This defines the low-pass filter needed to downsample. This would need to be altered to address the change in sampling rate.

    2. bool pdm2pcm16k(const void* pIn, uint32_t* pState, const int32_t* pBqCoeffs, int16_t* pOut);: This contains the implementation to convert pdm to 16KHz pcm data, but the implementation is not provided in the SDK.

    Is there any reference to make these changes? What about the #2 for which no code is provided.

    Thanks!

  • Hi,

    I understand that your customer now wants a sampling rate of 2.4MHz and decimate the data to get 16kHz PCM data.

    First, an important point. TI provides two decimation filters named pdm2pcm16k and pdm2pcm8k. The name of these filters can be a little misleading since these filters are designed to obtain a PCM signal at 16 kHz and 8 kHz only if the PDM signal has a sampling rate of 1.024MHz. In fact, these two filters are designed to decimate the input signal by 64 (1.024MHz/64=16kHz) or 128 (1.024MHz/128=8kHz).
    I would now like to highlight an important point. Changing the coefficients contained in PDMCC26XX_aBqCoeffs[] does NOT allow you to change the decimation factor of our filters at all (it will only change the quality of the decimation by rejecting more or less noise or allows you to amplify/reduce certain frequencies). To modify the decimation factor of a filter, you must modify the filter code itself (i.e. the code of pdm2pcm16k or pdm2pcm8k), which is far from trivial (including if you have access to the source code).

    This brings me to the second point. TI has chosen not to publish the code of its decimation filters. However, (as I said earlier) even with access to the source code, you will not really be able to easily reach "any" decimation factor (typically 150[2.4MHz/150 = 16kHz]). To explain it simply, decimation by a factor of 2 power N is much simpler and faster than a decimation by a "random" value (among other things for signal processing reasons). I don't have any reference explaining how to make these changes for you, sorry (I would almost suggest to rewrite from scratch the filter).

    A quick question / suggestion: why use a 2.4MHz sampling rate (which requires a decimation factor of 150) and not a 2.048 MHz sampling rate (which would require a decimation factor of 128)? It is true that it will not be possible to have exactly 2,048MHz (but 2,000 MHz), but you will be able to use the decimation filter pdm2pcm8k directly (reminder, pdm2pcm8k has a decimation factor of 128). Depending on the constraints of the application, this solution may have to be considered.

    EDIT: I made a mistake when I wrote that TI did not publish the source code of the decimations filters. This was indeed the case in the past but if you download a more recent version of the SDK you will find the decimations filters in source\drivers\pdm

    Best regards,

  • Hi Clement,

    Thanks for the explanation. I suspected that the changes are not trivial. I have advised them to use the 2MHz but since it will be slightly offset from 2.048MHz they are suspecting they may still have some audio issues due to the slight offset.

    Also, the PDM driver documentation doesn't cite the support for 2Mbps stream. It only specifically mentions the 1.024Mbps rate support. Can you clarify why?

    Thanks!

  • Hi,

    With regard to potential audio problems due to the delay between 2MHz and 2.048MHz, my advice would be to test. Depending on the application and the material used, it may be inaudible or very disturbing.

    Concerning your remark on the lack of documentation about the support of the 2Mbps stream, my expertise is limited. I mean, it’s a fact we do not document the 2Mbps stream support but at the same time we do not provide this frequency “out of the box” (this requires the customer to modify the PDM driver to have a different frequency). But be indulgent, it is always difficult to keep a driver easy to use and at the same time adapted to as many requirements as possible :)

    Regards,