spi: sam0: fix fast-rx path, and refresh comments
The SAM0 fast-path implementation was broken, and partially fixed in
commits 8181eed
and 8a99bd0...
This patch resolves an issue where the MSB is always zero on SAML21
parts, and appears to follow suit with the previous patches.
This patch also refreshes the commentary, and removes mention of the
"interleaved" operation that is no longer used - which appears to have
been problematic in the past.
In addition to this, it also resolves an off-by-one error in both the
fast_rx and fast_rxrx paths, which would have been tripped when
transmitting a zero-byte buffer.
Signed-off-by: Attie Grande <attie.grande@argentum-systems.co.uk>
This commit is contained in:
parent
b15ac058fa
commit
cfad60d4dd
|
@ -219,37 +219,17 @@ static void spi_sam0_fast_rx(SercomSpi *regs, const struct spi_buf *rx_buf)
|
|||
return;
|
||||
}
|
||||
|
||||
/* See the comment in spi_sam0_fast_txrx re: interleaving. */
|
||||
|
||||
/* Write the first byte */
|
||||
regs->DATA.reg = 0;
|
||||
len--;
|
||||
|
||||
/* Ensure the data register has shifted to the shift register before
|
||||
* continuing. Later writes are synchronised by waiting for the receive
|
||||
* to complete.
|
||||
*/
|
||||
while (!regs->INTFLAG.bit.DRE) {
|
||||
}
|
||||
|
||||
while (len) {
|
||||
/* Load byte N+1 into the transmit register */
|
||||
/* Send the next byte */
|
||||
regs->DATA.reg = 0;
|
||||
len--;
|
||||
|
||||
/* Read byte N+0 from the receive register */
|
||||
/* Wait for completion, and read */
|
||||
while (!regs->INTFLAG.bit.RXC) {
|
||||
}
|
||||
|
||||
*rx++ = regs->DATA.reg;
|
||||
}
|
||||
|
||||
/* Read the final incoming byte */
|
||||
while (!regs->INTFLAG.bit.RXC) {
|
||||
}
|
||||
|
||||
*rx = regs->DATA.reg;
|
||||
|
||||
spi_sam0_finish(regs);
|
||||
}
|
||||
|
||||
|
@ -267,39 +247,16 @@ static void spi_sam0_fast_txrx(SercomSpi *regs,
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The code below interleaves the transmit writes with the
|
||||
* receive reads to keep the bus fully utilised. The code is
|
||||
* equivalent to:
|
||||
*
|
||||
* Transmit byte 0
|
||||
* Loop:
|
||||
* - Transmit byte n+1
|
||||
* - Receive byte n
|
||||
* Receive the final byte
|
||||
*/
|
||||
|
||||
/* Write the first byte */
|
||||
regs->DATA.reg = *tx++;
|
||||
|
||||
while (tx != txend) {
|
||||
/* Send the next byte */
|
||||
regs->DATA.reg = *tx++;
|
||||
|
||||
/* Read byte N+0 from the receive register */
|
||||
/* Wait for completion, and read */
|
||||
while (!regs->INTFLAG.bit.RXC) {
|
||||
}
|
||||
|
||||
*rx++ = regs->DATA.reg;
|
||||
|
||||
/* We just received the response, send the next byte */
|
||||
regs->DATA.reg = *tx++;
|
||||
}
|
||||
|
||||
/* Read the final incoming byte */
|
||||
while (!regs->INTFLAG.bit.RXC) {
|
||||
}
|
||||
|
||||
*rx = regs->DATA.reg;
|
||||
|
||||
spi_sam0_finish(regs);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue