📄 w99av.c
字号:
#pragma DISABLE // will disable all interrupt for the duration of function
// can't use when function return is BIT
WORD W99AV_GetPSR(void)
{
#if IO == IO_PCI
// Chuan0.81, Use PCI Delay
//_Delay(DELAY);
_dwTemp=_inpdw((WORD)PSR0); // discard the value of first time reading
// Chuan0.83a, EPP don't need read back twice and delay.
#ifndef IO_EPP
//_Delay(DELAY);
_dwTemp=_inpdw((WORD)PSR0);
#endif // IO_EPP
return (WORD)_dwTemp;
#else
_bIdx = &_wTemp ;
*(_bIdx) = INPB(PSR1) ;
*(_bIdx+1) = INPB(PSR0) ;
return _wTemp ;
#endif
}
// ************************************************************************
// Function : W99AV_GetPSRDW
// Description : This function will get the current PSR value
// Arguments : None
// Return : The actual PSR value (DWORD is valid)
// Side Effect :
// ************************************************************************
#pragma NOAREGS
#pragma DISABLE // will disable all interrupt for the duration of function
// can't use when function return is BIT
DWORD W99AV_GetPSRDW(void)
{
#if IO == IO_PCI
// Chuan0.81, Use PCI Delay
//_Delay(DELAY);
_dwTemp=_inpdw((WORD)PSR0); // discard the value of first time reading
// Chuan0.83a, EPP don't need read back twice and delay.
#ifndef IO_EPP
//_Delay(DELAY);
_dwTemp=_inpdw((WORD)PSR0);
#endif // IO_EPP
return _dwTemp;
#else
_bIdx = &_dwTemp ;
*_bIdx = INPB(PSR3) ;
*(_bIdx+1) = INPB(PSR2) ;
*(_bIdx+2) = INPB(PSR1) ;
*(_bIdx+3) = INPB(PSR0) ;
return _dwTemp ;
#endif
}
// *******************************************************************************
// Function : _DM_WaitACK
// Description : Wait ACK for Read/Write DM
// Arguments : None
// Return : None
// Side Effect :
// *******************************************************************************
#pragma NOAREGS // called in ISR
BYTE _DM_WaitACK(void)
{
DWORD dwRet; // Chuan0.81, Need keep the value when receive ACK
//wyc1.23, _DM_WaitACK may interrupt W99AV_WriteDRAMBurst() & W99AV_ReadDRAMBurst (_wLeft will be modified)
//_wLeft = 0 ;
WORD wLeft;
wLeft=0;
while(1)
{
if(((dwRet = W99AV_ReadRegDW(ADCMR))&0x100))
{ // latch successfully
break;
}
if(wLeft++>ACKLOOP) // polling time out
{
// Chuan0.83a, Print this info at Serail Debug.
#if defined (SERIAL_DEBUG) || defined(SUPPORT_PRINTF)
printf("\nWait no DSP ACK!");
printf(" DEBR:%lx V:%lx A:%lx", W99AV_ReadRegDW(DEBR), W99AV_ReadRegDW (VBRR), W99AV_ReadRegDW (ABRR));
#endif
break;
}
}
W99AV_WriteRegDW (ADCMR, 0x0100, 0x0000) ;
return (BYTE)((dwRet&0x01FE00)>>9);
}
// *******************************************************************************
// Function : W99AV_ReadDM
// Description : Read a value from specified DM address by command
// Arguments : dwAddr:the specified DM address, only dwAddr(15:0) is valid
// pdwData:the DM[dwAddr] value, only [0:15] is valid
// Return : TRUE or FALSE
// Side Effect :
// ******************************************************************************
#pragma NOAREGS // called in ISR
#pragma DISABLE // will disable all interrupt for the duration of function
// can't use when function return is BIT
BYTE W99AV_ReadDM(DWORD dwAddr, DWORD* pdwData)
{
__dwW99AVCmdArg[0]=2; // number of ARG0~ARG15
__dwW99AVCmdArg[1]=CMDARG_RDM;
// Chuan 172r 2002/03/22: DM Addr just 16 bits so use mask.
__dwW99AVCmdArg[2]=dwAddr&0x0FFFF;
if(W99AV_CommandN(COMMAND_RDM)) // command_idx=0x08
{
// Chuan 172r 2002/03/22: In order to save code size. Remove the following
// code into _DM_WaitACK(), both W99AV_ReadDM and W99AV_WriteDM use.
// Chuan2.80p, 24bit width in 908
*pdwData = _DM_WaitACK();
*pdwData = W99AV_ReadRegW (DMDATAR) | (*pdwData<<16);
_btRet=TRUE;
}
else
{
_btRet=FALSE;
*pdwData = ERROR_VALUE; // Chuan1.05, avoid infinite loop when No Ack.
}
return _btRet;
}
// *********************************************************************
// Function : W99AV_WriteDM
// Description : Write a value to specified DM address by command
// Arguments : dwAddr:the specified DM address
// dwVal:the specified value to be written
// Return : TRUE or FALSE
// Side Effect :
// *********************************************************************
#pragma NOAREGS // called in ISR
#pragma DISABLE // will disable all interrupt for the duration of function
// can't use when function return is BIT
BYTE W99AV_WriteDM(DWORD dwAddr, DWORD dwVal)
{
__dwW99AVCmdArg[0]=3; // number of ARG0~ARG15
__dwW99AVCmdArg[1]=CMDARG_WDM; // command_arg=0x0001
// Chuan 172r 2002/03/22: DM Addr just 16 bits so use mask.
__dwW99AVCmdArg[2]=dwAddr&0x0FFFF;
__dwW99AVCmdArg[3]=(DWORD) dwVal ;
_btRet = (BIT)W99AV_CommandN(COMMAND_WDM); // command_idx=0x08
// Chuan 172r 2002/03/22: In order to save code size. Remove the following
// code into _DM_WaitACK(), both W99AV_ReadDM and W99AV_WriteDM use.
_DM_WaitACK();
return _btRet;
}
// ************************************************************************
// Function : W99AV_EnableInterrupt
// Description : Enable corresponding interrupt bit by setting IER
// Arguments : dwIER:the desired value of IER (only DWORD is valid)
// Return : None
// Side Effect :
// ************************************************************************
#pragma NOAREGS // called in ISR
#pragma DISABLE //Kevin1.23, dwIER may be compiled as xdata
void W99AV_EnableInterrupt(DWORD dwIER)
{
W99AV_WriteRegDW(IER, LOWORD(dwIER), HIWORD(dwIER) ); // issue new IER
}
// ******************************************************************************
// Function : W99AV_ClearInterrupt
// Description : It will clear the corresponding flag in PSR by setting ISR
// Arguments : wISR:the desired value of ISR (only WORD is valid)
// Return : None
// Side Effect :
// ******************************************************************************
#pragma NOAREGS // called in ISR
#pragma DISABLE //Kevin1.23, dwISR may be compiled as xdata
void W99AV_ClearInterrupt(DWORD dwISR)
{
W99AV_WriteRegDW(ISR, LOWORD(dwISR), HIWORD(dwISR));
}
// ***********************************************************************************
// Function : W99AV_WriteDRAMBurst
// Description : Write desired value to specified DRAM address by command
// according burst length
// Arguments : dwAddr:desired DRAM address, dwAddr(19:0) is valid
// pdwData:desired data to be written
// bLen:desired burst length
// Return : TRUE or FALSE
// Side Effect :
// ***********************************************************************************
#pragma NOAREGS // called in ISR
//Kevin1.23, uncomment, arguments may be compiled as xdata
#pragma DISABLE // will disable all interrupt for the duration of function
// can't use when function return is BIT
BYTE W99AV_WriteDRAMBurst(DWORD dwAddr, DWORD* pdwData, WORD wLen)
{
#ifdef CACHE_RW_ONLY ///SUPPORT_CACHE_RW //Kevin1.22CACHE
// Chuan 172r 2002/03/13: Use Block Cache Write instead of Burst Write
if (wLen>16383) // Chuan 172r 2002/03/26: 0xffff/4 = 16383
{
return FALSE;
}
// LLY2.80p, disable action while wLen==0
if(wLen == 0)
{
return TRUE;
}
return _WriteDRAMCache(dwAddr, pdwData, (WORD)(wLen*4));
#else
#define MAX_BURST_WRITE 14
//Kevin1.23, modify
/*
_wLeft = wLen ;
dwTmpAdd = dwAddr ;
pdwTmpData = pdwData ;
while (_wLeft)
{
if (_wLeft >= MAX_BURST_WRITE)
{
if (!_WriteDRAMBurst (dwTmpAdd, pdwTmpData, MAX_BURST_WRITE))
return FALSE ;
_wLeft -= MAX_BURST_WRITE ;
dwTmpAdd += MAX_BURST_WRITE ;
pdwTmpData += MAX_BURST_WRITE ;
}
else
{
if (!_WriteDRAMBurst (dwTmpAdd, pdwTmpData, (BYTE)_wLeft))
return FALSE ;
_wLeft = 0 ;
}
}
*/
while (wLen)
{
if (wLen >= MAX_BURST_WRITE)
{
if (!_WriteDRAMBurst (dwAddr, pdwData, MAX_BURST_WRITE))
return FALSE ;
wLen -= MAX_BURST_WRITE ;
dwAddr += MAX_BURST_WRITE ;
pdwData += MAX_BURST_WRITE ;
}
else
{
if (!_WriteDRAMBurst (dwAddr, pdwData, (BYTE)wLen))
return FALSE ;
wLen = 0 ;
}
}
return TRUE ;
#endif
}
// ***********************************************************************************
// Function : W99AV_ReadDRAMBurst
// Description : Read DRAM data from the specified DRAM address by command
// Arguments : dwAddr:desired DRAM address, dwAddr(19:0) is valid
// pdwData:a desired data to be read
// bLen:desired burst length
// Return : TRUE or FALSE
// Side Effect :
// ***********************************************************************************
#pragma NOAREGS // called in ISR
//Kevin1.23, uncomment, arguments may be compiled as xdata
#pragma DISABLE // will disable all interrupt for the duration of function
// can't use when function return is BIT
BYTE W99AV_ReadDRAMBurst(DWORD dwAddr, DWORD* pdwData, WORD wLen)
{
#ifdef CACHE_RW_ONLY ///SUPPORT_CACHE_RW //Kevin1.22CACHE
// Chuan 172r 2002/03/13: Use Block Cache Read instead of Burst Read
if (wLen>16383) // Chuan 172r 2002/03/26: 0xffff/4 = 16383
{
return FALSE;
}
// LLY2.80p, disable action while wLen==0
if(wLen == 0)
{
return TRUE;
}
return _ReadDRAMCache(dwAddr, pdwData, (WORD)(wLen*4));
#else
#define MAX_BURST_READ 16
//Kevin1.23, modify
/*
_wLeft = wLen ;
dwTmpAdd = dwAddr ;
pdwTmpData = pdwData ;
while (_wLeft)
{
if (_wLeft >= MAX_BURST_READ)
{
if (!_ReadDRAMBurst (dwTmpAdd, pdwTmpData, MAX_BURST_READ))
return FALSE ;
_wLeft -= MAX_BURST_READ ;
dwTmpAdd += MAX_BURST_READ ;
pdwTmpData += MAX_BURST_READ ;
}
else
{
if (!_ReadDRAMBurst (dwTmpAdd, pdwTmpData, (BYTE)_wLeft))
return FALSE ;
_wLeft = 0 ;
}
}
*/
while (wLen)
{
if (wLen >= MAX_BURST_READ)
{
if (!_ReadDRAMBurst (dwAddr, pdwData, MAX_BURST_READ))
return FALSE ;
wLen -= MAX_BURST_READ ;
dwAddr += MAX_BURST_READ ;
pdwData += MAX_BURST_READ ;
}
else
{
if (!_ReadDRAMBurst (dwAddr, pdwData, (BYTE)wLen))
return FALSE ;
wLen = 0 ;
}
}
return TRUE ;
#endif
}
// ***********************************************************************************
// Function : W99AV_WriteDRAMData
// Description : Write a desired value to specified DRAM address by command
// 1.Clear CACK bit of PSR
// 2.Write Command_index(15:0)=0x0008=COMMAND_WDRAM and
// Command_arg(31:16)=(burst_length-1)&0x3f=0x0
// 3.Write ARG1(31:0)=DRAM start address(19:0) and
// ARG2(31:0)=the desired DRAM data
// 4.Set Command Interrupt bit
// 5.Waiting for command acknowledge
// Arguments : dwAddr:desired DRAM address, dwAddr(19:0) is valid
// pdwData:desired data to be written
// Return : TRUE or FALSE
// Side Effect :
// ***********************************************************************************
#pragma NOAREGS // called in ISR
#pragma DISABLE // will disable all interrupt for the duration of function
// can't use when function return is BIT
BYTE W99AV_WriteDRAMData(DWORD dwAddr, DWORD dwData)
{
#ifdef CACHE_RW_ONLY
return _WriteDRAMCache(dwAddr, &dwData, 4);
#else
// 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: Direct mask while Call W99AV_OutData() in order to save code size and performance.
W99AV_OutIndex(0x10000000); // set AIR(31:0)=0x10000000
W99AV_OutData(0x1800000|COMMAND_WDRAM); // INC=1, burst length = 1
// Step 3 : Set ARG1 ~ ARG15 if necessary
W99AV_OutData(dwAddr);
W99AV_OutData(dwData);
// 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 : W99AV_ReadDRAMData
// Description : Read DRAM data from the specified DRAM address by command
// 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 to get desired data
// Arguments : dwAddr:desired DRAM address, dwAddr(19:0) is valid
// pdwData:a desired data to be read
// Return : TRUE or FALSE
// Side Effect :
// ***********************************************************************************
#pragma NOAREGS // called in ISR
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -