Need help to configure an I2S microphone array

Hi,

I managed to patch the jetson nano 40 pin headers thanks to the forum help in order to activate the I2S pin functions.

However, I have troubles getting data from the 7 channels of this microphone array.

I try to follow different configurations of amixer that I found in [the doc](Jetson Linux Linux Driver Package Development Guide/asoc_driver.19.2.html#wwpID0E02K0HA) or on the forum but at best I got only loud noise, at worst non functioning channels (with the TDM doc configuration for example).

For mics bit format, it isn’t written in the mic array site, but in the mic documentation, it is writtent 24-bit depth in a 32 bit word. I suppose I have to record in 32 bit.

What would be the steps to do in order to configure and use this device properly ? (if it’s even possible)

Thanks in advance

Hi,

i think you should configure the I2S interface to use a 32 bit word length for the codec part, and you can left it with a 0 in the input part. This way you can record in S8, S16 or S24, whatever you need.
It seems that you have 4 I2S interfaces with two channels of 32bits words, with 24 bits of useful data in each one.

You can config the I2S interfaces with amixer, using something like:

amixer -c TheNameOfYourCard --stdin <<EOF
sset "I2S3 fsync width" 31
sset "I2S3 codec bit format" 32
sset "I2S3 input bit format" 0
sset "I2S3 axbar bit format" 0
EOF

You should configure more things like who is the bit clock and frame clock master (in this case seems to be the array, so: sset “I2S3 codec master mode” “cbm-cfm”), which ADMAIF you are going to use (for example: sset “I2S3 Mux” “ADMAIF1” and sset “ADMAIF1 Mux” “I2S3”), the sample rate (sset “I2S3 Sample Rate” 48000), the format of the frame clock (i2s, dsp-a, dsp-b, etc)(for example: sset “I2S3 codec frame mode” “dsp-a”), the number of channels…

You can get a list of the properties and valid values using:

amixer -c TheNameOfYourCard 2>&1 | less

You can find the name of your card with:

cat /proc/asound/cards

Hope this helps you

Thanks for your reply.
I tried to follow your recommendations, however now I have the error when trying to record :

arecord: pcm_read:2103: read error: Input/output error

It seems it comes from the “I2S4 codec master mode” "cbm-cfm’. If I select “cbs-cfs” I can start recording again with the same problems as before.
I tried with I2S3 and I2S4.

When changing the frame clock format (between 'dsp, it doesn’t change the recorded output (it is again nonsense) when I use the cbs-cfs master mode.

Hi,

sorry, you’re right. In the datasheet it seems that the mic array is the slave for both clocks.

May be you have to config the number of channels of each I2S interface to 2:

amixer -c TheNameOfYourCard  sset "ADMAIF1 Channels" 2

I’m not sure, but i think that somewhere in the devicetree you should be setting up the frame to bit clock ratio (you should set this to 64), althouh maybe that the amixer logic set this value up for you. And maybe you should increase the axbar clock, in order to it being able to transfer all this channels. Have you checked the overrun/underrun bits of the i2s and adma interfaces?

Hi,

Thanks for helping me,

I forgot to mention that when I try to set the axbar bit format I have the error :

amixer -c tegrasndt210ref sset "I2S3 axbar bit format" 0
amixer: Unable to find simple control 'I2S3 axbar bit format',0

amixer -c tegrasndt210ref sset "I2S4 axbar bit format" 0
amixer: Unable to find simple control 'I2S4 axbar bit format',0

I also tried the following :

amixer -c tegrasndt210ref cset  name="I2S3 axbar bit format" 0
amixer: Cannot find the given element from control hw:1

amixer -c tegrasndt210ref cset  name="I2S4 axbar bit format" 0
amixer: Cannot find the given element from control hw:1

Also what do you mean by config the number of channels of each I2S interface to 2 ? Should I change the command ADMAIF1 for every ADMAIF values ?

And how can I check the overrun/underrun bits of the i2s / adma interfaces ?

When you talk about device tree, the .dtb file that is used while the board is booting ? Or is it a file that is used while flashing the board ?

Sorry I’m not familiar with these types of devices…

I’m sorry, we have a lot of customizations in the kernel and I think that this ‘axbar bit format’ is one of those.

From the info in the mic array web page, it seems that there are 4 i2s interfaces, each with 2 channels. So, you need to configure 4 i2s interfaces (4 i2s data lines), plus two common bit and frame clocks, to receive the 7 channels of the array, although in practice you should be capturing 4 audio streams, with 2 channels each, having one of them one channel with silence or with garbage. This is why i told you to configure each i2s interface’s number of channels to 2.

You can read the registers using de devmem2 tool (you can find the addresses in the Tegra X1 technical reference manual). I think you should be able to read them through sysfs too:

root@localhost:~# cat /sys/kernel/debug/regmap/tegra210-i2s.3/registers
00: 00000000
04: XXXXXXXX
08: 00000000
0c: XXXXXXXX
10: XXXXXXXX
...

root@localhost:~# cat /sys/kernel/debug/regmap/tegra210-admaif/registers
000: XXXXXXXX
004: XXXXXXXX
008: 00000000
00c: XXXXXXXX
010: XXXXXXXX
...

The register 0x10 of each i2s is the one with the underrun bit (with mask 0x02). Ant the registers 0x10 + (n – 1) * 0x40 (0x10, 0x50, 0x90 ...), are the registers of the ADMAIF with the dma overrun (mask 0x01).

And for the devicetree, yes, it should be a dtb file in the boot directory. You can check the file or files in /boot/extlinux, the FDT file referenced there is the one you need.

Hi,

Ok I think I don’t understand how to use the board and array properly. On other forum I read that the I2S4 pin could take 16 input as the same time, so I connected the array mics in series and plugged everything on the I2S4 pin 38.

What I don’t get is if I need 4 I2S interfaces, how can I connect mics properly ? The board only have 2 physical I2S interfaces. Maybe I can still use 4 interfaces while connecting everything on I2S4 pin 38 ?

Is an I2S interface just I2Sx with x being a number ?

If so, when I use

sudo cat /sys/kernel/debug/regmap/tegra210-i2s.3/registers

I can only access i2s.3 and i2s.2. For other values I get a no such file or directory error.

user@user-desktop:~$ sudo cat /sys/kernel/debug/regmap/tegra210-i2s.3/registers
[sudo] password for user: 
00: 00000001
04: 00000000
08: 00000000
0c: 00000005
10: 00000001
...
user@user-desktop:~$ sudo cat /sys/kernel/debug/regmap/tegra210-i2s.2/registers
00: 00000000
04: XXXXXXXX
08: 00000000
0c: XXXXXXXX
10: XXXXXXXX
...

In the device tree, I didn’t find exactly an attribute “frame to bit clock ratio”, the best I could find is bitclock-slave and bitclock-noninversion linked to i2s4 ans i2s3.

		nvidia,dai-link-1 {
			link-name = "spdif-dit-0";
			cpu-dai = <0x53>;
			codec-dai = <0x54>;
			cpu-dai-name = "I2S4";
			codec-dai-name = "dit-hifi";
			format = "i2s";
			bitclock-slave;
			frame-slave;
			bitclock-noninversion;
			frame-noninversion;
			bit-format = "s16_le";
			srate = <0xbb80>;
			num-channel = <0x2>;
			ignore_suspend;
			name-prefix = [78 00];
			status = "okay";
			linux,phandle = <0xc3>;
			phandle = <0xc3>;
		};

		nvidia,dai-link-2 {
			link-name = "spdif-dit-1";
			cpu-dai = <0x55>;
			codec-dai = <0x56>;
			cpu-dai-name = "I2S3";
			codec-dai-name = "dit-hifi";
			format = "i2s";
			bitclock-slave;
			frame-slave;
			bitclock-noninversion;
			frame-noninversion;
			bit-format = "s16_le";
			srate = <0xbb80>;
			num-channel = <0x2>;
			ignore_suspend;
			name-prefix = [79 00];
			status = "okay";
		};

I add the device tree in attachment if you have time to look.
tegra_custom.zip (40.7 KB)

Hello,

I’m sorry I couldn’t be of more help.

I don’t think you can directly connect that array to the Jetson Nano. The I2S4 does support 16 channels, but for that to work, the 16 channels have to come in a 16-channel TDM. Starting from a frame clock edge, the 16 channels should come one after the other in the I2S data signal. I’m not exactly sure what you mean when you say you connect the microphones in series, but if you want to connect the array to the Jetson Nano through a single I2S, you need to add some logic to mix the 7 (actually 8) channels to create a single TDM between the array and the Jetson Nano.

May be you can do it with a FPGA. I don’t know of any IC that can do that, but that doesn’t mean that it doesn’t exist.

Sorry again, and good luck with the project.

Hi,

When saying I connected the microphone in series, I meant that I just plugged the 4 microphone data outputs in an electronic breadboard, and plugged the output on the Jetson. Maybe a naive solution considering what you told me.
It’s a shame I can’t use this card, I will try to find an alternative solution.

Thanks for helping, at least I understand why it doesn’t work !

Last bump to be sure that the array is not compatible with the Jetson Nano. Since I can’t return the board, I want to be sure nothing can be done ?

Also I wanted to know, if the board needs 4 I2S interfaces to function properly, configuring only one interface should be enough to use 2 microphones at least ?