/*****************************************************
Chip type               : ATmega64L
Program type            : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 1024
*****************************************************/

//#define SWITCH5 PINE.7                   // tlacitka - v klidu 1, stisknute 0
//#define SWITCH4 PINE.6
#define SWITCH1 PINE.5                     
#define SWITCH2 PINE.4
#define SWITCH3 PINE.3

#include <mega64.h>
#include <delay.h>      // casove funkce
#include <math.h>       // logaritmus   

#include "t6963c.h"
#include "graphic.h"    // kresleni ikon, text
#include "functions.h"  // funkce - prevod dat, zobrazovani int, char, ...

#include <stdio.h>      // Standard Input/Output functions
#include <stdlib.h>

    int array[100];     // pole hodnot z AD prevodniku (1023 max)
    int voltage[100];   // prepocitane hodnoty na napeti v mV
    
    unsigned int sound_speed;           // rychlost zvuku v m/s
    unsigned int temperature;           // teplota - v desetinach stupne (23,4C = 234)
    unsigned char period_signal=6;      // pocet period ve vyslanem ultrazvukovem signalu - davce    
    unsigned char period_adc=4;         // perida prevodu adc - merici rozsah 
    unsigned char scale=10;             // meritko grafu - 0=automaticke 
    unsigned char set_temp=1;           // merit teplotu (1) nebo nemerit (0)

    eeprom char e_period_signal;        // promenne pro ukladani nastaveni do EEPROM
    eeprom char e_period_adc;
    eeprom char e_scale;
    eeprom char e_set_temp;    

void main(void)
{
    unsigned int m;
    unsigned int distance; 
    float time;
    unsigned char sensitivity;
    float voltage_x;
    unsigned char n;
    unsigned int x;
    unsigned char status=1;  // stav ve kterem je program -> 1-mereni, 0-pauza, 2-nastaveni, 3-prohlizeni prubehu         
    unsigned char setting=1; 
    
//***************************************************************************************************************
    
    init_mcu();             // inicializace mikrokontroleru - nastaveni bran, AD prevodnik, UART, timer0

    LCD_init();             // inicializace displeje
    LCD_clr_text();         // smazani displeje - text
    LCD_clr_gr(0x00);       // smazani displeje - grafika    
       
    LCD_mode_set(LCD_MODE_EXOR);                            // nastaveni displeje - rezim zobrazeni textu a grafiky
    LCD_display_mode(LCD_CURS_OFF,LCD_TEXT_ON_GRAPH_ON,1);  // text zapnuty, grafika zapnuta, kurzor vypnuty     
    LCD_diacritics_generate();                              // vygenerovani znaku diakritiky    
    
    if(e_period_signal>10) period_signal = 6;          // nahrani z eeprom (pokud je vymazana, tak defaultni hodnoty)
    else period_signal = e_period_signal;
    if(e_period_adc>7) period_adc = 4;
    else period_adc = e_period_adc; 
    if(e_scale>10) scale = 10;
    else scale = e_scale; 
    if(e_set_temp>1) set_temp = 1;
    else set_temp = e_set_temp;
    
    ADCSRA=0x80+period_adc;                             // perioda prevodu adc      
    
    
    intro();                                            // text - intro
    while((SWITCH1&&SWITCH2&&SWITCH3));                 // cokoliv stiskni
    while(!(SWITCH1&&SWITCH2&&SWITCH3));
    LCD_clr_text();                                     // smazani displeje
    LCD_clr_gr(0x00);
              
//************************************************************************************************************* 
// hlavni programova smycka - prepinani mezi stavy mereni, pauza, nastaveni a prohlizeni prubehu
//*************************************************************************************************************
while (1)
{  
//******************************** mereni *********************************************************************      
      if(status==1)
      { 
      icon_1();                  // spodni ikony
      
      if(set_temp==1) compute_temperature();  // jestli se ma merit teplota a pocitat rychlost zvuku nebo hodnoty pro pokojovou teplotu
      if(set_temp==0) { temperature=250;
                        sound_speed=347; }
      show_temperature();
             
      ADCSRA=0x80+period_adc;    // perioda prevodu adc 
       
      clear_graph();             // smazani prodchoziho prubehu                  
      
      generate_usonic(period_signal);   // vygeneruj davku ultrazvukoveho signalu (pocet kmitu = period_signal)
      
      if (period_adc==7) {  delay_us(200);                                      // korekce podle poctu kmitu v davce - prevod zacne pozdeji
                            for(n=0;n<(10-period_signal);n++) delay_us(10); }
      if (period_adc==6) {  delay_us(200);
                            for(n=0;n<(10-period_signal);n++) delay_us(10); }
      if (period_adc==5) {  delay_us(200);
                            for(n=0;n<(10-period_signal);n++) delay_us(10); }
      if (period_adc==4) {  delay_us(200);
                            for(n=0;n<(10-period_signal);n++) delay_us(10); }
      if (period_adc==3) {  delay_us(200);
                            for(n=0;n<(10-period_signal);n++) delay_us(10); }
      if (period_adc==2) {  delay_us(180);
                            for(n=0;n<(10-period_signal);n++) delay_us(10); }
      if (period_adc==1) {  delay_us(200);
                            for(n=0;n<(10-period_signal);n++) delay_us(10); }
                            

      for(n=0;n<100;n++)                    // prevod ADC, 100 vzorku
      {
      array[n]=read_adc_usonic();
      } 
      
      for(n=0;n<100;n++)                    // prepocet na napeti
      {
      voltage[n]=array[n]*2.443;
      }
      
      compute_scale();                      // vypocet meritka pro zobrazeni
      show_graph();                         // zobrazeni prubehu na displeji
      
      
     for(m=0;m<500;m++)                     // osetreni stisku tlacitek
      {      
      if(SWITCH1==0)                        // prvni tlacitko
                {
                   status=2;                // jdi na nastaveni
                     
                    while(SWITCH1==0);
                }
      if(SWITCH2==0)                        // druhe tlacitko
                {
                    status=0;               // jdi na pauzu
                    
                    while(SWITCH2==0);
                }
      if(status!=1) break;                
      delay_ms(1);      
      }    
}                  
//******************************** pauza *********************************************************************
      if(status==0)
      {   
      icon_3();                              // ikony dole
       
      LCD_text_xy(0,0);                      // nastaveni pozice na disp.
      LCD_string("                    ");    // smazani predchoziho textu
      show_temperature();                    // zobrazeni teploty                    
      
      show_graph();                          // vykresleni prubehu
      
      while(status==0)
      {
      if(SWITCH1==0)
                {  
                    status=3;                // jdi na prohlizeni prubehu
                     
                    while(SWITCH1==0);
                }
      if(SWITCH2==0)
                {
                    status=1;                // jdi na mereni
                    
                    while(SWITCH2==0);
                } 
      if(SWITCH3==0)                         // poslani dat po USB do pocitace
                {                        
                    LCD_clr_gr(0x00);        // smazani disp.
                    LCD_clr_text();
                    
                    icon_5();                // ikony dole
                    textUSB();               // text - informace          
                    
                    while((SWITCH1==1)&&(SWITCH2==1));     // tlacitko zpet a nebo OK = posli data
                    if(SWITCH1==0) status=0;
                    if(SWITCH2==0) {LCD_clr_gr(0x00);
                                    LCD_clr_text(); 
                                    dataUSB();            // posli data        
                                    status=0; }
                                    
                    LCD_clr_gr(0x00);                    // smaz dip.
                    LCD_clr_text();                    
                      
                    icon_3();                            // ikony dole
       
                    LCD_text_xy(0,0);       
                    show_temperature();                  // zobrazeni teploty
      
                    show_graph();                        // zobraz prubeh
                    
                    while(SWITCH2==0);
                    while(SWITCH1==0);
                }
      }
      }
      
//******************************** nastaveni *********************************************************************
      if(status==2)                  
      {
            LCD_clr_text();           // smazani disp.
            LCD_clr_gr(0x00);
            setting=1;
            
            icon_2();                // ikony dole
            
            LCD_text_xy(0,0);                     // text na dane pozici na displeji + diakritika
            LCD_string("Nastaven");
            LCD_char_diacritic(I_DLOUHE_M);
            LCD_char(':');
            
            LCD_text_xy(1,2);
            LCD_string("perioda vzorkov");
            LCD_char_diacritic(A_DLOUHE_M);
            LCD_char('n');
            LCD_char_diacritic(I_DLOUHE_M);
            LCD_char(':'); 
            
            LCD_text_xy(8,3);
            show_period_adc();                    // perioda prevodu - zobrazeni hodnoty
                        
            LCD_set_pixel(69,39,1);
            LCD_set_pixel(70,40,1);
            LCD_set_pixel(68,40,1);
            LCD_set_pixel(69,41,1);
            LCD_text_xy(1,5);
            LCD_string("po");
            LCD_char_diacritic(C_HACEK_M);            
            LCD_string("et kmitu v d");
            LCD_char_diacritic(A_DLOUHE_M);
            LCD_string("vce:");
            
            LCD_text_xy(8,6);
            show_char(period_signal);            // pocet period v davce - zobrazeni hodnoty
            
            LCD_text_xy(1,8);
            LCD_char('m');
            LCD_char_diacritic(E_HACEK_M);
            LCD_char_diacritic(R_HACEK_M);
            LCD_char_diacritic(I_DLOUHE_M);
            LCD_string("tko grafu:");
            
            LCD_text_xy(8,9);                         // meritko zobrazeni na displeji
            if (scale==0) LCD_string("auto       ");
            else {
                    show_char(scale);   
            
                    LCD_text_xy(10,9);
                    LCD_string(" x d");
                    LCD_char_diacritic(E_HACEK_M);
                    LCD_string("leno");
                }                         
            
            LCD_text_xy(1,11);                          // nastaveni jestli merit teplotu
            LCD_string("rychlost zvuku :");
            LCD_text_xy(7,12);
            if(set_temp==0) LCD_string("konst. 347m/s");
            if(set_temp==1) LCD_string("podle teploty");  
            
            LCD_text_xy(1,13);                         // navrat zpet z nastaveni
            LCD_string("zp");
            LCD_char_diacritic(E_HACEK_M);
            LCD_char('t');
            
                                                    
            
            LCD_display_mode(LCD_CURS_ON_BLINK_ON,LCD_TEXT_ON_GRAPH_ON,1);    //zapnuti blikani kurzoru
            LCD_cursor_xy(1,2);
            
            while(setting!=55)                           // prepinani mezi jednotlivymi volbami v menu
            {
            if(SWITCH1==0)
                {
                    if(setting==1)setting=11;            // zpet
                    if(setting==2)setting=22;
                    if(setting==3)setting=33;
                    if(setting==4)setting=44;
                    if(setting==5)setting=55; 
                    while(SWITCH1==0);
                }
            if(SWITCH2==0)
                {
                    setting=setting+1;                 // nahoru
                    if(setting==6) setting=1;   
                    while(SWITCH2==0);
                } 
            if(SWITCH3==0)
                {
                    setting=setting-1;                 // dolu
                    if(setting==0) setting=5;   
                    while(SWITCH3==0);
                }
                
            if(setting==1) LCD_cursor_xy(1,2);
            if(setting==2) LCD_cursor_xy(1,5);
            if(setting==3) LCD_cursor_xy(1,8);
            if(setting==4) LCD_cursor_xy(1,11);
            if(setting==5) LCD_cursor_xy(1,13); 
            
            if(setting==11) {                       // nastaveni periody prevodu
                            LCD_cursor_xy(8,3);
                            while(setting!=1)
                            {
                                if(SWITCH2==0)
                                {
                                if(period_adc==1) period_adc=1;    // dolu
                                else period_adc=period_adc-1;                                   
                                while(SWITCH2==0);
                                }
                                if(SWITCH3==0)
                                {
                                if(period_adc==7) period_adc=7;    //nahoru
                                else period_adc=period_adc+1;                                   
                                while(SWITCH3==0);
                                }
                                if(SWITCH1==0)
                                {
                                setting=1;                         // zpet          
                                while(SWITCH1==0);
                                }
                            LCD_text_xy(8,3);
                            show_period_adc();     
                            }
                            }
            
            if(setting==22) {                       // nastaveni poctu kmitu v davce
                            LCD_cursor_xy(8,6);
                            while(setting!=2)
                            {
                                if(SWITCH2==0)
                                {
                                if(period_signal==1) period_signal=1;   // dolu
                                else period_signal=period_signal-1;                                   
                                while(SWITCH2==0);
                                }
                                if(SWITCH3==0)
                                {
                                if(period_signal==10) period_signal=10; // nahoru
                                else period_signal=period_signal+1;                                   
                                while(SWITCH3==0);
                                }
                                if(SWITCH1==0)
                                {
                                setting=2;                              // zpet     
                                while(SWITCH1==0);
                                }
                            LCD_text_xy(8,6);
                            show_char(period_signal);    
                            }
                            }
                            
            if(setting==33) {                       // nastaveni meritka
                            LCD_cursor_xy(8,9);
                            while(setting!=3)
                            {
                                if(SWITCH2==0)
                                {  
                                while(SWITCH2==0);      // dolu
                                switch(scale) 
                                {
                                case 0: scale=10;
                                        break;
                                case 1: scale=0;
                                        break;
                                case 2: scale=1;
                                        break;
                                case 5: scale=2;
                                        break;
                                case 10:scale=5;
                                        break;
                                }              
                                
                                }
                                if(SWITCH3==0)             // nahoru
                                { 
                                while(SWITCH3==0); 
                                switch(scale) 
                                { 
                                case 0: scale=1;
                                        break;
                                case 1: scale=2;
                                        break;
                                case 2: scale=5;
                                        break;
                                case 5: scale=10;
                                        break;
                                case 10:scale=0;
                                        break;
                                }                              
                                
                                }
                                if(SWITCH1==0)              // zpet
                                {
                                setting=3;                                   
                                while(SWITCH1==0);
                                }   
                                
                            LCD_text_xy(8,9);                             // zobrazeni vybrane hodnoty meritka - cislo nebo napis auto
                            if (scale==0) LCD_string("auto       ");
                            else {
                                    show_char(scale);   
            
                                    LCD_text_xy(10,9);
                                    LCD_string(" x d");
                                    LCD_char_diacritic(E_HACEK_M);
                                    LCD_string("leno");
                                } 
                            }
                            } 
                            
            if(setting==44) {                       // nastaveni mereni telpoty - merit/nemerit
                            LCD_cursor_xy(7,12);
                            while(setting!=4)
                            {
                                if(SWITCH2==0)
                                {  
                                while(SWITCH2==0);
                                if(set_temp==0) set_temp=1;
                                else set_temp=0;                                              
                                }                                        
                                
                                if(SWITCH3==0)
                                { 
                                while(SWITCH3==0); 
                                if(set_temp==0) set_temp=1;
                                else set_temp=0;                                                             
                                }                                                       
                                
                                if(SWITCH1==0)
                                {
                                setting=4;                     // zpet              
                                while(SWITCH1==0);
                                }
                            LCD_text_xy(7,12);
                            if(set_temp==0) LCD_string("konst. 347m/s");
                            if(set_temp==1) LCD_string("podle teploty"); 
                            }
                            }
            }
            status=1; 
            
            e_scale = scale;                    // ulozeni do eeprom pameti             
            e_period_adc = period_adc;
            e_period_signal = period_signal;
            e_set_temp = set_temp;          
            
            LCD_display_mode(LCD_CURS_OFF,LCD_TEXT_ON_GRAPH_ON,1);  // vypnuti blikani kurzoru
            LCD_clr_text();
            LCD_clr_gr(0x00);      
      }
      
//******************************** prohlizeni proubehu **************************************************************     
      if(status==3)
      {
      icon_4();                             // ikony dole
      
      LCD_text_xy(0,0);                     // nastaveni pozice textu       
      LCD_string("                    ");   // smazani predchozi hodnoty
       
      x=0;                                  // pozice v poli, pozice na grafu +13 
      
      show_graph();                         // zobrazeni prubehu
      LCD_line(13+x,13,13+x,113,1);         // oprava prubehu, pokud prejede po nem kurzor zustal by zhasnuty bod
           
      while(status==3)
      {       
      if(SWITCH1==0)
                {  
                    status=0;               // konec prohlizeni, navrat zpet na pauzu
                     
                    while(SWITCH1==0);
                }
      if(SWITCH3==0)                                            //posun vpravo
                {
                    if(x<99) x++;   // maximum vpravo                    
                    else x=99; 
                    LCD_line(13+x,13,13+x,113,1);         // kurzor
                    LCD_line(13+x-1,13,13+x-1,113,0);     // oprava na predchozi pozici
                    show_graph();                         // zobraz prubeh
                    delay_ms(150);
                    
                    while(SWITCH3==0) { if(x<99) x++;           //pokud je tlacitko stisknute dlouho tak rychly posun        
                                        else x=99; 
                                        delay_ms(15);
                                        LCD_line(13+x,13,13+x,113,1);        // kurzor
                                        LCD_line(13+x-1,13,13+x-1,113,0);    // oprava na predchozi pozici
                                        show_graph(); }                      // zobraz prubeh              
                } 
                
      if(SWITCH2==0)                                            //posun vlevo
                {
                    if(x>0) x--;                 
                    else x=0;
                    LCD_line(13+x,13,13+x,113,1);           // kurzor
                    LCD_line(13+x+1,13,13+x+1,113,0);       // oprava na predchozi pozici
                    show_graph();                           // zobraz prubeh
                    delay_ms(150); 
                    
                    while(SWITCH2==0) { if(x>0) x--;                  //pokud je tlacitko stisknute dlouho tak rychly posun
                                        else x=0;
                                        delay_ms(15);
                                        LCD_line(13+x,13,13+x,113,1);      // kurzor
                                        LCD_line(13+x+1,13,13+x+1,113,0);  // oprava na predchozi pozici
                                        show_graph(); }                    // zobraz prubeh
                }      
                                                
                                                // vypocet napeti, casu, citlivosti a vydalenosti na grafu
      LCD_text_xy(0,0);
      show_voltage(voltage[x]);                 // zobraz napeti
      if (voltage[x]==0) sensitivity=145;       // vypocet citlivosti v dB
      else {
      voltage_x=voltage[x]*0.000033;             // napeti - float
      voltage_x=voltage_x/561;
      sensitivity=-20*log10(voltage_x);         // citlivost v dB
      }
      LCD_char(' ');
      show_sens(sensitivity);                   // zobrazeni citlivosti
      
      if (period_adc==7) time=x*0.000224;       // vypocet casu - podle periody prevodu konkretni hodnota
      if (period_adc==6) time=x*0.000112;
      if (period_adc==5) time=x*0.00006;
      if (period_adc==4) time=x*0.0000336;
      if (period_adc==3) time=x*0.0000203;
      if (period_adc==2) time=x*0.0000129;   //14  
      if (period_adc==1) time=x*0.000010;      
      distance=((time*sound_speed)/0.002);      // vzdalenost
      LCD_char(' ');
      show_distance(distance);                  // zobrazeni vzdalnosti
      }
      
      LCD_line(13+x,13,13+x,113,0);            // oprava grafu po odjeti kurzoru
      show_graph();     
      status=0;      
      }
      
      }       
}
