📄 i2saudio.cpp
字号:
ULONG ulRightVolume,
ULONG ulLeftVolume,
ULONG ulChannel
)
{
char cRightDacVolume, cLeftDacVolume;
if(m_bTwoWire)
{
cRightDacVolume = CHAR(ulRightVolume>>26) - (CHAR)51;
cLeftDacVolume = CHAR(ulLeftVolume>>26) - (CHAR)51;
//
// Write the codec registers.
//
EnterCriticalSection( &m_CriticalSection);
WriteCodecReg(CS4228_DAC1_VOL, cRightDacVolume);
WriteCodecReg(CS4228_DAC2_VOL, cLeftDacVolume);
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::WriteCodecReg(UCHAR ucRegAddr, UCHAR ucRegValue)
{
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.
//
uiVal |= GPIOG_EEDAT;
*GPIO_PGDR = uiVal;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
return (MMSYSERR_NOERROR);
}
//****************************************************************************
// I2SCodec::ReadCodecReg
//****************************************************************************
// ucRegAddr - CS4228 Register Address.
// pucRegValue - CS4228 Register Value.
//
MMRESULT I2SCodec::ReadCodecReg(UCHAR ucRegAddr, PUCHAR pucRegValue)
{
ULONG ulTimeout;
unsigned int uiVal, uiDDR;
unsigned char ucData, ucIdx, ucBit;
//
// 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;
//
// Configure the EE data and clock lines as outputs.
//
uiDDR |= (GPIOG_EEDAT | GPIOG_EECLK);
*GPIO_PGDDR = uiDDR;
//
// 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;
//
// Loop through the two bytes which we will send.
//
for(ucIdx = 0; ucIdx < 2; ucIdx++)
{
//
// Get the appropriate byte based on the current loop iteration.
//
if(ucIdx == 0)
{
ucData = CS4228_DEV_ADDRESS;
}
else
{
ucData = ucRegAddr;
}
//
// 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;
//
// Drive the EE clock line high.
//
*GPIO_PGDR = uiVal | GPIOG_EECLK;
//
// Wait a little bit for the EEDAT line to be pulled high.
//
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::ReadCodecReg Read timeout on register 0x%02x\r\n",
(ULONG)ucRegAddr
));
return (MMSYSERR_HANDLEBUSY);
}
}
//
// Drive the EE clock line low.
//
*GPIO_PGDR = uiVal;
//
// Reconfigure the EE data line as an output.
//
uiDDR |= GPIOG_EEDAT;
*GPIO_PGDDR = uiDDR;
}
//
// Drive the EE data line high.
//
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -