//-----------------------------------------------------------------------------
// F320_LED_Control.c
//-----------------------------------------------------------------------------
// Copyright 2006 Silicon Laboratories, Inc.
// http://www.silabs.com
//
// Program Description:
//
// This modules contains state machine for controlling the LEDs.  It is written
// to work with one LED connected to the PCA and one LED under software control
// or two LEDs connected to PCA channels.
//
// FID:            32X000040
// Target:         C8051F320
// Tool chain:     KEIL C51 7.0.0.1
//                 Silicon Laboratories IDE version 2.3
// Command Line:   See Readme.txt
// Project Name:   F320_FM_Radio
//
// Release 1.1
//    -No changes made to this module (DM)
//    -16 JAN 2006
//
// Release 1.0
//    -Initial Revision (DM)
//    -05 AUG 2005
//

//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------

#include "c8051f320.h"                 // SFR declarations
#include "F320_FM_RadioMain.h"         // Main project header
#include "F320_LED_Control.h"          // LED control header

//-----------------------------------------------------------------------------
// Variable Declaration
//-----------------------------------------------------------------------------

data BYTE Next_LED_Mode = NO_CHANGE_LED;
sbit STATIC_RED_LED = P3^0;

//-----------------------------------------------------------------------------
// LED_StateMachine
//
// Return Value : None
// Parameters   : None
//
// Controls the dimming, blinking and color patterns for LED using the PCA in
// 8-bit PWM mode and manual switching.
//
//-----------------------------------------------------------------------------
void LED_StateMachine (void) using USB_REGISTER_BANK
{
   static data BYTE Current_LED_Mode = SOLID_ORANGE_LED;
   static data BYTE Next_LED_State, State_Time_Left;

   if ((Next_LED_Mode != NO_CHANGE_LED) && (Current_LED_Mode != BLINK_RED_LED))
   {
      State_Time_Left = 0;             // Next state transition is immediate
      switch (Next_LED_Mode)
      {
         case ALL_COLOR_LED:
            Current_LED_Mode = Next_LED_Mode;
            Next_LED_Mode = NO_CHANGE_LED;
            Next_LED_State = OFF1_AC;
            break;

         case SOLID_GREEN_LED:
            Current_LED_Mode = Next_LED_Mode;
            Next_LED_Mode = NO_CHANGE_LED;
            break;

         case SOLID_RED_LED:
            Current_LED_Mode = Next_LED_Mode;
            Next_LED_Mode = NO_CHANGE_LED;
            break;

         case SOLID_ORANGE_LED:
            Current_LED_Mode = Next_LED_Mode;
            Next_LED_Mode = NO_CHANGE_LED;
            break;

         case BLINK_GREEN_LED:
            Current_LED_Mode = Next_LED_Mode;
            Next_LED_Mode = NO_CHANGE_LED;
            Next_LED_State = LED_OFF_BLINK;
            break;

         case BLINK_RED_LED:
            Current_LED_Mode = Next_LED_Mode;
            Next_LED_Mode = NO_CHANGE_LED;
            Next_LED_State = LED_OFF_BLINK;
            break;

         case BLINK_ORANGE_LED:
            Current_LED_Mode = Next_LED_Mode;
            Next_LED_Mode = NO_CHANGE_LED;
            Next_LED_State = LED_OFF_BLINK;
            break;

         default:
            Next_LED_Mode = BLINK_RED_LED;
            break;

      }
   }

   if (State_Time_Left == 0)
   {
      switch (Current_LED_Mode)
      {
         case ALL_COLOR_LED:
            switch(Next_LED_State)
            {
               case OFF1_AC:
                  GREEN_LED_DIMMER = 0xFF;
                  RED_LED_DIMMER = 0xFF;
                  STATIC_RED_LED = OFF;
                  State_Time_Left = 0x255;
                  Next_LED_State++;
                  break;

               case GREEN_RAMPUP1_AC:
                  GREEN_LED_DIMMER--;
                  STATIC_RED_LED ^= ON;
                  RED_LED_DIMMER = 0x80;
                  State_Time_Left = 4;
                  if (GREEN_LED_DIMMER == 0x60) Next_LED_State++;
                  break;

               case ORANGE_FULL1_AC:
                  STATIC_RED_LED = ON;
                  RED_LED_DIMMER = 0x60;
                  State_Time_Left = 9;
                  Next_LED_State++;
                  break;

               case GREEN_RAMPDOWN1_AC:
                  GREEN_LED_DIMMER++;
                  STATIC_RED_LED ^= ON;
                  RED_LED_DIMMER = 0x80;
                  State_Time_Left = 4;
                  if (GREEN_LED_DIMMER == 0xFF) Next_LED_State++;
                  break;

               case OFF2_AC:
                  STATIC_RED_LED = OFF;
                  RED_LED_DIMMER = 0xFF;
                  State_Time_Left = 0x0A;
                  Next_LED_State++;
                  break;

               case GREEN_RAMPUP2_AC:
                  GREEN_LED_DIMMER--;
                  STATIC_RED_LED = OFF;
                  State_Time_Left = 4;
                  if (GREEN_LED_DIMMER == 0x60) Next_LED_State++;
                  break;

               case ORANGE_FULL2_AC:
                  STATIC_RED_LED = ON;
                  RED_LED_DIMMER = 0x60;
                  State_Time_Left = 9;
                  Next_LED_State++;
                  break;

               case GREEN_RAMPDOWN2_AC:
                  GREEN_LED_DIMMER++;
                  STATIC_RED_LED = OFF;
                  RED_LED_DIMMER = 0xFF;
                  State_Time_Left = 4;
                  if (GREEN_LED_DIMMER == 0xFF) Next_LED_State = OFF1_AC;
                  break;

               default:
                  Next_LED_Mode = BLINK_RED_LED;
                  break;

            }
            break;
         case SOLID_GREEN_LED:
            GREEN_LED_DIMMER = MAX_BRIGHT_LED;
            RED_LED_DIMMER = MIN_BRIGHT_LED;
            STATIC_RED_LED = OFF;
            break;

         case SOLID_RED_LED:
            GREEN_LED_DIMMER = MIN_BRIGHT_LED;
            RED_LED_DIMMER = MAX_BRIGHT_LED;
            STATIC_RED_LED = ON;
            break;

         case SOLID_ORANGE_LED:
            GREEN_LED_DIMMER = MAX_BRIGHT_LED;
            RED_LED_DIMMER = MAX_BRIGHT_LED + ORANGE_OFFSET_LED;
            STATIC_RED_LED = ON;
            break;

         case BLINK_GREEN_LED:
            switch (Next_LED_State)
            {
               case LED_ON_FULL_BLINK:
                  GREEN_LED_DIMMER = MAX_BRIGHT_LED;
                  State_Time_Left = GREEN_ON_TIME_LED;
                  Next_LED_State++;
                  break;

               case LED_RAMPDOWN_BLINK:
                  GREEN_LED_DIMMER++;
                  State_Time_Left = GREEN_RAMPDOWN_TIME_LED;
                  if (GREEN_LED_DIMMER == MIN_BRIGHT_LED) Next_LED_State++;
                  break;

               case LED_OFF_BLINK:
                  GREEN_LED_DIMMER = OFF_BRIGHT_LED;
                  RED_LED_DIMMER = OFF_BRIGHT_LED;
                  STATIC_RED_LED = OFF;
                  State_Time_Left = GREEN_OFF_TIME_LED;
                  Next_LED_State++;
                  break;

               case LED_ON_MIN_BLINK:
                  GREEN_LED_DIMMER = MIN_BRIGHT_LED;
                  State_Time_Left = GREEN_RAMPUP_TIME_LED;
                  Next_LED_State++;
                  break;

               case LED_RAMPUP_BLINK:
                  GREEN_LED_DIMMER--;
                  State_Time_Left = GREEN_RAMPUP_TIME_LED;
                  if (GREEN_LED_DIMMER == MAX_BRIGHT_LED)
                     Next_LED_State = LED_ON_FULL_BLINK;
                  break;

               default:
                  Next_LED_Mode = BLINK_RED_LED;
                  break;

            }
            break;

         case BLINK_RED_LED:
            switch (Next_LED_State)
            {
               case LED_ON_FULL_BLINK:
                  RED_LED_DIMMER = MAX_BRIGHT_LED;
                  State_Time_Left = RED_ON_TIME_LED;
                  Next_LED_State++;
                  break;

               case LED_RAMPDOWN_BLINK:
                  RED_LED_DIMMER++;
                  State_Time_Left = RED_RAMPDOWN_TIME_LED;
                  if (RED_LED_DIMMER == MIN_BRIGHT_LED) Next_LED_State++;
                  break;

               case LED_OFF_BLINK:
                  RED_LED_DIMMER = OFF_BRIGHT_LED;
                  GREEN_LED_DIMMER = OFF_BRIGHT_LED;
                  STATIC_RED_LED = OFF;
                  State_Time_Left = RED_OFF_TIME_LED;
                  Next_LED_State++;
                  break;

               case LED_ON_MIN_BLINK:
                  RED_LED_DIMMER = MIN_BRIGHT_LED;
                  STATIC_RED_LED = ON;
                  State_Time_Left = RED_RAMPUP_TIME_LED;
                  Next_LED_State++;
                  break;

               case LED_RAMPUP_BLINK:
                  RED_LED_DIMMER--;
                  State_Time_Left = RED_RAMPUP_TIME_LED;
                  if (RED_LED_DIMMER == MAX_BRIGHT_LED)
                     Next_LED_State = LED_ON_FULL_BLINK;
                  break;

               default:
                  Next_LED_Mode = BLINK_RED_LED;
                  break;

            }
            break;

         case BLINK_ORANGE_LED:
            switch (Next_LED_State)
            {
               case LED_ON_FULL_BLINK:
                  GREEN_LED_DIMMER = MAX_BRIGHT_LED;
                  RED_LED_DIMMER = MAX_BRIGHT_LED + ORANGE_OFFSET_LED;
                  STATIC_RED_LED ^= ON;
                  State_Time_Left = ORANGE_ON_TIME_LED;
                  Next_LED_State++;
                  break;

               case LED_RAMPDOWN_BLINK:
                  GREEN_LED_DIMMER++;
                  RED_LED_DIMMER++;
                  STATIC_RED_LED ^= ON;
                  State_Time_Left = ORANGE_RAMPDOWN_TIME_LED;
                  if (RED_LED_DIMMER == MIN_BRIGHT_LED) Next_LED_State++;
                  break;

               case LED_OFF_BLINK:
                  GREEN_LED_DIMMER = OFF_BRIGHT_LED;
                  RED_LED_DIMMER = OFF_BRIGHT_LED;
                  STATIC_RED_LED = OFF;
                  State_Time_Left = ORANGE_OFF_TIME_LED;
                  Next_LED_State++;
                  break;

               case LED_ON_MIN_BLINK:
                  GREEN_LED_DIMMER = MIN_BRIGHT_LED;
                  RED_LED_DIMMER = MIN_BRIGHT_LED + ORANGE_OFFSET_LED;
                  STATIC_RED_LED ^= ON;
                  State_Time_Left = ORANGE_RAMPUP_TIME_LED;
                  Next_LED_State++;
                  break;

               case LED_RAMPUP_BLINK:
                  GREEN_LED_DIMMER--;
                  RED_LED_DIMMER--;
                  STATIC_RED_LED ^= ON;
                  State_Time_Left = ORANGE_RAMPUP_TIME_LED;
                  if (GREEN_LED_DIMMER == MAX_BRIGHT_LED)
                     Next_LED_State = LED_ON_FULL_BLINK;
                  break;

               default:
                  Next_LED_Mode = BLINK_RED_LED;
                  break;

            }
            break;

         default:
            Next_LED_Mode = BLINK_RED_LED;
            break;

      }
   }
   else State_Time_Left--;
}

//-----------------------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------------------