📄 dd_edma.c
字号:
#include "typedefine.h"
#include "dd_edma.h"
//#include "dd_core.h"
//#include "audio_adpcm_decoder.h"
#include "interrupt_manage.h"
//#include "mp4_vars.h"
#pragma DATA_SECTION(s_nEdmaChLink,".qbss");
#pragma DATA_ALIGN(s_nEdmaChLink,8);
static uint8 s_nEdmaChLink[64];
#pragma DATA_SECTION(s_nEdmaRamLink,".qbss");
#pragma DATA_ALIGN(s_nEdmaRamLink,8);
static uint8 s_nEdmaRamLink[MAX_EDMA_PARAM_RAM_ENTRY];
#pragma DATA_SECTION(s_nFreeEdmaChHead,".qbss");
static uint8 s_nFreeEdmaChHead;
#pragma DATA_SECTION(s_nFreeEdmaRamHead,".qbss");
static uint8 s_nFreeEdmaRamHead;
#pragma DATA_SECTION(s_nCompleteFlagTmp,".qbss");
#pragma DATA_ALIGN(s_nCompleteFlagTmp,4);
static uint8 s_nCompleteFlagTmp[4];
#pragma DATA_SECTION(s_pEdmaIsrTab,".qbss");
#pragma DATA_ALIGN(s_pEdmaIsrTab,4);
ISR_FUNC s_pEdmaIsrTab[64];
void InitEdma()
{
int i;
uint32 *pUint;
// *** EDMA初始化 ***
// IRQ_globalDisable_user(); //kang12.19
pUint = (uint32*)EDMA_REG_BASE;
// EDMA priority queue allocation registers
pUint[EDMA_PQAR0] = 6;
pUint[EDMA_PQAR1] = 12;
pUint[EDMA_PQAR2] = 12;
pUint[EDMA_PQAR3] = 12;
// EDMA event enable registers
pUint[EDMA_EERL] = 0;
pUint[EDMA_EERH] = 0;
// EDMA channel interrupt enable registers
pUint[EDMA_CIERL] = 0; //0x0000a000;
pUint[EDMA_CIERH] = 0;
// EDMA channel chain enable registers
pUint[EDMA_CCERL] = 0; //0xfdf00e60;
pUint[EDMA_CCERH] = 0; //0x000e0000;
// EDMA event clear registers
pUint[EDMA_ECRL] = 0xffffffff;
pUint[EDMA_ECRH] = 0xffffffff;
// EDMA channel interrupt pending registers
pUint[EDMA_CIPRL] = 0xffffffff;
pUint[EDMA_CIPRH] = 0xffffffff;
// EDMA event enable registers
pUint[EDMA_EERL] = 0; //0xfdf7af70;
pUint[EDMA_EERH] = 0; //0x3f0f0e00;
//
IRQ_map_user(8, 8); // 必须先将特定的event map 给某 channel 后,下面的函数才能起作用
IRQ_clear_user(8); //
IRQ_nmiEnable_user(); //kang 12.19 使能EDMA中断
IRQ_enable_user(8); //
//IRQ_globalEnable_user();
/**/
for(i=0;i<63;i++)
s_nEdmaChLink[i] = i+1;
s_nEdmaChLink[63] = 0xff;
s_nFreeEdmaChHead = 0;
for(i=0;i<MAX_EDMA_PARAM_RAM_ENTRY-1;i++)
s_nEdmaRamLink[i] = i+1;
s_nEdmaRamLink[MAX_EDMA_PARAM_RAM_ENTRY-1] = 0xff;
s_nFreeEdmaRamHead = 0;
for(i=0;i<64;i++)
{
s_pEdmaIsrTab[i] = (ISR_FUNC)NULL;
}
}
HANDLE AllocEdma(int nEdmaNum)//分配通道号
{
HANDLE hFirst,hRet;
uint32 *pUint;
pUint = (uint32*)EDMA_REG_BASE;
if(nEdmaNum <= 0)
return INVALID_EDMA_HANDLE;
hFirst = s_nFreeEdmaChHead;
nEdmaNum--;
while(hFirst != 0xff && nEdmaNum != 0)
{
hFirst = s_nEdmaChLink[hFirst];
nEdmaNum--;
}
if(hFirst != 0xff && nEdmaNum == 0)
{
hRet = s_nFreeEdmaChHead;
s_nFreeEdmaChHead = s_nEdmaChLink[hFirst];
s_nEdmaChLink[hFirst] = 0xff;
hFirst = hRet;
while(hFirst != 0xff)
{
if(hFirst<32)
{
pUint[EDMA_EERL] |= (1<<hFirst);
pUint[EDMA_ECRL] |= (1<<hFirst);
if(hFirst != hRet)
pUint[EDMA_CCERL] |= (1<<hFirst);
}
else
{
pUint[EDMA_EERH] |= (1<<(hFirst-32));
pUint[EDMA_ECRH] |= (1<<(hFirst-32));
if(hFirst != hRet)
pUint[EDMA_CCERH] |= (1<<(hFirst-32));
}
hFirst = s_nEdmaChLink[hFirst];
}
return hRet;
}
else
{
return INVALID_EDMA_HANDLE;
}
}
HANDLE AllocEdmaParamEntry(int nEdmaNum)
{
HANDLE hFirst,hRet;
if(nEdmaNum <= 0)
return INVALID_EDMA_HANDLE;
hFirst = s_nFreeEdmaRamHead;
nEdmaNum--;
while(hFirst != 0xff && nEdmaNum != 0)
{
hFirst = s_nEdmaRamLink[hFirst];
nEdmaNum--;
}
if(hFirst != 0xff && nEdmaNum == 0)
{
hRet = s_nFreeEdmaRamHead+64;
s_nFreeEdmaRamHead = s_nEdmaRamLink[hFirst];
s_nEdmaRamLink[hFirst] = 0xff;
return hRet;
}
else
{
return INVALID_EDMA_HANDLE;
}
}
void AllocSpecifiedEdma(HANDLE hEdma)
{
HANDLE hFirst;
uint32 *pUint;
uint8 tmp;
pUint = (uint32*)EDMA_REG_BASE;
if(hEdma < 0 || hEdma > 63)
return;
hFirst = s_nFreeEdmaChHead;
if(hFirst != 0xff && hFirst != hEdma)
{
while(s_nEdmaChLink[hFirst] != 0xff)
{
if(s_nEdmaChLink[hFirst] != hEdma)
{
hFirst = s_nEdmaChLink[hFirst];
}
else
{
tmp = s_nEdmaChLink[hFirst];
s_nEdmaChLink[hFirst] = s_nEdmaChLink[s_nEdmaChLink[hFirst]];
s_nEdmaChLink[tmp] = 0xff;
if((hEdma<32)&&(hEdma>=8))
{
pUint[EDMA_EERL] |= (1<<hEdma);
pUint[EDMA_ECRL] |= (1<<hEdma);
}
else
{
pUint[EDMA_EERH] |= (1<<(hEdma-32));
pUint[EDMA_ECRH] |= (1<<(hEdma-32));
}
break;
}
}
}
else if(hFirst == hEdma)
{
s_nFreeEdmaChHead = s_nEdmaChLink[s_nFreeEdmaChHead];
s_nEdmaChLink[hFirst] = 0xff;
if((hEdma<32)&&(hEdma>=8))
{
pUint[EDMA_EERL] |= (1<<hEdma);
pUint[EDMA_ECRL] |= (1<<hEdma);
}
else
{
pUint[EDMA_EERH] |= (1<<(hEdma-32));
pUint[EDMA_ECRH] |= (1<<(hEdma-32));
}
}
}
void ReleaseEdma(HANDLE hEdma)
{
HANDLE hFirst;
uint32 *pUint;
pUint = (uint32*)EDMA_REG_BASE;
if(hEdma < 0 || hEdma > 63+MAX_EDMA_PARAM_RAM_ENTRY)
return;
if(hEdma < 64)
{
hFirst = hEdma;
while(hFirst != 0xff)
{
if(hFirst < 32)
{
pUint[EDMA_EERL] &= ~(1<<hFirst);
pUint[EDMA_CCERL] &= ~(1<<hFirst);
pUint[EDMA_ECRL] |= (1<<hFirst);
}
else
{
pUint[EDMA_EERH] &= ~(1<<(hFirst-32));
pUint[EDMA_CCERH] &= ~(1<<(hFirst-32));
pUint[EDMA_ECRH] |= (1<<(hFirst-32));
}
hFirst = s_nEdmaChLink[hFirst];
}
hFirst = hEdma;
while(s_nEdmaChLink[hFirst] != 0xff)
{
hFirst = s_nEdmaChLink[hFirst];
}
s_nEdmaChLink[hFirst] = s_nFreeEdmaChHead;
s_nFreeEdmaChHead = hEdma;
}
else
{
hEdma = hEdma-64;
hFirst = hEdma;
while(s_nEdmaRamLink[hFirst] != 0xff)
{
hFirst = s_nEdmaRamLink[hFirst];
}
s_nEdmaRamLink[hFirst] = s_nFreeEdmaRamHead;
s_nFreeEdmaRamHead = hEdma;
}
}
HANDLE FindNextEdma(HANDLE hEdma)
{
if(hEdma < 0 || hEdma > 63+MAX_EDMA_PARAM_RAM_ENTRY)
return (HANDLE)INVALID_EDMA_HANDLE;
else if(hEdma < 64)
return (HANDLE)s_nEdmaChLink[hEdma];
else
return (HANDLE)s_nEdmaRamLink[hEdma-64];
}
void SetEdmaCompleteFlag(HANDLE hEdma)
{
SetEdma(hEdma,
(uint32)EMDA_OPT_PRI_URGENT|
EDMA_OPT_ESIZE_8|
EDMA_OPT_2DS_NO|
EDMA_OPT_SUM_INC|
EDMA_OPT_2DD_NO|
EDMA_OPT_DUM_INC|
EDMA_OPT_LINK_NO|
EDMA_OPT_FS_YES|
EDMA_OPT_TCC(hEdma),
(uint32)&s_nCompleteFlagTmp[0],
(uint32)2,
(uint32)&s_nCompleteFlagTmp[2],
(uint32)0,
(uint32)0);
StartEdma(hEdma);
WaitEdma(hEdma);
}
void HookEdmaIsr(HANDLE hEdma,ISR_FUNC pIsr)
{
uint32 *pUint;
pUint = (uint32*)EDMA_REG_BASE;
if(hEdma < 0 || hEdma > 63)
{
return;
}
else
{
////// DisableGie();
IRQ_globalDisable_user();
s_pEdmaIsrTab[hEdma] = pIsr;
if(hEdma < 32)
{
pUint[EDMA_CIERL] |= 1<<hEdma;
pUint[EDMA_CIPRL] |= 1<<hEdma;
}
else
{
pUint[EDMA_CIERH] |= 1<<(hEdma-32);
pUint[EDMA_CIPRH] |= 1<<(hEdma-32);
}
// EnableGie();
// IRQ_globalEnable_user();
}
}
void UnhookEdmaIsr(HANDLE hEdma)
{
uint32 *pUint;
pUint = (uint32*)EDMA_REG_BASE;
if(hEdma < 0 || hEdma > 63)
{
return;
}
else
{
// DisableGie();
s_pEdmaIsrTab[hEdma] = NULL;
if(hEdma < 32)
{
pUint[EDMA_CIERL] &= ~(1<<hEdma);
// pUint[EDMA_CIPRL] |= 1<<hEdma;
}
else
{
pUint[EDMA_CIERH] &= ~(1<<(hEdma-32));
// pUint[EDMA_CIPRH] |= 1<<(hEdma-32);
}
// EnableGie();
}
}
interrupt void EdmaIsr(void)
{
uint32 nIERL,nIERH,nIFRL,nIFRH;
uint32 *pUint;
uint32 nChNum;
pUint = (uint32*)EDMA_REG_BASE;
nIERL = pUint[EDMA_CIERL];
nIFRL = pUint[EDMA_CIPRL];
nIFRL = nIFRL & nIERL;
while(nIFRL)
{
nChNum = 31-_lmbd(1,nIFRL);
nIFRL &= ~(1<<nChNum);
pUint[EDMA_CIPRL] = 1<<nChNum;
(*s_pEdmaIsrTab[nChNum])();
}
nIERH = pUint[EDMA_CIERH];
nIFRH = pUint[EDMA_CIPRH];
nIFRH = nIFRH & nIERH;
while(nIFRH)
{
nChNum = 31-_lmbd(1,nIFRH);
nIFRH &= ~(1<<nChNum);
pUint[EDMA_CIPRH] = 1<<nChNum;
(*s_pEdmaIsrTab[nChNum+32])();
}
}
ISR_FUNC audio_isr()
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -