This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

I2S 32-bit word size

Hello,

I am struggling with interfacing an I2S digital microphone to the nRF52. To be more concrete, it is the Knowles SPH0645LM4H-B. I connected it as suggested in this thread. In the data sheet of the microphone it says:

The SPH0645LM4H microphone operates as an I2S slave. The master must provide the BCLK and WS signals. The Over Sampling Rate is fixed at 64 therefore the WS signal must be BCLK/64 and synchronized to the BCLK. Clock frequencies from 2.048Mhz to 4.096MHz are supported so sampling rates from 32KHz to 64KHz can be had by changing the clock frequency. The Data Format is I2S, 24 bit, 2’s compliment, MSB first. The Data Precision is 18 bits, unused bits are zeros.

I find this contradictory with the figure also provided in the data sheet of the microphone:

image description

In the image it is clear to see that WS toggles first after 32 clocks, which -for me- means, the word size is 32 bits (18 bits data, 6 bits set to 0, and 8 further bits floating).

The problem is that the nRF52's I2S interface does not support 32-bit word size.

/**
 * @brief I2S sample widths.
 */
typedef enum
{
    NRF_I2S_SWIDTH_8BIT  = I2S_CONFIG_SWIDTH_SWIDTH_8Bit,  ///< 8 bit.
    NRF_I2S_SWIDTH_16BIT = I2S_CONFIG_SWIDTH_SWIDTH_16Bit, ///< 16 bit.
    NRF_I2S_SWIDTH_24BIT = I2S_CONFIG_SWIDTH_SWIDTH_24Bit,  ///< 24 bit.
} nrf_i2s_swidth_t;

No matter what settings I try with the available 8, 16, or 24 bit word-size, I can't get all the relevant data bits from the microphone's data stream.

Any ideas how to solve this problem? Or are these two components (nRF52 and Knowles mic) simply incompatible?

Thank you in advance! NewtoM

  • Hi NewtoM,

    In I2S-master mode, there are restrictions on the sample width (taken from the nRF52832 I2S spec):

    In Master mode, the size of a half-frame (in number of SCK periods) equals the sample width (in number of bits), and in this case the alignment setting does not care as each half-frame in any case will start with the MSB and end with the LSB of the sample value.

    In slave mode, however, the sample width does not need to equal the frame size. This means you might have extra or fewer SCK pulses per half-frame than what the sample width specified in CONFIG.SWIDTH requires.

    The nRF52832 can accept 24 bits in 32 bit sample width if it is in I2S-slave mode, but not in master mode.

    However: Are you sure that this sensor assumes 32 bit sample width? The datasheet states that it support 24 bits I2S, and the figure that you posted is the only place it mentions 32 bits. Have you verified this with the component manufacturer?

    Cheers, Håkon

  • Hi Håkon,

    thanks for your reply!

    If I understand you correctly, if I use the nRF52 as I2S slave, I could possibly receive the 24 bits data from the 32 bit sample. The problem is that the I2S microphone does not provide a clock. And even if I would provide the clock from the slave nRF52 (possible, based on the specs), I don't see how I could set it up to provide 32 SCLKs per sample. (That gets back to the problem of missing possibility for using 32 bit word size.)

    As for the reliability of the information, well, the information I showed above is pretty much everything from the data sheet. Should you have some free minutes, have a look: "Knowles SPH0645LM4H-B data sheet". I will try to get in touch with them, too.

    Thanks! NewtoM

  • Hi Håkon,

    first of all, I haven't got any response from Knowles for my inquiry during the last 45 hours (EDIT: 300 hours). In the meantime I spent quite some time testing with the oscilloscope, trying to make things work, but it was a waste of time.

    Here are the three main setups I used:


    Setup 1:

    #define I2S_CONFIG_MASTER       NRF_I2S_MODE_MASTER
    #define I2S_CONFIG_FORMAT       NRF_I2S_FORMAT_I2S
    #define I2S_CONFIG_ALIGN        NRF_I2S_ALIGN_LEFT
    #define I2S_CONFIG_SWIDTH       NRF_I2S_SWIDTH_24BIT
    #define I2S_CONFIG_CHANNELS     NRF_I2S_CHANNELS_LEFT
    #define I2S_CONFIG_MCK_SETUP    NRF_I2S_MCK_32MDIV10   // -> 32 MHz / 10 = 3.2 MHz (master clock)
    #define I2S_CONFIG_RATIO        NRF_I2S_RATIO_48X      // -> 3.2 MHz / 48 = 66667 Hz (sampling rate)
                                                           // -> SCLK= 2*66667*16= 3.2 MHz (sample clock)
    

    SCLK provided as BCLK (bit clock) for the mic. I see no data on the data line with the scope:

    Ratio_48x


    Setup 2:

    #define I2S_CONFIG_MASTER       NRF_I2S_MODE_MASTER
    #define I2S_CONFIG_FORMAT       NRF_I2S_FORMAT_I2S
    #define I2S_CONFIG_ALIGN        NRF_I2S_ALIGN_LEFT
    #define I2S_CONFIG_SWIDTH       NRF_I2S_SWIDTH_24BIT
    #define I2S_CONFIG_CHANNELS     NRF_I2S_CHANNELS_LEFT
    #define I2S_CONFIG_MCK_SETUP    NRF_I2S_MCK_32MDIV10   // -> 32 MHz / 10 = 3.2 MHz (master clock)
    #define I2S_CONFIG_RATIO        NRF_I2S_RATIO_96X      // -> 3.2 MHz / 96 = 33333 Hz (sampling rate)
                                                           // -> SCLK= 2*33333*24= 1.6 MHz (sample clock)
    

    MCLK provided as BCLK for the mic (to make sure bit clock is 96x faster than word [aka left/right] clock). Sometimes I see some bits with the scope, but nothing stable:

    Ratio_96x


    Setup 3:

    #define I2S_CONFIG_MASTER       NRF_I2S_MODE_MASTER
    #define I2S_CONFIG_FORMAT       NRF_I2S_FORMAT_I2S
    #define I2S_CONFIG_ALIGN        NRF_I2S_ALIGN_LEFT
    #define I2S_CONFIG_SWIDTH       NRF_I2S_SWIDTH_16BIT
    #define I2S_CONFIG_CHANNELS     NRF_I2S_CHANNELS_LEFT
    #define I2S_CONFIG_MCK_SETUP    NRF_I2S_MCK_32MDIV10   // -> 32 MHz / 10 = 3.2 MHz (master clock)
    #define I2S_CONFIG_RATIO        NRF_I2S_RATIO_64X      // -> 3.2 MHz / 64 = 50000 Hz (sampling rate)
                                                           // -> SCLK= 2*50000*16= 1.6 MHz (sample clock)
    

    MCLK provided as BCLK for the mic (to make sure bit clock is 64x faster than word clock). Please note that this is the setup (BCLK/WCLK ratio = 64), which is required for the I2S microphone, as its specification states. Here, the data is fully visible on the scope (and it also changes plausibly with varied input to the microphone):

    Ratio_64x

    Now the problem here is, that I need to specify SWIDTH=16 in the nRF52's I2S setup to make this work. I expected to get at least the 16 most significant bits in the I2S data handler, but that is not what I get. The data delivered by the EasyDMA is some scrambled variant of the audio samples. One can guess what was recorded, but the bits keep being shifted back and forth and you cannot safely extract the bits you want.

    And this is the point where I give up and declare the Knowles SPH0645LM4H-B to be incompatible with the current version of the nRF52.

    Should one day the nRF52 support 32-bit word length (NRF_I2S_SWIDTH_32BIT) or Knowles build an I2S microphone with 24-bit word length, then they may work together.

  • In the last screenshot, you can see that the sensor replies, with a bit width of approx. 0.5 us, which gives 32 bits per LRCLK period. It looks like your conclusion is correct, as the nRF52832 cannot accept 32 bit width in master mode.

  • Just a comment, maybe for further HW and/or SW versions. After some search, it seems that the requirements a) 32-bit word length and b) 64x SCLK/LRCLK ratio are pretty common. At least, the InvenSense ICS43434 also uses these settings.

    Plus, I've found a good alternative using PDM microphones, see this thread for more.

Related