#include <xc.h>
#include <pic16f874.h>
// Defines
#define SYS_FREQ 20000000L //24 MHz overclock
//#define _XTAL_FREQ 24000000L
// Set configuration bits
// CONFIG1H
// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config CP = OFF         // FLASH Program Memory Code Protection bits (Code protection off)
#pragma config BOREN = OFF      // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF        // Low Voltage In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection (Code Protection off)
#pragma config WRT = OFF        // FLASH Program Memory Write Enable (Unprotected program memory may not be written to by EECON control)

#define GlcdDataBus      PORTB
#define GlcdControlBus   PORTD

#define GlcdDataBusDirnReg   TRISB
#define GlcdCtrlBusDirnReg   TRISD
/*
TRISAbits.TRISA0 = 0x00;
TRISAbits.TRISA1 = 0x00;
TRISAbits.TRISA2 = 0x00;
TRISAbits.TRISA3 = 0x00;
TRISAbits.TRISA4 = 0x00;
TRISBbits.TRISB0 = 0x00;
TRISBbits.TRISB1 = 0x00;
TRISBbits.TRISB2 = 0x00;
TRISBbits.TRISB3 = 0x00;
TRISBbits.TRISB4 = 0x00;
TRISCbits.TRISC0 = 0x00;
TRISCbits.TRISC1 = 0x00;
TRISCbits.TRISC2 = 0x00;
TRISCbits.TRISC3 = 0x00;
TRISCbits.TRISC4 = 0x00;
TRISDbits.TRISD0 = 0x00;
TRISDbits.TRISD1 = 0x00;
TRISDbits.TRISD2 = 0x00;
TRISDbits.TRISD3 = 0x00;
TRISDbits.TRISD4 = 0x00;
TRISEbits.IBF = 0x00;
TRISEbits.IBOV = 0x00;
TRISEbits.OBF = 0x00;
TRISEbits.PSPMODE = 0x00;
TRISEbits.TRISE0 = 0x00;
TRISEbits.TRISE1 = 0x00;
TRISEbits.TRISE2 = 0x00;
 ANSEL = 0x81;	//AN7 and AN0 enabled
ANSELH = 0x05;	//AN8 and AN10 enabled*/ // doesnt work







// LCD pins
#define RS     0//RE0
#define RW     1//RE1
#define EN     2//RE2
#define CS1    3//RA1
#define CS2    4//RA2



void delay(int cnt)
{
   int i;
    for(i=0;i<cnt;i++);
}

void Glcd_CmdWrite(char cmd)
{
    GlcdDataBus = cmd;           //Send the Command nibble
    GlcdControlBus &= ~(1<<RS);  // Send LOW pulse on RS pin for selecting Command register
    GlcdControlBus &= ~(1<<RW);  // Send LOW pulse on RW pin for Write operation
    GlcdControlBus |= (1<<EN);   // Generate a High-to-low pulse on EN pin
    delay(100);
    GlcdControlBus &= ~(1<<EN);

    delay(1000);
}

/* Function to send the Data to LCD */
void Glcd_DataWrite(char dat)
{
    GlcdDataBus = dat;           //Send the data on DataBus nibble
    GlcdControlBus |= (1<<RS);   // Send HIGH pulse on RS pin for selecting data register
    GlcdControlBus &= ~(1<<RW);  // Send LOW pulse on RW pin for Write operation
    GlcdControlBus |= (1<<EN);   // Generate a High-to-low pulse on EN pin
    delay(100);
    GlcdControlBus &= ~(1<<EN);

    delay(1000);
}


void Glcd_SelectPage0() // CS1=1, CS2=0
{
    GlcdControlBus |= (1<<CS1);
    GlcdControlBus &= ~(1<<CS2);
}

void Glcd_SelectPage1() // CS1=0, CS1=1
{
    GlcdControlBus &= ~(1<<CS1);
    GlcdControlBus |= (1<<CS2);
}


void Glcd_DisplayChar(const unsigned char *ptr_array)
{
    int i;
    for(i=0;i<512;i++) 
        Glcd_DataWrite(ptr_array[i]);
}

const unsigned char BME_logo_1 [] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xD0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xC0, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xE0, 0xF0, 0xF8, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD,
0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xE0, 0xFC, 0xFF, 0xC7, 0xFF, 0xFC, 0xE0, 0x00, 0x00, 0x00, 0x80, 0xC0,
0xE0, 0xF0, 0xF8, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0x13, 0x03, 0x03, 0x01, 0x03, 0x13, 0x13, 0x03, 0x03, 0x01,
0x03, 0x13, 0x13, 0x03, 0x03, 0x01, 0x9F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x05, 0x00, 0x06, 0x00, 0x02, 0x06, 0x06, 0x00, 0x00, 0x00, 0x0B, 0x13, 0x03, 0x0B,
0x03, 0x01, 0x01, 0x01, 0x03, 0x0B, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x0B, 0x0B, 0x03,
0x01, 0x01, 0x01, 0x03, 0x0B, 0x0B, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03, 0x0B, 0x03, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x3C, 0x24, 0x00, 0x00, 0x3C, 0x04, 0x3C, 0x24, 0x00,
0x00, 0x3C, 0x04, 0x3C, 0x24, 0x00, 0x40, 0x3C, 0x3C, 0x26, 0x00, 0x00, 0x3C, 0x3C, 0x24, 0x00,
0x00, 0x38, 0x3C, 0x3C, 0x00, 0x00, 0x38, 0x3C, 0x3C, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x00, 0x00,
0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x24,
0x3C, 0x3C, 0x00, 0x00, 0x26, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x3C,
0x3C, 0x00, 0x00, 0x00, 0x38, 0x38, 0x00, 0x38, 0x00, 0x38, 0x38, 0x00, 0x00, 0x00, 0xFD, 0x09,
0x20, 0xF8, 0xF8, 0xF8, 0xF0, 0x09, 0xFF, 0x00, 0xF0, 0xF8, 0xF8, 0xF0, 0x00, 0xFD, 0x09, 0xF0,
0xF8, 0xF8, 0xF8, 0xF0, 0x09, 0xFF, 0x00, 0xF0, 0xF8, 0xF8, 0xF0, 0x00, 0xFF, 0x09, 0xF0, 0xF8,
};

const unsigned char BME_logo_2 [] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x1E, 0x10, 0x00, 0x00, 0x1E, 0x00, 0x1E, 0x10, 0x00,
0x00, 0x1E, 0x00, 0x1E, 0x10, 0x00, 0x01, 0x1E, 0x1E, 0x10, 0x00, 0x00, 0x1E, 0x1E, 0x10, 0x00,
0x00, 0x1E, 0x1E, 0x10, 0x00, 0x00, 0x1E, 0x1E, 0x11, 0x00, 0x00, 0x1F, 0x1E, 0x13, 0x00, 0x00,
0x13, 0x1E, 0x1F, 0x00, 0x00, 0x11, 0x1E, 0x1E, 0x00, 0x00, 0x10, 0x1E, 0x1E, 0x00, 0x00, 0x10,
0x1E, 0x1E, 0x00, 0x00, 0x10, 0x1E, 0x1E, 0x00, 0x00, 0x00, 0x1E, 0x1E, 0x00, 0x00, 0x00, 0x1E,
0x1E, 0xE0, 0x10, 0x00, 0x1E, 0x1E, 0x10, 0x9E, 0x10, 0x9E, 0x1E, 0x00, 0x10, 0x00, 0x2F, 0x20,
0x18, 0x1F, 0x1F, 0x1F, 0x1F, 0x20, 0x2F, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x2F, 0x20, 0x1F,
0x1F, 0x1F, 0x1F, 0x1F, 0x20, 0x2F, 0x00, 0x1F, 0x1F, 0x1F, 0x1F, 0x00, 0x2F, 0x20, 0x1F, 0x1F,
0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x00, 0xE7, 0x04, 0x00, 0x00, 0xE7, 0x00, 0xE7, 0x04, 0x00,
0x00, 0xE7, 0x00, 0xE7, 0x00, 0x00, 0x10, 0x17, 0x07, 0x04, 0x00, 0x00, 0x17, 0x07, 0x04, 0x00,
0x00, 0x17, 0x07, 0x17, 0x00, 0x00, 0x17, 0x07, 0x17, 0x00, 0x00, 0x17, 0x07, 0x17, 0x00, 0x00,
0x17, 0x07, 0x17, 0x00, 0x00, 0x17, 0x07, 0x17, 0x00, 0x00, 0x17, 0x07, 0x17, 0x00, 0x00, 0x04,
0x07, 0x17, 0x00, 0x00, 0x04, 0x07, 0x17, 0x00, 0x00, 0x00, 0x07, 0x17, 0x00, 0x00, 0x00, 0x17,
0x07, 0x14, 0x00, 0x00, 0x67, 0x67, 0x00, 0x67, 0x00, 0x67, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x39, 0x21, 0x39, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x7F, 0x7F, 0x7E, 0x00, 0x00, 0x00, 0x7E,
0x7F, 0x7F, 0x7F, 0x7E, 0x00, 0x00, 0x00, 0x7E, 0x7F, 0x7F, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x39,
0x01, 0x01, 0x01, 0x81, 0x81, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81, 0x81, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81, 0x01, 0x21, 0x11, 0x11, 0x81, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81, 0x81, 0x81, 0x81, 0x81, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81, 0x81, 0x01, 0x01, 0x01, 0x01, 0x81,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81, 0x81, 0x81, 0x81, 0x81,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81, 0x81, 0x81, 0x81, 0x81,
0x81, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x81, 0x81, 0x81, 0x81,
0x00, 0x00, 0x00, 0x7F, 0x03, 0x07, 0x38, 0x60, 0x1C, 0x03, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x80, 0x80, 0x40, 0x3F, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x4D, 0x04, 0x04, 0x4C, 0x41, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x41, 0x00, 0x80, 0x40, 0x79, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x78, 0x0C, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x40, 0x04, 0x4C, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x44, 0x04, 0x4C
};

//ADCON0 = 0b01000001;

void main(void) {
    GlcdDataBusDirnReg = 0x00;  // Configure all the LCD pins as output
    GlcdCtrlBusDirnReg = 0x00;  // Configure the Ctrl pins as output

    /* Select the Page0/Page1 and Turn on the GLCD */
    Glcd_SelectPage0();
    Glcd_CmdWrite(0x3f);
    Glcd_SelectPage1();
    Glcd_CmdWrite(0x3f);
    delay(100);

    /* Select the Page0/Page1 and Enable the GLCD */
    Glcd_SelectPage0();
    Glcd_CmdWrite(0xc0);
    Glcd_SelectPage1();
    Glcd_CmdWrite(0xc0);
    delay(100);
    
    

    Glcd_SelectPage0(); // BME_logo_1
    Glcd_CmdWrite(0xb8);
    Glcd_DisplayChar(BME_logo_1);
    delay(100);

    Glcd_SelectPage1(); // BME_logo_2
    Glcd_CmdWrite(0xb8);
    Glcd_DisplayChar(BME_logo_2);

    while(1);
    return;
}