[SAI1 RX Issue] INMP441 Microphone connected via I2S, but RX only yields static data or errors

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

[SAI1 RX Issue] INMP441 Microphone connected via I2S, but RX only yields static data or errors

905 Views
WeberF
Contributor II

Hello everyone,

I'm currently working on a project using the FRDM-MCXN947 board and trying to interface an GY-INMP441 digital MEMS microphone via the SAI1 peripheral (I2S RX).

So far, I’ve taken the following steps:

  • Connected the INMP441 (SD to SAI1_RXD0, SCK to SAI1_RX_BCLK, WS to SAI1_RX_SYNC)

  • Supplied the microphone with 3.3 V and confirmed correct wiring

  • Used the MCUXpresso SDK and initialized SAI1 as I2S Master Receiver

  • Configured:

    • Clock source: 48 MHz FRO via CLOCK_AttachClk(kFRO_HF_to_SAI1)

    • Bit width: 24 bits (though tried 32 for alignment as well)

    • SAI1 DIV ends up being 46

  • Enabled SAI RX with SAI_RxEnable()

  • Tried both SAI_TransferReceiveNonBlocking() and SAI_ReadBlocking()

  • Observed the SD line on the oscilloscope – it shows far more activity when I blow into the microphone, suggesting it does send data.

However, I’m running into the following issues:

  • SAI_RX_ERROR is constantly triggered in the callback

  • When reading via SAI_ReadBlocking(), I either get repeated values (e.g., 0x401070A0) or just 0x00000000

  • FIFO status bits (RDRF) don’t reliably indicate valid data

  • Sign-extension and byte-shifting yields nonsensical or static sample values

  • The RCR2 register seems to apply the DIV value during setup, but I don't see meaningful variation in the received data

Despite confirming signal presence on BCLK, FS, and SD lines via oscilloscope, I can’t get valid, dynamic data from the microphone. I’ve also played with several .dataFirstBitShifted, FIFO packing, and wordLength settings without luck.


My questions:

  1. Has anyone successfully connected an INMP441 to the MCXN947 via SAI1?

  2. Is there anything specific I need to watch out for regarding SAI bitclock or word alignment with 24-bit microphones?

  3. Could the issue lie in the RCR2.DIV or bit-packing configuration?

  4. Is there a minimal working example (MWE) for I2S RX using SAI1 in Master mode with external BCLK/FS?


I would greatly appreciate any guidance, sample projects, or even tips for debugging SAI reception with this setup. Thank you in advance for your help!

I uploaded the project in the attachments. You may check the following files:
peripherals.c/h
pin_mux.c/h
clock_config.c/h
and the main file hello_world.c (i just used this demo, because of missing i2s/sai demos)

Sorry for this mess but im pretty down right now

Best regards,

FWeber

Labels (2)
Tags (2)
0 Kudos
Reply
4 Replies

845 Views
Celeste_Liu
NXP Employee
NXP Employee

Hello @WeberF ,

Thanks for your post. You can refer to the https://mcuxpresso.nxp.com/appcodehub?search=dm-usb-audio-7-1-channel-speaker-on-mcxn947 project in application code hub.

This project uses SAI peripheral.

Hope it can help you.

BRs,

Celeste

829 Views
WeberF
Contributor II

Thanks Celeste,

but sadly not. I guess it is a problem with the frequency on the bus or a wrong configuration of the SAI1_rx_config 

Well i have a frequency on my SCLK & SYNC but these are way to high. The calculated frequency from SAI_RxSetBitClockRate is not on my bus.

 

sai_transceiver_t SAI1_Rx_config = {

.masterSlave = kSAI_Master,

.bitClock = {

.bclkSrcSwap = false,

.bclkSource = kSAI_BclkSourceBusclk,

.bclkPolarity = kSAI_SampleOnRisingEdge,

.bclkInputDelay = false

},

.frameSync = {

.frameSyncWidth = 32U,

.frameSyncPolarity = kSAI_PolarityActiveLow,

.frameSyncEarly = true,

.frameSyncGenerateOnDemand = false

},

.syncMode = kSAI_ModeAsync,

.channelMask = kSAI_Channel0Mask | kSAI_Channel1Mask,

.startChannel = 0U,

.endChannel = 1U,

.channelNums = 2U,

.serialData = {

.dataMode = kSAI_DataPinStateTriState,

.dataWord0Length = (uint8_t)kSAI_WordWidth32bits,

.dataWordNLength = (uint8_t)kSAI_WordWidth32bits,

.dataWordLength = (uint8_t)kSAI_WordWidth32bits,

.dataOrder = kSAI_DataMSB,

.dataFirstBitShifted = 32U,

.dataWordNum = 1U,

.dataMaskedWord = 0x0U

},

.fifo = {

.fifoWatermark = 4U,

.fifoCombine = kSAI_FifoCombineDisabled,

.fifoPacking = kSAI_FifoPackingDisabled,

.fifoContinueOneError = true

}

};

sai_master_clock_t SAI1_MCLK_config = {

.mclkOutputEnable = false,

.mclkSourceClkHz = SAI1_MCLK_SOURCE_CLOCK_HZ,

.mclkHz = SAI1_USER_MCLK_HZ

};

 

static void SAI1_init(void) {

/* Initialize SAI clock gate */

SAI_Init(SAI1_PERIPHERAL);

/* Configures SAI Rx sub-module functionality */

SAI_RxSetConfig(SAI1_PERIPHERAL, &SAI1_Rx_config);

/* Set up SAI Rx bitclock rate by calculation of divider. */

SAI_RxSetBitClockRate(SAI1_PERIPHERAL, SAI1_RX_BCLK_SOURCE_CLOCK_HZ, SAI1_RX_SAMPLE_RATE, SAI1_RX_WORD_WIDTH, SAI1_RX_WORDS_PER_FRAME);

/* Enable selected Rx interrupts */

SAI_RxEnableInterrupts(SAI1_PERIPHERAL, (kSAI_SyncErrorInterruptEnable | kSAI_FIFOErrorInterruptEnable | kSAI_FIFORequestInterruptEnable));

/* Enable interrupt SAI1_IRQN request in the NVIC */

EnableIRQ(SAI1_IRQN);

}

0 Kudos
Reply

828 Views
WeberF
Contributor II
Oh these are the values for the functioncall
#define SAI1_RX_BCLK_SOURCE_CLOCK_HZ 48000000UL
/* Sample rate used for calculating the bit clock divider in the RxSetBitClockRate function. */
#define SAI1_RX_SAMPLE_RATE 48000UL
/* Word width used for calculating the bit clock divider in the RxSetBitClockRate function. */
#define SAI1_RX_WORD_WIDTH 32U
/* Number of words within frame used for calculating the bit clock divider in the RxSetBitClockRate function. */
#define SAI1_RX_WORDS_PER_FRAME 1U

So the calculated frequency should be at 1.536 MHz right?
0 Kudos
Reply

800 Views
Celeste_Liu
NXP Employee
NXP Employee

Hello @WeberF ,

According to the parameters you provided, the theoretical bit clock frequency calculation is indeed 1.536 MHz. However, I have checked the INMP441 datasheet(INMP441 Datasheet by TDK InvenSense | Digi-Key Electronics), which is a 24-bit device. I suggest that you should not configure a 32-bit word length. Please try to modify all word length-related parameters to 24 bits.

        .dataWord0Length = (uint8_t)kSAI_WordWidth24bits,  
        .dataWordNLength = (uint8_t)kSAI_WordWidth24bits,  
        .dataWordLength = (uint8_t)kSAI_WordWidth24bits,
#define SAI1_RX_WORD_WIDTH 24U

 

And Try to reduce the frame sync width,

.frameSyncWidth = 24U,

 

For 24-bit data, try setting the data shift configuration to 8 or 0.

.dataFirstBitShifted = 8U, //0U

 

Try enabling the FIFO packing:

.fifoPacking = kSAI_FifoPackingEnabled,

 

The INMP441 typically requires an MCLK input, but your configuration has disabled the MCLK output. Please make the necessary modifications.

sai_master_clock_t SAI1_MCLK_config = {
    .mclkOutputEnable = true,           
    .mclkSourceClkHz = SAI1_MCLK_SOURCE_CLOCK_HZ,
    .mclkHz = 2457600UL                
};

 

Since I don't have the same environment here, can you help modify the code and conduct the test? You can modify the code and then use an oscilloscope to check if the BCLK is 1.152MHz, and confirm whether the WS signal matches the data.

Hope it can help you.

BRs,

Celeste

 

 

0 Kudos
Reply