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

Getting i2s to work...

Hi,

I'd like to output some audio data through i2s. It's quite easy to understand your examples provided on infocenter, however, I can't get my code to work.

Here is what I do:

#define TX_BUFFER_SIZE    8                /* Length of transmit buffer, specified in 32-bit words */
                                                  
static uint32_t   mTxBuffer[TX_BUFFER_SIZE];

//-------------------------------------------------------------------

void  soundInitialise (ASoundCompleteCallback pCB)
{
    nrf_drv_i2s_config_t  config = NRF_DRV_I2S_DEFAULT_CONFIG;

    nrf_drv_i2s_init    (&config, onTxPrepare);
    nrf_gpio_pin_clear  (SDMODE_PIN);
    nrf_gpio_cfg_output (SDMODE_PIN);
}


void  soundPlay ()
{
    nrf_gpio_pin_set  (SDMODE_PIN);

    nrf_drv_i2s_start (NULL, mTxBuffer, TX_BUFFER_SIZE, 0);
}


static void  onTxPrepare (uint32_t const *p_data_received,
                          uint32_t       *p_data_to_send,
                          uint16_t        number_of_words)
{
    if (p_data_received != NULL)
        ;

    if (p_data_to_send  != NULL)
    {
        if (mTuneTx >= mTuneStop)
        {
            nrf_drv_i2s_stop   ();
            nrf_gpio_pin_clear (SDMODE_PIN);

            return;
        }

        while (number_of_words)
        {
            if (mTuneTx < mTuneStop)
               *p_data_to_send = *mTuneTx;
            else
               *p_data_to_send = 0;

            number_of_words--;
            mTuneTx++;
        }
    }
}

As soon as I call soundPlay () the code jumps into onTxPrepare () where a HardFault exception occurs. Why?

Thanks for your assistance.

Parents
  • Hi Martin,

    Thanks for this and yes, you're correct about the increment++.

    The code still crashes but with a bit of luck I'll get it to work. Please confirm that my assumptions are correct:

    • The buffer in nrf_drv_i2s_start () (2nd parameter) is used internally by the i2s driver, i.e. by easy-DMA or something like this.
    • What I need to do for this is to allocate a buffer in RAM? It's size needs to be a multiple of 4 bytes?
    • If I only want to send audio data to a PCM amplifier I need to react to p_data_to_send != NULL. Is that so?
    • I then need to copy number_of_words from my sound file (which is in const-memory) to *p_data_to_send.
    • p_data_to_send points to the buffer provided in nrf_drv_i2s_start ()?
    • number_of_words are 32-bit words?
    • If my sound file is done I call nrf_drv_i2s_stop () from within the interrupt routine?

    Thank you M

Reply
  • Hi Martin,

    Thanks for this and yes, you're correct about the increment++.

    The code still crashes but with a bit of luck I'll get it to work. Please confirm that my assumptions are correct:

    • The buffer in nrf_drv_i2s_start () (2nd parameter) is used internally by the i2s driver, i.e. by easy-DMA or something like this.
    • What I need to do for this is to allocate a buffer in RAM? It's size needs to be a multiple of 4 bytes?
    • If I only want to send audio data to a PCM amplifier I need to react to p_data_to_send != NULL. Is that so?
    • I then need to copy number_of_words from my sound file (which is in const-memory) to *p_data_to_send.
    • p_data_to_send points to the buffer provided in nrf_drv_i2s_start ()?
    • number_of_words are 32-bit words?
    • If my sound file is done I call nrf_drv_i2s_stop () from within the interrupt routine?

    Thank you M

Children
No Data
Related