📄 es1371.cpp
字号:
case ES1371_DAC0 :
// set the DAC0 DWORD frame count
HwPagedIOWrite( ES1371_DAC0CTL_PAGE,
ES1371_wDAC0FC_OFF,
(ulDesiredBufferSize/4 - 1) & 0x0000ffff );
// Write DAC0 interrupt count - sample frames per half-buffer (n-1).
HwRegRMW( ES1371_wDAC0IC_OFF, 0xffff, usInterruptCount );
// WRITE_PORT_USHORT((PUSHORT)(m_pPciAddr + ES1371_wDAC0IC_OFF),
// (USHORT) (ulSamplesPerInt - 1) ) ;
break;
case ES1371_DAC1 :
// set the DAC1 DWORD frame count
HwPagedIOWrite( ES1371_DAC1CTL_PAGE,
ES1371_wDAC1FC_OFF,
(ulDesiredBufferSize/4 - 1) & 0x0000ffff );
// Write DAC1 interrupt count - sample frames per half-buffer (n-1).
HwRegRMW( ES1371_wDAC1IC_OFF, 0xffff, usInterruptCount );
// WRITE_PORT_USHORT((PUSHORT)(m_pPciAddr + ES1371_wDAC1IC_OFF),
// (USHORT) (ulSamplesPerInt - 1) ) ;
break;
case ES1371_ADC :
// set the ADC DWORD frame count
HwPagedIOWrite( ES1371_ADCCTL_PAGE,
ES1371_wADCFC_OFF,
(ulDesiredBufferSize/4 - 1) & 0x0000ffff );
// Write ADC interrupt count - sample frames per half-buffer (n-1).
HwRegRMW( ES1371_wADCIC_OFF, 0xffff, usInterruptCount );
// WRITE_PORT_USHORT((PUSHORT)(m_pPciAddr + ES1371_wADCIC_OFF),
// (USHORT) (ulSamplesPerInt - 1) ) ;
break;
}
return ;
}
//--------------------------------------------------------------------------
//
// Name: StartDMAChannel
//
// Description: Start a particular DMA channel running.
//
// Parameters: UCHAR ucDMAChannel : Index of the DMA channel to start
//
// Returns: none
//
// Note:
//
//--------------------------------------------------------------------------
void
CES1371::StartDMAChannel( UCHAR ucDMAChannel )
{
UCHAR ucIOVal;
switch ( ucDMAChannel )
{
case ES1371_DAC0 :
if ( DMA_PAUSED == m_dmachannel[ucDMAChannel].ulDMAChannelState )
{
// modify pause bit for DAC0
ucIOVal = 0;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_DAC0PAUSE, ucIOVal );
}
else
{
// enable the DAC0 interrupt
ucIOVal = ES1371_SERCTL_DAC0IE;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_DAC0IE,
ucIOVal );
// start DAC0
ucIOVal = ES1371_DEVCTL_DAC0_EN;
HwRegRMW( ES1371_bDEVCTL_OFF,
ES1371_DEVCTL_DAC0_EN,
ucIOVal );
}
// save the state
m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_RUNNING;
break;
case ES1371_DAC1 :
if ( DMA_PAUSED == m_dmachannel[ucDMAChannel].ulDMAChannelState )
{
// modify pause bit for DAC1
ucIOVal = 0;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_DAC1PAUSE, ucIOVal );
}
else
{
// enable the DAC1 interrupt
ucIOVal = ES1371_SERCTL_DAC1IE;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_DAC1IE,
ucIOVal );
// start DAC1
ucIOVal = ES1371_DEVCTL_DAC1_EN;
HwRegRMW( ES1371_bDEVCTL_OFF,
ES1371_DEVCTL_DAC1_EN,
ucIOVal );
}
// save the state
m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_RUNNING;
break;
case ES1371_ADC :
// enable the ADC interrupt
ucIOVal = ES1371_SERCTL_ADCIE;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_ADCIE,
ucIOVal );
// start ADC
ucIOVal = ES1371_DEVCTL_ADC_EN;
HwRegRMW( ES1371_bDEVCTL_OFF,
ES1371_DEVCTL_ADC_EN,
ucIOVal );
// save the state
m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_RUNNING;
break;
}
return;
}
//--------------------------------------------------------------------------
//
// Name: StopDMAChannel
//
// Description: Stop a particular DMA channel.
//
// Parameters: UCHAR ucDMAChannel : Index of the DMA channel to stop
//
// Returns: none
//
// Note:
//
//--------------------------------------------------------------------------
void
CES1371::StopDMAChannel( UCHAR ucDMAChannel )
{
UCHAR ucIOVal;
ULONG ulFrameCount = 0;
switch ( ucDMAChannel )
{
case ES1371_DAC0 :
// Stop DAC0
ucIOVal = 0;
HwRegRMW( ES1371_bDEVCTL_OFF,
ES1371_DEVCTL_DAC0_EN, ucIOVal );
// disable the DAC0 interrupt
ucIOVal = 0;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_DAC0IE, ucIOVal );
if ( DMA_PAUSED == m_dmachannel[ucDMAChannel].ulDMAChannelState )
{
// modify pause bit for DAC0
ucIOVal = 0;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_DAC0PAUSE, ucIOVal );
}
// Clear out the Current Frame count register
ulFrameCount = HwPagedIORead( ES1371_DAC0CTL_PAGE, ES1371_wDAC0FC_OFF);
HwPagedIOWrite( ES1371_DAC0CTL_PAGE,
ES1371_wDAC0FC_OFF,
ulFrameCount & 0x0000ffff );
// save the state
m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_STOPPED;
break;
case ES1371_DAC1 :
// Stop DAC1
ucIOVal = 0;
HwRegRMW( ES1371_bDEVCTL_OFF,
ES1371_DEVCTL_DAC1_EN, ucIOVal);
// disable the DAC1 interrupt
ucIOVal = 0;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_DAC1IE, ucIOVal);
if ( DMA_PAUSED == m_dmachannel[ucDMAChannel].ulDMAChannelState )
{
// modify pause bit for DAC0
ucIOVal = 0;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_DAC1PAUSE, ucIOVal );
}
// Clear out the Current Frame count register
ulFrameCount = HwPagedIORead( ES1371_DAC1CTL_PAGE, ES1371_wDAC1FC_OFF);
HwPagedIOWrite( ES1371_DAC1CTL_PAGE,
ES1371_wDAC1FC_OFF,
ulFrameCount & 0x0000ffff );
// save the state
m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_STOPPED;
break;
case ES1371_ADC :
// Stop ADC
ucIOVal = 0;
HwRegRMW( ES1371_bDEVCTL_OFF,
ES1371_DEVCTL_ADC_EN, ucIOVal);
// disable the ADC interrupt
ucIOVal = 0;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_ADCIE, ucIOVal);
// Clear out the Current Frame count register
ulFrameCount = HwPagedIORead( ES1371_ADCCTL_PAGE, ES1371_wADCFC_OFF);
HwPagedIOWrite( ES1371_ADCCTL_PAGE,
ES1371_wADCFC_OFF,
ulFrameCount & 0x0000ffff );
// save the state
m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_STOPPED;
break;
}
return;
}
//--------------------------------------------------------------------------
//
// Name: PauseDMAChannel
//
// Description: Pause a particular DMA channel.
//
// Parameters: UCHAR ucDMAChannel : Index of the DMA channel to pause
//
// Returns: none
//
// Note:
//
//--------------------------------------------------------------------------
void
CES1371::PauseDMAChannel( UCHAR ucDMAChannel )
{
UCHAR ucIOVal;
switch ( ucDMAChannel )
{
case ES1371_DAC0 :
// wait until interrupt count is non-zero
// while ( !HwPagedIORead( ES1371_DAC0CTL_PAGE, ES1371_wDAC0CIC_OFF));
// modify pause bit for DAC0
ucIOVal = ES1371_SERCTL_DAC0PAUSE;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_DAC0PAUSE, ucIOVal );
// save the state
m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_PAUSED;
break;
case ES1371_DAC1 :
// wait until interrupt count is non-zero
// while ( !HwPagedIORead( ES1371_DAC1CTL_PAGE, ES1371_wDAC1CIC_OFF));
// modify pause bit for DAC1
ucIOVal = ES1371_SERCTL_DAC1PAUSE;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_DAC1PAUSE, ucIOVal);
// save the state
m_dmachannel[ucDMAChannel].ulDMAChannelState = DMA_PAUSED;
break;
case ES1371_ADC :
break;
}
return;
}
//--------------------------------------------------------------------------
//
// Name: GetDMAPosition
//
// Description: reads the current position of a DMA channel.
//
// Parameters: UCHAR ucDMAChannel : Index of the DMA channel
//
// Returns: ULONG current DMA position in bytes
//
// Note: This function returns the DMA position NOT the sample play
// cursor. It appears that this will be used for buffer filling.
//
//--------------------------------------------------------------------------
ULONG
CES1371::GetDMAPosition( UCHAR ucDMAChannel )
{
ULONG ulCurrentPos = 0;
switch ( ucDMAChannel )
{
case ES1371_DAC0 :
// read the Frame register
ulCurrentPos = HwPagedIORead( ES1371_DAC0CTL_PAGE, ES1371_wDAC0FC_OFF);
// the current frame count is in the upper WORD
ulCurrentPos >>= 16;
// multiply the DWORD count by 4 to get a BYTE count to return
ulCurrentPos *= 4;
break;
case ES1371_DAC1 :
// read the Frame register
ulCurrentPos = HwPagedIORead( ES1371_DAC1CTL_PAGE, ES1371_wDAC1FC_OFF);
// the current frame count is in the upper WORD
ulCurrentPos >>= 16;
// multiply the DWORD count by 4 to get a BYTE count to return
ulCurrentPos *= 4;
break;
case ES1371_ADC :
// read the Frame register
ulCurrentPos = HwPagedIORead( ES1371_ADCCTL_PAGE, ES1371_wADCFC_OFF);
// the current frame count is in the upper WORD
ulCurrentPos >>= 16;
// multiply the DWORD count by 4 to get a BYTE count to return
ulCurrentPos *= 4;
break;
}
return ulCurrentPos;
}
//--------------------------------------------------------------------------
//
// Name: GetInterruptSource
//
// Description: returns the source of the current interrupt
//
// Parameters: none
//
// Returns: UCHAR LONG current DMA position in bytes
//
//--------------------------------------------------------------------------
UCHAR
CES1371::GetInterruptSource( void )
{
ULONG intstat;
UCHAR intsrc;
intstat = READ_PORT_ULONG( (PULONG)(m_pPciAddr + ES1371_dSTATUS_OFF) );
// If we get all f's back we can't see the hardware
if ( 0xffffffff == intstat )
return ES1371_INT_NONE;
if ( !( ES1371_INTSTAT_PENDING & intstat ))
return ES1371_INT_NONE;
intsrc = (UCHAR)(intstat) & ES1371_INT_MASK;
return intsrc;
}
//--------------------------------------------------------------------------
//
// Name: AckDMAInterrupt
//
// Description: clean up a (set of) interrupt(s)
//
// Parameters: UCHAR ucIntSrc : a bit mask interrupts to ack
//
// Returns: none
//
//--------------------------------------------------------------------------
void
CES1371::AckDMAInterrupt( UCHAR ucIntSrc )
{
UCHAR ackmask = 0;
if ( ES1371_INT_ADC & ucIntSrc )
ackmask |= ES1371_SERCTL_ADCIE ;
if ( ES1371_INT_DAC0 & ucIntSrc )
ackmask |= ES1371_SERCTL_DAC0IE ;
if ( ES1371_INT_DAC1 & ucIntSrc )
ackmask |= ES1371_SERCTL_DAC1IE ;
// now ack the interrupts - first set the IEs to 0
HwRegRMW( ES1371_bSERCTL_OFF, ackmask, 0x00);
// then set the IEs back to 1
HwRegRMW( ES1371_bSERCTL_OFF, ackmask, ackmask);
}
//--------------------------------------------------------------------------
//
// Name: JoystickEnable
//
// Description: Enable or disable the joystick port IO range
//
// Parameters:
// ULONG ulIOPort : The starting IO address to use or 0 to disable
//
// Returns: none
//
//--------------------------------------------------------------------------
void
CES1371::JoystickEnable( ULONG ulIOPort )
{
UCHAR joyio = 0;
if ( ( 0x00000200 == ulIOPort ) ||
( 0x00000208 == ulIOPort ) ||
( 0x00000210 == ulIOPort ) ||
( 0x00000218 == ulIOPort ) )
{
// move the two useful bits to the correct position
joyio = UCHAR( ulIOPort >> 3 ) ;
// set the two bits that control the joystick io range
HwRegRMW( ES1371_bJOYCTL_OFF, 0x03, joyio );
// enable the joystick port
joyio = ES1371_DEVCTL_JSTICK_EN ;
HwRegRMW( ES1371_bDEVCTL_OFF, ES1371_DEVCTL_JSTICK_EN, joyio );
}
else // disable
{
// disable the joystick port
joyio = 0;
HwRegRMW( ES1371_bDEVCTL_OFF, ES1371_DEVCTL_JSTICK_EN, joyio );
}
}
/*****************************************************************************
* SynchronizedPagedIO()
*****************************************************************************
* Do paged IO syncronized with the ISR.
*/
NTSTATUS
SynchronizedPagedIO
(
IN PINTERRUPTSYNC InterruptSync,
IN PVOID syncIOContext
)
{
PSYNCIOCONTEXT context;
context = (PSYNCIOCONTEXT)syncIOContext;
ASSERT(context->pHardware);
ASSERT(context->ulPage);
ASSERT(context->ulIOAddress);
NTSTATUS ntStatus = STATUS_SUCCESS;
// write the page register if needed
if ( context->pHardware->m_ulDRegs[ES1371_bMEMPAGE_OFF/4] != context->ulPage )
{
WRITE_PORT_UCHAR(context->pHardware->m_pPciAddr + ES1371_bMEMPAGE_OFF,
UCHAR(context->ulPage) & 0x0f );
// save in the regs array
context->pHardware->m_ulDRegs[ES1371_bMEMPAGE_OFF/4] = context->ulPage;
}
// read or write the data
if ( context->fRead )
{
*(context->pulData) =
READ_PORT_ULONG(
PULONG(context->pHardware->m_pPciAddr + context->ulIOAddress) );
}
else // write
{
WRITE_PORT_ULONG(
PULONG(context->pHardware->m_pPciAddr + context->ulIOAddress),
*(context->pulData) );
}
return ntStatus;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -