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/CC1310: CC1310 I2C problem

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

Tool/software: TI-RTOS

I want to read data from Al3010(ambient sensor) by I2C

However,my code always stock in  

I2C_transfer(i2c, &i2cTransaction);

And don't work.

Could help me to know what happen?

Thanks.

Following code is My code .c 

#include <xdc/std.h>
#include <xdc/runtime/System.h>

#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>

#include <ti/drivers/PIN.h>
#include <ti/drivers/I2C.h>

#include "Board.h"

#define TASKSTACKSIZE 640

Task_Struct task0Struct;
Char task0Stack[TASKSTACKSIZE];


int main(void)

{


Bool transferOK;
int i;
uint8_t txBuffer[1];
uint8_t rxBuffer[2];
I2C_Handle i2c;
I2C_Params i2cParams;
I2C_Transaction i2cTransaction;
uint16_t ambientlight;

Board_initGeneral();
Board_initGPIO();
Board_initI2C();

I2C_Params_init(&i2cParams);

i2cParams.bitRate = I2C_400kHz;
i2c = I2C_open(Board_I2C_TMP, &i2cParams);
if (i2c == NULL) {
System_printf("Error Initializing I2C\n");
}
else {
System_printf("I2C Initialized!\n");
}

txBuffer[0] = 0x01;
i2cTransaction.slaveAddress = 0x1c;
i2cTransaction.writeBuf = NULL;
i2cTransaction.writeCount = 0;
i2cTransaction.readBuf= rxBuffer;
i2cTransaction.readCount = 2;
transferOK = I2C_transfer(i2c, &i2cTransaction);

  if (!transferOK) {   System_printf("I2C Bus fault\n");}

for (i=0;i<=1;i++) {

ambientlight=rxBuffer[0];
System_printf("rxBuffer[0] is %d \n", ambientlight);
ambientlight=rxBuffer[1];
System_printf("rxBuffer[1] is %d \n",ambientlight);

}



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

System_flush();

return (0);
}

  • linder,

    I think the reason the I2C_transfer() call is stuck is because you’re calling it within main(), before the kernel has been started, and before interrupts have been enabled.  Usually for TI-RTOS apps there will be a call to BIOS_start() at the end of main(), which finishes startup of kernel modules, and enables interrupts.

    If you add a call to BIOS_start() at the end of main(), and then do the I2C_transfer() from a Task context, does that work?

    Thanks,
    Scott

  • thank you! I have change my code


    #include <xdc/std.h>
    #include <xdc/runtime/System.h>

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

    /* TI-RTOS Header files */
    #include <ti/drivers/I2C.h>
    #include <ti/drivers/PIN.h>
    // #include <ti/drivers/SPI.h>
    // #include <ti/drivers/UART.h>
    // #include <ti/drivers/Watchdog.h>

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

    #define TASKSTACKSIZE 640

    Task_Struct task0Struct;
    Char task0Stack[TASKSTACKSIZE];

    /* Pin driver handle */

    /*
    * Application LED pin configuration table:
    * - All LEDs board LEDs are off.
    */


    Void taskFxn(UArg arg0, UArg arg1)
    {
    unsigned int i;
    uint16_t ambientlight;
    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 = 0x1C;
    i2cTransaction.writeBuf = txBuffer;
    i2cTransaction.writeCount = 0;
    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 */
    ambientlight = (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) {
    ambientlight |= 0xF000;
    }

    ambientlight /= 32;

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

    System_flush();
    Task_sleep(1000);
    }

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

    System_flush();
    }



    * ======== main ========
    */

    int main(void)
    {
    Task_Params taskParams;

    /* 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 */



    /* SysMin will only print to the console when you call flush or exit */
    System_flush();

    /* Start BIOS */
    BIOS_start();

    return (0);
    }

    However, i always get "I2C Bus fault"
    It seems my I2C_transfer(i2c, &i2cTransaction) is always fault.
    Could any possible problem happened in my code?
  • I think you are intending to write a byte to specify a register address to read from, but are specifying a writeCount of zero:

    linder wu said:

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

  • There was a suggested answer and since there has been no active on this thread for more than a week, the suggested answer was marked as verify. Please feel free to select the "Reject Answer" button and reply with more details.