/****************************************************************************************************/
/**
Copyright (c) 2009 Freescale Semiconductor
Freescale Confidential Proprietary
\file       LL64_Demo.c
\brief      
\author     Freescale Semiconductor
\author     Applications Austin, Texas
\author     
\version    0.3
\date       May/2009
*/
/****************************************************************************************************/
/*                                                                                                  */
/* All software, source code, included documentation, and any implied know-how are property of      */
/* Freescale Semiconductor and therefore considered CONFIDENTIAL INFORMATION.                       */
/* This confidential information is disclosed FOR DEMONSTRATION PURPOSES ONLY.                      */
/*                                                                                                  */
/* All Confidential Information remains the property of Freescale Semiconductor and will not be     */
/* copied or reproduced without the express written permission of the Discloser, except for copies  */
/* that are absolutely necessary in order to fulfill the Purpose.                                   */
/*                                                                                                  */
/* Services performed by FREESCALE in this matter are performed AS IS and without any warranty.     */
/* CUSTOMER retains the final decision relative to the total design and functionality of the end    */
/* product.                                                                                         */
/* FREESCALE neither guarantees nor will be held liable by CUSTOMER for the success of this project.*/
/*                                                                                                  */
/* FREESCALE disclaims all warranties, express, implied or statutory including, but not limited to, */
/* implied warranty of merchantability or fitness for a particular purpose on any hardware,         */
/* software ore advise supplied to the project by FREESCALE, and or any product resulting from      */
/* FREESCALE services.                                                                              */
/* In no event shall FREESCALE be liable for incidental or consequential damages arising out of     */
/* this agreement. CUSTOMER agrees to hold FREESCALE harmless against any and all claims demands or */
/* actions by anyone on account of any damage,or injury, whether commercial, contractual, or        */
/* tortuous, rising directly or indirectly as a result of the advise or assistance supplied CUSTOMER*/ 
/* in connectionwith product, services or goods supplied under this Agreement.                      */
/*                                                                                                  */
/****************************************************************************************************/
/*														              
* Filename:     LL64_Demo.c                
*														              
* Revision:      										              
*														              
* Functions:    Includes basic demo function
*         
* Description:  Performs multiple task to demonstrat the operation of. 
*               The LL64
*               
*
* Notes:        
*
*********************************************************************************/
#include "IO_Map.h"
#include "LL64_Demo.h"
#include "Calendar.h"
#include "LCD_GD5360P.h" /* LCD assignments */
#include "LL64_ADC.h"  /* ADC defines */
#include "sci_drv.h"   /* LL64 SCI defines */
#include <string.h> /* include peripheral declarations */
#include "LCD_Drive.h"
#include "LL64_PE_Demo_Definitions.h"
#include "TempMeasurement.h"
#include "TempControl.h"
#include "Accel.h"

/************************** variable Declarations ******************************/

volatile unsigned char channel_adc = 0;
volatile unsigned char state = 0;

unsigned short ADC_Conversion(unsigned char);
volatile unsigned char Result = 0;
volatile unsigned int C_x = 0;
volatile unsigned int C_y = 0;
volatile unsigned int C_z = 0;

extern  char ascii[]; 
extern unsigned char *columns[];
unsigned char *string;
unsigned int length, i,j;
unsigned char column,row,trim,t,data_b;
unsigned int min;
unsigned int max;
unsigned int Low, High;
unsigned long mean;
unsigned int data,data_c;
unsigned char new_channel;
unsigned int PotVal,Rz1Val;
unsigned char cal_restore;
UINT8 cbaMessage1 [ ] = {" LL64"};
bool LED1_ONOFF = 0;      //LED control bits - all on 
bool LED2_ONOFF = 0;
bool LED3_ONOFF = 0;
bool LED4_ONOFF = 0;
/*******************************************************************************
* Function:        LL64_demo
*
* Description:     
*
* Returns:         never return
*
* Notes:           
*                 
*******************************************************************************/

void LL64_demo(void) {
    
   Accel_WakeUp();    //Accel_WakeUp();        // wake up accelerometer
 
   C_x = Accel_GetX();     //Get RestingBaseline x,y and z
                           //this will depend on how the MCU board is positioned.
   C_y = Accel_GetY();
 
   C_z = Accel_GetZ();

  LED2_PutVal(LED2_ONOFF) ;
  LED3_PutVal(LED3_ONOFF) ;
  LED4_PutVal(LED4_ONOFF) ;

  vfnLCD_All_Segments_ON();    //turn on all LCD segments for self test
  WaitSec(1); 
  
  vfnLCD_All_Segments_OFF();

  LED2_PutVal(~LED2_ONOFF) ;
  LED3_PutVal(~LED3_ONOFF) ;
  LED4_PutVal(~LED4_ONOFF) ;

  SetAlpha(1,'9');
  SetAlpha(2,'L');
  SetAlpha(3,'L');
  SetAlpha(4,'6');
  SetAlpha(5,'4');
  WaitSec(1); 
  
  vfnCalendar_SetTime (6, 5, 4) ;
  vfnCalendar_SetDate (9, 8, 7, _FRIDAY_); 

  state = 0;
  Accel_Sleep();       //Sleep Accelerometer

  for(;;){
  if(state == 0) {
      StopClock(); //clock demo
  }else if(state ==1){
      LightSense(); //light sense demo
  }else if(state ==2){
      AccelDemo();  //Accelerometer Demo
  }else if(state ==3){
      ADCDemo();            //ADC Demo
  }
  }    
}
/*********************************** Function **********************************/
////////////////////////////////////////////////////////////////////////////  
// State 0 display time in stop mode
////////////////////////////////////////////////////////////////////////
void StopClock(void)
{
  vfnLCD_All_Segments_OFF();

  SetAlpha(1,'C');
  SetAlpha(2,'L');
  SetAlpha(3,'K');

//   vfnTOD_Init(_TOD_32_768KHZ_XTAL_, (TODSC_SECIE_MASK | !TODSC_QSECIE_MASK | !TODSC_MTCHIE_MASK ), TOD_MATCH_5_SEC);     
    vfnTOD_Init(_TOD_32_768KHZ_XTAL_, (!TODSC_SECIE_MASK | !TODSC_QSECIE_MASK | TODSC_MTCHEN_MASK| TODSC_MTCHIE_MASK ), TOD_MATCH_60_SEC);  
   WaitSec(1);
   vfnLCD_All_Segments_OFF();
   _LCD_COLON_ON;
   _LCD_COLON_Blink;
   vfnDisplayBlinkEnable();
   
/////////////////////STATE 0////////////////////////
//////Simple Clock in stop Mode////////////////////     
     while(state ==0){
       //display current time while in stop mode
       vfnDisplayBatteryLife(gu16ADCVDD);
       //vfnTempMeasurementStartConversion();
       //vfnDisplayTemperature(gu16Temperature);
       vfnUpdateDayAndTime(&Calendar_RTC);
       vfnDisplayDayOfWeek(Calendar_RTC.Day);
       AsmStop;
     }
}


////////////////////////////////////////////////////////////////////////////  
// State 1 Compare Light sensor to POT and ALARM
//   if Light sensor reading is higher than POT
////////////////////////////////////////////////////////////////////////
void LightSense(void) {
    vfnLCD_All_Segments_OFF();
    SetAlpha(1,'L');
    SetAlpha(2,'I');
    SetAlpha(3,'T');          //T is blank
    WaitSec(2);
    CR;
    LF;
    LF;
    DisplayString("Compare Light Sensor to POT");
    CR;
    LF;
    vfnDisplayBlinkDisable();
  ////////////STATE 1///////////////////    
 ////////// ADC Features State//////////
  /////Display POT Reading and  Rz reading
  /////Sound Alarm if RZ is Greater than POT 
 
  while(state == 1) {
    

    ADCCFG1 =(ADLPC_NORMAL|ADIV_8|ADLSMP_LONG|MODE_8|ADICLK_BUS);
    ADCSC3 = (ADCO_SINGLE);
    ADCSC1_ADCH = 4;       
    //Read Pot 
    DisplayString("POT = ");
    /*
    do{
  	   // Wait for conversion to complete 
    }while (ADCSC2_ADACT == 1); 
    Result = ADCRH;
    Low = Result&0x0F;
    
    DisplayByte(Result);

    if(Low<=0x09){
    SetAlpha(1,Low+48);
    } else    {
    SetAlpha(1,Low+55);
    }
    */
    Result = ADCRL;
    PotVal = ADCR;
    
    DisplayByte(Result);
    
    High = (Result&0xf0)/16;
    Low = Result&0x0F;
    
    if(High<=0x09){
    SetAlpha(1,High+48);
    } else    {
    SetAlpha(1,High+55);
    }

    if(Low<=0x09){
    SetAlpha(2,Low+48);
    } else    {
    SetAlpha(2,Low+55);
    }
     
    ADCSC1_ADCH = 10;       //Read Rz

    DisplayString("  Light Sensor Z1 = ");
     
    /*  use if in 12 bit mode
    do{
  	// Wait for conversion to complete 
    }while (ADCSC2_ADACT == 1); 
    Result = ADCRH;
    Low = Result&0x0F;
    if(Low<=0x09){
    SetAlpha(4,Low+48);
    } else    {
    SetAlpha(4,Low+55);
    }
     
    DisplayByte(Result);
    
    */     
    Result = ADCRL;
    Rz1Val = ADCR;
    Low = Result&0x0F;
    High = (Result&0xf0)/16;
 
    DisplayByte(Result);
    
    CR;LF;
     
    if(High<=0x09){
    SetAlpha(4,High+48);
    } else    {
    SetAlpha(4,High+55);
    }

    if(Low<=0x09){
    SetAlpha(5,Low+48);
    } else    {
    SetAlpha(5,Low+55);
    }
    
    if (Rz1Val > PotVal){
        //TPM1CH0 is buzzer
        PlaySound(2350);

    SetAlpha(3,'<'); 
    }else   {
        //TPM1CH0 buzzer off
    SetAlpha(3,'>'); 
     }
    if (Rz1Val == PotVal){
        //TPM1CH0 is buzzer
         SetAlpha(3,'='); 
    }    while(TODSC_QSECF == 0);
    TODSC_QSECF = 1;         

              
  } /* end while state = 1 */
 
}

////////////////////////////////////////////////////////////////////////////  
// State 2 Accelerometer Demo
//   Show Right/Left UP/ Down 
//Sensitivity (TA = 25°C, VDD = 3.3 V)
//g-Select1 & 2: 00  1.5g         800    mV/g
//g-Select1 & 2: 10   2g          600    mV/g
//g-Select1 & 2: 01   4g          300    mV/g
//g-Select1 & 2: 11   6g          200    mV/g
/*
As you move the board to the right edge Y axis increases and Z axis decreases						
As you move the board to the left edge Y axis decreases and Z axis increases - opposite of right edge						
As you move the board to the top edge X axis increas and Z axis decreases						
As you move the board upside down the Z axis decreas 2 x						
As you move the board to the handheld - portrate position Y increase and Z decreases						
As you move the board to the landscape position X decrease and Z decrease by half of the portrate????						
						
Nominal standing still varries by as much as +/- 		130	Z axis seems to <100	
Nominal reading - standard offset values is 				31124	32038	36303

jumpers for G = 00						
*/
////////////////////////////////////////////////////////////////////////
void AccelDemo(void) {

 unsigned int x,y,z;
 TODSC_SECIE = 0;
 vfnLCD_All_Segments_OFF();
 
 LF;
 string = "   ACCEL DEMO      ";
 DisplayString(string);  
// ScrollString(string);
 CR;
    SetAlpha(1,'A'); 
    SetAlpha(2,'C'); 
    SetAlpha(3,'C');
  WaitSec(2);
    SetAlpha(1,'P'); 
    SetAlpha(2,'O'); 
    SetAlpha(3,'S');
  WaitSec(2);

   Accel_WakeUp();    //Accel_WakeUp();        // wake up accelerometer
  
   CR;LF;
   DisplayString("| X Axis |");             
   DisplayString(" Y Axis  |");             
   DisplayString(" Z Axis  |");
   LF;
   DisplayString("|");


 /////////////////////////////////
 while(state==2){
 
  //Get X Y Z
  SendMsg("\r\n");

   x = Accel_GetX();     //Get x
   data_b = ADCRH;
   DisplayByte(data_b);          // Write out to SCI
   data_b = ADCRL;
   DisplayByte(data_b);          // Write out to SCI
   SendMsg(",");

   y = Accel_GetY();     //Get y 
   data_b = ADCRH;
   DisplayByte(data_b);          // Write out to SCI
   data_b = ADCRL;
   DisplayByte(data_b);          // Write out to SCI
   SendMsg(",");

   z = Accel_GetZ();     //Get z
   data_b = ADCRH;
   DisplayByte(data_b);          // Write out to SCI
   data_b = ADCRL;
   DisplayByte(data_b);          // Write out to SCI

 
 //Check Right Left UP Down
//Board flatup            UP    x = 0 G y = 0 G and z = +1G
//Board flat down         DOWN  x = 0 G y = 0 G and z = -1G
//Board on right edge     RIGHT x = 0 G y = +1G and z = 0 G
//Board on left edge      LEFT  x = 0 G y = -1G and z = 0 G
//Board tilted forward    FWD   x = +1G y = 0 G and z = 0 G        (PRIMARY CARD EDGE Toward Surface
//Board tilted backward   BWD   x = -1G y = 0 G and z = 0 G        (SECONDARY CARD EDGE Toward Surface

// 0 G - is appx 1.65 V   12 bit result of  2049  or 0x800    VDD = 3.3V
// +1 G is appx  2.45 V   12 bit result of  3040  or 0xBE0    VDD = 3.3V
// -1 G is appx  0.85 V   12 bit result of  1055  or 0x41F    VDD = 3.3V 

//As you move the board to the right edge Y axis increases and X and Z axis maintain							
//As you move the board to the left edge Y axis decreases and X and Z axis maintain, opposite of right edge							
//As you move the board to the back edge X axis increas and Y and Z axis maintain							
//As you move the board upside down the Z axis decreas and x and y maintain							

if(y>= 0xA00){

      //Set Right
   

       SendMsg(",");
       data_b = 0x02;
       DisplayByte(data_b);          // Write out to SCI
       data_b = 0x00;
       DisplayByte(data_b);          // Write out to SCI

       SetAlpha(1,'R'); 
       SetAlpha(2,'I'); 
       SetAlpha(3,'G');
 //      PlaySound(2350);

    } else if(y<=0x500){ 
     //Set Left
     
       SendMsg(",");
       data_b = 0x04;
       DisplayByte(data_b);          // Write out to SCI
       data_b = 0x00;
       DisplayByte(data_b);          // Write out to SCI

       SetAlpha(1,'L'); 
       SetAlpha(2,'E'); 
       SetAlpha(3,'F');
 //      PlaySound(2350);

   } else if(z>=0xA00){
 //Set UP
     
       SendMsg(",");
       data_b = 0x06;
       DisplayByte(data_b);          // Write out to SCI
       data_b = 0x00;
       DisplayByte(data_b);          // Write out to SCI

       SetAlpha(1,'U'); 
       SetAlpha(2,'P'); 
       SetAlpha(3,';');            //";" is all blank
//       PlaySound(2350);
     
 } else if(z<=0x500){
 //Set Down
     
       SendMsg(",");
       data_b = 0x08;
       DisplayByte(data_b);          // Write out to SCI
       data_b = 0x00;
       DisplayByte(data_b);          // Write out to SCI

       SetAlpha(1,'D'); 
       SetAlpha(2,'O'); 
       SetAlpha(3,';');            //";" is all blank
//       PlaySound(2350);

 } else if(x>=0xA00){
 //Set Backward
     
       SendMsg(",");
       data_b = 0x0A;
       DisplayByte(data_b);          // Write out to SCI
       data_b = 0x00;
       DisplayByte(data_b);          // Write out to SCI

       SetAlpha(1,'F'); 
       SetAlpha(2,'0'); 
       SetAlpha(3,'R');            
//       PlaySound(2350);

 } else if(x<=0x500){
 //Set Forward
     
       SendMsg(",");
       data_b = 0x0C;
       DisplayByte(data_b);          // Write out to SCI
       data_b = 0x00;
       DisplayByte(data_b);          // Write out to SCI

       SetAlpha(1,'B'); 
       SetAlpha(2,'A'); 
       SetAlpha(3,'C');            
//       PlaySound(2350);
 
 }else {
     
       SendMsg(",");
       data_b = 0x0E;
       DisplayByte(data_b);          // Write out to SCI
       data_b = 0x00;
       DisplayByte(data_b);          // Write out to SCI

//       string = " ,POSITION";
//       DisplayString(string);
       SetAlpha(1,'P'); 
       SetAlpha(2,'O'); 
       SetAlpha(3,'S');

   }    
 }       
}

      
/*****************************************************************************/
/*      ADCDEMO                                                              */
/*****************************************************************************/
/////////////////////STATE 3////////////////////////

void ADCDemo(void){
  ADCCFG1 =(ADLPC_NORMAL|ADIV_8|ADLSMP_LONG|MODE_12|ADICLK_BUS_2);
  ADCCFG2 =(ADACKEN_DISABLED|ADHSC_HISPEED|ADLSTS_20);
  //ADCCVA 0xFF,
  //ADCCVB 0xFF,
  ADCSC2 = (ADTRG_SW|ACFE_DISABLED|ACFGT_LESS|ACREN_DISABLED|REFSEL_EXT);
  ADCSC3 = (ADCO_SINGLE);
  ADCSC1 =(AIEN_OFF);
  
  LF;

  vfnLCD_All_Segments_OFF();
  SetAlpha(1,'A'); 
  SetAlpha(2,'D'); 
  SetAlpha(3,'C');
  WaitSec(2);
  DisplayString(" |   Values out of RESET  | ");
  
  ADCSC1_ADCH = channel_adc;       /* 0 & 4-11 */
  
    
  new_channel = 1;
// write ADC setup

  LF;
  DisplayString("| CFG1 = |"); 
  data_b = ADCCFG1;
  DisplayByte(data_b );          // Write  out to SCI
  DisplayString(" | CFG2 = |"); 
  data_b = ADCCFG2;
  DisplayByte(data_b);          // Write  out to SCI
  DisplayString(" | SC2 = |"); 
  data_b = ADCSC2;
  DisplayByte(data_b);          // Write  out to SCI
  DisplayString(" | SC3 = |"); 
  data_b = ADCSC3;
  DisplayByte(data_b);          // Write  out to SCI
  DisplayString(" | SC1A = |"); 
  data_b = ADCSC1;
  DisplayByte(data_b);          // Write  out to SCI
  LF;
  LF ;
        

//write database header
  DisplayString("| CFG1|");             
  DisplayString("  CHNL|");
  DisplayString(" DATA |");
  DisplayString(" VREFT|");
  DisplayString(" CFG2 |");

  Accel_WakeUp();    //Accel_WakeUp();        // wake up accelerometer

/////////////////////STATE 3////////////////////////
//////adc demo Mode////////////////////     
  while(state ==3){

      for (i=0x00;i<4;i++){
         if(i==0x00) {
          ADCCFG1 =(ADLPC_NORMAL|ADIV_8|ADLSMP_LONG|MODE_12|ADICLK_BUS_2);
         }
         if(i==1){
          ADCCFG1 =(ADLPC_NORMAL|ADIV_4|ADLSMP_LONG|MODE_12|ADICLK_BUS_2); 
         }
         if(i==2){
          ADCCFG1 =(ADLPC_NORMAL|ADIV_2|ADLSMP_LONG|MODE_12|ADICLK_BUS_2);
         }
         if(i==3){
          ADCCFG1 =(ADLPC_NORMAL|ADIV_1|ADLSMP_LONG|MODE_12|ADICLK_BUS_2);
         }
      for(t=0x40;t< 0xBF;t++) {
        trim = t;
        VREF1TRM = trim;
        VREF2TRM = trim;
      	do{
      	}while (ADCSC2_ADACT == 1);      /* Wait for conversion to complete */
        data = ADCR;
        if (new_channel ==1){
           mean = data;
           max = data;
           min = data;
           new_channel = 0;
        } else {
           mean = (mean + data)/2;
           if (data < min){
             min = data;
           }
           if (data > max){
              max = data;
           }
        }
        LF ;
        DisplayString("| ");             
        data_b = ADCCFG1;
        DisplayByte(data_b);          // Write  out to SCI
        DisplayString(" | ");
        DisplayByte(channel_adc);
        DisplayString(" | ");
        data_b = ADCRH;
        DisplayByte(data_b);          // Write out to SCI
        data_b = ADCRL;
        DisplayByte(data_b);          // Write out to SCI
        DisplayString(" | ");
        data_b = trim;                // VREF1 available on 80 pin 
        DisplayByte(data_b);          // Write out to SCI
        DisplayString(" | ");
        data_b = ADCCFG2;       // ADCCFG2 
        DisplayByte(data_b);          // Write out to SCI
        DisplayString(" |");
 
        ADCSC1_ADCH = channel_adc;       /* 0 & 4-11 */
        // Write the conversion result out to LCD.
        Low = (UINT8)((mean >> 8) & 0xF);   // Highest 4 bits to segment 1
        if(Low<=0x09){
        SetAlpha(1,Low+48);
        } else    {
        SetAlpha(1,Low+55);
        }
        High = (UINT8)((mean >> 4) & 0xF);  // Middle 4 bits to segment 2
        Low  = (UINT8)(mean & 0xF);         // Lowest 4 bits to segment 3

        if(High<=0x09){
        SetAlpha(2,High+48);
        } else    {
        SetAlpha(2,High+55);
        }
        if(Low<=0x09){
        SetAlpha(3,Low+48);
        } else    {
        SetAlpha(3,Low+55);
        }
        // Write the channel out to LCD segments 4 and 5
        Low = channel_adc&0x0F;
        High = (channel_adc&0xf0)/16;  
        if(High<=0x09){
        SetAlpha(4,High+48);
        } else    {
        SetAlpha(4,High+55);
        }
        if(Low<=0x09){
        SetAlpha(5,Low+48);
        } else    {
        SetAlpha(5,Low+55);
        }

        
      }/* for t - to change trim     */
     
      }/* for i - to change ADIV divide  */
     }
} /* loop forever */ 


////////////////////////////////////////////////////////////////////////////  
// Play sound at passed frequency for Quarter Second
////////////////////////////////////////////////////////////////////////

void PlaySound(unsigned int frequency)
{
  TPM1C0SC = 0x3C;
  TPM1C0V=frequency;
  while(TODSC_QSECF ==0);
     TODSC_QSECF =1;
  while(TODSC_QSECF ==0);
     TODSC_QSECF =1;
  
  TPM1C0SC = 0x00;
}


/********************************************************************
FUNCTION:		WaitSec
PURPOSE: 		General purpose delay 
INPUT NOTES: 8 bit unsigned value in seconds.
RETURN NOTES:	n/a
GENERAL NOTES:	depend on TOD running.
********************************************************************/
void WaitSec(unsigned char delay_sec){
	unsigned char j;
	DisableInterrupts;	
	for(j=0; j<delay_sec; j++){
      while(TODSC_SECF == 0);

      TODSC_SECF = 1;

	}
	EnableInterrupts;
}   // End WaitSec

