TMDX570LC43HDK: ADC count showing unexpected value from Temperature Sensor

Part Number: TMDX570LC43HDK
Other Parts Discussed in Thread: HALCOGEN

Tool/software:

Hello,

I followed below link and trying to read the Junction temperature on ADC2 module from Temperature Sensor - 3. The ADC count seems to be suspicious.

ADC value = 1351  (With different application like FreeRTOS application with busy loop, I get 1481 ....)

Slope and Offset calculated from Calibration Data, offset = 170.50, slope = 0.17

JunctionTempK = (((float)value) - Thermistor_Fit.offset) * Thermistor_Fit.slope;

With the above , JunctionTempK = (1351  - 170.50) * 0.17 = 200.68K => this is too cold. with 1481 it comes to 222.78 which looks suspicious. 

I think the pimux/ADC registers seem to be correct, as I see the ADC count changing depending on load on the MCU. Do I need to use any scaling factor, what am I missing?

Note - I have not modified any code , just using the source code from below link.

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1138183/faq-tms570lc4357-there-are-three-instances-of-temperature-sensors-in-this-mcu-how-to-configure-the-pin-multiplexing-pinmux-to-select-adc-pins-for-those-temperature-sensors?tisearch=e2e-sitesearch&keymatch=%252525252522TMS570LC4357%252525252522

Regards,

Sarbeswar

  • Hi Sarbeswar,

    Can you share the sensor's calibration data stored in OTP at 0xF0080330h-0xF008033Fh

  • Hi Wang, 

    Here is the data you had requested.

                                                                                                           ADC | Kelvin
    Address[0xF0080330], data = [0x79A012F] => 0x079A 012F => 1946 | 303
    Address[0xF0080334], data = [0x60E00E9] => 0x060E 00E9 => 1550 | 233
    Address[0xF0080338], data = [0x9D9018E] => 0x09D9 018E => 2521 | 398
    Address[0xF008033C], data = [0xFFFFFFFF] => 0xFFFF FFFF => 65535|65535

  • I got the same offset and slope for sensor 3.

    === sensor 3 ====
    303K ( 90°C, 0x12F) = 1946 (0x79A)
    233K (-40°C, 0x0E9) = 1550 (0x60E)
    398K (125°C, 0x18E) = 2521 (0x9D9)

    slope =0.17
    offset=170.5

    When you collected the ADC value, did you measure the junction temperature or temperature in the chamber?

  • Hi Wang,

    Do you mean to measure the junction temperature physically or a temperature gun? Sorry I did not get it? As I mentioned earlier, the calculated temperature from the slope and offset, does not look correct. It is too cold. Now while the board is up and running, 1 ft above the board, with a temperature gun (point to the MCU chip), it shows 116 degree F (273.15 + 116 = 389.15K).

  • Thanks. What's the sampled ADC values (sensor 1/2/3) at temperature Gun=116°C?

  • Sorry, by mistake I clicked on "Resolved". Please keep it open.

    Currently I am collecting samples periodically and it shows, 1368, 1370, 1369....

  • Note that, I am currently collecting from Sensor - 3. I have not tried Sensor 1 and Sensor 2 yet.

  • What is the ADC configuration: sampling time, discharge time, and ADC clock? 

    Is ADREFHI 3.3V and ADREFLO 0V on your board? A difference on ADREF of 5% can result in the calculations being off by 22°C at 125°C junction temperature.

    MibAC2 channel 30 is used to sample sensor 3. 

  • Above - ADC configuration. Below code ,

    /*
    * TempSensor.c
    *
    * Copyright (C) 2009-2015 Texas Instruments Incorporated - www.ti.com
    *
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    *
    * Redistributions of source code must retain the above copyright
    * notice, this list of conditions and the following disclaimer.
    *
    * Redistributions in binary form must reproduce the above copyright
    * notice, this list of conditions and the following disclaimer in the
    * documentation and/or other materials provided with the
    * distribution.
    *
    * Neither the name of Texas Instruments Incorporated nor the names of
    * its contributors may be used to endorse or promote products derived
    * from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    */

    #include "HL_sys_common.h"
    #include "HL_adc.h"
    #include "HL_pinmux.h"
    #include "TempSensor.h"

    #include "app_utils.h"

    /*
    * HALCoGen Setup
    * File -> New -> Project
    * Family -> Hercules
    * Device -> <TMS570LC43xx/RM48x>
    * Ok
    *
    * Driver Enable
    * - Enable ADC, [SCI1 and GIO](optional for debug), drivers
    *
    *
    * Select the target <TMS570LC43xx/RM48x>
    *
    * Uncheck default file location and point to the HALCoGen project path
    *
    * Use the same project name as the HALCoGen project.
    *
    * Select empty project without main.c
    *
    * Finish
    *
    * Open the project properties
    *
    * CCS Build -> ARM Compiler -> include option
    *
    * Add a new #include search path "../include"
    *
    */
    /* Thermistor */
    //#ifndef __little_endian__
    //#define __little_endian__ 0
    //#endif

    #if __little_endian__
    typedef struct OTP_temperature_calibration_data
    {
    uint16_t Temperature;
    uint16_t AdcValue;
    } OTP_temperature_calibration_data_t;
    #else
    typedef struct OTP_temperature_calibration_data
    {
    uint16_t AdcValue;
    uint16_t Temperature;
    } OTP_temperature_calibration_data_t;
    #endif

    #define THERMISTOR_CAL_DATA 0xF0080310 /* OTP Temperature Sensor Data Location */

    typedef struct Thermistor_Calibration
    {
    float slope;
    float offset;
    float rsquared;
    } Thermistor_CAL_t;


    static Thermistor_CAL_t Thermistor_Fit = {0.0, 0.0, 0.0};


    /*************************************************************/
    /**** Start of Temp Sensor functions ***/
    /*************************************************************/

    /** @fn float thermistor_read(void)
    * @brief read on-chip thermistor 3
    * @note This will return the temperature of thermistor 3 in Kelvin
    *
    * This requires adcInit() to be called before to setup ADC2.
    *
    * This function will modify the Pin Muxing and ADC2 to read the thermistor,
    * care has been taken to restore modified configurations however the user is
    * responsible for verifying both the Pin Muxing and ADC are configured
    * as desired.
    *
    * The returned temperature will need to be scaled by the reference voltage difference
    * Calibration values are taken at nominal voltage 3.30V.
    *
    * Kelvin = ReturnValue * (VccADrefHi - VccADrefLow)/3.30V
    * Celsius = Kelvin - 273.15;
    * Fahrenheit = (Kelvin - 273.15) * 1.8 + 32;
    *
    */
    float thermistor_read(float *temp)
    {
    unsigned int value, pinmux_restore, GxSEL_restore;
    volatile float JunctionTempK = 0.0;
    adcBASE_t *adcreg;

    /* Select the ADC */
    adcreg = adcREG2;

    if(adcreg->G1SR != 0x00000008 )
    return (-1.0); // Group 1 is being used

    /* Check that we have valid calibration data */
    if(Thermistor_Fit.rsquared == 0.0)
    return (-2.0); //Calibration data missing, must run thermistor_calibration() first

    /* Enable Temperature Sensors in Pin Muxing */

    /* Enable Pin Muxing */
    pinMuxReg->KICKER0 = 0x83E70B13U;
    pinMuxReg->KICKER1 = 0x95A4F1E0U;

    /* Enable Temp Sensor */
    pinMuxReg->PINMUX[174] &= 0xFEFFFFFF;

    /* Connect Sensor 3 - Temperature sensor 3's output is connected to AD2IN[30] */
    pinmux_restore = pinMuxReg->PINMUX[174];
    pinMuxReg->PINMUX[174] = (pinMuxReg->PINMUX[174] & 0xfffffffe) | 0x00000002;

    /* Start Converting, Choose Channel */
    GxSEL_restore = adcreg->GxSEL[1U]; // Save the original value in the channel select register
    adcreg->GxSEL[1U] = 0x40000000;

    /* Poll for end of Conversion */
    while(!(adcreg->G1SR & 1));

    /* Read adc value */
    value = adcreg->GxBUF[1U].BUF0;

    /* Disable Temperature Sensor */
    pinMuxReg->PINMUX[174] |= 0x01000000;

    /* Restore Sensor 3 Pin Muxing */
    pinMuxReg->PINMUX[174] = pinmux_restore;

    /* Disable Pin Muxing */
    pinMuxReg->KICKER0 = 0x00000000U;
    pinMuxReg->KICKER1 = 0x00000000U;

    /* Restore Channel Select Register */
    adcreg->GxSEL[1U] = GxSEL_restore;

    /* Convert ADC value into floating point temp Kelvin */
    JunctionTempK = (((float)value) - Thermistor_Fit.offset) * Thermistor_Fit.slope;
    //JunctionTempK = (((float)value) + Thermistor_Fit.offset) * Thermistor_Fit.slope; //SMSM - temporary adjustment, waiting on TI ticket
    *temp = JunctionTempK;
    print2Console("Value = %d, temp = %.2f\r\n", value, *temp);
    return JunctionTempK;
    } // thermistor_read


    /** @fn void thermistor_calibration(void)
    * @brief Load the thermister calibration information
    * @note
    */
    bool thermistor_calibration(void)
    {
    OTP_temperature_calibration_data_t *OTPdataptr;
    int i, cal_data_count=0;
    float slope,offset,sumtemp=0,sumconv=0,sumtempxconv=0,sumtempxtemp=0;
    float cal_adc_code_array[4],avgconv,cal_temperature_array[4],yx=0.0,ya=0.0,ym,yn;

    /* Create pointer to temp sensor 3 calibration data */
    OTPdataptr = (OTP_temperature_calibration_data_t *)(THERMISTOR_CAL_DATA + (2 * 0x10));

    //Dump Calibration Data for all 3 Sensors - Debug purpose
    uint32_t *raw = (uint32_t *) (THERMISTOR_CAL_DATA + (0 * 0x10));
    print2Console("Address[0x%X], value = [0x%X]\r\n", raw, *raw);
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+1), *(raw+1));
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+2), *(raw+2));
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+3), *(raw+3));
    raw = (uint32_t *) (THERMISTOR_CAL_DATA + (1 * 0x10));
    print2Console("Address[0x%X], value = [0x%X]\r\n", raw, *raw);
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+1), *(raw+1));
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+2), *(raw+2));
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+3), *(raw+3));
    raw = (uint32_t *) (THERMISTOR_CAL_DATA + (2 * 0x10));
    print2Console("Address[0x%X], value = [0x%X]\r\n", raw, *raw);
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+1), *(raw+1));
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+2), *(raw+2));
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+3), *(raw+3));

    /* Check for valid calibration data */
    /* Valid codes are 0 to 0xFFF, valid temperatures are 0 to 400 kelvin */
    for(i = 0; i < 4; i++)
    {

    /* Calculate Slope and Offset for the 4 possible value pairs */
    if((OTPdataptr[i].AdcValue < 0xFFF) && (OTPdataptr[i].Temperature < 401))
    {
    /* Load valid calibration information */
    cal_temperature_array[i] = (float)(OTPdataptr[i].Temperature);
    cal_adc_code_array[i] = (float)OTPdataptr[i].AdcValue;
    sumtemp += cal_temperature_array[i];
    sumconv += cal_adc_code_array[i];
    sumtempxconv += cal_temperature_array[i] * cal_adc_code_array[i];
    sumtempxtemp += cal_temperature_array[i] * cal_temperature_array[i];
    cal_data_count++;
    }
    }

    /* Calculate slope and Offset for the 4 possible value pairs */
    if(cal_data_count < 2)
    return FALSE;
    else
    {
    slope = (sumtempxtemp * cal_data_count - sumtemp * sumtemp) /
    (sumtempxconv * cal_data_count - sumtemp * sumconv);
    offset = (sumconv - sumtemp / slope) / cal_data_count;
    Thermistor_Fit.slope = slope;
    Thermistor_Fit.offset = offset;
    avgconv = sumconv / cal_data_count;
    }

    /* Calculate R-Squared Value */
    for(i = 0; i < cal_data_count; i++)
    {
    yn = (((cal_temperature_array[i] / slope) + offset) - cal_adc_code_array[i]);
    yx = yx + (yn * yn);
    ym = (avgconv - cal_adc_code_array[i]);
    ya = ya + (ym * ym);
    }
    Thermistor_Fit.rsquared = 1.0 - (yx / ya);

    print2Console("Thermistor_Fit.offset = %f, Thermistor_Fit.slope = %f, Thermistor_Fit.rsquared = %f\r\n", \
    Thermistor_Fit.offset, Thermistor_Fit.slope, Thermistor_Fit.rsquared);
    return TRUE;

    } // thermistor_calibrate

    Let me know if you want me to send you the complete ccs/halcogen project.

  • The ADC configuration looks fine.  

    What are the voltage level of ADREFHI and ADREFLO? Have you read the temperature from sensor1 and sensor 2? 

    1368, 1370, 1369 (your measurement) are far less than the expected value for 116°C (temperature Gun).

  • As I mentioned earlier, I have not tried snesor1 and sensor2. I will check on those. 

    Can you please let me know how I measure the ADREFIHI and and ADREFLO values?

  • Hi Wang,

    I used sensor 2, the slow and offset are coming as , below,

    hermistor_Fit.offset = -50.307293, Thermistor_Fit.slope = 0.157241, Thermistor_Fit.rsquared = 0.999949

    In case of sensor 3, 

    Thermistor_Fit.offset = 170.502441, Thermistor_Fit.slope = 0.169649, Thermistor_Fit.rsquared = 0.999647

    But in case of Sensor 2, the ADC value does not seem to be right, I am getting very low value below 300 , (287, 286...). Here is the code,

    float thermistor_read_sensor_2(float *temp)
    {
    unsigned int value, pinmux_restore, GxSEL_restore;
    volatile float JunctionTempK = 0.0;
    adcBASE_t *adcreg;

    /* Select the ADC */
    adcreg = adcREG2;

    if(adcreg->G1SR != 0x00000008 )
    return (-1.0); // Group 1 is being used

    /* Check that we have valid calibration data */
    if(Thermistor_Fit.rsquared == 0.0)
    return (-2.0); //Calibration data missing, must run thermistor_calibration() first

    /* Enable Temperature Sensors in Pin Muxing */

    /* Enable Pin Muxing */
    pinMuxReg->KICKER0 = 0x83E70B13U;
    pinMuxReg->KICKER1 = 0x95A4F1E0U;

    /* Enable Temp Sensor */
    pinMuxReg->PINMUX[174] &= 0xFEFFFFFF;

    /* Connect Sensor 2 - Temperature sensor 2's output is connected to AD2IN[31] */
    pinmux_restore = pinMuxReg->PINMUX[173];
    pinMuxReg->PINMUX[173] = (pinMuxReg->PINMUX[173] & 0xfeffffff) | 0x02000000;

    /* Start Converting, Choose Channel */
    GxSEL_restore = adcreg->GxSEL[1U]; // Save the original value in the channel select register
    adcreg->GxSEL[1U] = 0x40000000;

    /* Poll for end of Conversion */
    while(!(adcreg->G1SR & 1));

    /* Read adc value */
    value = adcreg->GxBUF[1U].BUF0;

    /* Disable Temperature Sensor */
    pinMuxReg->PINMUX[174] |= 0x01000000;

    /* Restore Sensor 3 Pin Muxing */
    pinMuxReg->PINMUX[173] = pinmux_restore;

    /* Disable Pin Muxing */
    pinMuxReg->KICKER0 = 0x00000000U;
    pinMuxReg->KICKER1 = 0x00000000U;

    /* Restore Channel Select Register */
    adcreg->GxSEL[1U] = GxSEL_restore;

    /* Convert ADC value into floating point temp Kelvin */
    JunctionTempK = (((float)value) - Thermistor_Fit.offset) * Thermistor_Fit.slope;
    //JunctionTempK = (((float)value) + Thermistor_Fit.offset) * Thermistor_Fit.slope; //SMSM - temporary adjustment, waiting on TI ticket
    *temp = JunctionTempK;
    print2Console("Value = %d, temp = %.2f\r\n", value, *temp);
    return JunctionTempK;
    } // thermistor_read

    bool thermistor_calibration_sensor_2(void)
    {
    OTP_temperature_calibration_data_t *OTPdataptr;
    int i, cal_data_count=0;
    float slope,offset,sumtemp=0,sumconv=0,sumtempxconv=0,sumtempxtemp=0;
    float cal_adc_code_array[4],avgconv,cal_temperature_array[4],yx=0.0,ya=0.0,ym,yn;

    /* Create pointer to temp sensor 3 calibration data */
    OTPdataptr = (OTP_temperature_calibration_data_t *)(THERMISTOR_CAL_DATA + (1 * 0x10));

    //Dump Calibration Data for all 3 Sensors - Debug purpose
    uint32_t *raw = (uint32_t *) (THERMISTOR_CAL_DATA + (0 * 0x10));
    print2Console("Address[0x%X], value = [0x%X]\r\n", raw, *raw);
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+1), *(raw+1));
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+2), *(raw+2));
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+3), *(raw+3));
    raw = (uint32_t *) (THERMISTOR_CAL_DATA + (1 * 0x10));
    print2Console("Address[0x%X], value = [0x%X]\r\n", raw, *raw);
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+1), *(raw+1));
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+2), *(raw+2));
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+3), *(raw+3));
    raw = (uint32_t *) (THERMISTOR_CAL_DATA + (2 * 0x10));
    print2Console("Address[0x%X], value = [0x%X]\r\n", raw, *raw);
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+1), *(raw+1));
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+2), *(raw+2));
    print2Console("Address[0x%X], value = [0x%X]\r\n", (raw+3), *(raw+3));

    /* Check for valid calibration data */
    /* Valid codes are 0 to 0xFFF, valid temperatures are 0 to 400 kelvin */
    for(i = 0; i < 4; i++)
    {

    /* Calculate Slope and Offset for the 4 possible value pairs */
    if((OTPdataptr[i].AdcValue < 0xFFF) && (OTPdataptr[i].Temperature < 401))
    {
    /* Load valid calibration information */
    cal_temperature_array[i] = (float)(OTPdataptr[i].Temperature);
    cal_adc_code_array[i] = (float)OTPdataptr[i].AdcValue;
    print2Console("ADC = %.2f, Temp = %.2f\r\n", cal_adc_code_array[i], cal_temperature_array[i]);
    sumtemp += cal_temperature_array[i];
    sumconv += cal_adc_code_array[i];
    sumtempxconv += cal_temperature_array[i] * cal_adc_code_array[i];
    sumtempxtemp += cal_temperature_array[i] * cal_temperature_array[i];
    cal_data_count++;
    }
    }

    /* Calculate slope and Offset for the 4 possible value pairs */
    if(cal_data_count < 2)
    return FALSE;
    else
    {
    print2Console("sumtempxtemp = %.2f, sumtemp = %.2f, sumtempxconv = %.2f, sumconv = %.2f\r\n", sumtempxtemp, sumtemp, sumtempxconv, sumconv);
    slope = (sumtempxtemp * cal_data_count - sumtemp * sumtemp) /
    (sumtempxconv * cal_data_count - sumtemp * sumconv);
    offset = (sumconv - sumtemp / slope) / cal_data_count;
    Thermistor_Fit.slope = slope;
    Thermistor_Fit.offset = offset;
    avgconv = sumconv / cal_data_count;
    }

    /* Calculate R-Squared Value */
    for(i = 0; i < cal_data_count; i++)
    {
    yn = (((cal_temperature_array[i] / slope) + offset) - cal_adc_code_array[i]);
    yx = yx + (yn * yn);
    ym = (avgconv - cal_adc_code_array[i]);
    ya = ya + (ym * ym);
    }
    Thermistor_Fit.rsquared = 1.0 - (yx / ya);

    print2Console("Thermistor_Fit.offset = %f, Thermistor_Fit.slope = %f, Thermistor_Fit.rsquared = %f\r\n", \
    Thermistor_Fit.offset, Thermistor_Fit.slope, Thermistor_Fit.rsquared);
    return TRUE;

    } // thermistor_calibrate

  • Please double check the code,

    The sensor 2 uses ADC2[31]

    adcreg->GxSEL[1U] = 0x80000000;

  • Thanks Wang. I have corrected the channel selection for Sensor-2 and I am getting similar ADC and temperature values. Also I tried with Sensor-1 and same result. All ADC values are in the range of 1300-1350.

    What is the next step, besides measuring the ADREF HI and LO voltages, which may take some time, as I need appropriate equipment.

  •   - Is there any way to change the status of the case. It shows "Resolved", as I by mistake clicked on "This Resolved my issue" button.

  • the ADREF HI and LO voltages,

    You can check the schematics of your board. The TMS570LC43x supports up to 5V ADC power supply and reference HI voltage level. If ADC is not powered by 3.3V, you need to scale the sampled the ADC value.

  • I checked the ADREFHI and ADREFLO differences, and found out to be 5.0V. So I multiplied the ADC sampling value with a factor of (5/3.3) and now I am getting realistic data. However, I am finding about 3 to 4 degree (Centegrade) difference between Sensor-2 and (Sensor-1 and Sensor-3). Sensor-1 and Sensor-3 temperature values looks closer. is it expected?

     

  • Hi,

    The three sensors are located at different locations. It is ok to see different temperatures read by 3 sensors.