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.

I2C_read() with C5515 and AIC3204 using the CSL

Other Parts Discussed in Thread: TMS320C5515, TLV320AIC3204

Hello,

I have a question concerning the TMS320C5515 EVM (or C5515 eZdsp). I am using the CSL 2.10 to configure the on-board TLV320AIC3204 codec with the function I2C_write(). This is working for 8 bits and I can verify this using an oscilloscope.

But how I have to configure the CSL I2C module to read a register (e.g. Register 42 -> Sticky Flag Register 1)  from the codec?

I tried several configurations but never see the REPEATED START condition to get the value out of the codec. It only sends the the slave address and the register address I want to read out, no matter if I change the number of bytes to receive.

 

    myread[0] = 0x0005;          // Read Register 5
    myread[1] = 0x0000;

    I2C_read(myread, 1, CSL_I2C_CODEC_ADDR, TRUE, ( (CSL_I2C_START) | (CSL_I2C_RESTART) | (CSL_I2C_STOP) ), CSL_I2C_MAX_TIMEOUT, FALSE);

 

 

This are the parameter to set up the I2C using the CSL:

    /* Setup I2C module */
    i2cSetup.addrMode    = CSL_I2C_ADDR_7BIT;
    i2cSetup.bitCount    = CSL_I2C_BC_8BITS;
    i2cSetup.loopBack    = CSL_I2C_LOOPBACK_DISABLE;
    i2cSetup.freeMode    = CSL_I2C_FREEMODE_DISABLE;
    i2cSetup.repeatMode  = CSL_I2C_REPEATMODE_DISABLE;
    i2cSetup.ownAddr     = CSL_I2C_OWN_ADDR;
    i2cSetup.sysInputClk = CSL_I2C_SYS_CLK;
    i2cSetup.i2cBusFreq  = CSL_I2C_BUS_FREQ;
    startStop            = ( (CSL_I2C_START) | (CSL_I2C_STOP) );

 

Thank you.

 

Martin

  • Hi,


    In order to read I2C register, you need to set I2C subaddress first with I2C write. For example, if you want read register 0x05, you write 0x05 and read contests.

     gI2cWrBuf[0]= 0x05;    // I2C subaddress

     status = I2C_write(gI2cWrBuf, 1, CSL_I2C_CODEC_ADDR, TRUE, startStop, CSL_I2C_MAX_TIMEOUT);

     status = I2C_read(myread, 1, CSL_I2C_CODEC_ADDR,      TRUE, startStop, CSL_I2C_MAX_TIMEOUT, FALSE);

    myread[0] is your read value.

    Regards,

    Hyun

  • Hello Hyum

    Thanks for your reply. I tried a few things and here are my results:

     

    (I have put the screenshots into this ZIP file.)

    8105.i2c_5515_error.zip

     

    1. Set breakpoints as shown in screenshot i2c_1.png

    For each breakpoint I get the following data on my oscilloscope:

    After breakpoint no.

       1  -  1_01.png  (I2C Write correct.)
       2  -  1_02.png  (I2C Write correct.)
       3  -  1_03.png  (Instead of a Master Write=0 it is 1, indicating a Read)
       4  -  1_04.png  (Now it it looks fine but rBuf[0]=0 )
       5  -  1_05.png  (Same again, but this time rBuf[0]=2 as expected.)

    Here again is what I read from the codec:

       I2C_read() register data is: 0
       I2C_read() register data is: 0
       I2C_read() register data is: 2



    2. Now I set the breakpoints as shown in screenshot i2c_2.png

       1  - 2_01.png  (I2C Write correct.)
       2  - 2_02.png  (I2C Write correct.)
       3  -  2_03.png  (Aha! Now there isn't the faulty Master Write=1)
       4  -  2_04.png  (OK, I get a rBuf[0]=2)
       5  -  2_05.png  (That's OK.)
       6  -  2_06.png  (Again I get the rBuf[0]=2)
       7  -  2_07.png  (OK)
       8  -  2_08.png  (OK, rBuf[0]=2)

    And my Console tells the same:

       I2C_read() register data is: 2
       I2C_read() register data is: 2
       I2C_read() register data is: 2


    3. If I set one breakpoint like in i2c_3.png or no breakpoint at all:


       I2C_read() register data is: 0
       I2C_read() register data is: 0
       I2C_read() register data is: 2



    I tested it several times, with different pages, with a complete restart, new enumeration of the debugger, etc.


    So, is this a problem with the debugger or the DSP itself? Will it work if I just flash it and let it run free?

    Martin

     

     


     

    Here is my code I used for this test:

     

    #include <stdio.h>
    #include <csl_general.h>
    #include <csl_i2c.h>

    /* I2C Configuration Details */
    #define CSL_I2C_SYS_CLK            (100)    // In MHz    (System Clock after PLL)
    #define CSL_I2C_BUS_FREQ        (10)    // In KHz
    #define CSL_I2C_CODEC_ADDR        (0x18)    // Codec (AIC3204)     0011000 -> 7 bit
    #define CSL_I2C_OWN_ADDR        (0x2F)

    void wait( Uint32 delay )
    {
        volatile Uint32 i;
        for ( i = 0 ; i < delay ; i++ ){ };
    }

    void delay( Uint32 usec )
    {
        wait( (Uint32)usec * 8 );
    }

    CSL_Status        status;
    CSL_I2cSetup    i2cSetup;
    Uint16            startStop;

    void main( void )
    {
        Uint16 wBuf[2];        // Write Buffer
        Uint16 rBuf[1];        // Read Buffer

        /* Initialize I2C module */
        status = I2C_init(CSL_I2C0);
        if(status != CSL_SOK)
        {
            printf("I2C Init Failed!!\n");
        }

        /* Setup I2C module */
        i2cSetup.addrMode    = CSL_I2C_ADDR_7BIT;
        i2cSetup.bitCount    = CSL_I2C_BC_8BITS;
        i2cSetup.loopBack    = CSL_I2C_LOOPBACK_DISABLE;
        i2cSetup.freeMode    = CSL_I2C_FREEMODE_DISABLE;
        i2cSetup.repeatMode  = CSL_I2C_REPEATMODE_DISABLE;
        i2cSetup.ownAddr     = CSL_I2C_OWN_ADDR;
        i2cSetup.sysInputClk = CSL_I2C_SYS_CLK;
        i2cSetup.i2cBusFreq  = CSL_I2C_BUS_FREQ;
        startStop            = ( (CSL_I2C_START) | (CSL_I2C_STOP) );

        status = I2C_setup(&i2cSetup);
        if(status != CSL_SOK)
        {
            printf("I2C Setup Failed!!\n");
        }

        /* Test some codec register */

        // Codec SW Reset
        wBuf[0] = 0x0001;            // Codec Register Address
        wBuf[1] = 0x0001;            // Codec Register Data
        I2C_write(wBuf, 2, CSL_I2C_CODEC_ADDR, TRUE, startStop, CSL_I2C_MAX_TIMEOUT);
        wait(20000);

        // Change Codec Page to 2
        wBuf[0] = 0x0000;
        wBuf[1] = 0x0002;
        I2C_write(wBuf, 2, CSL_I2C_CODEC_ADDR, TRUE, startStop, CSL_I2C_MAX_TIMEOUT);
        delay(1800);
       
        // 1. Read current Codec Page
        wBuf[0] = 0x0000;
        rBuf[0] = 0x0000;
        I2C_write(wBuf, 1, CSL_I2C_CODEC_ADDR, TRUE, startStop, CSL_I2C_MAX_TIMEOUT);
        I2C_read(rBuf, 1, CSL_I2C_CODEC_ADDR, TRUE, startStop, CSL_I2C_MAX_TIMEOUT, FALSE);
        printf("I2C_read() register data is: %d\n", rBuf[0]);
        delay(1800);   

        // 2: Read current Codec Page
        wBuf[0] = 0x0000;
        rBuf[0] = 0x0000;
        I2C_write(wBuf, 1, CSL_I2C_CODEC_ADDR, TRUE, startStop, CSL_I2C_MAX_TIMEOUT);
        I2C_read(rBuf, 1, CSL_I2C_CODEC_ADDR, TRUE, startStop, CSL_I2C_MAX_TIMEOUT, FALSE);
        printf("I2C_read() register data is: %d\n", rBuf[0]);
        delay(1800);

        // 3: Read current Codec Page
        wBuf[0] = 0x0000;
        rBuf[0] = 0x0000;
        I2C_write(wBuf, 1, CSL_I2C_CODEC_ADDR, TRUE, startStop, CSL_I2C_MAX_TIMEOUT);
        I2C_read(rBuf, 1, CSL_I2C_CODEC_ADDR, TRUE, ( (CSL_I2C_START) | (CSL_I2C_STOP)), CSL_I2C_MAX_TIMEOUT, FALSE);
        printf("I2C_read() register data is: %d\n", rBuf[0]);
        delay(1800);
    }

  • Hi,


    You did a good job to find out. In fact, if you put the delay between I2C_write and I2C_read, it'll fix your problem.

        I2C_write(wBuf, 1, CSL_I2C_CODEC_ADDR, TRUE, startStop, CSL_I2C_MAX_TIMEOUT);

       /* Give some delay */

       delay(1800); // It's the same effect of your break point.

        I2C_read(rBuf, 1, CSL_I2C_CODEC_ADDR, TRUE, ( (CSL_I2C_START) | (CSL_I2C_STOP)), CSL_I2C_MAX_TIMEOUT, FALSE);

     

    Regards,

    Hyun

  • Ah, right. Now this piece is working.

    But still, this is not a valid REPEATED START condition! The example you suggest sends a STOP condition and after some delay a START condition. How can I achieve a REPEATED START condition with the CSL?

     

  • Hi,

    We are looking into it now. I'll let you know when I get an answer.

    Regards,

    Hyun

  • Hi,

    We have done with ccs_v3.3_examples\i2c\example2 csl_i2c_dma_example.c and modified it to use restart.

    Please use attached file to check the restart working.

    Regards,

    Hyun

    csl_i2c_dma_example_restart.zip