nrf52840 SPI slave configuration event_handler

I use zephyr to do a spi communication on nrf52840, and my nrf52840 is spi slvae

I refer to the example of zephyr spi\zephyr\tests\drivers\spi\spi_loopback\src\spi.c
At present they all use simple spi_write/spi_read to read/write spi buffer
And in zephyr\include\drivers\spi.h the rx/tx buffer is transmitted by spi_transceive
However, in the spis sample of nordic, when the slave receives the transmission data from the master, it will send it to spis_event_handler
Determine if (event.evt_type == NRF_DRV_SPIS_XFER_DONE) in which to determine whether the transmission has been completed

On Zephyr, there is no clear example of spis event handler, most of them use while to read and write in turn
Where does zephyr judge the spis is received, and where to reach the event handler?
Also in \zephyr\drivers\spi\spi_nrfx_spi.c, I saw a function that does the same thing as the spis_event_handler of the Nordic example, as follows

static void event_handler(const nrfx_spi_evt_t *p_event, void *p_context)
{
struct spi_nrfx_data *dev_data = p_context;

if (p_event->type == NRFX_SPI_EVENT_DONE) {
spi_context_update_tx(&dev_data->ctx, 1, dev_data->chunk_len);
spi_context_update_rx(&dev_data->ctx, 1, dev_data->chunk_len);

transfer_next_chunk(dev_data->dev);
}
}

How can I add an event handler to my main function so that after my SPI master sends data, I can find out in the event handler?

If anyone has ideas on how to fix this issue I would greatly appreciate it.

Many thanks

Parents Reply
  • If you use nrfx_spis (CONFIG_NRFX_SPIS=y) directly; you can do this using the approach with a event_handler.

    Hello
    I just set CONFIG_NRFX_SPIS=y in prj.cpnf
    But I still don’t know how to use event_handler
    Do you mean that I can call the event handler directly in the main function?
    In addition to #include "spi_slave.h" and #include <nrfx_spis.h> in the main function, to directly use the event handler in spi_nrfx_spis.c?
    Or is there something similar to spi_async_call_cb used in #if (CONFIG_SPI_ASYNC) to make CONFIG_NRFX_SPIS=y can do event handler?

    Thanks,

    Po-Yi,Lin

Children
  • Hi,

     

    You either use the NRFX (CONFIG_NRFX_SPIS) library, or the zephyr library (CONFIG_SPI*), not both at the same time.

    They're two different libraries, interfacing the same peripheral.

     

    hmw said:
    Or is there something similar to spi_async_call_cb used in #if (CONFIG_SPI_ASYNC) to make CONFIG_NRFX_SPIS=y can do event handler?

    If you use CONFIG_SPI_ASYNC, you should follow the integration algorithm that is shown in the former test sample, by providing a specific thread where you poll for the spi data.

    This will, from the driver, only provide a signal when anything happens on the SPIS bus.

     

    If you want to use NRFX driver directly instead, there's unfortunately no example available, but you can have a look at the SPIS example in nrf5 sdk, and add the following to route the interrupt (this shows rtc as an example):

    https://github.com/Rallare/fw-nrfconnect-nrf/blob/nrf9160_samples/samples/nrf9160/nrfx/rtc/src/main.c#L59-L63

    Kind regards,

    Håkon

  • Hello
    Set as follows in my proj.conf

    CONFIG_DEBUG=y
    
    CONFIG_GPIO=y
    
    CONFIG_SPI=y
    CONFIG_SPI_NRFX=y
    
    CONFIG_SPI_SLAVE=y
    CONFIG_SPI_0=y
    
    CONFIG_SPI_0_OP_MODES=2
    
    CONFIG_SPI_0_NRF_ORC=0xff
    CONFIG_NRFX_SPIS0=y

    I also printk in the event_handler of spi_nrfx_spis.c to confirm whether this function will be reached
    The result will be
    How can I reference this event_handler in my main code?
    So that I can provide semaphore in the event handler

    thanks,

    Poyi

  • Hi,

     

    Here's a simplified spis example:

     

    Could you try this?

     

    Kind regards,

    Håkon

  • Hello
    Thank you for the code, but I have used it before and it doesn’t meet my requirements
    What I want is to have an IRQ_Handler that allows me to give semaphore behavior when an interrupt occurs
    At present, I am directly using nordic's spis code in zephyr to achieve this goal, but in the long run, it seems like it is not a good way.

    Thanks,

    Poyi

  • Hi,

     

    hmw said:
    What I want is to have an IRQ_Handler that allows me to give semaphore behavior when an interrupt occurs

    Then disabling the zephyr SPI driver (CONFIG_SPI*=n) and using the CONFIG_NRFX_SPIS driver directly is a possibility.

    You should not mix "spi_nrfx_spis" into the mix here, as this is the port file for the zephyr SPI driver.

     

    If you look at the nRF5 SDK example in peripheral/spis/, it has a slightly modified API (legacy API), but shows the flow of how to use the nrfx_spis driver.

    Note that you should also add CONFIG_NRFX_SPISx=y to choose which instance you want to use.

     

    Kind regards,

    Håkon 

Related