#include "lcd.h"
#include <xc.h> //XC32 prekladac
#include "delay.h"

void initLcd(void) {
    delayMs(50); //pockat vice jak 40 ms po ustaleni napajeni
    
    D7_ANSEL = 0; //dig. pin
    D6_ANSEL = 0;
    D5_ANSEL = 0;
    D4_ANSEL = 0;
    D2_ANSEL = 0;
    RS_ANSEL = 0;
    
    D7_TRIS = 0; //vystup
    D6_TRIS = 0;
    D5_TRIS = 0;
    D4_TRIS = 0;
    D3_TRIS = 0;
    D2_TRIS = 0;
    D1_TRIS = 0;
    D0_TRIS = 0;
    RS_TRIS = 0;
    RW_TRIS = 0;
    E_TRIS = 0;
    
    E = 1; //neaktivni v log. 1
    delayUs(1200); //pockat
    
    //LCD init
    RW = 0;
    
    cmdLcd(0x39); //8 b data, 2-radkovy (3) display, 5x8 text, sada instrukci 1
    cmdLcd(0x15); //kontrast 1/5, 3-radkovy display
    cmdLcd(0x55); //icon display vypnut, nastaveni napajeni, kontrast C5 a C4
    cmdLcd(0x6E); //nastaveni napajeni
    cmdLcd(0x72); //kontrast C3 az C0
    cmdLcd(0x38); //sada instrukci 0
    //cmdLcd(0x0F); //zapnout display, zapnout kurzor, zapnout blikani - pro debugovani
    cmdLcd(0x0C); //zapnout display, vypnout kurzor, vypnout blikani
    clearLcd();   //vymazat display
    cmdLcd(0x06); //posun doprava, automaticky
}

void cmdLcd(unsigned char cmd) { //odeslat prikaz
    RS = 0;
    LATE &= 0xFFFFFF00;
    LATE |= cmd;
    E = 0;
    
    if((cmd == 1) || (cmd == 2) || (cmd == 3)) { //nektere prikazy potrebuji delsi dobu na provedeni
        delayUs(1200);
    }
    
    else {
        delayUs(30);
    }
    
    E = 1;
}

void dataLcd(unsigned char data) { //vypise znak
    RS = 1;
    LATE &= 0xFFFFFF00;
    LATE |= data;
    E = 0;
    delayUs(30);
    E = 1;
}

void writeLineLcd(char* text) { //vypise 16 znaku
    unsigned char i;
    
    for(i = 0; i < 16; i++) {
        if(*text != 0) {
            dataLcd(*text);
            text++;
        }
        
        else { //pokud najde \n, vypise dale pouze prazdne policka
            dataLcd(' ');
        }
    }
}

void homeLcd(void) { //home
    cmdLcd(0x02);
}
void clearLcd(void) { //smazat, home
    cmdLcd(0x01);
}

void setAddrLcd(unsigned char line, unsigned char col) { //nastavit pozici kurzoru
    if((line > 2) || (col > 15)) {
        return;
    }
    
    unsigned char addr = (line << 4) + col;
    
    cmdLcd(0b10000000 | addr);
}

void writeStringLcd(unsigned char* text, unsigned char n) { //vypsat string
    if(n > 48) {
        return;
    }
    
    unsigned char i;
    
    for(i = 0; i < n; i++)
    {
        dataLcd(*text);
        text++;
    }
}