void Configure_DMA_For_Playback(uint16_t * source, uint32_t count, uint32_t num_playbacks) {

/*
	SIM->SCGC7 |= SIM_SCGC7_DMA_MASK;
	SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK;
*/
	
	// Disable DMA channel, allows changes
	DMAMUX0->CHCFG[0] = 0;

	Reload_DMA_Source = source;
	Reload_DMA_Byte_Count = count*2;
	DMA_Playback_Count = num_playbacks;
	
	// Generate DMA interrupt when done
	// Increment source, transfer words (16 bits)
	// Enable peripheral request
	DMA0->DMA[0].DCR = DMA_DCR_EINT_MASK | DMA_DCR_SINC_MASK | 
											DMA_DCR_SSIZE(2) | DMA_DCR_DSIZE(2) |
											DMA_DCR_ERQ_MASK | DMA_DCR_CS_MASK;

	
	// Configure NVIC for DMA ISR
	NVIC_SetPriority(DMA0_IRQn, 128); // 0, 64, 128 or 192
	NVIC_ClearPendingIRQ(DMA0_IRQn); 
	NVIC_EnableIRQ(DMA0_IRQn);	

	// Enable DMA MUX channel without periodic triggering
	// select TPM0 overflow as trigger
	DMAMUX0->CHCFG[0] = DMAMUX_CHCFG_SOURCE(54);   
}
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
/*!
      \fn static u32 u32fnDMA_MUXInit(u32 u32Channel, u32 u32Source)
      \brief  Initializes the DMA MUX with the desired source
      \param  u32Channel: DMA channel to be configured
      \param  u32Source: Trigger source
      \return OK if configurations was successful, ERROR otherwise
*/
static u32 u32fnDMA_MUXInit(u32 u32Channel, u32 u32Source)
{
	u32 u32Status = ERROR;
	/* Make sure the trigger selected is in range */
	if(DMA_TRIGGER_UNSUPPORT_TRIGGER > u32Source)
	{
		
		DMAMUX0_CHCFG(u32Channel) = DMAMUX_CHCFG_ENBL_MASK|DMAMUX_CHCFG_SOURCE(u32Source); 
		u32Status = OK;
	}

	return(u32Status);
}
Esempio n. 4
0
/**
 * @brief  初始化DMA模块
 * @param  DMA_InitStruct :DMA初始化配置结构体,详见dma.h
 * @retval None
 */
void DMA_Init(DMA_Init_t *Init)
{
	/* enable DMA and DMAMUX clock */
	SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK;    
	SIM->SCGC7 |= SIM_SCGC7_DMA_MASK;
    
    /* disable chl first */
    DMA0->DMA[Init->chl].DSR_BCR |= DMA_DSR_BCR_DONE_MASK;
    DMA0->DMA[Init->chl].DCR &= ~DMA_DCR_ERQ_MASK;
    
    /* dma chl source config */
    DMAMUX0->CHCFG[Init->chl] = DMAMUX_CHCFG_SOURCE(Init->chlTrigSrc);
    
    /* trigger mode */
    switch(Init->trigSrcMod)
    {
        case kDMA_TrigSrc_Normal:
            DMAMUX0->CHCFG[Init->chl] &= ~DMAMUX_CHCFG_TRIG_MASK;
            break;
        case kDMA_TrigSrc_Periodic:
            DMAMUX0->CHCFG[Init->chl] |= DMAMUX_CHCFG_TRIG_MASK;
            break;
        default:
            break;
    }
    DMA0->DMA[Init->chl].DCR = 0;
    /* transfer bytes cnt */
    DMA0->DMA[Init->chl].DSR_BCR = DMA_DSR_BCR_BCR(Init->transCnt);
    /* source config */
    DMA0->DMA[Init->chl].SAR  = Init->sAddr;
    DMA0->DMA[Init->chl].DCR |= DMA_DCR_SSIZE(Init->sDataWidth);
    (Init->sAddrIsInc)?(DMA0->DMA[Init->chl].DCR |= DMA_DCR_SINC_MASK):(DMA0->DMA[Init->chl].DCR &= ~DMA_DCR_SINC_MASK);
    DMA0->DMA[Init->chl].DCR |= DMA_DCR_SMOD(Init->sMod);
    /* dest config */
    DMA0->DMA[Init->chl].DAR  = Init->dAddr;
    DMA0->DMA[Init->chl].DCR |= DMA_DCR_DSIZE(Init->sDataWidth);
    (Init->dAddrIsInc)?(DMA0->DMA[Init->chl].DCR |= DMA_DCR_DINC_MASK):(DMA0->DMA[Init->chl].DCR &= ~DMA_DCR_DINC_MASK);
    DMA0->DMA[Init->chl].DCR |= DMA_DCR_DMOD(Init->dMod);
    /* defaut: cycle steal */
    DMA0->DMA[Init->chl].DCR |= DMA_DCR_CS_MASK;
    /* defaut: enable auto disable req */
    DMA0->DMA[Init->chl].DCR |= DMA_DCR_D_REQ_MASK;
    /* enable chl */
    DMAMUX0->CHCFG[Init->chl] |= DMAMUX_CHCFG_ENBL_MASK;
}
Esempio n. 5
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;
}
void Start_DMA_Playback() {
	
#if 0 // old demo code
	if (DMA_Playback_Count == 0)
		return;
#endif
	
	DMAMUX0->CHCFG[0] = DMAMUX_CHCFG_SOURCE(54);   

	// initialize source and destination pointers
	DMA0->DMA[0].SAR = DMA_SAR_SAR((uint32_t) Reload_DMA_Source);
	DMA0->DMA[0].DAR = DMA_DAR_DAR((uint32_t) (&(DAC0->DAT[0])));
	
	// byte count
	DMA0->DMA[0].DSR_BCR = DMA_DSR_BCR_BCR(Reload_DMA_Byte_Count);
	
	// verify done flag is cleared
	DMA0->DMA[0].DSR_BCR &= ~DMA_DSR_BCR_DONE_MASK; 
	
	DMAMUX0->CHCFG[0] |= DMAMUX_CHCFG_ENBL_MASK;

	// start the timer running
	TPM0_Start();
}
Esempio n. 7
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;
}
/*!
 *  @brief      DMA初始化,读取端口数据到内存
 *  @param      DMA_CHn         通道号(DMA_CH0 ~ DMA_CH15)
 *  @param      SADDR           源地址( (void * )&PTx_Bn_IN 或 (void * )&PTx_Wn_IN   )
 *  @param      DADDR           目的地址
 *  @param      PTxn            触发端口
 *  @param      DMA_BYTEn       每次DMA传输字节数
 *  @param      count           一个主循环传输字节数
 *  @param      cfg             DMA传输配置,从DMA_cfg里选择
 *  @since      v5.0
 *  @note       DMA PTXn触发源默认上升沿触发传输,若需修改,则初始化后调用 port_init 配置DMA 触发方式
                初始化后,需要调用 DMA_EN 来实现
 *  Sample usage:   uint8 buff[10];
                    dma_portx2buff_init(DMA_CH0, PTB_B0_IN, buff, PTA7, DMA_BYTE1, 10, DADDR_RECOVER);
                    //DMA初始化,源地址:PTB_B0_IN,目的地址:buff,PTA7触发(默认上升沿),每次传输1字节,共传输 10次 ,传输结束后恢复地址

                    port_init(PTA7,ALT1 | DMA_FALLING);             //默认触发源是上升沿,此处改为 下降沿触发

                    DMA_EN(DMA_CH0);                //需要使能 DMA 后才能传输数据
 */
void dma_portx2buff_init(DMA_CHn CHn, void *SADDR, void *DADDR, PTXn_e ptxn, DMA_BYTEn byten, uint32 count)
{
    uint8 BYTEs = (byten == DMA_BYTE1 ? 1 : (byten == DMA_BYTE2 ? 2 : (byten == DMA_BYTE4 ? 4 : 0 ) ) ); //计算传输字节数    uint8 ptx0;

    //断言,检测传递进来参数是否正确
    ASSERT(                                             //用断言检测 源地址和每次传输字节数是否正确
        (   (byten == DMA_BYTE1)                    //传输一个字节
            && ( (SADDR >= &PTA_B0_IN) && (SADDR <= ( &PTE_B3_IN )))
        )

        || (   (byten == DMA_BYTE2)                   //传输两个字节(注意,不能跨端口)
               && ( (SADDR >= &PTA_B0_IN)
                    && (SADDR <= ( &PTE_W1_IN ))
                    && (((uint32)SADDR & 0x03) != 0x03) )         //保证不跨端口
           )

        || (   (byten == DMA_BYTE4)                   //传输四个字节
               && ((SADDR >= &PTA_B0_IN) && (SADDR <= ( &PTE_B0_IN )))
               && (((uint32)SADDR & 0x03) == 0x00)           //保证不跨端口
           )
    );

    ASSERT(count < 0x8000); //断言,最大只支持0x7FFF

    //DMA 寄存器 配置

    /* 开启时钟 */
    SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;                        //打开DMA模块时钟

#if (defined(MK60DZ10)|| defined(MKL26Z4))
    SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK;                     //打开DMA多路复用器时钟
#elif defined(MK60F15)
    SIM_SCGC6 |= SIM_SCGC6_DMAMUX0_MASK;                    //打开DMA多路复用器时钟
#endif

    DMAMUX0_CHCFG(CHn)=0x00;
    DMA_DSR_BCR(CHn)|=DMA_DSR_BCR_DONE_MASK;

    /* 配置 DMA 通道 的 传输控制块 TCD ( Transfer Control Descriptor ) */
    DMA_SAR(CHn) =    (uint32)SADDR;                      // 设置  源地址
    DMA_DAR(CHn) =    (uint32)DADDR;                      // 设置目的地址
    DMA_DCR(CHn) =    (0
                       | DMA_DCR_SSIZE(byten)
                       | DMA_DCR_DSIZE(byten)
                       //| DMA_DCR_SINC_MASK                  //传输后源地址增加(根据位宽)
                       | DMA_DCR_DINC_MASK                  //传输后目的地址增加(根据位宽)
                       | DMA_DCR_CS_MASK                  // 0为不停得传输,直到BCR为0;1为一次请求传输一次
                       //| DMA_DCR_START_MASK               //软件触发传输
                       | DMA_DCR_ERQ_MASK                   //硬件触发传输(与上面START二选一)
                       | DMA_DCR_D_REQ_MASK                 //传输完成后硬件自动清ERQ

                       );
    DMA_DSR_BCR(CHn) =   (0
                     | DMA_DSR_BCR_BCR(count)              //传输数目
                     );


    /* 配置 DMA 触发源 */
#if defined(MK60DZ10)
    DMAMUX_CHCFG_REG(DMAMUX_BASE_PTR, CHn) = (0
#elif (defined(MK60F15) || defined(MKL26Z4))
    DMAMUX_CHCFG_REG(DMAMUX0_BASE_PTR, CHn) = (0
#endif
            | DMAMUX_CHCFG_ENBL_MASK                        /* Enable routing of DMA request */
            //| DMAMUX_CHCFG_TRIG_MASK                        /* Trigger Mode: Periodic   PIT周期触发传输模式   通道1对应PIT1,必须使能PIT1,且配置相应的PIT定时触发 */
            | DMAMUX_CHCFG_SOURCE( PTX(ptxn) + DMA_PORTA) /* 通道触发传输源:     */
                                             );

    //配置触发源(默认是 上升沿触发)
    port_init(ptxn, ALT1 | DMA_RISING);

    /*  配置输入源   */
    dma_gpio_input_init(SADDR,BYTEs);

    DMA_DIS(CHn);                                    //使能通道CHn 硬件请求
    //DMA_IRQ_CLEAN(CHn);

    /* 开启中断 */
    //DMA_EN(CHn);                                    //使能通道CHn 硬件请求
    //DMA_IRQ_EN(CHn);                                //允许DMA通道传输
}
Esempio n. 9
0
//======================================================================
//函数名称:DMA_Init()
//函数功能:初始化1个DMA模块
//输    入:DMA_Struct_TypeDef      *DMA_Struct         需要初始化的DMA结构体地址
//输    出:无
//返    回: 0          :       成功
//          -1          :       失败
//          -2          :       传输字节数超出范围(<0x0FFFFF)
//======================================================================
int DMA_Init(DMA_Struct_TypeDef *DMA_Struct)
{
    if ((*DMA_Struct).DMA_BytesCount > 0x0FFFFF)
        return (-2);

    const DMAMUX_x_TypeDef DMAMUX_x = DMAMUX_x_GET((*DMA_Struct).DMAMUX_Source);

    switch (DMAMUX_x)
    {
    case DMAMUX0:
        SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK;
        break;
    default:
        return (-1);
    }

    SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;

    DMAMUX_CHCFG_REG(DMAMUXx[DMAMUX_x], (*DMA_Struct).DMA_CHn) = 0;
    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) = 0;
    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_DMOD_MASK;

    const DMAMUX_SRC_TypeDef DMAMUX_SRC = DMAMUX_SRC_GET((*DMA_Struct).DMAMUX_Source);

    if (DMAMUX_SRC == DMA_SoftTrig)
    {
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_ERQ_MASK;
    }
    else
    {
        DMAMUX_CHCFG_REG(DMAMUXx[DMAMUX_x], (*DMA_Struct).DMA_CHn) |= DMAMUX_CHCFG_SOURCE(DMAMUX_SRC);

        if ((*DMA_Struct).DMAMUX_Trig == DMA_Periodic)
            DMAMUX_CHCFG_REG(DMAMUXx[DMAMUX_x], (*DMA_Struct).DMA_CHn) |= DMAMUX_CHCFG_TRIG_MASK;
        else
            DMAMUX_CHCFG_REG(DMAMUXx[DMAMUX_x], (*DMA_Struct).DMA_CHn) &= ~DMAMUX_CHCFG_TRIG_MASK;
    }

    //Source
    DMA_SAR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) =
        DMA_SAR_SAR((*DMA_Struct).DMA_Source.DMA_Addr);

    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_SSIZE_MASK;
    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_SSIZE((*DMA_Struct).DMA_Source.Data_Size);

    if ((*DMA_Struct).DMA_Source.Addr_INC == DMA_ADDR_INC)
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_SINC_MASK;
    else
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_SINC_MASK;

    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_SMOD_MASK;
    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_SMOD((*DMA_Struct).DMA_Source.Addr_MOD);

    //Destination
    DMA_DAR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) =
        DMA_SAR_SAR((*DMA_Struct).DMA_Destination.DMA_Addr);

    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_DSIZE_MASK;
    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_DSIZE((*DMA_Struct).DMA_Destination.Data_Size);

    if ((*DMA_Struct).DMA_Destination.Addr_INC == DMA_ADDR_INC)
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_DINC_MASK;
    else
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_DINC_MASK;

    DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_DMOD((*DMA_Struct).DMA_Destination.Addr_MOD);

    DMA_DSR_BCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DSR_BCR_BCR_MASK;
    DMA_DSR_BCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DSR_BCR_BCR((*DMA_Struct).DMA_BytesCount);

    if ((*DMA_Struct).DMA_CycleSteal == DMA_CycleSteal)
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) &= ~DMA_DCR_CS_MASK;
    else
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_CS_MASK;

    if (DMAMUX_SRC == DMA_SoftTrig)
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_START_MASK;
    else
        DMA_DCR_REG(DMAx[0], (*DMA_Struct).DMA_CHn) |= DMA_DCR_ERQ_MASK;

    //DMAMUX_CHCFG_REG(DMAMUXx[DMAMUX_x], (*DMA_Struct).DMA_CHx) |= DMAMUX_CHCFG_ENBL_MASK;

    return (0);
}
Esempio n. 10
0
void DMA1_Init(void)
{
	APP_TRACE("start 4.1\n\r");
  /* SIM_SCGC7: DMA=1 */
  SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;                                   
  /* SIM_SCGC6: DMAMUX=1 */
  SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK;                                   
  /* DMAMUX0_CHCFG0: ENBL=0,TRIG=0,SOURCE=0 */
  DMAMUX0_CHCFG0 = DMAMUX_CHCFG_SOURCE(0x00);                                   
  /* DMAMUX0_CHCFG1: ENBL=0,TRIG=0,SOURCE=0 */
  DMAMUX0_CHCFG1 = DMAMUX_CHCFG_SOURCE(0x00);                                   
  /* DMAMUX0_CHCFG2: ENBL=0,TRIG=0,SOURCE=0 */
  DMAMUX0_CHCFG2 = DMAMUX_CHCFG_SOURCE(0x00);                                   
  /* DMAMUX0_CHCFG3: ENBL=0,TRIG=0,SOURCE=0 */
  DMAMUX0_CHCFG3 = DMAMUX_CHCFG_SOURCE(0x00);                                   
  /* DMA_DSR_BCR0: DONE=1 */
  DMA_DSR_BCR0 |= DMA_DSR_BCR_DONE_MASK;                                   
  /* DMA_DSR_BCR1: DONE=1 */
  DMA_DSR_BCR1 |= DMA_DSR_BCR_DONE_MASK;                                   
  /* DMA_DSR_BCR2: DONE=1 */
  DMA_DSR_BCR2 |= DMA_DSR_BCR_DONE_MASK;                                   
  /* DMA_SAR0 = (uint32_t)&ADC0_RA */
  DMA_SAR0 = (uint32_t)((uint32_t)&ADC0_RA);
  /* DMA_SAR1 = 0 */
  DMA_SAR1 = (uint32_t)(0);
  /* DMA_SAR2 = 0 */
  DMA_SAR2 = (uint32_t)(0);
  /* DMA_DAR1 = &ADC0_CFG2 */
  DMA_DAR1 = (uint32_t)(&ADC0_CFG2);
  /* DMA_DAR2 = &ADC0_SC1A */
  DMA_DAR2 = (uint32_t)(&ADC0_SC1A);
  /* DMA_DSR_BCR0: ??=0,CE=0,BES=0,BED=0,??=0,REQ=0,BSY=0,DONE=0,BCR=0x10 */
  DMA_DSR_BCR0 = DMA_DSR_BCR_BCR(0x10);                                   
  /* DMA_DSR_BCR1: ??=0,CE=0,BES=0,BED=0,??=0,REQ=0,BSY=0,DONE=0,BCR=8 */
  DMA_DSR_BCR1 = DMA_DSR_BCR_BCR(0x08);                                   
  /* DMA_DSR_BCR2: ??=0,CE=0,BES=0,BED=0,??=0,REQ=0,BSY=0,DONE=0,BCR=8 */
  DMA_DSR_BCR2 = DMA_DSR_BCR_BCR(0x08);                                   
  	APP_TRACE("start 4.2\n\r");
	/* DMA_DCR0: EINT=1,ERQ=1,CS=1,AA=0,??=0,??=0,??=0,??=0,EADREQ=1,SINC=0,SSIZE=2,DINC=1,DSIZE=2,START=0,SMOD=0,DMOD=0,D_REQ=0,??=0,LINKCC=2,LCH1=1,LCH2=0 */
  DMA_DCR0 = DMA_DCR_EINT_MASK |
             DMA_DCR_ERQ_MASK |
             DMA_DCR_CS_MASK |
             DMA_DCR_EADREQ_MASK |
             DMA_DCR_SSIZE(0x02) |
             DMA_DCR_DINC_MASK |
             DMA_DCR_DSIZE(0x02) |
             DMA_DCR_SMOD(0x00) |
             DMA_DCR_DMOD(0x00) |
             DMA_DCR_LINKCC(0x02) |
             DMA_DCR_LCH1(0x01) |
             DMA_DCR_LCH2(0x00);       
  /* DMA_DCR1: EINT=0,ERQ=1,CS=1,AA=0,??=0,??=0,??=0,??=0,EADREQ=1,SINC=1,SSIZE=1,DINC=0,DSIZE=1,START=0,SMOD=0,DMOD=0,D_REQ=1,??=0,LINKCC=2,LCH1=2,LCH2=0 */
  DMA_DCR1 = DMA_DCR_ERQ_MASK |
             DMA_DCR_CS_MASK |
             DMA_DCR_EADREQ_MASK |
             DMA_DCR_SINC_MASK |
             DMA_DCR_SSIZE(0x01) |
             DMA_DCR_DSIZE(0x01) |
             DMA_DCR_SMOD(0x00) |
             DMA_DCR_DMOD(0x00) |
             DMA_DCR_D_REQ_MASK |
             DMA_DCR_LINKCC(0x02) |
             DMA_DCR_LCH1(0x02) |
             DMA_DCR_LCH2(0x00);       
  /* DMA_DCR2: EINT=0,ERQ=1,CS=1,AA=0,??=0,??=0,??=0,??=0,EADREQ=1,SINC=1,SSIZE=1,DINC=0,DSIZE=1,START=0,SMOD=0,DMOD=0,D_REQ=1,??=0,LINKCC=0,LCH1=0,LCH2=0 */
  	APP_TRACE("start 4.3\n\r");
	DMA_DCR2 = DMA_DCR_ERQ_MASK |
             DMA_DCR_CS_MASK |
             DMA_DCR_EADREQ_MASK |
             DMA_DCR_SINC_MASK |
             DMA_DCR_SSIZE(0x01) |
             DMA_DCR_DSIZE(0x01) |
             DMA_DCR_SMOD(0x00) |
             DMA_DCR_DMOD(0x00) |
             DMA_DCR_D_REQ_MASK |
             DMA_DCR_LINKCC(0x00) |
             DMA_DCR_LCH1(0x00) |
             DMA_DCR_LCH2(0x00);       
  /* DMAMUX0_CHCFG0: ENBL=1,TRIG=0,SOURCE=0x28 */
  DMAMUX0_CHCFG0 = (DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(0x28));                                   
  /* DMAMUX0_CHCFG1: ENBL=1,TRIG=0,SOURCE=0 */
  DMAMUX0_CHCFG1 = (DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(0x00));                                   
  /* DMAMUX0_CHCFG2: ENBL=1,SOURCE=0 */
	APP_TRACE("start 4.4\n\r"); 
 DMAMUX0_CHCFG2 = (uint8_t)((DMAMUX0_CHCFG2 & (uint8_t)~(uint8_t)(
                    DMAMUX_CHCFG_SOURCE(0x3F)
                   )) | (uint8_t)(
                    DMAMUX_CHCFG_ENBL_MASK
                   ));    
									  
				_int_install_isr(LDD_ivIndex_INT_DMA0, adc0_isr, NULL);
				enable_irq(0) ;   // ready for this interrupt. 
//		set_irq_priority(0, 2);
APP_TRACE("start 4.5\n\r");									 
}
void spi1_dma_master_spi0_slave(void)
{
	SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK; //DMAMUX Clock Gate Control: 1, clock enable---
	SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;   //DMA Clock Gate control: 1, clock enable----
	 
	m_tdata8[0] = 0xF0;
	m_tdata8[1] = 0x11;
	m_tdata8[2] = 0x22;
	m_tdata8[3] = 0x33;
	m_tdata8[4] = 0x44;
	m_tdata8[5] = 0x66;
	m_tdata8[6] = 0x77;
	m_tdata8[7] = 0x88;
	for (k=0; k<8; k++)
		m_rdata8[k] = 0;
                
    s_tdata8[0] = 0x01;   
	s_tdata8[1] = 0x23;
	s_tdata8[2] = 0x45;
	s_tdata8[3] = 0x67;
	s_tdata8[4] = 0x89;
	s_tdata8[5] = 0xAB;
	s_tdata8[6] = 0xCD;
	s_tdata8[7] = 0xEF;
	for (k=0; k<8; k++)
		s_rdata8[k] = 0;

#ifdef CMSIS
	disable_irq(DMA0_IRQn);    //DMA channel 0 transfer complete and error interrupt
	disable_irq(DMA1_IRQn);    //DMA channel 1 transfer complete and error	interrupt
	disable_irq(DMA2_IRQn);    //DMA channel 2 transfer complete and error	interrupt
	disable_irq(DMA3_IRQn);    //DMA channel 3 transfer complete and error	interrupt
#else
	disable_irq(0);    //DMA channel 0 transfer complete and error interrupt
	disable_irq(1);    //DMA channel 1 transfer complete and error	interrupt
	disable_irq(2);    //DMA channel 2 transfer complete and error	interrupt
	disable_irq(3);    //DMA channel 3 transfer complete and error	interrupt
#endif
	
    SIM_CLKDIV1 = ( 0
                   | SIM_CLKDIV1_OUTDIV1(0x1)
                   | SIM_CLKDIV1_OUTDIV4(0) );
	// disable DMA channel
	DMAMUX0_CHCFG0 = 0;
	DMAMUX0_CHCFG1 = 0;
	DMAMUX0_CHCFG2 = 0;
	DMAMUX0_CHCFG3 = 0;
    //
	//SPI0 receive dma source number is 16; SPI0 transmint dma source number is 17
	//*****channel 0--->TX, channel 1----->RX************
	DMAMUX0_CHCFG0 |= DMAMUX_CHCFG_ENBL_MASK & (~DMAMUX_CHCFG_TRIG_MASK);
	DMAMUX0_CHCFG0 |= DMAMUX_CHCFG_SOURCE(17); //TX---DMA channel 0-SPI0 source number--ENBL=1--TRIG=0---
	 
	DMAMUX0_CHCFG1 |= DMAMUX_CHCFG_ENBL_MASK & (~DMAMUX_CHCFG_TRIG_MASK);
	DMAMUX0_CHCFG1 |= DMAMUX_CHCFG_SOURCE(16); //RX---DMA channel 1-SPI0 source number--ENBL=1--TRIG=0---
         
    //*****channel 2--->TX, channel 3----->RX************
	DMAMUX0_CHCFG2 |= DMAMUX_CHCFG_ENBL_MASK & (~DMAMUX_CHCFG_TRIG_MASK);
	DMAMUX0_CHCFG2 |= DMAMUX_CHCFG_SOURCE(19); //TX---DMA channel 2-SPI1 source number--ENBL=1--TRIG=0---
	 
	DMAMUX0_CHCFG3 |= DMAMUX_CHCFG_ENBL_MASK & (~DMAMUX_CHCFG_TRIG_MASK);
	DMAMUX0_CHCFG3 |= DMAMUX_CHCFG_SOURCE(18); //RX---DMA channel 3-SPI1 source number--ENBL=1--TRIG=0---
	//************channel request number ???????*****************
	 

	DMA_SAR0 = (uint32_t)(&(s_tdata8));
	DMA_DAR0 = (uint32_t)(&(SPI0_D));

	DMA_DSR_BCR0 |= DMA_DSR_BCR_BCR(8);    //BCR contains the number of bytes yet to be transferred for a given block
	DMA_DCR0 = DMA_DCR_ERQ_MASK|DMA_DCR_EINT_MASK|DMA_DCR_D_REQ_MASK|DMA_DCR_CS_MASK
	 		   |DMA_DCR_DSIZE(1)|DMA_DCR_SSIZE(1)|DMA_DCR_SINC_MASK;			  //|DMA_DCR_CS_MASK

	DMA_SAR1 = (uint32_t)(&(SPI0_D));
	DMA_DAR1 = (uint32_t)(&(s_rdata8));
 
	DMA_DSR_BCR1 |= DMA_DSR_BCR_BCR(8);			//BCR contains the number of bytes yet to be transferred for a given block
	DMA_DCR1 = DMA_DCR_ERQ_MASK|DMA_DCR_EINT_MASK|DMA_DCR_D_REQ_MASK|DMA_DCR_CS_MASK
	 		   |DMA_DCR_DSIZE(1)|DMA_DCR_SSIZE(1)|DMA_DCR_DINC_MASK;			  //|DMA_DCR_CS_MASK
         
    DMA_SAR2 = (uint32_t)(&(m_tdata8));			   //----tx-----
	DMA_DAR2 = (uint32_t)(&(SPI1_D));
 
	DMA_DSR_BCR2 |= DMA_DSR_BCR_BCR(8);    //BCR contains the number of bytes yet to be transferred for a given block
	DMA_DCR2 = DMA_DCR_ERQ_MASK|DMA_DCR_EINT_MASK|DMA_DCR_D_REQ_MASK|DMA_DCR_CS_MASK
	 		   |DMA_DCR_DSIZE(1)|DMA_DCR_SSIZE(1)|DMA_DCR_SINC_MASK;			  //|DMA_DCR_CS_MASK

	DMA_SAR3 = (uint32_t)(&(SPI1_D));			  //----rx-----
	DMA_DAR3 = (uint32_t)(&(m_rdata8));

	DMA_DSR_BCR3 |= DMA_DSR_BCR_BCR(8);			//BCR contains the number of bytes yet to be transferred for a given block
	DMA_DCR3 = DMA_DCR_ERQ_MASK|DMA_DCR_EINT_MASK|DMA_DCR_D_REQ_MASK|DMA_DCR_CS_MASK
	 		   |DMA_DCR_DSIZE(1)|DMA_DCR_SSIZE(1)|DMA_DCR_DINC_MASK;			  //|DMA_DCR_CS_MASK
				 
#ifdef CMSIS
	enable_irq(DMA0_IRQn);
	enable_irq(DMA1_IRQn);
	enable_irq(DMA2_IRQn);
	enable_irq(DMA3_IRQn);
#else
	enable_irq(0);
	enable_irq(1);
	enable_irq(2);
	enable_irq(3);
#endif
	
	dma_int_cnt = 0;			//this variable is used to indicates the count of transmission interrupt
	extend_cnt = 0;
	m_DMA0_IntFlag = 0;
	m_DMA1_IntFlag = 0;
	m_DMA2_IntFlag = 0;
	m_DMA3_IntFlag = 0;

	printf("Initializing SPI module!\n\r");
	spi_init();
               
	while(!m_DMA0_IntFlag);

    while(!m_DMA3_IntFlag);

             
    for(k=0; k<8 ; k++)
    {
        if(s_tdata8[k] != m_rdata8[k])
        {  
            printf("k = 0x%01x\n\r",k); 
            printf("m_tdata8 = 0x%02x\n\r",m_rdata8[k]); 
            printf("s_rdata8 = 0x%02x\n\r",s_tdata8[k]); 
     //       error_count++;
            printf("Transmit failure!\n\r");
        }
        else
        {
            printf("m_tdata8 = 0x%02x\n\r",m_rdata8[k]); 
            printf("s_rdata8 = 0x%02x\n\r",s_tdata8[k]); 
            printf("Transmit successful!\n\r");
        }
    
    }

}