Hello,
I am currently interfacing MP34DT05 with nRF52840 using I2S protocol. I have tried using nrfx I2S drivers but it gives me initialization error. I have used the sample code given as the solution in the following link as reference, but cant make it work for my DK.
Below is my main.c file for nRF52840. I have only defined 3 pins because i just want to read the data from sensor.
#include <zephyr.h> #include <string.h> #include "nrfx_i2s.h" //#error Remember to define these pins before you run! // This assume you only have these 3 pins for I2S. #define I2S_WS_PIN 20 #define I2S_SD_PIN 21 #define I2S_SCK_PIN 22 #define I2S_DATA_BLOCK_WORDS 512 //How many numbers do we want. time reorded = DATA_BLOCK_WORDS / freq static uint32_t m_buffer_rx32u[I2S_DATA_BLOCK_WORDS]; static int32_t tmp[I2S_DATA_BLOCK_WORDS]; static nrfx_i2s_buffers_t initial_buffers; static bool data_ready_flag = false; ISR_DIRECT_DECLARE(i2s_isr_handler) { data_ready_flag = false; nrfx_i2s_irq_handler(); ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency */ return 1; /* We should check if scheduling decision should be made */ } static void data_handler(nrfx_i2s_buffers_t const *p_released, uint32_t status) { if (NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED == status) { nrfx_err_t err = nrfx_i2s_next_buffers_set(&initial_buffers); if (err != NRFX_SUCCESS) { printk("Error!, continuing running as if nothing happened, but you should probably investigate.\n"); } } if (p_released) { if (p_released->p_rx_buffer != NULL) { data_ready_flag = true; //This is used in print_sound() } } } void print_sound() { while (!data_ready_flag) { k_sleep(K_MSEC(1)); //Wait for data. Since we do not want I2S_DATA_BLOCK_WORDS amount of prints inside the interrupt. } nrfx_i2s_stop(); data_ready_flag = false; int64_t sum = 0; int64_t words = I2S_DATA_BLOCK_WORDS; for (int i = 0; i < I2S_DATA_BLOCK_WORDS; i++) { memcpy(tmp + i, m_buffer_rx32u + i, sizeof(uint32_t)); tmp[i] >>= 8; sum += tmp[i]; } int64_t mean = sum / words; for (int i = 0; i < I2S_DATA_BLOCK_WORDS; i++) { tmp[i] -= mean; printk("%d, ", tmp[i]); k_sleep(K_MSEC(16)); } printk("\n\n"); /** End of formatted data print*/ } nrfx_err_t get_sound_init() { IRQ_DIRECT_CONNECT(I2S_IRQn, 0, i2s_isr_handler, 0); memset(&m_buffer_rx32u, 0x00, sizeof(m_buffer_rx32u)); initial_buffers.p_rx_buffer = m_buffer_rx32u; //YOu should probably change this config to fit your I2S microphone and audio preferences. nrfx_i2s_config_t config = NRFX_I2S_DEFAULT_CONFIG(I2S_SCK_PIN, I2S_WS_PIN, NRFX_I2S_PIN_NOT_USED, NRFX_I2S_PIN_NOT_USED, I2S_SD_PIN); config.mode = NRF_I2S_MODE_MASTER; //Microphone requirement config.ratio = NRF_I2S_RATIO_64X; //Microphone requirement config.sample_width = NRF_I2S_SWIDTH_24BIT; //Microphone requirement config.mck_setup = NRF_I2S_MCK_32MDIV31; //Preference freq = (MCKfreq/ratio) =16.129 KHz. config.channels = NRF_I2S_CHANNELS_LEFT; //Preference nrfx_err_t err_code = nrfx_i2s_init(&config, data_handler); if (err_code != NRFX_SUCCESS) { printk("I2S init error\n"); return err_code; } err_code = nrfx_i2s_start(&initial_buffers, I2S_DATA_BLOCK_WORDS, 0); //start recording if (err_code != NRFX_SUCCESS) { printk("I2S start error\n"); return err_code; } //nrfx_i2s_stop() //stop recording k_sleep(K_SECONDS(2)); return err_code; } void main() { nrfx_err_t err; err = get_sound_init(); if (err != NRFX_SUCCESS) { return; } while (1) { k_sleep(K_SECONDS(5)); print_sound(); } }
Here is my project.conf file.
#I2S CONFIG_NRFX_I2S=y CONFIG_SPM_NRF_I2S0_NS=y #LOG CONFIG_LOG=y CONFIG_LOG_PRINTK=y CONFIG_LOG_BACKEND_SHOW_COLOR=n
I have also enabled I2S to be used in the non-secure area by following this post devzone.nordicsemi.com/.../adafruit-i2s-mems-microphone-breakout-with-the-nrf9160-dk
Can anyone suggest what else i have to do for initializing and reading data via I2S on nRF52840.