@jeremyzhou
I have that working now the issue I am having is that if I send in write data too fast I dont see the correct data on the output SPI device. If I include a delay of 3 microseconds after each write or wait for the tx fifo to empty, I do get the correct data. My application does not have enough time to include these delays, how can I avoid them?
I think this delay is needed to account for the stall when the tx fifo gets full. The LPSPI_CFGR1_NOSTALL_MASK is cleared which means Transfers will stall when the transmit FIFO is empty or the receive FIFO is full. Whye is the TX fifo ever getting full? Even after setting the tx watermark to 0, I still have the same issue.
How can I get the LPSPI to transmit data immediately without needing a delay?
Below is my LPSPI configuration code and example for loop for sending data based of the LPSPI example projects. I have set the RXMSK flasg to ignore the RX fifo. My only goal is to send data to the transmit fifo of the LPSPI quickly.
CLOCK_SetMux(kCLOCK_LpspiMux, LPSPI_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_LpspiDiv, LPSPI_CLOCK_SOURCE_DIVIDER);
lpspi_master_config_t masterConfig;
/*Master config*/
masterConfig.baudRate = 13000000;
masterConfig.bitsPerFrame = 16; //same issue using 32 bitsPerFrame
masterConfig.cpol = kLPSPI_ClockPolarityActiveHigh;
masterConfig.cpha = kLPSPI_ClockPhaseFirstEdge;
masterConfig.direction = kLPSPI_MsbFirst;
masterConfig.pcsToSckDelayInNanoSec = 1000000000 / masterConfig.baudRate;
masterConfig.lastSckToPcsDelayInNanoSec = 1000000000 / masterConfig.baudRate;
masterConfig.betweenTransferDelayInNanoSec = 1000000000 / masterConfig.baudRate;
masterConfig.whichPcs = kLPSPI_Pcs0;
masterConfig.pcsActiveHighOrLow = kLPSPI_PcsActiveLow;
masterConfig.pinCfg = kLPSPI_SdiInSdoOut;
masterConfig.dataOutConfig = kLpspiDataOutRetained;
LPSPI_MasterInit(LPSPI1, &masterConfig, LPSPI_CLOCK_FREQ);
LPSPI_Enable(LPSPI1, false);
LPSPI1->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
LPSPI_Enable(LPSPI1, true);
LPSPI_FlushFifo(LPSPI1, true, true);
LPSPI1->TCR =
(LPSPI1->TCR &
~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
LPSPI_TCR_CONT(1) | LPSPI_TCR_CONTC(0) | LPSPI_TCR_RXMSK(1) | LPSPI_TCR_TXMSK(0) | LPSPI_TCR_PCS(EXAMPLE_LPSPI_MASTER_PCS_FOR_INIT);
LPSPI_EnableInterrupts(EXAMPLE_LPSPI_MASTER_BASEADDR, kLPSPI_RxInterruptEnable);
/*TCR is also shared the FIFO , so wait for TCR written.*/
while (LPSPI_GetTxFifoCount(EXAMPLE_LPSPI_MASTER_BASEADDR) != 0) { }
for(int a=0; a<80; a++) // this function only works correctly if I include the 3 microsecond delay or wait loop
{
LPSPI_WriteData(LPSPI1, data1);
//mirocsecDelay(3);
//while (LPSPI_GetTxFifoCount(LPSPI1) == 16) { }
}
void LPSPI1_IRQHandler(void)
{
if (masterRxCount < TRANSFER_SIZE)
{
/* First, disable the interrupts to avoid potentially triggering another interrupt
* while reading out the RX FIFO as more data may be coming into the RX FIFO. We'll
* re-enable the interrupts EXAMPLE_LPSPI_MASTER_BASEADDRd on the LPSPI state after reading out the FIFO.
*/
LPSPI_DisableInterrupts(LPSPI1, kLPSPI_RxInterruptEnable);
while (LPSPI_GetRxFifoCount(LPSPI1))
{
/*Read out the data*/
masterRxData[masterRxCount] = LPSPI_ReadData(LPSPI1);
masterRxCount++;
if (masterRxCount == TRANSFER_SIZE)
{
break;
}
}
/* Re-enable the interrupts only if rxCount indicates there is more data to receive,
* else we may get a spurious interrupt.
* */
if (masterRxCount < TRANSFER_SIZE)
{
/* Set the TDF and RDF interrupt enables simultaneously to avoid race conditions */
LPSPI_EnableInterrupts(LPSPI1, kLPSPI_RxInterruptEnable);
}
}
/*Update rxWatermark. There isn't RX interrupt for the last datas if the RX count is not greater than rxWatermark.*/
if ((TRANSFER_SIZE - masterRxCount) <= g_masterRxWatermark)
{
LPSPI1->FCR =
(LPSPI1->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
LPSPI_FCR_RXWATER(((TRANSFER_SIZE - masterRxCount) > 1) ? ((TRANSFER_SIZE - masterRxCount) - 1U) : (0U));
}
if (masterTxCount < TRANSFER_SIZE)
{
while ((LPSPI_GetTxFifoCount(LPSPI1) < g_masterFifoSize) &&
(masterTxCount - masterRxCount < g_masterFifoSize))
{
/*Write the word to TX register*/
LPSPI_WriteData(LPSPI1, masterTxData[masterTxCount]);
++masterTxCount;
if (masterTxCount == TRANSFER_SIZE)
{
break;
}
}
}
/* Check if we're done with this transfer.*/
if ((masterTxCount == TRANSFER_SIZE) && (masterRxCount == TRANSFER_SIZE))
{
isMasterTransferCompleted = true;
/* Complete the transfer and disable the interrupts */
LPSPI_DisableInterrupts(LPSPI1, kLPSPI_AllInterruptEnable);
}
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}