📄 i2saudio.cpp
字号:
// *SAI_TX0_LEFT = 0;
// *SAI_TX0_RIGHT = 0;
// }
// DelayuS(160);
*SAI_TX0_EN = 1;
break;
case 1:
// for(i = 0; i<8 ;i++)
// {
// *SAI_TX1_LEFT = 0;
// *SAI_TX1_RIGHT = 0;
// *SAI_TX1_EN = 1;
// }
// DelayuS(160);
*SAI_TX1_EN = 1;
break;
case 2:
// for(i = 0; i<8 ;i++)
// {
// *SAI_TX2_LEFT = 0;
// *SAI_TX2_RIGHT = 0;
// *SAI_TX2_EN = 1;
// }
// DelayuS(160);
*SAI_TX2_EN = 1;
break;
}
return (MMSYSERR_NOERROR);
}
//****************************************************************************
// I2SCodec::StartRecord
//****************************************************************************
//
//
//
MMRESULT I2SCodec::StartRecord(ULONG ulChannel)
{
//if(!m_bPlaybackOpened)
//{
// *SAI_GCR = GCR_PCLK;
//}
switch(ulChannel)
{
case 0:
*SAI_RX0_EN = 1;
break;
case 1:
*SAI_RX1_EN = 1;
break;
case 2:
*SAI_RX2_EN = 1;
break;
}
return (MMSYSERR_NOERROR);
}
//****************************************************************************
// I2SCodec::StopPlayBack
//****************************************************************************
//
//
//
MMRESULT I2SCodec::StopPlayback(ULONG ulChannel)
{
switch(ulChannel)
{
case 0:
*SAI_TX0_EN = 0;
break;
case 1:
*SAI_TX1_EN = 0;
break;
case 2:
*SAI_TX2_EN = 0;
break;
}
return (MMSYSERR_NOERROR);
}
//****************************************************************************
// I2SCodec::StopRecord
//****************************************************************************
//
//
//
MMRESULT I2SCodec::StopRecord(ULONG ulChannel)
{
switch(ulChannel)
{
case 0:
*SAI_RX0_EN = 0;
break;
case 1:
*SAI_RX1_EN = 0;
break;
case 2:
*SAI_RX2_EN = 0;
break;
}
return (MMSYSERR_NOERROR);
}
//****************************************************************************
// I2SCodec::SetVolume
//****************************************************************************
//
//
//
MMRESULT I2SCodec::SetVolume
(
ULONG ulRightVolume,
ULONG ulLeftVolume,
ULONG ulChannel
)
{
UCHAR ucRightDacVolume, ucLeftDacVolume;
// ULONG ulRightDacVolume, ulLeftDacVolume;
UCHAR ulRightDacReg, ulLeftDacReg;
int iMaxVolumeVal=0;
//
// If We are not using i2s volume control just return.
//
if(!m_bUseI2SVolumeControl)
{
RETAILMSG(1,(L"+I2S::SetVolume: disbaled\r\n"));
return(MMSYSERR_NOERROR);
}
//RETAILMSG(1,(L"+I2S::SetVolume: = 0x%08x 0x%08x\r\n", ulRightVolume, ulLeftVolume));
m_VolumeSettings.dwMasterVolume= ulRightVolume<<16 | ulLeftVolume;
if(m_ulCodec == 4228)
{
iMaxVolumeVal=181;
ulRightDacReg = CS4228_DAC1_VOL;
ulLeftDacReg = CS4228_DAC2_VOL;
}
else
{
//iMaxVolumeVal=127;
iMaxVolumeVal=60;
ulRightDacReg = CS4271_DACA_VOL;
ulLeftDacReg = CS4271_DACB_VOL;
}
//
// Calculate the left and right volume.
//
ucRightDacVolume =(UCHAR) ( iMaxVolumeVal - ( ( iMaxVolumeVal * ( ulRightVolume)) / 0xFFFF ) )>>1;
ucLeftDacVolume =(UCHAR) ( iMaxVolumeVal - ( ( iMaxVolumeVal * ( ulLeftVolume)) / 0xFFFF ) )>>1;
//
// Write the codec registers.
//
EnterCriticalSection( &m_CriticalSection);
if( !m_bTwoWire )
SetSPIToI2S(m_ulCodec);
WriteCodecReg(ulRightDacReg, ucRightDacVolume);
WriteCodecReg(ulLeftDacReg, ucLeftDacVolume);
if( !m_bTwoWire )
SetSPIToPS2(m_ulCodec);
LeaveCriticalSection( &m_CriticalSection);
return (MMSYSERR_NOERROR);
}
//****************************************************************************
// I2SCodec::GetDmaPort
//****************************************************************************
// Returns the port type to the dma engine.
//
//
ULONG I2SCodec::GetDmaPort(void)
{
return PRALLOC_I2S1;
}
//****************************************************************************
// I2SCodec::WriteCodecReg
//****************************************************************************
// ucRegAddr - CS4228 Register Address.
// usRegValue - CS4228 Register Value.
//
MMRESULT I2SCodec::WriteCodecRegNOSPI(UCHAR ucRegAddr, UCHAR ucRegValue)
{
#ifdef CS4288_TWO_READ_MODE
ULONG uiVal, uiDDR;
unsigned char ucData, ucIdx, ucBit;
ULONG ulTimeout;
FUNC_I2S
(
(
L"WriteCodecReg: Reg = 0x%02x, Value = 0x%02x\n",
ucRegAddr,
ucRegValue
)
);
//
// Read the current value of the GPIO data and data direction registers.
//
uiVal = *GPIO_PGDR;
uiDDR = *GPIO_PGDDR;
//
// If the GPIO pins have not been configured since reset, the data
// and clock lines will be set as inputs and with data value of 0.
// External pullup resisters are pulling them high.
// Set them both high before configuring them as outputs.
//
uiVal |= (GPIOG_EEDAT | GPIOG_EECLK);
*GPIO_PGDR = uiVal;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Configure the EE data and clock lines as outputs.
//
uiDDR |= (GPIOG_EEDAT | GPIOG_EECLK);
*GPIO_PGDDR = uiDDR;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Drive the EE data line low. Since the EE clock line is currently
// high, this is the start condition.
//
uiVal &= ~GPIOG_EEDAT;
*GPIO_PGDR = uiVal;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Drive the EE clock line low.
//
uiVal &= ~GPIOG_EECLK;
*GPIO_PGDR = uiVal;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Loop through the three bytes which we will send.
//
for(ucIdx = 0; ucIdx < 3; ucIdx++)
{
//
// Get the appropriate byte based on the current loop iteration.
//
if(ucIdx == 0)
{
//
// Since this is a write operation, we set d0 of the address
// which is the r/w bit.
//
ucData = (UCHAR)CS4228_DEV_ADDRESS;
}
else if(ucIdx == 1)
{
ucData = ucRegAddr;
}
else
{
ucData = ucRegValue;
}
//
// Loop through the 8 bits in this byte.
//
for(ucBit = 0; ucBit < 8; ucBit++)
{
//
// Set the EE data line to correspond to the most significant bit
// of the data byte.
//
if(ucData & 0x80)
{
uiVal |= GPIOG_EEDAT;
}
else
{
uiVal &= ~GPIOG_EEDAT;
}
*GPIO_PGDR = uiVal;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Drive the EE clock line high.
//
*GPIO_PGDR = uiVal | GPIOG_EECLK;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Drive the EE clock line low.
//
*GPIO_PGDR = uiVal;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Shift the data byte to the left by one bit.
//
ucData <<= 1;
}
//
// We've sent the eight bits in this data byte, so we need to wait for
// the acknowledge from the target. Reconfigure the EE data line as
// an input so we can read the acknowledge from the device.
//
uiDDR &= ~GPIOG_EEDAT;
*GPIO_PGDDR = uiDDR;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Drive the EE clock line high.
//
*GPIO_PGDR = uiVal | GPIOG_EECLK;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Wait until the EE data line is pulled low by the target device.
//
ulTimeout = 0;
while(*GPIO_PGDR & GPIOG_EEDAT)
{
DelayuS( EE_DELAY_USEC );
ulTimeout++;
if(ulTimeout > EE_READ_TIMEOUT )
{
ERRMSG
((
L"I2SCodec::WriteCodecReg Write timeout on register 0x%02x\r\n",
(ULONG)ucRegAddr
));
return (MMSYSERR_HANDLEBUSY);
}
}
//
// Drive the EE clock line low.
//
*GPIO_PGDR = uiVal;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Reconfigure the EE data line as an output.
//
uiDDR |= GPIOG_EEDAT;
*GPIO_PGDDR = uiDDR;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
}
//
// Drive the EE data line low.
//
uiVal &= ~GPIOG_EEDAT;
*GPIO_PGDR = uiVal;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Drive the EE clock line high.
//
uiVal |= GPIOG_EECLK;
*GPIO_PGDR = uiVal;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Drive the EE data line high. Since the EE clock line is currently
// high, this is the stop condition.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -