#include <p18cxxx.h>
#include "lcd_4b.h"

#define RS 		LATDbits.LATD0
#define R_W 	LATDbits.LATD1
#define E  		LATDbits.LATD2
#define DATA	LATD


// Fonctions de gestion du LCD en mode 4 bits

void init_port_lcd (void)
{
	// LCD connecte au port D
	TRISD = 0;
	LATD = 0x00;
}

// Fonction permettant l affichage d un caractere
void lcd_car (unsigned char car)
{	
	tpo_us (200);
	RS = 1;
	R_W = 0;
	E = 0;
	
	DATA = ((car & 0xf0) | (DATA & 0x0f));		// Stockage des bits de poids fort de car dans DATA
	
	tpo_us (10);
	E = 1;
	tpo_us (10);
	E = 0;
	car <<= 4;

	DATA = ((car & 0xf0) | (DATA & 0x0f));		// Stockage des bits de poids faible de car dans DATA
	
	tpo_us (10);
	E = 1;
	tpo_us (10);
	E = 0;
}

// Fonction permettant l envoi d'une commande
void lcd_com (unsigned char commande)
{
	tpo_us (100);
	RS = 0;
	R_W = 0;
	E = 0;
	
	DATA = ((commande & 0xf0) | (DATA & 0x0f));

	tpo_us (10);
	E = 1;
	tpo_us (10);
	E = 0;
	commande <<= 4;
	
	DATA = ((commande & 0xf0) | (DATA & 0x0f));
	
	tpo_us (10);
	E = 1;
	tpo_us (10);
	E = 0;
}

// Fonction permettant l envoi d'une commande lors de l initialisation
void lcd_com_init (unsigned char commande)
{
	RS = 0;
	R_W = 0;
	E = 0;
	
	DATA = ((commande & 0xf0) | (DATA & 0x0f));
	
	tpo_us (10);
	E = 1;
	tpo_us (10);
	E = 0;
}

// 4-bit initialization
void init_lcd (void)
{
	tpo_ms (50);
	lcd_com_init (0x30);	// Function set
	tpo_ms (5);			
	lcd_com_init (0x30);	// Function set	
	tpo_us (150);		
	lcd_com_init (0x30);	// Function set
	tpo_us (150);		
	lcd_com_init (0x20);	// Function set	
	lcd_com (0x28);			// 4-bit interface, 4 display lines, 5x8 characters
	lcd_com (0x0C);			// Cursor off and display on
	lcd_com (0x01);			// Display clear
	lcd_com (0x06);			// Entry mode set
	tpo_ms (5);
}

// Fonction permettant l affichage d une chaine de caracteres
void lcd_str (unsigned char *str)
{
	unsigned char i=0;
	while(str[i]!= '\0')
	{
		lcd_car (str[i]);
		i++;
	}
}



// Fonctions de gestion du timer 0

void tpo_ms (unsigned short tmr_val)
{
	unsigned char data;

	T0CON = 0b00000100; 				// run in 16-bit timer, 1:32 prescale value
	tmr_val = 65535 - (375 * tmr_val);	 
		
	data = (tmr_val >> 8);

	TMR0H = data;
	TMR0L = tmr_val;
	T0CONbits.TMR0ON = 1;				// starts the timer
	
	while (INTCONbits.TMR0IF == 0);
	
	T0CONbits.TMR0ON = 0;				// stops the timer
	INTCONbits.TMR0IF = 0;
}

void tpo_us (unsigned short tmr_val)
{
	unsigned char data;

	T0CON = 0b00001000; 				// run in 16-bit timer, no prescaler
	tmr_val = 65535 - ( 12 * tmr_val);

	data = (tmr_val >> 8);

	TMR0H = data;
	TMR0L = tmr_val;	
	T0CONbits.TMR0ON = 1;				// starts the timer
	
	while (INTCONbits.TMR0IF == 0);
	
	T0CONbits.TMR0ON = 0;				// stops the timer
	INTCONbits.TMR0IF = 0;

}

