如下是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;
- }
|