/*------------ 1/2 Szitkovits Gábor -- LCD Menü ----------------------------------------------------
-------------- Az Lcd vezérlés nem az enyém ! ------------------------------------------------------
-- Proci = G2352 ami nem a végleges !!! A végleges G2xx3 lesz. -----------------------------------*/

#include "io430.h"
#include "lcd4x16.h"
#include "stdint.h"
#include "intrinsics.h"

#define fel BIT4
#define le  BIT5
#define set BIT7

unsigned int pwm_ert=100, xo=400, yo=300, ertek;        // PWM, X tengely, Y tengely értékek
/* A pwm_ert, xo, és yo, SPI-n vagy I2C-n kap értéket a gyro és gyorsulásmérőt vezérlő uC-tól,
 a most beállított értékek, csak ideiglenesek !!!!!!!!!!!!!   */
unsigned char poz, menu, pert;

const unsigned char *ekbetu;                            // Ékezetes betü
/*-------------------------- Előre írt szövegek az ékezet miatt plus a CGRAM változtatások miatt -*/
const unsigned char szoveg1[] = {" Készítette: "};
const unsigned char nev[] ={"Szitkovits Gábor"};
const unsigned char beall[] ={"    Beállítás  "};
const unsigned char tov[] ={"          Tovább"};
const unsigned char ind[] ={"   GW indítása "};
const unsigned char pwm_ertek[] ={"PWM érték: "};

// ------------------------- Delay milisec-ben -----------------------------------------------------
void delay_ms(volatile unsigned int t){       // A "t" értéke határozza meg a kéleltetés idejét
  unsigned int i;                             // "i" változó deklarálása
  for(i=0; i<t; i++){                         // "for" ciklus, ahol 1: i=0, 2: i vizsgálata 3: i=i+1
    __delay_cycles(1000);                     // 1000 uS = 1 mS
  }                           // for ciklus
}                             // void delay_ms
//-------------------------- Értékek állítása ------------------------------------------------------
void ertek_all(void){                      // Értékek állítása
  unsigned int gomb;                       // gomb változó deklarálása
  gomb = (~P1IN & fel + le + set) >> 4;    // P1.4 P1.5 P1.7 bemenetek berakása gomb változóba
  delay_ms(20);                            // Várunk 20 mS
  while(!(P1IN & fel));                    // felengedésre vár
  while(!(P1IN & le));                     // felengedésre vár
  while(!(P1IN & set));                    // felengedésre vár
  delay_ms(50);                            // várunk 50 mS
  switch(gomb){                            // gomb értéke? P1.4 = 2, P1.5 = 1, P1.7 = 8
    case 1:                                // P1.5
      ertek--;                             // ertek változó csökkentése egyel
      pert=1;
      break;                               // kilép
      case 2:                              // P1.4
        ertek++;                           // ertek változó növelése egyel                    
        pert=2;
        break;                             // kilép
        case 8:                            // P1.7
          pert=3;
          break;                           // kilép
  }                       // switch
}                         // void értékállítás
//-------------------------- Menü 1-2-4 kezelő gombok ----------------------------------------------
void menu_gombok(void){
  char ujra=1;                              // "ujra" változó deklarálása, a ciklushoz
  unsigned int gomb;                        // gomb változó deklarálása
  while(ujra){                              // ujra ciklus, addig fut míg ujra=0
    gomb = (~P1IN & fel + le + set) >> 4;   // P1.4 P1.5 P1.7 bemenetek berakása gomb változóba
    delay_ms(20);                           // Várunk 20 mS
    while(!(P1IN & fel));                   // felengedésre vár
    while(!(P1IN & le));                    // felengedésre vár
    while(!(P1IN & set));                   // felengedésre vár
    delay_ms(50);                           // Várunk 50 mS
    switch(gomb){                           // gomb értéke? P1.4 = 2, P1.5 = 1, P1.7 = 8
      case 1:                               // P1.5
        if (poz==2){                        // a "poz" változó mondja meg, melyik sorban van a nyíl
          sor(2);                           // 2. soba a kurzor
          print(" ");                       // a nyíl törlése egy szóközzel
          lcd_menu_nyil(1);                 // a nyíl kirajzolása az első sorba
        }
        if (poz==4){                        // ha a 4. sorban van a nyíl
          sor(4);                           // akkor a 4. sorba a kurzor
          print(" ");                       // kitöröljük a nyilat
          lcd_menu_nyil(2);                 // és a második sorba rakjuk a nyila
        }
        break;                              // kilép
        case 2:                             // P1.4
          if (poz==2){                      // ha a második sorban van a nyíl
            sor(2);                         // a 2. sorba a kurzort
            print(" ");                     // szóközzel töröljük a nyilat
            lcd_menu_nyil(4);               // és a negyedik sorba tesszük a nyilat
          }
          if (poz==1){                      // ha az első sorban van a nyíl
            sor(1);                         // kurzor az első sorba
            print(" ");                     // nyíl törlése
            lcd_menu_nyil(2);               // nyíl kirajzolása 2. soba
          }
          break;                            // kilép
          case 8:                           // P1.7
            if(poz==1){                     // Ha az első sorban van a nyíl
              menu=1;                       // menü változóba 1
            }
            if(poz==2){                     // Ha a második sorban van a nyíl
              menu=2;                       // menü változóba 2
            }
            if(poz==4){                     // Ha a negyedik sorban van a nyíl
              menu=4;                       // menü változóba 4
            }
            ujra=0;                         // ujra = 0-val, így vége a ciklusnak !!!!
            break;                          // kilép
    }                   // switch
  }                     // while
}                       // void menü_gombok
//-------------------------- Y offset állítása -----------------------------------------------------
void y_ert_all(void){             // Y tengely offset állítása
  char ujra=1;                    // "ujra" változó deklarálása, a ciklushoz
  sor(2);                         // kurzor a 2. sorba
  print(" ");                     // nyíl törlése
  lcd_menu_nyil(3);               // nyíl kirajzolása 3. sorba
  while(ujra){                    // ujra ciklus, addig fut míg ujra=0
    ertek_all();                  // érték állítás, menübe ugrás
    sor(2);                       // kurzor a 2. sorba
    print("  Y offset: ");        // szöveg Lcd-re írása 
    ertek_lcd(ertek);             // érték kiírása a szöveg után
    if (pert==1){                 // a "pert" változó figyelése, mely a "ert_all"-ban kapott értéket
      pert=0;                     // a "pert" változóba 0-t írunk, mert különben mindíg ide jönne
    }
    if (pert==2){                 // ha "pert=2"-vel
      pert=0;                     // a "pert" nullázása
    }
    if (pert==3){                 // ha "pert=3"-al
      yo=ertek;                   // "yo"-ba írjuk "ertek"-et
      pert=0;                     // "pert" nullázása
      ujra=0;                     // ujra = 0-val, így vége a ciklusnak !!!! 
    }
  }                 // while
}                   // void y_ert....
//--------------------------- X offset állítása ----------------------------------------------------
void x_ert_all(void){            // X tengely offset állítása
  char ujra=1;                   // "ujra" változó deklarálása, a ciklushoz
  sor(1);                        // kurzor az első sorba
  print(" ");                    // nyíl törlése
  lcd_menu_nyil(3);              // nyíl kirajzolása 3. sorba
  while(ujra){                   // ujra ciklus, addig fut míg ujra=0
    ertek_all();                 // érték állítás, menübe ugrás
    sor(1);                      // kurzor az első sorba
    print("  X offset: ");       // szöveg Lcd-re írása
    ertek_lcd(ertek);            // érték kiírása a szöveg után
    if (pert==1){                // ha "pert=1"-vel
      pert=0;                    // a "pert" nullázása
    }
    if (pert==2){                // ha "pert=2"-vel
      pert=0;                    // a "pert" nullázása
    }
    if (pert==3){                // ha "pert=2"-vel
      xo=ertek;                  // "xo"-ba írjuk "ertek"-et
      pert=0;                    // a "pert" nullázása
      ujra=0;                    // ujra = 0-val, így vége a ciklusnak !!!!
    }
  }             // while
}               // void x_ert_all
//------------------------- Menü 4 X Y tengely offset ----------------------------------------------
void menu_4(void){               // X Y tengely offset
  char ujra=1;                   // "ujra" változó deklarálása, a ciklushoz
  lcdclear();                    // Lcd törlése
  while(ujra){                   // ujra ciklus, addig fut míg ujra=0
    sor(1);                      // kurzor az első sorba
    print("  X offset: ");       // szöveg Lcd-re írása
    ertek_lcd(xo);               // érték kiírása a szöveg után
    sor(2);                      // kurzor a 2. sorba
    print("  Y offset: ");       // szöveg Lcd-re írása
    ertek_lcd(yo);               // érték kiírása a szöveg után
    sor(3);                      // kurzor a 3. sorba
    print("  le    ok   fel");   // szöveg Lcd-re írása
    sor(4);                      // kurzor a 4. sorba
    print("     Vissza     ");   // szöveg Lcd-re írása
    lcd_menu_nyil(1);            // nyíl kirajzolása
    menu_gombok();               // Gombkezelő menübe ugrás
    if (menu==1){                // a "menu" változó a gombkezelö menüben kap értéket
      menu=0;                    // menu változóba 0
      x_ert_all();               // ha "menu=1" akkor "x_ert_all" almenübe ugrás
    }
    if (menu==2){                // ha "menu=2" akkor
      menu=0;                    // menu változóba 0
      y_ert_all();               // és "y_ert_all" almenübe ugrás
    }
    if (menu==4){                // ha "menu=4" ami = vissza
      menu=0;                    // menu változóba 0
      ujra=0;                    // ujra = 0-val, így vége a ciklusnak !!!!
    }
  }            // while
}              // void menü_4
//----------------------- Menü 3  PWM beállítás ----------------------------------------------------
void menu_3(void){                 // PWM menü
  char ujra=1;                     // "ujra" változó deklarálása, a ciklushoz
  ertek = pwm_ert;                 // "pwm_ert" másolása "ertek"-be
  lcdclear();                      // Lcd törlése
  sor(4);                          // kurzor a 4. sorba
  print("  le    ki   fel");       // szöveg Lcd-re írása
  while(ujra){                     // ujra ciklus, addig fut míg ujra=0
    sor(2);                        // kurzor a 2. sorba
    ekbetu = pwm_ertek;            // az "ekbetu" mutatóba, a "pwm_ertek" szöveg
    while(*ekbetu){                // mutató ciklus
      lcd_putc(*ekbetu++);         // első betü kiírása
      if(!*ekbetu);                // ha vége a szövegnek, kilép a ciklusból
    }
    ertek_lcd(ertek);              // az érték kiírása a szöveg után
    ertek_all();                   // érték állítás almenübe ugrás
    if (pert==1){                  // ha "pert=1"-vel
      pert=0;                      // a "pert" nullázása
    }
    if (pert==2){                  // ha "pert=2"-vel
      pert=0;                      // a "pert" nullázása
    }
    if (pert==3){                  // ha "pert=3"-vel
      pert=0;                      // a "pert" nullázása
      ujra=0;                      // ujra = 0-val, így vége a ciklusnak !!!!
    }
  }         // while
}           // void menü_3
//----------------------- Menü 2  PWM vagy tengelyek vagy vissza -----------------------------------        
void menu_2(void){                      // Menü 2
  char ujra=1;                          // "ujra" változó deklarálása, a ciklushoz
  while(ujra){                          // ujra ciklus, addig fut míg ujra=0
    lcdclear();                         // lcd törlése
    sor(1);                             // kurzor az első sorba
    print("      PWM      ");           // szöveg Lcd-re írása
    sor(2);                             // kurzor a 2. sorba
    print("  X,Y tengely  ");           // szöveg Lcd-re írása
    sor(4);                             // kurzor a 4. sorba
    print("     Vissza    ");           // szöveg Lcd-re írása
    lcd_menu_nyil(1);                   // nyíl kirajzolása
    menu_gombok();                      // gombkezelő almenübe ugrás
    if (menu==1){                       // ha "menu=1" akkor
      menu=0;                           // menu változóba 0
      menu_3();                         // "menu_3" almenübe ugrás
    }
    if (menu==2){                       // ha "menu=2" akkor
      menu=0;                           // menu változóba 0
      menu_4();                         // "menu_4" almenübe ugrás
    }
    if (menu==4){                       // ha "menu=4" akkor
      menu=0;                           // menu változóba 0
      ujra=0;                           // ujra = 0-val, így vége a ciklusnak !!!!
    }
  }      
}          // void menü_2
//----------------------- Menü 1  GW indítás beállítások -------------------------------------------
void menu_1(void){                          // Főmenü
  char ujra=1;                              // "ujra" változó deklarálása, a ciklushoz
  while(ujra){                              // ujra ciklus, addig fut míg ujra=0
    lcdclear();                             // lcd törlése
    sor(1);                                 // kurzor az első sorba
    ekbetu = ind;                           // az "ekbetu" mutatóba, az "ind" szöveg
    while(*ekbetu){                         // mutató ciklus
      lcd_putc(*ekbetu++);                  // első betü kiírása
      if(!*ekbetu);                         // ha vége a szövegnek, kilép a ciklusból
      }
    sor(2);                                 // kurzor a 2. sorba
    ekbetu=beall;                           // az "ekbetu" mutatóba, a "beall" szöveg
    while(*ekbetu){                         // mutató ciklus
      lcd_putc(*ekbetu++);                  // első betü kiírása
      if(!*ekbetu);                         // ha vége a szövegnek, kilép a ciklusból
      }
    lcd_menu_nyil(1);                       // nyíl kirajzolása első sorba
    menu_gombok();                          // a "menu_gombok" almenübe ugrás
/*---- Ez a rész majd kikerül innen !!!!! --- Egy újabb almenü lesz ------------------------------*/
    if(menu==1){                            // ha "menu=1" akkor
      menu=0;                               // menu változóba 0
      ujra=0;                               // ujra = 0-val, így vége a ciklusnak !!!!
      lcdclear();                           // lcd törlése
      sor(3);                               // kurzor a 3. sorba
      print("Akku fesz:      ");            // szöveg Lcd-re írása
      sor(4);                               // kurzor a 4. sorba
      print(" itt lesz       ");            // szöveg Lcd-re írása
    }
//--------------------------------------------------------------------------------------------------
    if(menu==2){                            // ha "menu=2" akkor
      menu=0;                               // menu változóba 0
      menu_2();                             // "menu_2" almenübe ugrás
    }
  }         // while
}           // void menu_1
/*------------------------- Analóg Digitál konverter -----------------------------------------------
void adc(void){
  ADC10CTL1 = INCH_1 + ADC10DIV_3 ;  // A1 bemmenet, ADC óra osztó /4
  ADC10CTL0 = SREF_0 + ADC10SHT_3 + ADC10ON + ADC10IE;
//--Vcc & Vss a referencia, ADC10 bekapcsolása és megszakítás engedélyezése--
  ADC10AE0 |= BIT1;                  //P1.1 Analog bemenet engedélyezése
  ADC10CTL0 |= ENC + ADC10SC;    // Mintavétel és átalakítás ind
  __low_power_mode_0();          // LPM0 mód bekapcsolás
  adx = ADC10MEM;            // Ad konverzió étréke az ertek-be
}*/
//------------------------- Program ----------------------------------------------------------------
void main(void){

  WDTCTL = WDTPW + WDTHOLD;     // Watchdog tiltás
  BCSCTL1 = CALBC1_1MHZ;        // A gyárilag kalibrált 1 MHz
  DCOCTL = CALDCO_1MHZ;         // DCO frekvencia beállítása
//------------------------- Port beállítások -------------------------------------------------------
  P1DIR = 0x4F;                       // P1.0-P1.3 + P1.6 kimenet
  P1OUT = 0x00;                       // P1 port alacsony
  P1DIR &= ~(BIT4 + BIT5 + BIT7);     // P1.4 P1.5 P1.7 bemenetek (ideiglenes)
  P2DIR &= ~BIT0;                     // P2.0 bemenet
  P2IES |= BIT0;                      // P2.2 lefutó él
  P2IFG &= ~BIT0;                     // flag törlése
  P2IE |= BIT0;                       // megszakítás engedélyezése
  P2DIR |= BIT1;                      // P2.1 kimenet
  P2OUT &= ~BIT1;                     // P2.1 alacsony, itt van a led ami a végtelen ciklusban vill
  /*---------------- További portbeállítások: ------------------------------------------------------
  - SPI vagy I2C portok, de valószínübb az I2C (kevesebb porthasználat)
  - Analog port az akksi figyeléshez (hardver kész, szoftver kidolgozás alatt /matek/ )
  - H-híd hőmérséklet figyelés (hardver 1/2 kész, szoftver sehol)
  - A STOP gomb (jelen esetben P2.0) több funkciós: 1: STOP 2: H-híd áramfelvétel figyelés 
  (hardver kiépítve, szoftver kész). A STOP felirat villogása alatt, valami hangot kéne generálni !!
  - További ötletek, a portok fügvényében lesznek.                                                */  
  __enable_interrupt();               // megszakítás engedélyezése
//------------------------- Lcd beállítások -------------------------------------------------------- 
  lcdinit();              // Lcd inicializálás
  lcd_cgram_init();       // Ékezetek definiálása
//------------------------ Logo kiíratása ----------------------------------------------------------
  print("   GabcsiWay    ");         // szöveg Lcd-re írása
  sor(2);                            // kurzor a 2. sorba
  print(" ver: 1.1  2012 ");         // szöveg Lcd-re írása
  sor(3);                            // kurzor a 3. sorba
  ekbetu = szoveg1;                  // az "ekbetu" mutatóba, a "szoveg1" szöveg
  while(*ekbetu){                    // mutató ciklus
    lcd_putc(*ekbetu++);             // első betü kiírása
    if(!*ekbetu);                    // ha vége a szövegnek, kilép a ciklusból
  }
  sor(4);                            // kurzor a 4. sorba
  ekbetu = nev;                      // az "ekbetu" mutatóba, a "nev" szöveg
  while(*ekbetu){                    // mutató ciklus
    lcd_putc(*ekbetu++);             // első betü kiírása
    if(!*ekbetu);                    // ha vége a szövegnek, kilép a ciklusból
  }
  delay_ms(2000);                    // Várakozuni egy kicsit
  lcdclear();                        // Képernyő törlése
  menu_1();                          // Főmenü indítása
//-------------------------- Végtelen ciklus -------------------------------------------------------
    while(1){
      P2OUT |= BIT1;
      delay_ms(500);
      P2OUT &= ~BIT1;
      delay_ms(500);  
  }                                       // While
}                                         // Main
//-------------------------- Port 2 megszakítás ----------------------------------------------------
#pragma vector=PORT2_VECTOR
__interrupt void Port(void) {
  char ujra=50;                   // ciklus változó feltöltése
  while(ujra){                    // ciklus
    lcdclear();                   // lcd törlése
    delay_ms(500);                // várakozás 500 ms
    sor(2);                       // lcd 2. sor
    print("    S T O P !   ");    // szöveg kiírása
    delay_ms(500);                // várakozás
    ujra--;                       // ciklus futási idejének csökkentése
  }
  WDTCTL &= ~WDTHOLD;          // Watchdog engedélyezése
  WDTCTL = WDT_MDLY_0_5;       // Reset 0.5 ms mulva
//  P2IFG &= ~BIT2;            // P2.2 megszakítás flag törlése    Ez itt HÜLYESÉG !!!!!!
//  __delay_cycles(500);         // És ez is !!!! De elférnek.
}
/* -----------    H U R R Á   M Ű K Ö D I K   !!!!!!!!!! Szeretem a felkiáltójeleket -------------*/