SPI Slave event handler not triggered when CS arrested

Hi 

My question is most similar to https://devzone.nordicsemi.com/f/nordic-q-a/16488/spi-slave-peripheral-receive-interrupt-processing

I want the spis_event_handler to be called as soon as CS in pulled down by master.

/**
 * @brief SPIS user event handler.
 *
 * @param event
 */
void spis_event_handler(nrf_drv_spis_event_t event)
{
    static uint8_t data_array[50];
    static uint8_t index = 0;

    ret_code_t err_code;
	
    if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
    {
        spis_xfer_done = true;
        NRF_LOG_INFO(" Transfer completed. Received: %x", m_rx_buf[0]);
        if(m_rx_buf != NULL && m_rx_buf[0] != 0x06)
        {
          data_array[index] = m_rx_buf[0];
          index++;
        }
        if(data_array[index - 1] == 0x0a)
	{
            NRF_LOG_INFO("Buffer Len: %d", index);
            //for(i = 0; i < index; i++){
            //    //NRF_LOG_INFO("%x ", data_array[i]);
                
            //}
            NRF_LOG_HEXDUMP_INFO(data_array, strlen((const char *)data_array));
            if(index > 1)
            {

                    if (strncmp(data_array, COM_NOT_RX_OFFSET_CHAR, RX_OFFSET_LEN) == 0)
                    {
                            for(uint8_t i = 0; i<COM_NOT_CHAR_LEN - 18; i++) cmn[i] = data_array[i+RX_OFFSET_LEN];
                            do
                            {
                                    err_code = ble_cus_com_not_val_update(&m_cus, cmn, m_conn_handle);
                                    if (err_code != NRF_SUCCESS &&
                                            err_code != BLE_ERROR_INVALID_CONN_HANDLE &&
                                            err_code != NRF_ERROR_INVALID_STATE &&
                                            err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
                                    {
                                            APP_ERROR_CHECK(err_code);
                                    }
                            } while (err_code == NRF_ERROR_RESOURCES);
                            
                    }
                    else if (strncmp(data_array, SEN1_RX_OFFSET_CHAR, RX_OFFSET_LEN) == 0)
                    {
                            for(uint8_t i = 0; i<SEN1_CHAR_LEN; i++) s1d[i] = data_array[i+RX_OFFSET_LEN];
                            do
                            {
                                    err_code = ble_cus_sen_1_val_update(&m_cus, s1d, m_conn_handle);
                                    if (err_code != NRF_SUCCESS &&
                                            err_code != BLE_ERROR_INVALID_CONN_HANDLE &&
                                            err_code != NRF_ERROR_INVALID_STATE &&
                                            err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
                                    {
                                            APP_ERROR_CHECK(err_code);
                                    }
                            } while (err_code == NRF_ERROR_RESOURCES);
                            
                    }
            }
            index = 0;
        }
    }    
}

I'm interfacing nRF52840(Slave) and MSP430(Master) via SPI, the Slave has a dedicated I/O pin to trigger master to let master know that it want to send some data.

When master want to send some data It starts with CS, 1st pulling down the CS pin, this suppose to wake the Slave and event handler to process the data. but this doesn't seems to work.

 

I'm trying to develop a LP commes interface with nrf52 and MSP430 

https://devzone.nordicsemi.com/f/nordic-q-a/78428/low-power-uart-example-with-hfc I tried UART first which is not power efficient with nrf5 SDK and consumes around 350uA. So now working with SPIS for the commes this cost me more I/O then UART but still I'm okay if it solves my power concussion.

Currently I'm using MISO, MOSI, Clock, CS/SS and Data_Available(output pin interrupts MSP430) pins in nRF52 to communicate with MSP430. I not sure whether I need to go for one more pin like Income_Data(input from MSP430) to wake-up SPI Slave and set buffer for receiving data. If that's the case it going to cost me around 6 I/O Pins for implementing this Comms.

I would be good if i could save at least 1 I/O pin.

  • Read the SPIS chapter in the PS.

    For the SPIS to work, you set up RX and TX (Easy-)DMA buffers before the transaction starts. Once the transactions starts with the CS being pulled low, the CPU looses access to those buffers.

    Once the transaction finishes with CS=High, the interrupt handler will fire via END event.

  • Hi Turbo,

    I've SPIS init sequence as so, I've followed SPIS SDK example, though it's not very clear about Easy DMA etc.,

    nrf_drv_spis_config_t spis_config = NRF_DRV_SPIS_DEFAULT_CONFIG;
    spis_config.csn_pin               = APP_SPIS_CS_PIN;
    spis_config.miso_pin              = APP_SPIS_MISO_PIN;
    spis_config.mosi_pin              = APP_SPIS_MOSI_PIN;
    spis_config.sck_pin               = APP_SPIS_SCK_PIN;
    
    APP_ERROR_CHECK(nrf_drv_spis_init(&spis, &spis_config, spis_event_handler));

    Could you please share me any reference for the same.

     Thanks,

  • Ref: infocenter.nordicsemi.com/.../nRF52_PAN_109_add_v1.1.pdf

    3.9 SPIS workaround: Trigger GPIOTE on the CSN signal Use a GPIOTE event to wake the CPU when there is a falling edge on the SPIS CSN signal. 1. Set up a GPIOTE channel to generate events on falling edges of the CSN signal. 2. Enable interrupt generation for this event in the INTENSET register, and enable this interrupt in NVIC. 3. Handle the NVIC interrupt by clearing the generated event in the GPIOTE EVENT register and NVIC before putting CPU to sleep again. Pros: Specific workaround for SPIS without very large increase of current consumption. Cons: Workaround requires a GPIOTE, some increase of current consumption

    Will this work?

Related