I2S

HI

I am using the I2S on the nRF52840DK I have constructed an array and all works well except once I start it , it continues to run, I cant get it to play the sample just once, how can I do this

Start Code

NRF_I2S->ENABLE = 1;

// Configure data pointer
NRF_I2S->TXD.PTR = (uint32_t)&sine_table2[0];
NRF_I2S->RXTXD.MAXCNT = sizeof(sine_table2) / sizeof(uint32_t);

NRF_I2S->TASKS_START = 1;

for (;;)
{

    __WFE();

}

Any assistance would be appreciated.

Kind Regards

David

  • Hi,

    The TXPTRUPD event will be generated every time RXTXD.MAXCNT number of transmitted data words has been sent. You can stop transmitting when this event is generated. Alternatively, you can use our driver which makes it much more easier to setup and use the I2S peripheral.

    regards

    Jared 

  • Hi Jared

    Thanks for getting back to me, can you please show me how I can intercept and use the TXPTRUPD event in __WFE (Sleep Mode) as I cant seem to find any details on how to do this.

    Kind Regards

    David

  • Here you go:

    #include <nrf.h>
    
    #define PIN_MCK    (13)
    #define PIN_SCK    (14)
    #define PIN_LRCK   (15)
    #define PIN_SDOUT  (16)
    
    int main(void)
    {
      // Sine table (stereo, so every value is duplicated)
      int16_t sine_table[] = { 0, 0, 23170, 23170, 32767, 32767, 23170, 23170, 0, 0, -23170, -23170, -32768, -32768, -23170, -23170};
      
      // Enable transmission
      NRF_I2S->CONFIG.TXEN = (I2S_CONFIG_TXEN_TXEN_ENABLE << I2S_CONFIG_TXEN_TXEN_Pos);
      
      // Enable MCK generator
      NRF_I2S->CONFIG.MCKEN = (I2S_CONFIG_MCKEN_MCKEN_ENABLE << I2S_CONFIG_MCKEN_MCKEN_Pos);
      
      // MCKFREQ = 4 MHz
      NRF_I2S->CONFIG.MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV11  << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
      
      // Ratio = 64 
      NRF_I2S->CONFIG.RATIO = I2S_CONFIG_RATIO_RATIO_64X << I2S_CONFIG_RATIO_RATIO_Pos;
        
      // Master mode, 16Bit, left aligned
      NRF_I2S->CONFIG.MODE = I2S_CONFIG_MODE_MODE_MASTER << I2S_CONFIG_MODE_MODE_Pos;
      NRF_I2S->CONFIG.SWIDTH = I2S_CONFIG_SWIDTH_SWIDTH_16BIT << I2S_CONFIG_SWIDTH_SWIDTH_Pos;
      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;
      
      // Configure pins
      NRF_I2S->PSEL.MCK = (PIN_MCK << I2S_PSEL_MCK_PIN_Pos);
      NRF_I2S->PSEL.SCK = (PIN_SCK << I2S_PSEL_SCK_PIN_Pos); 
      NRF_I2S->PSEL.LRCK = (PIN_LRCK << I2S_PSEL_LRCK_PIN_Pos); 
      NRF_I2S->PSEL.SDOUT = (PIN_SDOUT << I2S_PSEL_SDOUT_PIN_Pos);
      
      
      // Configure data pointer
      NRF_I2S->TXD.PTR = (uint32_t)&sine_table[0];
      NRF_I2S->RXTXD.MAXCNT = sizeof(sine_table) / sizeof(uint32_t);
      
      //Enable interrupt and IRQ
      NRF_I2S->INTENSET = I2S_INTENSET_TXPTRUPD_Enabled << I2S_INTENSET_TXPTRUPD_Pos;
    
      
      NVIC_EnableIRQ(I2S_IRQn);
      
      NRF_I2S->ENABLE = 1;
      // Start transmitting I2S data
      NRF_I2S->TASKS_START = 1;
      
      
      // Since we are not updating the TXD pointer, the sine wave will play over and over again.
      // The TXD pointer can be updated after the EVENTS_TXPTRUPD arrives.
      while (1)
      {
        //__WFE();
      }
    }
    
    //IRQ handler
    
    void I2S_IRQHandler(void)
    {
      if (NRF_I2S->EVENTS_TXPTRUPD == 1)
      {
          NRF_I2S->EVENTS_TXPTRUPD = 0;
          NRF_I2S->TASKS_STOP = 1;
    
      }
    }

  • Hi Jared

    Thank for sending this code, the only problem is, when I put in 

    //IRQ handler

    void I2S_IRQHandler(void)
    {
    if (NRF_I2S->EVENTS_TXPTRUPD == 1)
    {
    NRF_I2S->EVENTS_TXPTRUPD = 0;
    NRF_I2S->TASKS_STOP = 1;

    }
    }

    I get these errors please see attached

     

    Thank you for all your help

    David

  • Hi,

    It's because you have included a source file which already contains the definition of the IRQ handler, the error message specifies that this is first defined in nrfx_I2S. I suggest omitting the driver from the project if you're only going to use the peripheral bare metal.

    regards

    Jared 

Related