C6748對EDMA的操作和通過EMIFA與FPGA傳輸資料(二)
阿新 • • 發佈:2018-11-10
/****************************************************************************/
/* */
/* 主函式 */
/* */
/****************************************************************************/
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的偏移量的大小。