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
  • I have understood that zephyr I2S APIs do not support NRF9160 ATM. Is that true?

    Correct. The work to add support for nRFx devices in the Zephyr I2S API is on-going, as part of this PR.

    For now, you will need to use the approach shown in this post (replace PDM with I2S).

    If that approach does not work, upload your project here, and I can take closer look. 

  • I am not sure if I understand you perfectly. I believe steps 1,2,3 an 4 are more or less obsolete as I2S is already included, compiled and i think I actually have the I2S_NS in use(0x40028000UL)

    I tried to use the IRQ define macros, but it still crashes at start.

    I try to strip my program to I2S only so that I can send it here 

  • i2s-prj.zip

    I tried to make a project with nothing but crashing I2S in it. I am running the SW in custom board, didn't check what the pins are in dev board.

  • 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

Related