/*********************************************************************************************** 功能:初始化DMA模块 形参:DMA_InitStruct: 初始化结构 返回:0 详解:0 ************************************************************************************************/ void DMA_Init(DMA_InitTypeDef *DMA_InitStruct) { //参数检查 assert_param(IS_DMA_REQ(DMA_InitStruct->PeripheralDMAReq)); assert_param(IS_DMA_ATTR_SSIZE(DMA_InitStruct->SourceDataSize)); assert_param(IS_DMA_ATTR_DSIZE(DMA_InitStruct->DestDataSize)); assert_param(IS_DMA_CH(DMA_InitStruct->Channelx)); assert_param(IS_DMA_MINOR_LOOP(DMA_InitStruct->MinorLoopLength)); //打开DMA0和DMAMUX时钟源 SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK; SIM->SCGC7 |= SIM_SCGC7_DMA_MASK; //配置DMA触发源 DMAMUX->CHCFG[DMA_InitStruct->Channelx] = DMAMUX_CHCFG_SOURCE(DMA_InitStruct->PeripheralDMAReq); //设置源地址信息 DMA0->TCD[DMA_InitStruct->Channelx].SADDR = DMA_InitStruct->SourceBaseAddr; //执行完源地址操作后,是否在源地址基础上累加 DMA0->TCD[DMA_InitStruct->Channelx].SOFF = DMA_SOFF_SOFF(DMA_InitStruct->SourceMinorInc); //设置源地址传输宽度 DMA0->TCD[DMA_InitStruct->Channelx].ATTR = 0; DMA0->TCD[DMA_InitStruct->Channelx].ATTR |= DMA_ATTR_SSIZE(DMA_InitStruct->SourceDataSize); //主循环进行完后 是否更改源地址 DMA0->TCD[DMA_InitStruct->Channelx].SLAST = DMA_InitStruct->SourceMajorInc; //设置目的地址信息 DMA0->TCD[DMA_InitStruct->Channelx].DADDR = DMA_InitStruct->DestBaseAddr; //执行完源地址操作后,是否在源地址基础上累加 DMA0->TCD[DMA_InitStruct->Channelx].DOFF = DMA_DOFF_DOFF(DMA_InitStruct->DestMinorInc); //设置目的地址传输宽度 DMA0->TCD[DMA_InitStruct->Channelx].ATTR |= DMA_ATTR_DSIZE(DMA_InitStruct->DestDataSize); //主循环进行完后 是否更改源地址 DMA0->TCD[DMA_InitStruct->Channelx].DLAST_SGA = DMA_InitStruct->DestMajorInc; //设置计数器长度 循环次数 //设置数据长度 长度每次递减 也被称作当前主循环计数 current major loop count DMA0->TCD[DMA_InitStruct->Channelx].CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(DMA_InitStruct->MinorLoopLength ); //起始循环计数器 当主循环计数器为0 时候 将装载起始循环计数器的值 DMA0->TCD[DMA_InitStruct->Channelx].BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(DMA_InitStruct->MinorLoopLength); //设置每一次传输字节的个数 个数到达上限时 DMA便将数据存入RAM DMA0->TCD[DMA_InitStruct->Channelx].NBYTES_MLNO = DMA_NBYTES_MLNO_NBYTES(DMA_InitStruct->TransferBytes); //设置DMA TCD控制寄存器 DMA0->TCD[DMA_InitStruct->Channelx].CSR = 0; if(DMA_InitStruct->DMAAutoClose == ENABLE) { DMA0->TCD[DMA_InitStruct->Channelx].CSR |=DMA_CSR_DREQ_MASK; } else { DMA0->TCD[DMA_InitStruct->Channelx].CSR &=(~DMA_CSR_DREQ_MASK); } //使能此寄存器DMA开始工作 DMA_SetEnableReq(DMA_InitStruct->Channelx,DMA_InitStruct->EnableState); //DMA 通道使能 DMAMUX->CHCFG[DMA_InitStruct->Channelx] |= DMAMUX_CHCFG_ENBL_MASK; }
/** * @brief 初始化DMA模块 * @param DMA_InitStruct :DMA初始化配置结构体,详见dma.h * @retval 分配到的DMA 通道 */ uint32_t DMA_Init(DMA_InitTypeDef *DMA_InitStruct) { uint8_t chl; /* enable DMA and DMAMUX clock */ #if defined(DMAMUX0) SIM->SCGC6 |= SIM_SCGC6_DMAMUX0_MASK; #endif #if defined(DMAMUX1) SIM->SCGC6 |= SIM_SCGC6_DMAMUX1_MASK; #endif #if defined(DMAMUX) SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK; #endif SIM->SCGC7 |= SIM_SCGC7_DMA_MASK; chl = DMA_InitStruct->chl; /* disable chl first */ DMA0->ERQ &= ~(1<<(chl)); /* dma chl source config */ DMAMUX_InstanceTable[0]->CHCFG[chl] = DMAMUX_CHCFG_SOURCE(DMA_InitStruct->chlTriggerSource); /* trigger mode */ switch(DMA_InitStruct->triggerSourceMode) { case kDMA_TriggerSource_Normal: DMAMUX_InstanceTable[0]->CHCFG[chl] &= ~DMAMUX_CHCFG_TRIG_MASK; break; case kDMA_TriggerSource_Periodic: DMAMUX_InstanceTable[0]->CHCFG[chl] |= DMAMUX_CHCFG_TRIG_MASK; break; default: break; } /* clear some register */ DMA0->TCD[chl].ATTR = 0; DMA0->TCD[chl].CSR = 0; /* minor loop cnt */ DMA0->TCD[chl].NBYTES_MLNO = DMA_NBYTES_MLNO_NBYTES(DMA_InitStruct->minorLoopByteCnt); /* major loop cnt */ DMA0->TCD[chl].CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(DMA_InitStruct->majorLoopCnt); DMA0->TCD[chl].BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(DMA_InitStruct->majorLoopCnt); /* source config */ DMA0->TCD[chl].SADDR = DMA_InitStruct->sAddr; DMA0->TCD[chl].SOFF = DMA_InitStruct->sAddrOffset; DMA0->TCD[chl].ATTR |= DMA_ATTR_SSIZE(DMA_InitStruct->sDataWidth); DMA0->TCD[chl].ATTR |= DMA_ATTR_SMOD(DMA_InitStruct->sMod); DMA0->TCD[chl].SLAST = DMA_SLAST_SLAST(DMA_InitStruct->sLastAddrAdj); /* destation config */ DMA0->TCD[chl].DADDR = DMA_InitStruct->dAddr; DMA0->TCD[chl].DOFF = DMA_InitStruct->dAddrOffset; DMA0->TCD[chl].ATTR |= DMA_ATTR_DSIZE(DMA_InitStruct->dDataWidth); DMA0->TCD[chl].ATTR |= DMA_ATTR_DMOD(DMA_InitStruct->dMod); DMA0->TCD[chl].DLAST_SGA = DMA_DLAST_SGA_DLASTSGA(DMA_InitStruct->dLastAddrAdj); /* auto close enable(disable req on major loop complete)*/ DMA0->TCD[chl].CSR |= DMA_CSR_DREQ_MASK; /* enable DMAMUX */ DMAMUX_InstanceTable[0]->CHCFG[chl] |= DMAMUX_CHCFG_ENBL_MASK; return chl; }