Problems with single Rx only dual SPI transfers using LPSPI in Circular FIFO mode on i.MXRT1166

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

Problems with single Rx only dual SPI transfers using LPSPI in Circular FIFO mode on i.MXRT1166

664 次查看
christian_mauderer
Contributor III

Hello,

I have a bit of an unexpected behaviour with an LPSPI on i.MXRT1166. My situation / setup is:

  • I'm trying to read data from an ADC connected via dual SPI.
  • Every time, the ADC has converted data, I get a short signal via the HREQ pin. The signal is about 4 SPI clock cycles long (shorter than a SPI transaction).
  • With the HREQ, a SPI transfer of 32 bit on two lines (-> 16 clocks) should be triggered.
  • I've set up a circular FIFO with a single TCR in the LPSPI that should read the data.
  • The data is pulled from the LPSPI via DMA.

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

0 项奖励
回复
4 回复数

614 次查看
EdwinHz
NXP TechSupport
NXP TechSupport

Hi @christian_mauderer,

I apologize for the late response. Are you still experiencing this issue?

BR,
Edwin.

0 项奖励
回复

601 次查看
christian_mauderer
Contributor III

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

0 项奖励
回复

578 次查看
EdwinHz
NXP TechSupport
NXP TechSupport

Hi @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.

0 项奖励
回复

521 次查看
christian_mauderer
Contributor III

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

0 项奖励
回复