/*
   Copyright (c) 2015, Digi International Inc.

   Permission to use, copy, modify, and/or distribute this software for any
   purpose with or without fee is hereby granted, provided that the above
   copyright notice and this permission notice appear in all copies.

   THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/***************************************************************************
	adc_calib_ramp.c

	This sample program is for the PowerCoreFLEX series core modules.

	Description
	===========
   This program demonstrates how to recalibrate the A/D ramp circuit.
   The A/D ramp circuit is calibrated with using the 2.5v voltage
   reference and end-of-ramp voltage points located on the core
   module.

   The calibration constants generated by this program will be rewritten
   into simulated EEPROM in flash which then can be used to calculate the
   voltage for the following A/D channels.

   CH Function
   -- --------------
   0  2.5V reference.
   1  End-of-ramp voltage.
   2  Thermistor.

   The program will then continuously display the voltage of the above A/D
   channels.

	Setup
	===========
	With your voltmeter monitor the A/D 2.5V reference (TP10) and End-of-
   Ramp Voltage (TP9) located near the edge of the PowerCoreFLEX series core
   module PCB.

	Instructions
	============
	1. Power-on the core module.
	2. Compile and run this program.
	3. Follow the instructions as displayed.

***************************************************************************/
#class auto

// Sample library for PowerCoreFLEX series core modules
#use "PowerCoreFLEX.lib"


// Use the common ISR library for the triac and the ADC
// ramp circuit.
#use "adctriac_isr.lib"
#use "adcramp.lib"


nodebug
void msDelay(unsigned int delay)
{
	auto unsigned long done_time;

	done_time = MS_TIMER + delay;
   while( (long) (MS_TIMER - done_time) < 0 );
}


// set the STDIO cursor location and display a string
void DispStr(int x, int y, char *s)
{
   x += 0x20;
   y += 0x20;
   printf ("\x1B=%c%c%s", x, y, s);
}


void main()
{
	auto int i;
   auto long value1, value2;
	auto float volts1, volts2;
   auto float Vread0, Vread1, Vread2;
   auto char buffer[256];
   auto int key;
   auto int calib;

   // The brdInit function is only used to configure the I/O
   // on the prototyping board and is not required for the A/D
   // library which will configure everything required to access
   // the A/D circuit.
	brdInit();

   // Initialize the A/D ramp circuit and low-level driver.
   anaInRampInit();


   while(1)
	{
		DispStr(1, 1,"!!!Caution this will overwrite the calibration constants set at the factory.");
		DispStr(1, 2,"Do you want to continue(Y/N)?");
      while(!kbhit());
		key = getchar();
		if(key == 'Y' || key == 'y')
		{
      	calib = TRUE;
			break;
		}
		else if(key == 'N' || key == 'n')
		{
         calib = FALSE;
			break;
		}
	}
	while(kbhit()) getchar();

   if(calib)
   {
   	printf("\n\n Enter the actual 2.5v reference voltage = ");
		gets(buffer);
		while(kbhit()) getchar();

		volts1 = atof(buffer);
		value1 = 0;
      ref_conversion_done = FALSE;
		for(i=0; i<10; i++)
      {
      	while(!ref_conversion_done);
         ref_conversion_done = FALSE;
			value1 += anaInRamp(0);
      }
      value1 = value1/10;
		printf(" Rawdata = %d\n", value1);


      printf("\n\n Enter the actual 3.12v reference voltage = ");
		gets(buffer);
		while(kbhit()) getchar();

		volts2 = atof(buffer);
		value2 = 0;
      ramp_conversion_done = FALSE;
		for(i=0; i<10; i++)
      {
      	while(!ramp_conversion_done);
         ramp_conversion_done = FALSE;
			value2 += anaInRamp(1);
      }
      value2 = value2/10;
		printf(" Rawdata = %d\n", value2);

      // For the Ramp the first point set to 0 and the second
      // point is the 2.5v reference.
      anaInCalibRamp((int)value1, volts1, (int) value2, volts2);
      anaInEEWrRamp();

      // !!! Attention !!!
      // Must delay accessing the ramp A/D circuit after doing a write to
      // the program code flash, so the ramp A/D circuit can re-sync due to
      // interrupts being disabled.
      msDelay(50);

   }
   printf(" Calibration completed...\n\n");
   printf(" Now Continually read and display A/D voltages:\n");
   ref_conversion_done = FALSE;
   ramp_conversion_done = FALSE;
   temp_conversion_done = FALSE;
   while(1)
   {
   	// Notes:
      // 1. The conversion flags are predefined and will be set
      // by the ADC low-level driver.
      // 2. If the conversion flags aren't used, and if you read
      // the ramp A/D channel faster than the A/D conversion rate,
      // then the data will be from the previous A/D conversion until a
      // new A/D conversion is completed.
      if(ref_conversion_done && ramp_conversion_done && temp_conversion_done)
      {
      	// Continually read and display the voltage for ramp A/D channels.
      	Vread0 = anaInRampVolts(0);
      	Vread1 = anaInRampVolts(1);
      	Vread2 = anaInRampVolts(2);
      	printf(" RefVolt = %.3f RampVolts = %.3f TempVolt = %.3f    \r",
                Vread0, Vread1, Vread2);
         ref_conversion_done = FALSE;
         ramp_conversion_done = FALSE;
         temp_conversion_done = FALSE;
      }
	}
}


