Hi all.
I've attached a single channel microphone onto my nRF9151 and I'd like to capture blocks of audio for processing. I've configured the device tree like this:
i2s: &i2s0 {
compatible = "nordic,nrf-i2s";
pinctrl-0 = <&i2s0_default>;
pinctrl-names = "default"; // , "sleep";
clock-source = "PCLK32M_HFXO";
status = "okay";
};
&pinctrl {
i2s0_default: i2s0_default {
group1 {
psels = <NRF_PSEL(I2S_SCK_M, 0, 25)>,
<NRF_PSEL(I2S_LRCK_M, 0, 23)>,
<NRF_PSEL(I2S_SDIN, 0, 24)>;
};
};
}
Apologies for formatting - it's corrupting the symbols somehow. Then in a simple main.c, I put this:
#define I2S_DEV DT_NODELABEL(i2s)
static const struct device *i2s = DEVICE_DT_GET(I2S_DEV);
...
#define SAMPLE_FREQUENCY 44100
#define SAMPLE_BIT_WIDTH 24
#define BYTES_PER_SAMPLE sizeof(int32_t)
#define NUMBER_OF_CHANNELS 2
#define SAMPLES_PER_BLOCK ((SAMPLE_FREQUENCY / 1000) * NUMBER_OF_CHANNELS)
#define INITIAL_BLOCKS 2
#define TIMEOUT 1000
#define BLOCK_SIZE (BYTES_PER_SAMPLE * SAMPLES_PER_BLOCK)
#define BLOCK_COUNT (INITIAL_BLOCKS + 4)
K_MEM_SLAB_DEFINE_STATIC(mem_slab, BLOCK_SIZE, BLOCK_COUNT, 4);
if (!device_is_ready(i2s)) {
printk("I2S device %s is not ready!\n\r", i2s->name);
// return -1;
}
// Configure I2S
struct i2s_config config = {
.word_size = SAMPLE_BIT_WIDTH, // 24 bit as ICS43434 Datasheet.
.channels = NUMBER_OF_CHANNELS, // 1 ch - single ICS43434 (left first! WS = 0).
.format = I2S_FMT_DATA_FORMAT_I2S, // Data on Left Ch - While WS is LOW
.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER, // nRF drives bit clk (SCK) & frame clk (WS).
.frame_clk_freq = SAMPLE_FREQUENCY, // 44kHz as usual.
.mem_slab = &mem_slab, //
.block_size = BLOCK_SIZE, //
.timeout = TIMEOUT //
};
ret = i2s_configure(i2s, I2S_DIR_RX, &config);
if (ret < 0) {
printk("Failed to configure I2S RX stream: %d\n", ret);
return false;
}
// Trigger ONCE - outside the loop
ret = i2s_trigger(i2s, I2S_DIR_RX, I2S_TRIGGER_START);
if (ret < 0) {
printk("Failed to trigger START: %d\n", ret);
return false;
}
// Read...
while(1) {
void *mem_block;
uint32_t block_size;
// read
ret = i2s_read(i2s, &mem_block, &block_size);
if (ret < 0) {
printk("Failed to read data: %d\n", ret);
break;
}
// Debug: Print block info and sample data
int32_t *samples = (int32_t *)mem_block;
char buf[100];
sprintf(buf, "BUF=%d %d %d %d %d %d %d %d\n",
samples[0], samples[1], samples[2], samples[3],
samples[4], samples[5], samples[6], samples[7]);
printk(buf);
}