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?