gregeric
Posts: 1511
Joined: Mon Nov 28, 2011 10:08 am

Add an I2S mic using device tree & simple-audio-card

Sun Feb 05, 2017 3:44 pm

Here I'm using an ICS43432. Other I2S mics will likely work with the same steps & codec.

For wiring, see https://github.com/nejohnson2/rpi-i2s

For software, you can either follow the steps there, or do it the modern way here using a device tree overlay.

Firstly, get an updated kernel & matching kernel header files:

Code: Select all

sudo apt-get update
sudo apt-get dist-upgrade
sudo apt-get install raspberrypi-kernel-headers
sudo reboot
Next, while the upstream ics43432 codec is not currently supported by current Pi kernel builds, we must it build manually.

Get the source & create a simple Makefile:

Code: Select all

mkdir ics43432
cd ics43432
wget https://raw.githubusercontent.com/raspberrypi/linux/rpi-4.4.y/sound/soc/codecs/ics43432.c
nano Makefile
Makefile contents:

Code: Select all

obj-m := ics43432.o

all:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
	make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

install:
	sudo cp ics43432.ko /lib/modules/$(shell uname -r)
	sudo depmod -a
Those indentations are a single tab character - use spaces & it won't work.

Build:

Code: Select all

make all install
Next, we create a new device tree overlay. Create a file i2s-soundcard-overlay.dts with this content:

Code: Select all

/dts-v1/;
/plugin/;

/ {
    compatible = "brcm,bcm2708";

    fragment@0 {
        target = <&i2s>;
        __overlay__ {
            status = "okay";
        };
    };

    fragment@1 {
        target-path = "/";
        __overlay__ {
            card_codec: card-codec {
                #sound-dai-cells = <0>;
                compatible = "invensense,ics43432";
                status = "okay";
            };
        };
    };

    fragment@2 {
        target = <&sound>;
        master_overlay: __dormant__ {
            compatible = "simple-audio-card";
            simple-audio-card,format = "i2s";
            simple-audio-card,name = "soundcard";
            simple-audio-card,bitclock-master = <&dailink0_master>;
            simple-audio-card,frame-master = <&dailink0_master>;
            status = "okay";
            simple-audio-card,cpu {
                sound-dai = <&i2s>;
            };
            dailink0_master: simple-audio-card,codec {
                sound-dai = <&card_codec>;
            };
        };
    };

    fragment@3 {
        target = <&sound>;
        slave_overlay: __overlay__ {
                compatible = "simple-audio-card";
                simple-audio-card,format = "i2s";
                simple-audio-card,name = "soundcard";
                status = "okay";
                simple-audio-card,cpu {
                    sound-dai = <&i2s>;
                };
                dailink0_slave: simple-audio-card,codec {
                    sound-dai = <&card_codec>;
                };
        };
    };

    __overrides__ {
        alsaname = <&master_overlay>,"simple-audio-card,name",
                    <&slave_overlay>,"simple-audio-card,name";
        compatible = <&card_codec>,"compatible";
        master = <0>,"=2!3";
    };
};
Compile & install the overlay:

Code: Select all

dtc -@ -I dts -O dtb -o i2s-soundcard.dtbo i2s-soundcard-overlay.dts
sudo cp i2s-soundcard.dtbo /boot/overlays
Finally, invoke usage by adding this to /boot/config.txt:

Code: Select all

dtoverlay=i2s-soundcard,alsaname=mems-mic
Reboot and you'll have a microphone recording device

Code: Select all

pi@raspberrypi:~arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: memsmic [mems-mic], device 0: bcm2835-i2s-ics43432-hifi ics43432-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Make a 10 second long recording with:

Code: Select all

arecord -Dhw:1 -c2 -r48000 -fS32_LE -twav -d10 -Vstereo test.wav
The volume level is low, and with just one module attached is in one channnel only, silence in the other. Both those issues can be addressed by modifying .asoundrc, see the next post to follow.

The overlay is flexible enough to use other codecs by way of the compatible= override. If your preferred codec, a simple ADC or DAC, has a .compatible string defined, use that "manufacturer,chipset" string in the override. There's a switch "master" too if your codec is capable of working as clock master instead of the default slave (untested).

Composit
Posts: 6
Joined: Fri Feb 03, 2017 3:51 pm

Re: Add an I2S mic using device tree & simple-audio-card

Sun Feb 05, 2017 5:57 pm

Great "how to" - thanks.

After the following command I got warnigs:

Code: Select all

root@raspberrypi:~/ics43432# dtc -@ -I dts -O dtb -o i2s-soundcard.dtbo i2s-soundcard-overlay.dts
Warning (unit_address_vs_reg): Node /fragment@0 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /fragment@1 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /fragment@2 has a unit name, but no reg property
Warning (unit_address_vs_reg): Node /fragment@3 has a unit name, but no reg property
Is it of any meaning or just normal ?

Checking for the recording device looks fine:

Code: Select all

root@raspberrypi:~# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: memsmic [mems-mic], device 0: bcm2835-i2s-ics43432-hifi ics43432-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: Device [USB Audio Device], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
The USB Audio Device will be removed as soon as the mems-mic arrives and is connected to the RPi Zero. ;)

gregeric
Posts: 1511
Joined: Mon Nov 28, 2011 10:08 am

Re: Add an I2S mic using device tree & simple-audio-card

Sun Feb 05, 2017 6:13 pm

Yeah, I get those too but it all works :roll:

To create the soft mixer for volume control I used plugh's work, extending it so that we produce true mono/single channel output. Note that I've configured my mic as left - if yours is right you'll have to edit the mic_mono multi section. If you have a stereo pair, you may omit the last section where mic_mono is defined. Edit the alsa config:

Code: Select all

cd ~
nano .asoundrc
& add:

Code: Select all

pcm.mic_hw{
	type hw
	card memsmic
	channels 2
	format S32_LE
}
pcm.mic_mm{
	type mmap_emul
	slave.pcm mic_hw
}
pcm.mic_sv{
	type softvol
	slave.pcm mic_mm
	control {
		name "Boost Capture Volume"
		card memsmic
	}
	min_dB -3.0
	max_dB 50.0
}
pcm.mic_mono{
	type multi
	slaves.a.pcm mic_sv
	slaves.a.channels 2
	bindings.0.slave.a
	bindings.a.channel 0
}
To activate the mixer, we must first make a recording using the newly configured mic_sv pcm:

Code: Select all

arecord -Dmic_sv -c2 -r48000 -fS32_LE -twav -d10 -Vstereo test.wav
Now we can tinker with the boost control. In a terminal, run alsamixer, press F6, select device "mems-mic", then F4 for capture controls. A useful boost is 20-30dB.
A mixer is also in the desktop's Audio Device Settings.

Now when you make a new recording with -Dmic_mono in place of the raw -Dhw:1, & you will have boosted sound in both channels :)
Last edited by gregeric on Fri Mar 10, 2017 8:24 am, edited 1 time in total.

User avatar
Gavinmc42
Posts: 1814
Joined: Wed Aug 28, 2013 3:31 am

Re: Add an I2S mic using device tree & simple-audio-card

Mon Feb 06, 2017 2:39 am

Any idea if these would work?
https://www.invensense.com/products/ics-52000/

Current digital mics only allow left/right channels on i2s.
The 52000 would allow for up to 16 microphones.
With 4+ mics directional sounds could be analysised.

Interleaved data would need extracting.
I'm dancing on Rainbows.
Raspberries are not Apples or Oranges

gregeric
Posts: 1511
Joined: Mon Nov 28, 2011 10:08 am

Re: Add an I2S mic using device tree & simple-audio-card

Mon Feb 06, 2017 7:21 am

I saw that TDM device while I was searching for suitable microphones - looks similar to I2S. One or two might work, & I expect flatmax will know for sure if it's possible & how to connect them.

It should work with these: Invensense INMP441 (obsolete), ICS43432, ICS43434, & Knowles SPH0645. There may be others.

Composit
Posts: 6
Joined: Fri Feb 03, 2017 3:51 pm

Re: Add an I2S mic using device tree & simple-audio-card

Tue Feb 14, 2017 7:22 pm

gregeric wrote:Yeah, I get those too but it all works :roll:

To create the soft mixer for volume control I used plugh's work, adding the mapping from left to both channels (I've grounded the L/R pin, configuring it as left) so that sound comes out of both speakers. Edit the alsa config:

Code: Select all

cd ~
nano .asoundrc
& add:

Code: Select all

pcm.mic_hw{
	type hw
	card memsmic
	channels 2
	format S32_LE
}
pcm.mic_mm{
	type mmap_emul
	slave.pcm mic_hw
}
pcm.mic_rt{
	type route
	slave.pcm mic_mm
	ttable.0.0 1
	ttable.0.1 0
	ttable.1.0 1
	ttable.1.1 0
}
pcm.mic_sv{
	type softvol
	slave.pcm mic_rt
	control {
		name "Boost Capture Volume"
		card memsmic
	}
	min_dB -3.0
	max_dB 50.0
}
To activate the mixer, we must first make a recording using the newly configured mic_sv pcm:

Code: Select all

arecord -Dmic_sv -c2 -r48000 -fS32_LE -twav -d10 -Vstereo test.wav
Now we can tinker with the boost control. In a terminal, run alsamixer, press F6, select device "mems-mic", then F4 for capture controls. A useful boost is 20-30dB.
A mixer is also in the desktop's Audio Device Settings.

Now when you make a new recording with -Dmic_sv in place of the raw -Dhw:1, & you will have boosted sound in both channels :)

Today I got my ics43432. Wired it to the Zero followed the instructions regarding soft mixer and recorded a file.
Everything works fine.

There is just one issue left.
For playback I wired the I2S max98357 amplifier to the Zero.
https://learn.adafruit.com/adafruit-max ... p/overview
There are some I2S signals shared with the ics43432.

Both devices (mic and amp) make use of dtoverlay (defined in /boot/config.txt).
For max98357 it is: dtoverlay=hifiberry-dac
For ics43432 it is: dtoverlay=i2s-soundcard,alsaname=mems-mic

As long as only one I2S device is activated (commenting out one of the above lines in config.txt) everything works fine.
Either sound output through max98357 or sound inout through ics43432.

But having both dtoverlay definitions uncommented only the second entry gets read and the first one is skipped or overwritten.

Does anyone know if this is at all possible and what the configuration looks like to have both I2S modules working at the same time ?

For max98357 I had to create:
/etc/asound.conf

For ics43432 I had to create:
/root/ics43432i2s-soundcard-overlay.dts
/root/.asoundrc

and both have entries for:
/boot/config.txt

gregeric
Posts: 1511
Joined: Mon Nov 28, 2011 10:08 am

Re: Add an I2S mic using device tree & simple-audio-card

Tue Feb 14, 2017 7:42 pm

Glad it's working for you :)

In order to get both capture & playback working, I think you'll have to create a new, combined overlay using simple card (extending my one perhaps). Some hints at https://www.kernel.org/doc/Documentatio ... e-card.txt

Either that, or create your own machine driver & matching overlay. See https://github.com/raspberrypi/linux/tr ... nd/soc/bcm for machine driver sources of other Pi DAC/ADC boards.

Sorry, I am no expert here, having started from zero knowledge to get my mic up & running.

gregeric
Posts: 1511
Joined: Mon Nov 28, 2011 10:08 am

Re: Add an I2S mic using device tree & simple-audio-card

Wed Feb 15, 2017 4:19 pm

As a workaround, and if one or the other and not both at the same time is acceptable, you might have neither in config.txt. Instead use dynamic device tree - see section 3.5 at https://www.raspberrypi.org/documentati ... e.md#part3

You might then be able to load & use the capture codec. When playback is required, remove the first overlay, then load the other one corresponding to the playback codec.

Composit
Posts: 6
Joined: Fri Feb 03, 2017 3:51 pm

Re: Add an I2S mic using device tree & simple-audio-card

Wed Feb 15, 2017 8:04 pm

The project is about an intercom solution. So record and playback should be on simoultaneously.

I can load both dtoverlays - looks like this:

Code: Select all

pi@raspberrypi:~ $ sudo dtoverlay -l
Overlays (in load order):
0:  i2s-soundcard  alsaname=mems-mic
1:  hifiberry-dac
But there is always just one entry in /proc/asound/cards

Code: Select all

pi@raspberrypi:~ $ cat /proc/asound/cards
 0 [memsmic        ]: mems-mic - mems-mic
                      mems-mic
depending on the order the dtoverlays are loaded.

So I wonder how to tell Raspi to allow both sound devices at the same time.
It looks as if both devices are loaded as card 0.

Mixing 2 soundcards should be quite simple according to this description - if the two sound cards get registered by Pi:
https://bbs.archlinux.org/viewtopic.php?id=125913

Maybe I should open a new topic since this is no longer a mic problem ;)

gregeric
Posts: 1511
Joined: Mon Nov 28, 2011 10:08 am

Re: Add an I2S mic using device tree & simple-audio-card

Wed Feb 15, 2017 8:51 pm

Ah, didn't realise both overlays were loading. I still suspect the answer lies in extending the simple card overlay I presented to include both codecs you have connected, #sound-dai-cells = <1> etc.

I have a DAC & will endeavour to find time away from my current project to take a look.

Composit
Posts: 6
Joined: Fri Feb 03, 2017 3:51 pm

Re: Add an I2S mic using device tree & simple-audio-card

Wed Feb 15, 2017 9:08 pm

I agree. This seems to be the right approach.
But as you surely noticed - I'm absolutely not familiar with overlay code and there is not much documentation for it.

Would be awesome combining mic (ICS43432) and dac (max98357 or something similar) in the simple audio card overlay.

I look forward to hear from you - but don't abandon your other project ;)
Meanwhile I go on searching for additional information.

mbt28
Posts: 10
Joined: Wed Feb 04, 2015 10:35 am

Re: Add an I2S mic using device tree & simple-audio-card

Thu Feb 16, 2017 2:52 pm

Hi,

How is it possible to implement one mono input and one stereo input? I would like to include i2s fm receiver as stereo input.

Another question, can I use every pin configured as I2S in?

Many thanks

gregeric
Posts: 1511
Joined: Mon Nov 28, 2011 10:08 am

Re: Add an I2S mic using device tree & simple-audio-card

Thu Feb 16, 2017 10:14 pm

Hi - I'm not sure what you are asking with regards to mono plus stereo inputs. It's likely beyond the scope of my knowledge (TDM required?), and perhaps off topic for this thread.

mbt28
Posts: 10
Joined: Wed Feb 04, 2015 10:35 am

Re: Add an I2S mic using device tree & simple-audio-card

Mon Feb 20, 2017 11:56 am

Hi,

I mean, I would like to use a mono or stereo mic. In addition to that I would like to use an FM receiver over I2S. I suppose It should work with same logic as mic. So in this case 2-3 I2S in to the rpi, is it possible?

Thanks

gregeric
Posts: 1511
Joined: Mon Nov 28, 2011 10:08 am

Re: Add an I2S mic using device tree & simple-audio-card

Mon Feb 20, 2017 12:06 pm

The ics32432 is designed to work singly, or as a stereo pair. There is no ENABLE input to turn them off, so I don't see how they could be used simply with another capture codec like your I2S FM part. External circuitry may be required: perhaps you can use a GPIO plus p-channel MOSFET to power it (them) down when you want FM.

mbt28
Posts: 10
Joined: Wed Feb 04, 2015 10:35 am

Re: Add an I2S mic using device tree & simple-audio-card

Mon Feb 20, 2017 2:03 pm

I actually want to directly connect fm ic to rapsberry pi, I want to hear your opinions that if raspberry pi capable of having 3 i2s in channel?

1ch I2S mic
2ch (L+R) I2S FM Receiver

gregeric
Posts: 1511
Joined: Mon Nov 28, 2011 10:08 am

Re: Add an I2S mic using device tree & simple-audio-card

Mon Feb 20, 2017 6:46 pm

Other than by way of the scheme I suggested in my previous post, then no, not possible, to the best of my knowledge. Out of interest, what is this FM Rx codec part number?

mbt28
Posts: 10
Joined: Wed Feb 04, 2015 10:35 am

Re: Add an I2S mic using device tree & simple-audio-card

Fri Feb 24, 2017 11:57 am

Hi,

I would like to use this IC or another one which have similar I2S interface. (Maybe gps, wifi, bt, fm combo). I2S stereo dac+ I2S stereo in(mic) + I2S stereo in(fm), can all be implemented in the same time?

https://www.silabs.com/documents/public ... 77-A20.pdf

john12john
Posts: 2
Joined: Tue Mar 21, 2017 8:19 am

Re: Add an I2S mic using device tree & simple-audio-card

Tue Mar 21, 2017 8:27 am

Hey all, great instructions! I got it working using this I2S mems microphone breakout from Adafruit:
https://learn.adafruit.com/adafruit-i2s ... t/overview

I was wondering if you manage to change the bit-rate. I'd like to do recording with a bit rate of 16bit but it seems this sampling format is non available:

Code: Select all

pi@raspberrypi:~ $ arecord -D mic_sv  -r 44100 -f S16_LE -t wav -d 0 -c 2  test.wav
Recording WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
arecord: set_params:1233: Sample format non available
Available formats:
- S32_LE
Do somebody have found a workaround that?

gregeric
Posts: 1511
Joined: Mon Nov 28, 2011 10:08 am

Re: Add an I2S mic using device tree & simple-audio-card

Tue Mar 21, 2017 1:43 pm

The mics sample to 24 bits, supporting S24_LE & S32_LE formats natively. The former is still 32 bits wide, padded with 00's - perfect for our 32-bit processor.

If you want 16-bit, you'll have to do it in software. That's probably do-able by editing that .asoundrc chain with another plugin to do the conversion. Take a look at http://www.alsa-project.org/alsa-doc/al ... ugins.html, the "Automatic conversion plugin".

john12john
Posts: 2
Joined: Tue Mar 21, 2017 8:19 am

Re: Add an I2S mic using device tree & simple-audio-card

Thu Mar 23, 2017 12:28 pm

gregeric wrote:The mics sample to 24 bits, supporting S24_LE & S32_LE formats natively. The former is still 32 bits wide, padded with 00's - perfect for our 32-bit processor.

If you want 16-bit, you'll have to do it in software. That's probably do-able by editing that .asoundrc chain with another plugin to do the conversion. Take a look at http://www.alsa-project.org/alsa-doc/al ... ugins.html, the "Automatic conversion plugin".
The "Automatic conversion plugin" works well. I just added those lines to the .asoundrc chain and it did the trick:

Code: Select all

pcm.mic_plug{
        type plug
        slave.pcm mic_sv
}

gregeric
Posts: 1511
Joined: Mon Nov 28, 2011 10:08 am

Re: Add an I2S mic using device tree & simple-audio-card

Thu Mar 23, 2017 6:02 pm

That's good to hear, and thanks for coming back to post your enhancement.

robertguy09
Posts: 5
Joined: Thu Mar 30, 2017 9:05 pm

Re: Add an I2S mic using device tree & simple-audio-card

Tue Apr 04, 2017 3:21 am

john12john wrote:Hey all, great instructions! I got it working using this I2S mems microphone breakout from Adafruit:
https://learn.adafruit.com/adafruit-i2s ... t/overview

I was wondering if you manage to change the bit-rate. I'd like to do recording with a bit rate of 16bit but it seems this sampling format is non available:

Code: Select all

pi@raspberrypi:~ $ arecord -D mic_sv  -r 44100 -f S16_LE -t wav -d 0 -c 2  test.wav
Recording WAVE 'test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo
arecord: set_params:1233: Sample format non available
Available formats:
- S32_LE
Do somebody have found a workaround that?
I am trying to use the same Adafruit mics. Did you have to modify anything to get these mem mics working? I have been trying for about a week and can't get it to work. :(

Every time I try making a recording, all I get is like white noise. and the little bar for the left mic during the recording stays at 25% no matter how loud or whatever I do.

gregeric
Posts: 1511
Joined: Mon Nov 28, 2011 10:08 am

Re: Add an I2S mic using device tree & simple-audio-card

Tue Apr 04, 2017 12:50 pm

I'd guess you have LRCLK & BCLK swapped. I don't have such a module, but here's how I'd wire it:

LRCLK -> FS (BCM19, pin 35)
BCLK -> CLK (BCM18, pin 12)
DOUT -> DIN (BCM20, pin 38)

Then ground SEL, connect GND & 3V to the Pi's GND & 3V3.

robertguy09
Posts: 5
Joined: Thu Mar 30, 2017 9:05 pm

Re: Add an I2S mic using device tree & simple-audio-card

Tue Apr 04, 2017 4:03 pm

gregeric wrote:I'd guess you have LRCLK & BCLK swapped. I don't have such a module, but here's how I'd wire it:

LRCLK -> FS (BCM19, pin 35)
BCLK -> CLK (BCM18, pin 12)
DOUT -> DIN (BCM20, pin 38)

Then ground SEL, connect GND & 3V to the Pi's GND & 3V3.
Thank you for the fast response!

I have checked that over and over. I am 99.99% sure it is wired correctly. I have even tried 4 other Pi's (Pi 2,3 and 0) and 3 of the same mics and got same results.

Here is an image of how I have it wired.
https://goo.gl/photos/rrtL7MKCy43bHvve7

Return to “Interfacing (DSI, CSI, I2C, etc.)”

Who is online

Users browsing this forum: No registered users and 4 guests