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.

TLV320AIC3256: Difficulty reading miniDSP-D coefficient registers

Part Number: TLV320AIC3256

Tool/software:

Dear TI,

I am working on a project that uses an ESP32-S3 MINI module with a TLV320AIC3256. Generally, things are working really well. I am able to download my PurePath generated project to the AIC3256 and it runs great. When I attempt to write coefficients to miniDSP-D, everything works fine too. Note, I am using adaptive mode and have developed an algorithm to keep both coefficient banks up to date. Now, I am attempting to read-back coefficients. Specifically, I have configured a specAna_TI_V1 as a VU meter and want to read the VU values from it. I have tested the specAna_TI_V1 as a VU meter on the TLV320AIC3256EVM-U board and it works fine. I have also connected my project (board / firmware) to PurePath Studio via the I2C port and sure enough PurePath can read the VU coefficient on my board. However, when I attempt to read coefficient with the ESP32-S3 I get incorrect data. (It looks like I'm reading page 0x00 instead of page 0x2d).

The basic algorithm is this:

  1. Swap miniDSP-D buffers
  2. Select the VU coefficient page 
  3. Select the VU coefficient start register
  4. Read-back four bytes.

I connected up a Saleae and have a trace of the ESP32-S3 transactions: I can verify that the incorrect data is actually on the I2C bus. I have also generated a Saleae trace using the PurePath Studio I2C Memory tool to swap the buffers and read back the coefficients. It works, but seems to do a lot more than necessary. However, one thing did stand out: Instead of reading the four bytes of the VU coefficient as a single read, it sets the address for each I2C read then reads the AIC3256 one byte at a time. Why is this? From my reading it looks like there's an auto-increment function in the AIC3256 I2C read / write.

My plan right now is to duplicate the PurePath Studio process as closely as possible on the ESP32-S3. However I'm not sure why this would be necessary. Is there a document of some sort that outlines how to do coefficient reads from an AIC3256? Perhaps someone can look at my Saleae traces and tell me why each of these transactions is required -- and in some cases what PurePath Studio is doing?

Thanks for your help,

ACV

  • Hi ACV,

    While I look into this, could you share your I2C transactions on the Saleae? Is there any noticeable pattern to the incorrect data (such as the data appears shifted by x addresses), is it all 0, is it garbage data?

    Thanks,
    Jeff McPherson

  • 6232.ti.zip

    These captures are using the TI I2C Memory Tool in PurePath Studio to read my board via I2C. These are working transactions...

  • rev-c_swap&read.zip

    Here is my code attempting to swap buffers (which appears to work) and read four bytes (which appears to not work).

    The set-up appears correct to me. What am I doing wrong?

  • Hi Anthony,

    Trying to wrap my head around your code here. I've translated it into a script below. Am I interpreting it correctly? I see a lot of page swapping between 2C and 2D but not a lot of writing to those registers. It looks like you want to read the buffer from page 2D, but there's no writing over that buffer. There are only writes in page 2C.

    Swap&Read (ESP32-S3)
    w 0x30 00 2C #page change to 2C
    r 0x30 01 01 #returns 0x06
    w 0x30 00 2C #page change to 2C
    w 0x30 01 07 #
    w 0x30 00 2D #page change to 2D
    r 0x30 40 04 #returns 0x80, 0x00, 0x00, 0x00
    w 0x30 00 2C #page change to 2C
    r 0x30 01 01 #returns 0x04
    w 0x30 00 2C #page change to 2C
    w 0x30 01 05 #
    w 0x30 00 2D #page change to 2D
    r 0x30 40 04 #returns 0x80, 0x00, 0x00, 0x00
    w 0x30 00 2C #page change to 2C
    r 0x30 01 01 #returns 0x06
    w 0x30 00 2C #page change to 2C
    w 0x30 01 07 #
    w 0x30 00 2D #page change to 2D
    r 0x30 40 04 #returns 0x80, 0x00, 0x00, 0x00

    Even looking through the rev-c_swap sequence from PPS I don't see where the swap occurs. I see switching pages and a few single writes but nothing that resembles swapping a whole buffer. Can you help clarify where you expect the swap to occur in these code sequences?

    Thank you,
    Jeff McPherson

  • # swap
    w 0x30 00 2C # page change to 2C 
    r 0x30 01 01 # read DAC Adaptive Filter Configuration Register (returns 0x06) 
    w 0x30 00 2C # page change to 2C (not required)
    w 0x30 01 07 # or in DAC Adaptive Filter Buffer Switch control bit
    
    # read coefficient 0x002c -- this is page 0x2d, register 0x40 
    w 0x30 00 2D # page change to 2D (select coefficient page)
    r 0x30 40 04 # returns 0x80, 0x00, 0x00, 0x00 (Read coefficient)
    
    # swap
    w 0x30 00 2C # page change to 2C
    r 0x30 01 01 # read DAC Adaptive Filter Configuration Register (returns 0x04)
    w 0x30 00 2C # page change to 2C
    w 0x30 01 05 # or in DAC Adaptive Filter Buffer Switch control bit
    
    # read coefficient 0x002c -- this is page 0x2d, register 0x40 
    w 0x30 00 2D # page change to 2D
    r 0x30 40 04 # returns 0x80, 0x00, 0x00, 0x00
    
    # swap
    w 0x30 00 2C # page change to 2C
    r 0x30 01 01 # returns 0x06
    w 0x30 00 2C # page change to 2C
    w 0x30 01 07 # or in DAC Adaptive Filter Buffer Switch control bit
    
    # read coefficient 0x002c -- this is page 0x2d, register 0x40 
    w 0x30 00 2D #page change to 2D
    r 0x30 40 04 #returns 0x80, 0x00, 0x00, 0x00
    

    I have annotated your script with my notes. Here is a theory of operation:

    This code shows three complete swap / read iterations. Since this is a VU meter, I want to read the VU data periodically.

    The first action is a swap. This takes four I2C transactions: The code reads the DAC Adaptive Filter Configuration Register (0x2c) or's in the DAC Adaptive Filter Buffer Switch control bit (0x01) and writes the byte back out to the DAC Adaptive Filter Configuration Register (0x2c). There is one redundant write to select the DAC Adaptive Filter Configuration Register.

    The second action is a read. This takes two I2C transactions: The code reads coefficient 0x2c from the DAC Coefficient Memory. Note that this is a coefficient. It's address must be translated into an I2C page / register pair. In this case that's page:0x2D and register 0x40. Once the page and register have been selected, the code reads the four bytes. This data is incorrect. I expect it to be VU data not a constant 0x80 0x00 0x00 0x00.

  • Hi Anthony,

    Thank you for the explanation. It makes sense now. How are you ensuring that you are waiting until the next frame boundary before attempting to read?

    I'm also noticing between your i2c plots that the code from PPS is using start/stop reads i.e. reading one byte at a time of the coefficient. But your code is attempting to read the whole coefficient in one transaction. It's also calling to read register 0x51 which is strange. While I work on decoding the transactions, is is possible for your controller to use a start/stop read mode rather than sequential? I know that sounds odd, and normally sequential reads are better but I think we should try to match PPS as a close as possible here since it appears to work correctly.

    Best regards,
    Jeff McPherson

  • Jeff,

    I've worked out the issue.

    I added a few more functions to read more and more data and I realized the read was working fine. The issue has to do with having multiple threads accessing the same peripheral. Currently, the code doesn't have protection from multiple threads accessing the AIC3256 at the same time.

    Thanks for your help!

    ACV