#pragma num_alias_table_entries	14
#include 

IO_0 output bitshift numbits(8) clockedge(+) io_com_data;
IO_2 output bit en;
//IO_3 output frequency clock(3) io_sound;
//IO_4 input bit ir;
IO_5 input bit up;
IO_6 input bit down;
IO_7 input bit enter;
IO_8 input bit esc;

network input SNVT_switch nvi_lighting[4];
//network input SNVT_count nvi_light_sensor;
//network input SNVT_count nvi_door_contact;
//network input SNVT_count nvi_person_det;
//network input SNVT_count nvi_smoke_det;
network input SNVT_count nvi_no_lighting;
network input SNVT_count nvi_no_blind;
network input SNVT_count nvi_no_air_cond;
network input SNVT_count nvi_size;

network output SNVT_switch nvo_lighting[4];
//network output SNVT_count nvo_light_sensor;
//network output SNVT_count nvo_person_det;
//network output SNVT_count nvo_smoke_det;
network output SNVT_count nvo_no_lighting;
network output SNVT_count nvo_no_blind;
network output SNVT_count nvo_no_air_cond;
network output SNVT_count nvo_size;

SNVT_switch lighting_level[4];

int item = 1;
int part = 1;
int cur_pos = 1;
int mnu_pos = 1;
char display[20];

eeprom int no_lighting = 4;
eeprom int no_blind = 2;
eeprom int no_air_cond = 3;
eeprom int size = 20;
//eeprom int light_sensor = 0;
//eeprom int door_contactor = 0;
//eeprom int person_detector = 0;
//eeprom int smoke_detector = 0; 

void writecmd(int a)
{
	io_out(en, 1);
	io_out(io_com_data, 0b00000000UL);
	io_out(io_com_data, a);
	io_out(en, 0);
	delay(0);
}

void command(int a)
{
	io_out(en, 1);
	io_out(io_com_data, 0b00000000UL);
	switch(a)
	{
		case 0:
			io_out(io_com_data, 0b00000001UL);	//clear
			break;
		case 1:
			io_out(io_com_data, 0b00111000UL);	//datainterface
			break;
		case 20:
			io_out(io_com_data, 0b00001000UL);	//displayoff
			break;
		case 21:
			io_out(io_com_data, 0b00001100UL);	//displayon
			break;
		case 30:
			io_out(io_com_data, 0b00000100UL);	//autoforward off
			break;
		case 31:
			io_out(io_com_data, 0b00000110UL);	//autoforward on
			break;
	}
	io_out(en, 0);
	if(a == 2)
	{
		delay(63);
	}
	else
	{
		delay(0);
	}
}

void chr(char a)
{
	io_out(en, 1);
	io_out(io_com_data, 0b10000000UL);
	io_out(io_com_data, a);
	io_out(en, 0);
	delay(0);
}

void str(char a[20])
{
	int chr_num;
	for(chr_num = 0; a[chr_num] != '~'; chr_num = chr_num + 1)
	{
		chr(a[chr_num]);
	}
}

void name(int a)
{
	switch(a)
	{
		case 1:
			strcpy(display, " Lighting~");
			break;
		case 11:
			strcpy(display, " Lamp 1~");
			break;
		case 12:
			strcpy(display, " Lamp 2~");
			break;
		case 13:
			strcpy(display, " Lamp 3~");
			break;
		case 14:
			strcpy(display, " Lamp 4~");
			break;
		case 2:
			strcpy(display, " Blind~");
			break;
		case 21:
			strcpy(display, " Blind 1~");
			break;
		case 22:
			strcpy(display, " Blind 2~");
			break;
		case 23:
			strcpy(display, " Blind 3~");
			break;
		case 24:
			strcpy(display, " Blind 4~");
			break;
		case 3:
			strcpy(display, " Air Condition~");
			break;
		case 31:
			strcpy(display, " Air Cond. 1~");
			break;
		case 32:
			strcpy(display, " Air Cond. 2~");
			break;
		case 33:
			strcpy(display, " Air Cond. 3~");
			break;
		case 34:
			strcpy(display, " Air Cond. 4~");
			break;
		case 4:
			strcpy(display, " Other~");
			break;
		case 41:
			strcpy(display, " Light Sensor~");
			break;
		case 42:
			strcpy(display,	" Door Contact~");
			break;
		case 43:
			strcpy(display, " Person Detector~");
			break;
		case 44:
			strcpy(display,	" Smoke Detector~");
			break;
	}
	str(display);
}

void move(int a, int b)
{
	if(a == 1)
	{
		writecmd(127 + b);
	}
	else if(a == 2)
	{
		writecmd(128 + 63 + b);
	}
	else if(a == 3)
	{
		writecmd(128 + 19 + b);
	}
	else if(a == 4)
	{
		writecmd(128 + 83 + b);
	}
}

void dec_num(unsigned int a)
{
	unsigned int b, c, d;
	b = a / 200;
	if(b == 0)
	{
		c = a / 20;
		d = (a % 20) / 2;
	}
	else
	{
		c = 0;
		d = 0;
	}
	chr(48 + b);
	chr(48 + c);
	chr(48 + d);
	chr('%');
}

void menu(int a)
{
	int b, c;
	b = 4;
	command(0);
	if(a == 1)
	{
		for(b = 1; b <= 4; b = b + 1)
		{
			move(b, 1);
			name(b);
		}
		move(cur_pos, 1);
		chr(126);
	}
	else if(a == 11 || a == 12 || a == 13 || a == 14)
	{
		if(a == 11)
		{
			b = no_lighting;
		}
		else if(a == 12)
		{
			b = no_blind;
		}
		else if(a == 13)
		{
			b = no_air_cond;
		}
        for(c = 1; c <= b; c = c + 1)
		{
			move(c, 1);
			if(a == 11)
			{
				name(10 + c);
				if(lighting_level[c - 1].state == 1)
				{
					move(c, size - 8);
					strcpy(display, " ON~");
					str(display);
					move(c, size - 3);
					dec_num(lighting_level[c - 1].value);
				}
				else if(lighting_level[c - 1].state == 0)
				{
					move(c, size - 8);
					strcpy(display, "OFF~");
					str(display);
					move(c, size - 3);
					strcpy(display, "    ~");
					str(display);
				}
			}
			else if(a == 12)
			{
				name(20 + c);
			}
			else if(a == 13)
			{
				name(30 + c);
			}
			else if(a == 14)
			{
				name(40 + c);
//				if (c == 1)
//				{
//					 	move(c,17);
//					 	dec_num(light_sensor);
//					 	move(c,20);
//						strcpy(display,"%~");
//						str(display);
//				}		 	
//				else if (c == 2)
//				{
//						move(c,17);
//						dec_num(door_contactor);
//						move(c,20);
//						strcpy(display,"%~");
//						str(display);
//				}
			}
		}
		if(a == 11 || a == 12 || a == 13 )
		{
			move(cur_pos, 1);
			chr(126);
		}
	}
	else if(a == 21 || a == 22 || a == 23)
	{
		if(mnu_pos == 21)
		{
			move(2, 8);
			strcpy(display, "Level~");
			str(display);
			move(3, 9);
			dec_num(lighting_level[item - 1].value);
		}
		else if(mnu_pos == 22)
		{
			move(1, 8);
			strcpy(display, "Motion~");
			str(display);
			move(2, 8);
			strcpy(display, " UP~");
			str(display);
			move(3, 8);
			strcpy(display, " STOP~");
			str(display);
			move(4, 8);
			strcpy(display, " DOWN~");
			str(display);
			move(cur_pos, 8);
			chr(126);
		}
		else if(mnu_pos == 23)
		{
			move(1, 1);
			strcpy(display, " Power~");
			str(display);
			move(2, 1);
			strcpy(display, " Swing~");
			str(display);
			move(3, 1);
			strcpy(display, " Fan Speed~");
			str(display);
			move(4, 1);
			strcpy(display, " Temperture~");
			str(display);
			move(cur_pos, 1);
			chr(126);
		}
	}	
	else if(a == 33)
	{
		if(part == 1 || part == 2)
		{
			move(1, 8);
			if(part == 1)
			{
				strcpy(display, "Power~");
			}
			else if(part == 2)
			{
				strcpy(display, "Swing~");
			}
			str(display);
			move(2, 8);
			strcpy(display, " ON~");
			str(display);
			move(3, 8);
			strcpy(display, " OFF~");
			str(display);
			move(cur_pos, 8);
			chr(126);
		}
		else if(part == 3)
		{
			move(1, 6);
			strcpy(display, "Fan Speed~");
			str(display);
			move(2, 8);
			strcpy(display, " HI~");
			str(display);
			move(3, 8);
			strcpy(display, " MED~");
			str(display);
			move(4, 8);
			strcpy(display, " LO~");
			str(display);
			move(cur_pos, 8);
			chr(126);
		}
	}
}

void roll_cur(int a)
{
	int b;
	if(mnu_pos == 11)
	{
		b = no_lighting;
	}
	else if(mnu_pos == 12)
	{
		b = no_blind;
	}
	else if(mnu_pos == 13)
	{
		b = no_air_cond;
	}
	switch(a)
	{
		case 1:
			if(cur_pos > 1)
			{
				move(cur_pos, 1);
				chr(' ');
				cur_pos = cur_pos - 1;
				move(cur_pos, 1);
				chr(126);
				item = item - 1;
			}
			break;
		case 2:
			if(cur_pos < 4)
			{
				move(cur_pos, 1);
				chr(' ');
				cur_pos = cur_pos + 1;
				move(cur_pos, 1);
				chr(126);
				item = item + 1;
			}
			break;
		case 12:
			if(cur_pos < 4 && cur_pos < b)
			{
				move(cur_pos, 1);
				chr(' ');
				cur_pos = cur_pos + 1;
				move(cur_pos, 1);
				chr(126);
				item = item + 1;
			}
			break;
		case 21:
			if(mnu_pos == 21)
			{
				if(lighting_level[item - 1].value < 200)
				{
					if((lighting_level[item - 1].value % 40) == 0)
					{
						lighting_level[item - 1].value = lighting_level[item - 1].value + 40;
					}
					else
					{
						lighting_level[item - 1].value  = ((lighting_level[item - 1].value / 40) + 1) * 40;
					}
					menu(21);
				}
			}
			else if(mnu_pos == 22)
			{
				if(cur_pos > 2)
				{
					move(cur_pos, 8);
					chr(' ');
					cur_pos = cur_pos - 1;
					move(cur_pos, 8);
					chr(126);
				}
			}
			else if(mnu_pos == 23)
			{
				if(cur_pos > 1)
				{
					move(cur_pos, 1);
					chr(' ');
					cur_pos = cur_pos - 1;
					move(cur_pos, 1);
					chr(126);
					part = cur_pos;
				}
			}
			break;
		case 22:
			if(mnu_pos == 21)
			{
				if(lighting_level[item - 1].value > 0)
				{
					if((lighting_level[item - 1].value % 40) == 0)
					{
						lighting_level[item - 1].value = lighting_level[item - 1].value - 40;
					}
					else
					{
						lighting_level[item - 1].value  = (lighting_level[item - 1].value / 40) * 40;
					}
					menu(21);
				}
			}
			else if(mnu_pos == 22)
			{
				if(cur_pos < 4)
				{
					move(cur_pos, 8);
					chr(' ');
					cur_pos = cur_pos + 1;
					move(cur_pos, 8);
					chr(126);
				}
			}
			else if(mnu_pos == 23)
			{
				if(cur_pos < 4)
				{
					move(cur_pos, 1);
					chr(' ');
					cur_pos = cur_pos + 1;
					move(cur_pos, 1);
					chr(126);
					part = cur_pos;
				}
			}
			break;
		case 31:
			if(cur_pos > 2)
			{
				move(cur_pos, 8);
				chr(' ');
				cur_pos = cur_pos - 1;
				move(cur_pos, 8);
				chr(126);
			}
			break;
		case 32:
			if(part == 1 || part == 2)
			{
				if(cur_pos < 3)
				{
					move(cur_pos, 8);
					chr(' ');
					cur_pos = cur_pos + 1;
					move(cur_pos, 8);
					chr(126);
				}
			}
			else if(part == 3)
			{
				if(cur_pos < 4)
				{
					move(cur_pos, 8);
					chr(' ');
					cur_pos = cur_pos + 1;
					move(cur_pos, 8);
					chr(126);
				}
			}
			break;
	}
}

when(nv_update_occurs(nvi_size))
{
	size = (short) nvi_size;
}

when(nv_update_occurs(nvi_no_lighting))
{
	no_lighting = (short) nvi_no_lighting;
	if(mnu_pos == 11)
	{
		menu(11);
	}
}

when(nv_update_occurs(nvi_no_blind))
{
	no_blind = (short) nvi_no_blind;
	if(mnu_pos == 12)
	{
		menu(12);
	}
}

when(nv_update_occurs(nvi_no_air_cond))
{
	no_air_cond = (short) nvi_no_air_cond;
	if(mnu_pos == 13)
	{
		menu(13);
	}
}

when(nv_update_occurs(nvi_lighting))
{
	int a;
	for(a = 0; a < 4; a = a + 1)
	{
		lighting_level[a].value = nvi_lighting[a].value;
		lighting_level[a].state = nvi_lighting[a].state;
	}
	if(mnu_pos == 11)
	{
		menu(11);
	}
	else if(mnu_pos == 21)
	{
		menu(21);
	}
}

//when(nv_update_occurs(nvi_light_sensor))
//{	light_sensor = nvi_light_sensor;
//		if(mnu_pos == 14)
//		{	
//			menu(14);
//		}
//}

//when(nv_update_occurs(nvi_door_contact))
//{
//	door_contactor = nvi_door_contact;
//		if(mnu_pos == 14)
//		{	
//			menu(14);
//		}
//}

//when(nv_update_occurs(nvi_person_det))
//{
//		person_detector = nvi_person_det;
//		if(mnu_pos == 14)
//		{	
//			menu(14);
//		}
//}

//when(nv_update_occurs(nvi_smoke_det))
//{
//		smoke_detector = nvi_smoke_det;
//		if(mnu_pos == 14)
//		{	
//			menu(14);
//		}
//}

when(reset)
{
	delay(600);
	command(1);
	delay(160);
	command(1);
	delay(2);	
	command(1);
	delay(160);
	command(1);
	command(20);
	command(0);
	command(21);
	menu(1);
	nvo_size = size;
	nvo_no_lighting = no_lighting;
	nvo_no_blind = no_blind;
	nvo_no_air_cond = no_air_cond;
//	nvo_light_sensor = light_sensor;
}

when(io_changes(up)to 0)
{
	if(mnu_pos == 1 || mnu_pos == 11 || mnu_pos == 12 || mnu_pos == 13 )
	{
		roll_cur(1);
	}
	else if(mnu_pos == 21 || mnu_pos == 22 || mnu_pos == 23 )
	{
		roll_cur(21);
	}
	else if(mnu_pos == 33)
	{
		roll_cur(31);
	}
}

when(io_changes(down)to 0)
{
	if(mnu_pos == 1)
	{
		roll_cur(2);
	}
	else if(mnu_pos == 11 || mnu_pos == 12 || mnu_pos == 13)
	{
		roll_cur(12);
	}
	else if(mnu_pos == 21 || mnu_pos == 22 || mnu_pos == 23)
	{
		roll_cur(22);
	}
	else if(mnu_pos == 33)
	{
		roll_cur(32);
	}
}

when(io_changes(enter)to 0)
{
	if(mnu_pos == 1)
	{
		cur_pos = 1;
		mnu_pos = item + 10;
		menu(mnu_pos);
		item = 1;
	}
	else if(mnu_pos == 11 || mnu_pos == 12 || mnu_pos == 13)
	{
		if(mnu_pos == 12)
		{
			cur_pos  = 3;
		}
		if(mnu_pos == 13)
		{
			cur_pos = 1;
		}
		mnu_pos = mnu_pos + 10;
		menu(mnu_pos);
	}
	else if(mnu_pos == 21 || mnu_pos == 23)
	{
		if(mnu_pos == 21)
		{
			nvo_lighting[item - 1].value = lighting_level[item - 1].value;
			if(lighting_level[item - 1].value != 0)
			{
				nvo_lighting[item - 1].state = 1;
			}
			else
			{
				nvo_lighting[item - 1].state = 0;
			}
			cur_pos = item;
			mnu_pos = mnu_pos - 10;
			menu(mnu_pos);
		}
		else if(mnu_pos == 23)
		{
			if(part == 1 || part == 2 || part == 3)
			{
				cur_pos = 2;
			}
			mnu_pos = mnu_pos + 10;
			menu(mnu_pos);
		}
	}
}

when(io_changes(esc)to 0)
{
	if(mnu_pos == 11 || mnu_pos == 12 || mnu_pos == 13 || mnu_pos == 14)
	{
		cur_pos = mnu_pos - 10;
		item = cur_pos;
		mnu_pos = 1;
		menu(1);
	}
	else if(mnu_pos == 21 || mnu_pos == 22 || mnu_pos == 23 || mnu_pos == 24)
	{
		if(mnu_pos == 21)
		{
			lighting_level[item - 1].value = nvi_lighting[item - 1].value;
			lighting_level[item - 1].state = nvi_lighting[item - 1].state;
		
		}
		cur_pos = item;
		mnu_pos = mnu_pos - 10;
		menu(mnu_pos);
	}
	else if(mnu_pos == 33)
	{
		cur_pos = part;
		mnu_pos = mnu_pos - 10;
		menu(mnu_pos);
	}	
}

    Source: geocities.com/hk/cloud_fan_school/Program/LCD/20040120

               ( geocities.com/hk/cloud_fan_school/Program/LCD)                   ( geocities.com/hk/cloud_fan_school/Program)                   ( geocities.com/hk/cloud_fan_school)                   ( geocities.com/hk)