LPSPI read extra byte

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

LPSPI read extra byte

跳至解决方案
404 次查看
rmaier
Contributor III

Hello,

 

I am struggling with the LPSPI module on the S32K144. I want to send some bytes and receive some bytes of varying length. This works with the exception that I have to send an additional dummy byte. Let's say I want to Tx 2 bytes and Rx 2 bytes, I have to Tx a total of 5 bytes. What am I missing to only have to send 4 bytes to write/read 4 bytes?

Here's my function:

void Spi_Transceive(uint8_t txLen, uint8_t *txBuf, uint8_t rxLen, uint8_t *rxBuf, uint8_t module, uint8_t pcs)
{

    uint16_t total = rxLen + txLen - 1;
    uint32_t totalBytes = 0;
    const uint32_t tcr_base =
        LPSPI_TCR_FRAMESZ(7) | // 8-bit frames
        LPSPI_TCR_PCS(pcs) |
        LPSPI_TCR_CPOL(0) | 
        LPSPI_TCR_CPHA(1) |
        LPSPI_TCR_PRESCALE(0) |
        LPSPI_TCR_WIDTH(0) |
        LPSPI_TCR_CONTC(1);

    LPSPI2->CR |= LPSPI_CR_RTF_MASK | LPSPI_CR_RRF_MASK;
    LPSPI2->SR = 0xFFFFFFFFu;
    LPSPI2->FCR = LPSPI_FCR_TXWATER(0) | LPSPI_FCR_RXWATER(0);

    while (!(LPSPI2->SR & LPSPI_SR_TDF_MASK))
        ;
    LPSPI2->TCR = tcr_base | LPSPI_TCR_CONT(1);
    LPSPI2->TDR = (uint8_t)txBuf[0];
    totalBytes++;

    for (uint8_t i = 1; i < txLen; i++)
    {
        if (totalBytes == total)
        {
            LPSPI2->TCR = tcr_base | LPSPI_TCR_CONT(0);
        }

        while (!(LPSPI2->SR & LPSPI_SR_TDF_MASK))
            ;

        LPSPI2->TDR = (uint8_t)txBuf[i];
        totalBytes++;

        while (!(LPSPI2->SR & LPSPI_SR_RDF_MASK))
            ;
        (void)LPSPI2->RDR;
    }

    if (rxLen > 0)
    {
        while (!(LPSPI2->SR & LPSPI_SR_TDF_MASK))
            ;
        LPSPI2->TDR = 0x00; // NOP
        while (!(LPSPI2->SR & LPSPI_SR_RDF_MASK))
            ;
        (void)LPSPI2->RDR;
    }
    else
    {
        return;
    }

    for (uint8_t i = 0; i < rxLen; i++)
    {
        if (totalBytes == total)
        {
            LPSPI2->TCR = tcr_base | LPSPI_TCR_CONT(0);
        }
        while (!(LPSPI2->SR & LPSPI_SR_TDF_MASK))
            ;

        LPSPI2->TDR = 0x00; // NOP
        totalBytes++;

        while (!(LPSPI2->SR & LPSPI_SR_RDF_MASK))
            ;
        rxBuf[i] = (uint8_t)LPSPI2->RDR;
    }
}

 

Here's the initialization:

    PCC->PCCn[PCC_LPSPI2_INDEX] = 0;                  /* Disable clocks to modify PCS ( default) 	*/
    PCC->PCCn[PCC_LPSPI2_INDEX] = PCC_PCCn_PR_MASK    /* (default) Peripheral is present.			*/
                                  | PCC_PCCn_CGC_MASK /* Enable PCS=SPLL_DIV2 (40 MHz func'l clock) 	*/
                                  | PCC_PCCn_PCS(6);

    LPSPI2->CR = 0x00000000;    
    LPSPI2->IER = 0x00000000;   
    LPSPI2->DER = 0x00000000;  
    LPSPI2->CFGR0 = 0x00000000; 
    LPSPI2->CFGR1 = LPSPI_CFGR1_MASTER_MASK | LPSPI_CFGR1_SAMPLE(1) | LPSPI_CFGR1_AUTOPCS(0) | LPSPI_CFGR1_PCSPOL(0b0000); 

    LPSPI2->TCR = LPSPI_TCR_CPHA_MASK | LPSPI_TCR_PRESCALE(2) | LPSPI_TCR_PCS(0) | LPSPI_TCR_FRAMESZ(7) | LPSPI_TCR_CONT(1);

    LPSPI2->CCR = LPSPI_CCR_SCKPCS(4) | LPSPI_CCR_PCSSCK(4) | LPSPI_CCR_DBT(8) | LPSPI_CCR_SCKDIV(8); 
    LPSPI2->FCR = LPSPI_FCR_TXWATER(3); 
    LPSPI2->CR = LPSPI_CR_MEN_MASK | LPSPI_CR_DBGEN_MASK; 

  

标记 (2)
0 项奖励
回复
1 解答
284 次查看
PetrS
NXP TechSupport
NXP TechSupport

Hi,

clear CONTC bit in TCR.
See attached main.c file I used in S32K144_Project_LPSPI demo.
It gives right frames. I tested below sequences

PetrS_0-1755679051074.pngPetrS_1-1755679060431.png

BR, Petr

 

 

 

在原帖中查看解决方案

4 回复数
353 次查看
PetrS
NXP TechSupport
NXP TechSupport

Hi,

for each write to TDR you should increment your totalBytes. For each TDR write there should be RDR reading. After CONT is cleared you should read RDR finally. Try below one, but I did not tested that.

 

void Spi_Transceive(uint8_t txLen, uint8_t *txBuf, uint8_t rxLen, uint8_t *rxBuf, uint8_t module, uint8_t pcs)
{

    uint16_t total = rxLen + txLen;
    uint32_t totalBytes = 0;
    const uint32_t tcr_base =
        LPSPI_TCR_FRAMESZ(7) | // 8-bit frames
        LPSPI_TCR_PCS(pcs) |
        LPSPI_TCR_CPOL(0) | 
        LPSPI_TCR_CPHA(1) |
        LPSPI_TCR_PRESCALE(0) |
        LPSPI_TCR_WIDTH(0) |
        LPSPI_TCR_CONTC(1);

    LPSPI2->CR |= LPSPI_CR_RTF_MASK | LPSPI_CR_RRF_MASK;
    LPSPI2->SR = 0xFFFFFFFFu;
    LPSPI2->FCR = LPSPI_FCR_TXWATER(0) | LPSPI_FCR_RXWATER(0);

    if (txLen>0)
	{
    	LPSPI2->TCR = tcr_base | LPSPI_TCR_CONT(1);
		while (!(LPSPI2->SR & LPSPI_SR_TDF_MASK));
		LPSPI2->TDR = *txBuf++;
		totalBytes++;
		while(totalBytes < txLen)
		{
			while (!(LPSPI2->SR & LPSPI_SR_TDF_MASK));
			LPSPI2->TDR = *txBuf++;
			totalBytes++;
			while (!(LPSPI2->SR & LPSPI_SR_RDF_MASK));
			(void)LPSPI2->RDR;
		}
		if(rxLen==0) 
		{
			LPSPI2->TCR = tcr_base | LPSPI_TCR_CONT(0);
			while (!(LPSPI2->SR & LPSPI_SR_RDF_MASK));
			(void)LPSPI2->RDR;
		}
		
	}
    
    if (rxLen>0)
    {
    	if(txLen==0) LPSPI2->TCR = tcr_base | LPSPI_TCR_CONT(1);
		while (!(LPSPI2->SR & LPSPI_SR_TDF_MASK));
		LPSPI2->TDR = 0x00; // NOP
		totalBytes++;
		if(txLen>0)
		{
			while (!(LPSPI2->SR & LPSPI_SR_RDF_MASK));
			(void)LPSPI2->RDR;
    	}
     	while(totalBytes < total)
		{
    		while (!(LPSPI2->SR & LPSPI_SR_TDF_MASK));
    		LPSPI2->TDR = 0x00; // NOP
			totalBytes++;
			while (!(LPSPI2->SR & LPSPI_SR_RDF_MASK));
			*rxBuf++ = LPSPI2->RDR;
		}
    	LPSPI2->TCR = tcr_base | LPSPI_TCR_CONT(0);
		while (!(LPSPI2->SR & LPSPI_SR_RDF_MASK));
		*rxBuf++ = LPSPI2->RDR;
    }
	
}

 BR, Petr

0 项奖励
回复
305 次查看
rmaier
Contributor III

Hello Petr,

 

Thanks for your support. The first read attempt always stays forever in the while RDF mask loop. Even with your code. Any idea why?

if (rxLen == 0)
        {
            LPSPI2->TCR = tcr_base | LPSPI_TCR_CONT(0);
            while (!(LPSPI2->SR & LPSPI_SR_RDF_MASK)) // Stuck here on 1st read
                ;
            (void)LPSPI2->RDR;
        }

 

0 项奖励
回复
285 次查看
PetrS
NXP TechSupport
NXP TechSupport

Hi,

clear CONTC bit in TCR.
See attached main.c file I used in S32K144_Project_LPSPI demo.
It gives right frames. I tested below sequences

PetrS_0-1755679051074.pngPetrS_1-1755679060431.png

BR, Petr

 

 

 

258 次查看
rmaier
Contributor III

Thanks for your help, Petr.

标记 (2)
0 项奖励
回复