//kniznica.c

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "lcd.h"
#include "kniznica.h"

void pinSet()
{
    TRISAbits.TRISA6 = 0;
    TRISA |= 0b00011111;
    ANSELA &= 0b11100000;
    TRISC &= 0b11110000;
    TRISE &= 0b11111000;
    TRISF &= 0b00010000;
    LED_in = 0;
    LATF &= 0b00000000;
}

void initTimer()
{
    //Timer1
	T1CON = 0x22; //prescale 1:4 -> , 16-bit, timer off
    T1CLK = 0x01; //Fosc/4 + prescale 1:4 -> f = 62500 Hz -> 16 us
    //comparator
    CCP1CONbits.EN = 1; //CCP enable
    CCP1CONbits.MODE = 1; //toggle output, clear TMR1, set flag
    CCPR1L = 0xA0;
    CCPR1H = 0x0F; //compare timer with 4000 -> 16us * 4000 = 64ms
    //Timer1 on
    T1CONbits.ON =1;
    //interrupt
    INTCON0bits.GIE = 1; //interrupt on
    PIR4bits.CCP1IF = 0; //CCP1 flag off
    PIE4bits.CCP1IE = 1; //CCP1 interrupt on
    
    //Timer3
    T3CON = 0x22; //prescale 1:4 -> , 16-bit, timer off
    T3CLK = 0x01; //Fosc/4 + prescale 1:4 -> f = 62500 Hz -> 16 us
    //Timer3 on
    T3CONbits.ON = 1;
}

void initAdc()
{
	ADCON0 = 0x54; //CONT = 1, dedicated osc, right-justified
    ADREF = 0x03; //NREF = Vss, PREF = FVR
    FVRCON = 0x83; //FVR enabled, Buffer Gain 4x -> FVR = 4,096 V
}

void initB()
{
	//set B0, B1, B2, B3 to analog input
    TRISB |= 0b00001111;
    ANSELB |=0b00001111;
}

void supplyOff()
{
    LATF &= 0b00000000;
    //Vsetko sa vypne
    variable = 0;
    LED_in = 0;
    LED_LDO = 0;
    LED_load_LDO = 0;
    LED_boost = 0;
    LED_load_boost = 0;
    LED_buck = 0;
    LED_load_buck = 0;
    LED_pump = 0;
}

void supplySet (unsigned int zdroj)
{
    LATF &= 0b00000000;
    //Zapne LED iba pri zvolenom zdroji, ostatne vypne
    switch(zdroj)
    {
        case 1:
            LED_boost = 0;
            LED_load_boost = 0;
            LED_buck = 0;
            LED_load_buck = 0;
            LED_pump = 0;
            LED_LDO = 1;
            LED_load_LDO = 1;
            break;
        case 2:
            LED_LDO = 0;
            LED_load_LDO = 0;
            LED_buck = 0;
            LED_load_buck = 0;
            LED_pump = 0;
            LED_boost = 1;
            LED_load_boost = 1;
            break;
        case 3:
            LED_LDO = 0;
            LED_load_LDO = 0;
            LED_boost = 0;
            LED_load_boost = 0;
            LED_pump = 0;
            LED_buck = 1;
            LED_load_buck = 1;
            break;
        case 4:
            LED_LDO = 0;
            LED_load_LDO = 0;
            LED_boost = 0;
            LED_load_boost = 0;
            LED_buck = 0;
            LED_load_buck = 0;
            LED_pump = 1;
            break;
        default:
            LED_LDO = 0;
            LED_load_LDO = 0;
            LED_boost = 0;
            LED_load_boost = 0;
            LED_buck = 0;
            LED_load_buck = 0;
            LED_pump = 0;
            break;
    }
}

float temperatureMeasure (uint8_t bits)
{
    if(bits <= 4 && bits != 0)
    {
        ADCON0bits.GO = 0; //stop conversion
        ADCON0bits.ON = 0; //Turn Adc off
        ADPCH = 7 + bits; //bits = 1->ANB0,= 2->ANB1,= 3->ANB2,= 4->ANB3
        ADCON0bits.ON = 1; //Turn Adc on
        ADCON0bits.GO = 1; //start conversion
        __delay_ms(1);
        resultAD = (ADRESH << 8) + ADRESL;
        return ((((float)(resultAD))/1000) - 0.4)/0.0195;
    }
    return 0;
}

void updateTemperature()
{
    temp = temperatureMeasure (variable);
    posLcd (3, 1); //Vypisane na zaciatok tretieho riadku
    snprintf(buffer, 16, "Teplota: %.1f", temp);
    writeLcd (buffer);
    posLcd (3, 15); //Vypisane stpen C za teplotu
    datLcd (0xDF);
    datLcd ('C');
}

void displaySupply()
{
    posLcd (2, 1); //Vypisane na zaciatok druheho riadku
    if (variable == 1)
    {
        writeLcd ("LDO         39");
    }
    else if (variable == 2)
    {
        writeLcd ("BOOST      120");
    }
    else if (variable == 3)
    {
        writeLcd ("BUCK        27");
    }
    else if (variable == 4)
    {
        writeLcd ("NABOJOVA PUMPA  ");  
    }
    if (variable <=3 && variable != 0)
    {  
        posLcd (2, 16); //Vypisane ohm
        datLcd (0x1E);
    }
}

