This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

What is xfer_desc.rx_length when NRF_DRV_SPI_FLAG_REPEATED_XFER is set?

I am doing externally triggered SPIM transfer on the Nrf52 using PPI.

I found that the NRF_SPIM_TASK_SUSPEND is a very power hungry operation as SPI suspend waits for the trigger majority of the time in a high power state. Then I continued to look into the "REPEATED" and "RX_POST_INC" flag for SPIM and hope to use that.

I have a data buffer of size N > 255 (uint8_t), and can segment that into data chunks that can be fitted into uint8_t such that M = N/segments.

Each external trigger calls for 2 bytes of SPI data read = K, using the "REPEATED_TRANSFER" flag I hope to be able to stop the transfer after each trigger is done (2 bytes) and increment RX counter until at least M is reached after a sequence of external triggers and then an interrupt calls for a handler and service it.

So, what is xfer_desc.rx_length for setting up SPIM? K or M or can be N for "REPEATED_TRANSFER? How to utilize the "LIST_MODE" - which should be designed to be even sweeter?

I have read this infocenter.nordicsemi.com/index.jsp

But need more detail how this is designed. Please advice with clarity. How the SPIM is setup, how the PPI could be used to trigger and suspend/stop and checks for when the RX count satisfied for the event NRF_SPIM_EVENT_ENDRX. Mockup code structures would be great!

Thanks!

FI

  • Hi FI,

    Could you explain me what K is ?

    If you set xfer_desc.rx_length = 2 and enable the flag NRF_DRV_SPI_FLAG_RX_POSTINC, the SPIM driver will generate END event every 2 bytes received, and then increase the pointer 2 bytes each time on each repeated transfer.

    I don't really understand the relation between M and 2 bytes you mentioned above.

    But it's pretty simple the repeated mode. You choose the size of the buffer, and every time we finished that number of bytes (rx or tx buffer, depends on which one bigger) we move the pointer to the next position, according to that number of bytes (tx and rx move independently).

    In the example code in the webpage you quoted, every time a PPI event triggered the SPI, the SPI will tranfer 1 meaning byte, 2 dummy bytes (ORC byte) and read 3 bytes. After that it moves the TX pointer 1 bytes ahead and the RX pointer 3 bytes ahead, generates an END event.

    What is the LIST_MODE you were talking about ? .LIST is already used in the repeat mode.

  • Bui, thanks for the explanation.

    K is 2 bytes, I call that the trigger size. M is segment size, it is a placeholder variable depends on the implementation of this repeat mode, since SPI buffer size has a limit of 255 (uint8_t), with your explanation, there is no need to segment into M if K is < 255. And, the repeated mode by default has LIST on makes sense, the SPI buffer domain is K, and data buffer domain is N. So now, we need to watch separately when N is populated, for example using a counter? Could you comment on how to set back the pointer to the start of N? Does this need to be done with setting the xfer descriptor of type nrf_drv_spi_xfer_desc_t and initiate another nrf_drv_spi_xfer in call routine in for example the counter =N interrupt? Thanks.

    BTW. The example code in the link should not increment TX pointer after each transfer right?

  • Hi FI,

    You are right, the NRF_DRV_SPI_FLAG_TX_POSTINC is not set so the TX pointer will be fixed and it will transfer the same byte every time.

    To count the number of bytes you received you can count END event, number of byte received = number of END x K bytes.

    When it hits the total N, you can simply call nrf_drv_spi_xfer(&spi, &xfer, flags); again, or update the register directly use NRF_SPIM0->RXD.PTR.

Related