Request confirmation if SPIM & SPIS drivers in nCS are working on interrupts

Hi,

For my application I am supposed to evaluate if nordic SPIM & SPIS drivers are working on interrupts..?

In the driver file "nrfx_spim.c" I observed the below code:

Is this NRFX_IRQ_ENABLE actually interrupts enabling at the SPIM driver..?

How can I confirm if nrfx SPIM & SPIS drivers are working on interrupts..?
I need to prove for the sake of development & design.

Kindly help.

Thanks,

Ubaid

Parents Reply Children
  • Hi ,

    Thank you for the confirmation,

    drivers does use interrupts to handle certain states

    Can you please elaborate on how you mean certain states..?


    And also can you kindly point me to the SPI driver code where SPI interrupts are being used so that i may analyze further..?

    Thanks,

    Ubaid

  • The different states of the SPIM/S HW: see SPIM — Serial peripheral interface master with EasyDMA, and nrfx:spim.c: 

    static void irq_handler(NRF_SPIM_Type * p_spim, spim_control_block_t * p_cb)
    {
    
    #if NRFX_CHECK(NRFX_SPIM_NRF52_ANOMALY_109_WORKAROUND_ENABLED)
        if ((nrf_spim_int_enable_check(p_spim, NRF_SPIM_INT_STARTED_MASK)) &&
            (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_STARTED)) )
        {
            /* Handle first, zero-length, auxiliary transmission. */
            nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_STARTED);
            nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END);
    
            NRFX_ASSERT(p_spim->TXD.MAXCNT == 0);
            p_spim->TXD.MAXCNT = p_cb->tx_length;
    
            NRFX_ASSERT(p_spim->RXD.MAXCNT == 0);
            p_spim->RXD.MAXCNT = p_cb->rx_length;
    
            /* Disable STARTED interrupt, used only in auxiliary transmission. */
            nrf_spim_int_disable(p_spim, NRF_SPIM_INT_STARTED_MASK);
    
            /* Start the actual, glitch-free transmission. */
            nrf_spim_task_trigger(p_spim, NRF_SPIM_TASK_START);
            return;
        }
    #endif
    
        if (nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END))
        {
    #if NRFX_CHECK(NRFX_SPIM3_NRF52840_ANOMALY_198_WORKAROUND_ENABLED)
            if (p_spim == NRF_SPIM3)
            {
                anomaly_198_disable();
            }
    #endif
            nrf_spim_event_clear(p_spim, NRF_SPIM_EVENT_END);
            NRFX_ASSERT(p_cb->handler);
            NRFX_LOG_DEBUG("Event: NRF_SPIM_EVENT_END.");
            finish_transfer(p_cb);
        }
    }

  • Hello ,

    Thanks for the confirmation, I can see that for each SPI channel there is an irq_handler written in the driver.
    Can you please just let me know from where the below function irq_handler is being called..?

    static void irq_handler(NRF_SPIM_Type * p_spim, spim_control_block_t * p_cb)
    {

    Thanks,

  • See f.ex:

    #if NRFX_CHECK(NRFX_SPIM0_ENABLED)
    void nrfx_spim_0_irq_handler(void)
    {
        irq_handler(NRF_SPIM0, &m_cb[NRFX_SPIM0_INST_IDX]);
    }
    #endif

    nrfx_spim_0_irq_handler is the ISR connected to the SPIM0's IRQ. The peripheral HW has only one IRQ, and that IRQ can be connected to the events that the HW peripheral can generate through the INTENSET register. 

    In irq_handler() the driver can read f.ex the EVENTS_END register through the following call nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END). 


    Also: The tasks and events of the peripherals can be used together with PPI — Programmable peripheral interconnect to create state machines that operates entirely without any CPU use. F.ex, you can configure a TIMER's COMPARE event to trigger the SAMPLE task of the SAADC, and you can further connect the SAADC's END event to the SPIM's START task. Thereby effectively streaming ADC data over SPI without a single IRQ being fired, all with the help of PPI EasyDMA. 

  • Hello ,

    Thanks for the confirmation

    In irq_handler() the driver can read f.ex the EVENTS_END register through the following call nrf_spim_event_check(p_spim, NRF_SPIM_EVENT_END). 
Related