├── README.md ├── incs43432_breakout.png ├── rpi-pins.png └── teensy-i2s.md /README.md: -------------------------------------------------------------------------------- 1 | # rpi-i2s 2 | Using the ICS43432 MEMS microphone on a Raspberry Pi with i2s 3 | 4 | There has been poor documentation online about using i2s on a RaspberryPi and in particular connecting a MEMs microphone. There is plenty of discussion but no clear tutorial and/or explaination. These notes are meant to be a comprehensive way of connecting a microphone to an RPi over i2s. 5 | 6 | ## Hardware Setup 7 | 8 | The following documentation used the ICS43432 MEMs microphone with a breakout board on an RPi 3. Mirophone documentation can be found [here](https://www.embeddedmasters.com/datasheets/embedded/EMMIC-ICS43432-DS.pdf). Header pins were soldered to the breakout board. Unfortunately the breakout board was poorly designed and in order to properly install the header pins, the pin labels were covered. Regardless, the connection uses Pulse Code Modulation which requires four GPIO pins from the RPi. The PCM setup can be found [here](https://pinout.xyz/pinout/pcm). The connection is as follows: 9 | 10 | 11 | 12 | ``` 13 | Mic - RPi 14 | --------- 15 | VCC - 3.3v 16 | Gnd - Gnd 17 | L/R - Gnd (this is used for channel selection. Connect to 3.3 or GND) 18 | SCK - BCM 18 (pin 12) 19 | WS - BCM 19 (pin 35) 20 | SD - BCM 20 (pin 38) 21 | ``` 22 | ![INCS43432 Breakoutboard](incs43432_breakout.png) 23 | 24 | ## Software Requirements 25 | 26 | The following is taken from [Paul Creaser's writeup](https://paulcreaser.wordpress.com/2015/11/01/mems-mic-module/). I've added a bit more how-to description as well as fixed a few typo's in Paul's execution. They're simple fixes but for someone who's never compiled a kernel driver, debugging a typo can be annoying. 27 | 28 | ``` 29 | $ cat /etc/os-release 30 | PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)" 31 | NAME="Raspbian GNU/Linux" 32 | VERSION_ID="8" 33 | VERSION="8 (jessie)" 34 | ID=raspbian 35 | ID_LIKE=debian 36 | HOME_URL="http://www.raspbian.org/" 37 | SUPPORT_URL="http://www.raspbian.org/RaspbianForums" 38 | BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs" 39 | ``` 40 | 41 | ### i2s Configuration 42 | Several files need to be modified. Uncomment ```#dtparam=i2s=on``` in ```/boot/config.txt``` and add ```snd-bcm2835``` to ```/etc/modules```. 43 | 44 | ``` 45 | $ uname -a 46 | Linux raspberrypi 4.4.14-v7+ #896 SMP Sat Jul 2 15:09:43 BST 2016 armv7l GNU/Linux 47 | 48 | $ sudo sed -i 's/#dtparam=i2s=on/dtparam=i2s=on/' /boot/config.txt 49 | $ echo 'snd-bcm2835' | sudo tee --append /etc/modules > /dev/null 50 | 51 | $ sudo reboot # reboot RPi 52 | 53 | $ lsmod | grep snd # confirm modules are loaded 54 | snd_soc_simple_card 6790 0 55 | snd_soc_bcm2835_i2s 6354 2 56 | snd_soc_core 125885 2 snd_soc_bcm2835_i2s,snd_soc_simple_card 57 | snd_pcm_dmaengine 3391 1 snd_soc_core 58 | snd_bcm2835 20511 3 59 | snd_pcm 75698 3 snd_bcm2835,snd_soc_core,snd_pcm_dmaengine 60 | snd_timer 19160 1 snd_pcm 61 | snd 51844 10 snd_bcm2835,snd_soc_core,snd_timer,snd_pcm 62 | ``` 63 | ### Kernel Compiling 64 | 65 | Paul provides some explaination about installing the proper gcc compiler. I didnt have any propblems with this. 66 | 67 | First update and install necessary dependencies: 68 | 69 | ``` 70 | $ sudo apt-get update 71 | $ sudo rpi-update 72 | 73 | $ gcc --version 74 | gcc (Raspbian 4.9.2-10) 4.9.2 75 | 76 | # mics dependencies that needed to be installed 77 | $ sudo apt-get install bc 78 | $ sudo apt-get install libncurses5-dev 79 | 80 | # just for good measure 81 | $ sudo apt-get update 82 | $ sudo rpi-update 83 | ``` 84 | Get the kernel source and compile. This takes a very long time on an RPi. I believe there are ways of doing this on a local machine but I didnt try. I would recommend installing the application ```sudo apt-get install screen```. 85 | 86 | ``` 87 | $ sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source 88 | $ sudo chmod +x /usr/bin/rpi-source 89 | $ /usr/bin/rpi-source -q --tag-update 90 | $ rpi-source 91 | ``` 92 | > Note: The ```rpi-source``` file downloaded here is different from what Paul used. It seems there has been an update and the new source is being used above. Information about ```rpi-source``` can be found [here](https://github.com/notro/rpi-source/wiki). 93 | 94 | ### Compile the i2S module 95 | 96 | Mount the previously compiled kernal and check that the module name matches the source code ```3f203000.i2s```. 97 | ``` 98 | $ sudo mount -t debugfs debugs /sys/kernel/debug 99 | $ sudo cat /sys/kernel/debug/asoc/platforms 100 | 3f203000.i2s 101 | snd-soc-dummy 102 | ``` 103 | 104 | Now get the module and compile against the kernel source code. The modeule was written by [Paul Creaser](https://github.com/PaulCreaser/rpi-i2s-audio). In his documentation (and in the code itself), he states to modify the code changing certain names and changing the master/slave mode. I didnt understand what to change - so I did not change anything and everything seems to work fine. If someone wants to further elaborate on this please do so!!! 105 | 106 | ``` 107 | $ git clone https://github.com/PaulCreaser/rpi-i2s-audio 108 | $ cd rpi-i2s-audio 109 | $ make -C /lib/modules/$(uname -r )/build M=$(pwd) modules 110 | $ sudo insmod my_loader.ko 111 | ``` 112 | 113 | Verify the module was loaded: 114 | ``` 115 | $ lsmod | grep my_loader 116 | my_loader 1789 0 117 | 118 | $ dmesg | tail 119 | [ 9.777145] Bluetooth: HCI UART protocol H4 registered 120 | [ 9.777150] Bluetooth: HCI UART protocol Three-wire (H5) registered 121 | [ 9.777251] Bluetooth: HCI UART protocol BCM registered 122 | [ 9.946690] Bluetooth: BNEP (Ethernet Emulation) ver 1.3 123 | [ 9.946701] Bluetooth: BNEP filters: protocol multicast 124 | [ 9.946716] Bluetooth: BNEP socket layer initialized 125 | [36934.903189] request module load 'bcm2708-dmaengine': 0 126 | [36934.903444] register platform device 'asoc-simple-card': 0 127 | [36934.903455] Hello World :) 128 | [36934.921322] asoc-simple-card asoc-simple-card.0: snd-soc-dummy-dai <-> 3f203000.i2s mapping ok 129 | ``` 130 | 131 | ### Autoload Module on Startup 132 | 133 | Here is the [Linux Kernel Module Programming Guide](http://tldp.org/LDP/lkmpg/2.6/html/lkmpg.html#AEN119) where you can read all about modules in Linux. A great resource but dont dive in too deep!!! 134 | 135 | First copy the ```module.ko``` file to the folder ```/lib/modules/```: 136 | ``` 137 | $ sudo cp my_loader.ko /lib/modules/$(uname -r) 138 | ``` 139 | Then you need to add the module to the ```/etc/modules``` list, then reload and reboot! 140 | ``` 141 | $ echo 'my_loader' | sudo tee --append /etc/modules > /dev/null 142 | $ sudo depmod -a 143 | $ sudo modprobe my_loader 144 | $ sudo reboot 145 | ``` 146 | 147 | ### Test 148 | 149 | Record a file on the RPi and copy it to my local machine for listening. My machine recorded only one channel despite the code specifiying two channels. I'm pretty sure only one channel should work. Further investigation required. 150 | 151 | ``` 152 | $ arecord -l 153 | **** List of CAPTURE Hardware Devices **** 154 | card 1: sndrpisimplecar [snd_rpi_simple_card], device 0: simple-card_codec_link snd-soc-dummy-dai-0 [] 155 | Subdevices: 1/1 156 | Subdevice #0: subdevice #0 157 | 158 | $ arecord -D hw:1 -c2 -r 48000 -f S32_LE -t wav -v file.wav 159 | 160 | # On my local machine - Move file from RPi to local machine for listening 161 | $ scp pi@:/home/pi/file.wav ~/Desktop/file.wav 162 | ``` 163 | -------------------------------------------------------------------------------- /incs43432_breakout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nejohnson2/rpi-i2s/0f62c1e576128711c1e5bba08a5d5bf9984caae5/incs43432_breakout.png -------------------------------------------------------------------------------- /rpi-pins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nejohnson2/rpi-i2s/0f62c1e576128711c1e5bba08a5d5bf9984caae5/rpi-pins.png -------------------------------------------------------------------------------- /teensy-i2s.md: -------------------------------------------------------------------------------- 1 | # Teensy I2S Notes 2 | 3 | Audio data uses I2S signals, TX (to headphones and/or line out) and RX (from line in or mic), and 3 clocks: 4 | 5 | ``` 6 | LRCLK - 44.1 kHz - Pin 23 7 | BCLK - 1.41 MHz - Pin 9 8 | MCLK - 11.29 MHz - Pin 11 9 | ``` 10 | --------------------------------------------------------------------------------