Search by Tags

Soc Temperature Readout (WinCE)

 
Applicable for

Compare with Revision




Subscribe for this article updates

This article demonstrates how to read Colibri/Apalis internal Soc temperature.

Colibri PXAxxx

PXAxxx processors do not have internal temperature sensors. External temperature sensor must be added to the carrier board if temperature measurements are required.

Colibri T20, T30

To measure Temperature of Soc on Colibri T20, T30 and Apalis T30 module use following code:

#include <windows.h>
 
/// Temperature zone
typedef enum
{
    NvRmTmonZoneId_Module = 1,  ///< specifies the temperature sensor located on the module, away from the CPU.
    NvRmTmonZoneId_Core   = 2,  ///< specifies the temperature sensor measuring the CPU core voltage
} NvRmTmonZoneId;
 
/// NvError NvRmDiagGetTemperature(NvRmDeviceHandle pHandle, NvRmTmonZoneId ZoneId, DWORD* pTemperatureC);
///
/// Read a temperature from the on-module temperature sensor
/// @param[in]  pHandle         not required. Always set to 0
/// @param[in]  ZoneId          specifies which temperature sensor to read
/// @param[out] pTemperatureC   measured temperature in degree C
/// @return                     0 indicates success, any other value indicates an error
typedef DWORD (*PFNNvRmDiagGetTemperature)(DWORD, NvRmTmonZoneId, DWORD*);
PFNNvRmDiagGetTemperature NvRmDiagGetTemperature;
 
/// Demo function to read the temperatures on Tegra modules
/// To keep the code simple, there is no error handling implemented.
int _tmain(int argc, _TCHAR* argv[])
{
    HMODULE hMod;
    DWORD   moduleTemperature;
    DWORD   cpuTemperature;
 
    // evaluate function pointers
    hMod=LoadLibrary(L"libnvrm.dll");
    NvRmDiagGetTemperature  = (PFNNvRmDiagGetTemperature)GetProcAddress(hMod, L"NvRmDiagGetTemperature");
 
    // read temperatures
    NvRmDiagGetTemperature(0, NvRmTmonZoneId_Module, &moduleTemperature);
    NvRmDiagGetTemperature(0, NvRmTmonZoneId_Core,   &cpuTemperature);
    return 0;
}

Colibri VFxx

To measure temperature of Soc on Colibri VF50, VF61 module use following code:

#include <windows.h>
#include "winioctl.h"
 
#define ADC_AVG_32      3
#define ADC_MODE_10BIT  1 
#define IOCTL_ADC_READ CTL_CODE(32768,2048,METHOD_BUFFERED,FILE_ANY_ACCESS)
 
typedef struct
{
    BYTE        channel;                                // ADC channel used
    BOOL        useaverage;
    BOOL        avgsamples;                             // Number of samples to be averaged to get value
    BOOL        mode;                                   // ADC mode 8, 10, 12 bit mode
} ADC_READ;
 
typedef struct
{
    DWORD       vTemp25;                                // V_Temp value at 25 'C at VDD 3.3V see ADC electrical characteristic in datasheet
    float       slopeCoefficient;                       // temperature slope value used to calculate temperature see datasheet
    BYTE        channel;                                // temperature sensor connected to 26 channel of adc
}TEMPERATURE_SENSOR;
 
int wmain()
{
    HANDLE      adc0            =   NULL;               // handle to adc device
    ADC_READ    adcRead;                                // ADC configuration 
    TEMPERATURE_SENSOR tempSensor;                      // Internal temperature sensor configuration
    DWORD       adcValue        =   0;                  // variable to get adc value
    DWORD       returned        =   0;                  // variable holds number of bytes returned by DeviceIoControll      
    float       temperature     =   0;                  // variable to hold temperature reading
    DWORD       error           =   0;                  // error value used by Getlasterror to return error 
    tempSensor.channel          =   26;                 // Temperature sensor channel
    tempSensor.slopeCoefficient =   1.8;                // temp slope to calculate value
    tempSensor.vTemp25          =   721;                // VTemp at 25 'C
    adcRead.useaverage          =   TRUE;   
    adcRead.avgsamples          =   ADC_AVG_32;         // 32 samples averaged                                      
    adcRead.mode                =   ADC_MODE_10BIT;     // ADC used in 10 bit mode
    adcRead.channel             =   tempSensor.channel; // adc_channel 26 connected to internal temperature sensor
    // provide handle to adc0
    adc0 = CreateFile(TEXT("ADC1:"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if(!adc0)
    {
        printf("GetLastError %x\r\n", GetLastError());
        printf("ERROR - opening ADC0\r\n");
        return -1;
    }
    // get adc value at channel 26(temperature sensor)
    if(!DeviceIoControl(adc0, IOCTL_ADC_READ, &adcRead, sizeof(ADC_READ), &adcValue, sizeof(DWORD), &returned, NULL))
    {
        printf("GetLastError %x\r\n", GetLastError());
        printf("ERROR - Reading ADC value at channel %d\r\n", adcRead.channel);
        return -1;
    }
    temperature = 25 - ((adcValue*3.22 - tempSensor.vTemp25)/tempSensor.slopeCoefficient);// calculation to obtain temperature
    printf("Temperature is %2.2f 'C\r\n", temperature);
    CloseHandle(adc0);
    printf("Press Enter to exit \r\n");
    getchar();
    return 0;
}

Download projects

You can download demo source code for Colibri Txx from here and for Colibri VFxx from here.