/** ###################################################################
**     Filename  : Events.C
**     Project   : voltmeter_led
**     Processor : MC56F8006_48_LQFP
**     Beantype  : Events
**     Version   : Driver 01.03
**     Compiler  : Metrowerks DSP C Compiler
**     Date/Time : 11/10/2008, 7:29 PM
**     Abstract  :
**         This is user's event module.
**         Put your event handler code here.
**     Settings  :
**     Contents  :
**         AD1_OnEnd - void AD1_OnEnd(void);
**
**     (c) Copyright UNIS, a.s. 1997-2008
**     UNIS, a.s.
**     Jundrovska 33
**     624 00 Brno
**     Czech Republic
**     http      : www.processorexpert.com
**     mail      : info@processorexpert.com
** ###################################################################*/
/* MODULE Events */

#include "Cpu.h"
#include "Events.h"

// Define analog voltage power supply to VDDA
#define VDDA		3.3f

// Define PGA running modes
enum TPGA_MODE 
{
	PGA_OFFSET_CALIBRATION,
	PGA_GAIN_CALIBRATION,
	PGA_MISSION
};
const word Dimmer[] = 
{
 0x0000,0x800,0x1800,0x7fff  	    // off, very dim, dim, full on.
};

volatile word SampleValue = 0;		// store the ADC sample value

volatile word Voffset;				// store the ADC sample value for offset calibration
volatile word Vgain;				// store the ADC sample value for gain calibration

volatile float PGACoefA;			// sotre the PGA calibration coefficient A 
									// A = VDDA / [3 X (Vgain - Voffset)]

volatile float PGACoefB;			// sotre the PGA calibration coefficient B 
									// B = VDDA X Voffset / [3 X (Vgain - Voffset)]
									
									
// Define external functions
extern void PGA_StartCalibration();
									
/*
** ===================================================================
**     Event       :  Timer0ISR 
**
**     Description :
**       This is timer 0 interrupt service routine for compare event.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/


#pragma interrupt alignsp /* Comment this line if the appropriate 'Interrupt preserve registers' property */
                         /* is set to 'yes' (#pragma interrupt saveall is generated before the ISR)      */
void Timer0ISR(void)
{
  static word bFlag = 0;

  bFlag ^= 1;
  
  // Always clear the timer compare flag
  TMR0_SCTRL &= ~TMR0_SCTRL_TCF_MASK;
}

/*
** ===================================================================
**     Event       :  AD1_OnEnd (module Events)
**
**     From bean   :  AD1 [ADC]
**     Description :
**         This event is called after the measurement (which consists
**         of <1 or more conversions>) is/are finished.
**         The event is available only when the <Interrupt
**         service/event> property is enabled.
**     Parameters  : None
**     Returns     : Nothing
** ===================================================================
*/
void AD1_OnEnd(void)
{
  static word bPGAMode = PGA_OFFSET_CALIBRATION;
  static word bGainSel = 0;
  float	DeltaV;
  
  PE_AD1_GetChanValue((unsigned int*)&SampleValue);	// Get the ADC value
    
  if(bPGAMode == PGA_OFFSET_CALIBRATION)
  {
  	// It is offset calibration phase
  	Voffset = SampleValue >>3;
	
	// NOTE: Values for Vgain and Voffset should be measured
    // via the ADC during device startup.
	// Disable PGA

    // Must ensure the Gain = 1 before conducting gain calibration.	
    bGainSel = PGA0_CNTL0 & (PGA0_CNTL0_GAINSEL_MASK);
    
    PGA0_CNTL0 &= ~(PGA0_CNTL0_EN_MASK | PGA0_CNTL0_GAINSEL_MASK);
    
	// Change PGA mode to gain calibration mode
  	PGA0_CNTL1 = (PGA0_CNTL1_CALMODE_MASK | PGA0_CNTL1_CPD1_MASK);

	// Re-enable PGA to start up for gain calibration
    PGA_StartCalibration();
    
  	bPGAMode = PGA_GAIN_CALIBRATION;		// go to gain calibration
  }
  else if( bPGAMode == PGA_GAIN_CALIBRATION)
  {
	Vgain 	 =  SampleValue >>3;
  	PGACoefA =  VDDA / (3 * (Vgain - Voffset));
  	PGACoefB =  VDDA * Voffset / (3 * (Vgain - Voffset));
 
 	// Disable PGA0
    PGA0_CNTL0 &= ~(PGA0_CNTL0_EN_MASK);
     	
  	// Restore user's GAIN setting
    PGA0_CNTL0 |= bGainSel;  	
  	
  	PGA0_CNTL0 &= ~PGA0_CNTL0_TM_MASK;		// use h/w trigger
  	PGA0_CNTL1 = PGA0_CNTL1_CPD1_MASK;						
  	
	// Renable PGA0
	PGA0_CNTL0 |= (PGA0_CNTL0_EN_MASK);
	  	  
	// Wait for PGA to startup
	while(!(PGA0_STS & PGA0_STS_STCOMP_MASK))
	{  	
	}	

	TMR_ENBL |= TMR_ENBL_ENBL0_MASK;		// enable timer 0 to trigger PDB/PGA/ADC  
	  		
  	bPGAMode = PGA_MISSION;					// go to mission mode with h/w trigger by timer 0
  }
  else
  {
#define RAWdata
#ifndef RAWdata
  	  // ĶĪV = A X Result - B;
  	  DeltaV = PGACoefA * (SampleValue>>3) - PGACoefB;
  	  
  	  // Calculate the expected Result = $FFF X (ĶĪV/VDDA) + $7FF
  	  SampleValue = 0x0FFF * (DeltaV/VDDA) + 0x07FF;
  	  SampleValue <<= 3;
#endif RAWdata  	
	  // With PWM modulus  register which is 0x7fff (max).
	  // Output 6 "digits" of voltage result, showing all 12 bits of adc value.
	  // Each of the 6 LED displays two bits of the 12-bit ADC result!
	  PWMC1_SetDuty(0,(int)Dimmer[(SampleValue & 0x6000)>>13]) ;  SampleValue <<= 2 ; // LED1
	  PWMC1_SetDuty(1,(int)Dimmer[(SampleValue & 0x6000)>>13]) ;  SampleValue <<= 2 ; // LED2
	  PWMC1_SetDuty(2,(int)Dimmer[(SampleValue & 0x6000)>>13]) ;  SampleValue <<= 2 ; // LED3
	  PWMC1_SetDuty(3,(int)Dimmer[(SampleValue & 0x6000)>>13]) ;  SampleValue <<= 2 ; // LED4
	  PWMC1_SetDuty(4,(int)Dimmer[(SampleValue & 0x6000)>>13]) ;  SampleValue <<= 2 ; // LED5
	  PWMC1_SetDuty(5,(int)Dimmer[(SampleValue & 0x6000)>>13]) ;                      // LED6
	  PWMC1_Load();    // nothing really changes until this is done!    	  	
  }  
}


/* END Events */

/*
** ###################################################################
**
**     This file was created by UNIS Processor Expert 2.99 [04.17]
**     for the Freescale 56800 series of microcontrollers.
**
** ###################################################################
*/
