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.

TMS320F28075 internal temperature

Other Parts Discussed in Thread: CONTROLSUITE

The TRM for the 28075, in section 8.3.4, states that the internal junction temperature can be sampled at ADCIN13 on ADCA by enabling it with the TSNSCTL register.  However, there is no further information about how to interpret the ADC value and convert it to a temperature.  Is there another document or some sample code that shows how to do this?

  • Hi Angelo,

    See this post:
    e2e.ti.com/.../1600961

    This is essentially applicable to the F28075 device as well.
  • Devin,

    Since I am currently working with a TMX version of the processor, I take it that the conversion factors won't be in the OTP registers until we get TMS versions. Is this correct? Will a conversion function be added to the control Suite at that time also (it is not in the current version I am using, v150)?

    Thanks,
    Angelo
  • Devin,

    As a follow up question to my earlier reply:  is there a nominal equation that we can use to calculate the junction temperature while we are waiting for the calibrated TMS parts?  Even though the accuracy will be off, it will allow us to proceed with firmware development.

    Thanks,

    Angelo

  • Hi Angelo,

      I'll let Devin address your specific question, but I want to caution that the temp sensor accuracy likely will not be a guaranteed min/max spec in the TMS DS, and I expect it may be +/-15 degrees TYP.  It is not that it can't be used as a general gauge of the junction temperature, but want you to have the proper expectation.

    Regards,

    Joe

  • Hi Angelo,

    I will provide you with some preliminary SW with static values, hopefully by the end of next week. The official SW release will appear in ControlSUITE near the end of September.
  • Hi Angelo,

    Attached are the following draft software files:

    F2807x_TempSensorConv.c : The support functions for the temp sensor. This file should be placed in  .. \F2807x_common\source.

    adc_soc_epwm_tempsensor_cpu01.c : An example that samples the temp sensor and then calls the support functions to interpret the results. Note that the project that you create for this code should link in the above F2807x_TempSensorConv.c file.

    F2807x GlobalPrototypes.h: An updated header file with the temp sensor support functions included.  This should be placed in .. \F2807x_common\sinclude.

    These are provided as-is; official versions will eventually be released in ControlSUITE.

    //###########################################################################
    // FILE:   adc_soc_epwm_tempsensor_cpu01.c
    // TITLE:  Sample temperature sensor and convert to temperature for F2807x.
    //
    //! \addtogroup cpu01_example_list
    //! <h1> ADC temperature sensor conversion (adc_soc_epwm_tempsensor)</h1>
    //!
    //! This example sets up the ePWM to periodically trigger the ADC.  The
    //! ADC converts the internal connection to the temperature sensor,
    //! which is then interpreted as a temperature by calling the
    //! GetTemperatureC function.
    //!
    //! After the program runs, the memory will contain:\n
    //! - \b sensorSample \b: The raw reading from the temperature sensor. \n
    //! - \b sensorTemp \b: The interpretation of the sensor sample as a
    //! temperature in degrees Celsius.
    //!
    //###########################################################################
    // $TI Release: F2807x Support Library vXXX $
    // $Release Date: XXX CDT 2015 $
    // $Copyright: Copyright (C) 2013-2015 Texas Instruments Incorporated -
    //             http://www.ti.com/ ALL RIGHTS RESERVED $
    //###########################################################################
    
    #include "F28x_Project.h"     // Device Headerfile and Examples Include File
    
    void ConfigureADC(void);
    void ConfigureEPWM(void);
    void SetupADCEpwm(void);
    interrupt void adca1_isr(void);
    
    Uint16 sensorSample;
    int16 sensorTemp;
    
    void main(void)
    {
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the F2807x_SysCtrl.c file.
        InitSysCtrl();
    
    // Step 2. Initialize GPIO:
    // This example function is found in the F2807x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
        InitGpio(); // Skipped for this example
        
    // Step 3. Clear all interrupts and initialize PIE vector table:
    // Disable CPU interrupts
        DINT;
    
    // Initialize the PIE control registers to their default state.
    // The default state is all PIE interrupts disabled and flags
    // are cleared.
    // This function is found in the F2807x_PieCtrl.c file.
        InitPieCtrl();
    
    // Disable CPU interrupts and clear all CPU interrupt flags:
        IER = 0x0000;
        IFR = 0x0000;
    
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    // This will populate the entire table, even if the interrupt
    // is not used in this example.  This is useful for debug purposes.
    // The shell ISR routines are found in F2807x_DefaultIsr.c.
    // This function is found in F2807x_PieVect.c.
        InitPieVectTable();
    
    //Map ISR functions
        EALLOW;
        PieVectTable.ADCA1_INT = &adca1_isr; //function for ADCA interrupt 1
        EDIS;
    
    //Configure the ADC and power it up
        ConfigureADC();
    
    //Initialize the temperature sensor
    //Note: The argument needs to change if using a VREFHI voltage other than 3.0V
        InitTempSensor(3.0);
    
    //Configure the ePWM
        ConfigureEPWM();
    
    //Setup the ADC for ePWM triggered conversions on temperature sensor
        SetupADCEpwm();
    
    //Enable global Interrupts and higher priority real-time debug events:
        IER |= M_INT1; //Enable group 1 interrupts
        EINT;  // Enable Global interrupt INTM
        ERTM;  // Enable Global realtime interrupt DBGM
    
    //enable PIE interrupt
        PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
    
    //sync ePWM
        EALLOW;
        CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    
    //start ePWM
        EPwm1Regs.ETSEL.bit.SOCAEN = 1;  //enable SOCA
        EPwm1Regs.TBCTL.bit.CTRMODE = 0; //unfreeze, and enter up count mode
    
    //take conversions indefinitely in loop
            while(1);
    }
    
    //Write ADC configurations and power up the ADC for both ADC A and ADC B
    void ConfigureADC(void)
    {
    	EALLOW;
    
    	//write configurations
    	AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
        AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);
    
    	//Set pulse positions to late
    	AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    
    	//power up the ADC
    	AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    
    	//delay for 1ms to allow ADC time to power up
    	DELAY_US(1000);
    
    	EDIS;
    }
    
    void ConfigureEPWM(void)
    {
    	EALLOW;
    	// Assumes ePWM clock is already enabled
    	EPwm1Regs.ETSEL.bit.SOCAEN	= 0;	        // Disable SOC on A group
    	EPwm1Regs.ETSEL.bit.SOCASEL	= 4;	        // Select SOC on up-count
    	EPwm1Regs.ETPS.bit.SOCAPRD = 1;		        // Generate pulse on 1st event
    	EPwm1Regs.CMPA.bit.CMPA = 0x0800;          // Set compare A value to 2048 counts
    	EPwm1Regs.TBPRD = 0x1000;			        // Set period to 4096 counts
    	EPwm1Regs.TBCTL.bit.CTRMODE = 3;            // freeze counter
    	EDIS;
    }
    
    void SetupADCEpwm(void)
    {
    	Uint16 acqps;
    
    	acqps = 83; //temperature sensor needs at least 700ns acquisition time
    
    	//Select the channels to convert and end of conversion flag
    	EALLOW;
    	AdcaRegs.ADCSOC0CTL.bit.CHSEL = 13;  //SOC0 will convert internal connection A13
    	AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
    	AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5; //trigger on ePWM1 SOCA/C
    	AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
    	AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;   //enable INT1 flag
    	AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
    }
    
    interrupt void adca1_isr(void)
    {
    	sensorSample = AdcaResultRegs.ADCRESULT0;
    	sensorTemp = GetTemperatureC(sensorSample);
    
    	AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
    	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    }
    

    F2807x_GlobalPrototypes.h

    //###########################################################################
    // FILE:   F2807x_TempSensorConv.c
    // TITLE:  F2807x Temperature Sensor Conversion Functions
    //###########################################################################
    // $TI Release: F2807x Support Library vXXX $
    // $Release Date: XXX $
    // $Copyright: Copyright (C) 2013-2015 Texas Instruments Incorporated -
    //             http://www.ti.com/ ALL RIGHTS RESERVED $
    //###########################################################################
    
    #include "F2807x_device.h"     // F2807x Headerfile Include File
    #include "F2807x_Examples.h"   // F2807x Examples Include File
    
    // Useful definitions
    #define FP_SCALE 32768       //Scale factor for Q15 fixed point numbers (2^15)
    #define FP_ROUND FP_SCALE/2  //Added to Q15 numbers before converting to integer to round the number
    
    // Amount to add to Q15 fixed point numbers to shift from Celsius to Kelvin
    // (Converting guarantees number is positive, which makes rounding more efficient)
    #define KELVIN 273
    #define KELVIN_OFF FP_SCALE*KELVIN
    
    
    // The following pointers to function calls are:
    //Slope of temperature sensor (deg. C / ADC code).  Stored in fixed point Q15 format.
    #define getTempSlope() (*(int (*)(void))0x7036E)()
    //ADC code corresponding to temperature sensor output at 0 deg. C
    #define getTempOffset() (*(int (*)(void))0x70372)()
    
    int32 tempSensor_tempSlope;
    Uint16 tempSensor_tempOffset;
    float32 tempSensor_scaleFactor;
    
    //Initialize the temperature sensor by powering up the sensor, loading
    //the calibration values from OTP to RAM, and recording the intended
    //VREFHI voltage.  
    //note: This function doesn't support VREFLO != 0.0V, but this could 
    //be implemented if desired. 
    void InitTempSensor(float32 vrefhi_voltage)
    {
    	EALLOW;
    
    	//power up the the temperature sensor
    	AnalogSubsysRegs.TSNSCTL.bit.ENABLE = 1;
    	//delay to allow the sensor to power up
    	DELAY_US(1000);
    
        EDIS;
    
        //need to remember VREFHI voltage so that sensor readings can be scaled
        //to match 2.5V values used for calibration data.
        tempSensor_scaleFactor = vrefhi_voltage;
        
        //check the device revision
        if(DevCfgRegs.REVID >= 3)
        {
            //for production devices (Rev. C), pull the slope and offset from OTP
            tempSensor_tempSlope = (int32)getTempSlope();
            tempSensor_tempOffset = getTempOffset();
        }
        else
        {
            //for pre-production devices, use these static values for slope and offset
            tempSensor_tempSlope = 5196;
            tempSensor_tempOffset = 1788;
        }   
    }
    
    //This function uses the reference data stored in OTP to convert the raw temperature
    //sensor reading into degrees C
    int16 GetTemperatureC(int16 sensorSample)
    {
        sensorSample = (int16)((tempSensor_scaleFactor/2.5)*(sensorSample));
    
        return ((sensorSample - tempSensor_tempOffset)*tempSensor_tempSlope + FP_ROUND + KELVIN_OFF)/FP_SCALE - KELVIN;
    }
    
    //This function uses the reference data stored in OTP to convert the raw temperature
    //sensor reading into degrees K
    int16 GetTemperatureK(int16 sensorSample)
    {
        sensorSample = (int16)((2.5/tempSensor_scaleFactor)*(sensorSample));
    
        return ((sensorSample - tempSensor_tempOffset)*tempSensor_tempSlope + FP_ROUND + KELVIN_OFF)/FP_SCALE;
    }
    

  • Devin,

    I finally had a chance to try this out on one of our TMX320F28075 parts and it seems to be working fine.

    Thanks,

    Agnelo