KL28 LPSPI last bit not complete in continues PCS mode

cancel
Showing results for 
Search instead for 
Did you mean: 

KL28 LPSPI last bit not complete in continues PCS mode

884 Views
liangliangma
Contributor II

The last bit of a frame does not complete when CONT and CONTC bits are set in LPSPI TCR register, the SCK signal keeps high as the wave form in the attached picture. Is there any problem with register configuration, or it is designed like this?

I know that clear CONT and CONTC bits will complete the transfer and deassert PCS, but for the write-then-read operations which is the common use case of SPI bus, the CS signal must be kept asserted, and in that case the first frame received in the read operation has to be abandoned, as it is actually the last frame of the previous write operation. This is quite a dirty solution for the LPSPI driver and makes the SPI a asynchronous interface.

Labels (1)
5 Replies

151 Views
drodgers
Senior Contributor I

Hi there,

I know this is two years after the original post and reply, but I wanted to let you know that I have run into this exact same issue on the RT1050 and its LPSPI peripheral.  I've made a forum post here.  Long and short of it... there is no solution other than not attempting another transfer with PCSx asserted after performing a read.  When doing a write-then-read, when you write N bytes, don't require or expect to pull N bytes out of the RX FIFO... just keep a "garbage" count of N bytes, and decrement it with each byte you pull out of the RX FIFO.  But don't require that the garbage count reach zero before finishing the write; carry that over to the read operation.  As you start doing your dummy writes to get your read bytes, you'll then trash the remaining garbage byte(s) from the RX FIFO, and start pulling the actual read data from the RX FIFO.  When your read is complete, write TCR with CONTC set to 0, and that will finish the last SCK cycle and release the last byte into the RX FIFO.  Hope this helps.

0 Kudos

151 Views
liangliangma
Contributor II

Hi David,

Thanks very much for sharing your findings. I have also found the same solution, but it makes the general driver dirty, in the end I decide to use the PCS only in a high speed write only device, and use GPIO in the generic driver for all other low speed devices. I have checked the LPSPI driver in the linux kernel, it seems an extra byte of 0 is written at the end of the transmit. I haven't got chance to check how it works yet.

This KL28 MCU is the very first one from Freescale I have used, it seems like there is no software/firmware guy involved during the design, a lot of things just seems weird to me.

151 Views
drodgers
Senior Contributor I

For what it's worth, NXP has now confirmed that this is in fact a bug in the LPSPI IP (silicon), and they will fix it, presumably before the next release of a chip with the LPSPI peripheral in it.

https://community.nxp.com/thread/500746

0 Kudos

151 Views
TomE
Specialist I

Shouldn't this be an item in the KL28 published Errata? I've read the latest one and can't find anything matching this.

Tom

0 Kudos

151 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi,

Sorry for the later reply.

I do a test with FRDM-KL28Z board. When finish the SPI transfer, customer need to clear the LPSPI_TCR register's [CONT] and [CONTC] bit.

My test code is below:


    /*Master config*/
    masterConfig.baudRate = TRANSFER_BAUDRATE;
    masterConfig.bitsPerFrame = 16;
    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 = EXAMPLE_LPSPI_MASTER_PCS_FOR_INIT;
    masterConfig.pcsActiveHighOrLow = kLPSPI_PcsActiveLow;

    masterConfig.pinCfg = kLPSPI_SdiInSdoOut;
    masterConfig.dataOutConfig = kLpspiDataOutRetained;

    LPSPI_MasterInit(EXAMPLE_LPSPI_MASTER_BASEADDR, &masterConfig, EXAMPLE_LPSPI_MASTER_CLOCK_FREQ);
    
    LPSPI0 ->FCR |= LPSPI_FCR_TXWATER(3);
    LPSPI0 ->TCR |= LPSPI_TCR_CONT_MASK;
    LPSPI0 ->TDR = 0x1234;
    LPSPI0 ->TDR = 0x5678;
    LPSPI0 ->TDR = 0x9abc;
    
    LPSPI0 ->TCR &= ~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK);

Below is the test result:

pastedImage_1.png

Wish it helps.


Have a great day,
Ma Hui

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos