📄 hwctxt.cpp
字号:
PBYTE pbDMATemp;
BOOL bSuccess=FALSE;
FUNC_WPDD("+MapDMABuffers");
// Allocate a block of virtual memory big enough to hold the DMA buffers
pbDMATemp = (PBYTE)VirtualAlloc(0,
AUDIO_BUFFER_SIZE * 4,
MEM_RESERVE,
PAGE_NOACCESS);
if (pbDMATemp)
{
// Map the physical DMA buffer to the virtual address we just allocated
bSuccess = VirtualCopy(pbDMATemp,
(LPVOID)DMA_BUFFER_VIRTUAL,
AUDIO_BUFFER_SIZE * 4,
PAGE_READWRITE | PAGE_NOCACHE);
}
if (bSuccess)
{
// Save pointers to the virtual addresses so the driver can access them
m_Output_pbDMA_PAGES[0] = pbDMATemp;
m_Output_pbDMA_PAGES[1] = pbDMATemp + AUDIO_BUFFER_SIZE;
m_Input_pbDMA_PAGES[0] = pbDMATemp + 2*AUDIO_BUFFER_SIZE;
m_Input_pbDMA_PAGES[1] = pbDMATemp + 3*AUDIO_BUFFER_SIZE;
}
FUNC_WPDD("-MapDMABuffers");
return bSuccess;
}
void HardwareContext::InitInputDMA()
{
FillInputDescriptors();
//Dump the Descriptor
RETAILMSG(ZONE_ERROR, (TEXT( "\r\n")));
RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvA->ddadr %x \r\n" ),m_vpAudioRcvA->ddadr) );
RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvA->dsadr %x \r\n" ),m_vpAudioRcvA->dsadr) );
RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvA->dtadr %x \r\n" ),m_vpAudioRcvA->dtadr) );
RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvA->dcmd %x \r\n" ),m_vpAudioRcvA->dcmd ) );
RETAILMSG(ZONE_ERROR, (TEXT( "\r\n")));
RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvB->ddadr %x \r\n" ),m_vpAudioRcvB->ddadr) );
RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvB->dsadr %x \r\n" ),m_vpAudioRcvB->dsadr) );
RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvB->dtadr %x \r\n" ),m_vpAudioRcvB->dtadr) );
RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioRcvB->dcmd %x \r\n" ),m_vpAudioRcvB->dcmd ) );
}
void HardwareContext::InitOutputDMA()
{
FillOutputDescriptors();
//Dump the Descriptor
// RETAILMSG(ZONE_ERROR, (TEXT( "\r\n")));
// RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitA->ddadr %x \r\n" ),m_vpAudioXmitA->ddadr) );
// RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitA->dsadr %x \r\n" ),m_vpAudioXmitA->dsadr) );
// RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitA->dtadr %x \r\n" ),m_vpAudioXmitA->dtadr) );
// RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitA->dcmd %x \r\n" ),m_vpAudioXmitA->dcmd ) );
// RETAILMSG(ZONE_ERROR, (TEXT( "\r\n")));
// RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitB->ddadr %x \r\n" ),m_vpAudioXmitB->ddadr) );
// RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitB->dsadr %x \r\n" ),m_vpAudioXmitB->dsadr) );
// RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitB->dtadr %x \r\n" ),m_vpAudioXmitB->dtadr) );
// RETAILMSG(ZONE_ERROR, (TEXT( "m_vpAudioXmitB->dcmd %x \r\n" ),m_vpAudioXmitB->dcmd ) );
}
void HardwareContext::InitCodec()
{
PowerUp();
}
void HardwareContext::StartOutputDMA()
{
// RETAILMSG(ZONE_ERROR, (TEXT("+StartOutputDMA\r\n")));
unsigned long ulTemp;
//reset the AC97 to workaround issue in sighting 46676
ulTemp = m_pAc97regs->gcr;
ulTemp |= 8; // the ACOFF bit set means begin a clean shutdown.
m_pAc97regs->gcr = ulTemp; // do it.
// wait for the ACOFFD (acoff "done") bit to assert.
while(1)
{
ulTemp = m_pAc97regs->gsr;
if( ulTemp & 0x8 )
break;
}
// turn the aclink back on
ulTemp = m_pAc97regs->gcr;
ulTemp &= ~8; // the ACOFF bit needs to be cleared;
m_pAc97regs->gcr = ulTemp;
//end of workaround
if (!m_OutputDMARunning)
{
m_OutputDMARunning=TRUE;
m_OutBytes[0]=m_OutBytes[1]=0;
v_nNextPage[WAPI_OUT] = 0;
ULONG OutputTransferred = 0;
OutputTransferred = TransferOutputBuffers(0);
if (OutputTransferred==0)
OutputTransferred=TransferOutputBuffers(1);
if (OutputTransferred!=0)
{
// Initialize the DMA channel format
//WAPI_INOUT
AC97SetSampleRate(SAMPLERATE, WAPI_OUT);
//RETAILMSG(ZONE_ERROR, (TEXT( "Starting DMA XMIT channel %d \r\n" ),DMA_CH_OUT) );
//m_pDMARegisters->dcsr[DMA_CH_OUT] = DCSR_STOPIRQEN;
m_pDMARegisters->ddg[PlaybackChannel].ddadr = DMA_XMIT_A_DESCRIPTOR_BASE_PHYSICAL;
m_pDMARegisters->drcmr[12] = DMA_MAP_VALID_MASK | PlaybackChannel ;
//m_pAc97regs->pocr = 0x8; //enable the Pcm Input Fifo Interrupt
m_pAc97regs->posr = 0x10; //clear the output Fifo error
m_pDMARegisters->dcsr[PlaybackChannel] |= DCSR_RUN; // set the RUN bit
RETAILMSG(ZONE_ERROR, (TEXT("Started Output DMA\r\n")));
}
else
m_OutputDMARunning=FALSE,RETAILMSG(ZONE_ERROR, (TEXT("no Output started with DMA\r\n")));
NKDbgPrintfW(TEXT("Started Output DMA\r\n"));
}
// RETAILMSG(ZONE_ERROR, (TEXT("-StartOutputDMA\r\n")));
}
void HardwareContext::StopOutputDMA()
{
NKDbgPrintfW(TEXT("StopOutputDMA\r\n"));
if (m_OutputDMARunning)
{
//stop the dma channel and mute
//TODO Mute
StopDmac(PlaybackChannel);
m_OutputDMARunning=FALSE;
NKDbgPrintfW(TEXT("Stopped output DMA\r\n"));
}
}
void HardwareContext::StartInputDMA()
{
if (!m_InputDMARunning)
{
AC97SetSampleRate(SAMPLERATE, WAPI_IN);
// For now, pretend input dma is running in case we accidentally get reentered
m_InputDMARunning=TRUE;
m_InBytes[0]=m_InBytes[1]=0;
v_nNextPage[WAPI_IN] = 0;
//DMA_CH_RCV:
DEBUGMSG(ZONE_ERROR, (TEXT( "Starting DMA Recieve channel \r\n" )) );
m_pDMARegisters->ddg[RecordingChannel].ddadr = DMA_RCV_A_DESCRIPTOR_BASE_PHYSICAL;
m_pDMARegisters->drcmr[11] = DMA_MAP_VALID_MASK | RecordingChannel ;
m_pAc97regs->pisr = 0x10; //clear Pcm Input Fifo status
m_pDMARegisters->dcsr[RecordingChannel] |= DCSR_RUN; // set the RUN bit
}
}
void HardwareContext::StopInputDMA()
{
if (m_InputDMARunning)
{
m_InputDMARunning=FALSE;
StopDmac(RecordingChannel);
}
}
DWORD HardwareContext::GetInterruptThreadPriority()
{
// HKEY hDevKey;
// DWORD dwValType;
// DWORD dwValLen;
DWORD dwPrio = 249; // Default priority
/* hDevKey = OpenDeviceKey((LPWSTR)m_DriverIndex);
if (hDevKey)
{
dwValLen = sizeof(DWORD);
RegQueryValueEx(
hDevKey,
TEXT("Priority256"),
NULL,
&dwValType,
(PUCHAR)&dwPrio,
&dwValLen);
RegCloseKey(hDevKey);
}
*/
return dwPrio;
}
BOOL HardwareContext::InitInterruptThread()
{
FUNC_WPDD("+InitInterruptThread\r\n");
BOOL bSuccess;
//m_IntrAudio=SYSINTR_AUDIO;
// m_hAudioInterrupt = CreateEvent( NULL, FALSE, FALSE, NULL);
//if (!m_hAudioInterrupt)
// {
// FUNC_WPDD("ERROR: InitInterruptThread\r\n");
// return FALSE;
// }
//bSuccess = InterruptInitialize(m_IntrAudio, m_hAudioInterrupt, NULL, 0);
//m_vpBLReg->hex_led = 0x97ACFFFD;
m_hAudioInputInterruptThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)CallInputInterruptThread,
this,
0,
NULL);
m_hAudioOutputInterruptThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)CallOutputInterruptThread,
this,
0,
NULL);
if (!m_hAudioInputInterruptThread)
{
while (1)
{
DWORD myval = 0xDEADBEEF;
m_vpBLReg->hex_led = myval--;
}
return FALSE;
}
if (!m_hAudioOutputInterruptThread)
{
while (1)
{
DWORD myval = 0xDEADBEEF;
m_vpBLReg->hex_led = myval--;
}
return FALSE;
}
// Bump up the priority since the interrupt must be serviced immediately.
CeSetThreadPriority(m_hAudioInputInterruptThread, GetInterruptThreadPriority());
CeSetThreadPriority(m_hAudioOutputInterruptThread, GetInterruptThreadPriority());
FUNC_WPDD("-InitInterruptThread\r\n");
return TRUE;
}
BOOL HardwareContext::Deinit()
{
UnmapRegisters((PVOID)m_pDriverGlobals, sizeof(*m_pDriverGlobals));
UnmapRegisters((PVOID)m_pGPIORegisters, sizeof(*m_pGPIORegisters));
//UnmapRegisters((PVOID)m_pOSTimer, sizeof(m_pOSTimer));
UnmapRegisters((PVOID)m_pDMARegisters, sizeof(*m_pDMARegisters));
//UnmapRegisters((PVOID)m_pInterruptController,sizeof(*m_pInterruptController));
UnmapRegisters((PVOID)m_pAc97regs, sizeof(*m_pAc97regs));
//#ifdef PLAT_LUBBOCK
UnmapRegisters((PVOID)m_vpBLReg, sizeof(*m_vpBLReg));
//#endif
return TRUE;
}
PVOID HardwareContext::MapRegisters(PVOID pBase, DWORD dwSize)
{
PVOID pReg;
BOOL bSuccess;
pReg = VirtualAlloc( 0, dwSize, MEM_RESERVE, PAGE_NOACCESS);
if (pReg)
{
bSuccess = VirtualCopy( pReg,
pBase,
dwSize,
PAGE_READWRITE | PAGE_NOCACHE
);
if (!bSuccess)
{
UnmapRegisters(pReg, dwSize);
pReg=NULL;
}
}
return pReg;
}
void HardwareContext::UnmapRegisters(PVOID pReg, DWORD dwSize)
{
}
ULONG HardwareContext::TransferInputBuffer(ULONG NumBuf)
{ FUNC_WPDD("TransferInputBuffer ");
ULONG BytesTransferred;
PBYTE pBufferStart = m_Input_pbDMA_PAGES[NumBuf];
PBYTE pBufferEnd = pBufferStart + dma_page_size;
PBYTE pBufferLast;
pBufferLast = m_InputDeviceContext.TransferBuffer(pBufferStart, pBufferEnd,NULL);
BytesTransferred = m_InBytes[NumBuf] = pBufferLast-pBufferStart;
//RETAILMSG(1, (TEXT("In(%d) %d bytes, dcsro=0x%x\r\n"),NumBuf, BytesTransferred, m_pDMARegisters->chan[AUDIO_PLAYBACK_DMA].dcsr_ro));
return BytesTransferred;
}
ULONG HardwareContext::TransferInputBuffers(DWORD dwDCSR)
{ FUNC_WPDD("TransferInputBuffer ");
return TransferInputBuffer( dwDCSR );
}
ULONG HardwareContext::TransferOutputBuffer(ULONG NumBuf)
{ FUNC_WPDD("TransferOutputBuffer ");
ULONG BytesTransferred;
PBYTE pBufferStart = m_Output_pbDMA_PAGES[NumBuf];
PBYTE pBufferEnd = pBufferStart + dma_page_size;
PBYTE pBufferLast;
pBufferLast = m_OutputDeviceContext.TransferBuffer(pBufferStart, pBufferEnd,NULL);
BytesTransferred = m_OutBytes[NumBuf] = pBufferLast-pBufferStart;
#if 1 // Enable if you need to clear the rest of the DMA buffer
StreamContext::ClearBuffer(pBufferLast,pBufferEnd);
#endif
return BytesTransferred;
}
ULONG HardwareContext::TransferOutputBuffers(DWORD dwDCSR)
{// FUNC_WPDD("TransferOutputBuffer ");
return TransferOutputBuffer( dwDCSR );
}
/*
AUDIO_STATE HardwareContext::GetInterruptType( VOID )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -