This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Is it possible to do back to back SPI transfers or read only during RX time?

I need to write received data from SPI to address pointed by a parameter. When doing a transfer, spi drivers also read the data sent by slave during TX. I know this is normal since SPI is full-duplex protocol. However, I have strict time constraints so I can't copy read data between buffers (I've done this and it worked but the performance wasn't great). Also, I can't use pointer arithmetics since buffer is elsewhere. I thought that if I could make TX - RX transfer back to back seperately, I can solve this problem. Is there a way to do this or do I have an alternate solution?

  • From the SPIM — Serial peripheral interface master with EasyDMA specs:
    The .PTR and .MAXCNT registers are double-buffered. They can be updated and prepared for the next transmission immediately after having received the STARTED event.

    There's also the EasyDMA list, that allows you to fill any number of buffers in the same transfer. 

     
    When doing a transfer, spi drivers also read the data sent by slave during TX. I know this is normal since SPI is full-duplex protocol. However, I have strict time constraints so I can't copy read data between buffers (I've done this and it worked but the performance wasn't great).

     What exactly do you mean? Are you only using one buffer each for TX and RX?

  • For example, if I want to transmit 4 bytes and receive 2 bytes, I receive 6 bytes in total with only last 2 I'm interested. As I said, I know that's normal but I only want the last 2 bytes to be written into specified rx buffer address.

  • Maybe you could do something with an EasyDMA array list with buffer lengths of 2. 

    Why do you need a separate buffer for the two RX bytes? 

  •  Let me give you a small example

    void example_function(const uint8_t *p_tx, uint32_t tx_count, uint8_t *p_rx, uint32_t rx_count)
    {
    /* I need to write tx_count bytes from p_tx
    * Then I need to read rx_count bytes to p_rx
    * If I set up nrf_drv_spi_transfer or nrfx_spim_xfer to write tx_count bytes and read rx_count bytes, I only see (rx_count - tx_count) bytes in p_rx.
    * If I change it to write tx_count bytes and receive (tx_count + rx_count) bytes, I have the data that I want in my buffer but with extra tx_count bytes from tx time.
    * If I copy received data to a local buffer, then memcpy only the data that I want, it works but performance is not great. */
    }

    Why do you need a separate buffer for the two RX bytes?

    It was an example, it's not always 2 bytes.

  • seneryilmaz said:
    If I copy received data to a local buffer, then memcpy only the data that I want, it works but performance is not great.

    What exactly do you mean by 'performance is not great'? What are your requirements? 

    btw:
    If you read with fixed-width buffers and use DMA ArrayLists then you can do 'x' amount of transfers of length 'y', back-to-back, without needing to process the data until you're done with all the transfers. 

Related