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.

RTOS/TM4C1294NCPDT: I2C_transfer() function in TI RTOS

Part Number: TM4C1294NCPDT
Other Parts Discussed in Thread: SYSBIOS, TMP006, TMP102

Tool/software: TI-RTOS

Hi,

/* Below is my sample code */

/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/System.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>

/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/I2C.h>

/* Example/Board Header files */
#include "Board.h"

#define TASKSTACKSIZE       640

Task_Struct task0Struct;
Char task0Stack[TASKSTACKSIZE];

Task_Struct task1Struct;
Char task1Stack[TASKSTACKSIZE];

/*
 *  ======== taskFxn ========
 *  Task for this function is created statically. See the project's .cfg file.
 */

void i2cfunc()
{
 unsigned int    i;
     uint16_t        temperature;
     uint8_t         txBuffer[1];
     uint8_t         rxBuffer[2];
     I2C_Handle      i2c;
     I2C_Params      i2cParams;
     I2C_Transaction i2cTransaction;

     /* Create I2C for usage */
     I2C_Params_init(&i2cParams);
     i2cParams.bitRate = I2C_400kHz;
     i2c = I2C_open(Board_I2C_TMP, &i2cParams);
     if (i2c == NULL) {
         System_abort("Error Initializing I2C\n");
     }
     else {
         System_printf("I2C Initialized!\n");
     }

     /* Point to the T ambient register and read its 2 bytes */
     txBuffer[0] = 0x01;
     i2cTransaction.slaveAddress = Board_TMP006_ADDR;
     i2cTransaction.writeBuf = txBuffer;
     i2cTransaction.writeCount = 1;
     i2cTransaction.readBuf = rxBuffer;
     i2cTransaction.readCount = 2;

     /* Take 20 samples and print them out onto the console */
     for (i = 0; i < 20; i++) {
         if (I2C_transfer(i2c, &i2cTransaction)) {
             /* Extract degrees C from the received data; see TMP102 datasheet */
             temperature = (rxBuffer[0] << 6) | (rxBuffer[1] >> 2);

             /*
              * If the MSB is set '1', then we have a 2's complement
              * negative value which needs to be sign extended
              */
             if (rxBuffer[0] & 0x80) {
                 temperature |= 0xF000;
             }
            /*
             * For simplicity, divide the temperature value by 32 to get rid of
             * the decimal precision; see TI's TMP006 datasheet
             */
             temperature /= 32;

             System_printf("Sample %u: %d (C)\n", i, temperature);
         }
         else {
             System_printf("I2C Bus fault\n");
         }

         System_flush();
         Task_sleep(1000);
     }

     /* Deinitialized I2C */
     I2C_close(i2c);
     System_printf("I2C closed!\n");

     System_flush();
}

Void taskFxn(UArg arg0, UArg arg1)
{
 i2cfunc();
}

/*
 *  ======== main ========
 */
int main(void)
{
    Task_Params taskParams;
    Task_Params task1Params;

    /* Call board init functions */
    Board_initGeneral();
    Board_initGPIO();
    Board_initI2C();

    /* Construct tmp006 Task thread */
    Task_Params_init(&taskParams);
    taskParams.stackSize = TASKSTACKSIZE;
    taskParams.stack = &task0Stack;
    Task_construct(&task0Struct, (Task_FuncPtr)taskFxn, &taskParams, NULL);

    /* Turn on user LED */
    GPIO_write(Board_LED0, Board_LED_ON);

    System_printf("Starting the I2C example\nSystem provider is set to SysMin."
                  " Halt the target to view any SysMin contents in ROV.\n");
    /* SysMin will only print to the console when you call flush or exit */
    System_flush();

    /* Start BIOS */
    BIOS_start();

    return (0);
}

This program is working fine with single task, But if I use multiple task the I2C transfer function is not working.

Question :

1. Why the (I2C_transfer(i2c, &i2cTransaction)) is working fine with single task and not with multiple task?

2. What should I do to have a complete transfer of the I2C_transfer call.

3. I have increased the stack size of the task and the priority of the task. In both the way I2C transfer is not completed.

4.It seems like before the I2C transfer, other task are serviced by the processor. is it so? how to resolve it?

  • Hi,
    Is this only a snippet of your code? I don't see multiple tasks but only one i2c task. I see that you have created one task using Task_construct(&task0Struct, (Task_FuncPtr)taskFxn, &taskParams, NULL). If you have multiple tasks you will need to call Task_construct for each.
  • Also, are both tasks trying to open the same I2C instance (e.g. i2c = I2C_open(Board_I2C_TMP, &i2cParams)). You can only call open once. If you need to have multiple tasks use the same handle, only call open once and then have the tasks use that same handle.

    Todd