Part Number: AM3354
Hi experts
Our customers have problems with UART sending and receiving
Processor: am3354
OS: ucos
UART transceivers use EDMA. The driver code is as follows
void STM32F_StartDMARecv( INT8U COM_No, INT8U *pStartAddr )
{
UARTDMAEnable(SOC_Uart_BaseAddr[COM_No], UART_DMA_MODE_1_ENABLE);
UARTx_RxEDMAPaRAMSetConfig(SOC_Uart_BaseAddr[COM_No], pStartAddr, 63, EdmaUart_RxChaNum[COM_No], 0xFFFF, EdmaUart_RxChaNum[COM_No]);
EDMA3EnableTransfer(EdmaUart_RxChaNum[COM_No], EDMA3_TRIG_MODE_EVENT);
}
void UARTDMAEnable(unsigned int baseAdd, unsigned int dmaModeFlag)
{
/* Setting the DMAMODECTL bit in SCR to 1. */
HWREG(baseAdd + UART_SCR) |= (UART_SCR_DMA_MODE_CTL);
/* Clearing the DMAMODE2 field in SCR. */
HWREG(baseAdd + UART_SCR) &= ~(UART_SCR_DMA_MODE_2);
/* Programming the DMAMODE2 field in SCR. */
HWREG(baseAdd + UART_SCR) |= ((dmaModeFlag << UART_SCR_DMA_MODE_2_SHIFT) &
UART_SCR_DMA_MODE_2);
}
void UARTx_RxEDMAPaRAMSetConfig(
unsigned int baseaddr,
unsigned char *rxBuffer,
unsigned int length,
unsigned int tccNum,
unsigned short linkAddr,
unsigned int chNum)
{
/* Fill the PaRAM Set with transfer specific information */
paramSet.srcAddr = (unsigned int)baseaddr;
paramSet.destAddr = (unsigned int)rxBuffer;
paramSet.aCnt = (unsigned short)1;
paramSet.bCnt = (unsigned short)length; //paramSet.bCnt = (unsigned short)63; 20171013
paramSet.cCnt = (unsigned short)1;
paramSet.destBIdx = (short)1;
paramSet.destCIdx = (short)1;
paramSet.srcBIdx = (short)0;
paramSet.srcCIdx = (short)0;
paramSet.linkAddr = (unsigned short)linkAddr;
paramSet.bCntReload = (unsigned short)0;
/* OPT PaRAM Entries. */
paramSet.opt = (unsigned int)0x0;
/* Source and Destination addressing modes are Incremental. */
/* Enable AB Synchronized Transfer. */
paramSet.opt |= (1 << EDMA3CC_OPT_SYNCDIM_SHIFT);
/* Setting the Transfer Complete Code(TCC). */
paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
/* Enabling the Completion Interrupt. */
paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
/* Now write the PaRAM Set */
EDMA3SetPaRAM(chNum, ¶mSet);
}
/****************************发送部分代码*******************************************/
void StartDMASend( INT8U COM_No, INT8U *pDMATransStart, INT16U DMATransNum )
{
if(COM_No==2)
{
UARTDMAEnable(SOC_UART_3_REGS, UART_DMA_MODE_1_ENABLE);
UART3TxEDMAPaRAMSetConfig(pDMATransStart,
DMATransNum,//numByteChunks * txBytesPerEvent,
EDMA3_CHA_UART3_TX_Direct,
EDMA3CC_OPT(2),
EDMA3_CHA_UART3_TX_Direct);
TxDummyPaRAMConfEnable(2);
EDMA3SetEvt( EDMA3_CHA_UART3_TX_Direct );
EDMA3EnableTransfer(EDMA3_CHA_UART3_TX_Direct,EDMA3_TRIG_MODE_EVENT);
}
}
void UART3TxEDMAPaRAMSetConfig(unsigned char *txBuffer,
unsigned int length,
unsigned int tccNum,
unsigned short linkAddr,
unsigned int chNum)
{
EDMA3CCPaRAMEntry paramSet;
/* Fill the PaRAM Set with transfer specific information */
paramSet.srcAddr = (unsigned int) txBuffer;
paramSet.destAddr = (unsigned int)SOC_UART_3_REGS;
paramSet.aCnt = (unsigned short)1;
paramSet.bCnt = (unsigned short)length;
paramSet.cCnt = (unsigned short)1;
paramSet.srcBIdx = (short)1;
paramSet.srcCIdx = (short)1;
/* The destination indexes should not increment since it is a h/w register. */
paramSet.destBIdx = (short)0;
paramSet.destCIdx = (short)0;
paramSet.linkAddr = (unsigned short)linkAddr;
paramSet.bCntReload = (unsigned short)0;
/* OPT PaRAM entries. */
paramSet.opt = (unsigned int)0x0;
/* Source and Destination addressing modes are Incremental. */
/* AB Synchronized Transfer. */
// paramSet.opt |= (1 << EDMA3CC_OPT_SYNCDIM_SHIFT);
/* Setting the Transfer Complete Code(TCC). */
paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
/* Enabling the Completion Interrupt. */
paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
/* Now write the PaRAM Set */
EDMA3SetPaRAM(chNum, ¶mSet);
}
/****************************���ղ��ִ���*******************************************/
void STM32F_StartDMARecv( INT8U COM_No, INT8U *pStartAddr )
{
UARTDMAEnable(SOC_Uart_BaseAddr[COM_No], UART_DMA_MODE_1_ENABLE);
UARTx_RxEDMAPaRAMSetConfig(SOC_Uart_BaseAddr[COM_No], pStartAddr, 63, EdmaUart_RxChaNum[COM_No], 0xFFFF, EdmaUart_RxChaNum[COM_No]);
EDMA3EnableTransfer(EdmaUart_RxChaNum[COM_No], EDMA3_TRIG_MODE_EVENT);
}
void UARTDMAEnable(unsigned int baseAdd, unsigned int dmaModeFlag)
{
/* Setting the DMAMODECTL bit in SCR to 1. */
HWREG(baseAdd + UART_SCR) |= (UART_SCR_DMA_MODE_CTL);
/* Clearing the DMAMODE2 field in SCR. */
HWREG(baseAdd + UART_SCR) &= ~(UART_SCR_DMA_MODE_2);
/* Programming the DMAMODE2 field in SCR. */
HWREG(baseAdd + UART_SCR) |= ((dmaModeFlag << UART_SCR_DMA_MODE_2_SHIFT) &
UART_SCR_DMA_MODE_2);
}
void UARTx_RxEDMAPaRAMSetConfig(
unsigned int baseaddr,
unsigned char *rxBuffer,
unsigned int length,
unsigned int tccNum,
unsigned short linkAddr,
unsigned int chNum)
{
/* Fill the PaRAM Set with transfer specific information */
paramSet.srcAddr = (unsigned int)baseaddr;
paramSet.destAddr = (unsigned int)rxBuffer;
paramSet.aCnt = (unsigned short)1;
paramSet.bCnt = (unsigned short)length; //paramSet.bCnt = (unsigned short)63; 20171013
paramSet.cCnt = (unsigned short)1;
paramSet.destBIdx = (short)1;
paramSet.destCIdx = (short)1;
paramSet.srcBIdx = (short)0;
paramSet.srcCIdx = (short)0;
paramSet.linkAddr = (unsigned short)linkAddr;
paramSet.bCntReload = (unsigned short)0;
/* OPT PaRAM Entries. */
paramSet.opt = (unsigned int)0x0;
/* Source and Destination addressing modes are Incremental. */
/* Enable AB Synchronized Transfer. */
paramSet.opt |= (1 << EDMA3CC_OPT_SYNCDIM_SHIFT);
/* Setting the Transfer Complete Code(TCC). */
paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
/* Enabling the Completion Interrupt. */
paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
/* Now write the PaRAM Set */
EDMA3SetPaRAM(chNum, ¶mSet);
}
/****************************���Ͳ��ִ���*******************************************/
void StartDMASend( INT8U COM_No, INT8U *pDMATransStart, INT16U DMATransNum )
{
if(COM_No==2)
{
UARTDMAEnable(SOC_UART_3_REGS, UART_DMA_MODE_1_ENABLE);
UART3TxEDMAPaRAMSetConfig(pDMATransStart,
DMATransNum,//numByteChunks * txBytesPerEvent,
EDMA3_CHA_UART3_TX_Direct,
EDMA3CC_OPT(2),
EDMA3_CHA_UART3_TX_Direct);
TxDummyPaRAMConfEnable(2);
EDMA3SetEvt( EDMA3_CHA_UART3_TX_Direct );
EDMA3EnableTransfer(EDMA3_CHA_UART3_TX_Direct,EDMA3_TRIG_MODE_EVENT);
}
}
void UART3TxEDMAPaRAMSetConfig(unsigned char *txBuffer,
unsigned int length,
unsigned int tccNum,
unsigned short linkAddr,
unsigned int chNum)
{
EDMA3CCPaRAMEntry paramSet;
/* Fill the PaRAM Set with transfer specific information */
paramSet.srcAddr = (unsigned int) txBuffer;
paramSet.destAddr = (unsigned int)SOC_UART_3_REGS;
paramSet.aCnt = (unsigned short)1;
paramSet.bCnt = (unsigned short)length;
paramSet.cCnt = (unsigned short)1;
paramSet.srcBIdx = (short)1;
paramSet.srcCIdx = (short)1;
/* The destination indexes should not increment since it is a h/w register. */
paramSet.destBIdx = (short)0;
paramSet.destCIdx = (short)0;
paramSet.linkAddr = (unsigned short)linkAddr;
paramSet.bCntReload = (unsigned short)0;
/* OPT PaRAM entries. */
paramSet.opt = (unsigned int)0x0;
/* Source and Destination addressing modes are Incremental. */
/* AB Synchronized Transfer. */
// paramSet.opt |= (1 << EDMA3CC_OPT_SYNCDIM_SHIFT);
/* Setting the Transfer Complete Code(TCC). */
paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);
/* Enabling the Completion Interrupt. */
paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
/* Now write the PaRAM Set */
EDMA3SetPaRAM(chNum, ¶mSet);
}
The serial data format is: baud rate 1000000, 8 data bits, even parity, 1 stop bit.
Q1:UART sending problem: When they using UART EDMA to send data, occasionally the data is not completely sent (missing the last few bytes). Like below figures


Q2:UART receiving problem: When receiving data, it often occurs that the previous data is less received. When such a situation occurs, it is found that the time of sending and receiving is very close. After about 2us after sending the data, the opposite end will send data.
See Figure 3 and Figure 4


What is the reason for this phenomenon and how should EDMA be configured?
BR
Ethan