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); }
/*********************************************************************************************** 功能:初始化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; }
/*! \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); }
/** * @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; }
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(); }
/** * @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通道传输 }
//====================================================================== //函数名称: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); }
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"); } } }