This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TLV320AIC12K with I2C driver

Other Parts Discussed in Thread: TLV320AIC12K

Hi,

  I am looking for a I2C driver for audio codec TLV320AIC12K, written on any TI DSP (or c6657 DSP). 

Regards,

Hari

  • Hi, Hari,

    Sorry we missed your post. Did you find the driver you were looking for?

    -d2

  • Hi D2 (Don, Dapkus),

       Thanks for responding to my query. Yes I am still looking for such a program. 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. 

    Also I tried to derive a code. I tried to read default register values. 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);

    }

  • I have now the default registers reads successful. 

    Is there any Eval program for this AIC device? or similar AIC device on C6xxx DSP?