I2S Microphone and K22F

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

I2S Microphone and K22F

Jump to solution
1,635 Views
eduardoumana
Contributor III

I am trying to set up the INMP441 digital I2S microphone with the Kinetis K22F Freedom Board. The microphone data sheet is at:

http://www.invensense.com/mems/microphone/documents/INMP441.pdf

I have been able to implement the correct settings for the Bit Clock and Frame Sync (64 clocks per frame, 2 words per frame, etc...) through the 5 I2Sx_RCR registers. I am now trying to quickly obtain data from the microphone but have not been successful. Here is my code.

    CHIPEN = 1;

    L = 1;

    //Pins Init

    SIM_SCGC5 |= 0x42B82;       //Enables PORTC

    PORTC_PCR5 |= 0x400;        //PTC5 --> I2S0_RXD0 -> DATA (coming from Microphone)

    PORTC_PCR7 |= 0x400;        //PTC7 --> I2S0_RX_FS -> FRAME (Sent to Microphone)

    PORTC_PCR9 |= 0x400;        //PTC9 --> I2S0_RX_BCLK -> BITCLOCK (Sent to Microphone)

    //Clock Init

    SIM_SCGC6 |= 0x8000;            //Turn on I2S Clock Gate

    SIM_SOPT2 |= 0x30000;           //I2S Clocking Sourced from 48MHz IRC48MCLK

    I2S0_MCR |= 0x43000000;      //Output Enable. Mux IRC48MCLK into Fractional Divider

    I2S0_RCR2 |= 0x4000000;       //MCLK MSEL to BCLK

    I2S0_MDR |= 0x1F07C;            //Set I2S Master Clock to 12.2880MHz

    I2S0_RCR2 |= 0x300000D;       //DIV is 13 - > 9000kHz Sample Rate. BCD = 1

    SIM_SCGC6 |= 0x8000;             //Re-Enable I2S Module

    //Receive Init

    I2S0_RCSR = 0x0;                      //Disable Receive as per Datasheet

    I2S0_RCR1 |= 0x1;                    //Sets FIFO Watermark to 1

    I2S0_RCR3 |= 0x10000;            //Enable Receive Data Channel

    I2S0_RCR4 |= 0x11F19;            //Internal Frame Sync. Early Frame Sync. 32 SYWD. FRSZ 2.

    I2S0_RCR5 |= 0x1F1F1F00;       //32 Bits per Word. 32 Bits in First Word. Shifted 32.

    I2S0_RCSR = 0x2000000;          //FIFO Reset

    I2S0_RCSR |= 0x80000100;       //Enable and FIFO Enable

 

while(1) {

        if(I2S0_RCSR & 0x10000){

            pr(&I2S0_RDR0);               //Reads content from data register, problem is that is constantly 0

            led_red = 0;

        }

    }

}

The problem is that the I2S0_RDR0 register is stuck at 0. So evidently I am not getting data from the microphone. Any ideas? (The microphone is indeed sending data on the right channel as confirmed with an oscilloscope)

Labels (1)
Tags (3)
0 Kudos
1 Solution
665 Views
eduardoumana
Contributor III

The FIFO was overflowing, an error flag was raised and never cleared so the FIFO didn't accept more data. The fix is setting FCONNT and clearing the error:

if(I2S0_RCSR & 0x10000){

            pr(&I2S0_RDR0); 

            led_red = 0;

        }       

        if (I2S0_RCSR & 0x20000){

            I2S0_RCSR |= 0x20000;

        }

View solution in original post

0 Kudos
6 Replies
665 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Eduardo,

has your issue fixed yet? If not, can you use interrupt mechanism to read the I2S0_RDR0 without FIFO?

BR

XiangJun Rong

0 Kudos
666 Views
eduardoumana
Contributor III

The FIFO was overflowing, an error flag was raised and never cleared so the FIFO didn't accept more data. The fix is setting FCONNT and clearing the error:

if(I2S0_RCSR & 0x10000){

            pr(&I2S0_RDR0); 

            led_red = 0;

        }       

        if (I2S0_RCSR & 0x20000){

            I2S0_RCSR |= 0x20000;

        }

0 Kudos
665 Views
eduardoumana
Contributor III

Some updates: The FIFO request flag is going high, so I am able to read I2S0_RDR0. However, the FIFO then overflows. The FIFO error flag rises.

Any hints as to how to keep the FIFO from overflowing?

0 Kudos
665 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Eduardo,

As you know that the RFW bits in I2Sx_RCR1 register specifies the watermark level, for example, if you set RFW bits as 3, once the FRF bit in I2Sx_RCSR register is set, you can read the I2S0_RDR register 4 times to empty the FIFO.

BR

XiangJun Rong

0 Kudos
665 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Eduardo,

Regarding your question, I do not think you have the code to poll the status register to check if the I2S has received the data, then read the I2S0_RDR0 register.

how about using the code:

     

    while(1){

       //  wait(0.01);

     if(I2S0_RCSR&0x10000) //check the FIFO Request Flag

{

         pr(&I2S0_RDR0);  //Prints register address and contents

         led_red = 0;

    }

I do not debug your code, pls have a try to test the code.

BR

XiangJun Rong

665 Views
eduardoumana
Contributor III

Unfortunately that didn't work. The FIFO request flag is not raised, so the contents of I2S0_RDR0 are never read.

I think the issue is the micro controller not "interpreting/receiving" the data because the microphone is indeed sending it. Two possible issues come to mind:

1) The data from the microphone should be connected to I2S0_RDX0, right?

2) The data sheet talks about enabling the receive channel to access the FIFO. Am I forgetting to enable a channel, a FIFO or something along those lines?

0 Kudos