Hello, I am having an issue with the LPSPI Slave module that I would like to get some help with. This is using the IMX1060 EVKB
My Goal: Registering End of SPI Transfer (CS Idle)
Problem : I am expecting a transfer of a certain length (4 bytes) and I have found that it is possible to RX those bytes out of order so that the first byte that I see in my buffer, is not B0 from the transmit side. This mostly happens if the TX is running and sending, and I boot up during a send.
What I would like to do is detect when the CS line goes high (transfer complete) and to reset my byte count when that occurs so that if I get unaligned at some point, I can easily re-align with the TX.
I am attempting to do this by using the kLPSPI_TransferCompleteInterruptEnable flag. However that flag never seems to be set. Interestingly the kLPSPI_FrameCompleteFlag does get set, even though I do not enable that interrupt flag.
I am initializing my interrupt using lightly modified code from an example:
LPSPI_SetFifoWatermarks(EXAMPLE_LPSPI_SLAVE_BASEADDR, txWatermark, g_slaveRxWatermark);
LPSPI_Enable(EXAMPLE_LPSPI_SLAVE_BASEADDR, false);
EXAMPLE_LPSPI_SLAVE_BASEADDR->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
LPSPI_Enable(EXAMPLE_LPSPI_SLAVE_BASEADDR, true);
/*Flush FIFO , clear status , disable all the interrupts.*/
LPSPI_FlushFifo(EXAMPLE_LPSPI_SLAVE_BASEADDR, true, true);
LPSPI_ClearStatusFlags(EXAMPLE_LPSPI_SLAVE_BASEADDR, kLPSPI_AllStatusFlag);
LPSPI_DisableInterrupts(EXAMPLE_LPSPI_SLAVE_BASEADDR, kLPSPI_AllInterruptEnable);
LPSPI_SelectTransferPCS(EXAMPLE_LPSPI_SLAVE_BASEADDR, whichPcs);
LPSPI_EnableInterrupts(EXAMPLE_LPSPI_SLAVE_BASEADDR, kLPSPI_RxInterruptEnable | kLPSPI_TransferCompleteInterruptEnable );
And my IRQ handler is :
void LPSPI_Slave_IRQ_Handler(void)
{
uint32_t status_flags = LPSPI_GetStatusFlags(EXAMPLE_LPSPI_SLAVE_BASEADDR);
if (slaveRxCount < TRANSFER_SIZE && ((status_flags & (uint32_t)kLPSPI_RxDataReadyFlag) != 0U ) )
{
LPSPI_ClearStatusFlags( EXAMPLE_LPSPI_SLAVE_BASEADDR, kLPSPI_RxDataReadyFlag );
/* While reading out the RX FIFO as more data may be coming into the RX FIFO. We'll
* re-enable the interrupts after reading out the FIFO.
*/
while (LPSPI_GetRxFifoCount(EXAMPLE_LPSPI_SLAVE_BASEADDR))
{
slaveRxData[slaveRxCount] = LPSPI_ReadData(EXAMPLE_LPSPI_SLAVE_BASEADDR);
if(slaveRxCount == 0 ){
data_is_for_us = ParseFirstByte(slaveRxData[0] );
}
slaveRxCount++;
if (slaveRxCount == TRANSFER_SIZE)
{
//We will assume that our slave data matches our desired Xfer size in the interest of speed
if(data_is_for_us){
Parse_SPI_Data(slaveRxData); //now parts the data
}
slaveRxCount = 0;
isSlaveTransferCompleted = true;
// LPSPI_DisableInterrupts(EXAMPLE_LPSPI_SLAVE_BASEADDR, kLPSPI_RxInterruptEnable);
break;
}
}
}
//kLPSPI_TransferCompleteFlag
//check if the frame complete flag has thrown. This does fire when uncommented
// if ((status_flags & (uint32_t)kLPSPI_FrameCompleteFlag) != 0U) {
// //if the frame is complete, we reset our slaveRxCount
// slaveRxCount = 0; // TODO get this working properly
// LPSPI_ClearStatusFlags( EXAMPLE_LPSPI_SLAVE_BASEADDR, kLPSPI_FrameCompleteFlag );
// }
if ((status_flags & (uint32_t)kLPSPI_TransferCompleteFlag) != 0U) {
//if the frame is complete, we reset our slaveRxCount
slaveRxCount = 0; // TODO get this working properly
LPSPI_ClearStatusFlags( EXAMPLE_LPSPI_SLAVE_BASEADDR, kLPSPI_TransferCompleteFlag );
}
SDK_ISR_EXIT_BARRIER;
}
So my question is :
What signal should I expect when the CS line goes high/idle? It seems that FrameComplete is really just checking if 8 an 8-bit frame has arrived, which is not really useful for me. However, I do not know if TransferComplete corresponds to the CS line going idle, or something else. There is not really any documentation around this
Thanks
解決済! 解決策の投稿を見る。
Trying to detect the state of the CS pin could complicate your project, I recommend you instead to use the SR[MBF] Module busy flag (48.5.1.5 Status (SR) reference manual) to detect if the module is in idle or busy state.
Let me know if this works for you.
Best Regards, Miguel.
Trying to detect the state of the CS pin could complicate your project, I recommend you instead to use the SR[MBF] Module busy flag (48.5.1.5 Status (SR) reference manual) to detect if the module is in idle or busy state.
Let me know if this works for you.
Best Regards, Miguel.
This appears to work well, thank you