//--------------------------------------------------------------------------------------------------
//	PROGRAM : vytvorene menu pro PID regulator
//	VERSION : 1.0
//	AUTHOR  : Bc. Pazour Zbyněk
//	DATE	: 07.09.2009
//--------------------------------------------------------------------------------------------------
#include "menu.h"
#include <avr/eeprom.h>

volatile int16_t	 kalibrace1,kalibrace2;

static	 uint8_t		 pid[7];
volatile uint8_t		 teppt1[6],teppt2[6];
volatile uint8_t		 vyber_cidel=0,cidlo,zobrazeni,citac,led;
volatile uint16_t 	 Ti,Td,Dif,Kr,Tmax,por,per;


//************************************************************************************************************
///////***	DEFINICE TLACITEK	****
//************************************************************************************************************

///////////////////////Tlačítko nahoru////////////////////////////////////////////
char  up (char b,char poc)
{
	if(!(PINB&(1<<UP)))			//pokud je stisknuto
	{
	delay_ms(10);				//prodleva 10ms k ošetření zákmitů
	if(!(PINB&(1<<UP)))			//opětovná kontrola
		{
		lcd_clrscr();			//smazaní displeje
		if(b!=0)b--;			//změna směru
		else b=(poc-1);
		delay_ms(180);
		
		}		
	}
	return b;
}

///////////////////////Tlačítko dolu////////////////////////////////////////////

char down (char b,char poc)
{
	if(!(PINB&(1<<DOWN)))		//pokud je stisknuto
	{
	delay_ms(10);				//prodleva 10ms k ošetření zákmitů
		if(!(PINB&(1<<DOWN)))	//opětovná kontrola
		{
		lcd_clrscr();			//smazaní displeje		
		if(b<(poc-1))b++;		//změna směru
		else b=0;
		delay_ms(180);	
		}
	}
	return b;
}
///////////////////////Tlačítko ESC////////////////////////////////////////////
char esc(char b,char poc)
{
	if(!(PINB&(1<<ESC)))		//pokud je stisknuto
	{
	delay_ms(10);				//prodleva 10ms k ošetření zákmitů
		if(!(PINB&(1<<ESC)))	//opětovná kontrola
		{
		b=poc;
		delay_ms(180);			//Návrat v menu o úroveň výš
		lcd_clrscr();			//smazaní displeje
		}
	}
	return b;
}

///////////////////////Tlačítko MENU////////////////////////////////////////////
char menu (void)
{
u8 nam;
if(!(PINB&(1<<MENU))) 			//pokud je stisknuto
	{
	delay_ms(10);				//prodleva 10ms k ošetření zákmitů
	if(!(PINB&(1<<MENU)))		//opětovná kontrola
		{
		nam=1;					//posun v menu o pozici níž
		delay_ms(180);
		lcd_clrscr();			//smazaní displeje
		}	
	}
else nam=0;
return nam;
}


//************************************************************************************************************
///////***	ULOŽENÍ NASTAVENÝCH PARAMETRŮ REGULÁTORU DO INTERNÍ EEPROM	****
//************************************************************************************************************


void zapis_par_pid (void)
{
eeprom_write_byte(alok_led,led);					//	Uloží proměnou LED na adresu danou alok_led
while eeprom_is_ready();							//	čekám dokud není paměť připravena pro další zápis
eeprom_write_byte(alok_vyber_cidel,vyber_cidel);
while eeprom_is_ready();
eeprom_write_byte(alok_cidlo,cidlo);
while eeprom_is_ready();
eeprom_write_byte(alok_zobrazeni,zobrazeni);
while eeprom_is_ready();
eeprom_write_byte(alok_citac,citac);
while eeprom_is_ready();
eeprom_write_word(alok_Ti,Ti);
while eeprom_is_ready();
eeprom_write_word(alok_Td,Td);
while eeprom_is_ready();
eeprom_write_word(alok_Kr,Kr);
while eeprom_is_ready();
eeprom_write_word(alok_Dif,Dif);
while eeprom_is_ready();
eeprom_write_word(alok_Per,per);
while eeprom_is_ready();
eeprom_write_word(alok_por,por);
while eeprom_is_ready();
eeprom_write_word(alok_kalibrace1,kalibrace1);
while eeprom_is_ready();
eeprom_write_word(alok_kalibrace2,kalibrace2);
}


//************************************************************************************************************
///////***	NAČTENÍ NASTAVENÝCH PARAMETRŮ REGULÁTORU DO INTERNÍ EEPROM	****
//************************************************************************************************************

void nacti_par_pid (void)
{
led = eeprom_read_byte(alok_led);				//	Načte proměnou LED z adresy dané alok_led
vyber_cidel = eeprom_read_byte(alok_vyber_cidel);
cidlo = eeprom_read_byte(alok_cidlo);
zobrazeni = eeprom_read_byte(alok_zobrazeni);
citac = eeprom_read_byte(alok_citac);
Ti = eeprom_read_word(alok_Ti);
Td = eeprom_read_word(alok_Td);
Kr = eeprom_read_word(alok_Kr);
Dif = eeprom_read_word(alok_Dif);
per = eeprom_read_word(alok_Per);
por = eeprom_read_word(alok_por);
kalibrace1 = eeprom_read_word(alok_kalibrace1);
kalibrace2 = eeprom_read_word(alok_kalibrace2);
}


//************************************************************************************************************
///////***	HLAVICKOVY SOUBOR MENU	****
//************************************************************************************************************
void dispmenu (void)
{
b=0;
DIS_ON;	
wdt_disable();
delay_ms(250);						
nacti_par_pid();
	while (b<1)
	{
		lcd_gotoxy(2,0);
		lcd_puts("MENU");

		if (menu())					//při stisknutí tlačítka MENU se přesunu na nižší úroveň menu
		{
		submenu1();
		delay_ms(180);
		}
			
	b=esc(b,1);						//kontrola yda nechceme opustit nastaveni MENU
	}

zapis_par_pid();					//uložení nastavených hodnot na interní eeprom
delay_ms(100);														// Zapnu globalni preruseni
wdt_enable(WDTO_1S);				// Zapnu watchdog s periodou 500ms


}


//************************************************************************************************************
///////***	MENU PRVNÍ ÚROVNĚ	****
//************************************************************************************************************
void submenu1 (void) 
{

b=0;			
	while(b<2)
	{	
		switch (b)
		{
			case 0:
			{
			lcd_gotoxy(1,0);
			lcd_puts("nastav");		//zobrazím nápis nastav
			if (menu())
				{
				submenu_nastav();	//postoupím do menu druhé úrovně nastavení
				}
			}break;
		
			case 1 :
			{
			lcd_gotoxy(1,0);
			lcd_puts("zobraz");		//zobrazím nápis zobraz
			if (menu())
				{
				submenu_zobraz();	//postoupím do menu druhé úrovně zobrazení
				}
			}break;
		
		}

	b=down(b,2);					//kontrola zda nebylo zmáčknuté další tlačítko
	b=up(b,2);	
	b=esc(b,2);
	
	
		
	}
b=0;
}
//************************************************************************************************************
///////***	MENU DRUHÉ ÚROVNĚ	****
//************************************************************************************************************
/*


Submenu  druhé úrovně pro nastavení PID regulátoru a zobrazení hodnot na displeji 
Submenu nastav obsahuje nastavení času, parametrů PID, komunikace, ukládání dat do paměti, výběr čidel

*/

//-----------------------SUBMENU NASTAV-----------------------------------------------------------------------
void submenu_nastav (void)
{
b=0;
	while(b<5)
	{
		switch (b)
		{
			case 0:
			{
			lcd_gotoxy(1,0);
			lcd_puts("cas&dat");
			
				if (menu())
					{
					submenu_casdat();	//Postoupím do menu třetí úrovně
					}
			}break;

			case 1:
			{
			lcd_gotoxy(1,0);
			lcd_puts("par.PID");
		
				if (menu())
					{
				submenu_PIDpar();		//Postoupím do menu třetí úrovně
					}
			}break;
			
			case 2:
			{
			lcd_gotoxy(2,0);
			lcd_puts("LCD");
			lcd_gotoxy(2,1);
			lcd_puts("led");
				if (menu())
					{
					submenu_led();		//Postoupím do menu třetí úrovně
					}
			}break;
			
			case 3:
			{
			lcd_gotoxy(0,0);
			lcd_puts("ukladani");
		
				if (menu())
					{
					submenu_uloz();		//Postoupím do menu třetí úrovně
					}
			}break;

			case 4:
			{
			lcd_gotoxy (1,0);
			lcd_puts("cidla");

				if (menu())
				{
				submenu_cidla();		//Postoupím do menu třetí úrovně
				}
				
			}break;
			
		
		}
	b=down(b,5);
	b=up(b,5);	
	b=esc(b,5);

	}
	b=0;
}


//-----------------------SUBMENU ZOBRAZ-----------------------------------------------------------------------
/*
Na výběr pro zobrazení na displeji mám tři možnosti

1) Teplota- Zobrazí aktuální stav teplot na obou dvou čidlech
2) Čas -Zobrazí aktuální čas a datum
3) Úsporný režim- vypne lcd a nic se nám na displeji nezobrazuje
*/
void submenu_zobraz (void)
{
b=0;
	while(b<3)
	{
	
		switch (b)
		{
			case 0:
			{
			lcd_gotoxy(0,0);
			lcd_puts("cas&dat.");
				if (menu())
				{
				zobrazeni=0;
				lcd_gotoxy(3,0);
				lcd_puts("OK");		//po potvrzení volby se nám zobrazí nápis OK
				delay_ms(500);	
			
				}
			}break;

			case 1:
			{
			lcd_gotoxy(0,0);
			lcd_puts("teplota");
		
			if (menu())
				{
				zobrazeni=1;
				lcd_gotoxy(3,0);
				lcd_puts("OK");
				delay_ms(500);	
			
				}
			}break;
			
			case 2:
			{
			lcd_gotoxy(0,0);
			lcd_puts("usporny");
			lcd_gotoxy(1,1);
			lcd_puts("rezim");
			if (menu())
				{
				zobrazeni=2;
				lcd_gotoxy(3,0);
				lcd_puts("OK");
				delay_ms(500);	
			
				}
			}break;

		}
		
		b=down(b,3);
		b=up(b,3);	
		b=esc(b,3);
}
b=0;
}


//************************************************************************************************************
///////***	MENU TŘETÍ ÚROVNĚ	****
//************************************************************************************************************

//----------------------------------PERIODA UKLADANI TEPLOT---------------------------------------------------

void submenu_uloz (void)
{
				
				b=0;
					while (b==0)
					{
						if(!(PINB&(1<<DOWN)))
						{
							if (citac>0)citac--;
							else (citac=99);
						delay_ms(50);
						}
					
						if(!(PINB&(1<<UP)))
						{
							if (citac<99)citac++;
							else (citac=0);							
						delay_ms(50);
						}
						
						sprintf (pid,"Per.=%2d",citac);
						lcd_gotoxy(1,0);
						lcd_puts(pid);
			
							
						if(!(PINB&(1<<MENU)))
						{	
						delay_ms(50);
						lcd_clrscr ();	
						lcd_gotoxy (2,0);
						lcd_puts("OK");
						delay_ms(500);
						lcd_clrscr();
						b=1;	
						}
					
						if(!(PINB&(1<<ESC))) 
						{
						lcd_clrscr();
						b=1;
						delay_ms(150);
						}	
					}//while
			nastav_citac(citac);

}


//---------------------------------- PARAMETRY PID -----------------------------------------------------------

void submenu_PIDpar(void)
{
b=0;
int a;
	while(b<6)
	{
		switch (b)
		{
			case 0:
			{
			lcd_gotoxy(1,0);
			lcd_puts("nastav");
			lcd_gotoxy(3,1);
			lcd_puts("Ti");			
			if (menu())
				{
				b=0;
					while (b==0)
					{
						if(!(PINB&(1<<DOWN)))
						{
							if (Ti>0)Ti--;
							else (Ti=9999);
						delay_ms(100);
						}
					
						if(!(PINB&(1<<UP)))
						{
							if (Ti<9999)Ti++;
							else (Ti=0);							
						delay_ms(100);
						}
						
						sprintf (pid,"Ti=%4d",Ti);
						lcd_gotoxy(0,0);
						lcd_puts(pid);
			
							
						if(!(PINB&(1<<MENU)))
						{	
						delay_ms(50);
						lcd_clrscr ();	
						lcd_gotoxy (2,0);
						lcd_puts("OK");
						delay_ms(500);
						lcd_clrscr();
						b=1;	
						}
					
						if(!(PINB&(1<<ESC))) 
						{
						lcd_clrscr();
						b=1;
						delay_ms(150);
						}	
					}//while
				}//if

			}break;

			case 1:
			{
			lcd_gotoxy(1,0);
			lcd_puts("nastav");
			lcd_gotoxy(3,1);
			lcd_puts("Td");	
				if (menu())
				{
				b=0;
					while (b==0)
					{
						if(!(PINB&(1<<DOWN)))
						{
							if (Td>0)Td--;
							else (Td=9999);
							delay_ms(100);
						}
					
						if(!(PINB&(1<<UP)))
						{
							if (Td<9999)Td++;
							else (Td=0);
						delay_ms(100);
						}

						sprintf (pid,"Td=%4d",Td);
						lcd_gotoxy(0,0);
						lcd_puts(pid);
							
						if(!(PINB&(1<<MENU)))
						{	
						delay_ms(50);
						lcd_clrscr ();	
						lcd_gotoxy (2,0);
						lcd_puts("OK");
						delay_ms(500);
						lcd_clrscr();
						b=2;	
						}
					
						if(!(PINB&(1<<ESC))) 
						{
						lcd_clrscr();
						b=2;
						delay_ms(150);
						}	
					}
				}
			}break;

			case 2:
			{
			lcd_gotoxy(1,0);
			lcd_puts("nastav");
			lcd_gotoxy(3,1);
			lcd_puts("Kr");	
				if (menu())
				{
				b=0;
					while (b==0)
					{
						if(!(PINB&(1<<DOWN)))
						{
							if (Kr>0)Kr--;
							else (Kr=999);
							delay_ms(200);
						}
					
						if(!(PINB&(1<<UP)))
						{
							if (Kr<999)Kr++;
							else (Kr=0);
						delay_ms(200);
						}
						a=Kr/10;
						sprintf (pid,"Kr=%2d.%1d",a,(Kr-(10*a)));
						lcd_gotoxy(0,0);
						lcd_puts(pid);
							
						if(!(PINB&(1<<MENU)))
						{	
						delay_ms(50);
						lcd_clrscr ();	
						lcd_gotoxy (2,0);
						lcd_puts("OK");
						delay_ms(500);
						lcd_clrscr();
						b=3;	
						}
					
						if(!(PINB&(1<<ESC))) 
						{
						lcd_clrscr();		
						b=3;
						delay_ms(150);
						}
					}		
				}
			}break;

			case 3:
			{
			lcd_gotoxy(1,0);
			lcd_puts("nastav");
			lcd_gotoxy(2,1);
			lcd_puts("Tmax");	
				if (menu())
				{
				b=0;
					while (b==0)
					{
						if(!(PINB&(1<<DOWN)))
						{
							if (Tmax>0)Tmax--;
							else (Tmax=999);
							delay_ms(100);
						}
					
						if(!(PINB&(1<<UP)))
						{
							if (Tmax<999)Tmax++;
							else (Tmax=0);
						delay_ms(100);
						}
						a=Tmax/10;
						sprintf (pid,"Tm=%2d.%1d",a,(Tmax-(a*10)));
						lcd_gotoxy(0,0);
						lcd_puts(pid);
							
						if(!(PINB&(1<<MENU)))
						{	
						delay_ms(50);
						lcd_clrscr ();	
						lcd_gotoxy (2,0);
						lcd_puts("OK");
						delay_ms(500);
						lcd_clrscr();
						b=4;	
						}
					
						if(!(PINB&(1<<ESC))) 
						{
						lcd_clrscr();		
						b=4;
						delay_ms(150);
						}	
					}	
				}
			}break;

			case 4:
			{
			lcd_gotoxy(1,0);
			lcd_puts("nastav");
			lcd_gotoxy(2,1);
			lcd_puts("Dif");	
				if (menu())
				{
				b=0;
					while (b==0)
					{
						if(!(PINB&(1<<DOWN)))
						{
							if (Dif>0)Dif--;
							else (Dif=999);
							delay_ms(80);
						}
					
						if(!(PINB&(1<<UP)))
						{
							if (Dif<999)Dif++;
							else (Dif=0);
						delay_ms(80);
						}


						a=Dif/10;
						sprintf (pid,"D=%2d.%1d",a,(Dif-(a*10)));
						lcd_gotoxy(0,0);
						lcd_puts(pid);
							
						if(!(PINB&(1<<MENU)))
						{	
						delay_ms(50);
						lcd_clrscr ();	
						lcd_gotoxy (2,0);
						lcd_puts("OK");
						delay_ms(500);
						lcd_clrscr();
						b=5;	
						}
					
						if(!(PINB&(1<<ESC))) 
						{
						lcd_clrscr();		
						b=5;
						delay_ms(150);
						}	
					}
				}
			}break;
		
			case 5:
			{
			lcd_gotoxy(1,0);
			lcd_puts("nastav");
			lcd_gotoxy(1,1);
			lcd_puts("Period");	
				if (menu())
				{
				b=0;
					while (b==0)
					{
						if(!(PINB&(1<<DOWN)))
						{
							if (per>10)per=per-10;
							else (per=1000);
							delay_ms(280);
						}
					
						if(!(PINB&(1<<UP)))
						{
							if (per<1000)per=per+10;
							else (per=10);
						delay_ms(280);
						}


						
						sprintf (pid,"T=%d",per);
						lcd_gotoxy(0,0);
						lcd_puts(pid);
							
						if(!(PINB&(1<<MENU)))
						{	
						delay_ms(50);
						lcd_clrscr ();	
						lcd_gotoxy (2,0);
						lcd_puts("OK");
						delay_ms(500);
						lcd_clrscr();
						b=7;	
						}
					
						if(!(PINB&(1<<ESC))) 
						{
						lcd_clrscr();		
						b=7;
						delay_ms(150);
						}	
					}
				}
			}break;

		}//switch1
	b=down(b,6);
	b=up(b,6);	
	b=esc(b,6);
	}//while
b=0;
}//fce



//-----------------------------------SUBMENU ČAS A DATUM------------------------------------------------------
/*
nastavení času a data
1) nastav- nastavení
2)vynuluj- nastaví čas na 00:00:00 a datum na 00.00.00
*/
void submenu_casdat (void)
{
b=0;
	while(b<2)
	{
	
		switch (b)
		{
		
			case 0:
			{
			lcd_gotoxy(1,0);
			lcd_puts("nastav");
		
				if (menu())
				{
				nacti_RTC();
				nastav_cas();
				}
			}break;
		
			case 1:
			{
			lcd_gotoxy(0,0);
			lcd_puts("vynuluj");
		
				if (menu())
				{
				smaz_cas();
				}
			}break;

			
		}
	b=down(b,2);
	b=up(b,2);	
	b=esc(b,2);
		
	}
	b=0;
}


//-----------------------------------SUBMENU LED -nastavení podsvícení------------------------------------------------------

void submenu_led (void)
{
b=0;
	while(b<2)
	{
		switch (b)
		{
			case 0:
			{
			lcd_gotoxy(1,0);
			lcd_puts("zap.");
			if (menu())
				{
				led=0;
				SVIT_ON;
				lcd_gotoxy(2,0);
				lcd_puts("OK");
				delay_ms(500);
				b=3;
				}
			}break;

			case 1:
			{
			lcd_gotoxy(1,0);
			lcd_puts("vyp.");
			if (menu())
				{
				led=1;
				SVIT_OFF;
				lcd_gotoxy(2,0);
				lcd_puts("OK");
				delay_ms(500);
				b=3;
				}
			}break;
		
		}//switch
		b=down(b,2);
		b=up(b,2);	
		b=esc(b,2);
	}//while
	b=0;
}//fce




//-----------------------------------SUBMENU CIDLA------------------------------------------------------
/*

1) Vyber - máme možnost vybrat mezi dvěma typy čidel. PT100 a KTY 81/210.
 Potvrzení volby je zobrazeno nápisem OK

2)Kalibrace - pro možnost upravit velikost teploty npř v závislosti na délce použitého vedení je 
zde možnost kalibrace. Velikost rozdílu je zobrazena indexy (0,+,-) 
*/

void submenu_cidla (void)
{
b=0;

	while(b<2)
	{
		switch (b)
		{
		
			case 0:
			{
			lcd_gotoxy(1,0);
			lcd_puts("vyber");
			delay_ms(180);

				if (menu())
				{
				b=0;
				while (b<2)
				{
					switch (b)
					{
		
					case 0:
						{
						lcd_gotoxy(1,0);
						lcd_puts("PT100");

								if (menu())
								{
								vyber_cidel=0;
								lcd_gotoxy(2,0);
								lcd_puts("OK");
								delay_ms(500);
								b=3;
								
								}	
						}break;
					case 1:
						{
						lcd_gotoxy(1,0);
						lcd_puts("KTY/81");

								if (menu())
								{
								vyber_cidel=1;
								lcd_gotoxy(2,0);
								lcd_puts("OK");
								delay_ms(500);
								b=3;
								}	
						}break;

					}//switch	

						b=down(b,2);
						b=up(b,2);	
						b=esc(b,2);
		
				}//while
				b=1;
				}//if
			}break;

			case 1:
			{
			lcd_gotoxy(1,0);
			lcd_puts("kalibr");
			
				if (menu())
				{
				b=0;
					while (b<2)
					{
						switch (b)
						{
							case 0:
							{
							
							lcd_gotoxy(0,0);
							lcd_puts("cidlo 1");
								if (menu())
								{
								b=0;	
									while (b==0)
									{
									
									vzorkovani();
									lcd_gotoxy(1,0);
									lcd_puts(teppt1);
									lcd_gotoxy(1,1);
									lcd_puts(teppt2);
									lcd_gotoxy(6,0);
									if (kalibrace1>0) lcd_puts("+");
									else if (kalibrace1<0) lcd_puts("-");
									else lcd_puts("0");
									delay_ms(400);
						
									if(!(PINB&(1<<DOWN)))
									{
									kalibrace1--;
									delay_ms(280);	
									}	

									if(!(PINB&(1<<UP)))
									{	
									kalibrace1++;	
									delay_ms(280);		
									}
						
									if(!(PINB&(1<<ESC)))
									{
									delay_ms(180);
									lcd_clrscr();
									b=1;
									}

									if (menu())
									{
									b=1;
									delay_ms(180);
									}
									}
								}
			
							}break;

							case 1:
							{
								
							lcd_gotoxy(0,0);
							lcd_puts("cidlo 2");
								if (menu())
								{
								b=0;		
									while(b==0)
									{
									vzorkovani();
									lcd_gotoxy(0,0);
									lcd_puts(teppt1);
									lcd_gotoxy(0,1);
									lcd_puts(teppt2);
									lcd_gotoxy(6,1);
									if (kalibrace2>0) lcd_puts("+");
									else if (kalibrace2<0) lcd_puts("-");
									else lcd_puts("0");
									delay_ms(100);
									if(!(PINB&(1<<DOWN)))
									{
									kalibrace2--;
									delay_ms(280);	
									}	

									if(!(PINB&(1<<UP)))
									{	
									kalibrace2++;	
									delay_ms(280);		
									}
					
									if(!(PINB&(1<<ESC)))
									{
									delay_ms(180);
									lcd_clrscr();
									b=3;
									}
								
									if (menu())
									{
									b=3;
									delay_ms(180);
									}
									}
								}
							
							}break;						

						}//svitch
					b=down(b,2);
					b=up(b,2);	
					b=esc(b,2);
					}//while

					b=0;
				}//if
			}break;
		}//switch

		b=down(b,2);
		b=up(b,2);	
		b=esc(b,2);
	
	}//while
	b=0;

}//menu
//////////////////////////////////////////////////////////
