📄 i2saudio.cpp
字号:
//
uiVal |= GPIOG_EEDAT;
*GPIO_PGDR = uiVal;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
#endif
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;
*GPIO_PGDR = uiVal;
//
// 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 repeated start condition.
//
uiVal &= ~GPIOG_EEDAT;
*GPIO_PGDR = uiVal;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Drive the EE clock low.
//
uiVal &= ~GPIOG_EECLK;
*GPIO_PGDR = uiVal;
//
// Re-send the address. Loop through the 8 bits in this byte.
//
ucData = (UCHAR)(CS4228_DEV_ADDRESS | 1);
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 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);
}
}
//
// 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 );
//
// Now read the value from the target. Loop through the 8 bits in the
// byte.
//
ucData = 0;
for(ucBit = 0; ucBit < 8; ucBit++)
{
//
// Drive the EE clock line high.
//
*GPIO_PGDR = uiVal | GPIOG_EECLK;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Read this bit from the target.
//
if(*GPIO_PGDR & GPIOG_EEDAT)
{
ucData = (UCHAR)( ucData | (1 << (7 - ucBit)) );
}
//
// 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.
//
uiVal |= GPIOG_EEDAT;
*GPIO_PGDR = uiVal;
//
// Delay to meet the EE Interface timing specification.
//
DelayuS( EE_DELAY_USEC );
//
// Return the byte that we read.
//
*pucRegValue = ucData;
FUNC_I2S
(
(
L"ReadCodecReg: Reg = 0x%02x, Value = 0x%02x\n",
(ULONG)ucRegAddr,
(ULONG)ucData
)
);
return (MMSYSERR_NOERROR);
}
static volatile ULONG ulJunk;
//****************************************************************************
// I2SCodec::ProducePIOTone
//****************************************************************************
// For Debug only.
//
// Uses I2S to produce a PIO tone.
//
//
void I2SCodec::ProducePIOTone(void)
{
ULONG ulCount;
ULONG ulCount2;
volatile ULONG ulTemp;
//volatile ULONG ulCSR;
ULONG ulMax= 0x0007Fffff, ulMin=0x00800000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -