USART SPI Slave missing bytes during tx

Discussion around product based on ARM Cortex M4 core.

Moderators: nferre, ncollot

MattiasE
Posts: 3
Joined: Fri Dec 13, 2013 3:51 pm

USART SPI Slave missing bytes during tx

Tue Jan 10, 2017 12:14 pm

I have a simple code with the USART setup as SPI slave. I prepare 8 bytes of data for transfer in the PDC (DMA) buffer.
If a master reads all 8 bytes in a single transaction it is received OK. However, if the master reads it in 2 byte chunks (2 bytes every time the CS is low) every third byte is lost.
In fact, every time the /CS line is pulsed low (without any action on the clock) one byte is consumed by the USART. My guess is that every time the /CS line is brought low the THR is transferred to the shift register even if the shift register data have not been shifted out in the previous transaction. Effectively one byte between every transaction is lost.

This is undesired for me as I want to be able to set up a (potentially) large buffer to transmit using DMA and I want the master to be able to read the buffer in small chunks.

Do anybody know a solution/workaround to this? Does the SPI peripheral have the same behavior as the USART?

The only solution I see is to fire an interrupt after every transaction that checks if there are untransferred data in the shift register and then prepare the next buffer. However, this makes the code timing critical and the interrupt must be able to fire and finish before the SPI master decides to read the next bytes. I would like to avoid that.

Any thoughts about this?
Best regards
Mattias Eriksson
tsvoipio
Posts: 53
Joined: Wed Aug 19, 2015 9:44 pm

Re: USART SPI Slave missing bytes during tx

Tue Jan 10, 2017 11:06 pm

Maybe you have misunderstood how SPI transfers work.

A SPI always transfers one data unit into both directions at the same time. Most often the data unit is a byte, but on many peripherals it can be up to 16 bits in length. The transfer is entirely controlled by the SPI master unit sending.

The original SPI peripherals used the trailing edge of SS- (slave select) to copy the contents of the shift register to the data holding register at the slave receiver.

This means that you may have lost the case if you intend to flood the transmission in a large swoop and pick it in smaller pieces at the receiver. The double PDC may help if it is used with ping-pong buffers and if the receiving process is fast enough to keep the buffers always flowing. It is possible to get an interrupt from PDC when the first buffer is used, and you have then the time of the second buffer receiving to get the third buffer to the PDC as the second one (see PDC functional description).

Return to “SAM4 Cortex-M4 MCU”

Who is online

Users browsing this forum: No registered users and 1 guest