/*
 * Copyright(C) Paul und Scherer (mct.de/mct.net)
 *
 * This example demonstrates how to...
 *
 *  ... use the ADC to read the temperature sensor.
 */

#include <stdio.h>
#include <target.h>
#include "../delay.h"

/*
 * AD0.2 (=P0.24) is continuously sampled (in burst mode).
 * The voltage output of the temperature sensor (connected
 * to AD0.2) is converted to degree Celsius and displayed.
 *
 * The voltage produced by the temperature sensor is 424mV
 * @ 0 degree Celsius (OFFSET) and rises/falls with 6.25mV
 * per degree Celsius (GAIN), i.e.
 *
 *  Us(Ts) = GAIN*Ts+OFFSET   [mV] or
 *  Ts(Us) = (Us-OFFSET)/GAIN [degree Celsius]
 *
 * The ADC measurement range is 0V to Vdd (=3.3V). Because
 * the ADC has a resolution of 10 bits, a value of n, read
 * from an ADC channel equals n*3.3V/1024, i.e.
 *
 *  Ts(n) = (n*3300/1024-OFFSET)/GAIN [degree Celsius]
 *
 * To avoid using floats, all voltages are in microvolt.
 */

#define OFFSET	424000
#define GAIN	  6250
#define Ts(n)	(((n)*3300000/1024-OFFSET)/GAIN)

int
main(void)
{
	Intern_ad0cr = /* SEL    (Bit 0..  7) */     0x04	// select channel 2
		     | /* CLKDIV (Bit 8.. 15) */   0x0f00	// pclk/(x+1) <=4.5MHz
		     | /* BURST  (Bit16     ) */  0x10000	// BURST on
		     | /* PDN    (Bit21     ) */ 0x200000;	// power up

	Intern_pinsel1 |= 0x30000;		// enable AD0.2 pin

	while (1) {
		long adc;			// ADC data

		delay(1000);			// pause to smooth output

		/*
		 * Wait for DONE, then print temperature.
		 */
		while ((adc = Intern_ad0dr2) >= 0) ;
		printf("Ts: %ld [degree Celsius]\n", Ts((adc>>6)&0x3ff));
	}
}
