AM1808 的UART1、UART2 在使用DMA进行收发的时候,需要配置哪些寄存器?
Shine:
可以参考一下AM1808 starterware里的UART+EDMA例程。
software-dl.ti.com/…/index_FDS.html
processors.wiki.ti.com/…/StarterWare_01.00.01.01_User_Guide
yiguang ge:
回复 Shine:
我用了AM1808_StarterWare_1_00_03_03例程的程序写出来,数据发送不出来 UartTransmitData设置完PaRam后,EDMA3的中断没有
Shine:
回复 yiguang ge:
例程能运行吗?修改了什么地方?
yiguang ge:
回复 Shine:
例程没有开发环境,只修改了发送接收的字节数,另外初始化的配置方法从原来Main函数移动到我现在的程序中变更代码如下
/* Callback Function Declaration*/
static void (*cb_Fxn[EDMA3_NUM_TCC]) (unsigned int tcc, unsigned int status);static void ConfigureAINTCIntEDMA3(void);
static void EDMA3Initialize(void);
static void UartTransmitData(unsigned int tccNum, unsigned int chNum,uchar *buffer, unsigned int buffLength);
static void UartReceiveData(unsigned int tccNum, unsigned int chNum,uchar *buffer);
static void callback(unsigned int tccNum, unsigned int status);/****************************************************************************/
/*変数の定義(非公開)*/
/****************************************************************************//**送信バッファ**/
uchar UartDmaSndBuf[ UART_DMA_SIZE ];/* UART DMA 送信バッファ*//**受信バッファ**/
uchar UartDmaRcvBuf[ UART_DMA_SIZE ];/* UART DMA 受信バッファ*//****************************************************************************/
/*GLOBAL VARIABLES*/
/****************************************************************************//** This function configures the AINTC to receive EDMA3 interrupts.
*/
static void ConfigureAINTCIntEDMA3(void)
{
// IntRegister(SYS_INT_CCINT0, Edma3ComplHandlerIsr);
//IntChannelSet(SYS_INT_CCINT0, 2);//port_outl(AINTC_EISR, WT_EISR_11);
//IntSystemEnable(SYS_INT_CCINT0);DrvAintc_Enable( AINTC_NO_EDMA3_0_CC0_INT0 );//IntRegister(SYS_INT_CCERRINT, Edma3CCErrHandlerIsr);
//IntChannelSet(SYS_INT_CCERRINT, 2);//port_outl(AINTC_EISR, WT_EISR_12);
// IntSystemEnable(SYS_INT_CCERRINT);DrvAintc_Enable( AINTC_NO_EDMA3_0_CC0_ERRINT);
DrvAintc_Enable( AINTC_NO_EDMA3_0_TC0_ERRINT);
}/* Function used to Initialize EDMA3 */
static void EDMA3Initialize(void)
{
#if 1/* Enabling the PSC for EDMA3CC_0.*/
//PSCModuleControl(ADDR_PSC_0, 0, 0, PSC_MDCTL_NEXT_ENABLE);
/* Enabling the PSC for EDMA3TC_0.*/
//PSCModuleControl(ADDR_PSC_0, 1, 0, PSC_MDCTL_NEXT_ENABLE);DrvPsc_Set( PSC_MOD_EDMA3_CH0, PSC_STA_ENABLE ); /* @暫定 */DrvPsc_Set( PSC_MOD_EDMA3_TR0, PSC_STA_ENABLE );DrvPsc_Set( PSC_MOD_EDMA3_TR1, PSC_STA_ENABLE );
/* DMA initialization */port_outl(EDMA_QWMTHRA, UART_WT_QWMTHRA);
/* Initialization of EDMA3 */EDMA3Init(EDMA3_BASE,EVT_QUEUE_NUM);/*** Enable AINTC to handle interuppts. Also enable IRQ interuppt in ** ARM processor.*/
//SetupAINTCInt();
/* Register EDMA3 Interrupts */ConfigureAINTCIntEDMA3();
#elseDrvPsc_Set( PSC_MOD_EDMA3_CH0, PSC_STA_ENABLE ); /* @暫定 */DrvPsc_Set( PSC_MOD_EDMA3_TR0, PSC_STA_ENABLE );DrvPsc_Set( PSC_MOD_EDMA3_TR1, PSC_STA_ENABLE );
/* DMA initialization */port_outl(EDMA_QWMTHRA, UART_WT_QWMTHRA);/* DMA channel initialization */port_setl(EDMA_DRAE0, UART_WT_DRAE0);port_setl(EDMA_EESR_SADW0, UART_WT_EESR);port_clrl(EDMA_DMAQNUM0, UART_CR_DMAQNUM0);/* DMA error interrupt initialization */port_outl(EDMA_EMCR, UART_WT_EMCR);port_outl(EDMA_CCERRCLR, UART_WT_CCERRCLR);port_outl(EDMA_ERREN, UART_WT_ERREN);port_outl(EDMA_ERRCLR,UART_WT_ERRCLR);/* Interrupt setup */port_clrl(AINTC_CMR2, CR_CMR2);port_setl(AINTC_CMR2, WT_CMR2);port_clrl(AINTC_CMR3, CR_CMR3);port_setl(AINTC_CMR3, WT_CMR3);
#if 1 /* setup by CpuDrv.c */port_setl(AINTC_HIER, WT_HIER);
#endifport_setl(AINTC_HIEISR, WT_HIEISR);port_setl(AINTC_ESR1, WT_ESR1);
#if 1 /* setup by CpuDrv.c */port_setl(AINTC_GER, WT_GER);
#endifport_outl(AINTC_EISR, WT_EISR_11);port_outl(AINTC_EISR, WT_EISR_12);port_outl(AINTC_EISR, WT_EISR_13);
#endif
}/* EDMA3 Completion Handler */
static void edma3ComplHandler(unsigned int baseAdd, unsigned int regionNum)
{volatile unsigned int pendingIrqs;volatile unsigned int isIPR = 0;
unsigned int indexl;unsigned int Cnt = 0;indexl = 1;DrvAintc_ClrStatus(SYS_INT_CCINT0);isIPR = HWREG(baseAdd + EDMA3CC_S_IPR(regionNum));if(isIPR){while ((Cnt < EDMA3CC_COMPL_HANDLER_RETRY_COUNT)&& (indexl != 0u)){indexl = 0u;pendingIrqs = HWREG(baseAdd + EDMA3CC_S_IPR(regionNum));while (pendingIrqs){if((pendingIrqs & 1u) == TRUE){/*** If the user has not given any callback function* while requesting the TCC, its TCC specific bit* in the IPR register will NOT be cleared.*//* here write to ICR to clear the corresponding IPR bits */
#if 0HWREG(baseAdd + EDMA3CC_S_ICR(regionNum)) = (1u << indexl);
(*cb_Fxn[indexl])(indexl, EDMA3_XFER_COMPLETE);
#elseHWREG(baseAdd + EDMA3CC_S_ICR(regionNum)) = (1u << indexl);//EDMA3ClrIntr(baseAdd, indexl);if(indexl==EDMA3_CHA_UART2_TX)(*cb_Fxn[indexl])(indexl, EDMA3_XFER_COMPLETE);else if(indexl==EDMA3_CHA_UART2_RX)(*cb_Fxn[indexl])(indexl, EDMA3_XFER_COMPLETE);
#endif}++indexl;pendingIrqs >>= 1u;}Cnt++;}}
}void Edma3ComplHandlerIsr(void)
{/* Invoke Completion Handler ISR */edma3ComplHandler(EDMA3_BASE, 0);
}
/* EDMA3 Error Handler */
static void edma3CCErrHandler(unsigned int baseAdd)
{volatile unsigned int pendingIrqs = 0;unsigned int regionNum = 0;unsigned int evtqueNum = 0;unsigned int index = 1;unsigned int Cnt = 0;DrvAintc_ClrStatus(SYS_INT_CCERRINT);
if((HWREG(baseAdd + EDMA3CC_EMR) != 0 ) || \(HWREG(baseAdd + EDMA3CC_QEMR) != 0) || \(HWREG(baseAdd + EDMA3CC_CCERR) != 0)){/* Loop for EDMA3CC_ERR_HANDLER_RETRY_COUNT number of time, breaks when no pending interrupt is found */while ((Cnt < EDMA3CC_ERR_HANDLER_RETRY_COUNT) && (index != 0u)){index = 0u;pendingIrqs = HWREG(baseAdd + EDMA3CC_EMR);while (pendingIrqs){/*Process all the pending interrupts*/if((pendingIrqs & 1u)==TRUE){/* Write to EMCR to clear the corresponding EMR bits.*/HWREG(baseAdd + EDMA3CC_EMCR) = (1u<<index);/*Clear any SER*/HWREG(baseAdd + EDMA3CC_S_SECR(regionNum)) = (1u<<index);}++index;pendingIrqs >>= 1u;}index = 0u;pendingIrqs = HWREG(baseAdd + EDMA3CC_QEMR);while (pendingIrqs){/*Process all the pending interrupts*/if((pendingIrqs & 1u)==TRUE){/* Here write to QEMCR to clear the corresponding QEMR bits*/HWREG(baseAdd + EDMA3CC_QEMCR) = (1u<<index);/*Clear any QSER*/HWREG(baseAdd + EDMA3CC_S_QSECR(0)) = (1u<<index);}++index;pendingIrqs >>= 1u;}index = 0u;pendingIrqs = HWREG(baseAdd + EDMA3CC_CCERR);if (pendingIrqs != 0u){/* Process all the pending CC error interrupts. *//* Queue threshold error for different event queues.*/for (evtqueNum = 0u; evtqueNum < EDMA3_0_NUM_EVTQUE; evtqueNum++){if((pendingIrqs & (1u << evtqueNum)) != 0u){/* Clear the error interrupt. */HWREG(baseAdd + EDMA3CC_CCERRCLR) = (1u << evtqueNum);}}
/* Transfer completion code error. */if ((pendingIrqs & (1 << EDMA3CC_CCERR_TCCERR_SHIFT)) != 0u){HWREG(baseAdd + EDMA3CC_CCERRCLR) = (0x01u << EDMA3CC_CCERR_TCCERR_SHIFT);}++index;}Cnt++;}}
}void Edma3CCErrHandlerIsr()
{/* Invoke CC Error Handler ISR */edma3CCErrHandler(EDMA3_BASE);
}/****************************************************************************/
/* 機能 [:UART 初期化*/
/* 名称 [:void DrvUart_Init( void )*/
/* 引数 [:なし*/
/* 戻値 [:なし*/
/* 概要 [:*/
/****************************************************************************/
void DrvUartDma_Init( void )
{uchar i;/* Initialize EDMA3 Controller */EDMA3Initialize();
/* Initialize UART */DrvUart1Dma_Init();
for(i=0; i<EDMA3_NUM_TCC; i++)cb_Fxn[i]=NULL;/* Request DMA Channel and TCC for UART Transmit*/EDMA3RequestChannel(EDMA3_BASE, EDMA3_CHANNEL_TYPE_DMA, EDMA3_CHA_UART2_TX, EDMA3_CHA_UART2_TX,EVT_QUEUE_NUM);
/* Registering Callback Function for TX*/cb_Fxn[EDMA3_CHA_UART2_TX] = &callback;
/* Request DMA Channel and TCC for UART Receive */EDMA3RequestChannel(EDMA3_BASE, EDMA3_CHANNEL_TYPE_DMA,EDMA3_CHA_UART2_RX, EDMA3_CHA_UART2_RX,EVT_QUEUE_NUM);
/* Registering Callback Function for RX*/cb_Fxn[EDMA3_CHA_UART2_RX] = &callback;
/* Enabling UART in DMA Mode*/UARTDMAEnable(SOC_UART_2_REGS, UART_RX_TRIG_LEVEL_8 |UART_DMAMODE |UART_FIFO_MODE );
/* Free EDMA3 Channels for TX and RX */
//EDMA3FreeChannel(EDMA3_BASE, EDMA3_CHANNEL_TYPE_DMA,
//EDMA3_CHA_UART2_TX, EDMA3_TRIG_MODE_EVENT,
//EDMA3_CHA_UART2_TX, EVT_QUEUE_NUM);//EDMA3FreeChannel(EDMA3_BASE, EDMA3_CHANNEL_TYPE_DMA,
//EDMA3_CHA_UART2_RX, EDMA3_TRIG_MODE_EVENT,
//EDMA3_CHA_UART2_RX, EVT_QUEUE_NUM);
}/*
** This function is used to set the PaRAM entries in EDMA3 for the Transmit Channel
** of UART. EDMA3 Enable Transfer is also called within this API.
*/static void UartTransmitData(unsigned int tccNum, unsigned int chNum,uchar *buffer, unsigned int buffLength)
{EDMA3CCPaRAMEntry paramSet;
/* Fill the PaRAM Set with transfer specific information */paramSet.srcAddr = (unsigned int) buffer;//データソースアドレスparamSet.destAddr = UART2_RBR_THR_REG;//目的地のアドレスparamSet.aCnt = (unsigned short) buffLength;//MAX_ACNT;//;//1次元データの次元paramSet.bCnt = MAX_BCNT;//(unsigned short) buffLength; //2次元データの次元paramSet.cCnt = MAX_CCNT;//3次元データの次元
/* The src index should increment for every byte being transferred. */paramSet.srcBIdx = (short) 0u;//ソースアドレスの2次元インデックス
/* The dst index should not be increment since it is a h/w register*/paramSet.destBIdx = (short) 1u;//目的地の2次元索引/* AB sync Transfer Mode */paramSet.srcCIdx = (short) 0u;//ソースアドレスの3次元インデックスparamSet.destCIdx = (short) 0u;//目的地の3次元索引paramSet.linkAddr = (unsigned short)0xFFFFu;//0x4FE0u;// //LINKモードパラメータの設定paramSet.bCntReload = (unsigned short)0u;//LINKモードパラメータの設定paramSet.opt = 0x00000000u;//通路選択パラメータparamSet.opt |= (EDMA3CC_OPT_DAM );paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
// paramSet.opt |= (EDMA3CC_OPT_SYNCDIM); //AB-synchronized
// paramSet.opt = 0x0011F003u;
/* Now write the PaRAM Set */EDMA3SetPaRAM(EDMA3_BASE, chNum, ¶mSet);
/* Enable EDMA Transfer */EDMA3EnableTransfer(EDMA3_BASE, chNum, EDMA3_TRIG_MODE_EVENT);
}/*
** This function is used to set the PARAM SET of EDMA3 for the Receive Channel
** of UART. EDMA3 Enable Transfer is also called within this API.
*/static void UartReceiveData(unsigned int tccNum, unsigned int chNum,uchar *buffer)
{EDMA3CCPaRAMEntry paramSet;
/* Fill the PaRAM Set with transfer specific information */paramSet.srcAddr = UART2_RBR_THR_REG;paramSet.destAddr = (unsigned int) buffer;paramSet.aCnt = MAX_ACNT;paramSet.bCnt = UART_DMA_SIZE;paramSet.cCnt = MAX_CCNT;
/* The src index should not be increment since it is a h/w register*/paramSet.srcBIdx = 0;/* The dest index should incremented for every byte */paramSet.destBIdx = 1;
/* AB sync Transfer Mode */paramSet.srcCIdx = 0;paramSet.destCIdx = 0;paramSet.linkAddr = (unsigned short)0xFFFFu;//0x4FE0u;//paramSet.bCntReload = 0;paramSet.opt = 0x00000000u;paramSet.opt |= ((EDMA3CC_OPT_SAM) << EDMA3CC_OPT_SAM_SHIFT); paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC);paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT);
// paramSet.opt |= (EDMA3CC_OPT_SYNCDIM); //AB-synchronized
// paramSet.opt = 0x0011E004u;
/* Now write the PaRAM Set */EDMA3SetPaRAM(EDMA3_BASE, chNum, ¶mSet);
/* Enable EDMA Transfer */EDMA3EnableTransfer(EDMA3_BASE, chNum, EDMA3_TRIG_MODE_EVENT);
}void UARTDMAEnable (unsigned int baseAdd, unsigned int flags)
{HWREG(baseAdd + UART_FCR) = (flags & (UART_FIFO_MODE | \UART_DMAMODE | \UART_RX_TRIG_LEVEL));
}void UARTDMADisable (unsigned int baseAdd, unsigned int flags)
{/* Enabling the FIFO mode of operation.*/HWREG(baseAdd + UART_FCR) = (flags & (UART_FIFO_MODE | UART_RX_TRIG_LEVEL));
}/*
** This function is used as a callback from EDMA3 Completion Handler.
** UART in DMA Mode is Disabled over here.
*/
static void callback(unsigned int tccNum, unsigned int status)
{UARTDMADisable(SOC_UART_2_REGS, (UART_RX_TRIG_LEVEL_8 | UART_FIFO_MODE));
}/****************************************************************************/
/* 機能 [:UART DMA 送信*/
/* 名称 [:void UartDmaSend(uchar *SendChar, ulong Length)*/
/* 引数 [:uchar *SendChar 送信データulong Length 送信長さ*/
/* 戻値 [:なし*/
/* 概要 [: 512 byte Send*/
/****************************************************************************/
void UartDmaSend(uchar *SendChar, ulong Length)
{
// DrvMmu_CacheInv();MemSet(UartDmaSndBuf, 0x00, UART_DMA_SIZE);if(Length>=UART_DMA_SIZE){MemCopy(&UartDmaSndBuf[0], SendChar, UART_DMA_SIZE);}else{MemCopy(&UartDmaSndBuf[0], SendChar, Length);}
// UARTDMADisable(SOC_UART_2_REGS, (UART_RX_TRIG_LEVEL_8 | UART_FIFO_MODE));UARTDMAEnable(SOC_UART_2_REGS, UART_RX_TRIG_LEVEL_8 |UART_DMAMODE |UART_FIFO_MODE );UartTransmitData(EDMA3_CHA_UART2_TX, EDMA3_CHA_UART2_TX, &UartDmaSndBuf[0], UART_DMA_SIZE);}
/****************************************************************************/
/* 機能 [:UART DMA 受信*/
/* 名称 [:void UartDmaRcv(void)*/
/* 引数 [:なし*/
/* 戻値 [:なし*/
/* 概要 [: 512 byte Rcv*/
/****************************************************************************/
void UartDmaRcv(void)
{
// DrvMmu_CacheInv();
// UARTDMADisable(SOC_UART_2_REGS, (UART_RX_TRIG_LEVEL_8 | UART_FIFO_MODE));
UARTDMAEnable(SOC_UART_2_REGS, UART_RX_TRIG_LEVEL_8 |UART_DMAMODE |UART_FIFO_MODE );
UartReceiveData(EDMA3_CHA_UART2_RX, EDMA3_CHA_UART2_RX, &UartDmaRcvBuf[0]);
}