Hi,
I am currently using Gauss DSP C6657 I2C connected to TLV320AIC device. I appreciate if you can provide me a closest set of programs (I2C driver with Audio codec driver). Initiailization, some sample application like sinusoid or any other example with MCBSP.
Our current hardware is:
AIC - I2C - Gauss C6657 (control)
- MCBSP - Gauss C6657 (TDM)
is ususal design everyone follows. Appreciate whatever you can provide to start with.
With the below code, I tried to read default register values. But I fail to read correctly.
The read progam:
REG_DEF codec_default[] = {
{ CTRL1_REG, FALSE, 0x00 }, /* first read to clear ovf bits */
{ CTRL2_REG, TRUE, 0x20 },
{ CTRL3_REG, TRUE, 0x01 },
{ CTRL4_REG, FALSE, 0x30 }, /* first read gets N and P values */
{ CTRL4_REG, FALSE, 0x90 }, /* second read gets M value */
{ CTRL5A_REG, FALSE, 0x2a },
{ CTRL5B_REG, FALSE, 0x6a },
{ CTRL5C_REG, FALSE, 0xb8 },
{ CTRL5D_REG, FALSE, 0xc1 },
{ CTRL6_REG, TRUE, 0x00 },
{ 0xff, FALSE, 0x00 }
};
for(sptr = codec_default; sptr->reg != 0xff; sptr++){
if(READ(sptr->reg, &sys_data) != OK)
{
return(ERROR);
}
if(sptr->mask == FALSE)
continue;
if(sptr->value != sys_data){
printf("Failed: register %02x was %02x expected %02x\n",
sptr->reg, sys_data, sptr->value);
return(ERROR);
}
}
/******************************************************************************
*
* Function: bakeri2cWriteBlock
*
* Description: Enters master transmitter mode, writes a specified number
* of bytes.
*
* Parameters: uint8_t uchEepromI2cAddress - i2c address of EEPROM
* uint32_t *puiData - pointer to the buffer base address
* uint32_t uiNumBytes - number of bytes of buffer
* uint32_t uiEndBusState - The state on which bus should be left
*
* Return Value: I2C_RET - status
*
******************************************************************************/
I2C_RET bakeri2cWriteBlock( uint8_t uchEepromI2cAddress, uint8_t *puiData,
uint32_t uiNumBytes, uint32_t uiEndBusState)
{
uint32_t uiTimeoutCounter;
uint32_t uiPollingStatus;
uint32_t uiValue;
uint32_t uiStatusReg;
uint32_t uiCount;
uint32_t uiByteType;
/* Check for the bus busy signal */
uiTimeoutCounter = 0;
do
{
uiPollingStatus = I2C_REG_STR_FIELD_BB(I2CR->ICSTR);
if (uiPollingStatus)
{
bakerI2CDelay (I2C_MASTER_TRANSMITTER_BUS_ACCESS_DELAY_US);
uiTimeoutCounter += 1;
if (uiTimeoutCounter >= I2C_MAX_MASTER_TRANSMITTER_BUS_ACCESS_TIMEOUT)
{
/* Return to slave receiver, clear nack and bus busy */
I2CR->ICMDR = I2C_VAL_REG_MDR_SLVRCV;
I2CR->ICSTR = I2C_VAL_REG_STR_ON_FAIL;
//platform_errno = PLATFORM_ERRNO_DEV_TIMEOUT;
return (I2C_RET_IDLE_TIMEOUT);
}
}
else
{
/* The bus is free */
uiTimeoutCounter = 0;
}
}while (uiTimeoutCounter != 0);
/* Enter master transmitter mode, set the slave address register */
I2CR->ICMDR = I2C_VAL_REG_MDR_MSTXMT;
I2CR->ICSAR = (uint8_t)uchEepromI2cAddress;
bakerI2CDelay (DELAY_CONST);
/* Put the first byte into the transmit register, set the start bit */
//uiValue = (*puiData >> 8) & 0x00ff;
uiValue = (uint32_t) ((*puiData++) & 0xFF);
I2CR->ICDXR = uiValue;
uiByteType = I2C_BYTE_LSB;
/* Set the start bit */
I2CR->ICMDR = I2C_VAL_REG_MDR_MSTXMTSTRT;
for (uiCount = 1; uiCount < uiNumBytes; uiCount++)
{
uiTimeoutCounter = 0;
do
{
/* Read status */
uiStatusReg = I2CR->ICSTR;
/* On Nack return failure */
if (I2C_REG_STR_FIELD_NACK(uiStatusReg))
{
/* Return to slave receiver, clear nack and bus busy */
I2CR->ICMDR = I2C_VAL_REG_MDR_SLVRCV;
I2CR->ICSTR = I2C_VAL_REG_STR_ON_FAIL;
//platform_errno = PLATFORM_ERRNO_DEV_NAK;
return (I2C_RET_NO_ACK);
}
/* Check for transmit ready */
if (I2C_REG_STR_FIELD_XRDY(uiStatusReg))
{
uiTimeoutCounter = 0;
if (uiByteType == I2C_BYTE_MSB)
{
//uiValue = (*puiData >> 24) & 0x00ff;
uiValue = (uint32_t) ((*puiData++) & 0xFF);
uiByteType = I2C_BYTE_SMSB;
}
else if (uiByteType == I2C_BYTE_SMSB)
{
//uiValue = (*puiData >> 16) & 0x00ff;
uiValue = (uint32_t) ((*puiData++) & 0xFF);
uiByteType = I2C_BYTE_SLSB;
}
else if (uiByteType == I2C_BYTE_SLSB)
{
//uiValue = (*puiData >> 8) & 0x00ff;
uiValue = (uint32_t) ((*puiData++) & 0xFF);
uiByteType = I2C_BYTE_LSB;
}
else
{
//uiValue = (*puiData) & 0x00ff;
uiValue = (uint32_t) ((*puiData++) & 0xFF);
uiByteType = I2C_BYTE_MSB;
//puiData += 1;
}
/*Write data Transmit Data Register */
I2CR->ICDXR = uiValue;
}
else
{
/* XRDY bit not set */
bakerI2CDelay (DELAY_CONST);
uiTimeoutCounter += 1;
if (uiTimeoutCounter >= I2C_MAX_MASTER_TRANSMITTER_TIMEOUT)
{
/* Return to slave receiver, clear nack and bus busy */
I2CR->ICMDR = I2C_VAL_REG_MDR_SLVRCV;
I2CR->ICSTR = I2C_VAL_REG_STR_ON_FAIL;
//platform_errno = PLATFORM_ERRNO_DEV_TIMEOUT;
return (I2C_RET_IDLE_TIMEOUT);
}
}
}while (uiTimeoutCounter != 0);
} /* end for loop */
/* If releasing the bus, send a stop bit */
if (uiEndBusState == I2C_RELEASE_BUS)
{
/* Wait for the ardy bit to go high */
uiTimeoutCounter = 0;
do
{
uiStatusReg = I2CR->ICSTR;
if (I2C_REG_STR_FIELD_ARDY(uiStatusReg))
{
I2CR->ICMDR = I2C_VAL_REG_MDR_MSTXMTSTOP;
I2CR->ICSTR = I2C_VAL_REG_STR_CLR_BUSY;
bakerI2CDelay (DELAY_CONST);
uiTimeoutCounter = 0;
}
else
{
/* Registers not ready for access */
uiTimeoutCounter += 1;
if (uiTimeoutCounter >= I2C_MAX_MASTER_TRANSMITTER_ARDY_TIMEOUT)
{
/* On timeout put the peripheral into reset, wait, then
* take it out of reset */
I2CR->ICMDR = I2C_VAL_REG_MDR_RESET;
bakerI2CDelay (DELAY_CONST);
I2CR->ICMDR = I2C_VAL_REG_MDR_SLVRCV;
//platform_errno = PLATFORM_ERRNO_DEV_TIMEOUT;
return (I2C_RET_IDLE_TIMEOUT);
}
bakerI2CDelay (DELAY_CONST);
}
}while (uiTimeoutCounter != 0);
} /* end bus release */
return (I2C_RET_OK);
} // bakeri2cWriteBlock
/******************************************************************************
*
* Function: bakeri2cRead
*
* Description: Reads a fixed number of bytes from an I2C prom. The read
* consists of a master write of 2 bytes (forming a 16 bit address,
* msb transmitted first), followed by a master read of the
* input number of bytes.The bytes that are read are placed
* in puiData in big endian format
*
* Parameters: uint8_t uchEepromI2cAddress - i2c address of EEPROM
* uint32_t *puiData - pointer to the buffer base address
* uint32_t uiNumBytes - number of bytes of buffer
* uint32_t uiEndBusState - The state on which bus should be left
*
* Return Value: I2C_RET - status
*
******************************************************************************/
I2C_RET bakeri2cRead ( uint8_t uchEepromI2cAddress, uint8_t *puiData, uint32_t uiNumBytes)
{
uint32_t uiStatusReg;
uint32_t uiTimeoutCounter;
uint32_t iCount;
I2C_RET uiReturnValue;
uint16_t ushValue;
#if 0
/* Write the byte address to the eeprom. Do not send a stop */
uiReturnValue = i2cEepromWriteBlock ( uchEepromI2cAddress, &byte_addr, 2, I2C_DO_NOT_RELEASE_BUS);
if (uiReturnValue != I2C_RET_OK)
return (uiReturnValue);
/* Give the I2C prom 10ms to process the read command */
bakerI2CDelay (DELAY_CONST);
#endif
/* Set the start bit, begin the master read */
I2CR->ICMDR = I2C_VAL_REG_MDR_MSTRCV;
for (iCount = 0; iCount < uiNumBytes; iCount++)
{
uiTimeoutCounter = 0;
do
{
/* Read status */
uiStatusReg = I2CR->ICSTR;
/* On Nack return failure */
if (I2C_REG_STR_FIELD_NACK(uiStatusReg))
{
/* Return to slave receiver, clear nack and bus busy */
I2CR->ICMDR = I2C_VAL_REG_MDR_SLVRCV;
I2CR->ICSTR = I2C_VAL_REG_STR_ON_FAIL;
//platform_errno = PLATFORM_ERRNO_DEV_NAK;
return (I2C_RET_NO_ACK);
}
/* Check for receive byte ready */
if (I2C_REG_STR_FIELD_RRDY(uiStatusReg))
{
ushValue = I2CR->ICDRR & 0x00ff;
uiTimeoutCounter = 0;
*puiData = (uint8_t) ushValue;
puiData++;
}
else
{ /* RRDY bit not set */
bakerI2CDelay (DELAY_CONST);
uiTimeoutCounter += 1;
if (uiTimeoutCounter >= I2C_MAX_MASTER_RECEIVE_TIMEOUT) {
/* Return to slave receiver, clear nack and bus busy */
I2CR->ICMDR = I2C_VAL_REG_MDR_SLVRCV;
I2CR->ICSTR = I2C_VAL_REG_STR_ON_FAIL;
//platform_errno = PLATFORM_ERRNO_DEV_TIMEOUT;
return (I2C_RET_IDLE_TIMEOUT);
}
}
} while (uiTimeoutCounter != 0);
} /* end for loop */
/* The data block has been read. Send the stop bit */
I2CR->ICMDR = I2C_VAL_REG_MDR_MSTRCVSTOP;
/* Wait for the rrdy and read the dummy byte */
uiTimeoutCounter = 0;
do
{
uiStatusReg = I2CR->ICSTR;
/* Check for receive byte ready */
if (I2C_REG_STR_FIELD_RRDY(uiStatusReg))
{
ushValue = I2CR->ICDRR & 0x00ff;
uiTimeoutCounter = 0;
}
else
{ /* rrdy not set */
bakerI2CDelay (DELAY_CONST);
uiTimeoutCounter += 1;
if (uiTimeoutCounter >= I2C_MAX_MASTER_RECEIVE_TIMEOUT)
{
/* Return to slave receiver, clear nack and bus busy */
I2CR->ICMDR = I2C_VAL_REG_MDR_SLVRCV;
I2CR->ICSTR = I2C_VAL_REG_STR_ON_FAIL;
//platform_errno = PLATFORM_ERRNO_DEV_TIMEOUT;
return (I2C_RET_IDLE_TIMEOUT);
}
}
}while (uiTimeoutCounter != 0);
return (I2C_RET_OK);
} // bakeri2cRead
int audiocodec_readRegister(uint8_t in_reg_addr, uint8_t *dest_buffer)
{
uint32_t uiReturnValue;
// write the register address that we want to read.
uiReturnValue = bakeri2cWriteBlock(CODEC_I2C_ADR, &in_reg_addr, 1, I2C_DO_NOT_RELEASE_BUS);
if (uiReturnValue != I2C_RET_OK)
return (-1);
// clock out the register data.
uiReturnValue = bakeri2cRead(CODEC_I2C_ADR, dest_buffer, 1);
if (uiReturnValue != I2C_RET_OK)
return (-1);
return (0);
}
int audiocodec_writeRegister(uint8_t in_reg_addr, uint8_t in_data)
{
uint32_t uiReturnValue;
uint8_t i2c_data[2];
i2c_data[0] = in_reg_addr;
i2c_data[1] = in_data;
// write the register that we want to read.
uiReturnValue = bakeri2cWriteBlock(CODEC_I2C_ADR, i2c_data, 2, I2C_RELEASE_BUS);
if (uiReturnValue != I2C_RET_OK)
return (-1);
return (0);
}