📄 es1371.cpp
字号:
}
void
CES1371::SetDMAVolume(ULONG ulChannelIndex, USHORT usLeftVal, USHORT usRightVal)
{
switch(ulChannelIndex)
{
case ES1371_DAC0:
SRCRegWrite(SRC_DAC0_VOL_L, usLeftVal);
SRCRegWrite(SRC_DAC0_VOL_R, usRightVal);
break;
case ES1371_DAC1:
SRCRegWrite(SRC_DAC1_VOL_L, usLeftVal);
SRCRegWrite(SRC_DAC1_VOL_R, usRightVal);
break;
case ES1371_ADC:
SRCRegWrite(SRC_ADC_VOL_L, usLeftVal);
SRCRegWrite(SRC_ADC_VOL_R, usRightVal);
break;
}
}
//--------------------------------------------------------------------------
//
// Name: SetDMAChannelFormat
//
// Description: Set the Format of a particular DMA channel.
//
// Parameters: ULONG ulChannelIndex : Index of the DMA channel to init
// ULONG ulChannels : Number of audio channels 1=mono 2=stereo
// ULONG ulSampleSize : Sample size - 8bit or 16bit
// ULONG ulSampleRate : actual number of samples/second.
//
// Returns: none
//
// Note:
//
//--------------------------------------------------------------------------
void
CES1371::SetDMAChannelFormat( ULONG ulChannelIndex,
ULONG ulChannels,
ULONG ulSampleSize,
ULONG ulSampleRate )
{
UCHAR ucFormatBits;
UCHAR ucSkipCount;
// save off the info for power managment
m_dmachannel[ulChannelIndex].ulChannels = ulChannels;
m_dmachannel[ulChannelIndex].ulSampleSize = ulSampleSize;
m_dmachannel[ulChannelIndex].ulSampleRate = ulSampleRate;
// first set the new sample rate
SRCSetRate ( ulChannelIndex, (USHORT) ulSampleRate );
switch ( ulChannelIndex )
{
case ES1371_DAC0 :
// set format bits for DAC0 ...
ucFormatBits = 0x00;
if( 2 == ulChannels )
ucFormatBits |= ES1371_PCM_DAC0_STEREO ;
if( 16 == ulSampleSize )
ucFormatBits |= ES1371_PCM_DAC0_16BIT ;
HwRegRMW( ES1371_bSERFMT_OFF,
ES1371_PCM_DAC0_STEREO|ES1371_PCM_DAC0_16BIT,
ucFormatBits );
break;
case ES1371_DAC1 :
// set format bits for DAC1 ...
ucFormatBits = 0x00;
if( 2 == ulChannels )
ucFormatBits |= ES1371_PCM_DAC1_STEREO ;
if( 16 == ulSampleSize )
{
ucFormatBits |= ES1371_PCM_DAC1_16BIT ;
// set the SKIP register for proper playback
ucSkipCount = 0x10;
HwRegRMW( ES1371_bSKIPC_OFF, (UCHAR)0x18, ucSkipCount );
}
else
{ // set the SKIP register for proper playback
ucSkipCount = 0x08;
HwRegRMW( ES1371_bSKIPC_OFF, (UCHAR)0x18, ucSkipCount );
}
HwRegRMW( ES1371_bSERFMT_OFF,
ES1371_PCM_DAC1_STEREO|ES1371_PCM_DAC1_16BIT,
ucFormatBits );
break;
case ES1371_ADC :
// set format bits for ADC ...
ucFormatBits = 0x00;
if( 2 == ulChannels )
ucFormatBits |= ES1371_PCM_ADC_STEREO ;
if( 16 == ulSampleSize )
ucFormatBits |= ES1371_PCM_ADC_16BIT ;
HwRegRMW( ES1371_bSERFMT_OFF,
ES1371_PCM_ADC_STEREO|ES1371_PCM_ADC_16BIT,
ucFormatBits );
break;
}
}
//--------------------------------------------------------------------------
//
// Name: SetDMAChannelBuffer
//
// Description: Set the buffer sizes of a particular DMA channel.
//
// Parameters: ULONG ulChannelIndex : Index of the DMA channel to init
// ULONG ulBufferLength : Size in bytes of the whole DMA buffer
// ULONG ulSamplesPerInt : Count of samples before interrupting
//
// Returns: none
//
// Note:
//
//--------------------------------------------------------------------------
void
CES1371::SetDMAChannelBuffer( ULONG ulChannelIndex,
ULONG ulBufferLength,
ULONG ulSamplesPerInt )
{
ULONG ulDesiredBufferSize = m_dmachannel[ulChannelIndex].ulBufferSize;
USHORT usInterruptCount = (USHORT) (ulSamplesPerInt - 1);
m_dmachannel[ulChannelIndex].ulBufferLength = ulBufferLength;
m_dmachannel[ulChannelIndex].ulSamplesPerInt = ulSamplesPerInt;
// buffer can't be bigger than half the physical buffer
// convert to dwords and subtract one to get register value
ulDesiredBufferSize = MIN( ulDesiredBufferSize, ulBufferLength )/4 - 1;
ULONG ulPrevCount;
switch ( ulChannelIndex )
{
case ES1371_DAC0 :
// set the DAC0 DWORD frame count
ulPrevCount = HwPagedIORead( ES1371_DAC0CTL_PAGE, ES1371_wDAC0FC_OFF);
HwPagedIOWrite( ES1371_DAC0CTL_PAGE,
ES1371_wDAC0FC_OFF,
(ulPrevCount & 0xffff0000) | (ulDesiredBufferSize & 0x0000ffff) );
// Write DAC0 interrupt count - sample frames per half-buffer (n-1).
HwRegRMW( ES1371_wDAC0IC_OFF, 0xffff, usInterruptCount );
break;
case ES1371_DAC1 :
// set the DAC1 DWORD frame count
ulPrevCount = HwPagedIORead( ES1371_DAC1CTL_PAGE, ES1371_wDAC1FC_OFF);
HwPagedIOWrite( ES1371_DAC1CTL_PAGE,
ES1371_wDAC1FC_OFF,
(ulPrevCount & 0xffff0000) | (ulDesiredBufferSize & 0x0000ffff) );
// Write DAC1 interrupt count - sample frames per half-buffer (n-1).
HwRegRMW( ES1371_wDAC1IC_OFF, 0xffff, usInterruptCount );
break;
case ES1371_ADC :
ulPrevCount = HwPagedIORead( ES1371_ADCCTL_PAGE, ES1371_wADCFC_OFF);
// set the ADC DWORD frame count
HwPagedIOWrite( ES1371_ADCCTL_PAGE,
ES1371_wADCFC_OFF,
(ulPrevCount & 0xffff0000) | (ulDesiredBufferSize & 0x0000ffff) );
// Write ADC interrupt count - sample frames per half-buffer (n-1).
HwRegRMW( ES1371_wADCIC_OFF, 0xffff, usInterruptCount );
break;
}
}
//--------------------------------------------------------------------------
//
// Name: StartDMAChannel
//
// Description: Start a particular DMA channel running.
//
// Parameters: ULONG ulChannelIndex : Index of the DMA channel to start
//
// Returns: none
//
// Note:
//
//--------------------------------------------------------------------------
void
CES1371::StartDMAChannel( ULONG ulChannelIndex )
{
UCHAR ucIOVal;
switch ( ulChannelIndex )
{
case ES1371_DAC0 :
if ( DMA_PAUSED == m_dmachannel[ulChannelIndex].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[ulChannelIndex].ulDMAChannelState = DMA_RUNNING;
break;
case ES1371_DAC1 :
if ( DMA_PAUSED == m_dmachannel[ulChannelIndex].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[ulChannelIndex].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[ulChannelIndex].ulDMAChannelState = DMA_RUNNING;
break;
}
return;
}
//--------------------------------------------------------------------------
//
// Name: StopDMAChannel
//
// Description: Stop a particular DMA channel.
//
// Parameters: ULONG ulChannelIndex : Index of the DMA channel to stop
//
// Returns: none
//
// Note:
//
//--------------------------------------------------------------------------
void
CES1371::StopDMAChannel( ULONG ulChannelIndex )
{
UCHAR ucIOVal;
switch ( ulChannelIndex )
{
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[ulChannelIndex].ulDMAChannelState )
{
// modify pause bit for DAC0
ucIOVal = 0;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_DAC0PAUSE, ucIOVal );
}
// save the state
m_dmachannel[ulChannelIndex].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[ulChannelIndex].ulDMAChannelState )
{
// modify pause bit for DAC0
ucIOVal = 0;
HwRegRMW( ES1371_bSERCTL_OFF,
ES1371_SERCTL_DAC1PAUSE, ucIOVal );
}
// save the state
m_dmachannel[ulChannelIndex].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);
// save the state
m_dmachannel[ulChannelIndex].ulDMAChannelState = DMA_STOPPED;
break;
}
}
//--------------------------------------------------------------------------
//
// Name: PauseDMAChannel
//
// Description: Pause a particular DMA channel.
//
// Parameters: ULONG ulChannelIndex : Index of the DMA channel to pause
//
// Returns: none
//
// Note:
//
//--------------------------------------------------------------------------
void
CES1371::PauseDMAChannel( ULONG ulChannelIndex )
{
UCHAR ucIOVal;
switch ( ulChannelIndex )
{
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[ulChannelIndex].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[ulChannelIndex].ulDMAChannelState = DMA_PAUSED;
break;
case ES1371_ADC :
break;
}
}
//--------------------------------------------------------------------------
//
// Name: GetDMAPosition
//
// Description: reads the current position of a DMA channel.
//
// Parameters: ULONG ulChannelIndex : 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( ULONG ulChannelIndex )
{
ULONG ulCurrentPos = 0;
switch ( ulChannelIndex )
{
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -