Пример #1
0
/***********************************************************************************************
 功能:初始化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;
}
Пример #2
0
/**
 * @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;
}