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.

TLV320AIC3106: Write to registers at runtime

Part Number: TLV320AIC3106
Other Parts Discussed in Thread: TMS320C6748, OMAP-L138, REG102

Hello,

I have a question related to this other thread I opened:

https://e2e.ti.com/support/audio-group/audio/f/audio-forum/1031331/tmdslcdk6748-pop-noises-on-example-usb_devaudio_lcdkomapl138_c674x

I am using the USB audio example to implement our audio processing algorithm, but first i have to get rid of the pop noises in the example. The pop noises are caused because of a bad synchronization between the usb clock and the codec clock

I am trying to implement a function similar to SysCtlI2SMClkAdjust(int iMClkAdjust) which is mentioned in the thread. However, the function uses deprecated macros and defines which don't exist anymore in the drivers.

My idea is to search for the current values of the PLL inside the codec and slightly change them in each USB callback iteration similar to the description of the SysCtlI2SMClkAdjust function. But I'm trying to do it with the i2c implemented functions of the codec (like CodecRecWrite or CodecRegRead and I'm not sure if this is the right way to do it. Could you give me some tips on the issue?

Thanks in advance,

jpom

  • Hi,

    In the datasheet section 10.3.2 onwards talks about how to generate the audio interface from clock to the different audio format.

    https://www.ti.com/lit/ds/symlink/tlv320aic3106.pdf?ts=1632170828749&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FTLV320AIC3106

    It's good to understand how the clocks are generated and there's also an excel sheet that calculate the clock and setting for you below.

    Once you understand that, you can read or write the respective register setting using the register map in section 10:6.

    This is standard I2C interface and if you want there are examples as well on how the IC is configured in the following user guide:

    https://www.ti.com/lit/ug/slau855/slau855.pdf?ts=1632171100734&ref_url=https%253A%252F%252Fwww.ti.com%252Fproduct%252FTLV320AIC3106

    Regards.

  • Hello,

    Thanks for the answer. The excel is really useful.

    I already read the clock generation part, I understand I have to slghtly modify the PLL values (J,D,P, R) in order to change the sampling rate. My issue comes with the I2C communicaton with the codec. The I2C is already initialized and opened in the function I2CCodecIfInit:

    void I2CCodecIfInit(unsigned int baseAddr, unsigned int intCh,
    unsigned int slaveAddr)
    {
    I2C_Params i2cParams;
    I2C_HwAttrs mcasp_i2c_cfg;
    I2C_slaveAddr =(uint32_t)slaveAddr;
    I2C_init();

    I2C_Params_init(&i2cParams);
    i2cParams.transferMode = I2C_MODE_BLOCKING;

    I2C_socGetInitCfg(I2C_MCASP_INSTANCE, &mcasp_i2c_cfg);

    /* Modify the default I2C configurations if necessary */
    mcasp_i2c_cfg.enableIntr=false;
    /* Set the default I2C init configurations */
    I2C_socSetInitCfg(I2C_MCASP_INSTANCE, &mcasp_i2c_cfg);
    I2C_handle_glob = I2C_open(I2C_MCASP_INSTANCE, &i2cParams);
    }

    Once the I2C communication is opened I understand I can use the I2C functions to send and read data from the registers. Here is what I can't undersand, can I call these I2C functions from the USB callback? The idea is on each callback, read the actual value of J,D,P,R and slightly change the sampling rate value, then writting these registers again.

    I see that, reading the register 102, for instance, I get the reset value from it (0x02) instead of the written value (0x08), so supposedly I can't read the actual values for J,D,R,P... This is what I don't get. 

    Thanks for your tme

    jp

  • Hi,

    As there are several pages of register, you would want to specify which page the transactions are for.

    I have attached an example of the transaction when writing a value 5 to "J" in register 6 of page 0.

    You can probe your I2C lines and check the transaction like the attached.

    I2C Example.pptx

    Regards.

  • Hi,

    As there are several pages of register for this device, you would want to specify the page # follows by the register itself.

    I have attached an example of the transaction when writing a value 5 to J below.

    0257.I2C Example.pptx

    Give a try and probe the I2C lines to ensure the format and transactions are correct.

    Regards.

  • Hello,

    Thanks again for the answer. I tried selecting the page right before reading the register but still the read value is not correct.

    By the way, in my codec (aic3106) register 6 is for the D value , not J.

    I think the issue may be somewhere else.

    Kind regards,

    jp

  • Hi,

    Change the register accordingly as what I have provided is an example of the I2C transaction.

    You want to see the I2C signals with a scope/analyzer like Saleae and ensure the format is correct and device ACK the transaction like what I have provided above. From there then you can tell if the transaction is successful or not.

    Regards.

  • Hello,

    Thanks for your answer. I tried to read the signal but i can't see anything in the oscilloscope. I'm using the same function to write/read in the registers as provided in the example (CodecRegWrite or CodecRegRead) which uses the I2C library to do the transactions. I still think the problem is where I am calling these functions, the I2C transactions should be correct.

    Regards,

    jp

  • Hi,

    I'm not familiar with the TMS320C6748 part, but from the AIC3106 side those are the I2C transactions and if the command is configured correctly you should see the I2C traces in the scope. Let me assign this to Jianzhong Xu from TMS320C6748 who helped you initially with this part.

    Regards.

  • Hello Jpom,

    In case you're not aware of, there are I2C example projects in OMAP-L138 PDK. You may want to look at those examples for I2C programming on C6748 DSP. 

    Regards,

    Jianzhong

  • Hello,

    Thanks once more. I read the examples and I still can't understand the difference with my code.

    Let's say we want to read register 102 from the AIC3106.

    With the I2C initializated and opened with handler I2C_handle_glob and working in master mode, we do:


    unsigned char writebuf[1];
    I2C_Transaction i2cTransaction;

    regAddr = AIC31_P0_REG102 ; // we want to read register 102 (for example)

    slaveData[0] = regAddr;

    // Here we have to send an I2C message with the address of the i2c slave as 'Address' field and the register address as data

    writebuf[0]=slaveData[0]; 

    // We initialize the transaction with default values
    I2C_transactionInit(&i2cTransaction);

    // 1. First we setup the I2C message to send

    // Override the default address with our slave address
    i2cTransaction.slaveAddress = I2C_slaveAddr;

    // Write the register address to the slave
    i2cTransaction.writeBuf = (uint8_t *)&writebuf[0];

    // Number of bytes to write
    i2cTransaction.writeCount = 1;

    // Read buffer to store the answer from the slave
    i2cTransaction.readBuf = (uint8_t *)&slaveData[0];

    // Read one byte from the slave
    i2cTransaction.readCount = 1; 

    // 2. Send the I2C message
    I2C_transfer(I2C_handle_glob, &i2cTransaction);

    Sorry but this is made this way in all the code and also in the examples. I need more details on what should I do with the i2c transaction. I still think there is a problem setting this inside the USB callback (I can't use the I2C functions directly at this point because the handler is declared in the codec_if.c file, so I use the CodecRegWrite and Read functions)

    Regards,

    jp

  • Hi again,

    I realized that my implementation was correct. The problem was that the codec was not acting as master as I supposed, due to the MCASP_MASTER define. So it wasn't never setting those values for the sampling rate. Therefore, the values in the registers were the reset ones. Now I'm trying to use the codec as master so I can adjust the PLL in runtime.

    You can close the thread, thanks for the help!

    Regards,

    jp

  • Hi jp,

    Thanks for the update. I'll close this thread.

    Regards,

    Jianzhong