📄 ac97codec.cpp
字号:
// AC97Codec::StopRecord
//****************************************************************************
//
//
//
MMRESULT AC97Codec::StopRecord(ULONG ulChannel)
{
//
// For PIO mode an interrupt is generated continously if the
// Recieve Interrupt is enabled, but Receive is disabled.
//
// Disable the Recieve Interrupt then disable Recieve.
//
m_puAC97Ch[AC97I_IE>>2] = m_ulIE &= ~IE_RIE;
m_puAC97Ch[AC97I_RXCR>>2] = m_ulRXCR;
return MMSYSERR_NOERROR;
}
//****************************************************************************
// AC97Codec::GetDmaPort
//****************************************************************************
//
//
//
ULONG AC97Codec::GetDmaPort(void)
{
return PRALLOC_AAC1;
}
//****************************************************************************
// PeekAC97
//****************************************************************************
// Read an AC97 codec Register.
//
// ulCodecReg - AC97 Codec Register
// pulValue - Codec Register value.
//
// Return MMSYSERROR_NOERROR
// MMSYSERROR_ERROR
//
MMRESULT AC97Codec::PeekAC97(UINT ulCodecReg, PULONG pulValue)
{
ULONG ulRGIS;
LARGE_INTEGER liStart, liCurrent;
BOOL b;
//
// How it is supposed to work is:
// - The ac97 controller sends out a read addr in slot 1.
// - In the next frame, the codec will echo that address back in slot 1
// and send the data in slot 2. SLOT2RXVALID will be set to 1.
//
// Read until SLOT2RXVALID goes to 1. Reading the data in AACS2DATA
// clears SLOT2RXVALID.
//
b = QueryPerformanceCounter(&liStart);
for(;;)
{
//
// Sleep for a little bit.
//
//Sleep(1);
b = QueryPerformanceCounter(&liCurrent);
//
// Check to see if there is any data in the receive fifo.
//
ulRGIS = *AC97I_RGIS;
if(ulRGIS & GIS_SLOT1TXCOMPLETE)
break;
if((liStart.QuadPart + TIMEOUT_AC97_READ) <liCurrent.QuadPart)
{
ERRMSG((L"PeekAC97 SLOT2TXVALID timed out. reg = 0x%02x.\r\n", ulCodecReg));
return MMSYSERR_ERROR;
}
}
//if( !(ulRGIS & GIS_SLOT2RXVALID) )
//{
// ERRMSG((L"PeekAC97: SLOT2RXVALID timed out, reg = 0x%02x..\n", ulCodecReg));
// return MMSYSERR_ERROR;
//}
//
// Write the address to AACS1DATA.
//
*AC97I_S1DATA = ulCodecReg;
b = QueryPerformanceCounter(&liStart);
for(;;)
{
//
// Sleep for a little bit.
//
// Sleep(1);
b = QueryPerformanceCounter(&liCurrent);
//
// Check to see if there is any data in the receive fifo.
//
ulRGIS = *AC97I_RGIS;
if((ulRGIS & (GIS_SLOT1TXCOMPLETE | GIS_SLOT2RXVALID)) ==
(GIS_SLOT1TXCOMPLETE | GIS_SLOT2RXVALID))
break;
if((liStart.QuadPart + TIMEOUT_AC97_READ) <liCurrent.QuadPart)
{
ERRMSG((L"PeekAC97 timed out reading reg = 0x%04x.\r\n", ulCodecReg));
return MMSYSERR_ERROR;
}
}
//
// Read in the value from S2Data
//
*pulValue = *AC97I_S2DATA;
AC97_MSG((L"PeekAC97: Reg = 0x%02x, Value = 0x%04x\r\n",ulCodecReg, *pulValue));
return MMSYSERR_NOERROR;
}
//****************************************************************************
// PokeAC97
//****************************************************************************
// Writes an AC97 codec Register.
//
// ulCodecReg - AC97 Codec Register
// ulValue - New Codec Register valuie.
//
// Return MMSYSERROR_NOERROR
// MMSYSERROR_ERROR
//
MMRESULT AC97Codec::PokeAC97(ULONG ulCodecReg, ULONG ulValue)
{
BOOL b;
ULONG ulRGIS;
LARGE_INTEGER liStart, liCurrent;
AC97_MSG((L"PokeAC97: Reg = 0x%02x, Value = 0x%04x\r\n",ulCodecReg, ulValue));
//
// Read AACS2DATA to be sure and clear the SLOT2RXVALID bit.
// May not be necessary, not sure.
//
// uiTemp = Ac97Global->AACS2DATA.Value;
//
// Write the data to AACS2DATA, then the address to AACS1DATA.
//
*AC97I_S2DATA = ulValue;
*AC97I_S1DATA = ulCodecReg;
b = QueryPerformanceCounter(&liStart);
for(;;)
{
//
// Sleep for a little bit.
//
// Sleep(1);
b = QueryPerformanceCounter(&liCurrent);
//
// Check to see if there is any data in the receive fifo.
//
ulRGIS = *AC97I_RGIS;
if(ulRGIS & GIS_SLOT2TXCOMPLETE)
break;
if((liStart.QuadPart + TIMEOUT_AC97_READ) <liCurrent.QuadPart)
{
ERRMSG((L"PokeAC97: SLOT2TXVALID timed out reg = 0x%02x.\r\n", ulCodecReg));
return MMSYSERR_ERROR;
}
}
return MMSYSERR_NOERROR;
}
static volatile ULONG ulJunk;
//****************************************************************************
// I2SCodec::ProducePIOTone
//****************************************************************************
// For Debug only.
//
// Uses I2S to produce a PIO tone.
//
//
void AC97Codec::ProducePIOTone(void)
{
ULONG ulCount;
volatile ULONG ulTemp;
volatile ULONG ulSR;
ULONG ulMax= 0x80008000, ulMin=0x7FFF7FFF;
//
// Enable the AC97 transmit channel 0.
//
m_puAC97Ch[AC97I_TXCR>>2] = m_ulTXCR | TXCR_TEN;
ulTemp = ulMax;
for(ulCount = 0; ;ulCount ++)
{
if(ulCount& 0x40)
{
ulTemp = ulMax;
}
else
{
ulTemp = ulMin;
}
do
{
ulSR = m_puAC97Ch[AC97I_SR >>2];
} while( ulSR & SR_TXFF);
m_puAC97Ch[AC97I_DR >>2] = ulTemp;
}
}
//****************************************************************************
// I2SCodec::CapturePIO
//****************************************************************************
// For Debug only.
//
// Uses I2S to produce a PIO tone.
//
//
void AC97Codec::CapturePIO(void)
{
ULONG ulCount;
volatile ULONG ulTemp[100];
volatile ULONG ulSR;
//
// Enable the AC97 capture channel 0.
//
m_puAC97Ch[AC97I_RXCR>>2] = m_ulRXCR | RXCR_REN;
for(;;)
{
for(ulCount = 0; ulCount <100;ulCount ++)
{
do
{
ulSR = m_puAC97Ch[AC97I_SR >>2];
} while( ulSR & SR_RXFE);
ulTemp[ulCount] = m_puAC97Ch[AC97I_DR >>2] ;
}
}
}
//****************************************************************************
// I2SCodec::CaptureNPlay
//****************************************************************************
// Play and capture to test the AC97 codec interface.
//
//
void AC97Codec::CaptureNPlay(void)
{
volatile ULONG ulTemp;
volatile ULONG ulSR;
//
// Enable the AC97 transmitt channel 0.
//
m_puAC97Ch[AC97I_RXCR>>2] = m_ulRXCR | RXCR_REN;
m_puAC97Ch[AC97I_TXCR>>2] = m_ulTXCR | TXCR_TEN;
for(;;)
{
do
{
ulSR = m_puAC97Ch[AC97I_SR >>2];
} while( ulSR & SR_RXFE);
ulTemp = m_puAC97Ch[AC97I_DR >>2] ;
ulSR = m_puAC97Ch[AC97I_SR >>2];
if(!( ulSR & SR_TXFF))
{
m_puAC97Ch[AC97I_DR >>2] = ulTemp;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -