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

    I have used the driver to config the device but I still have 4 lines of code that are bare bones can you please assist me in converting them to use the driver. Please bare in mind this is the first time I have used your product/code.  my code is below

    #define PIN_MCK (41) //P1.09
    #define PIN_BCLK (40) //P1.08
    #define PIN_LRCK (38) //P1.06
    #define PIN_SDOUT (39) //P1.07


    static void data_handler(nrf_drv_i2s_buffers_t const * p_released,uint32_t status)
    {

    }


    int main(void)
    {
    uint32_t err_code = NRF_SUCCESS;

    nrf_gpio_cfg_output(LED);
    nrf_gpio_cfg_input(Button, NRF_GPIO_PIN_PULLUP);

    err_code = NRF_LOG_INIT(NULL);
    APP_ERROR_CHECK(err_code);

    nrf_drv_i2s_config_t config = NRF_DRV_I2S_DEFAULT_CONFIG;

    config.sck_pin = PIN_BCLK;
    config.lrck_pin = PIN_LRCK;
    config.sdout_pin = PIN_SDOUT;

    config.mode = I2S_CONFIG_MODE_MODE_Master;
    config.sample_width = I2S_CONFIG_SWIDTH_SWIDTH_16BIT;

    config.mck_setup = NRF_I2S_MCK_32MDIV8;
    config.ratio = NRF_I2S_RATIO_512X;
    config.channels = NRF_I2S_CHANNELS_RIGHT;

    err_code = nrf_drv_i2s_init(&config, data_handler);
    APP_ERROR_CHECK(err_code);


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


    NRF_I2S->ENABLE = 1;
    NRF_I2S->TASKS_START = 1;


    for (;;)
    {
    __WFE();
    }


    }

    Regards

    David

  • Hi there,

    I agree that the example from the SDK might be too complicated for someone that is just starting using our products. The bare-metal example I shared earlier should worked as I did test it before I uploaded it. Regarding your code:

    DPJONES said:
    NRF_I2S->TXD.PTR = (uint32_t)&sine_table2[0];
    NRF_I2S->RXTXD.MAXCNT = sizeof(sine_table2) / sizeof(uint32_t);


    NRF_I2S->ENABLE = 1;
    NRF_I2S->TASKS_START = 1;

    This block should be replaced by calling nrf_drv_i2s_start() where you pass the buffer, the buffer size as parameters. At the end of the function it will start the transfer, by triggering the START task. 

    The data handler should be called when the peripheral has finished accessing the buffer. You can therefore stop the function when the handler is called. 

    regards

    Jared 

  • Hi Jared

    Here I have tried to use the nrf_drv_i2s_start  but  giving warnings my array is an int16_t  so have tried to cast, this seems to be what the function expects. 

    err_code = nrf_drv_i2s_start((uint32_t)sine_table2, 8192, 0);
    APP_ERROR_CHECK(err_code);

    Here are the warnings.

    Can you please advice where I am going wrong.

    Regards

    David

  • That's not how you should pass the buffer as a parameter. Look at the I2S example, first you declare a nrf_drv_i2s_buffers_t struct which hold the TX and/or RX buffer. Then you pass the pointer address nrf_drv_i2s_buffers_t struct to the nrf_drv_i2s_start(). I2S example:

     
  • Hi  Jared

    I have replaced the code as you suggested, I am using an int16 array of 8192, so I have used a cast to unint32, but when compiled I get the error below.

    Thanks for your help 

    David

Related