S32K148 LPSPI Busy After Transfer Complete with RXMSK

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

S32K148 LPSPI Busy After Transfer Complete with RXMSK

Jump to solution
474 Views
sean_dvorscak
Contributor III

I am having issues when doing LPSPI transfers in master mode with RXMSK set.

Below is the follow code snippet that I perform to write the TDR and read the RDR based on the framesize of the transfer. Once all TX FIFO write, and RX FIFO reads have occurred, we exit the transfer function.

I used to also check for the TCF in the do-while() logic, but I started noticing that the function would always timeout (3ms timeout in this instance) even though I had performed all Tx/Rx writes/reads, and the Chip Select was verified by Oscope to de-assert. This was causing me issues, so I got rid of the check for TCF, and instead clear flags at the beginning of the transfer.

When I removed the TCF check in the do-while() logic, I started dropping SPI transfers when calling this routine repeatedly due to the MBF being set when I initiated this routine. I then noticed when I performed transfers with RXMSK set (c_rxwrds = 0 when RXMSK is set) I would observe this timeout behavior, but not when RXMSK was cleared.

Guess the TCF flag taking so long to set was trying to tell me something, but I cannot find any reference material that would suggest the MBF/TCF would be set longer than the expected transfer time considering Bit Rate and Framesize (Bit Rate = 4MHz; Framesize = 16-264).

Is there any documentation related to the RXMSK and how it might affect the TCF/MBF?

Would also like to note that both CONT/CONTC are 0 during transfers.

// Check if module is free, and attempt to set TCR
if (0U == (pInst->SR & LPSPI_SR_MBF_MASK))
{
  // Clear any lingering status flags
  pInst->SR |= SR_W1C_FLAGS;

  // Checking for true garuntees we are able to start the intended transfer
  if (true == Set_Tcr(pInst, pTcr))
  {
    // Get time at start of transfer
    start_time = Timer_Get_LptmrCnr();

    // Perform all necessary Tx/Rx actions
    do
    {
      // Attempt to fill Tx fifo if there are still words to transmit
      while ((c_txwrds > 0U)
      && (true == Set_Tdr(pInst, tx_data[exp_wrds - c_txwrds])))
      {
        c_txwrds--;
      }

      // Attempt to empty Rx fifo if there are still words to receive
      while ((c_rxwrds > 0U)
      && (true == Get_Rdr(pInst, &rx_data[exp_wrds - c_rxwrds])))
      {
        c_rxwrds--;
      }
    } while ( ((c_txwrds + c_rxwrds) > 0U)
                && (false == Timer_TimerExpired(start_time, timeout)));

}

0 Kudos
Reply
1 Solution
440 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

the TCF is set when the LPSPI returns to idle state with the transmit FIFO empty.
The code you shared does not show where SR flags are checked, if ever, maybe in Set_Tdr or Get_Rdr.
You should rather use RDF and TDF flags to know when RX FIFO/TX FIFO can be read/written. With RXMSK no data is expected to be read out, but you should rely on TDF to be sure TX FIFO is ready to accept new data.

BR, Petr

View solution in original post

0 Kudos
Reply
2 Replies
441 Views
PetrS
NXP TechSupport
NXP TechSupport

Hi,

the TCF is set when the LPSPI returns to idle state with the transmit FIFO empty.
The code you shared does not show where SR flags are checked, if ever, maybe in Set_Tdr or Get_Rdr.
You should rather use RDF and TDF flags to know when RX FIFO/TX FIFO can be read/written. With RXMSK no data is expected to be read out, but you should rely on TDF to be sure TX FIFO is ready to accept new data.

BR, Petr

0 Kudos
Reply
412 Views
sean_dvorscak
Contributor III
Thanks for the reply.

I found a couple of problems with the logic I had, and I also updated my Get_Rdr/Set_Tdr functions to poll the RDF/TDF instead of monitoring the RXCOUNT/TXCOUNT.

I think a combination of both these changes has made my function overrun problem go away for now.
0 Kudos
Reply