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.

CC3200: I2C communication problem

Part Number: CC3200
Other Parts Discussed in Thread: , CC2650

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

  • Have you tried using a logic analyzer to see what happens? Or tried using breakpoints and debugging to see where it breaks?

    Jesu
  • Hi

    Yes i tried with breakpoints

    When i run step by step all work fine

    Regards

  • Harizi - 

    I can see the i2c.c file in the SDK here ==> C:\ti\CC3200SDK_1.1.0\cc3200-sdk\driverlib can you check that with the locate file button?

    we also have updated the SDK twice since that release - if you would like to update or get the v1.1 again, please visit here ==> 

  • hi guys

    Thank for your reply.

    After your answer i updated my sdk version from 1.1 to 1.3 but the result stay the same.

    When i run the program, leds and sensors (on I2C too) work fine but after few minutes the problem happens again.

    I tryed to run my code for the leds in the I2C demo from the CC3200 SDK 1.3, it worked perfectly.

    thank for the help

    regards
  • Hi Harizi,

    Does the i2cdemo example work for the sensors too or is that the only device giving you problems?

    Jesu
  • Hi Jesu,

    I'm an Harizi's co-worker.

    In the project, there is 2 tasks with I2C transmission. One for the sensors measurement and the second one to drive LED with an PCA9685.

    When we only active the sensor task, the I2C transmission works fine (over a night).
    but we have the issue with the LED task (illustrate in the first post).

    We implemented the PCA commands in the I2CDemo to be sure that our commands are good and drive the LED as expected. Thats's the case.

    If you have any idea of something to check ?

    Best regards
    Michaël
  • Hi Michael,

    From your description it seems like more of an RTOS problem than it is an I2C problem. How are your tasks running?

    Jesu
  • Jesu,

    In ROV view, the BIOS don't detect any bug,
    The task "Led" (task with the lowest priority in the project) is in running mode and every other tasks are blocked waiting for semaphore.

    The Led task is the lowest priority task because it's only for LED animations (blink, breath effect,...) to inform the user. So it's not critical versus Wifi/BLE tasks.

    So, nothing weird for me.

    Michaël
  • Hi Michael,

    Just to make sure you're not having a scheduling problem could you make the LED task higher priority than the sensor task? The idea is if the LED task starts working then it's a scheduling problem.

    Jesu
  • Hi Jesu

    We tried to disable the sensor task and ran the program with the led task but everytime we get the same issue that in the first post.

    The program is stuck in an I2C function as you can see in the screenshot below.

    The LED task remaining is the only one to use I2C communication so i don't think it.

    Best regards.

  • 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

  • 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
  • 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

  • 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

  • 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

  • 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

  • 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

  • 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
  • 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

  • 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

  • Hi Hnz

    - How long is your I2C bus?
    SDA : 75,5mm (width : 0,15mm)
    SCL : 77mm

    How many slaves do you have connected?
    2

    What I2C slaves do you use?
    PCA9685PW (LED driver)
    SI7020-A20-GM1 (Temperature Sensor)

    What is a problematic slave?
    I2C freeze with the LED driver (PCA9685)

    - What value of pull-ups do you use? Did you try use stronger pull-ups?
    I’m using 5k pullup resistors, I also tried with 1k resistors, and I still have the bug.

    - Are all your I2C slaves designed to be used at 400kHz I2C?
    Yes

    - Did you try decrease clock to 100kHz?
    Yes, same issue

    - 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.
    I recorded with a logic analyzer, (the screenshot is above in the thread), but with my oscilloscope, I'm not sure to succeed, I will try.

    Best Regards

  • Hi,

    How often communication with PCA9685 stuck? Can you estimate numbers (e.g. one of 1000 requests, etc.).

    I am almost 100% sure that issue causing internal logic in PCA9685 chip whcih stuck from some reasons. Now is question how it is often. In case of problem occurs very often, you will need fix this at hardware side. But in case of occurrence is rarely it make sense change software side. It may to be reasonable to add additional timeouts and tests. In case of SCL stuck in low may to be important error I2C_MASTER_ERR_ARB_LOST.

    My personal opinion. I never used _if abstraction layer at CC3200 SDK. Function in this layer are not much robust and the are usage of them wasting CPU time. It is much more efficient to use interrupts and maybe even DMA.

    Update:

    Just to be sure. In case of stuck it stays forever at while loop in I2CTransact() and did not return? Right?

    Jan

  • Hi everyone,

    Thanks for the help Jan. I would also like to add if software side fix makes sense - you can probably get away with triggering a software reset periodically on the LED driver before the expected failure happens. The PCA9685 has a software reset feature via I2C bus. It would be interesting to see if a periodic software reset prevents the i2c failure.

    Jesu

  • Hi guys,

    To Jesu: Yes I tried to use the reset feature of the PCA9685 module but it did nothing, always the same failure happens.

    To Hnz: Right, when stuck it stays in I2CTransact() at the while loop forever and never return.

    The communication with the PCA9685 module stuck absolutely every time and very quickly ( < 1 seconde ).

    Always Thank

    Louison

  • Hi Louison,

    In case of communication stuck that often, than I think is no way how fix this by software. You need this fix your hardware. But there is a good question what is wrong in your case. Did you tested more PCA9685 chips? Did you tested your PCA9685 chip with another MCU? Maybe we forgot to one of obvious potential reasons of issue - damaged chip or some EMC issue.

    Software solution is not a your case, but if occurrence of issue will be a low (let say 1% of all communications), it may to be reasonable add detection of fault state, like:

    unsigned int err;
    
    while(((err = MAP_I2CMasterIntStatusEx(I2C_BASE, false)) & (I2C_INT_MASTER | I2C_MRIS_CLKTOUT | 0x80)) == 0)
    {
    }
    
    // Arbitration Lost Raw Interrupt Status (0x80 is a ARBLOSTRIS flag in I2CMRIS register)
    if ((err & 0x80) != 0) {
      // 
      // Do I2C restore procedure by generation of SCL impulses.
      // Also I2C peripheral should be restarted after this procedure.
      //
    }

    But I think this code not save you, because your communication with PCA9685 chips is so unreliable.

    Jan

  • Hi guys,

    I have news ! We can now affirm this is not an Hardware problem !

    Remember, the projet is based on the Blefi example project.

    The LEDs work very well when the function LoadBleFiCfg() is comented in the GwGenericTask. If this function is called, the issue happens.

    But if this function is comented, things like bluetooth and mqtt don't work. Certainly cause they don't have config.

    I don't know how this function can impact on the I2C communication but it happens.

    Again thank for the help !

    Regards

  • Hi,

    Sorry, I haven't experience with this reference design. I haven't time to study this design. I am not able to help you with this exact design.

    But how you can be sure that this is not hardware problem? It may to be EM interference between your BLE and I2C. Is your I2C bus near BLE antenna? Issue can be determined using spectrum analyser and EMC probes.

    Jan
  • Hello,

    What device is the bluetooth running on?

    Jesu
  • hi,

    @Hnz you are true, ccan't be sure it's not hardware problem but there are easly 2cm between I2C bus and Ble antenna. And i don't have spectrum analyser to test that.

    @Jesu the Bluetooth run on a CC2650 device

    Regards

  • Hi,

    Distance 2cm may not be enough depends on your antenna. For 2.4GHz is a reactive near field up to 2 cm.

    Jan
  • Hello,

    Have you tried to debug your software further to figure out what exactly in the LoadBleFiCfg function causes the I2C to fail? I'm not familiar with the blefi example but if possible, start commenting parts of the LoadBleFiCfg to find the point of failure. The idea is, I doubt a simple function call is going to break I2C, this function must be doing something that causes it to fail.

    To Jan's point, it may still be a HW issue where once Bluetooth is configured and ready, it interferes with I2C or it may be actually be a SW issue where it's overriding some setting or causing a scheduling problem.

    Jesu
  • Hello,

    I'm going to close this thread due to inactivity. Feel free to respond if you have anymore questions.

    Jesu
  • Hi,

    We can't try your method cause LoadBleFiCfg function simply load or create then load a configuration file so nothing in this function break I2C directly.
    We also try to run the program with a deported PCA9685PW (LED driver) but the result is the same.

    The other I2C slave, SI7020-A20-GM1 (Temperature Sensor), work fine everytime so I don't think that is a hardware problem.


    Regards
  • Could you think of any pins or peripherals the blefi function may be using that causes your problem? Maybe there is overlapping somewhere?

    Jesu
  • Hi jesu,

    We found the cause and the solution of our problem.

    CC3200 was stuck in the loop waiting for the ACK from PCA 9685.

    Our guess is something happens and delays the CC3200 for the I2C transaction.

    So we put the I2C task priority to the top, and now it's works.

    Wifi and Bluetooth transmissions are still working and the prototype is running since 72 hours without interruption.

    Thanks for the help.

    Best regards,

    Michaël