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;