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/TMP116: RTOS/TMP

Part Number: TMP116
Other Parts Discussed in Thread: CC1310, , SYSBIOS

Tool/software: TI-RTOS

Hello, 

I have a custom PCB (cc1310) interfaced with a sensor type TMP 116, when measuring the current consumption I found 130 micro amp, the latter is still active mode. my question how to make it in standby mode?

  • Hi abdelkader,

    To put TMP116 into Shutdown mode, you must set the MOD bits to 01 in the Configuration Register. See Table 6 on page 25 of the datasheet. Shutdown is the lowest power mode for TMP116, because it disables temperature measurements.

    Thanks,
    Ren
  • Hello and thank you for your reply,

    I used the example provided by texas instrument Sail Library, my code contains threads. my question to what threads is the cause of power consumption.

    Here is my code:

    ----------------------------------------Main---------------------------------------------------------------------------------------------------------------------------------
    * POSIX Header files */
    #include <pthread.h>
    #include <stdlib.h>
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    #include <stdint.h>
    #include <stddef.h>
    #include <unistd.h>
    #include <semaphore.h>

    /* BIOS Header files */
    #include <ti/drivers/rf/RF.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/I2C.h>

    /* TI-RTOS Header files */
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/Power.h>

    #include <ti/devices/cc13x0/driverlib/aon_batmon.h>
    #include <ti/devices/cc13x0/driverlib/aux_adc.h>
    #include <ti/devices/cc13x0/driverlib/chipinfo.h>
    #include <ti/devices/cc13x0/driverlib/sys_ctrl.h>
    #include <semaphore.h>
    #include <ti/sail/tmp116/tmp116.h>

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

    /* EasyLink API Header files */
    #include "easylink/EasyLink.h"



    #include "version.h"
    #include "../sonde_gw_fw/sys_intf.h"

    #include <string.h>
    #include <math.h>

    #define RFEASYLINKTX_TASK_STACK_SIZE 1024
    #define RFEASYLINKTX_TASK_PRIORITY 2

    #define RFEASYLINKTX_BURST_SIZE 1
    #define THREADSTACKSIZE 768

    #define SAMPLE_TIME 1 /*In seconds*/
    #define TMP_TASK_STACK_SIZE 768

    TMP116_Handle tmp116Handle = NULL;
    I2C_Handle i2cHandle = NULL;
    sem_t tmp116Sem;

    uint8_t SavedBattery;


    /* Global sample rate which may be accessed and set from GUI Composer App */
    volatile uint16_t sampleTime;

    /*
    * ======== tmp116Callback ========
    * When an ALERTing condition is met on the TMP116 hardware, the ALERT pin
    * is asserted generating an interrupt. This callback function serves as
    * an ISR for a single TMP116 sensor.
    */
    void tmp116Callback(uint_least8_t index)
    {
    sem_post(&tmp116Sem);
    }

    /*
    * ======== tmp116AlertTask ========
    * This task is unblocked when the ALERT pin is asserted and generates an
    * interrupt. When the TMP116 is in INTERRUPT mode, the status register must
    * be read to clear the ALERT pin.
    */

    void *tmp116AlertTask(void *arg0)
    {
    uint16_t data;

    while(1) {

    /* Pend on semaphore, tmp116Sem */
    if (0 == sem_wait(&tmp116Sem)) {

    /* Reads status register, resetting the ALERT pin */
    TMP116_readStatus(tmp116Handle, &data);

    /* Check Object Temperature High Flag */
    if (data & TMP116_STAT_ALR_HI) {
    }

    /* Check Object Temperature Low Flag */
    if (data & TMP116_STAT_ALR_LO) {
    }

    }
    }
    }

    Task_Struct txTask; /* not static so you can see in ROV */
    static Task_Params txTaskParams;
    static uint8_t txTaskStack[RFEASYLINKTX_TASK_STACK_SIZE];

    Task_Struct sensorTask; /* not static so you can see in ROV */
    static Task_Params sensorTaskParams;
    static uint8_t sensorTaskStack[RFEASYLINKTX_TASK_STACK_SIZE];

    typedef struct {
    uint8_t reason;
    int8_t temp_deg_frac_8;
    uint8_t temp_deg_frac_8_vir;
    uint8_t bat_20mV;
    } opto_sonde_data_t;

    typedef struct {
    int8_t temp_MSB;
    uint8_t temp_LSB;
    }data_t;

    void sleepAndReset(uint32_t sleep_time_secs) {

    uint32_t secs = sleep_time_secs;
    while (secs > 0)
    {
    uint32_t sleep_s = secs > 2000 ? 2000 : secs;
    Task_sleep((sleep_s * 1000u * 1000) / Clock_tickPeriod);
    secs -= sleep_s;
    }

    SysCtrlSystemReset();
    }

    static void rfEasyLinkTxFnx(UArg arg0, UArg arg1)
    {

    opto_sonde_data_t* optosonde_data = (opto_sonde_data_t*) arg0;

    EasyLink_init(EasyLink_Phy_Custom);

    /*
    * If you wish to use a frequency other than the default, use
    * the following API:
    * EasyLink_setFrequency(868000000);
    */

    /* Set output power to 12dBm */
    // EasyLink_setRfPwr(12);
    EasyLink_setRfPwr(10);

    EasyLink_TxPacket txPacket;

    // Fill packet data
    uint8_t payload_ptr = 0;
    // Payload version
    txPacket.payload[payload_ptr++] = (uint8_t) (0x0);
    // Src MAC
    EasyLink_getIeeeAddr(&txPacket.payload[payload_ptr]);
    payload_ptr += 8;

    // Copy data
    txPacket.payload[payload_ptr++] = (uint8_t) (optosonde_data->reason);
    txPacket.payload[payload_ptr++] = (uint8_t) (optosonde_data->temp_deg_frac_8 );
    txPacket.payload[payload_ptr++] = (uint8_t) (optosonde_data->temp_deg_frac_8_vir);
    txPacket.payload[payload_ptr++] = (uint8_t) (optosonde_data->bat_20mV);
    // Firmware version
    memcpy(&txPacket.payload[payload_ptr], &VERSION_HASH, sizeof(VERSION_HASH));
    payload_ptr += sizeof(VERSION_HASH);

    txPacket.len = payload_ptr;
    txPacket.absTime = 0;
    txPacket.dstAddr[0] = OPTOSONDE_ADDR;

    EasyLink_Status result = EasyLink_transmit(&txPacket);

    if (result == EasyLink_Status_Success)
    {
    /* Toggle LED1 to indicate TX */
    // PIN_setOutputValue(pinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1));
    }
    else
    {
    /* Toggle LED1 and LED2 to indicate error */
    // PIN_setOutputValue(pinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1));
    // PIN_setOutputValue(pinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2));
    }

    Task_sleep(5);
    }

    void sendorTask_AlertCB(UArg arg0, UArg arg1)
    {
    static opto_sonde_data_t optosonde_data;
    optosonde_data.reason = optosonde_reason_periodic;
    data_t* temptread =(data_t* )arg0;

    optosonde_data.temp_deg_frac_8 = (temptread->temp_MSB);
    optosonde_data.temp_deg_frac_8_vir = (temptread->temp_LSB);
    if (!AONBatMonNewBatteryMeasureReady())
    {
    // Wait
    optosonde_data.bat_20mV =SavedBattery;
    }
    else{
    SavedBattery = (AONBatMonBatteryVoltageGet() * 390625) / 2000000;
    optosonde_data.bat_20mV = SavedBattery;
    AONBatMonDisable();

    }

    // Init Tx task
    Task_Params_init(&txTaskParams);
    txTaskParams.stackSize = RFEASYLINKTX_TASK_STACK_SIZE;
    txTaskParams.priority = RFEASYLINKTX_TASK_PRIORITY + 1;
    txTaskParams.stack = &txTaskStack;
    txTaskParams.arg0 = (xdc_UArg) &optosonde_data;

    Task_construct(&txTask, rfEasyLinkTxFnx, &txTaskParams, NULL);

    }


    /*
    * ======== mainThread ========
    */
    void *mainThread(void *argc)
    {

    static data_t temptread;
    int8_t MSB;
    uint8_t LSB;
    float tempToread;
    I2C_Handle i2cHandle;
    I2C_Params i2cParams;
    int retc;
    pthread_t alertTask;
    pthread_attr_t pAttrs;
    sampleTime = SAMPLE_TIME;
    TMP116_Params tmp116Params;

    /* Call driver init functions */
    //GPIO_init();
    I2C_init();
    TMP116_init();


    /* Create I2C for usage */
    I2C_Params_init(&i2cParams);

    i2cParams.bitRate = I2C_400kHz;

    i2cHandle = I2C_open(Board_I2C_TMP, &i2cParams);
    if (i2cHandle == NULL) {
    while (1);
    }
    else {
    }

    if(0 != sem_init(&tmp116Sem,0,0))
    {
    /* sem_init() failed */
    while (1);
    }

    pthread_attr_init(&pAttrs);
    pthread_attr_setstacksize(&pAttrs, TMP_TASK_STACK_SIZE);
    retc = pthread_create(&alertTask, &pAttrs, tmp116AlertTask, NULL);
    if (retc != 0) {
    /* pthread_create() failed */
    while (1);
    }

    /* Initialize tmp116Params structure to defaults */
    TMP116_Params_init(&tmp116Params);

    /* Callback for ALERT event */
    tmp116Params.callback = &tmp116Callback;

    /* Open TMP116 sensor with custom Params */
    tmp116Handle = TMP116_open(Board_TMP007_ROOMTEMP, i2cHandle, &tmp116Params);

    /* Check if the open is successful */
    if (tmp116Handle == NULL) {
    while(1);
    }

    /* Allow the sensor hardware to complete its first conversion */
    sleep(2);


    /* Get Die Temperature in Celsius */
    if (!TMP116_getTemp(tmp116Handle, TMP116_CELSIUS,&tempToread)) {

    }

    /* Begin infinite task loop */
    while (1) {

    TMP116_getTemp(tmp116Handle, TMP116_CELSIUS, &tempToread);
    /* Get Die and Object Temperatures */
    MSB = (int8_t )tempToread;
    LSB = (uint8_t )((tempToread-MSB) * 100);
    temptread.temp_MSB=MSB;
    temptread.temp_LSB=LSB;

    // Sensor task
    Task_Params_init(&sensorTaskParams);
    sensorTaskParams.stackSize = RFEASYLINKTX_TASK_STACK_SIZE;
    sensorTaskParams.priority = RFEASYLINKTX_TASK_PRIORITY;
    sensorTaskParams.stack = &sensorTaskStack;
    sensorTaskParams.arg0 = (xdc_UArg) &temptread;

    Task_construct(&sensorTask, sendorTask_AlertCB, &sensorTaskParams, NULL);

    // Tell RTC to sleep
    #ifdef OPTOSONDE_DEMO_MODE
    uint32_t sleep_time_s = 30;
    #elif OPTOSONDE_VITICODE
    uint32_t sleep_time_s = 10 * 60;
    #else
    uint32_t sleep_time_s = 1 *60;
    #endif

    sleepAndReset(sleep_time_s);

    }
    }

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

    void maini2c(void)
    {
    pthread_t thread;
    pthread_attr_t pAttrs;
    struct sched_param priParam;
    int retc;
    int detachState;

    /* Set priority and stack size attributes */
    pthread_attr_init(&pAttrs);
    priParam.sched_priority = 1;

    detachState = PTHREAD_CREATE_DETACHED;
    retc = pthread_attr_setdetachstate(&pAttrs, detachState);
    if (retc != 0) {
    // /* pthread_attr_setdetachstate() failed */
    while (1);
    }

    pthread_attr_setschedparam(&pAttrs, &priParam);

    retc |= pthread_attr_setstacksize(&pAttrs, THREADSTACKSIZE);
    if (retc != 0) {
    /* pthread_attr_setstacksize() failed */
    while (1);
    }

    retc = pthread_create(&thread, &pAttrs, mainThread, NULL);
    if (retc != 0) {
    /* pthread_create() failed */
    while (1);
    }

    /* destroy pthread attribute */
    pthread_attr_destroy(&pAttrs);
    }


    int opto_main(void)
    {

    /* Call driver init functions. */
    maini2c();
    Board_initGeneral();

    /* Start BIOS */
    BIOS_start();

    return (0);
    }
  • Hi abdelkader,

    Please direct your software questions to the CC1310 team in their forum.
    e2e.ti.com/.../

    Thanks,
    Ren
  • Hello and thank you for the reply,
    Just a quick question on the example used for the TMP 116 sensor (sail library), which conversion mode is used? and how ?
  • Hi abdelkader,

    The Conversion Mode is most likely 00: Continuous Conversion. This is the default Conversion Mode. In this mode, the device performs temperature measurements at intervals specified by the CONV bits. This temperature information is stored in Temperature Register 00h and overwritten when a new temperature measurement completes. When querying the Temperature Register using I2C Read transaction, the most recent value is retrieved. There's no need to initialize the device or perform other I2C transactions prior to using the device in this manner.

    To use Shutdown as your Conversion Mode, you must command the TMP116 to perform temperature measurements. If you do not do this, the value in the Temperature Register will never update. To command the device to update temperature, you use the One Shot Conversion Mode MOD = 11b. Each time you write to the Configuration Register with MOD = 11b, the TMP116 will start a temperature measurement.

    Thanks,
    Ren
  • Hello and thank you very much for this explanation,
    Can I write my code without the threads for reading the temperature? Why are threads on the example given by the library "sail"?
  • Hi abdelkader,

    Please direct your software questions to the CC1310 team in their forum.
    e2e.ti.com/.../

    Thanks,
    Ren