IMXRT 106x LPSPI Slave Register CS Idle

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

IMXRT 106x LPSPI Slave Register CS Idle

Jump to solution
578 Views
functional_des
Contributor III

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 

Labels (1)
0 Kudos
1 Solution
545 Views
Miguel04
NXP TechSupport
NXP TechSupport

Hi @functional_des 

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.

View solution in original post

0 Kudos
2 Replies
546 Views
Miguel04
NXP TechSupport
NXP TechSupport

Hi @functional_des 

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.

0 Kudos
539 Views
functional_des
Contributor III

This appears to work well, thank you

0 Kudos