/*                   Lcd vezérlés
                                   E = GP7,  RS = GP6,  D7-D4 = GP3-0                             */
#include "io430.h"
#include "lcd_i2c.h"

//------------------------- Ékezetes betűk ---------------------------------------------------------
const unsigned char betwk[] = {0x02,0x04,0x0E,0x01,0x0F,0x11,0x0F,0x00,    //á
0x02,0x04,0x0E,0x11,0x1F,0x10,0x0E,0x00,    //é
0x02,0x04,0x0C,0x04,0x04,0x04,0x0E,0x00,    //í
0x02,0x04,0x0E,0x11,0x11,0x11,0x0E,0x00,    //ó
0x02,0x04,0x11,0x11,0x11,0x13,0x0D,0x00,    //ú
0x0A,0x00,0x11,0x11,0x11,0x13,0x0D,0x00,    //ü
0x05,0x0A,0x11,0x11,0x11,0x13,0x0D,0x00,    //ű
0x05,0x0A,0x0E,0x11,0x11,0x11,0x0E,0x00};   //ő

//------------------------- MCP 23008 GP írása -----------------------------------------------------
void mcp23008_i2c(unsigned char tx){
    UCB0CTL1 |= UCTR + UCTXSTT;             // adatküldés indítás
    UCB0TXBUF = 0x0a;                       // MCP23008 OLAT adatregiszter
    while (!(IFG2 & UCNACKIFG));            // várunk míg kiér az adat
    UCB0TXBUF = tx;                         // GP portra írás
    while (!(IFG2 & UCNACKIFG));            // várunk míg kiér az adat
    UCB0CTL1 |= UCTXSTP;                    // i2c álj
    __delay_cycles(500);                    // várunk
}                 // void mcp
//---------------------- Lcd inicializálás ---------------- E=GP7, RS=GP6, D7-D4= GP3-0 ------------
void lcdinit(void){
    mcp23008_i2c(0x3);            // D4-D5 magas, E, RS alacsony        0b00000011
    mcp23008_i2c(0x83);           // D4-D5 magas, E magas, RS alacsony  0b10000011
    delay_ms(2);                  // várunk
    mcp23008_i2c(0x3);            // D4-D5 magas, E, RS alacsony        0b00000011
    delay_ms(5);                  // várunk min 4,1ms-ot
    
    mcp23008_i2c(0x83);           // D4-D5 magas, E magas, RS alacsony  0b10000011
    delay_ms(2);                  // várunk
    mcp23008_i2c(0x3);            // D4-D5 magas, E, RS alacsony        0b00000011  
    
    mcp23008_i2c(0x83);           // D4-D5 magas, E magas, RS alacsony  0b10000011
    delay_ms(2);                  // várunk
    mcp23008_i2c(0x3);            // D4-D5 magas, E, RS alacsony        0b00000011
    
    mcp23008_i2c(0x3 & 0xf2);     // D5 magas, E, RS alacsony           0b00000010
    mcp23008_i2c(0x82);           // D5 magas, E, RS alacsony           0b10000010
    delay_ms(2);                  // várunk
    mcp23008_i2c(0x2);            // D5 magas, E, RS alacsony           0b00000010

    lcdparancs(0x28);             // 4bites mód beállítás
    delay_ms(5);                  // várunk
    lcdparancs(0x0C);             // lcd be, cursor kikapcsolás
    lcdparancs(0x01);             // képernyőtörlés
}                // void lcd inicializálás
//------------------------ Lcd command -------------------------------------------------------------
void lcdparancs(unsigned char adat){
    mcp23008_i2c((adat >> 4) & 0x0F);              // adat küldés
    mcp23008_i2c(((adat >> 4) & 0x0F)+0x80);       // E=0b1000xxxx, E magas + adat 
    mcp23008_i2c((adat >> 4) & 0x0F);              // E alacsony + adat
    mcp23008_i2c(adat & 0x0f);                     // adat küldés
    mcp23008_i2c((adat & 0x0f)+0x80);              // E magas + adat
    mcp23008_i2c(adat & 0x0f);                     // E alacsony + adat
}                // void lcd parancs
//----------------------- Lcd adat -----------------------------------------------------------------
void lcdadat(unsigned char adat_ki){
    mcp23008_i2c(((adat_ki >> 4) & 0x0f)+0x40);          // Lcd adat küldés
    mcp23008_i2c(((adat_ki >> 4) & 0x0f)+0xc0);          // Lcd adat küldés
    mcp23008_i2c(((adat_ki >> 4) & 0x0f)+0x40);          // Lcd adat küldés
    mcp23008_i2c((adat_ki & 0x0f)+0x40);                 // Lcd adat küldés
    mcp23008_i2c((adat_ki & 0x0f)+0xc0);                 // Lcd adat küldés
    mcp23008_i2c((adat_ki & 0x0f)+0x40);                 // Lcd adat küldés
}                // void lcd adat
//--------------------- Lcd-re szöveg írás ---------------------------------------------------------
void print(char *karakter){
  while (*karakter){  
    lcdadat(*karakter);
    karakter++;
  }
}                // void írás
//--------------------- Kurzor pozíció -------------------------------------------------------------
void kurzorxy(unsigned char  x,unsigned char y){
    if(x<40){
        if(y) x |= 0x40;
        x |=0x80;
        lcdparancs(x);
    }
}               // void kurzor
//--------------------- Lcd sorváltás 4x16 or 4x20 lcd-hez -----------------------------------------
void sor(unsigned char a){
    if(a==1){a=0x80;}            // 4x16-os lcd-hez van beállítva !!!!
    if(a==2){a=0xc0;}
    if(a==3){a=0x90;}
    if(a==4){a=0xd0;}
    lcdparancs(a);
}               //  void sor
//--------------------- Lcd képernyő törlés --------------------------------------------------------
void lcdclear(void){
  lcdparancs(0x01);
  delay_ms(2);
}              // void képernyőtörlés
//--------------------- Lcd értékek kiírása max 1000 -----------------------------------------------
void lcd_ertek(int szam){
    unsigned char ezer, szaz, tiz, egy;
    ezer = szam / 1000;
    lcdadat(ezer + 0x30);
    szaz = ((szam - ezer * 1000)-1) / 100;
    lcdadat(szaz + 0x30);
    tiz = (szam %100)/10;
    lcdadat(tiz + 0x30);
    egy = szam %10;
    lcdadat(egy + 0x30);
}            // void érték kiírása
//--------------------- Lcd ékezetes betük kiírása -------------------------------------------------
void lcd_putc(unsigned char data) {
         char c;
         if (c=data) {
           switch(c) {
             case 'á':  c = 0x00; break;    // cgram 0x40 + 0x00
             case 'é':  c = 0x01; break;    //              0x08
             case 'í':  c = 0x02; break;    //              0x10
             case 'ó':  c = 0x03; break;    //              0x18
             case 'ú':  c = 0x04; break;    //              0x20
             case 'ü':  c = 0x05; break;    //              0x28
             case 'ű':  c = 0x06; break;    //              0x30
             case 'ő':  c = 0x07; break;    //              0x38
             case 'ö':  c = 0xEF; break;    //              ?
           }
           lcdadat(c);
         }
}           // void ékezetes betűk
//-------------------- Lcd cgram feltöltése ékezetes betükkel --------------------------------------
void lcd_cgram_init(void) {
  unsigned char i;
         lcdparancs(0x40);               // kurzor a CGRAM elejére
         for(i=0; i<64; i++) {
           lcdadat(betwk[i]);            // karakterek feltöltése
         }                               // ékezetes karakterekkel
         lcdparancs(0x80);               // kurzor a DDRAM elejére
}           // void cgram