Esempio n. 1
0
/***********************************************************************************************
 功能:设置DMA MINOR LOOP LENGTH
 形参:DMAChl: DMA0_CH0 - DMA_CH15
			 DataNumber: 循环长度
 返回:0
 详解:0
************************************************************************************************/
void DMA_SetCurrDataCounter(uint8_t DMAChl,uint16_t DataNumber)
{
	//检测参数
	assert_param(IS_DMA_CH(DMAChl));
	assert_param(IS_DMA_MINOR_LOOP(DataNumber));
	
	DMA0->TCD[DMAChl].CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(DataNumber);
}
Esempio n. 2
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;
}
Esempio n. 3
0
void DmaChannelInit(int channel, void *source_ptr, void *dest_ptr, int size, int source,
                    int source_inc, int dest_inc) {
  // Configure mux.
  // Disable channel and clear everything.
  DMAMUX_CHCFG(channel) = 0x00;
  
  // Select source.
  DMAMUX_CHCFG(channel) |= DMAMUX_CHCFG_SOURCE(source);
  
  // Configure channel.
  // Set up source and dest addresses.
  DMA_SADDR(channel) = (int)source_ptr;
  DMA_DADDR(channel) = (int)dest_ptr;

  // Set soruce and dest address increment.
  DMA_SOFF(channel) = source_inc;
  DMA_DOFF(channel) = dest_inc;

  // Set size of transfer 0x00 = 1 byte.
  DMA_ATTR(channel) = DMA_ATTR_SSIZE(0) | DMA_ATTR_DSIZE(0);
  // Set bytes per minor loop.
  DMA_NBYTES_MLNO(channel) = 0x01;
  
  // Set number of minor loops.
  DMA_CITER_ELINKNO(channel) = DMA_CITER_ELINKNO_CITER(size);
  DMA_BITER_ELINKNO(channel) = DMA_BITER_ELINKNO_BITER(size);

  // Adjustment applied after major loop finishes
  DMA_SLAST(channel) = -(size * source_inc);  // Source address adjustment.
  DMA_DLAST_SGA(channel) = -(size * dest_inc);  // Destination address adjustment.
  
  // Set to disable on completion.
  DMA_CSR(0) |= DMA_CSR_DREQ_MASK;
  
  // Enable DMA request for channel.
  DMA_ERQ |= (1 << channel);
  
  // Enable mux.
  DMAMUX_CHCFG(channel) |= DMAMUX_CHCFG_ENBL_MASK;
}
Esempio n. 4
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;
}
Esempio n. 5
0
/**
 * @brief  设置 DMA MajorLoopCount 计数值
 * @param  chl: DMA通道号
 *         @arg HW_DMA_CH0
 *         @arg HW_DMA_CH1
 *         @arg HW_DMA_CH2
 *         @arg HW_DMA_CH3
 * @retval None
 * @note   数值不能超过 DMA_CITER_ELINKNO_CITER_MASK
 */
void DMA_SetMajorLoopCounter(uint8_t chl, uint32_t val)
{
    DMA0->TCD[chl].CITER_ELINKNO &= ~DMA_CITER_ELINKNO_CITER_MASK;
    DMA0->TCD[chl].CITER_ELINKNO |= DMA_CITER_ELINKNO_CITER(val);
}