/*
 * ======== Standard MSP430 includes ========
 */
#include <msp430.h>
/*
 * ======== time related includes ========
 */
//#include <string.h>
#include <time.h>
#include "rtc.h"
/*
 * ======== Grace related includes ========
 */
#include <ti/mcu/msp430/csl/CSL.h>

 //LCD functions
 void xmitt(unsigned char, unsigned char);
 void delay_c(unsigned int);
 void pulse();
 void write_lcd(unsigned char, unsigned char);
 void cls(unsigned char);//Clear Screen.
 void LCD_string(char *string,unsigned char);//Print Character String. Second char is for inverted text.
 void LCD_char(unsigned char, unsigned char);//Print Individual Character. Second char is for inverted text.
 void Big_char(unsigned char, unsigned char);//Print LARGE Individual Character. Second char is for inverted text.
 void lead_zero(unsigned int);//Add leading zero to single digit numbers.
 void set_position(int,int);//Set current LCD position.

 //LCD Variables
 unsigned char night = 1;//True for clock showing night time illumination.
 unsigned char aux_out = 0;//Used to control 5 remaining ouputs on control shift register. Values above bit 2 (8 or more).
 unsigned int y_pos = 0;//Cursor Position Left to Right.
 unsigned char x_col;//Cursor row position 0-Top to 7-Bottom.
 const unsigned char font[] = {

    	      // font data

    	      0x00, 0x00, 0x00, 0x00, 0x00,// (space)

    	  	0x00, 0x00, 0x5F, 0x00, 0x00,// !

    	  	0x00, 0x07, 0x00, 0x07, 0x00,// "

    	  	0x14, 0x7F, 0x14, 0x7F, 0x14,// #

    	  	0x24, 0x2A, 0x7F, 0x2A, 0x12,// $

    	  	0x23, 0x13, 0x08, 0x64, 0x62,// %

    	  	0x36, 0x49, 0x55, 0x22, 0x50,// &

    	  	0x00, 0x05, 0x03, 0x00, 0x00,// '

    	  	0x00, 0x1C, 0x22, 0x41, 0x00,// (

    	  	0x00, 0x41, 0x22, 0x1C, 0x00,// )

    	  	0x08, 0x2A, 0x1C, 0x2A, 0x08,// *

    	  	0x08, 0x08, 0x3E, 0x08, 0x08,// +

    	  	0x00, 0x50, 0x30, 0x00, 0x00,// ,

    	  	0x08, 0x08, 0x08, 0x08, 0x08,// -

    	  	0x00, 0x60, 0x60, 0x00, 0x00,// .

    	  	0x20, 0x10, 0x08, 0x04, 0x02,// /

    	  	0x3E, 0x51, 0x49, 0x45, 0x3E,// 0

    	  	0x00, 0x42, 0x7F, 0x40, 0x00,// 1

    	  	0x42, 0x61, 0x51, 0x49, 0x46,// 2

    	  	0x21, 0x41, 0x45, 0x4B, 0x31,// 3

    	  	0x18, 0x14, 0x12, 0x7F, 0x10,// 4

    	  	0x27, 0x45, 0x45, 0x45, 0x39,// 5

    	  	0x3C, 0x4A, 0x49, 0x49, 0x30,// 6

    	  	0x01, 0x71, 0x09, 0x05, 0x03,// 7

    	  	0x36, 0x49, 0x49, 0x49, 0x36,// 8

    	  	0x06, 0x49, 0x49, 0x29, 0x1E,// 9

    	  	0x00, 0x36, 0x36, 0x00, 0x00,// :

    	  	0x00, 0x56, 0x36, 0x00, 0x00,// ;

    	  	0x00, 0x08, 0x14, 0x22, 0x41,// <

    	  	0x14, 0x14, 0x14, 0x14, 0x14,// =

    	  	0x41, 0x22, 0x14, 0x08, 0x00,// >

    	  	0x02, 0x01, 0x51, 0x09, 0x06,// ?

    	  	0x32, 0x49, 0x79, 0x41, 0x3E,// @

    	  	0x7E, 0x11, 0x11, 0x11, 0x7E,// A

    	  	0x7F, 0x49, 0x49, 0x49, 0x36,// B

    	  	0x3E, 0x41, 0x41, 0x41, 0x22,// C

    	  	0x7F, 0x41, 0x41, 0x22, 0x1C,// D

    	  	0x7F, 0x49, 0x49, 0x49, 0x41,// E

    	  	0x7F, 0x09, 0x09, 0x01, 0x01,// F

    	  	0x3E, 0x41, 0x41, 0x51, 0x32,// G

    	  	0x7F, 0x08, 0x08, 0x08, 0x7F,// H

    	  	0x00, 0x41, 0x7F, 0x41, 0x00,// I

    	  	0x20, 0x40, 0x41, 0x3F, 0x01,// J

    	  	0x7F, 0x08, 0x14, 0x22, 0x41,// K

    	  	0x7F, 0x40, 0x40, 0x40, 0x40,// L

    	  	0x7F, 0x02, 0x04, 0x02, 0x7F,// M

    	  	0x7F, 0x04, 0x08, 0x10, 0x7F,// N

    	  	0x3E, 0x41, 0x41, 0x41, 0x3E,// O

    	  	0x7F, 0x09, 0x09, 0x09, 0x06,// P

    	  	0x3E, 0x41, 0x51, 0x21, 0x5E,// Q

    	  	0x7F, 0x09, 0x19, 0x29, 0x46,// R

    	  	0x46, 0x49, 0x49, 0x49, 0x31,// S

    	  	0x01, 0x01, 0x7F, 0x01, 0x01,// T

    	  	0x3F, 0x40, 0x40, 0x40, 0x3F,// U

    	  	0x1F, 0x20, 0x40, 0x20, 0x1F,// V

    	  	0x7F, 0x20, 0x18, 0x20, 0x7F,// W

    	  	0x63, 0x14, 0x08, 0x14, 0x63,// X

    	  	0x03, 0x04, 0x78, 0x04, 0x03,// Y

    	  	0x61, 0x51, 0x49, 0x45, 0x43,// Z

    	  	0x00, 0x00, 0x7F, 0x41, 0x41,// [

    	  	0x02, 0x04, 0x08, 0x10, 0x20,// "\"

    	  	0x41, 0x41, 0x7F, 0x00, 0x00,// ]

    	  	0x04, 0x02, 0x01, 0x02, 0x04,// ^

    	  	0x40, 0x40, 0x40, 0x40, 0x40,// _

    	  	0x00, 0x01, 0x02, 0x04, 0x00,// `

    	  	0x20, 0x54, 0x54, 0x54, 0x78,// a

    	  	0x7F, 0x48, 0x44, 0x44, 0x38,// b

    	  	0x38, 0x44, 0x44, 0x44, 0x20,// c

    	  	0x38, 0x44, 0x44, 0x48, 0x7F,// d

    	  	0x38, 0x54, 0x54, 0x54, 0x18,// e

    	  	0x08, 0x7E, 0x09, 0x01, 0x02,// f

    	  	0x08, 0x14, 0x54, 0x54, 0x3C,// g

    	  	0x7F, 0x08, 0x04, 0x04, 0x78,// h

    	  	0x00, 0x44, 0x7D, 0x40, 0x00,// i

    	  	0x20, 0x40, 0x44, 0x3D, 0x00,// j

    	  	0x00, 0x7F, 0x10, 0x28, 0x44,// k

    	  	0x00, 0x41, 0x7F, 0x40, 0x00,// l

    	  	0x7C, 0x04, 0x18, 0x04, 0x78,// m

    	  	0x7C, 0x08, 0x04, 0x04, 0x78,// n

    	  	0x38, 0x44, 0x44, 0x44, 0x38,// o

    	  	0x7C, 0x14, 0x14, 0x14, 0x08,// p

    	  	0x08, 0x14, 0x14, 0x18, 0x7C,// q

    	  	0x7C, 0x08, 0x04, 0x04, 0x08,// r

    	  	0x48, 0x54, 0x54, 0x54, 0x20,// s

    	  	0x04, 0x3F, 0x44, 0x40, 0x20,// t

    	  	0x3C, 0x40, 0x40, 0x20, 0x7C,// u

    	  	0x1C, 0x20, 0x40, 0x20, 0x1C,// v

    	  	0x3C, 0x40, 0x30, 0x40, 0x3C,// w

    	  	0x44, 0x28, 0x10, 0x28, 0x44,// x

    	  	0x0C, 0x50, 0x50, 0x50, 0x3C,// y

    	  	0x44, 0x64, 0x54, 0x4C, 0x44,// z

    	  	0x00, 0x08, 0x36, 0x41, 0x00,// {

    	  	0x00, 0x00, 0x7F, 0x00, 0x00,// |

    	  	0x00, 0x41, 0x36, 0x08, 0x00,// }

    	  	0x08, 0x08, 0x2A, 0x1C, 0x08,// ->

    	  	0x08, 0x1C, 0x2A, 0x08, 0x08, // <-

    	  	0x0,0x0,0x0,0x80,    0xe0,0xf8,0x7c,0x1c, 0x1e,0xe,0xe,0xe,    0x1e,0x9c,0xfc,0xf8,
    	    0xe0,0xc0,0x0,0x0,   0x0,0x0,0xfc,0xff,   0xff,0x3,0x0,0x0,    0x80,0xe0,0xf0,0xfc,
    	    0xfe,0xff,0x7f,0x1f, 0xff,0xff,0xfc,0x0,  0x0,0x0,0x3f,0xff,   0xff,0xf0,0xfc,0xff,
    	    0xff,0x7f,0x1f,0x7,  0x3,0x0,0x0,0xc0,    0xff,0xff,0x3f,0x0,  0x0,0x0,0x0,0x1,
    	    0x7,0x1f,0x3f,0x3d,  0x78,0x70,0x70,0x70, 0x78,0x38,0x3e,0x1f, 0x7,0x1,0x0,0x0, // Big 0.

    	  	0x0,0x0,0x80,0xc0,   0xc0,0xe0,0xf0,0x78,  0x7c,0xfe,0xfe,0xfe,  0xfe,0x0,0x0,0x0,
    	    0x0,0x0,0x0,0x0,     0x0,0x1,0x1,0x1,      0x1,0x1,0x0,0x0,      0x0,0xff,0xff,0xff,
    	    0xff,0x0,0x0,0x0,	 0x0,0x0,0x0,0x0,	   0x0,0x0,0x0,0x0,		 0x0,0x0,0x0,0x0,
    	    0x0,0xff,0xff,0xff,  0xff,0x0,0x0,0x0,	   0x0,0x0,0x0,0x0,		 0x0,0x0,0x70,0x70,
    	    0x70,0x70,0x70,0x70, 0x70,0x7f,0x7f,0x7f,  0x7f,0x70,0x70,0x70,  0x70,0x70,0x70,0x0, //Big 1

    	    0x0,0x0,0x0,0xf0,	 0xf8,0x7c,0x3c,0x1c,  0x1e,0xe,0xe,0xe,	 0xe,0x1e,0x1c,0x7c,
    	    0xf8,0xf0,0xc0,0x0,  0x0,0x0,0x0,0x0,      0x0,0x0,0x0,0x0,      0x0,0x0,0x0,0x0,
    	    0x0,0x80,0xe0,0xf0,  0xff,0x3f,0xf,0x0,    0x0,0x0,0x0,0x0,      0x80,0x80,0xc0,0xe0,
    	    0xf0,0x78,0x3c,0x1e, 0xf,0x7,0x3,0x1,      0x0,0x0,0x0,0x0,      0x0,0x18,0x3c,0x3f,
    	    0x3f,0x3f,0x3f,0x3d, 0x3c,0x3c,0x3c,0x3c,  0x3c,0x3c,0x3c,0x3c,  0x3c,0x3f,0x3f,0x0, //Big 2.

    	    0x0,0x0,0x0,0x38,	 0x38,0x3c,0x1c,0x1e,  0xe,0xe,0xe,0xe,     0x1e,0x1c,0x7c,0xf8,
    	    0xf0,0xc0,0x0,0x0,   0x0,0x0,0x0,0x0,	   0x0,0x0,0x0,0x0,	    0xc0,0xc0,0xc0,0xe0,
    	    0xe0,0xf0,0xf8,0xbf, 0x1f,0xf,0x0,0x0,     0x0,0x0,0x0,0x0,	    0x0,0x0,0x0,0x0,
    	    0x0,0x1,0x1,0x1,	 0x1,0x3,0x7,0xf,	   0xff,0xfe,0xf8,0x0,	0x0,0xc,0x1c,0x3c,
    	    0x3c,0x38,0x78,0x70, 0x70,0x70,0x70,0x70,  0x70,0x38,0x3c,0x1e, 0xf,0x7,0x1,0x0, //Big 3.

    	    0x0,0x0,0x0,0x0,	 0x0,0x0,0x0,0x0,      0x80,0xe0,0xf0,0x7c, 0x1e,0xfe,0xfe,0xfe,
    	    0x0,0x0,0x0,0x0,     0x0,0x0,0x0,0x0,      0xc0,0xf0,0xf8,0x7e, 0x1f,0x7,0x1,0x0,
    	    0x0,0xff,0xff,0xff,  0x0,0x0,0x0,0x0,      0x0,0x78,0x7c,0x7f,  0x7f,0x73,0x70,0x70,
    	    0x70,0x70,0x70,0x70, 0x70,0xff,0xff,0xff,  0x70,0x70,0x70,0x0,  0x0,0x0,0x0,0x0,
    	    0x0,0x0,0x0,0x0,     0x0,0x38,0x38,0x38,   0x38,0x3f,0x3f,0x3f, 0x38,0x38,0x38,0x0, //Big 4.

    	    0x0,0x0,0x0,0xfc,    0xfc,0xfc,0x3c,0x3c,  0x3c,0x3c,0x3c,0x3c, 0x3c,0x3c,0x3c,0x3c,
    	    0x3c,0x0,0x0,0x0,    0x0,0x0,0x0,0xff,     0xff,0xff,0x70,0x70, 0x38,0x38,0x38,0x38,
    	    0x78,0x78,0xf0,0xe0, 0xc0,0x80,0x0,0x0,    0x0,0x0,0x0,0x0,     0x0,0x0,0x0,0x0,
    	    0x0,0x0,0x0,0x0,     0x0,0x0,0x0,0x3,      0xff,0xff,0xfe,0x0,  0x0,0x8,0x1c,0x3c,
    	    0x38,0x78,0x78,0x70, 0x70,0x70,0x70,0x70,  0x78,0x38,0x3c,0x1f, 0xf,0x7,0x0,0x0, //Big 5.

    	    0x0,0x0,0x0,0x0,     0x0,0xc0,0xe0,0xf0,   0x78,0x38,0x1c,0x1c, 0xe,0xe,0xe,0xe,
    	    0xe,0xe,0xe,0x0,     0x0,0x0,0xe0,0xfc,    0xff,0xff,0xc7,0xe1, 0xe0,0x70,0x70,0x70,
    	    0x70,0xf0,0xe0,0xe0, 0xc0,0x0,0x0,0x0,     0x0,0x0,0x3f,0xff,   0xff,0xff,0x3,0x1,
    	    0x0,0x0,0x0,0x0,     0x0,0x0,0x1,0x7,      0xff,0xff,0xfc,0x0,  0x0,0x0,0x0,0x3,
    	    0x7,0x1f,0x1f,0x3c,	 0x78,0x70,0x70,0x70,  0x70,0x78,0x3c,0x3e, 0x1f,0x7,0x1,0x0,// Big 6.

    	    0x0,0x78,0x7c,0x7c,  0x1c,0x1c,0x1c,0x1c,  0x1c,0x1c,0x1c,0x1c, 0x1c,0x1c,0x1c,0xfc,
    	    0xfc,0xfc,0x7c,0x0,  0x0,0x0,0x0,0x0,      0x0,0x0,0x0,0x0,     0x0,0x0,0x0,0x0,
    	    0xe0,0xf8,0xff,0x7f, 0xf,0x1,0x0,0x0,      0x0,0x0,0x0,0x0,     0x0,0x0,0x0,0x0,
    	    0x0,0xe0,0xf8,0xff,  0xff,0x1f,0x3,0x0,    0x0,0x0,0x0,0x0,     0x0,0x0,0x0,0x0,
    	    0x0,0x0,0x0,0x38,    0x3f,0x3f,0x1f,0x3,   0x0,0x0,0x0,0x0,     0x0,0x0,0x0,0x0, //Big 7.

    	    0x0,0x0,0xc0,0xf0,   0xf8,0x7c,0x1c,0x1e,  0xe,0xe,0xe,0xe,     0x1e,0x1c,0x7c,0xf8,
    	    0xf0,0xc0,0x0,0x0,   0x0,0x0,0xf,0x3f,     0x7f,0xf8,0xe0,0xc0, 0xc0,0xc0,0xc0,0xc0,
    	    0xc0,0xe0,0xf0,0x7f, 0x3f,0xf,0x0,0x0,     0x0,0x0,0xf0,0xfc,   0xfe,0xf,0x7,0x3,
    	    0x3,0x1,0x1,0x3,     0x3,0x3,0x7,0xf,      0xfe,0xfc,0xf0,0x0,  0x0,0x0,0x3,0xf,
    	    0x1f,0x3e,0x38,0x78, 0x70,0x70,0x70,0x70,  0x70,0x38,0x3c,0x1e, 0x1f,0xf,0x3,0x0, //Big 8.

    	    0x0,0x0,0x80,0xe0,   0xf8,0x7c,0x3c,0x1e,  0xe,0xe,0xe,0xe,     0x1e,0x3c,0xf8,0xf8,
    	    0xe0,0xc0,0x0,0x0,   0x0,0x0,0x3f,0xff,    0xff,0xe0,0x80,0x0,  0x0,0x0,0x0,0x0,
    	    0x0,0x80,0xc0,0xff,  0xff,0xff,0xfe,0x0,   0x0,0x0,0x0,0x0,     0x3,0x7,0x7,0xf,
    	    0xe,0xe,0xe,0xe,     0x7,0x87,0xe3,0xff,   0xff,0x7f,0xf,0x0,   0x0,0x0,0x70,0x70,
    	    0x70,0x70,0x70,0x70, 0x70,0x38,0x38,0x1c,  0x1e,0xf,0x7,0x3,    0x1,0x0,0x0,0x0, //Big 9.

    	    0x0,0x0,0x0,0x0,     0x0,0x0,0x0,0x80,     0xc0,0xc0,0xc0,0xc0, 0xc0,0x80,0x0,0x0,
    	    0x0,0x0,0x0,0x0,     0x0,0x0,0x0,0x0,      0x0,0x0,0xf,0x1f,    0x3f,0x3f,0x3f,0x3f,
    	    0x3f,0x1f,0xf,0x0,   0x0,0x0,0x0,0x0,      0x0,0x0,0x0,0x0,     0x0,0x0,0xf0,0xf8,
    	    0xfc,0xfc,0xfc,0xfc, 0xfc,0xf8,0xf0,0x0,   0x0,0x0,0x0,0x0,     0x0,0x0,0x0,0x0,
    	    0x0,0x0,0x0,0x1,     0x3,0x3,0x3,0x3,      0x3,0x1,0x0,0x0,     0x0,0x0,0x0,0x0, //Big :.
    	  };


 //Clock functions.
 /*Addition of RTC coding is from opossum as listed on:
   * http://forum.43oh.com/topic/1957-software-real-time-clock-rtc-two-methods/
   * This includes rtc.h and rtc.c.
   */
 void WDTISRHandler();
 void show_time(const struct tm *t);
 int _dow(int,int,int);
 char two_dig[] = "00";//Array for leading zero function.
 unsigned char colon_on;//Turns colon on and off every half second.
 unsigned char store_min;//Check for change in minutes.
 unsigned char store_hour;//Check for change in hour.
 void set_time(void);//Set the variables in rtc.c

//Clock Variables.
 struct tm ts;                    // Time structure
 time_t tt;						  // Time in seconds since epoch
 unsigned char WD_ticks = 0;	  // Watchdog is at 4hz. Branch depending on need.
 unsigned char alarm_pend = 0;    // Alarm pending. BIT 0 is for alarm pending. BIT 1 is for alarm reset.

 //IR functions.
  void Port2ISRHandler();//triggers each time IR Modulated Pulse is sent.
  void TimerA3_50us();// counts intervals of 50 microseconds
  void dump_no(void);//dumps numbers collected from signal.
  void IR_set_time (void);//Pulls up settings menu.

  //Variables for IR functions
   	unsigned int A3_counter = 0;
 	unsigned char utime[12];
 	unsigned char uindex = 0;
 	//Remote control map.

/*
 * Clock operation functions
 */
 	void update_LCD();// Update Screen every half second.

 /*
  * Clock operation variables.
  */
 unsigned char rmode = 1;//1 is clock function. 0 is settings function.

  /*
  * Menu operation.
  */
 //Menu functions.
 void first_menu(void);
 void second_menu(unsigned char);
 void set_digit(unsigned char,unsigned char);
//Menu variables.

 //menu settings. hour, minute, AM PM Military Time, month, year, day, alarm hour, alarm minute, weekday repeat
 unsigned char men_set[9] = {12,0,1,12,12,12,25,0,0};
 char Message[] = "                                                                             ";
 signed char men_row = 0;//Menu Row
 signed char men_col = 0;//Menu Col
 signed char old_row = 0;//stores previous row number
 signed char old_col = 0;//stores previous col number
 char button;//stored keyboard input char.
 unsigned char f_menu = 7;//7 if we are on top level menu.
 unsigned char misc1 = 0;//Global misc. variable.
 unsigned char misc2 = 0;//Global misc. variable.
 unsigned char men_choice = 0;//Menu item chosen by right movement.

 	/*
 	 *  ======== main ========
 	 */
 	 //P1.5 is clock out. Blue.
 	 //P1.7 is data out. Yellow.
 	// P2.0 is our shift register latch pin. Orange.
 	// P2.1 is our output enable on GLCD board. White.
 	// P2.3 is our IR input.

void main(int argc, char *argv[])
{
    CSL_init();                     // Activate Grace-generated configuration
    __enable_interrupt();           // Set global interrupt enable
    CCTL0 |= CCIE; //shut off timer interupt.

  //Initialize transmit buffer with zero.
    P2OUT |= BIT0;//P2.0 is our latch pin. Set Low
    UCB0TXBUF = 0x00;
    P2OUT  &= ~BIT0;//Set P2.0 High

    delay_c(60000);//Give LCD time to power up.

    //Initialization
    write_lcd(63,2);//initialize left side of screen.
    write_lcd(63,1);//initialize right side of screen.

    //clear screen.
   cls(night);//To White, Black is 1.

 //Set time.
   set_time();

}
/*
 * LCD Functions.
 */
//Pulse Enable pin.
void pulse(){
	P2OUT |= BIT1;//P2.1 is Enable. Set High
	delay_c(2);
	P2OUT &= ~BIT1;//Set P2.1 Low
	}

//Write to LCD
void write_lcd(unsigned char low_byte, unsigned char high_byte){
	 high_byte = high_byte + aux_out;//Adds ability to switch 5 remaining shift register outputs.
	 xmitt(high_byte,1);//set control inputs.
	 xmitt(low_byte,0); //set data inputs and shift register out.
	 pulse();
}

//Set LCD postion for next character.
//Order is traditional X across, Y up down.
void set_position(int col,int row){
	if(col < 64){
		write_lcd(64 + col,1);//Set left half Y (columns) to col.
		write_lcd(64,2);      //Set right half Y (columns) to 0.
		}
	else{
		write_lcd(col,2);//Set right half Y (columns) to col less left side distance.
		write_lcd(64,1);      //Set left half Y (columns) to 0.
	}
	write_lcd(184 + row,1);//Set X (Rows) to row.
	write_lcd(184 + row,2);//Set X (Rows) to row.
	x_col = row;//Set software marker for Up to Down.
	y_pos = col;//Set software marker for Left to Right.
}

//Clear Screen. 0 is White, 1 is black
void cls(unsigned char white_){
	unsigned char row_no = 0;
	unsigned char col_no = 0;
	unsigned char csel = 1;

	 for(csel = 1;csel < 3;csel++){
		 write_lcd(64,csel);//Set Y (columns) to 0.
		 write_lcd(184,csel);//Set X (Rows) to 0.
		 write_lcd(192,csel);//Set display to top of screen.

		 for(row_no = 0;row_no < 8;row_no++){
			 for(col_no = 0;col_no < 64;col_no++){
				 write_lcd((row_no + 184),csel);
				 if(white_)
					 write_lcd(0,(csel + 4));
				 else
					 write_lcd(255,(csel + 4));
			 }
		  }
		write_lcd(64,csel);//Set Y (columns) to 0.
		write_lcd(184,csel);//Set X (Rows) to 0.
		write_lcd(192,csel);//Set display to top of screen.

	 }
	 x_col = 0;//set row to zero.
   }

//Print character strings.
void LCD_string(char *string,unsigned char invert_c)
{
	while (*string) {
		if (y_pos > 125){LCD_char(10,night);}
		LCD_char(*string++,invert_c);
	}
}

//Print Individual Character.
void LCD_char(unsigned char letter, unsigned char invert_c){
	unsigned int start_char;
	unsigned int count_char;
	if (letter == 13){
		y_pos = 0;
		write_lcd(64,1);
		write_lcd(64,2);}//Carriage Return. Reset Y to 0.
	else {
		if (letter == 10)//Line Feed. Bump Row, Reset if past bottom. Reset Y to 0.
			{x_col++;
			if (x_col > 7){
				x_col = 0;
			}
				write_lcd(184 + x_col,1);//Set X Row to top (left side).
				write_lcd(184 + x_col,2);//Set X Row to top (right side).
				y_pos = 0;//Reset Y to 0.
		}
		else
			{
				start_char = (letter - 32) * 5;
				for (count_char = start_char; count_char < (start_char + 5);count_char++){
					if(y_pos < 64){
						if(invert_c) write_lcd(font[count_char],5);//Write on left side of screen.
						else write_lcd(~(font[count_char]),5);//Write on left side of screen.
					}
					else {
						if(invert_c) write_lcd(font[count_char],6);//Write on right side of screen.
						else write_lcd(~(font[count_char]),6);//Write on right side of screen.
					}
					y_pos++;
				}
				if(y_pos < 64){
					if(invert_c) write_lcd(0,5);//one black space.
					else write_lcd(255,5);//one clear space.
				}
				else{
					if(invert_c) write_lcd(0,6);//one black space.
					else write_lcd(255,6);//one clear space.
				}
				y_pos++;
			}
	}
}

//Print Individual LARGE Character (X4).
void Big_char(unsigned char letter,unsigned char invert_c){
	unsigned int start_char;
	unsigned int count_char;
	unsigned char next_row;//drop down a row every 20 pixels.

	start_char = (letter - 48) * 80 + 480;//Big text starts 480 bytes into the array.
	next_row = 0;
		for (count_char = start_char; count_char < (start_char + 80);count_char++){
			if(next_row > 19){ //if we have printed a complete line
				next_row = 0;
				set_position(y_pos - 20,x_col + 1);//drop down a line and return to left starting position.
			}
			next_row++;
			if(y_pos < 64){
				if(invert_c) write_lcd(font[count_char],5);//Write on left side of screen.
				else write_lcd(~(font[count_char]),5);//Write on left side of screen.
			}
			else{
				if(invert_c) write_lcd(font[count_char],6);//Write on right side of screen.
				else write_lcd(~(font[count_char]),6);//Write on right side of screen.
			}
			y_pos++;
		}
}

//Simple routine to send character to SPI buffer.
void xmitt(unsigned char x_byte, unsigned char low_byte){
	 P2IE &= ~BIT3; // Kil P2.3 interupt.
	if(low_byte) {P2OUT &= ~BIT0;}//P2.0 is our latch pin. Set Low
		IFG2 &= ~UCB0RXIFG;                     // Clear flag
	    UCB0TXBUF = x_byte;                       // Send address
	    while (!(IFG2&UCB0RXIFG));              // Wait for TX to finish
	    IFG2 &= ~UCB0RXIFG;                     // Clear flag
   	if(!(low_byte)){P2OUT |=BIT0;}//Set P2.0 High
    P2IE |= BIT3; // Start P2.3 interupt.
}

//Time delay routine
void delay_c(unsigned int count){
	volatile unsigned int delay_t;
	unsigned int loop_c;
	delay_t = 10 * count;
	for(loop_c = 0;loop_c < delay_t;loop_c++){
		delay_t++;
		delay_t--;
		}
}


//Add leading zero if needed. Returns value in Global two_dig array.
 void lead_zero(unsigned int inVal)
 {
  unsigned int workval = inVal;//Declared internally.
  unsigned int gvar = 0;//General purpose variable.

  if(workval >= 10){
  	gvar = workval / 10;
  	two_dig[0] = gvar + '0';
  	workval = workval - (gvar * 10);
  }
  else{
  	two_dig[0] = '0';
  }
  two_dig[1] = workval + '0';
 }

 //IR functions
 // Port2 Interrupt Handler
 void Port2ISRHandler(){
 		// Rising edge captured on P2.3 input pin
        P2IFG &= ~BIT3; // Clear P2.3 IFG
        if (A3_counter > 1000) uindex = 0;
        if((A3_counter < 40) && (A3_counter > 10)){
     	   if (A3_counter <25) utime[uindex] = 0;
     	   else utime[uindex] = 1;
     	   uindex++;
     	   if(uindex > 11){
     		   dump_no();
     	   }
     	  }
        A3_counter = 0; //clear counter.
        CCTL0 = CCIE;//turn on timer.

  }

//20 Khz counter for IR timing.
 void TimerA3_50us(){
 	A3_counter++;
 }

 void IR_set_time (void){//Take IR inputs up, left, enter, right, and down to manipulate menu.
	   if ((alarm_pend&BIT0) && (rmode != 3)){//If alarm is set to go off, shut off pending alarm
		   alarm_pend &= ~BIT0;
		   alarm_pend |= BIT1;//Turn on alarm reset flag.
		   set_position(84,1);
		   LCD_string("       ",night);
	   }
	   else {//go through normal settings menu. Allow alarm to be turned back on afterword.
		   switch (rmode){
		   case 1://we are transitioning out of clock mode to settings mode.
			   	   men_set[0] = ts.tm_hour;       // Hour
			   	   men_set[1] = ts.tm_min  ;      // Minute
			   	   men_set[3] = ts.tm_mon + 1;    // Month (0 based!)
			   	   men_set[5] = ts.tm_mday;       // Day of Month
			   	   men_set[4] = ts.tm_year - 100; // Year
			   	   rmode = 0;//clock is now in settings mode.
		   case 0: //we are in settings mode. Fall through from above statement is intentional.
			   	   cls(0);
			   	   if (button == '<' && men_col !=0) men_col-- ;//LEFT
			   	   if (button == '^') men_row--;//UP
			   	   if (button == '>') men_col++;//RIGHT
			   	   if (button == 'v') men_row++;//DOWN
			   	   if(f_menu==7)first_menu();//Top Level Menu choices.
			   	   else second_menu(f_menu);//used for alphanumeric text entry.
			   	   alarm_pend &= ~BIT1; //Clear alarm reset so alarm can sound next day.
			   	   break;
		   case 3://The alarm is sounding.
			   	   rmode = 1;//Turn clock mode back on.
			   	   aux_out &= ~BIT3;//set alarm output low
			   	   misc2=17;//set countdown timer for silencing sequence
			   	   set_position(84,1);
			   	   LCD_string("       ",night);
			   	   break;
		   default:
			   	   break;
		   }
	   }
 }

 void dump_no(void){
 	//char str[15]; debugging purposes.
 	unsigned int dump_var;
 	unsigned int dump_code; dump_code = 0;
 	P2IE &= ~BIT3;//Kill interupt for IR input
 	CCTL0 |= CCIE; //shut off timer interupt.
 	dump_var = 0x800;
 	dump_code = 0;

 	for(uindex = 0;uindex < 12;uindex++){
 		if(utime[uindex] == 1) dump_code = dump_code + dump_var;
 		dump_var = dump_var / 2;
 	}
 	for(uindex = 0;uindex < 12;uindex++){
 		utime[uindex] = 0;//Zero out array.
 	}

 	/*Keep for debugging purposes. Gives us the actual code from the remote.
 		sprintf(str, "%x", dump_code);
 		IR_set_time(str);
 		IR_set_time(" ");
 		IR_set_time("\n");*/



 		switch (dump_code)
 		{

 		case 0x81a:
 		//	IR_set_time("2");
 			button='^';
 			IR_set_time();//Remote 2 rerouted as up
 			break;
  		case 0xc1a:
 //			IR_set_time("4");
 			button='<';
 			IR_set_time();//Remote 4 rerouted as left
 			break;
 		case 0x21a:
//			IR_set_time("5");
 			button='.';
 			IR_set_time();//Remote 5 rerouted as enter
 			break;
 		case 0xa1a:
 //			IR_set_time("6");
 			button='>';
 			IR_set_time();//Remote 6 rerouted as right
 			break;
 		case 0xe1a:
 //			IR_set_time("8");
 			button='v';
 			IR_set_time();//Remote 8 rerouted as down
 			break;
  		default :
 			//IR_set_time("error");
 			break;
 		}


 }
/*
 * Time and Calendar functions.
 */

//Interupt is called exactly 250ms.
void WDTISRHandler(){
	WD_ticks++;
	switch(WD_ticks){
	case(2):
			update_LCD();// Update Screen every half second.
			break;
	case(4):
			rtc_tick(&ts);// Update time counter every second.
			update_LCD();// Update Screen every half second.
			WD_ticks = 0;//Zero counter.
	}

}

 void show_time(const struct tm *t)  // Show time on LCD
 {
     static char *dow[7] = {
         "Sunday",
         "Monday",
         "Tuesday",
         "Wednesday",
         "Thursday",
         "Friday",
         "Saturday"
     };

     static char *moy[12] = {
             "January",
             "February",
             "March",
             "April",
             "May",
             "June",
             "July",
             "August",
             "September",
             "October",
             "November",
             "December"
         };

     if (store_hour != t->tm_hour){//only do major updates on the hour.
    	 	 store_hour = t->tm_hour;//Reset test.
    	 	 if(store_hour == 12) ts.tm_sec++;//Add 1 leap second per day, at noon, to make up for variance in this clock.
    	 	 if((store_hour > 5) && (store_hour < 20)) night = 0;//Show daytime illumination between 6 AM and 8 PM.
    	 	 else night = 1;
    	 	 cls(night);
         	 set_position(10,2);//Print hour 1st digit
         	 lead_zero(t->tm_hour);
         	 if(men_set[2]!=2){ //If we are not in military time.
         		 if(t->tm_hour > 12){ //Past noon.
         			 lead_zero(t->tm_hour - 12);
         			 Big_char(two_dig[0],night);
         		 }
         		 else Big_char(two_dig[0],night);
         		 set_position(114,4);
         		 if(t->tm_hour > 11) LCD_char('P',night);//PM Hours//After noon, before midnight.
         		 else LCD_char('A',night);//After midnight, before noon.
         	 	 LCD_char('M',night);
         	 }
         	 else Big_char(two_dig[0],night);
          	 set_position(30,2);//Print hour 2nd digit
         	 Big_char(two_dig[1],night);
         	  //Update rest of screen.
         	 set_position(0,6);
         	 LCD_string(moy[t->tm_mon],night);
         	 LCD_string(" ",night);
         	 lead_zero(t->tm_mday);
         	 LCD_string(two_dig,night);
         	 LCD_string(",",night);
         	 LCD_string(" ",night);
         	 LCD_string("20",night);
         	 lead_zero(t->tm_year - 100);
         	 LCD_string(two_dig,night);
         	 set_position(0,7);
         	 LCD_string(dow[t->tm_wday],night);
         	 set_position(60,7);//Put cursor at bottom of screen.
         	 for(misc1 = t->tm_wday * 11; misc1 < (t->tm_wday * 11)+ 11;misc1++){//Print out message for day.
         		LCD_char(Message[misc1],night);
         		}
          }

     if (store_min != t->tm_min){//only write minutes when there is a change.
    	 set_position(70,2);//Print minute 1st digit
    	 lead_zero(t->tm_min);
    	 Big_char(two_dig[0],night);
    	 set_position(90,2);//Print minute 2nd digit
    	 Big_char(two_dig[1],night);
    	 store_min = t->tm_min;
    	 set_position(84,0);
    	 if(men_set[6] < 24){//if alarm is turned on
       		 LCD_string("ALARM",night);
    		 if(!men_set[8] || ((t->tm_wday >0) && (t->tm_wday < 6))){//If alarm is not set to repeat on weekdays or it is a weekday
    				if((men_set[6] == t->tm_hour) && (men_set[7] == t->tm_min)){//if it is time for the alarm to go off.
    					if(alarm_pend&BIT0){//if alarm is pending
    						rmode = 3;//set to Alarm mode for cancellation.
    						aux_out |= BIT3;//turn alarm on electrically.
    					}
    					alarm_pend &= ~BIT1; //Clear alarm reset so alarm can sound next day.
    				 }
    				 	if(!(alarm_pend&BIT1)){ //Has alarm been reset?
    				 		alarm_pend |= BIT0;//Set alarm pending if alarm has not been reset.
    				 		set_position(84,1);
    				 		if(men_set[2]!=2){ //If we are not in military time.
    				 		    if(men_set[6] > 12) lead_zero(men_set[6] - 12); //Past noon. Subtract 12 from military time..
    				 		    else lead_zero(men_set[6]); // ... or not.
    				 		    LCD_string(two_dig,night);
    				 		    LCD_string(":",night);
    				 		    lead_zero(men_set[7]);
    				 		    LCD_string(two_dig,night);
    				 		    if(men_set[6] > 11) LCD_char('P',night);//PM Hours//After noon, before midnight.
    				 		    else LCD_char('A',night);//After midnight, before noon.
    				 		    LCD_char('M',night);
    				 		}
    				 	    else {
    				 	    	lead_zero(men_set[6]);
    				 	    	LCD_string(two_dig,night);
    				 	    	LCD_string(":",night);
    				 	    	lead_zero(men_set[7]);
    				 	    	LCD_string(two_dig,night);
    				 	    }
    				   }
    		 }
    		 else {//blank out area.
    			 set_position(84,1);
    			 LCD_string("       ",night);
    		 }
    	 }
    	 else LCD_string("       ",night);
     }
     lead_zero(t->tm_sec);//Print seconds
     set_position(114,3);
     LCD_string(two_dig,night);
       //silence alarm if it is going off.
     if (misc2 != 0){
    	 if(misc2 == 13) aux_out |= BIT3;//turn alarm on electrically.
    	 if(misc2 == 1) aux_out &= ~BIT3;//turn alarm off electrically.
    	 misc2--;
     }

     if(colon_on){//blink colon every half second.
    	 set_position(50,2);
    	 Big_char(58,night);
    	 colon_on = 0;//set to false
     }
     else{
    	 set_position(52,2);
    	 LCD_string("   ",night);
    	 set_position(52,3);
    	 LCD_string("   ",night);
    	 set_position(52,4);
    	 LCD_string("   ",night);
    	 set_position(52,5);
    	  LCD_string("   ",night);
    	 colon_on = 1;//set to true
    }

     /*
     LCD_string(" ");
     lead_zero(t->tm_hour);
     LCD_string(two_dig);
     LCD_string(":");
     lead_zero(t->tm_min);
     LCD_string(two_dig);
     LCD_string(":");
     lead_zero(t->tm_sec);
     LCD_string(two_dig);
     LCD_string(" ");
     LCD_string(dow[t->tm_wday]);
     LCD_string("\r");
   //End Greg Code.
     if(t->tm_hour < 10) {
         x = -1;
         lcd_fill(0, 1, 10, 2, 0);
     } else {
         x = 4;
         lcd_fill(0, 1, 4, 2, 0);
         lcd_pd12(t->tm_hour / 10, x, 1);
     }
     lcd_pd12(t->tm_hour % 10, x + 11, 1);
     lcd_pd12(11, x + 22, 1);
     lcd_pd12(t->tm_min / 10, x + 27, 1);
     lcd_pd12(t->tm_min % 10, x + 38, 1);
     lcd_pd12(11, x + 49, 1);
     lcd_pd12(t->tm_sec / 10, x + 54, 1);
     lcd_pd12(t->tm_sec % 10, x + 65, 1);
     lcd_fill(x + 76, 1, 8 - x, 2, 0);

     if(t->tm_mon < 9) {
         x = -4;
         lcd_fill(0, 3, 7, 2, 0);
     } else {
         x = 1;
         lcd_fill(0, 3, 1, 2, 0);
         lcd_pd12((t->tm_mon + 1) / 10, x, 3);
     }
     lcd_pd12((t->tm_mon + 1) % 10, x + 11, 3);
     lcd_pd12(13, x + 22, 3);
     lcd_pd12(t->tm_mday / 10, x + 30, 3);
     lcd_pd12(t->tm_mday % 10, x + 41, 3);
     lcd_pd12(13, x + 52, 3);
     lcd_pd12(t->tm_year %100 / 10, x + 60, 3);
     lcd_pd12(t->tm_year % 10, x + 71, 3);
     lcd_fill(x + 82, 3, 2 - x, 2, 0);

     d = dow[t->tm_wday];
     w = strlen(d) * 6;
     x = (84 - w) >> 1;
     lcd_fill(0, 5, x, 1, 0);
     lcd_print(d, x, 5);
     x += w;
     lcd_fill(x, 5, 84 - x, 1, 0);
     */
 }

//Convert date to day of week.
 int _dow(int y, int m, int d)
   {
       static const unsigned char t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4};
       y -= m < 3;
       return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
   }

 // Update Screen every half second.
void update_LCD(){
	 P2IE |= BIT3;//Set interupt for IR input
	 if(rmode)//if we are in clock mode (1) and not settings.
	 {
		show_time(&ts);
	 }
 }


 /*
  * Menu functions.
  */

 //Return value within bounds for adjusting numbers.
 void set_digit(unsigned char index, unsigned char bound){
 	if(men_row > old_row){//we are counting down
 		if (bound > 9){//Decrementing 10's digit.
 			if (men_set[index] > 9) men_set[index] = men_set[index] - 10;
 			}
 		else{//Decrementing 1's digit
 			if ((men_set[index]%10) > 0) men_set[index] = men_set[index] - 1;
 			}
 		}
 	if(men_row < old_row){//we are counting up
 		if (bound > 9){//Incrementing 10's digit.
 			if (men_set[index] <= bound) men_set[index] = men_set[index] + 10;
 			}
 		else{//Incrementing 1's digit
 			if ((men_set[index]%10) < bound) men_set[index] = men_set[index] + 1;
 			}
 		}
 	old_row = men_row;
 }

//Set time.
 void set_time(void) {//Transfer initial and changed settings to rtc.c
	 ts.tm_hour = men_set[0];                                     // Hour
	 ts.tm_min = men_set[1];                                      // Minute
	 ts.tm_sec = 0;  												//Second
	 ts.tm_mon =  men_set[3] - 1;                                // Month (0 based!)
	 ts.tm_mday =  men_set[5];                                    // Day of Month
	 ts.tm_year = men_set[4] + 100;                           // Year
	 ts.tm_wday = _dow((2000 + men_set[4]),ts.tm_mon + 1,ts.tm_mday);
	 ts.tm_yday = 0;                                     // Not used by mktime()
	 ts.tm_isdst = 0;
 }
//Top Level menu
 void first_menu(void){
	char *c_apmt[3]={"AM","PM","MT"};
	if (men_col==0) {//If we are in main menu
		if(men_row < 0){//Roll over counting down
			men_row = 4;
			}
		if(men_row > 4){//Roll over counting up
			men_row = 0;
			}
		men_choice = men_row;
	}
	set_position(0,0);//Place cursor in upper left.
	//Print Top Menu Choices with stored information.
	LCD_string(" Set Time:",0);
	lead_zero(men_set[0]);
	LCD_string(two_dig,0);
	LCD_string(":",0);
	lead_zero(men_set[1]);
	LCD_string(two_dig,0);
	LCD_string(":",0);
	LCD_string(c_apmt[men_set[2]],0);
	LCD_string("\n\r",0);
	LCD_string(" Set Date:20",0);
	lead_zero(men_set[4]);
	LCD_string(two_dig,0);
	LCD_string(":",0);
	lead_zero(men_set[3]);
	LCD_string(two_dig,0);
	LCD_string(":",0);
	lead_zero(men_set[5]);
	LCD_string(two_dig,0);
	LCD_string("\n\r",0);
	LCD_string(" Set Alarm:",0);
	lead_zero(men_set[6]);
	LCD_string(two_dig,0);
	LCD_string(":",0);
	lead_zero(men_set[7]);
	LCD_string(two_dig,0);
	LCD_string(" WD:",0);
	if(men_set[8]) LCD_string("Y",0);//Is the alarm to go off every weekday?
	else LCD_string("N",0);
	LCD_string(" Set Message\n\r",0);
	LCD_string(" Mo Tu We Th Fr Sa Su",0);
	LCD_string(" End\n\r",0);

	switch (men_choice){
		case 0://Set Time
			set_position(0,0);
			LCD_string("X",1);//Put "X" by Set Time.
			if (men_col==0){//No selection
				old_row=men_row;//keeps value from getting crazy
			}
			if (men_col==1){//Hour 1st digit
				set_digit(0,20);//Hour,20 as bound
				lead_zero(men_set[0]);
				set_position(60,0);
				LCD_char(two_dig[0],1);
			}
			if (men_col==2){//Hour 2nd digit
				set_digit(0,9);//Hour,9 as bound
				lead_zero(men_set[0]);
				set_position(66,0);
				LCD_char(two_dig[1],1);
			}
			if (men_col==3){//Minute 1st digit
				set_digit(1,50);//Minute,50 as bound
				lead_zero(men_set[1]);
				set_position(78,0);
				LCD_char(two_dig[0],1);
			}
			if (men_col==4){//Minute 2nd digit
				set_digit(1,9);//Minute,9 as bound
				lead_zero(men_set[1]);
				set_position(84,0);
				LCD_char(two_dig[1],1);
			}
			if (men_col==5){//AM PM Military Time
				set_digit(2,2);//apmt,2 as bound
				set_position(96,0);
				if((men_set[2] == 1) && (men_set[0] < 12)) men_set[0] = men_set[0] + 12;//Adjust time to PM
				if((men_set[2] == 0) && (men_set[0] > 12)) men_set[0] = men_set[0] - 12;//Adjust time to AM
				LCD_string(c_apmt[men_set[2]],1);
			}
			if (men_col==6){//Loop past the end
				men_col = 0;
				men_row = 1;
				old_row=men_row;//keeps value from getting crazy
				first_menu();
				break;
			}
		break;
		case 1://Set date
			set_position(0,1);
			LCD_string("X",1);//Put "X" by Set Date.
			if (men_col==0){//No selection
				old_row=men_row;//keeps value from getting crazy
			}
			if (men_col==1){//Year 3rd digit
				set_digit(4,90);//Year 1st digit,90 as bound
				lead_zero(men_set[4]);
				set_position(72,1);
				LCD_char(two_dig[0],1);
			}
			if (men_col==2){//Year 4th digit
				set_digit(4,9);//Year 2nd digit,9 as bound
				lead_zero(men_set[4]);
				set_position(78,1);
				LCD_char(two_dig[1],1);
			}
			if (men_col==3){//Month 1st digit
				set_digit(3,10);//Month 1st digit,10 as bound
				lead_zero(men_set[3]);
				set_position(90,1);
				LCD_char(two_dig[0],1);
			}
			if (men_col==4){//Month 2nd digit
				set_digit(3,9);//Month 2nd digit,9 as bound
				lead_zero(men_set[3]);
				set_position(96,1);
				LCD_char(two_dig[1],1);
			}
			if (men_col==5){//Day 1st digit
				set_digit(5,30);//Day of Month 1st digit,30 as bound
				lead_zero(men_set[5]);
				set_position(108,1);
				LCD_char(two_dig[0],1);
			}
			if (men_col==6){//Day 2nd digit
				set_digit(5,9);//Day of Month 2nd digit,9 as bound
				lead_zero(men_set[5]);
				set_position(114,1);
				LCD_char(two_dig[1],1);
			}
			if (men_col==7){//Loop past the end
				men_col = 0;
				men_row = 2;
				old_row=men_row;//keeps value from getting crazy
				first_menu();
				break;
			}
		break;
		case 2://Set Alarm
			set_position(0,2);
			LCD_string("X",1);//Put "X" by Set Alarm.
			if (men_col==0){//No selection
				old_row=men_row;//keeps value from getting crazy
			}
			if (men_col==1){//Hour 1st digit
			set_digit(6,20);//Alarm Hour 1st digit bound of 20
			lead_zero(men_set[6]);
			set_position(66,2);
			LCD_char(two_dig[0],1);
			}
			if (men_col==2){//Hour 2nd digit
			set_digit(6,9);//Alarm Hour 2nd digit,9 as bound
			lead_zero(men_set[6]);
			set_position(72,2);
			LCD_char(two_dig[1],1);
			}
			if (men_col==3){//Minute 1st digit
			set_digit(7,50);//Alarm minute 1st digit 50 as bound
			lead_zero(men_set[7]);
			set_position(84,2);
			LCD_char(two_dig[0],1);
			}
			if (men_col==4){//Minute 2nd digit
			set_digit(7,9);//Alarm minute 2nd digit 9 as bound
			lead_zero(men_set[7]);
			set_position(90,2);
			LCD_char(two_dig[1],1);
			}
			if (men_col==5){//Repeat alarm each weekday
			set_digit(8,1);//1 as bound
			set_position(120,2);
			if(men_set[8]) LCD_string("Y",1);//Is the alarm to go off every weekday?
			else LCD_string("N",1);
			}
			if (men_col==6){//Loop past the end
				men_col = 0;
				men_row = 3;
				old_row=men_row;//keeps value from getting crazy
				first_menu();
				break;
			}
		break;
		case 3://Set Message
			set_position(0,3);
			LCD_string("X",1);//Put "X" by Set Message.
			if (men_col==0){//No selection made
				old_row=men_row;//keeps value from getting crazy
				old_col=men_col;
			}
			if (men_col==1){//Monday
				set_position(6,4);
				LCD_string("Mo",1);
				if(old_row != men_row) second_menu(1);//Go into text mode
			}
			if (men_col==2){//Tuesday
				set_position(24,4);
				LCD_string("Tu",1);
				if(old_row != men_row) second_menu(2);//Go into text mode
			}
			if (men_col==3){//Wednesday
				set_position(42,4);
				LCD_string("We",1);
				if(old_row != men_row) second_menu(3);//Go into text mode
			}
			if (men_col==4){//Thursday
				set_position(60,4);
				LCD_string("Th",1);
				if(old_row != men_row) second_menu(4);//Go into text mode
			}
			if (men_col==5){//Friday
				set_position(78,4);
				LCD_string("Fr",1);
				if(old_row != men_row) second_menu(5);//Go into text mode
			}
			if (men_col==6){//Saturday
				set_position(96,4);
				LCD_string("Sa",1);
				if(old_row != men_row) second_menu(6);//Go into text mode
			}
			if (men_col==7){//Sunday
				set_position(114,4);
				LCD_string("Su",1);
				if(old_row != men_row) second_menu(0);//Go into text mode
			}
			if (men_col==8){//Loop past the end
				men_col = 0;
				men_row = 4;
				old_row=men_row;//keeps value from getting crazy
				first_menu();
				break;
			}
		break;
		case 4://End Menu
			set_position(0,5);//Skips below days of week.
			LCD_string("X",1);//Put "X" by End.
			if (men_col==1){//Exit from Menus.
				rmode=1;//set back in clock mode
				store_hour++;//force clock refresh
				store_min++;
				cls(night);//clear screen
				men_row=0;//zero IR position.
				men_col=0;
				old_col=0;
				old_row=0;
				set_time();
				update_LCD();
			}
		break;
		default:
		break;
	}
}
 //Second level menu function.
 void second_menu(unsigned char dawe){
		unsigned char start;
		unsigned char end;
		unsigned char nl = 0;//new line
		unsigned char f_loop;//used for loops.

		f_menu=dawe;//set to stay in day of week.

		cls(0);//clear the screen.
		set_position(0,0);
		if(men_col > old_col){//move highlight right
			misc1++;
			if(misc1 > 90){
				 misc1 = 0;//loop back to beginning.
				 old_row=4;men_row=4;
				 old_col=1;men_col=1;
			}
		}
		if((men_col < old_col) && (misc1 > 0))misc1--;//move highlight left
		if((men_row < old_row) && (misc1 >12)) misc1 = misc1 - 13;//jumpt one row up
		if(men_row > old_row){//jump one row down
			misc1 = misc1 + 13;
			if(misc1 > 90){
				 misc1 = misc1 - 90;//loop back to beginning.
				 old_row=4;men_row=4;
				 old_col=1;men_col=1;
			}
		}
		for(f_loop = 32;f_loop < 123;f_loop++){
			if((f_loop - 32) == misc1){//Highlight character selected
				LCD_char(f_loop,1);
			}
			else LCD_char(f_loop,0);//or not.
			nl++;
			if(nl > 12){
				nl = 0;
				LCD_string("\n\r",0);
			}

		}
		start = dawe * 11;//using a single dim array.
		end = start + 11;
		if(button == '.'){//has "enter" been pushed?
			Message[start + misc2] = misc1 + 32;//store chosen text character in message array.
			misc2++;
			if (misc2 > 10){//have all the characters been entered?
			men_col = 1;//Put row and column counters where they were.
			men_row = 4;
			old_col = 1;
			old_row = 4;
			misc1 = 0;
			misc2 = 0;
			f_menu = 7;//Reset to first level menu.
			}
		}
		set_position(0,7);//Put cursor at bottom of screen.
		for(f_loop = start;f_loop < end;f_loop++){//Print out message for day.
			if(Message[f_loop] == 32)LCD_char('|',0);
			else LCD_char(Message[f_loop],0);
		}
		old_col = men_col;//reset registers for next compare.
		old_row = men_row;

 }

 //intialize all vectors
#pragma vector=PORT1_VECTOR,TIMER0_A1_VECTOR,TIMER1_A0_VECTOR,TIMER1_A1_VECTOR,ADC10_VECTOR,USCIAB0RX_VECTOR,USCIAB0TX_VECTOR,COMPARATORA_VECTOR,NMI_VECTOR
__interrupt void ISR_trap(void)
{
 // the following will cause an access violation which results in a PUC reset
 WDTCTL = 0;
}
