Dear experts,
I have was hoping you could provide me with some advice.
I am using the C6748 together with DSP/BIOS (v5.42.1.09) and the EDMA3 LLD (v1.11.03.01).
I have recently moved the Tx part of our UART driver over to EDMA in order to reduce CPU load. The UART Rx part of the driver has been using the EDMA3 for a while now and is considered stable.
Due to the asynchronous nature of UART Tx, the typical PING/PONG buffering approach cannot be used. Instead a new EDMA Tx transfer is initiated as new bytes become available for transmission. This is obviously a bit inefficient for small transmissions, but the CPU load reduction at continuous high-speed transmissions are very significant, which is the typical use-case.
The basic concept of the driver is as follows:
- The user calls the UART transmit function, which essentially buffers the user's data in a large process buffer and posts a semaphore.
- A dedicated UART transmit task pends on this semaphore and when awoken, it programs the EDMA to transfer the available bytes, up until a maximum of 1024 bytes at a turn. An "EDMA busy" flag is also set to indicate that an UART EDMA Tx transfer is in progress, to prevent the EDMA from being programmed again, while it has not yet completed.
- Since the UART Rx is also using the EDMA3, the UART FIFO buffering cannot be enabled/disabled to trigger a UART Tx event for the EDMA3. Instead a single byte is written to the UART Tx FIFO (which is empty at this point) through the THR register, followed by enabling the EDMA transfer with a EDMA3_DRV_enableTransfer() call.
- When the EDMA UART Tx transfer has completed, a callback is executed to disable the UART Tx channel [EDMA3_DRV_disableTransfer() and EDMA3_DRV_disableLogicalChannel()] and clear the TCC flag [EDMA3_DRV_checkAndClearTcc()]. The "EDMA busy" flag is also cleared to indicate that a new UART EDMA Tx transfer can now be programmed. Finally, the semaphore is posted again to awake the task to check if there are still bytes available for transfer.
My problem is as follows:
- At an UART baud rate of 115200, the driver works perfectly
- At an UART baud rate of 230400, bytes are sometimes dropped or swapped
I have put in some statistic variables to count the amount of EDMA UART Tx transfers initiated and the amount of callbacks received. At a baud rate of 115200, these two variables stay exactly in sync, i.e. one callback for every transfer initiated. However, at a baud rate of 230400 I found that the callback function fires more than actual transfers initiated. I believe that this would explain my data errors, but I just can't explain why this is happening.
Do you guys maybe have any ideas? Am I maybe triggering the UART Tx EDMA event incorrectly?