LPSPI Receive Fifo Overrun in Master Mode with Stalling and TxMask Enabled

cancel
Showing results for 
Search instead for 
Did you mean: 

LPSPI Receive Fifo Overrun in Master Mode with Stalling and TxMask Enabled

148 Views
Contributor II

Suffice to say, I'm fairly certain I've found an ugly new chip errata on the RT1060 (and presumably all other parts using the LPSPI module). When performing a continuing read, with CONT set in the original TCR, and CONTC set in the new TCR, and setting TXMSK in both, sometime after writing the new TCR, a RX fifo overrun may occur in Master Mode with NOSTALL clear.

This originally progressed from a workaround to the errata presented in RT1050 LPSPI last bit not completing in continuous mode.

I'm still working on gathering more specific data.

Labels (1)
0 Kudos
2 Replies

65 Views
Contributor II

Further data: It appears that somehow writing TCR for a continuing transfer primes the module for an RX Fifo overrun. If one is able to keep the fifo below capacity, no error occurs. However, when at capacity, the module will still transfer data until the overrun occurs. After the overrun occurs, the module will then stall at the *next* word boundary. 

It also appears that the overrun that occurs in this situation is not reported until the second such overrun occurs.

setTcr = false;
if ((fmSz <= 64) && ((i+fmSz) < checkLen)) {
if ((checkLen - i) > 512) {
uint8_t rxf;
readLen = 512;
// ser_putstring("Read: 512\r\n");
Pin_B0_02 = 1;
if (spi.FSR & LPSPI_FSR_TXCOUNT_MASK) {
Pin_SD_B0_03 = 1;
}
while ((rxf = ((spi.FSR & LPSPI_FSR_RXCOUNT_MASK) >> LPSPI_FSR_RXCOUNT_SHIFT))
< 0x10)
{ Pin_B0_02 = rxf & 1; }
Pin_SD_B0_03 = 1;
Pin_B0_02 = 0;
if (spi.TCR & LPSPI_TCR_CONT_MASK) {
if (spi.SR & LPSPI_SR_REF_MASK) {
ser_putstring("Rx Overrun\r\n");
spi.SR = LPSPI_SR_REF(1);
}
else {
ser_putstring("sr: ");
Pin_B0_02 = 1;
ser_putword(spi.SR), ser_putstring("\r\n");
Pin_B0_02 = 0;
}
if (spi.SR & LPSPI_SR_REF_MASK) {
ser_putstring("Rx Overrun before tcr\r\n");
spi.SR = LPSPI_SR_REF(1);
}
}
if (i || !tcrIsSet) {
SetTCR(tcr | LPSPI_TCR_FRAMESZ(0xFFF)
| LPSPI_TCR_CONT(1) | LPSPI_TCR_CONTC(i!=0));
setTcr = true;
}
Pin_SD_B0_03 = 0;
fmSz += 512;
}

0 Kudos

65 Views
Contributor II

I've further narrowed down the issue: After discontinuing use of CONT and CONTC and manually toggling Chip Select as a GPIO I have found that the issue is solely caused by the use of the TXMSK flag. If TXMSK is set, the Receive FIFO may be overrun. This overrun will not be reported until *after* reading from RDR following the actual overrun. It appears that the module attempts to read an additional word above the Fifo's capacity before it recognizes that the fifo is full (off-by-one).

As a result the following facts are in play:

  1. TXMSK should not be used.
  2. If it is necessary that TXMSK is used (i.e. the module is being operated in Dual or Quad input mode) adhere to the following:
    1. CONTinuous Transfer and CONTinuing Command must not be used if the total RX word count exceeds the RX Fifo count.
    2. If it is necessary that more data be Received than can fit within the RX Fifo for the given word count, it is necessary to run the Chip Select in GPIO mode and remove the use of CONT and CONTC. In addition, each frame that sets TXMSK must be limited to the size of the RX Fifo and the RX Fifo must be empty prior to the start of each command.
0 Kudos