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.

  • TI Thinks Resolved

CC3200: I2C communication problem

Prodigy 220 points

Replies: 35

Views: 1148

Part Number: CC3200

Hi 

i currently work on a cc3200 module and i try to use I2C bus to pilot some LEDs

It work perfectly during one or two minutes then the program block in I2C write function. you can see it here :

tank for help

regards

  • In reply to harizi louison:

    hi

    sorry for double post

    But we just use a logic analyzer to see I2C data.

    Everything is fine until the program block in I2C write function.

    We can see on this screenshot the partial last data trame send with the write command, the registry where write, but no value and the clock stay in LOW state.

    On this other screenshot you can see something strange 4.488 ms after the "last data trame".

    Here a global vision of the end of the communication if it can help.

    thank a lot for the help

    Best Regards

  • Expert 7755 points

    In reply to harizi louison:

    Hi,

    At this point I'm not sure what could be going on without looking at some code. If you don't mind sharing some code snippets to see how I2C transaction are being handled maybe I could think of some other reasons as to what may be the issue. Given I can't see everything going on it's difficult to give any more advice. Aside from that, we have an app note for troubleshooting I2C problems. It goes over a lot of scenarios . Maybe reading it will spark an idea.

    www.ti.com/.../scaa106.pdf

    Jesu
  • In reply to Jesu:

    Hi Jesu

    Here you can find the init function for led task:

    void ledTask_init() { unsigned char config[3]={0x00,0x21,0x04}; unsigned char cmd_init_off[5]={0x06,0x00,0x00,0x00,0x10}; I2C_IF_Open(I2C_MASTER_MODE_FST); I2C_IF_Write(Board_PCA9685_ADDR, config, 3, true); I2C_IF_Write(Board_PCA9685_ADDR, cmd_init_off, 5, true); I2C_IF_Close(); osi_SyncObjCreate(&g_ledStatSyncObj); osi_TaskCreate(led_manager, (const signed char *)"Led Manager", OSI_STACK_SIZE, NULL, 1, NULL); gg_ulBase = TIMERA3_BASE; // set timer address Timer_IF_Init(PRCM_TIMERA3, gg_ulBase, TIMER_CFG_PERIODIC, TIMER_A, 0); // configuring the timer Timer_IF_IntSetup(gg_ulBase, TIMER_A, TimerledHandler); // setup interrupt for timer timeout Timer_IF_Start(gg_ulBase, TIMER_A, 5000); // start timer in mSec }



    Here is the task function:
    void led_manager(void *pvParameters)
    {
        volatile unsigned char LoopVar = 0xFF;
    
        while (LoopVar)
        {
            osi_SyncObjWait(&g_ledStatSyncObj, OSI_WAIT_FOREVER); //OSI_WAIT_FOREVER
    
            I2C_IF_Open(I2C_MASTER_MODE_FST);
    respiration(); change_color_led('W');
    I2C_IF_Close(); } }

    And finally you can see here the respiration function who will control the leds

    with as global:

    unsigned char rregister[4]={0x0A,0x16,0x2E,0x22};
    unsigned char cmd_for_all[13]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; // modif by color change func

    void respiration()
    {
        static char state = 0;
        static int value = 0;
        char inc = 100;
        static char tempo = 0;
        char i;
    
        if (state == 0)
        {
            if (value < 4096)
            {
                transformCircleColor(value);
                for (i = 0; i < 4; i++)
                {
                    cmd_for_all[0] = rregister[i];
                    I2C_IF_Write(Board_PCA9685_ADDR, cmd_for_all, 13, true);
                }
                value += (value < 2000 ? (value < 1000 ? (int)inc / 2 : (int)inc) : (int)inc * 2);
            }
            else
            {
                value = 4095;
                state = 1;
            }
        }
        else
        {
            if (value > 0)
            {
                transformCircleColor(value);
                for (i = 0; i < 4; i++)
                {
                    cmd_for_all[0] = rregister[i];
                    I2C_IF_Write(Board_PCA9685_ADDR, cmd_for_all, 13, true);
                }
                value -= (value < 2000 ? (value < 1000 ? (int)inc / 2 : (int)inc) : (int)inc * 2);
            }
            else if (value < 0 && tempo == 0)
            {
                transformCircleColor(value);
                value = 0;
                for (i = 0; i < 4; i++)
                {
                    cmd_for_all[0] = rregister[i];
                    I2C_IF_Write(Board_PCA9685_ADDR, cmd_for_all, 13, true);
                }
                tempo++;
            }
            else if (value == 0 && tempo < 16)
            {
                tempo++;
            }
            else
            {
                value = 0;
                state = 0;
                tempo = 0;
            }
        }
    }

    void transformCircleColor(int value)
    {
        if (cmd_for_all[2] != 0)
        {
            cmd_for_all[2] = 0x00;
            cmd_for_all[3] = value;
            cmd_for_all[4] = value >> 8;
        }
        if (cmd_for_all[6] != 0)
        {
            cmd_for_all[6] = 0x00;
            cmd_for_all[7] = value;
            cmd_for_all[8] = value >> 8;
        }
        if (cmd_for_all[10] != 0)
        {
            cmd_for_all[10] = 0x00;
            cmd_for_all[11] = value;
            cmd_for_all[12] = value >> 8;
        }
        if (cmd_for_all[7] != 0 || cmd_for_all[8] != 0)
        {
            cmd_for_all[7] = value / 2;
            cmd_for_all[8] = (value / 2)>>8;
        }
    }

    thank for the help

  • Expert 7755 points

    In reply to harizi louison:

    Hello,

    Code looks good to me as well. Does the failure consistently happen after the ACK like in the first waveform you provided? The goal is to see if there's a pattern every time it fails to investigate further.

    Also, I noticed SCLK is held low between 2 earlier transaction marked below. It may be worth investigating if that happens between every transaction.

    At this point I believe the best thing to do is analyze the waveforms captured to make sure everything is happening as expected.

    Jesu

  • In reply to Jesu:

    Hi Jesu

    After a lot of research on the TI forum about cc3200 and I2C we found this post : 

     in this post Jan Dospel a tips to reinit I2C communication when it get stuck :

    - set punumx at SCL to GPIO and output
    - generate some pulses on SCL (directly set hi and low level, it is not used pull-up in this case to driven high state)
    - set punmux back to I2C SCL
    - re-initialise I2C peripheral

    So to do that we tried to apply the fix in the part 16.2 from that document 

    This not worked but we we aren't sure where the I2cEmulation() function must be called.

    Thank for all the help

    Best Regards

  • Expert 7755 points

    In reply to harizi louison:

    Hello,

    Your I2CEmulation call looks correct but I don't think you're going to get there since you report that you're getting stuck in the while loop above it. Could you confirm if SCL stays low between transactions? Also, does the I2C fault consistently happen with the same slave device?


    Jesu

  • In reply to Jesu:

    hi
    I confirm to you the SCL stays LOW between transactions.
    And the I2C fault happen with the same slave device everytime.

    I did a new record with logic analyzer, this is the last communication before the stuck of the program.

    The write command is ok with an ACK but after it...

    It couldn't be because the clock is not perfectly regular ?

    Best Regards

  • Guru 32945 points

    In reply to harizi louison:

    Hi,

    I think you have hardware problem with your bus or your I2C slave. You should check that you have properly set values of pull-ups and how looks edges at oscilloscope. Procedure described at link above should works in case of slave held SCL in low properly.

    Jan


    Please click to "Verify Answer", if your question was answered.

  • In reply to Jan D:

    Hi Jan

    We just use an oscilloscope to see edges and we got this : 

    The signals look ok so apparently this is no an hardware problem.

    Thx for the help

    Regards

  • Guru 32465 points

    In reply to harizi louison:

    Hi,

    SCL line looks ok, but at SDA you have weird 0.3-0.4V glitches at high state. They should not be there. Capacitance of your I2C bus also does not looks low.
    - How long is your I2C bus? How many slaves do you have connected? What I2C slaves do you use? What is a problematic slave?
    - What value of pull-ups do you use? Did you try use stronger pull-ups?
    - Are all your I2C slaves designed to be used at 400kHz I2C?
    - Did you try decrease clock to 100kHz?
    - Are you able capture at oscilloscope moment when your slave stuck? Yes, I know that this may to be tricky and you will need to use Ext trigger.

    Jan


    Please click to "Verify Answer", if your question was answered.

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.