//-----------------------------------------------------------------------------
// main.c
//-----------------------------------------------------------------------------
// Copyright 2004 UK SolarCar Team.
//
// AUTH: Saravana Kannan
// DATE: 14 May 04
//
// This file contains the main() function and the PPPT code.
//
// Target: C8051F31x
// Tool chain: KEIL C51 6.03 / KEIL EVAL C51
//

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <c8051f310.h>		// SFR declarations
#include <stdio.h>
#include "init.h"
#include "serial.h"
#include "adc.h"
#include "pwm.h"

//-----------------------------------------------------------------------------
//  Global Constants
//-----------------------------------------------------------------------------
#define INC		0
#define DEC		1
#define VPANIC	2
#define IPANIC	3

#define DINC	1
#define NUMWAIT	3
#define VLIMIT	3.0
#define ILIMIT  0.3
#define PANICDUTY  	0.3
#define PANICDELAY	10
#define HILIMIT		0xBF
#define LOWLIMIT	0x66
sbit LED = P3 ^ 3;		// LED='1' means ON


//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
unsigned int keyinQ = 0;
unsigned int paniccnt = 0;
int op = 1;
unsigned int pcnt = 0;

/* Global variables used by the PPPT code. */
int pwrmode = INC;
int dec = 0;
float p_ocurr = 0, vdiff = 0;
int canpanic = 0;

//-----------------------------------------------------------------------------
// Function PROTOTYPES
//-----------------------------------------------------------------------------
void incDuty ();
void decDuty ();

//-----------------------------------------------------------------------------
// MAIN Routine
//-----------------------------------------------------------------------------

void main (void)
{

//   char keypress;

    // Disable Watchdog timer
    PCA0MD &= ~0x40;		// WDTE = 0 (clear watchdog timer enable)
    SYSCLK_Init ();		// Initialize Oscillator
    PORT_Init ();		// Initialize Port I/O
    UART0_Init ();		// Initialize UART

    ADC0_Init ();		// Init ADC0
    AD0EN = 1;			// Enable ADC0

    Timer0_Init ();		// Init Timer0 to generate interrupts at a 20KHz rate.
    Timer2_Init ();
    PCA_Init (0x66);		// Pass initial duty cycle. Initial duty of 0 is needed. Pass FF for 100% duty.
    EA = 1;			// Enable global interrupts.

    keyinQ = 0;

    if (op == 1)
	initLCD ();
    else
	initRADIO ();

// This helps?? 
//   PCA0CPH0 = 0;

    while (1)
    {
	if (pcnt >= 31)
	{
	    speed = getspeed ();
	    dispLCD ();
	    pcnt = 0;
	}
    }
}

void incDuty ()
{
    if (PCA0CPH0 < (HILIMIT - DINC))
	PCA0CPH0 += DINC;
    else
	PCA0CPH0 = HILIMIT;
}

void decDuty ()
{
    if (PCA0CPH0 > DINC)
	PCA0CPH0 -= DINC;
    else
	PCA0CPH0 = 0x00;
}

void powermgmt ()
{

    /* Read values from the ADC */
    ovolt = get_out_volt ();
    ocurr = get_out_curr ();
    ivolt = get_in_volt ();
    icurr = get_in_curr ();

//        vdiff = ovolt - ivolt;
//        if(vdiff<0) vdiff = -vdiff;
//        if(vdiff<VLIMIT) pwrmode = VPANIC;
/*	  if(ocurr<ILIMIT && canpanic)
      {
	   pwrmode = IPANIC;
	   paniccnt=0;
	  }*/

    switch (pwrmode)
    {
    case INC:
	incDuty ();
	if (ocurr > ILIMIT)
	    canpanic = 1;
	if (ocurr < p_ocurr)
	    dec++;
	else if (dec > 0)
	    dec--;
	if (dec >= NUMWAIT)
	{
	    dec = 0;
	    pwrmode = DEC;
	}
	p_ocurr = ocurr;
	break;
    case DEC:
	decDuty ();
	if (PCA0CPH0 <= LOWLIMIT)
	    pwrmode = INC;
	if (ocurr < p_ocurr)
	    dec++;
	else if (dec > 0)
	    dec--;
	if (dec >= NUMWAIT)
	{
	    dec = 0;
	    pwrmode = INC;
	}
	p_ocurr = ocurr;
	break;
/*	   case VPANIC:
	   		PCA0CPH0=PANICDUTY;
			pwrmode=INC;
			break;*/
    case IPANIC:
	PCA0CPH0 = 0;
	canpanic = 0;
	ocurr = 0;
	p_ocurr = 0;
	if (paniccnt == 0)
	{
	    pwrmode = INC;
	    PCA0CPH0 = LOWLIMIT;
	    ocurr = 0;
	    p_ocurr = 0;
	}
	break;
    }

}

//-----------------------------------------------------------------------------
// Interrupt Service Routines
//-----------------------------------------------------------------------------


// Should use 8bit mode and set TL0 to FB to generate TO overflow at 4.9MHz

/*void UART_ISR (void) interrupt 4
{
   if(RI0==1)
   {
    keyinQ=1;
    //RI0 = 0;
   }
}*/
