There's a new bug introduced in the 2.8.2 SDK for iMX RT1010, in EDMA_SubmitTransfer(). The function now also checks if the TCD's CITER != BITER, which actually will be the case if the EDMA_AbortTransfer() is called while the transfer is active. This will result in EDMA_SubmitTransfer() to return busy, preventing the restart of the EDMA transfer, contradicting the statement at EDMA_AbortTransfer: "Users can submit another transfer after calling this API."
The details of the new busy condition:
/* * Check if EDMA channel is busy: * 1. if channel active bit is set, it implies that minor loop is executing, then channel is busy * 2. if channel active bit is not set and BITER not equal to CITER, it implies that major loop is executing, * then channel is busy * * There is one case can not be covered in below condition: * When transfer request is submitted, but no request from peripheral, that is to say channel sevice doesn't * begin, if application would like to submit another transfer , then the TCD will be overwritten, since the * ACTIVE is 0 and BITER = CITER, for such case, it is a scatter gather(link TCD) case actually, so * application should enabled TCD pool for dynamic scatter gather mode by calling EDMA_InstallTCDMemory. */ if (((handle->base->TCD[handle->channel].CSR & DMA_CSR_ACTIVE_MASK) != 0U) || (((handle->base->TCD[handle->channel].CITER_ELINKNO & DMA_CITER_ELINKNO_CITER_MASK) != (handle->base->TCD[handle->channel].BITER_ELINKNO & DMA_BITER_ELINKNO_BITER_MASK)))) { return kStatus_EDMA_Busy; }
Hi Jeremy, do we have any update on this issue, I faced the same thing and I think the issue from this
back in old days, the checking is different
"Comparing the driver versions, I do think that the change to EDMA_SubmitTransfer() checking for CITER != BITER makes sense, but I see how that cause an issue when there is an aborted transfer. I think the correct fix is to change the EMDA_AbortTransfer function so that it clears BITER and CITER along with the CSR. This will prevent an aborted transfer from looking like a major loop in progress to the submit transfer function."
Thanks for the quick response, I do think that by resetting CITER and BITER could solve the issue
Let me test out the changes and get back to you
Hi Benedek,
Sorry for the reply late.
I don't think call EDMA_SubmitTransfer() after the EDMA_Abort Transfer() function, then it will result in EDMA_SubmitTransfer() to return busy. as the CSR register will be cleared in the EDMA_Abort Transfer() as below shows.
Have a great day,
TIC
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Here's how to reproduce the issue:
while (1)
{
/* If RX is idle and g_rxBuffer is empty, start to read data to g_rxBuffer. */
if ((!rxOnGoing) && rxBufferEmpty)
{
rxOnGoing = true;
LPUART_ReceiveEDMA(DEMO_LPUART, &g_lpuartEdmaHandle, &receiveXfer);
}
// TEST BEGIN
{
lpuart_transfer_t received = receiveXfer;
LPUART_EnableRxDMA(DEMO_LPUART, 0);
// ensure no DMA data is cached
__DSB();
int status = LPUART_TransferGetReceiveCountEDMA(DEMO_LPUART, &g_lpuartEdmaHandle, (uint32_t*)&received.dataSize);
if (status == kStatus_NoTransferInProgress)
{
// if the transfer is complete, the length isn't modified
// transferred.dataSize = mEdma.rxDataSizeAll;
}
if (received.dataSize == 0)
{
// nothing was received, just re-enable feeding DMA
LPUART_EnableRxDMA(DEMO_LPUART, 1);
}
else
{
// need to abort current transfer before starting a new one
LPUART_TransferAbortReceiveEDMA(DEMO_LPUART, &g_lpuartEdmaHandle);
// switch to other buffer
LPUART_ReceiveEDMA(DEMO_LPUART, &g_lpuartEdmaHandle, &receiveXfer);
}
}
// TEST END
/* If TX is idle and g_txBuffer is full, start to send data. */
if ((!txOnGoing) && txBufferFull)
{
txOnGoing = true;
LPUART_SendEDMA(DEMO_LPUART, &g_lpuartEdmaHandle, &sendXfer);
}
/* If g_txBuffer is empty and g_rxBuffer is full, copy g_rxBuffer to g_txBuffer. */
if ((!rxBufferEmpty) && (!txBufferFull))
{
memcpy(g_txBuffer, g_rxBuffer, ECHO_BUFFER_LENGTH);
rxBufferEmpty = true;
txBufferFull = true;
}
}
The result is:
The abort and restart is unsuccessful, which leads to the same byte being reported as received, and no further data reception is happening.
Hi,
I‘ve basically replicated your phenomenon, and I'll report this phenomenon in the next round of the Filed Trial of the SDK library.
Have a great day,
TIC
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------
Hi Benedek Kupper,
Thank you for your interest in NXP Semiconductor products and
for the opportunity to serve you.
I'll check it soon.
Have a great day,
TIC
-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!
- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------