LPSPI read extra byte

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

LPSPI read extra byte

ソリューションへジャンプ
406件の閲覧回数
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 解決策
286件の閲覧回数
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 返答(返信)
355件の閲覧回数
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 件の賞賛
返信
307件の閲覧回数
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 件の賞賛
返信
287件の閲覧回数
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

 

 

 

260件の閲覧回数
rmaier
Contributor III

Thanks for your help, Petr.

タグ(2)
0 件の賞賛
返信