DSP

C6748对EDMA的操作和通过EMIFA与FPGA传输数据(二)

2019-07-13 11:09发布

/****************************************************************************/ /* */ /* 主函数 */ /* */ /****************************************************************************/ int main(void) { volatile unsigned int status = FALSE; int i;unsigned short adc_en; g_bSPingPong = 0; q=0; str[0]=0; str1[0]=0; /*初始化ADC使能*/ adc_en = 0x3001; //48kHz // 外设使能配置 PSCInit(); // GPIO 管脚复用配置 GPIOBankPinMuxSet(); // GPIO 管脚初始化 GPIOBankPinInit(); // DSP 中断初始化 InterruptInit(); // GPIO 管脚中断初始化 GPIOBankPinInterruptInit(); // EMIFA 初始化 HJBSP_OMAPL138_EMIFA_Init(); for (i = 0; i < EMIF_INIT; i++) { paraint[i] = 0x0001; } for (i = 0; i < EMIF_INIT; i++) { fraint[i] = 0x0000; } for (i = 0; i < EMIF_INIT; i++) { wegint[i] = 0x0001; }//波束形成参数配置 EDMA3Init(SOC_EDMA30CC_0_REGS, evtQ); EDMA3InterruptInit(); for (i = 0; i < EMIF_INIT; i++) { ((short *)SOC_EMIFA_CS2_ADDR)[i+0x0000] = paraint[i] ; } for (i = 0; i < EMIF_INIT; i++) { ((short *)SOC_EMIFA_CS2_ADDR)[i+0x0020] = fraint[i] ; } for (i = 0; i < EMIF_INIT; i++) { ((short *)SOC_EMIFA_CS2_ADDR)[i+0x0040] = wegint[i] ; } for (i = 0; i < EMIF_INIT; i++) { ((short *)SOC_EMIFA_CS2_ADDR)[i+0x0060] = 0x0000 ; } ((short *)SOC_EMIFA_CS2_ADDR)[0x0011] = 0x0000;//dac enable fashe ,DSP产生的数字信号,给FPGA,FPGA转化成模拟信号 ((short *)SOC_EMIFA_CS2_ADDR)[0x0088] = 0x0000;//adc enable jieshou #ifdef CHTYPE_DMA status = EDMA3Test(); #else status = QDMA3Test(); #endif /*向FPGA写ADC_EN*/ ((short *)SOC_EMIFA_CS2_ADDR)[0x0088] = adc_en;//,外部来的模拟信号,模拟转数字,给到FPGA,让F while(1); { }//dsp空跑,有中断才会打断它,完成中断后再回来 } #ifdef CHTYPE_DMA /****************************************************************************/ /* */ /* EDMA3 测试 */ /* */ /****************************************************************************/ unsigned int EDMA3Test() { volatile unsigned int index = 0; volatile unsigned int count = 0; EDMA3CCPaRAMEntry paramSet; unsigned int retVal = 0u; unsigned int acnt = MAX_ACOUNT; unsigned int bcnt = MAX_BCOUNT; dst0Buff = (char *)_dst0Buff; dst1Buff = (char *)_dst1Buff; // 申请 DMA 通道和 TCC retVal = EDMA3RequestChannel(SOC_EDMA30CC_0_REGS, chType, chNum, tccNum, evtQ); // 注册回调函数 cb_Fxn[tccNum] = &callback; if (TRUE == retVal) { paramSet.srcAddr = SOC_EMIFA_CS2_ADDR + 0x1200;//FPGA的数据的第一个通道存放地址 paramSet.destAddr = 0x80004000; paramSet.aCnt = (unsigned short)256*2; paramSet.bCnt = (unsigned short)12*8; paramSet.cCnt = (unsigned short)1; paramSet.srcBIdx = (short)0; paramSet.destBIdx = (short)256*2; if (syncType == EDMA3_SYNC_A) { // A Sync 传输模式 paramSet.srcCIdx = (short)0; paramSet.destCIdx = (short)0; } else { // AB Sync 传输模式 paramSet.srcCIdx = ((short)acnt * (short)bcnt); paramSet.destCIdx = ((short)acnt * (short)bcnt); } paramSet.linkAddr = (unsigned short)0x0820u; paramSet.bCntReload = (unsigned short)12*8u; paramSet.opt = 0u; // Src 及 Dest 使用 INCR 模式 paramSet.opt &= 0xFFFFFFFCu; // 编程 TCC paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC); paramSet.opt &= 0xFF1FFFFF; paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT); if (syncType == EDMA3_SYNC_A) { paramSet.opt &= 0xFFFFFFFBu; } else { // AB Sync 传输模式 paramSet.opt |= (1 << EDMA3CC_OPT_SYNCDIM_SHIFT); } // 写参数 RAM EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, chNum, ¶mSet); paramSet.srcAddr = SOC_EMIFA_CS2_ADDR + 0x1200; paramSet.destAddr = 0x80004000; paramSet.aCnt = (unsigned short)256*2; paramSet.bCnt = (unsigned short)12*8; paramSet.cCnt = (unsigned short)1; paramSet.srcBIdx = (short)0; paramSet.destBIdx = (short)256*2; if (syncType == EDMA3_SYNC_A) { // A Sync 传输模式 paramSet.srcCIdx = (short)0; paramSet.destCIdx = (short)0; } else { // AB Sync 传输模式 paramSet.srcCIdx = ((short)acnt * (short)bcnt); paramSet.destCIdx = ((short)acnt * (short)bcnt); } paramSet.linkAddr = (unsigned short)0x0820u; // paramSet.linkAddr = (unsigned short)0xFFFF; paramSet.bCntReload = (unsigned short)12*8u; paramSet.opt = 0u; // Src 及 Dest 使用 INCR 模式 paramSet.opt &= 0xFFFFFFFCu; // 编程 TCC paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC); paramSet.opt &= 0xFF1FFFFF; paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT); if (syncType == EDMA3_SYNC_A) { paramSet.opt &= 0xFFFFFFFBu; } else { // AB Sync 传输模式 paramSet.opt |= (1 << EDMA3CC_OPT_SYNCDIM_SHIFT); } // 写参数 RAM EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, 64, ¶mSet); paramSet.srcAddr = SOC_EMIFA_CS2_ADDR + 0x1200; // paramSet.destAddr = (unsigned int)(dst1Buff); paramSet.destAddr = 0x80010000; paramSet.aCnt = (unsigned short)256*2; paramSet.bCnt = (unsigned short)12*8; paramSet.cCnt = (unsigned short)1; paramSet.srcBIdx = (short)0; paramSet.destBIdx = (short)256*2; if (syncType == EDMA3_SYNC_A) { // A Sync 传输模式 paramSet.srcCIdx = (short)0; paramSet.destCIdx = (short)0; } else { // AB Sync 传输模式 paramSet.srcCIdx = ((short)acnt * (short)bcnt); paramSet.destCIdx = ((short)acnt * (short)bcnt); } paramSet.linkAddr = (unsigned short)0x0800u; paramSet.bCntReload = (unsigned short)12*8u; paramSet.opt = 0u; // Src 及 Dest 使用 INCR 模式 paramSet.opt &= 0xFFFFFFFCu; // 编程 TCC paramSet.opt |= ((tccNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC); // 使能 Intermediate & Final 传输完成中断 // paramSet.opt |= (1 << EDMA3CC_OPT_ITCINTEN_SHIFT); // paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT); paramSet.opt &= 0xFF1FFFFF; paramSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT); if (syncType == EDMA3_SYNC_A) { paramSet.opt &= 0xFFFFFFFBu; } else { // AB Sync 传输模式 paramSet.opt |= (1 << EDMA3CC_OPT_SYNCDIM_SHIFT); } // 写参数 RAM EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, 65, ¶mSet); } return retVal; } 通道0链接到通道65,通道65链接到通道64,通道64链接到通道65,后面这两个就可以进行乒乓的操作,地址分别是0x80004000、0x80010000。
解释一下为什么link的0x0820u表示通道65,0x800表示通道64。
这里写图片描述 通道0的位置为0x01c04000,通道1的位置为0x01c04020,以此类推,即可得出通道64和65的偏移量的大小。