/*
	SC15KEY.C

	CM71xx/Z1 and CM72xx/Z2

	Demonstrates the use of the 5key library and the real time kernel for the
	SmartCore Evaluation Board. Key scan and beeper service are called
	periodically by TASK0 (every 25ms).
*/
 
// The LCD/keypad module for the SmartCore Evaluation Board is needed to
// run this sample program.

#use 5key.lib
#use rtk.lib
#use lcd2l.lib
#use vdriver.lib
#define DebounceCount 20	// Debounce key every 20x25ms = 0.50 sec
#define BeepScale 0.04		// BeepScale*millisecond is the actual ON time
									// when up_beep(ms) is called. This number has to
									// match the periodicity of lc_beepscan(); 
// globals for real_time_kernel
int 					task0(),task1(),task2(),task3(),task4(),task5(),backgnd();
int (*Ftask[])() = {
	 					task0,  task1,  task2,  task3,  task4,  task5,  backgnd
};
#define NTASKS 7
#define TASK0 0
#define TASK1 1
#define TASK2 2
#define TASK3 3
#define TASK4 4
#define TASK5 5

#define MODIFY     1
#define NOT_MODIFY 0
#define USERTCLK   0x10
#define NORTCLK    0x00

#define RUNKERNEL 1          // use the real time kernel

char time[15];	char *t_help[] = 		{	"Set system time,",
													"Use FIELD, UP & DOWN",
													"keys to change."};
char date[15];	char *d_help[] = 		{	"Set system date,",
													"Use FIELD, UP & DOWN",
													"keys to change."};
int  count1;	char *c1_help[] = 	{	"Counter 1 help.",
													"Use FIELD, UP & DOWN",
													"keys to change."};
int  count2;	char *c2_help[] =		{	"Counter 2 help",
													"Use FIELD, UP & DOWN",
													"keys to change."};
float temp0;	char *t0_help[] =		{	"Temp0 is parameter 0",
													"Use FIELD, UP & DOWN",
													"keys to change."};
float temp1;	char *t1_help[] =		{	"Temp1 is parameter 1",
													"Use FIELD, UP & DOWN",
													"keys to change."};
char control;	char *c_help[] =		{	"on/off control for",
													"something."};
void f1key(), f2key(), f3key(), f4key();
void alarm1(), alarm2(), alarm3(), alarm4();
void time_date_menu();
void mix_var_menu();

main(){
	struct tm dtime;
	 
	VdInit();			// initialize the virtual driver
	lc_kxinit();		// initialize the keypad variables
	lc_init();	// initialize the lcd
		  
// initialize the real time clock if not already running
	tm_rd( &dtime );
	if( (dtime.tm_year < 95) || (dtime.tm_year > 99)){
		dtime.tm_year = 95;
		dtime.tm_mon  =  6;
		dtime.tm_mday =  1;
		dtime.tm_wday =  4;
		dtime.tm_hour =  8;
		dtime.tm_min  =  0;
		dtime.tm_sec  =  0;
		tm_wr( &dtime );
	 }
	 control = 0;
	 count1 = 5;	temp0 = 45.0;
	 count2 = 6;	temp1 = 35.23;

	 _5key_setmsg(0, "Demo 5key System");     	// set message 0
	 _5key_setmsg(1, "Message Bulletin");     	// set message 1
	 _5key_setfunc( f1key,f2key,f3key,f4key );	// set the function keys
	 _5key_setalarm( alarm1,NO_FUNCTION,NO_FUNCTION,NO_FUNCTION );
																// set the alarm functions
	 backgnd();												// background for the RTK
}

indirect task0(){							// keyscan and beeper service every 25ms
	lc_beepscan();
	lc_keyscan();
}
indirect task1(){
	_ALARM1 = 1;							// demo usage of alarm functions  
}
indirect task2(){
	count1++;								// increment demo variable for monitoring
	if(count1 > 999) count1 = 100;
	temp1++;									// increment demo variable for monitoring
	if(temp1 > 999.99) temp1 = 100.00;
}
indirect task3(){}			// task not used
indirect task5(){}			// task not used

// task server for 5key system menu
indirect task4(){
	for(;;){
		time_date_menu();		// time date menu
		mix_var_menu();      // mix variables menu
	}
}

indirect backgnd(){
	run_every( TASK0,    1);	// key scan and beeper service every 25ms
	run_every( TASK1, 4000);	// _ALARM1 every 100 sec
	run_every( TASK2,   40);	// increment demo variables every 1 sec.
	request  ( TASK4      );	// request the 5key task
	for(;;) runwatch();			// monitor with the watch window
}

// 5key system time date menu
void time_date_menu(){
	int key;
	lcd_server(3,0L,"Time Date Set");
	for(;;){
		key = _5key_date("date   ",date,d_help,sizeof(d_help),USERTCLK,MODIFY,10);
		if( key == MENU )	return;
		
		key = _5key_time("time   ",time,t_help,sizeof(t_help),USERTCLK,MODIFY,10);
		if( key == MENU ) return;
	}
}

// 5key system mixed variables menu
void mix_var_menu(){
	int key;
	lcd_server(3,0L,"Mixed Variables");
	for(;;){
		key = _5key_boolean("ON/OFF ",&control,NO_HELP,0,MODIFY,10); 
		if( key == MENU ) return;
		
		key = _5key_integer("Count1",&count1,200,1,c1_help,sizeof(c1_help),
				NOT_MODIFY, 10); 
		if( key == MENU ) return;
		
		key = _5key_integer("Count2",&count2,50,10,c2_help,sizeof(c2_help),
		      MODIFY, 10); 
		if( key == MENU ) return;
		
		key = _5key_float("Temp0",&temp0,200.0,0.02,t0_help,sizeof(t0_help),
				MODIFY, 10); 
		if( key == MENU ) return;
		
		key = _5key_float("Temp1",&temp1,200.0,0.02,t1_help,sizeof(t1_help),
				NOT_MODIFY, 10); 
		if( key == MENU ) return;
	 }
}
// exercise function keys
indirect void f1key(){
	lcd_server( 3, 0x00000000L, "hello function key 1" );
	suspend(30);
	lcd_server( 0, 0x01000000L, "bye function key 1  " );
	suspend(30);
}
indirect void f2key(){
	lcd_server( 3, 0x00000000L, "hello function key 2" );
	suspend(30);
	lcd_server( 0, 0x01000000L, "bye function key 2  " );
	suspend(30);
}
indirect void f3key(){
	lcd_server( 3, 0x00000000L, "hello function key 3" );
	suspend(30);
	lcd_server( 0, 0x01000000L, "bye function key 3  " );
	suspend(30);
}
indirect void f4key(){
	lcd_server( 3, 0x00000000L, "hello function key 4" );
	suspend(30);
	lcd_server( 0, 0x01000000L, "bye function key 4  " );
	suspend(30);
}
// exercise alarm
indirect void alarm1(){
	lcd_server( 3, 0x00000000L, "hello alarm 1       " );
	lcd_server( 0, 0x01000000L, "bye alarm 1         " );
	suspend(30);
}
/**/