external interrupt -> PPI -> SPI burst reading (chip select )

To the kind attention of Nordic support team,

Following PPI examples, I configured PPI so that an external interrupt (transition hi->low on a gpio pin) is triggering a SPI reading. It works well. At least it works well when running in a specific program environment, where I set chip select inside gpiote interrupt handler. I ported the same PPI setting in another program, and I noticed that the CS timing is not good anymore (see screenshot below, CS is enabled after clock has already started). My question is: how to drive chip select in the correct way? When,exactly, CS should be set by the CPU? I'm not using SPIM3.

Best regards

Parents
  • Hi guys,

    I found that chip select must be handled properly using PPI channels as well.

    In particular external interrupt event is causing cs to be enabled AND spi reading task start ( that is why I used nrf_drv_ppi_channel_fork_assign, to have one event start two tasks)

    Then end spi event is causing cs to go high. In particular the chip select pin task is toggling. That is perfectly fine, given the right starting condition. Please Nordic, confirm at your convenience if it sounds good to you / you have any other suggestion about how to handle chip select.

    Thank you

Reply
  • Hi guys,

    I found that chip select must be handled properly using PPI channels as well.

    In particular external interrupt event is causing cs to be enabled AND spi reading task start ( that is why I used nrf_drv_ppi_channel_fork_assign, to have one event start two tasks)

    Then end spi event is causing cs to go high. In particular the chip select pin task is toggling. That is perfectly fine, given the right starting condition. Please Nordic, confirm at your convenience if it sounds good to you / you have any other suggestion about how to handle chip select.

    Thank you

Children
  • Hi, 

    The easiest approach would be to use the nrfx driver and call nrfx_spim_xfer() and pass nrfx_spim_config_t as a parameter with the SS pin defined. Then the timing of the chip select pin will be implemented correctly by the driver. You can set a flag in the GPIOTE handler that is checked in the main loop and then execute the SPIM transfer. Something like this:

    int flag = 0;
    
    void gpiote_event_handler(nrfx_spim_evt_t const * p_event,
                           void *                  p_context)
    {
       flag = 1;
    
    }
    
    int main(void)
    {
        ppi_init();
        nrfx_spim_init();
        while(1)
        {
            if(flag)
            {
                nrfx_spim_xfer();
                flag = 0;
            }
        }
    }

    Also this comment by my colleague Kenneth is worth a read, especially his suggestion of having two compare events where one is for triggering the chip select pin and the other is for starting the transfer. It complicates the logic a bit, and maybe using the driver as I suggested over would be better for you. It all depends on how complex you want the code to be and your timing requirements. 

    regards

    Jared 

Related