#include <p18f452.h>
#include <delays.h>

#pragma	config	OSC=HS, PWRT=ON, BOR=OFF, WDT=OFF, CCP2MUX=OFF, LVP=OFF, DEBUG=OFF
#pragma	config	CP0=OFF, CP1=OFF, CP2=OFF, CP3=OFF, CPB=OFF, CPD=OFF
#pragma	config	WRT0=OFF, WRT1=OFF, WRT2=OFF, WRT3=OFF, WRTB=OFF, WRTC=OFF, WRTD=OFF
#pragma	config	EBTR0=OFF, EBTR1=OFF, EBTR2=OFF, EBTR3=OFF, EBTRB=OFF

#define	Data		PORTD
#define	DataTris	TRISD
#define	Ctrl		PORTB
#define	CtrlTris	TRISB
#define	E_pin		PORTBbits.RB0
#define	E_pin_tris	DDRBbits.RB0
#define	RW_pin		PORTBbits.RB1
#define	RW_pin_tris	DDRBbits.RB1
#define	RS_pin		PORTBbits.RB2
#define	RS_pin_tris	DDRBbits.RB2

void init_mcu(void)
{
	RCON     = 0b00011111;	// no priority interrupt levels
	EECON1   = 0b00000100;	// access data eeprom memory, memory access, memory write enabled
	INTCON   = 0b00000000;	// all int disabled, perpherial int disabled, TMR0 overflow int disabled
							// external int disabled, portb int disabled
	INTCON2  = 0b10000000;	// portb pull-ups disabled
	INTCON3  = 0b00000000;	// low priority ext int 1 & 2, ext int 1 & 2 disabled
	PIR1     = 0b00000000;	// no peripherial ints occured
	PIR2     = 0b00000000;	// no peripherial ints occured
	PIE1     = 0b00000000;	// no peripherial ints allowed
	PIE2     = 0b00000000;	// no peripherial ints allowed
	IPR1     = 0b00000000;	// low priority peripherial ints
	IPR2     = 0b00000000;	// low priority peripherial ints
	T0CON    = 0b00001000;	// TMR0 stopped
	T1CON    = 0b00000000;	// TMR1 stopped
	T2CON    = 0b00000000;	// TMR2 stopped
	T3CON    = 0b00000100;	// TMR3 stopped
	CCP1CON  = 0b00000000;	// CCP disabled
	SSPSTAT  = 0b00000000;	// MSSP status clear
	SSPCON1  = 0b00000000;	// MSSP no collision, no overflow, disabled (pins as I/O)
	SSPCON2  = 0b00000000;	// everything disabled and iddle
	TXSTA    = 0b10000010;	// master mode, 8-bit, transmit disabled, async, low speed, empty shift reg
	RCSTA    = 0b00000000;	// serial port disabled, 8-bit, receiver disabled, no addr detection, no errors
	ADCON0   = 0b00000000;	// Fosc/2, ch0 selected, ADC OFF
	ADCON1   = 0b10000110;	// right justified, Fosc/2, all pins digital
	LVDCON   = 0b00000000;	// LVD OFF
		
	DataTris = 0b00000000;	// all outputs
	CtrlTris = 0b00000000;	// all outputs
}
void init_LCD(void)		// Clock is 4MHz; for other frequency the delays must be changed
{
	Data = 0x00;
	Ctrl = 0x00;
	
	Delay1KTCYx(100);	// Wait more than 30ms for LCD POR procedure
	RS_pin = 0;
	RW_pin = 0;
	Data = 0b00111000;	// 2 lines, 5x7 dots
	Delay1KTCYx(1);		// LCD gets the data
	E_pin = 1;
	Delay1KTCYx(1);
	E_pin = 0;
	Delay10TCYx(10);	// wait more than 39us
	RS_pin = 0;
	RW_pin = 0;
	Data = 0b00001100;	// display on, cursor off
	Delay1KTCYx(1);		// LCD gets the data
	E_pin = 1;
	Delay1KTCYx(1);
	E_pin = 0;
	Delay10TCYx(10);	// wait more than 39us
	RS_pin = 0;
	RW_pin = 0;
	Data = 0b00000001;	// display clear
	Delay1KTCYx(1);		// LCD gets the data
	E_pin = 1;
	Delay1KTCYx(1);
	E_pin = 0;
	Delay1KTCYx(10);	// wait more than 1.53ms	
	RS_pin = 0;
	RW_pin = 0;
	Data = 0b00000110;	// increment, shift cursor right
	Delay1KTCYx(1);		// LCD gets the data
	E_pin = 1;
	Delay1KTCYx(1);
	E_pin = 0;
	Delay1KTCYx(100);	// wait
}
void main( void )
{
	init_mcu();
	init_LCD();
	
	// write text to LCD
	RS_pin = 1;
	RW_pin = 0;
	Data = 0x35;	// "S"
	Delay1KTCYx(1);		// LCD gets the data
	E_pin = 1;
	Delay1KTCYx(1);
	E_pin = 0;
	Delay1KTCYx(10);	// wait
	
	Data = 0x00;
	Ctrl = 0x00;
	
	while (1)
	{
	}
} 
