Get the temperature of iMX6

I have a WEC7 of Colibri iMX6.
I would like to get the temperature of iMX6.
iMX6 the SOC there is a block that Temperature Monitor (TEMPMON).
For example, it is possible to get the temperature from this block?

This is a small test application I wrote to monitor CPU temperature every minute, it’s not really “production code” (no error testing, few comments, no defines used for addresses and values).
You need to download our libraries and SDK to build it, you can find them here:
http://developer.toradex.com/software/windows-embedded-compact/imx6-wec-software#Windows_Embedded_Compact_Software_Development_Kit_SDK
http://developer.toradex.com/software/windows-embedded-compact/imx6-wec-software#Toradex_CE_Libraries_and_Code_Samples

Code has been fixed thanks to kyas suggestions.

Here’s the code:

#include "windows.h"
#include "mapmem.h"

int _tmain(int argc, _TCHAR* argv[])
{
	// Init map mem lib
	HANDLE maphandle=Map_Init();

	// we need to map the OCOTPANA1 fuse to read calibration values
	volatile DWORD* ocotpana1;

	ocotpana1=(DWORD*)Map_MapMemory(0x021BC4E0,sizeof(DWORD));

	// split the value into room temperature (25C) value, hot value and hot reference temp
	DWORD roomcount,hotcount,hottemp;

	roomcount=*ocotpana1>>20;
	hotcount=(*ocotpana1>>8)&0x00000FFF;
	hottemp=*ocotpana1&0x000000FF;

	// map the TEMPMON registers (TEMPSENSE0 and TEMPSENSE1, both have separate registers to set,clear and toggle bits)
	volatile DWORD *tempsense0,*tempsense1;
	volatile DWORD *tempsense0set,*tempsense0clr,*tempsense0tog;
	volatile DWORD *tempsense1set,*tempsense1clr,*tempsense1tog;

	tempsense0=(DWORD*)Map_MapMemory(0x020C8180,8*sizeof(DWORD));
	tempsense0set=tempsense0+1;
	tempsense0clr=tempsense0+2;
	tempsense0tog=tempsense0+3;

	tempsense1=tempsense0+4;
	tempsense1set=tempsense1+1;
	tempsense1clr=tempsense1+2;
	tempsense1tog=tempsense1+3;

	// disable auto updates
	*tempsense1clr=0xFFFFFFFF;

	//set alarm to max value (we are not using the interrupt)
	*tempsense0set=0xFFF00000;

	// power-on sensor
	*tempsense0clr=0x00000001;

	// measure
	for (;;)
	{
		// clears start flag (thanks to kyas remarks)
		*tempsense0clr=0x00000002;

		Sleep(1);

		// start
		*tempsense0set=0x00000002;
		Sleep(1);

		// wait until measured value is valid
		while (!(*tempsense0 & 0x00000004))
			Sleep(1);
    	
		// calculate temperature in Celsius
		DWORD tempcount=(*tempsense0 >> 8) & 0x00000FFF;
		DWORD tmeas=(DWORD)((double)hottemp-(tempcount-hotcount)*((hottemp-25.0)/(roomcount-hotcount)));

		// print it out
		_tprintf(TEXT("Temperature: %d\r\n"),tmeas);
		RETAILMSG(1,(TEXT("Temperature: %d\r\n"),tmeas));

		// wait a minute before doing a new measurement
		Sleep(1000);
	}
	return 0;
}

Thank you for answering my question.
It is likely to be able to get the temperature.
We are currently testing the program.
We ask for your continued support.

I copied your code and i get a reasonable temperature value of 59 degrees. Unfortunately this value stays constant! A new value is measured every 5 seconds but I waited for minutes and it did not change. Rebooting the board gave a new value … this stayed fixed again. So to conclude:
The measurement works only once after reboot and then it stays fixed. What could be the problem?

Our System:
IMX6 Apalis IMG v1.0 WIN CE 2013
Ixora Board

I By adding the code, I was able to get the temperature to continue.

// clear
*tempsense0clr = 0x00000002;
*tempsense0clr = 0x00000004;
System.Threading.Thread.Sleep(10);

// start
*tempsense0set = 0x00000002;
System.Threading.Thread.Sleep(10);

You are right. Start bit is not cleared and so a new reading is not started, the code just takes the value of previous read.
Sorry for the issue.
I’ll fix the code in the original answer to keep it simpler for people that reach this thread via search.

How would this code need to change to work on iMX7, please?

Please do not comment on old questions that are not related to your question.
I will close this now and please open a new question.

Make sure you unmap the mapped memory as soon as you have read out the calibration and temperature data. E.g. call:
Map_UnMapMemory(ocotpana1);
Map_UnMapMemory(tempsense0);

Without calling the unmap function I run in a data abort exception after a few thousand calls of the provided function above. (Not sure whether the exception is cause because of a limitation of the virtual address space of my WEC7 process or if it’s an issue of the mapMem library).

If your running Iinux then

float cpu_temperature()
{
FILE* fp; // Handle to the file
long double value; // Temporary long value
float system_temp; // Temporary float value

fp = fopen("/sys/devices/virtual/thermal/thermal_zone0/temp", “r”); // Open the file for read access
if (fp > 0) // If file was opened
{
fscanf(fp, “%Lf”, &value); // Read the value
fclose(fp); // Close the file

system_temp = value;                                          // Copy the long value into the float
system_temp /= 1000;                                         // Divide to get the whole degrees and decimal places

}
else
{
system_temp = 0; // Failed to open the file so set return value to 0
}

return system_temp;
}

According to AN5215 (nxp.com) there is an updated and more precise formula to calculate temperature in Celsius:
DWORD tempcount=(*tempsense0 >> 8) & 0x00000FFF;
double slope = 0.4148468 - 0.0015423 * roomcount;
double offset = 3.580661;
double tmeas2 = 25.0 + (double(tempcount) - double(roomcount)) / slope + offset;