I'm trying to convert some code from ESP32 to nRF, and I'm having problems with the microphone input. Mind you, I'm a beginner with nRF, so I'm sure I'm missing something!
I have this in the prj.conf file:
CONFIG_I2S=y CONFIG_I2S_NRFX=y
and this nrf9161dk_nrf9161_ns.overlay:
&pinctrl {
i2s0_default: i2s0_default {
group1 {
psels =
<NRF_PSEL(I2S_SCK_M, 0, 21)>, /* BCLK */
<NRF_PSEL(I2S_SDIN, 0, 22)>, /* DOUT*/
<NRF_PSEL(I2S_LRCK_M, 0, 23)>; /* LRCL */
};
};
};
&i2s0 {
compatible = "nordic,nrf-i2s";
status = "okay";
pinctrl-0 = <&i2s0_default>;
pinctrl-names = "default";
};
I can see this in the GPIO overview in VS Code, and I made sure those pins weren't in use. My SPH0645s BCLK is connected to P0.21, DOUT is connected to P0.22, LRCL is connected to P0.23.
Here's the code, mic_input.c:
#define SAMPLE_RATE 48000
#define BLOCK_TIME_MS 125
#define SAMPLES_PER_BLOCK (SAMPLE_RATE * BLOCK_TIME_MS / 1000)
#define BLOCK_SIZE (SAMPLES_PER_BLOCK * sizeof(int16_t))
K_MEM_SLAB_DEFINE(i2s_rx_slabs, BLOCK_SIZE, 2, 4);
__aligned(4) static int16_t raw_buf[SAMPLE_RATE / 8];
static void mic_thread(void *, void *, void *)
{
printf("Mic thread started!\n");
printf("Block size: %d\n", BLOCK_SIZE);
printf("Buffer size: %d\n", sizeof(raw_buf));
// Finn I2S-enhet
i2s_dev = DEVICE_DT_GET(I2S_DEV_NODE);
__ASSERT(device_is_ready(i2s_dev), "I2S device not ready");
__ASSERT(i2s_dev, "I2S device not found");
// Konfigurer I2S
struct i2s_config cfg = {
.word_size = 16,
.channels = 1,
.format = I2S_FMT_DATA_FORMAT_I2S,
.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER,
.frame_clk_freq = 48000,
.block_size = 12000, // matcher slab blokk
.mem_slab = &i2s_rx_slabs,
.timeout = 2000,
};
//Configure I2S RX
int ret = i2s_configure(i2s_dev, I2S_DIR_RX, &cfg);
if(ret < 0) {
LOG_ERR("I2S configure failed: %d", ret);
return;
}
printf("i2S configured!\n");
// Reset og gjør klar buffere
ret = i2s_trigger(i2s_dev, I2S_DIR_RX, I2S_TRIGGER_PREPARE);
if (ret < 0) {
LOG_ERR("I2S trigger prepare failed: %d", ret);
return;
}
printf("i2S prepared!\n");
//Trigger I2S RX
ret = i2s_trigger(i2s_dev, I2S_DIR_RX, I2S_TRIGGER_START);
if (ret < 0) {
printk("I2S trigger start failed: %d\n", ret);
return;
}
printf("i2S triggered!\n");
k_sleep(K_MSEC(1)); // Vent litt så clocks starter
printf("Staring I2S RX...\n");
void *mem_block;
size_t size;
while (true) {
ret = i2s_read(i2s_dev, &mem_block, &size);
if (ret == 0) {
// Vi fikk en gyldig buffer!
memcpy(raw_buf, mem_block, size);
// Nå kan du bruke raw_buf fritt
printk("First sample: %d\n", ((int32_t *)raw_buf)[0]);
// Release buffer etter bruk!
//i2s_release(i2s_dev, I2S_DIR_RX);
}
else if (ret == -EAGAIN) {
printk("No audio available, waiting...\n");
k_sleep(K_MSEC(10));
}
else {
printk("i2s_read() error: %d\n", ret);
k_sleep(K_MSEC(100));
}
}
}
K_THREAD_DEFINE(mic_thread_instance, 2048, mic_thread, NULL, NULL, NULL, 7, 0, 0);
... but I only get:
Mic thread started! Block size: 12000 Buffer size: 12000 i2S configured! *** Booting nRF Connect SDK v3.0.0-3bfc46578e42 *** *** Using Zephyr OS v4.0.99-3e0ce7636fa6 *** [00:00:00.318,511] <inf> i2s_nrfx: I2S MCK frequency: 1523809, actual PCM rate: 47619 [00:00:00.319,976] <err> mic: I2S trigger prepare failed: -5

Where do I start?

