How to do SPIM with handshakes

I'm using SDK15.3 on an nRF52840 with FreeRTOS and specifically non-preemptive scheduling.

I want to so some transfers on SPIM (it's configure with DMA but that's not a requirement)... I've got a part I'm talking to that has a READY handshake signal coming back from it that kicks in during long transfers... basically it's implementing XON/XOFF for the regular SPI transaction.

Got any hints at how to handle that?

Parents
  • Hi

    I'm sorry, but I'm not sure what you're asking how to handle here. Is the READY handshake interrupting your transfers when you're not expecting it to, or what exactly is the issue here? There could be buffer that reaches its limit for example, but please share some more information here on what the issue here is.

    Best regards,

    Simon

  • nuts,,,, wrong button here.. let me see if I can clear the idea.

    Think of RS232 XON/XOFF functionality.  In this case we're using an outside signal to hold off the transmission of bytes.  When it asserts, I need to not send the next byte (while keeping the select signal asserted).  Once it de-asserts, I can resume sending bytes via SPI

  • Yes, there is a similar XON/XOFF functionality in the SPIM, use PPI to trigger hardware SPIM TASKS_SUSPEND and TASKS_RESUME from the active and inactive edges of the external hold signal.

    "A transaction can be suspended and resumed using the SUSPEND and RESUME tasks. When the SUSPEND task is triggered, the SPI master will complete transmitting and receiving the current ongoing byte before it is suspended"

  • Very interesting indeed.... sounds like that's the ticket for sure.  I don't suppose someone has some example code of how to do it?

Reply Children
  • I got involved just because I saw FreeRTOS here but the code that you seek does not necessarily depend on FreeRTOS.

    After you initialize the SPI using nrf_drv_spim_init, I think you can use something like below code as template to have the connections you see through PPI to the tasks.

    This is uncompiled code trying to show you the logic. Please use that as template.

  • Great! Thanx... this should get me there..

  • How does this code know which edge is active and which is not? I'm looking for a down edge as suspend and an up edge as resume..

  • Hi Randy,

    The key lies in the configuration of the GPIOTE input:

    Here, a preset configuration was used. The preset configurations can be found in modules/nrfx/drivers/include/nrfx_gpiote.h.

    You might notice the symbols are named a little different. That's because they are given aliases in integration/nrfx/legacy/nrf_drv_gpiote.h.

    These aliases are to adapt usage of the old nrf_drv APIs to new nrfx APIs.

    Hieu

  • Yah, I get the HITOLO and that thing... here's the question then:

    I've got one pin that the HITOLO would cause a suspend and the LOTOHI would cause the resume.  Setting this to check on TOGGLE makes sense since it's a single pin and both edges are significant (but different)

    How then would I work nrf_drv_ppi_channel_assign() since the pin is going to generate events on both edges and the nrf_drv_gpiote_in_event_addr_get(READY_PIN) wouldn't therefor distinguish which edge it's seeing.

    Does PPI just pingpong between the edges when you get both like this?

    Or do I need to assign an ISR to this nrfx_gpiote_in_init() and reset the association during that (i.e. a manual pingpong)?