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/EK-TM4C1294XL: can't read the data from opt3001 called inside a task using I2C

Part Number: EK-TM4C1294XL
Other Parts Discussed in Thread: OPT3001

Tool/software: TI-RTOS

Hi, 

I'm trying to read the lux value from opt3001 sensor in Sensor BoosterPack attached on EK-TM4C129. The problem is that I don't really know how to read the data from the sensor. I'm able to set the register configuration by writing. Also, i came across all the I2C examples but none of them used readbuffer from I2C except the RF example, which i'm trying to do the same but with the opt3001, but the problem is that they didn't use the function to read the buffer. can anyone guide me or write a function and use it to read the lux?? I've done the same code in a normal project, and it works fine (no TI-RTOS). please have a look at the C file. Thank you very much. 

/* XDCtools Header files */

#include <Board.h>
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <ti/drivers/GPIO.h>
#include <ti/drivers/I2C.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
#include <xdc/runtime/System.h>
#include <xdc/std.h>

// Register addresses
#define REG_RESULT                      0x00
#define REG_CONFIGURATION               0x01
#define REG_LOW_LIMIT                   0x02
// Register values
#define CONFIG_ENABLE                   0x70C4
#define LOW_LIMIT_REG_ENABLE            0xFF0F // 0x0FFFF
// Bit values
#define DATA_RDY_BIT                    0x0080  // Data ready

#define TASKSTACKSIZE   768

Bool SensorOpt3001ReadLight(uint16_t *rawData);
void SensorOpt3001ReadConfig(uint16_t *rawData);
void SensorOpt3001ReadResult(uint16_t *rawData);
void SensorOpt3001Convert(uint16_t rawData, float *convertedLux);


Task_Struct         task0Struct;
Task_Params         taskParams;
Char                task0Stack[TASKSTACKSIZE];
I2C_Handle          i2c;

void writeI2C(I2C_Handle handle, uint8_t regAddr, uint16_t value) {

    uint8_t             writeBuffer[3];
    I2C_Transaction     i2cTransaction;

    i2cTransaction.slaveAddress = Board_OPT3001_ADDR;
    /* Write to a 16-bit status register */
    i2cTransaction.writeBuf = writeBuffer;
    i2cTransaction.writeCount = 3;
    i2cTransaction.readCount = 0;

    writeBuffer[0] = regAddr;
    writeBuffer[1] = value >> 8;   //HIGHER BYTE value
    writeBuffer[2] = value & 0xFF; //LOWER BYTE value

    if (!I2C_transfer(handle, &i2cTransaction)) System_abort("Bad I2C Write transfer!");
    else System_printf("writeI2C sent\n");
    System_flush();
}

void readI2C(I2C_Handle handle, uint8_t regAddr, uint16_t *data) {

    uint8_t             writeBuffer[1];
    uint8_t             readBuffer[2];
    I2C_Transaction     i2cTransaction;

    i2cTransaction.slaveAddress = Board_OPT3001_ADDR;

    /* Write to a 16-bit status register */
    i2cTransaction.writeBuf = writeBuffer;
    i2cTransaction.readBuf = readBuffer;
    i2cTransaction.writeCount = 1;
    i2cTransaction.readCount = 2;

    writeBuffer[0] = regAddr;        // READ Addr
    if (!I2C_transfer(handle, &i2cTransaction)) System_abort("Bad I2C Read transfer!");
    Task_sleep(200);
    *data =  ((uint16_t)readBuffer[0] << 8) + readBuffer[1];
    Task_sleep(200);
}

Bool SensorOpt3001ReadLight(uint16_t *rawData) {

    Bool success;
    readI2C(i2c, REG_CONFIGURATION, (uint16_t *)rawData);
    Task_sleep(100);
    success = ( *rawData & DATA_RDY_BIT) == DATA_RDY_BIT;

    if (success) {
        readI2C(i2c, REG_RESULT, (uint16_t *)rawData);
        Task_sleep(100);
    } else {
        *rawData = 0;
    }

    return success;
}

void SensorOpt3001Convert(uint16_t rawData, float *convertedLux) {
    uint16_t e, m;
    m = rawData & 0x0FFF;
    e = (rawData & 0xF000) >> 12;
    *convertedLux = m * (0.01 * exp2(e));
}

void opt3001SensorFxn() {

    I2C_Params          i2cParams;
    uint16_t            rawData;
    Bool                success;
    float               lux;

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

    /* Reset the sensor for low-limit reg and wait */
    writeI2C(i2c, REG_CONFIGURATION, CONFIG_ENABLE);
    Task_sleep(1000);
    writeI2C(i2c, REG_LOW_LIMIT, LOW_LIMIT_REG_ENABLE);
    Task_sleep(1000);

    while (1) {
        success = SensorOpt3001ReadLight(&rawData);
        if (success) {
            SensorOpt3001Convert(rawData, &lux);
            System_printf("lux:%0.2f\n", lux);
        }
        System_flush();
    }
}

void opt3001SensorTask() {
    Task_Params_init(&taskParams);
    taskParams.stackSize = TASKSTACKSIZE;
    taskParams.stack = &task0Stack;
    taskParams.instance->name = "opt3001SensorTask";
    taskParams.priority = 1;
    Task_construct(&task0Struct, (Task_FuncPtr)opt3001SensorFxn, &taskParams, NULL);
}

/*
 *  ======== main ========
 */
int main(void) {
    /* Call board init functions */
    Board_initGeneral();
    Board_initGPIO();
    Board_initI2C();

    opt3001SensorTask();

     /* Turn on user LED */
    GPIO_write(Board_LED0, Board_LED_ON);
    System_printf("Starting the 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);
}