Using INMP441 I2S Microphone

Status
Not open for further replies.

edumana

New member
I am trying to get the INMP441 I2S digital microphone working with the Teensy 3.1. The mic has good S/N Ratio and I don't need pre-amps etc..., so it really simplifies design. If I can get it working that is.... I have written some code because the Audio Library is not really set up to use this microphone due to clock specifics. The data sheet is here:

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

My code is:

Code:
    ... Clock & Pin init, etc... 
     
    //Receive Init
    I2S0_RCSR = 0x0;                  //Disable Receive as per Data sheet
    I2S0_RCR1 |= 0x1;                 //Sets FIFO Watermark to 1 
    I2S0_RCR4 |= 0x11F19;          //Internal Frame Sync. MSB. Early Frame Sync. SYWD = 32. FRSZ = 2.  
    I2S0_RCR5 |= 0x1F1F1F00;     //32 Bits per Word. 32 Bits in First Word. Shifted 32.  (The Mic really sends 24, could this be the problem?)

    I2S0_RCSR = 0x4000000;       //FIFO Reset
    I2S0_RCSR |= 0x80000100;    //Enable I2S and FIFO Enable 
          
    while(1){
         delay(1);
         pr(&I2S0_RDR0);               //This reads register contents (Data?)
         led_red = 0;
    }

I checked with the oscilloscope. I know that the Frame Sync and Bit Clock are working properly (64 clocks per frame, 2 words per frame), and also that the Microphone is indeed returning data in the serial data line. The receiver (Teensy) mode is asynchronous, which I decided from pg. 1324 of Manual.

The issue is that the I2S0_RDR0 register doesn't show any data, just a 0. I have tried both L and R channels and no luck.
 
I would also like to use this microphone but I haven't progressed as far as Edumana. Is there a simple way to configure the port pins and clocks for this microphone?

I am beginning to understand a bit of this. It looks like I could configure many of the pins to enable their alternate I2S functions, not just pins 5, 9, and 23 as fixed in the Audio library. I would have to configure the bit clock and frame select clocks for 48 kHz or whatever, specify 32 bits per word, enable the FIFO, etc. as edumana has done above.

It looks a bit complicated but I think I will give this a try and report how it goes...

The Mic really sends 24, could this be the problem?

The mic sends 24 bits of information with an 8-bit pad for each 32 bitclock cycles that make up half the 64-bit data frame, two 32-bit words (L and R) per 64-bit frame. If the microcontroller is receiving 32 bits per serial word per frame it should still appear as something other than zeroes.

And as per the mic data sheet aren't there requirements for a 1-bit delay, whether the 8-bit pad is MSB or LSB, whether the word is read on rising or falling edges. This is really rather complicated it seems to me. Are all of these requirements configured by the "key code" in the application note?

Data Word Length
The output data word length is 24 bits per channel.
The INMP441 must always have 64 clock cycles for every stereo data
-word (fSCK=64×fWS).
Data-Word Format
The default data format is I²S (two’s complement), MSB-first.
In this format, the MSB of each word is delayed by one SCK cycle from
the start of each half-frame.

Shouldn't the FIFO watermark be set at 4 or 6 as per the Application Note?
 
Last edited:
There is the FSE bit in RCR4 that you can set for the frame to assert early. About watermark I am not sure. The application note is 4, but in the Audio library Paul sets it to 1 or 2 I believe. I think it depends if you are doing stereo, which my code is not trying to do. Also, the correct way of polling the Data register is:

Code:
if(I2S0_RCSR&0x10000){      //check the FIFO Request Flag
        pr(&I2S0_RDR0);         //Prints register address and contents
        led_red = 0;
}

I think we are close!
 
I think I am making some progress on this.

First an embarrasing admission. I made an error in the board and switch SD and WS. Fortunately this is easy to correct on the breadboard. New board designed and in the fab. Next, my colleague adapted an I2S CODEC function to read I2S data from the Teensy 3.1 which seems to work; at least it looks like we are getting serial data out of the microphones. I haven't analyzed it properly yet with an oscilloscope. I just wanted to report that we are making progress in case anyone else is stuck like we were.

I will post a link to GitHub where a simple sketch resides that allows serial data to be read via I2S from these microphones...
 
Last edited:
Hi, did anyone get anywhere with this?

I've one of the INMP441 breakout boards connected to a Teensy and it produces a bitstream to Serial, but I'm not sure how to analyse that data (or even how to tell if it is valid).

What I'd like to do with it is chuck it through an FFT and get a spectrogram (as per the Adafruit example), then use the spectrogram to generate patterns for my LED staff. Ideally, someone has a library that can go straight from an I2C bitstream to an FFT, but all that I have found (e.g. ArduinoFFT) require an audio input to an ADC pin, rather than just digital all the way through.

So any suggestions?
 
First, I would recommend switching to the ICS43432 for any serious work. Second, the cyborg ears project uses these mics and can provide some technical assistance if you ask them nicely (search the forum). Lastly, here is the advice I received from one of them for reading the serial I2S data captured from a Serial monitor (of shunted to a file on linux) from these mics using Audacity:

import it in Audacity like this:
>> File->Import->Raw data in the main menu.
>> Magic settings here are:
>> - Codec: Signed 24 Bit PCM
>> - Byte-order: Big Endian (!)
>> - Channel: 2 Stereo
>> - 0 Byte offset: 336 (explained below)
>> - 100%
>> - sampling frequency: 48000

Although I could never get it to work myself on my XP machine. if you discover a better way to play back and manipulate the sound, please share.
 
Status
Not open for further replies.
Back
Top