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

Parents
  • 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.

Reply
  • 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.

Children
Related