Not easy to find a datasheet for that! This is a datasheet of each of the microphones on it: https://www.waveshare.net/w/upload/0/01/MSM261S4030H0R.pdf
The mics take 1.8V to 3.3V so it's likely that the MIC signals on the board will be 3.3V max, but worth double checking that before connecting to Bela.
As the board provides MIC_D0, MIC_D1, MIC_D2, MIC_D3, MIC_CK, MIC_WS, we can guess that they paired microphones on each data line (with one spare slot), using the configuration outlined at page 10 of the datasheet.
The datasheet further says:
I²S DATA INTERFACE
The serial data is in slave mode I²S format, which has 24‐bit depth in a 32 bit word. In a
stereo frame there are 64 SCK cycles, or 32 SCK cycles per data‐word. When L/R=0, the output
data in the left channel, while L/R=Vdd, data in the right channel. The output data pin (SD) is
tri‐stated after the LSB is output so that another microphone can drive the common data line.
Data Word Length
The output data‐word length is 24 bits per channel. The Mic must always have 64 clock
cycles for every stereo data‐word (fSCK = 64 × fWS).
Data‐Word Format
The default data format is I²S, MSB‐first. In this format, the MSB of each word is delayed by
one SCK cycle from the start of each half‐frame
So it would seem that you need:
- 4x I2S data in lines
- 2 slots, 32bit each
- bit delay of 1
- the clock lines are inputs into the mic board (have to be generated by Bela)
That's not easy to achieve while retaining all of the Bela functionalities, because there are 4x I/O data lines and if you use all 4 of them for the mic board, you won't be able to use the Bela codec's inputs or outputs. If you can sacrifice one channel from the mic board (whichever is on the data line with a single slot), then you could use 6 in from the microphones + stereo out from the Bela codec.
To achieve that, something like this might work. Start from the dev
branch and apply the following changes:
diff --git a/core/I2c_MultiI2sCodec.cpp b/core/I2c_MultiI2sCodec.cpp
index ea2e5c23a..b9f982d73 100644
--- a/core/I2c_MultiI2sCodec.cpp
+++ b/core/I2c_MultiI2sCodec.cpp
@@ -3,15 +3,15 @@
I2c_MultiI2sCodec::I2c_MultiI2sCodec(int i2cBus, int i2cAddress, CodecType type, bool verbose)
: I2c_Codec(i2cBus, i2cAddress, type, verbose),
dataSize(16),
- slotSize(16)
+ slotSize(32)
{
setMode("I2sMain");
AudioCodecParams p = getParameters();
p.slotSize = slotSize;
setParameters(p);
I2c_Codec::getMcaspConfig();
- mcaspConfig.params.inSerializers = {0, 1};
- mcaspConfig.params.outSerializers = {2, 3};
+ mcaspConfig.params.inSerializers = {0, 1, 3};
+ mcaspConfig.params.outSerializers = {2};
}
McaspConfig& I2c_MultiI2sCodec::getMcaspConfig()
and run with --board BelaMiniMultiI2s
. You'll also need to change the pinmux settings to all the relevant pins.
If you are on Bela, you may be able to bend out the data pin coming from the codec. On BelaMini, you'd need to try this and hope it works: shift the data from the ADC in the unused half of the 32-bit word so that it doesn't conflict with the data coming from the codec board in the first 16 bits. This may work:
diff --git a/core/I2c_Codec.cpp b/core/I2c_Codec.cpp
index effd7507e..1cdfa6862 100644
--- a/core/I2c_Codec.cpp
+++ b/core/I2c_Codec.cpp
@@ -215,7 +215,7 @@ int I2c_Codec::startAudio(int shouldBeReady)
if(writeRegister(0x09, crb)) // Audio serial control register B
return 1;
unsigned int crc = params.startingSlot * params.slotSize + params.bitDelay;
- if(writeRegister(0x0A, crc)) // Audio serial control register C: specifying offset in bits
+ if(writeRegister(0x0A, 16 + crc)) // Audio serial control register C: specifying offset in bits
return 1;
// clock generation
Using more channels should be possible using the code you posted above, as those do not use the McASP data lines which are the limiting factor with the above approach. I would however advise to use the PRU GPIOs instead of the main GPIOs as it currently does (see comments here).