1. 程式人生 > >C6748對EDMA的操作和通過EMIFA與FPGA傳輸資料(二)

C6748對EDMA的操作和通過EMIFA與FPGA傳輸資料(二)

/****************************************************************************/
/*                                                                          */
/*              主函式                                                      */
/*                                                                          */
/****************************************************************************/ 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, &paramSet); 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, &paramSet); 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, &paramSet); } return retVal; }

通道0連結到通道65,通道65連結到通道64,通道64連結到通道65,後面這兩個就可以進行乒乓的操作,地址分別是0x80004000、0x80010000。
解釋一下為什麼link的0x0820u表示通道65,0x800表示通道64。
這裡寫圖片描述

通道0的位置為0x01c04000,通道1的位置為0x01c04020,以此類推,即可得出通道64和65的偏移量的大小。