This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

I2S on NRF9160

I have understood that zephyr I2S APIs do not support NRF9160 ATM. Is that true?

Also, I could not find any samples about using NRFX I2S drivers on NRF9160. Are there any such samples anywhere?

Now I took the approach that I try to use I2S from /modules/hal/nordic/nrfx/drivers/src, but I am having some problems with it. SDK version 1.1. What I have done, is basically just 

CONFIG_NRFX_I2S=y

and then calling nrfx_i2s_init. Program crashes as soon as nrfx_i2s.c code assigns something to NRF_I2S. This happens actually in nrf_i2s_configure inline function. NRF_I2S seems to be a pointer

NRF_I2S_NS_BASE             0x40028000UL

I suspect that I might have some non-secure definitions/lifting missing somewhere, but no idea really what and where exactly. Any hints about the details in getting this to work or in general how to use I2S in NRF9160 are appreciated, thanks

Parents Reply Children
  • It looks like the key for not to crash was a combination of

    IRQ_DIRECT_CONNECT(I2S_IRQn, 0,
                         i2s_isr_handler, 0);
                         
    ISR_DIRECT_DECLARE(i2s_isr_handler) {
      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 */
    }

    and

    config.mck_setup = NRF_I2S_MCK_32MDIV21;

    to the application. And

    #ifdef NRF_I2S
    		PERIPH("NRF_I2S", NRF_I2S, 1),
    #endif

    to the SDK

    I thought that I don't need MCK as I don't have the wire connected either, but apparently I do need it. And now that I know that, documentation also states that "This generator always needs to be enabled when in Master mode"

  • Hi fastfox,

    I am trying to do the same thing, but I have a don't receive any dat. I am using this microphone (https://www.adafruit.com/product/3421).The microphone  works with a raspberry pi so the microphone works.I don't know how to fix this.  I think the problem is the datahandler.I connected
    LRCL with pin 8
    DOUT with 9
    BCLK with pin 10

    Here is my code can you help me?

    #include <nrf.h>
    #include <zephyr.h>
    #include <device.h>
    #include <sys/printk.h>
    #include <stdbool.h>
    #include <nrfx_i2s.h>
    #include <string.h>
    
    #include "microphone.h"
    #include "button.h"
    #include "udp.h"
    
    #define  I2S_BUFFER_SIZE 1024
    #define  SCK_PIN    10 
    #define  SDIN_PIN   9
    #define  LRCK_PIN   8
    #define  MCK_PIN    7
    #define  SDOUT_PIN  6 
    
    int counter;
    static uint32_t rx_buffer[I2S_BUFFER_SIZE]={0};
    static uint32_t tx_buffer[I2S_BUFFER_SIZE]={0};
    static nrfx_i2s_buffers_t buffer;   
     
    ISR_DIRECT_DECLARE(i2s_isr_handler) 
    {
      nrfx_i2s_irq_handler();
      ISR_DIRECT_PM();
    
      return 1; 
    }
    
    static void data_handler(nrfx_i2s_buffers_t const * p_released, uint32_t status)
    { 
      if (NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED == status)
      {
        printk("%u\n",status);
        nrfx_err_t err = nrfx_i2s_next_buffers_set(&buffer);
        if (err != NRFX_SUCCESS ) {
            printk("next buffer failed with error code:%d\n",err);
          } 
      }
    
      if(p_released != NULL){
        if (p_released->p_rx_buffer != NULL)
        {
            //uint8_t* data=p_released->p_rx_buffer;
            //data[0] == p_released->p_rx_buffer[0]
            uint8_t data[I2S_BUFFER_SIZE]={0};
            memcpy(data,p_released->p_rx_buffer, sizeof(p_released->p_rx_buffer));
            for(int i=0; i <1024; i++)
            {
                printk("data: 0x%hhX\n",data[i]);
                printk("data2:0x%hhX\n",p_released->p_rx_buffer[i]);
            }
          }
        }
      }
    }
    
    void recordaudio(void)
    {
      printk("Start i2s configuration\n");
      nrfx_err_t err;
      uint16_t buffer_size=2048;
      nrfx_i2s_config_t config = NRFX_I2S_DEFAULT_CONFIG(SCK_PIN,LRCK_PIN,MCK_PIN,SDOUT_PIN,SDIN_PIN);
      
      buffer.p_rx_buffer=rx_buffer;
      buffer.p_tx_buffer=tx_buffer;
    
     //config.irq_priority = NRFX_I2S_DEFAULT_CONFIG_IRQ_PRIORITY;
    // config.mode = NRF_I2S_MODE_MASTER;
    // config.mck_setup = NRF_I2S_MCK_32MDIV8;
    // config.channels = NRF_I2S_CHANNELS_LEFT;
    // config.sample_width = NRF_I2S_SWIDTH_16BIT;
    // config.ratio = NRF_I2S_RATIO_32X;
    // config.format = NRF_I2S_FORMAT_I2S;
    // config.alignment=NRF_I2S_ALIGN_LEFT;
    //  
     IRQ_DIRECT_CONNECT(I2S_IRQn, 0,i2s_isr_handler, 0);
    
      err = nrfx_i2s_init(&config, data_handler);
      if (err != NRFX_SUCCESS)
      {
          printk("i2s init failed:%d\n",err);
      }
      printk("i2s_start\n");
      err=nrfx_i2s_start(&buffer,buffer_size, 0);
      if(err!=NRFX_SUCCESS )
        {
         printk("i2s start failed with error:%d\n",err);
        }
      while(1)
         {
          printk("recording\n");
          k_sleep(2000);
         }
        printk("\n stop recording \n");
        nrfx_i2s_stop();
        nrfx_i2s_uninit();
    }

    Thank you in advance

  • I am far from expert in this matter, but IIRC default config uses 16bit width and I believe your mic uses 24bits. I had the definitions like this:

      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;
      config.mck_setup = NRF_I2S_MCK_32MDIV21;     // MCK running at 32MHz/21 = 1.5238095MHz
      config.channels = NRF_I2S_CHANNELS_LEFT;     // We only have one channel(mono)
      config.sample_width = NRF_I2S_SWIDTH_24BIT;  // Mic uses 24 bit words
      config.ratio = NRF_I2S_RATIO_96X;            // This becomes LRCK frequency aka sample rate?. MCK/96 = 15.873ksamples/s = Under low power limit
      config.format = NRF_I2S_FORMAT_I2S;
    with this mic: https://invensense.tdk.com/products/ics-43434/

  • Hi fastfox,

         Is your i2s working now? I am developing the i2s function, but I also encountered the problem of the program crashing. I debug it and find that it crashed when calling the function "nrf_i2s_task_trigger". I see that this is just an assignment operation, I don't understand why it would crash, can you give me some advice?

    NRF_STATIC_INLINE void nrf_i2s_task_trigger(NRF_I2S_Type * p_reg,
                                                nrf_i2s_task_t task)
    {
        *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL;
    }

Related