/*
 * File:   main.c
 * Author: michal
 *
 * Created on 7 lutego 2018, 20:03
 */

// PIC16LF1509 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF       // Internal/External Switchover Mode (Internal/External Switchover Mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)
// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LPBOR = OFF      // Low-Power Brown Out Reset (Low-Power BOR is disabled)
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>
#include "hardware.h"
#include "processing.h"
#include <stdint.h>
#include "structs.h"


struct ui_state ui_state;
uint8_t g_shift = 0x0;


void main(void)
{
    struct results results;
    struct config config = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
    uint8_t locked = 0;
    uint8_t tmp_resetnextcycle = 0;
    
    INT_LAT = 0x0;
    init(&config);
    for(volatile uint16_t del = 32767; del > 0; --del);
    while(SW8); for(volatile uint16_t del = 32767; del > 0; --del);
    while(!SW8); for(volatile uint16_t del = 32767; del > 0; --del);
    INT_LAT = 0x1;

    while(1)
    {
        RCSTAbits.OERR = 0x0;
        if(RCREG == 0xFF)
        {
            get_result(&results);
            send_config(&config);

            display(&results, &config);
            
            config.comp_open = 0x0;     //after requesting compensation/calibration clear the request bits
            config.comp_short = 0x0;
            config.do_the_cal = 0x0;
            if(tmp_resetnextcycle)      //wait one main loop cycle before reset (after getting turn_off) to allow for successfull sending the turn off request to main board
                asm ("RESET");
            if(config.turn_off)
                tmp_resetnextcycle = 1;
        }
        
        if(ui_state.keys == 0x00)
            locked = 0x0;
        
        if(SW2 && !locked && !g_shift)                  //select display format
        {
            locked = 0x1;
            ++ui_state.disp_format;
            if(ui_state.disp_format > 5)
                ui_state.disp_format = 0;
            leds_disp_format(ui_state.disp_format);
        }
        
        if(SW4 && !locked && !g_shift)                  //select display format
        {
            locked = 0x1;
            --ui_state.disp_format;
            if(ui_state.disp_format < 0)
                ui_state.disp_format = 5;
            leds_disp_format(ui_state.disp_format);
        }
        
        if(SW5 && !locked && !g_shift)                  //select frequency
        {
            locked = 0x1;
            ++config.fq_sel;
            if(config.fq_sel > 3)
                config.fq_sel = 0;
            leds_fq_sel(config.fq_sel);
        }
        
        if(SW7 && !locked && !g_shift)                  //select amplitude
        {
            locked = 0x1;
            ++config.amp_sel;
            if(config.amp_sel > 2)
                config.amp_sel = 0;
            leds_amp_sel(config.amp_sel);
        }
        
        if(SW5 && !locked && g_shift)                  //compensation open
        {
            locked = 0x1;
            config.comp_open = 0x1;
            g_shift = 0x0;
            leds_shift();
        }
        
        if(SW7 && !locked && g_shift)                  //compensation short
        {
            locked = 0x1;
            config.comp_short = 0x1;
            g_shift = 0x0;
            leds_shift();
        }
        
        if(SW2 && !locked && g_shift)                  //calibration
        {
            locked = 0x1;
            config.do_the_cal = 0x1;
            g_shift = 0x0;
            leds_shift();
        }
        
        if(SW6 && !locked)                  //set globa shift flag (alternative keys functions)
        {
            locked = 0x1;
            if(g_shift == 0x0)
                g_shift = 0x1;
            else
                g_shift = 0x0;
            leds_shift();
        }
        
        if(SW8 && !locked)                  //turn off
        {
            locked = 0x1;
            config.turn_off = 0x1;
        }
        
    }
    return;
}
