//----------------------header files included-------------------------------------------------------------
#include <p18f4550.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//----------------------functions declared----------------------------------------------------------------
#define RS  PORTEbits.RE0
#define RW  PORTEbits.RE1
#define EN  PORTEbits.RE2
void myMsDelay (unsigned int time);			//1ms delay 
void cmdwrite();							//send instruction to LCD
void datawrite();							//send data to LCD
void lcd_initiate();						//initialize the LCD
void disp_num(unsigned int x);				//print numeric on LCD
void disp(char str[]);						//print character on LCD
//int eeprom_read(int address);				//read from eeprom
//void eeprom_write(int address, int data);	//write to eeprom
//-------------------------------------------------------------------------------------------------------
/*The following lines of code perform interrupt vector relocation to work with the USB
bootloader. These must be used with every application program to run as a USB application.*/
extern void _startup (void);
#pragma code _RESET_INTERRUPT_VECTOR = 0x1000
void _reset (void)
{
_asm goto _startup _endasm
}
#pragma code
#pragma code _LOW_INTERRUPT_VECTOR = 0x1018
void low_ISR (void)
{
}
#pragma code
#pragma code _HIGH_INTERRUPT_VECTOR = 0x1008
void high_ISR (void)
{
}
#pragma code
//------------------------delay routine of 1ms-----------------------------------------------------
void myMsDelay (unsigned int time)
{
	unsigned int i, j;
	for (i = 0; i < time; i++)
	for (j = 0; j < 710; j++);			//configured for 1ms at 12MHz
}
//------------------------command write routine----------------------------------------------------
void cmdwrite()
{
    RS=0;
    RW=0;
    EN=1;
    myMsDelay(1);
    RS=0;
    RW=0;
    EN=0;
    myMsDelay(1);
}
//------------------------data write routine-------------------------------------------------------
void datawrite()
{
    RS=1;
    RW=0;
    EN=1;
    myMsDelay(1);
    RS=1;
    RW=0;
    EN=0;
    myMsDelay(1);
}
//------------------------initial lcd configuration------------------------------------------------
void lcd_initiate()
{
    PORTD = 0x38; //set the lcd to 8-bit mode
    cmdwrite();
    myMsDelay(1);
    PORTD = 0x01; //clear lcd
    cmdwrite();
    myMsDelay(1);
    PORTD = 0x0C; //display set to on, cursor set to off
    cmdwrite();
    myMsDelay(1);
    PORTD = 0x80; //position to first row first column
    cmdwrite();
    myMsDelay(1);
}
//------------------------routine to display any numerical value-----------------------------------
void disp_num(unsigned int x)
{
    unsigned int num[8], i=0;
    if (x==0)
    {
	    PORTD=(48);
	    datawrite();
    }
    else
    {
	    while(x>0)
	    {
	        num[i] = x % 10;
	        x = x / 10;
	        i++;
	    }
	    while(i>0)
	    {
		    i--;
	        PORTD=(num[i]+48);
	        datawrite();
	    }
    }
}
//------------------------routine to display character value---------------------------------------
void disp(char str[])
{
    unsigned int i=0, l;
    l=strlen(str);
    while(i<l)
    {
        PORTD = str[i];
        datawrite();
        i++;
    }
}
//------------------------eeprom write function----------------------------------------------------
/*void eeprom_write(int address,int data)
{
    EEADR=address;               //Write address to the EEADR register
    EEDATA=data;                 //copy data to the EEDATA register for write to EEPROM location
    EECON1bits.EEPGD=0;          //Access data EEPROM memory
    EECON1bits.CFGS=0;           //Access flash program or data memory
    EECON1bits.WREN=1;           //Allow write to the memory
    INTCONbits.GIE=0;            //Disable global interrupt
    
    //below sequence in EECON2 Register is necessary to write data to EEPROM memory
    EECON2=0x55;
    EECON2=0xaa;
    
    EECON1bits.WR=1;             //Start writing data to EEPROM memory
    INTCONbits.GIE=1;            //Enable interrupt
    
    while(PIR2bits.EEIF==0);     //EEIF bit is set when write operation is completed
                                 //monitor this bit for write operation
    PIR2bits.EEIF=0;             //Reset EEIF for further write operation
}*/
//------------------------eeprom read funtion------------------------------------------------------
/*int eeprom_read(int address)
{
	EEADR=address;				// Read data at location 0x00
    EECON1bits.WREN=0;			// WREN bit is clear for Read operation
    EECON1bits.EEPGD=0;			// Access data EEPROM memory
    EECON1bits.RD=1;			// To Read data of EEPROM memory set RD=1
    return(EEDATA);
 }*/
//------------------------main function------------------------------------------------------------
void main(void)
{
	unsigned int i, a, address, data, read;	//integer variable declaration
	unsigned int date[]= {18,06,2019};
	char str1[]="SANDESH";				//character variable declaration
	char str2[]="-";					//character variable declaration
	char str3[]="  ";					//character variable declaration
	ADCON1 = 0x0E; 						//Configuring the PORTE pins as digital I/O
	TRISB=0xF0; 						// Configures RB7 - RB4 as inputs to which the switches are connected and RB3-R0 as ouputs to which LEDS are connected
	INTCON2bits.RBPU=0; 				// Enabling the weak internal pull-ups on PORTB
	TRISE = 0x00; 						//Configuring PORTE as output
	TRISD = 0x00; 						//Configuring PORTD as output
	lcd_initiate();						//initialize the LCD
//-------------------------Name and Date display---------------------------------------------------
	PORTD = 0x01; 						//clear screen
	cmdwrite();			
    PORTD = 0x80; 						//position to first row first column
    cmdwrite();
	disp(str1);							//display name
	PORTD = 0xC0; 						//position to second row first column
    cmdwrite();
	disp_num(date[0]);					//display date
	disp(str2);
	disp_num(date[1]);					//display month
	disp(str2);
	disp_num(date[2]);					//display year
//-------------------------------------------------------------------------------------------------
	while(1)
	{
		read = (PORTB & 0xF0)/16;		//read PORTB data
		PORTD = 0xCC; 					//position to second row eleventh column
	    cmdwrite();
    	disp_num(read);					//write PORTB data
    	disp(str3);
    	myMsDelay(1000);				//1s refresh delay
		//-----------------------write 8 bytes of data to memory-----------------------------------
		/*	for (i=0;i<8;i++)
			{
				address = i;					//generate address
				data = dat[i];
				eeprom_write(address,data);		//write data to memory
			}
		//-----------------------read 8 bytes of data from memory----------------------------------
			for (i=0;i<8;i++)
			{
				PORTD = 0xCA; 					//position to second row eleventh column
	    		cmdwrite();
				address = i;					//generate address
				data = eeprom_read(address);	//read data from memory
				disp_num(data);					//display data
				disp(str3);						//clean display area
				myMsDelay(5000);				//5 s delay
			}*/
	}
}
