Hello,
I have a bit of an unexpected behaviour with an LPSPI on i.MXRT1166. My situation / setup is:
My problem now is, that instead of one 32 bit transfers, I get two on every HREQ. Any ideas what the reason for that could be?
If I put two TCRs into the FIFO, I get two transfers too. If I put three TCRs into it, it's three transfers. So these would work like expected. Only the situation with one transfer doesn't work.
I also tried splitting up the transfer into two 16 bit transfers. But in that case, I get three transfers during the first trigger and two (like expected) on all others.
My register settings are:
LPSPI_Type *lpspi = /* Pointer to my LPSPI */;
/* Disable module. */
lpspi->CR &= ~LPSPI_CR_MEN_MASK;
/* Flush FIFOs */
lpspi->CR |= LPSPI_CR_RRF_MASK | LPSPI_CR_RTF_MASK;
lpspi->CR &= ~LPSPI_CR_RRF_MASK | LPSPI_CR_RTF_MASK;
/* Make sure that FIFO is empty. */
assert(lpspi->FSR == 0);
lpspi->IER = 0;
lpspi->CCR = LPSPI_CCR_SCKDIV(precalculated_sckdiv) |
LPSPI_CCR_SCKPCS(0) |
LPSPI_CCR_PCSSCK(0) |
LPSPI_CCR_DBT(0);
lpspi->CFGR0 = LPSPI_CFGR0_HREN_MASK | LPSPI_CFGR0_CIRFIFO_MASK;
lpspi->CFGR1 = LPSPI_CFGR1_OUTCFG(1) | LPSPI_CFGR1_MASTER(1);
/* Disable the FIFO watermark. */
lpspi->FCR = 0;
/* Rx will be handled by DMA. */
lpspi->DER = LPSPI_DER_RDDE_MASK;
/* Everything is prepared. Module can be enabled again. */
lpspi->CR |= LPSPI_CR_MEN_MASK;
/*
* Prepare the DMA. The following snipped is at a different location in
* my original code. I copied it here to make the example more readable.
* "transfers" is the total number of ADC conversions that I expect in
* my bigger sequence.
*/
tcd->SADDR = (uintptr_t)&lpspi->RDR;
tcd->SDF = EDMA_TCD_SDF_SOFF(0) | EDMA_TCD_SDF_SSIZE_32BIT |
EDMA_TCD_SDF_SMOD(0) | EDMA_TCD_SDF_DSIZE_32BIT |
EDMA_TCD_SDF_DMOD(0);
tcd->NBYTES = EDMA_TCD_NBYTES_ALT_NBYTES(BYTES_PER_LPSPI_RX_TRANSFER) |
EDMA_TCD_NBYTES_ALT_MLOFF(0) | EDMA_TCD_NBYTES_ALT_DMLOE;
tcd->SLAST = 0;
tcd->DADDR = (uintptr_t)dma_buffer;
tcd->CDF = EDMA_TCD_CDF_DOFF(BYTES_PER_LPSPI_RX_TRANSFER) |
EDMA_TCD_CDF_CITER(transfers);
tcd->DLAST_SGA = 0;
tcd->BMF = EDMA_TCD_BMF_BITER(transfers);
/*
* Usually here comes a code that would enable the DMA channel and copy
* the tcd to the right location in the DMA so that the DMA can work
* on the next trigger.
*/
uint32_t tcr = LPSPI_TCR_CPOL(0) | LPSPI_TCR_CPHA(1) |
LPSPI_TCR_PRESCALE(ctx->adc.lpspi_prescale) | LPSPI_TCR_PCS(0) |
LPSPI_TCR_LSBF(0) | LPSPI_TCR_BYSW(0) | LPSPI_TCR_RXMSK(0) |
LPSPI_TCR_TXMSK(1) | LPSPI_TCR_WIDTH(1) |
LPSPI_TCR_FRAMESZ(DATABITS_PER_CHANNEL * CHANNELS - 1);
/* Put SPI commands into the FIFO */
lpspi->TCR = tcr;
/* Clear empty flags */
lpspi->SR |= LPSPI_SR_REF_MASK | LPSPI_SR_TEF_MASK;
/*
* No transfer happened yet. As soon as a HREQ happens, I would expect
* one transfer with 16 clocks (32 bits). But instead I get two on each
* HREQ.
*
* I checked the LPSPI FIFO Status register at this point and it shows
* only one word in the FIFO.
*/
Best regards
Christian Mauderer
Hello @EdwinHz,
yes, I still experience the issue. At the moment I assume that it is an undiscovered chip erratum. Putting two or three TCR commands into the FIFO buffer works just like expected. There is only a problem when putting a single one into the FIFO.
Best regards
Christian Mauderer
It's very likely that it is an undiscovered chip erratum. I believe this weird behaviour with the TCR register has been reported before, on the following community post: https://community.nxp.com/t5/i-MX-RT/LPSPI-bugs-around-TCR-More-FSL-library-bugs-plus-an-LPSPI/td-p/...
I was told that the SDK team is working on implementing software workarounds to these issues. I will add this to the comments for the SDK team.
Sorry for the inconvenience this may cause.
BR,
Edwin.
Hello @EdwinHz,
thanks for the reply. The post that you linked seems to handle mainly reading of the TCR (which is a known erratum). I have problems with writing into the FIFO. So I would expect that this doesn't apply here? Further issues that are linked from that post have some trouble with the HAL.
Did I miss any hints that would apply to my problem? I currently have trouble with a single TCR write with masked Tx-data triggered by a HREQ. And all that in a circular FIFO. So most likely I managed to pick nearly every exotic configuration that the LPSPI offers.
Is there some known workarround for problems with writing TCRs? I don't have a problem if I have to implement them myself. I don't use a lot of the SDK in my current situation anyway.
I know, that on the i.MXRT1050, there are some errata, that would apply to my situation (ERR011097 and ERR050607). But they don't seem to be applicable to the i.MXRT116x series. Is that still correct or are they just not listed for the i.MXRT116x?
With kind regards
Christian Mauderer