/* 
 * File:   main.c
 * Author: gabor
 *
 * Created on 2015. február 11., 15:33
 */

#include <stdio.h>
#include <stdlib.h>
#include <pic.h>
#include <xc.h>
#include <pic16f1788.h>

#pragma config FOSC = INTOSC     //RA6 pin10; RA7 pin9
#pragma config WDTE = OFF        //Watchdog Timer
#pragma config PWRTE = OFF       //Power-up Timer
#pragma config MCLRE = OFF       //digital input
#pragma config CP = OFF          //Program memory code protection is disabled
#pragma config CPD = OFF         //Data memory code protection is disabled
#pragma config BOREN = OFF       //Tapfesz ingatozaskor Reset
#pragma config IESO = OFF        //ketsebesseges inditas
#pragma config FCMEN = OFF       //órajel figyel? áramkör
#pragma config LVP = OFF         //Alacsony feszültség
#pragma config PLLEN = OFF        //Frekvencia 4x

/*
 * 
 */

void init ( void );
void init_lcd ( void );
void write_lcd ( unsigned char );
void pulse_E ( void );
void RS( unsigned char );
void RW( unsigned char );
void delay100us( void );
void delay5ms( void );
void analog_ki( unsigned int );
unsigned int get_analog( void );

unsigned char temp_C;
unsigned int analog;

int main(int argc, char** argv) {
    init();
    init_lcd();
    while(1)
    {
        RS(0);                   //parancs
        write_lcd(0b00000010);   //kurzor home
        delay5ms();
    analog = get_analog()+500;
    analog_ki(analog);

    TMR1L = 0x00;
    TMR1H = 0x00;
    PIR1bits.TMR1IF = 0;
    while(!PIR1bits.TMR1IF);       //Várakozás
    TMR1L = 0x00;
    TMR1H = 0x00;
    PIR1bits.TMR1IF = 0;
    while(!PIR1bits.TMR1IF);       //Várakozás
    TMR1L = 0x00;
    TMR1H = 0x00;
    PIR1bits.TMR1IF = 0;
    while(!PIR1bits.TMR1IF);       //Várakozás
    TMR1L = 0x00;
    TMR1H = 0x00;
    PIR1bits.TMR1IF = 0;
    while(!PIR1bits.TMR1IF);       //Várakozás
    }

    return (EXIT_SUCCESS);
}

void init( void )
{
    //OSCCONbits.SCS = 0b00;           //Órajel forrás választás PLL
    OSCCONbits.SCS = 0b11;           //Belső órajel foffés
    OSCCONbits.IRCF = 0b1111;        //16Mhz
    //OSCCONbits.SPLLEN = 1;           //PLL On *** Innentől 32Mhz

    LATAbits.LATA0 = 0;
    TRISAbits.TRISA0 = 1;            //Bemenet
    ANSELAbits.ANSA0 = 1;            //Analog input  141.o.

    TRISB = 0;                       //kimenet
    TRISC = 0b00011111;              //RC5-6-7 kimenet E, R/W, RS


               //   Init TMR1
    T1CONbits.TMR1CS = 0b00;         //Tosc/4
    T1CONbits.T1CKPS = 0b11;         //előosztás 8-al
    T1CONbits.TMR1ON = 1;            //TMR1 on
    PIR1bits.TMR1IF = 0;             //Megszakítás törlése
               //   Init  TMR0
    //OPTION_REGbits.TMR0CS = 0;       //Fosc/4
    //OPTION_REGbits.PSA = 0;          //Előosztó on
    //OPTION_REGbits.PS = 0b111;       //Előosztó 256
    //INTCONbits.TMR0IF = 0;           //Megszakítás törlése

    INTCONbits.GIE = 1;                //Globális
    INTCONbits.PEIE = 1;               //Periféria
    PIE1bits.ADIE = 1;                 //ADC
    PIR1bits.ADIF = 0;                 //ADC megszakításjelző törlése

    ADCON0bits.ADRMD = 0;              //
    ADCON1bits.ADFM = 1;               // jobbra igazítva 12 bit
    ADCON0bits.CHS = 0b00000;          // AN0
    ADCON2bits.CHSN = 0b1111;          // ADC -in bemenete Vss-re
    ADCON1bits.ADCS = 0b111;           // Frc oszcillátor
    ADCON1bits.ADNREF = 0;             // Vref- Vss
    ADCON1bits.ADPREF = 0b01;          // Vref+ AN3, pin5  Külső Vref
    ADCON0bits.ADON = 1;               // ADC On
}

void init_lcd( void )
{
    TMR1L = 0x58;
    TMR1H = 0x9E;
    PIR1bits.TMR1IF = 0;
    while(!PIR1bits.TMR1IF);       //Várakozás 50 ms

    RS(0);                         //Parancs
    RW(0);                         //Írás

    write_lcd(0b00110000);         //Function set, 8bit

    delay5ms();

    write_lcd(0b00110000);         //Function set, 8bit

    delay100us();

    write_lcd(0b00110000);         //Function set, 8bit

    delay100us();

    write_lcd(0b00111000);         //Function set, 8bit, 2 sor, 5x7 font

    delay100us();

    write_lcd(0b00001000);         //Display Control, display, cursor, blink Off

    delay100us();

    write_lcd(0b00000001);         //Display Clear

    delay5ms();

    write_lcd(0b00001111);         //Display Control, display, cursor, blink On

    delay100us();

    write_lcd(0b00000110);        //Entry Mode Set I/D = 1 növeli a kurzor p.

    delay5ms();
}

void write_lcd ( unsigned char info)
{
   LATB = info;
   pulse_E();
}

void pulse_E ( void )
{
    temp_C = PORTC;
    temp_C = temp_C | 0b10000000;
    PORTC = temp_C;                //LCD Enable On
    NOP();
    NOP();
    NOP();
    NOP();
    temp_C = temp_C & 0b01111111;
    PORTC = temp_C;                //LCD Enable Off
}
void RS( unsigned char parancs)
{
    if (parancs == 1)
    {
        temp_C = PORTC;
        temp_C = temp_C | 0b00100000;
        PORTC = temp_C;               // RC = 1 data
    }
    else
    {
        temp_C = PORTC;
        temp_C = temp_C & 0b11011111;
        PORTC = temp_C;               // RC = 0 instruction
    }
}void RW( unsigned char olvas)
{
    if (olvas == 1)
    {
        temp_C = PORTC;
        temp_C = temp_C | 0b01000000;
        PORTC = temp_C;               // RW = 1 read
    }
    else
    {
        temp_C = PORTC;
        temp_C = temp_C & 0b10111111;
        PORTC = temp_C;               // RW = 0 write
    }
}
void delay100us( void )
{
    TMR1L = 0xCE;
    TMR1H = 0xFF;
    PIR1bits.TMR1IF = 0;
    while(!PIR1bits.TMR1IF);       //Várakozás 100 us
}
void delay5ms( void )
{
    TMR1L = 0x3C;
    TMR1H = 0xF6;
    PIR1bits.TMR1IF = 0;
    while(!PIR1bits.TMR1IF);       //Várakozás 5 ms
}
void analog_ki( unsigned int szam )
{
    unsigned char ezer = 0, szaz = 0, tiz = 0, egy = 0;
    if (szam >= 1000)
    {
       ezer = szam / 1000;
       szam = szam - ezer * 1000;
    }
    if (szam >= 100)
    {
        szaz = szam / 100;
        szam = szam - szaz * 100;
    }
    if (szam >= 10)
    {
        tiz = szam / 10;
        szam = szam - tiz * 10;
    }
    egy = szam;
    RS(1);      // adat ki
    write_lcd(48+ezer);
    delay5ms();
    write_lcd(48+szaz);
    delay5ms();
    write_lcd(48+tiz);
    delay5ms();
    write_lcd(48+egy);
}
unsigned int get_analog( void )
{
    unsigned long temp = 0, max = 0, osszeg = 0;
    unsigned int i = 0;
    for (i = 0; i < 256; i++ )
    {
        //delay100us();
        ADCON0bits.GO_nDONE = 1;
        //SLEEP();
        while(ADCON0bits.GO_nDONE);
        //PIR1bits.ADIF = 0;
        temp = ADRESH;
        temp = temp<<8;
        temp = temp + ADRESL;
        if (max < temp)
        {
            max = temp;
        }
        osszeg = osszeg + temp;
    }
    return osszeg>>8;
}