📄 w99av.c
字号:
#pragma DISABLE // will disable all interrupt for the duration of function
// can't use when function return is BIT
BYTE W99AV_ReadDRAMData(DWORD dwAddr, DWORD* pdwData)
{
#ifdef CACHE_RW_ONLY
return _ReadDRAMCache(dwAddr, pdwData, 4);
#else
// LLY.160a-1, using API calling instead of put all procedure while it's necessary
// Then, it can save the code size
// Chuan2.80p, RISC will do this now
//_SwitchCacheToGeneral();
// Step 1 : clear CACK bit of PSR
// Chuan2.80p, move to W99AV_SetCommandEnable()
//W99AV_ClearInterrupt(INT_CACK); // set bit(5)--CACKC in ISR
// Step 2 : set ARG0(31:0)
W99AV_OutIndex(0x10000000); // set AIR(31:0)=0x10000000
W99AV_OutData(0x07000000|COMMAND_RDRAM);
// Step 3 : Set ARG1(31:0)=DRAM starting address
W99AV_OutData(dwAddr);
// TCC026, CMC found that if only read 1 data, sometimes the data will be wrong
// So we read 2 data. But only read 1 from command ram
// OSD size not correct due to this problem
W99AV_OutData (0x0101) ; // INC=1, burst length = 2
//W99AV_OutData (0x0100) ; // INC=1, burst length = 1
// Step 4 : set Command Interrupt bit
W99AV_SetCommandEnable();
// Step 5 : waiting for Command acknowledge
_btRet=_W99AV_WaitACK(INT_CACK); // Chuan 172r 2002/03/13: Use current function _W99AV_WaitACK().
if(_btRet)
{
// Step 6 : read desired from ARG0
W99AV_OutIndex(0x10000000); // set AIR(31:0)=0x10000000
*pdwData=W99AV_InData();
}
else
*pdwData = ERROR_VALUE; // Chuan1.05, different ret value between Debug and Release to avoid infinite loop when No Ack at release mode.
return _btRet;
#endif
}
// ***********************************************************************
// Function : W99AV_OutIFIFO
// Description : Write a DWORD(32 bit) value to IFIFO (IBDPR0)
// The host may send MPEG bitstream to the chip by
// writing bitstream into this register
// IBDPR0 is a 8 bit I/O port
// Total space of IFIFO is 64 BYTE
// Arguments : dwVal:the value to be written (DWORD unit) or
// bVal:the value to be written (BYTE unit)
// Return : none
// Side Effect :
// ***********************************************************************
#pragma NOAREGS // be called in ISR
#pragma DISABLE // will disable all interrupt for the duration of function
// can't use when function return is BIT
#if IO == IO_PCI
void W99AV_OutIFIFO(DWORD dwVal)
{
// Chuan0.81, Use PCI Delay
//_Delay(DELAY);
_outpdw((WORD)IBDPR0,dwVal);
}
#else // #if IO==IO_PCI
void W99AV_OutIFIFO(BYTE bVal)
{
OUTB(IBDPR0,bVal);
}
#endif // #if IO==IO_PCI
#pragma NOAREGS // called in ISR
BYTE _W99AV_WaitACK(WORD wACKType)
{
// Step 4: Waiting for Command acknowledge
_wCnt=0;
_btRet=FALSE;
while(1)
{
if((W99AV_GetPSR() & wACKType))
{ // latch successfully
_btRet=TRUE;
break;
}
if(_wCnt++>ACKLOOP) // polling time out
{
#if defined (SERIAL_DEBUG) || defined(SUPPORT_PRINTF)
printf("\nWait no ACK!");
// Chuan1.05, Show DSP/RISC PC, V-Rem, A-Rem
// Chuan1.10, Don't need divide by 2 from 20031106 RISC code.
// printf("\nDEBR:%lx, V:%lx, A:%lx", W99AV_ReadRegDW(DEBR), (W99AV_ReadRegDW (VBRR) >> 1), W99AV_ReadRegDW (ABRR));
printf(" DEBR:%lx V:%lx A:%lx", W99AV_ReadRegDW(DEBR), W99AV_ReadRegDW (VBRR), W99AV_ReadRegDW (ABRR));
#endif
break;
}
}
return _btRet;
}
// ***********************************************************************************
// Function : _ReadDRAMCache
// Description : Read DRAM data from the specified DRAM address by command
// according burst length
// 1.Clear CACK bit of PSR register
// 2.Write Command_index(15:0)=0x0008 and
// Command_arg(31:16)=0x0700
// 3.Write ARG1(31:0)=DRAM starting address(19:0)
// 4.Set Command Interrupt bit
// 5.Waiting for command acknowledge
// 6.Read ARG0~ARG1 to get desired data
// Arguments : dwAddr:desired DRAM address, dwAddr(19:0) is valid
// pdwData:a desired data to be read, max is 16 DWORD
// bLen:desired burst length, max is 16
// Return : TRUE or FALSE
// Side Effect :
// ***********************************************************************************
#ifdef CACHE_RW_ONLY ///SUPPORT_CACHE_RW //Kevin1.22CACHE
#pragma NOAREGS // be called in ISR
#pragma DISABLE // will disable all interrupt for the duration of function
// can't use when function return is BIT
BYTE _ReadDRAMCache(DWORD dwAddr, DWORD* pdwData, WORD wLen)
{
// Step 1: Specify the desired DRAM address into CBAR[20:0]
W99AV_OutCacheAddr(dwAddr);
// Step 2: Specify the NO# of bytes which will be moved from DRAM to Cache
// into BMSR1 & BMSR0
W99AV_SetCacheRWNo(wLen);
// Step 3: Set Cache R/W mode=011 to assert an block read cache interrupt to RISC
W99AV_SetCacheRWMode(0x33);
_wLeft = 0;
wLen/=4;
while(_wLeft != wLen)
{
// Step 4: Waiting for Command acknowledge
if (!_W99AV_WaitACK(INT_CACK))
{
pdwData[_wLeft] = ERROR_VALUE; // Chuan1.05, different ret value between Debug and Release to avoid infinite loop when No Ack at release mode.
return FALSE;
}
while(1)
{
// Step 5: Read Data from Cache
_bIdx = (BYTE *)&pdwData[_wLeft] ;
#if IO == IO_PCI
*(_bIdx+3) = W99AV_InCacheData();
*(_bIdx+2) = W99AV_InCacheData();
*(_bIdx+1) = W99AV_InCacheData();
*_bIdx = W99AV_InCacheData();
#else
*_bIdx=INPB(CDPR);
*(_bIdx+1)=INPB(CDPR);
*(_bIdx+2)=INPB(CDPR);
*(_bIdx+3)=INPB(CDPR);
#endif
_wLeft++;
// Per 256 Byte need wait ACK again.
if ((_wLeft >= wLen)||((_wLeft%64)==0))
break;
}
}
return TRUE;
}
#endif
// ***********************************************************************************
// Function : _ReadDRAMBurst
// Description : Read DRAM data from the specified DRAM address by command
// according burst length
// 1.Clear CACK bit of PSR register
// 2.Write Command_index(15:0)=0x0008 and
// Command_arg(31:16)=0x0700
// 3.Write ARG1(31:0)=DRAM starting address(19:0)
// 4.Set Command Interrupt bit
// 5.Waiting for command acknowledge
// 6.Read ARG0~ARG1 to get desired data
// Arguments : dwAddr:desired DRAM address, dwAddr(19:0) is valid
// pdwData:a desired data to be read, max is 16 DWORD
// bLen:desired burst length, max is 16
// Return : TRUE or FALSE
// Side Effect :
// ***********************************************************************************
#ifndef CACHE_RW_ONLY ///SUPPORT_CACHE_RW //Kevin1.22CACHE
#pragma NOAREGS // be called in ISR
#pragma DISABLE // will disable all interrupt for the duration of function
// can't use when function return is BIT
BYTE _ReadDRAMBurst(DWORD dwAddr, DWORD* pdwData, BYTE bLen)
{
// Step 1 : clear CACK bit of PSR
// Chuan2.80p, move to W99AV_SetCommandEnable()
//W99AV_ClearInterrupt(INT_CACK); // set bit(5)--CACKC in ISR
// Step 2 : set ARG0(31:0)
W99AV_OutIndex(0x10000000); // set AIR(31:0)=0x10000000
W99AV_OutData(0x07000008);
// Step 3 : Set ARG1(31:0)=DRAM starting address
W99AV_OutData(dwAddr);
// TCC037, always set length to 16 since odd number will have problem. Provided by CMC
// TCC037, must request 16 at a time due to H/W bug
W99AV_OutData ((DWORD)((0x01<<8)|(16-1))) ; //INC=1
//W99AV_OutData ((DWORD)((0x01<<8)|(bLen-1))) ; //INC=1
// Step 4 : set Command Interrupt bit
W99AV_SetCommandEnable();
// Step 5 : waiting for Command acknowledge
_btRet=_W99AV_WaitACK(INT_CACK); // Chuan 172r 2002/03/13: Use current function _W99AV_WaitACK().
if(_btRet)
{
// Step 6 : read desired from ARG0~ARG1
//TCC022, for performance issue
W99AV_OutIndex(0x10000000); // set AIR(31:0)=0x10000000
for(_bTemp=0;_bTemp<bLen;_bTemp++)
{
//W99AV_OutIndex(0x10000000+i); // set AIR(31:0)=0x10000000
// TCC043, for performance issue.
#if IO == IO_8051
_bIdx = &pdwData[_bTemp] ;
*_bIdx = INPB (DPR3) ;
*(_bIdx+1) = INPB (DPR2) ;
*(_bIdx+2) = INPB (DPR1) ;
*(_bIdx+3) = INPB (DPR0) ;
#else
pdwData[_bTemp]=W99AV_InData();
#endif
}
// TCC037, must read all data requested. Provided by CMC
for(_bTemp=bLen;_bTemp<16;_bTemp++)
{
// TCC043, for performance issue.
#if IO == IO_8051
_bIdx = &_dwTemp ;
*_bIdx = INPB (DPR3) ;
*(_bIdx+1) = INPB (DPR2) ;
*(_bIdx+2) = INPB (DPR1) ;
*(_bIdx+3) = INPB (DPR0) ;
#else
_dwTemp = W99AV_InData () ;
#endif
}
}
else
pdwData[0] = ERROR_VALUE; // Chuan1.05, avoid infinite loop when No ack.
return _btRet;
}
#endif
// ***********************************************************************************
// Function : _WriteDRAMBurst
// Description : Write desired value to specified DRAM address by instruction
// according burst length
// 1.Write AIR(31:28)=0x2, AIR(24:20)=burst length
// AIR(18:0)=Desired DRAM address
// 2.Write desired data into DPR3,DPR2,DPR1 and DPR0 respectively
// in burst mode until the burst length is reached
// 3.Waiting for DRAM_LTH=1 in PSR
// Arguments : dwAddr:desired DRAM address, dwAddr(18:0) is valid
// pdwData:desired data to be written, max is 14 DWORD
// bLen:desired burst length, max is 14
// Return : TRUE or FALSE
// Side Effect :
// ***********************************************************************************
#ifndef CACHE_RW_ONLY ///SUPPORT_CACHE_RW //Kevin1.22CACHE
#pragma NOAREGS // be called in ISR
#pragma DISABLE // will disable all interrupt for the duration of function
// can't use when function return is BIT
BYTE _WriteDRAMBurst(DWORD dwAddr, DWORD* pdwData, BYTE bLen)
{
// Step 1 : clear CACK bit of PSR
// Chuan2.80p, move to W99AV_SetCommandEnable()
//W99AV_ClearInterrupt(INT_CACK); // set bit(5)--CACKC in ISR
// Step 2 : set ARG0(31:0)
// Chuan 172r 2002/03/22: Directly mask the following statement while Call W99AV_OutData()
//_dwTemp = (DWORD) 0x1800000 ; // INC=1
//_dwTemp |=((DWORD)((bLen-1)&0x7f))<<16; // Command_arg(31:15)=(bLen-1)&0x3f
//_dwTemp=_dwTemp | (DWORD)(COMMAND_WDRAM);
W99AV_OutIndex(0x10000000); // set AIR(31:0)=0x10000000
W99AV_OutData((DWORD) 0x1800000|(((DWORD)((bLen-1)&0x7f))<<16)|(DWORD)(COMMAND_WDRAM));
// Step 3 : Set ARG1 ~ ARG15 if necessary
//W99AV_OutIndex(0x10000001); // set AIR(31:0)=0x10000000
W99AV_OutData(dwAddr);
for(_bTemp=0;_bTemp<bLen;_bTemp++)
{
//TCC022, for performance issue
//W99AV_OutIndex(0x10000002+i); // set AIR(31:0)=0x10000000
W99AV_OutData(pdwData[_bTemp]);
}
// Step 4 : set Command Interrupt bit
W99AV_SetCommandEnable();
// Step 5 : waiting for Command acknowledge
return _W99AV_WaitACK(INT_CACK); // Chuan 172r 2002/03/13: Use current function _W99AV_WaitACK().
}
#endif
// ***********************************************************************************
// Function : _WriteDRAMCache
// Description : Write desired value to specified DRAM address by instruction
// according burst length
// 1.Write AIR(31:28)=0x2, AIR(24:20)=burst length
// AIR(18:0)=Desired DRAM address
// 2.Write desired data into DPR3,DPR2,DPR1 and DPR0 respectively
// in burst mode until the burst length is reached
// 3.Waiting for DRAM_LTH=1 in PSR
// Arguments : dwAddr:desired DRAM address, dwAddr(18:0) is valid
// pdwData:desired data to be written, max is 14 DWORD
// bLen:desired burst length, max is 14
// Return : TRUE or FALSE
// Side Effect :
// ***********************************************************************************
#ifdef CACHE_RW_ONLY ///SUPPORT_CACHE_RW //Kevin1.22CACHE
#pragma NOAREGS // be called in ISR
#pragma DISABLE // will disable all interrupt for the duration of function
// can't use when function return is BIT
BYTE _WriteDRAMCache(DWORD dwAddr, DWORD* pdwData, WORD wLen)
{
// Step 1: Specify the desired DRAM address into CBAR[20:0]
W99AV_OutCacheAddr(dwAddr);
// Step 2: Specify the NO# of bytes which will be moved from Cache to DRAM
// into BMSR1 & BMSR0
W99AV_SetCacheRWNo(wLen);
// Step 3: Set Cache R/W mode=100 to assert an block write cache interrupt to RISC
W99AV_SetCacheRWMode(0x04);
_wLeft = 0;
wLen/=4;
while(_wLeft != wLen)
{
while(1)
{
// Step 4: Write Data to Cache
_bIdx = (BYTE *)&pdwData[_wLeft] ;
#if IO == IO_PCI
W99AV_OutCacheData(*_bIdx);
W99AV_OutCacheData(*(_bIdx+1));
W99AV_OutCacheData(*(_bIdx+2));
W99AV_OutCacheData(*(_bIdx+3));
#else
OUTB(CDPR, *(_bIdx+3));
OUTB(CDPR, *(_bIdx+2));
OUTB(CDPR, *(_bIdx+1));
OUTB(CDPR, *_bIdx);
#endif
_wLeft++;
// Per 256 Byte need wait ACK again.
if ((_wLeft >= wLen)||((_wLeft%64)==0))
break;
}
// Step 5: Waiting for Command acknowledge
if (!_W99AV_WaitACK(INT_CACK))
return FALSE;
}
return TRUE;
}
#endif
// **************************************************************************
// Function : _Delay
// Description : Loop for delay a moment
// Arguments : wLoop:the loop time
// Return : none
// Side Effect :
// **************************************************************************
#if IO == IO_PCI
void _Delay(WORD wLoop)
{
WORD i;
for(i=0;i<wLoop;i++);
}
#endif
// **************************************************************************
// Function : W99AV_PCIDelay
// Description : Loop for delay a moment
// Arguments : None
// Return : none
// Side Effect :
// **************************************************************************
// Chuan0.81, create.
#if IO == IO_PCI
void W99AV_PCIDelay(void)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -