如下是DMA初始化配置的参考代码,配置了串口DMA接收和串口DMA发送:
//DMA单元
#define RX_DMA_UNIT (CM_DMA1)
//DMA通道号·通道号越小优先级越高
#define RX_DMA_CH (DMA_CH0)
//DMA单元时钟
#define RX_DMA_FCG_ENABLE() (FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_DMA1, ENABLE))
//AOS系统的目标·触发DMA1通道0传输
#define RX_DMA_TRIG_SEL (AOS_DMA1_0)
//AOS系统的触发源·接收数据寄存器满中断
#define RX_DMA_TRIG_EVT_SRC (EVT_SRC_USART1_RI)
//AOS系统的目标·DMA完成中断
#define RX_DMA_RECONF_TRIG_SEL (AOS_DMA_RC)
//AOS系统的触发源·AOS_STRG中断源
#define RX_DMA_RECONF_TRIG_EVT_SRC (EVT_SRC_AOS_STRG)
//DMA传输完成中断·通道号1
#define RX_DMA_TC_INT (DMA_INT_TC_CH0)
//DMA传输完成标志·通道号2
#define RX_DMA_TC_FLAG (DMA_FLAG_TC_CH0)
//DMA传输完成中断号
#define RX_DMA_TC_IRQn (INT000_IRQn)
//DMA传输完成中断源
#define RX_DMA_TC_INT_SRC (INT_SRC_DMA1_TC0)
//串口DMA发送配置
#define TX_DMA_UNIT (CM_DMA2)
#define TX_DMA_CH (DMA_CH0)
#define TX_DMA_FCG_ENABLE() (FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_DMA2, ENABLE))
#define TX_DMA_TRIG_SEL (AOS_DMA2_0)
#define TX_DMA_TRIG_EVT_SRC (EVT_SRC_USART1_TI)
#define TX_DMA_TC_INT (DMA_INT_TC_CH0)
#define TX_DMA_TC_FLAG (DMA_FLAG_TC_CH0)
#define TX_DMA_TC_IRQn (INT001_IRQn)
#define TX_DMA_TC_INT_SRC (INT_SRC_DMA2_TC0)
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
static __IO en_flag_status_t m_enTxEnd = SET;
static uint8_t m_4gRxBuf[RX_FRAME_LEN_MAX];
static uint8_t *m_auTxBuf = NULL;
/*******************************************************************************
* Local function definitions ('static')
******************************************************************************/
static void RX_DMA_TC_IrqCallback(void);
static void TX_DMA_TC_IrqCallback(void);
/*
* DMA_Config()
* 配置串口DMA接收和DMA发送
*/
static int32_t DMA_Config(void)
{
int32_t i32Ret;
stc_dma_init_t stcDmaInit;
stc_dma_llp_init_t stcDmaLlpInit;
stc_irq_signin_config_t stcIrqSignConfig;
static stc_dma_llp_descriptor_t stcLlpDesc;
//使能DMA和FCG时钟
RX_DMA_FCG_ENABLE();
TX_DMA_FCG_ENABLE();
FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
/* USART_RX_DMA */
(void)DMA_StructInit(&stcDmaInit);
stcDmaInit.u32IntEn = DMA_INT_ENABLE;//DMA interrupt enable
stcDmaInit.u32BlockSize = 1UL;//DMA block size
stcDmaInit.u32TransCount = ARRAY_SZ(m_4gRxBuf);//DMAbuf大小
stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT;//DMAbuf位宽
stcDmaInit.u32DestAddr = (uint32_t)m_4gRxBuf;//DMAbuf地址
stcDmaInit.u32SrcAddr = (uint32_t)(&USART_UNIT->RDR);//由外设到内存的 外设地址 -> 串口数据寄存器
stcDmaInit.u32SrcAddrInc = DMA_SRC_ADDR_FIX;//由外设到内存的 源地址模式 固定
stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_INC;//由外设到内存的 目标地址模式 自动递增
i32Ret = DMA_Init(RX_DMA_UNIT, RX_DMA_CH, &stcDmaInit);
if (LL_OK == i32Ret)
{
(void)DMA_LlpStructInit(&stcDmaLlpInit);
stcDmaLlpInit.u32State = DMA_LLP_ENABLE;
stcDmaLlpInit.u32Mode = DMA_LLP_WAIT;
stcDmaLlpInit.u32Addr = (uint32_t)&stcLlpDesc;
(void)DMA_LlpInit(RX_DMA_UNIT, RX_DMA_CH, &stcDmaLlpInit);//初始化DMA链表指针
stcLlpDesc.SARx = stcDmaInit.u32SrcAddr;
stcLlpDesc.DARx = stcDmaInit.u32DestAddr;
stcLlpDesc.DTCTLx = (stcDmaInit.u32TransCount << DMA_DTCTL_CNT_POS) | (stcDmaInit.u32BlockSize << DMA_DTCTL_BLKSIZE_POS);;
stcLlpDesc.LLPx = (uint32_t)&stcLlpDesc;
stcLlpDesc.CHCTLx = stcDmaInit.u32SrcAddrInc | stcDmaInit.u32DestAddrInc | stcDmaInit.u32DataWidth | \
stcDmaInit.u32IntEn | stcDmaLlpInit.u32State | stcDmaLlpInit.u32Mode;
DMA_ReconfigLlpCmd(RX_DMA_UNIT, RX_DMA_CH, ENABLE);
DMA_ReconfigCmd(RX_DMA_UNIT, ENABLE);
AOS_SetTriggerEventSrc(RX_DMA_RECONF_TRIG_SEL, RX_DMA_RECONF_TRIG_EVT_SRC);
stcIrqSignConfig.enIntSrc = RX_DMA_TC_INT_SRC;
stcIrqSignConfig.enIRQn = RX_DMA_TC_IRQn;
stcIrqSignConfig.pfnCallback = &RX_DMA_TC_IrqCallback;
(void)INTC_IrqSignIn(&stcIrqSignConfig);
NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);
AOS_SetTriggerEventSrc(RX_DMA_TRIG_SEL, RX_DMA_TRIG_EVT_SRC);
DMA_Cmd(RX_DMA_UNIT, ENABLE);
DMA_TransCompleteIntCmd(RX_DMA_UNIT, RX_DMA_TC_INT, ENABLE);
(void)DMA_ChCmd(RX_DMA_UNIT, RX_DMA_CH, ENABLE);
}
(void)DMA_StructInit(&stcDmaInit);
stcDmaInit.u32IntEn = DMA_INT_ENABLE;
stcDmaInit.u32BlockSize = 1UL;
stcDmaInit.u32TransCount = ARRAY_SZ(m_4gRxBuf);
stcDmaInit.u32DataWidth = DMA_DATAWIDTH_8BIT;
stcDmaInit.u32DestAddr = (uint32_t)(&USART_UNIT->TDR);
stcDmaInit.u32SrcAddr = (uint32_t)m_4gRxBuf;
stcDmaInit.u32SrcAddrInc = DMA_SRC_ADDR_INC;
stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_FIX;
i32Ret = DMA_Init(TX_DMA_UNIT, TX_DMA_CH, &stcDmaInit);
if (LL_OK == i32Ret)
{
stcIrqSignConfig.enIntSrc = TX_DMA_TC_INT_SRC;
stcIrqSignConfig.enIRQn = TX_DMA_TC_IRQn;
stcIrqSignConfig.pfnCallback = &TX_DMA_TC_IrqCallback;
(void)INTC_IrqSignIn(&stcIrqSignConfig);
NVIC_ClearPendingIRQ(stcIrqSignConfig.enIRQn);
NVIC_SetPriority(stcIrqSignConfig.enIRQn, DDL_IRQ_PRIO_DEFAULT);
NVIC_EnableIRQ(stcIrqSignConfig.enIRQn);
AOS_SetTriggerEventSrc(TX_DMA_TRIG_SEL, TX_DMA_TRIG_EVT_SRC);
DMA_Cmd(TX_DMA_UNIT, ENABLE);
DMA_TransCompleteIntCmd(TX_DMA_UNIT, TX_DMA_TC_INT, ENABLE);
}
return i32Ret;
}
|