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

nRF52810 SPI and duration of CS after last byte transferred

In my attempt of learning the nRF52 "eco system" (nRF52 DK, nRF15.3 SDK, SES and pca10040e project  for nRF52810), I have combined the GATT_C, GPIO and SPI examples to make an application for streaming CAN data over BLE. CAN is a mcp2515 chip with SPI, and I use SPI with DMA to transfer data to and from the mcp2515.

Everything works fine wrt SPI. However, it seems to me that the CS goes systematically high (or with other words, the SoftDevice releases the SPI) ~15 us after last byte is transferred over the SPI bus.  

My question is if there is a way to reduce the time from the SPI SCK goes inactive to the CS goes high (CS is active low on the mcp2515)? 



In the picture the red is the CS and the blue is the SPI SCK.

Parents
  • For controlling the CS there are two options: either this is done automatically by SoftDevice or you could control the CS pin yourself. This can be done by setting the ss_pin of the nrf_drv_spi_config_t struct to NRF_DRV_SPI_PIN_NOT_USED. In my projects I always control the CS (or Slave Select as it is called here) myself.

  • Thanks for the advice. I tested it, but it had little to no impact in my application

    I guess I also have to do some more clever stuff than only controlling  SS/CS myself?

    I have an spi_eventhandler():

    void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                           void *                    p_context)
    {
          spi_xfer_done = true;
    }

    and typically my SPI functions looks like this:

    uint8_t mcp2515_readRegister( uint8_t address)                                                                     
    {
        uint8_t ret;
        ret_code_t err_code;
    
        uint8_t m_tx_buf[] = {MCP_READ, address};
        uint8_t m_rx_buf[] = {0, 0, 0};
    
        //mcp2515_select();
        err_code = nrf_drv_spi_transfer(&spi, m_tx_buf, 2, m_rx_buf, 3);
        APP_ERROR_CHECK(err_code);
        
        while (!spi_xfer_done) { __WFE(); }
        spi_xfer_done = false;
        //mcp2515_unselect();
    
        return m_rx_buf[2];
    }


    In the case of controlling CS/SS myself: The reason why it have little impact in my code is probably that before I can set CS high, I wait for __WFE, which triggers my SPI_eventhandler, which set the flag to terminate the wait loop. 

    On other controllers I usually handle all these things in interrupt service routines (ISR), but I am not there yet that I know how to deal with ISRs on the nRF-platform using the SoftDevice for BLE...

  • Did you try adding your mcp2515_unselect() in the spi_event_handler()? That's effectively doing it in an ISR.

Reply Children
Related