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, TI-RTOS, I2C Task just stops transmitting

I've got a strange issue. I2C is working but randomly stopping transmission without an error message.

Hardware: CC3200LP + Adafruit Servo shield PCA9685 + 6k pullups on SDA and SCL.

Code:

Init i2c

...

/*
Init code for I2C
*/
void I2C_start(unsigned int indexI2C){

	I2C_Params_init(&i2cParams);
	i2cParams.bitRate = I2C_100kHz;
	i2cParams.transferMode = I2C_MODE_BLOCKING;
	i2cParams.transferCallbackFxn = NULL;
	i2c = I2C_open(indexI2C, &i2cParams);
	if (i2c == NULL) {
		System_abort("Error Initializing I2C\n");
	}
	else {
		 System_printf("I2C Initialized!\n");
		 System_flush();
	}
}

...

/*
Code for multible PWM output settings
*/

... void Update_multiple_LEDs(uint16_t *OUTPUT_VALUES) { txBufferMulti[0] = 0x6; //LED0 register has to addressed. Auto increment is doing the rest for(i = 0; i < 8; i++){ u = i * 4 ; txBufferMulti[u+1] = 0x0; //on txBufferMulti[u+2] = txBufferMulti[u+1]>>8; //on txBufferMulti[u+3] = OUTPUT_VALUES[i]; //off txBufferMulti[u+4] = OUTPUT_VALUES[i]>>8;//off } i2cTransaction.writeBuf = txBufferMulti; i2cTransaction.writeCount = 33; i2cTransaction.readBuf = rxBuffer; i2cTransaction.readCount = 0; i2cTransaction.slaveAddress = PCA9685_1; if (!(I2C_transfer(i2c, &i2cTransaction))) { System_printf("I2C Bus fault\n"); System_flush(); } Task_sleep(10); }

...

main

...

Void i2cTask(){


	System_printf("I2C Task started...\n");
	System_flush();

	uint16_t OUTPUT_ZEROVALUE_ARRAY[8] = {0,0,0,0,0,0,0,0};
	uint16_t OUTPUT_VALUE_ARRAY_R[8] = {100,0,0,1000,2000,3000,4000,4095}; //PWM Values {Cnannel 0, Channel 1, Channel 3, ...}
	uint16_t OUTPUT_VALUE_ARRAY_G[8] = {0,100,0,1000,2000,3000,4000,4095}; //PWM Values {Cnannel 0, Channel 1, Channel 3, ...}
	uint16_t OUTPUT_VALUE_ARRAY_B[8] = {0,0,100,1000,2000,3000,4000,4095}; //PWM Values {Cnannel 0, Channel 1, Channel 3, ...}

	I2C_start(Board_I2C_TMP);

	PC9685_init(PWM_FREQUNCY); //I2C and PWM Frequency in Hz

	Update_multiple_LEDs(OUTPUT_ZEROVALUE_ARRAY);

	while (1) {


			Update_multiple_LEDs(OUTPUT_VALUE_ARRAY_R);
			Update_multiple_LEDs(OUTPUT_VALUE_ARRAY_G);
			Update_multiple_LEDs(OUTPUT_VALUE_ARRAY_B);


}

The code is working and the first 8 PWMs are updated every 10ms. But is just stops after a while and there is no clock or data on the bus.

I'm new to ti-rtos + i2c...

Any idea what the issue is?

Thanks 

  • I might have solved it.

    I does seem that you need to write all 16 pwm registers (not just the first 8 as I did in the first place) on the PCA9685 if you want to use the auto-increment option. Although thee is no hint in the documentation...

    So its not an TI issue.

    Thanks

  • Update: Unfortunately it still doesn't work. I does seem like an task issue. 

    I modified the task and added a GPIO (blue), (yellow is i2c) for debug purposes.

    ...	
    while (1) {
    			/*Set GPIO 15 HIGH  */
    			MAP_GPIOPinWrite(GPIOA2_BASE,GPIO_PIN_6,GPIO_PIN_6); //Set GPIO Pin 15 to 1
    			Update_multiple_LEDs(OUTPUT_VALUE_ARRAY_R);
    			Task_sleep(10);
    			Update_multiple_LEDs(OUTPUT_VALUE_ARRAY_G);
    			Task_sleep(10);
    			Update_multiple_LEDs(OUTPUT_VALUE_ARRAY_B);
    			MAP_GPIOPinWrite(GPIOA2_BASE,GPIO_PIN_6,0); //Set GPIO Pin 15 to 0
    			Task_sleep(10);
    			}
    ...

    It's working just fine, for a while 

    It just stops without any report, nothing.

    Any ideas?

    Thanks

  • Sorry for the late reply.

    What version of TI-RTOS are you using? Can you switch to use the instrumented I2C library so you can view Log Events?

    Please add this to the .cfg file:

    TIRTOS.libType = TIRTOS.LibType_Instrumented;
    
    var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
    LoggingSetup.loggerType = LoggingSetup.LoggerType_STOPMODE;
    LoggingSetup.loadLogging = false;
    var LoggerIdle = xdc.useModule('ti.uia.sysbios.LoggerIdle');
    
    var Main = xdc.useModule('xdc.runtime.Main');
    Main.common$.diags_INTERNAL = Diags.ALWAYS_ON;

    You should be able to see "Main" logs printed out in the LoggerStopMode tab in ROV. Can you paste the last set of I2C logs?

  • Hi Tom,

    thank you for your post.

    I added your code to the cfg but it didn't compile, so a hat to comment out some lines. 

    Errors:

    XDC runtime error: ti.tirtos.TIRTOS: no property named 'LibType_Instrumented'

    ti.tirtos.TIRTOS: no property named 'LibType_Instrumented'

    //TIRTOS.libType = TIRTOS.LibType_Instrumented;
    
    var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
    LoggingSetup.loggerType = LoggingSetup.LoggerType_STOPMODE;
    LoggingSetup.loadLogging = false;
    //var LoggerIdle = xdc.useModule('ti.uia.sysbios.LoggerIdle');
    
    var Main = xdc.useModule('xdc.runtime.Main');
    Main.common$.diags_INTERNAL = Diags.ALWAYS_ON;
    

    After the I2C task stops running I have to pause the mcu to retrieve ROV. 

    Any ideas whats causing this?

     

  • You need something like this in your .cfg file:
    /* ================ Driver configuration ================ */
    var TIRTOS = xdc.useModule('ti.tirtos.TIRTOS');
    TIRTOS.useI2C = true;
    TIRTOS.libType = TIRTOS.LibType_Instrumented;

    Then in ROV, you can "Main" records within the "LoggerStopMode" view.

  • Hi Tom,

    here's my cfg which I can compile without any errors. If I add your code I get 2 errors.

    /*
     *  ======== ti_rtos_simplelink.cfg ========
     */
    
    /* ================ General configuration ================ */
    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Log = xdc.useModule('xdc.runtime.Log');
    var Main = xdc.useModule('xdc.runtime.Main');
    var Memory = xdc.useModule('xdc.runtime.Memory');
    var System = xdc.useModule('xdc.runtime.System');
    var Text = xdc.useModule('xdc.runtime.Text');
    
    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    var Clock = xdc.useModule('ti.sysbios.knl.Clock');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var UART = xdc.useModule('ti.drivers.UART');
    var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
    var Mailbox = xdc.useModule('ti.sysbios.knl.Mailbox');
    
    /* ================ Driver configuration ================ */
    var TIRTOS = xdc.useModule('ti.tirtos.TIRTOS');
    var GPIO = xdc.useModule('ti.drivers.GPIO');
    var Timer = xdc.useModule('ti.sysbios.family.arm.m3.Timer');
    var SPI = xdc.useModule('ti.drivers.SPI');
    var I2C = xdc.useModule('ti.drivers.I2C');
    
    I2C.libType = I2C.LibType_NonInstrumented;
    
    
    /* SPI Task */
    var task5Params = new Task.Params();
    task5Params.instance.name = "SPI";
    task5Params.priority = 1;
    task5Params.stackSize = 1024;
    Program.global.SPI = Task.create("&spiTask", task5Params);
    SPI.libType = SPI.LibType_Instrumented;
    System.extendedFormats = '%$L%$S%$F%f';
    
    
    
    
    //UART.libType = UART.LibType_Instrumented;
    
    /*
     * Comment this line to allow module names to be loaded on the target.
     * The module name strings are placed in the .const section. Setting this
     * parameter to false will save space in the .const section.  Error and
     * Assert messages will contain an "unknown module" prefix instead
     * of the actual module name.
     */
    Defaults.common$.namedModule = false;
    
    /*
     * Minimize exit handler array in System.  The System module includes
     * an array of functions that are registered with System_atexit() to be
     * called by System_exit().
     */
    System.maxAtexitHandlers = 2;
    
    /*
     * Comment this line to allow Error, Assert, and Log strings to be
     * loaded on the target.  These strings are placed in the .const section.
     * Setting this parameter to false will save space in the .const section.
     * Error, Assert and Log message will print raw ids and args instead of
     * a formatted message.
     */
    Text.isLoaded = false;
    
    Program.stack = 1024;
    
    /* ================ System configuration ================ */
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    System.SupportProxy = SysMin;
    SysMin.bufSize = 512;
    SysMin.flushAtExit = true;
    
    /* ================ BIOS configuration ================ */
    /*
     * Disable unused BIOS features to minimize footprint.
     * This example uses Tasks but not Swis or Clocks.
     */
    BIOS.libType = BIOS.LibType_Custom;
    BIOS.swiEnabled = false;
    BIOS.logsEnabled = true;
    BIOS.assertsEnabled = false;
    BIOS.heapSize = 4096;
    
    /* No runtime stack checking is performed */
    Hwi.checkStackFlag = false;
    
    /* ================= Task configuration ================= */
    Task.checkStackFlag = true;
    Task.enableIdleTask = true;
    Task.numPriorities = 8;
    
    /* TCP  task */
    var task0Params = new Task.Params();
    task0Params.instance.name = "tcpServer";
    task0Params.stackSize = 2048;
    task0Params.priority = 4;
    Program.global.tcpServer = Task.create("&tcpServerTask", task0Params);
    
    /* Simplelink  task */
    var task1Params = new Task.Params();
    task1Params.instance.name = "simplelink";
    task1Params.stackSize = 2048;
    task1Params.priority = 5;
    Program.global.simplelink = Task.create("&simplelinkTask", task1Params);
    
    /* Uart  task */
    var task2Params = new Task.Params();
    task2Params.instance.name = "uart";
    task2Params.stackSize = 2048;
    task2Params.priority = 2;
    Program.global.uart = Task.create("&uartTask", task2Params);
    
    /* CC3200 PWM  task */
    var task3Params = new Task.Params();
    task3Params.instance.name = "CC3200PWM";
    task3Params.arg0 = 50;
    task3Params.priority = 6;
    task3Params.stackSize = 2048;
    Program.global.CC3200PWM = Task.create("&CC3200PWMTask", task3Params);
    
    /* UDP  task */
    var task4Params = new Task.Params();
    task4Params.instance.name = "udpServer";
    task4Params.stackSize = 2048;
    task4Params.priority = 3;
    Program.global.udpServer = Task.create("&udpServerTask", task4Params);
    
    /* I2C Task */
    var task6Params = new Task.Params();
    task6Params.instance.name = "I2C";
    task6Params.priority = 7;
    task6Params.stackSize = 4096;
    //task6Params.vitalTaskFlag = true;
    Program.global.I2C = Task.create("&i2cTask", task6Params);
    
    
    /* Mailbox */
    var mailbox0Params = new Mailbox.Params();
    mailbox0Params.instance.name = "UARTmailbox";
    Program.global.UARTmailbox = Mailbox.create(64, 1, mailbox0Params);
    
    Clock.timerId = 0;
    Clock.tickPeriod = 1000;
    
    Task.deleteTerminatedTasks = true;
    
    
    //by Tom Kopriva
    //TIRTOS.libType = TIRTOS.LibType_Instrumented;
    //TIRTOS.useI2C = true;
    
    var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
    LoggingSetup.loggerType = LoggingSetup.LoggerType_STOPMODE;
    LoggingSetup.loadLogging = false;
    //var LoggerIdle = xdc.useModule('ti.uia.sysbios.LoggerIdle');
    
    var Main = xdc.useModule('xdc.runtime.Main');
    Main.common$.diags_INTERNAL = Diags.ALWAYS_ON;
    
    
    
    
    
    

  • Hi,

    please check the logs I added:

    Everything is running OK:


     

    After ~5min the I2C Task just stops working:

    I'm out of ideas...

    Thanks

  • Sorry for late reply.

    The logs (the one on the bottom) doesn't really show a problem. It's trying to write out another byte to the I2C controller but it doesn't look like it's getting another I2C interrupt. Have the interrupts for the I2C, NVIC/Hwi module been disabled?

    I don't see it in the code snippets, but I can see that you have several other Tasks running. Are any of them disabling interrupts?