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

spi transfer blocks BLE, causing nRF51 program to reset

BLE is first initialised in my code, then SPI is initialised. If no SPI transfers are to be executed in the code, the code compiles, runs correctly and BLE functions correctly.

When I send a message using SPI, the time to transfer this message blocks the BLE. The full SPI message is not transfered, the BLE disconnects and the main loop restarts.

Any suggestions about changing BLE advertising intervals, potentially calling the SPI transfer from a BLE event handler, or any other simple solution to my problem of integrating BLE and SPI into a single program, for the nRF51422 development kit, using SDK 8 and S110.

Note: I am using SPI to code a 96x96 pixel LCD display. If I send an SPI message to write to the full screen (1346 bytes), the BLE is interrupted and the code fails and restarts. However, if I only write to a single line of the LCD (16 bytes), the BLE is not interrupted and the code works perfectly. Why is this? Can I adjust timing constraints for BLE or SPI?

    //@brief Function for initializing a SPI master driver.
    static void spi_master_init(spi_master_hw_instance_t   spi_master_instance,
                                spi_master_event_handler_t spi_master_event_handler,
                                const bool                 lsb)

   

    {

    uint32_t err_code = NRF_SUCCESS;

    // Configure SPI master.
    spi_master_config_t spi_config = SPI_MASTER_INIT_DEFAULT;

    switch (spi_master_instance)
    {
        #ifdef SPI_MASTER_0_ENABLE
        case SPI_MASTER_0:
        {
            spi_config.SPI_Pin_SCK  = SPIM0_SCK_PIN;
            spi_config.SPI_Pin_MISO = SPIM0_MISO_PIN;
            spi_config.SPI_Pin_MOSI = SPIM0_MOSI_PIN;
            spi_config.SPI_Pin_SS   = SPIM0_SS_PIN;
        }
        break;
        #endif /* SPI_MASTER_0_ENABLE */



        default:
            break;
    }
    

    spi_config.SPI_CONFIG_ORDER = SPI_CONFIG_ORDER_MsbFirst;
    

    err_code = spi_master_open(spi_master_instance, &spi_config);
    APP_ERROR_CHECK(err_code);

    // Register event handler for SPI master.
    spi_master_evt_handler_reg(spi_master_instance, spi_master_event_handler);
}

  

    #ifdef SPI_MASTER_0_ENABLE
    //brief Handler for SPI0 master events.
    void spi_master_0_event_handler(spi_master_evt_t spi_master_evt)
    {
    
        switch (spi_master_evt.evt_type)
        {
            case SPI_MASTER_EVT_TRANSFER_COMPLETED:
                m_transfer_completed = true;
                
                //Set Chip Select LO
                nrf_gpio_pin_clear(pinCS);
                
                break;
    
            default:
                // No implementation needed.
                break;
        }
    }
    #endif /* SPI_MASTER_0_ENABLE */

In the 'main' function, BLE is first initialised, then SPI is initialised, then I write to the screen.

  • Not enough information. Where are you calling your SPI code from, are you using a blocking mode or an interrupt mode? The softdevice is perfectly capable of working with SPI and everything else running so you just have a coding bug. Post some code, give some more details. (and post some code doesn't mean please paste in your entire project)

Related