I am using NXP i. MX RT 1052 controller.
I am using SDK_2.9.1_EVKB-IMXRT1050 code for DMA LPSPI at location '...\boards\evkbimxrt1050\driver_examples\lpspi\edma_b2b_transfer\master'.
In the code, in LPSPI_MasterTransferEDMA() function, if isPcsContinuous is enabled, a separate software TCD is configured and used to pass data to SPI TCR register after data is transmitted to TDR register.
i have below questions -
1. What is the use of isPcsContinuous bit?
2. What is the need of separate software TCD when there is separate TCD for Tx and Rx channel?
3. Why there is need to put data in TCR register through DMA?
Fore reference, the code snippet is provided as below -
if (handle->isPcsContinuous)
{
handle->transmitCommand = base->TCR & ~(LPSPI_TCR_CONTC_MASK | LPSPI_TCR_CONT_MASK);
transferConfigTx.srcAddr = (uint32_t) & (handle->transmitCommand);
transferConfigTx.srcOffset = 0;
transferConfigTx.destAddr = (uint32_t) & (base->TCR);
transferConfigTx.destOffset = 0;
transferConfigTx.srcTransferSize = kEDMA_TransferSize4Bytes;
transferConfigTx.destTransferSize = kEDMA_TransferSize4Bytes;
transferConfigTx.minorLoopBytes = 4;
transferConfigTx.majorLoopCounts = 1;
EDMA_TcdReset(softwareTCD_pcsContinuous);
EDMA_TcdSetTransferConfig(softwareTCD_pcsContinuous, &transferConfigTx, NULL);
}
if (handle->txData != NULL)
{
transferConfigTx.srcAddr = (uint32_t)(handle->txData);
transferConfigTx.srcOffset = 1;
}
else
{
transferConfigTx.srcAddr = (uint32_t)(&handle->txBuffIfNull);
transferConfigTx.srcOffset = 0;
}
transferConfigTx.destOffset = 0;
transferConfigTx.srcTransferSize = kEDMA_TransferSize1Bytes;
dif = 0U;
switch (handle->bytesEachRead)
{
case (1U):
transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes;
transferConfigTx.minorLoopBytes = 1;
if (handle->isByteSwap)
{
dif = 3;
}
break;
case (2U):
transferConfigTx.destTransferSize = kEDMA_TransferSize2Bytes;
transferConfigTx.minorLoopBytes = 2;
if (handle->isByteSwap)
{
dif = 2;
}
break;
case (4U):
transferConfigTx.destTransferSize = kEDMA_TransferSize4Bytes;
transferConfigTx.minorLoopBytes = 4;
break;
default:
transferConfigTx.destTransferSize = kEDMA_TransferSize1Bytes;
transferConfigTx.minorLoopBytes = 1;
assert(false);
break;
}
transferConfigTx.destAddr = (uint32_t)txAddr + dif;
transferConfigTx.majorLoopCounts = handle->writeRegRemainingTimes;
if (isThereExtraTxBytes)
{
EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
&transferConfigTx, softwareTCD_extraBytes);
}
else if (handle->isPcsContinuous)
{
EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
&transferConfigTx, softwareTCD_pcsContinuous);
}
else
{
EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
&transferConfigTx, NULL);
}
Hi,
1. isPcsContinuous means that is configured for a continuous transfer that keeps PCS asserted between frames.
2. Please check below explanation.
3. Writing to the TCR register inserts a new frame during a continuous transfer, in this case, TCR is not an ordinary register. Instead, we should view it as the entry to send control command.
Best regards,
Felipe