Module operation

nRF54L15 | nRF54L10 | nRF54L05 Datasheet

Described here is a typical operating procedure for the I2S module.

  1. Configure the I2S module using the CONFIG registers
    // Enable reception
    NRF_I2S->CONFIG.RXEN = (I2S_CONFIG_RXEN_RXEN_Enabled <<
                                           I2S_CONFIG_RXEN_RXEN_Pos);
    // Enable transmission
    NRF_I2S->CONFIG.TXEN = (I2S_CONFIG_TXEN_TXEN_Enabled <<
                                           I2S_CONFIG_TXEN_TXEN_Pos);
    // Enable MCK generator
    NRF_I2S->CONFIG.MCKEN = (I2S_CONFIG_MCKEN_MCKEN_Enabled <<
                                           I2S_CONFIG_MCKEN_MCKEN_Pos);
    // MCKFREQ = 4 MHz
    NRF_I2S->CONFIG.MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV8 <<
                                           I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
    // Ratio = 256 
    NRF_I2S->CONFIG.RATIO = I2S_CONFIG_RATIO_RATIO_256X <<
                                           I2S_CONFIG_RATIO_RATIO_Pos;
    // MCKFREQ = 4 MHz and Ratio = 256 gives sample rate = 15.625 ks/s
    // Sample width = 16 bit
    NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_16Bit <<
                                           I2S_CONFIG_SWIDTH_SWIDTH_Pos;
    // Alignment = Left
    NRF_I2S->CONFIG.ALIGN = I2S_CONFIG_ALIGN_ALIGN_Left <<
                                           I2S_CONFIG_ALIGN_ALIGN_Pos;
    // Format = I2S
    NRF_I2S->CONFIG.FORMAT = I2S_CONFIG_FORMAT_FORMAT_I2S <<
                                           I2S_CONFIG_FORMAT_FORMAT_Pos;
    // Use stereo 
    NRF_I2S->CONFIG.CHANNELS = I2S_CONFIG_CHANNELS_CHANNELS_Stereo <<
                                           I2S_CONFIG_CHANNELS_CHANNELS_Pos;
    
  2. Map IO pins using the PINSEL registers
    // MCK routed to pin 0
    NRF_I2S->PSEL.MCK = (0 << I2S_PSEL_MCK_PIN_Pos) | 
                        (I2S_PSEL_MCK_CONNECT_Connected <<
                                                     I2S_PSEL_MCK_CONNECT_Pos);
    // SCK routed to pin 1
    NRF_I2S->PSEL.SCK = (1 << I2S_PSEL_SCK_PIN_Pos) | 
                        (I2S_PSEL_SCK_CONNECT_Connected <<
                                                     I2S_PSEL_SCK_CONNECT_Pos); 
    // LRCK routed to pin 2
    NRF_I2S->PSEL.LRCK = (2 << I2S_PSEL_LRCK_PIN_Pos) | 
                         (I2S_PSEL_LRCK_CONNECT_Connected <<
                                                     I2S_PSEL_LRCK_CONNECT_Pos); 
    // SDOUT routed to pin 3
    NRF_I2S->PSEL.SDOUT = (3 << I2S_PSEL_SDOUT_PIN_Pos) | 
                          (I2S_PSEL_SDOUT_CONNECT_Connected <<
                                                     I2S_PSEL_SDOUT_CONNECT_Pos);
    // SDIN routed on pin 4
    NRF_I2S->PSEL.SDIN = (4 << I2S_PSEL_SDIN_PIN_Pos) | 
                         (I2S_PSEL_SDIN_CONNECT_Connected <<
                                                     I2S_PSEL_SDIN_CONNECT_Pos); 
                        
  3. Configure TX and RX data pointers using the TXD, RXD and RXTXD registers
    NRF_I2S->TXD.PTR = my_tx_buf;
    NRF_I2S->RXD.PTR = my_rx_buf;
    NRF_I2S->TXD.MAXCNT = sizeof(my_rx_buf);
                        
  4. Enable the I2S module using the ENABLE register
    NRF_I2S->ENABLE = 1;
  5. Start audio streaming using the START task
    NRF_I2S->TASKS_START = 1;
  6. Handle received and transmitted data when receiving the TXPTRUPD and RXPTRUPD events
    if(NRF_I2S->EVENTS_TXPTRUPD  != 0)
    {
        NRF_I2S->TXD.PTR = my_next_tx_buf;
        NRF_I2S->EVENTS_TXPTRUPD = 0;
    }
    
    if(NRF_I2S->EVENTS_RXPTRUPD != 0)
    {
        NRF_I2S->RXD.PTR = my_next_rx_buf;
        NRF_I2S->EVENTS_RXPTRUPD = 0;
    }