/* 
    lcd.c:		routines pour le carte Axiom CML912C32 
    Version:	1.0 / Février 2005
    Auteur:     Patrice Delpy     
*/


// fichier d'inclusion 
#include "..\ports_d256.h"
#include "lcd.h"

// Constantes
#define WR          0x20     	// lcd WR bit
#define RS          0x40     	// lcd RS bit
#define EN          0x80		// lcd EN bit
#define LCD_delai   0x200	 	// ajuster cette valeur en fonction des performances de l'afficheur: plus important si on constate un clignotement

// Variables
extern unsigned char LCD_buffer // holds data and status bits sent to LCD
extern unsigned char LCD_statut	// holds LCD status

// Prototypes
void LCD_init();
void LCD_put_string(char *sptr);
void LCDput_char(unsigned char datval);

/********************************************/
void LCD_tempo_nano(unsigned int val)
{
    while(val > 0)
         { val--;
         }
}
/********************************************/
void LCD_tempo_micro(unsigned int val)
{
    while(val > 0)
         { val--;;
           LCD_tempo2(LCD_delai);
         }
}
/********************************************/
void LCD_envoi()
{
    LCD_tempo_micro(1);
    LCD_statut = SPI0SR;				// lecture du registre d'état = remise à 0
    SP0DR = LCD_buffer; 				// envoie l'octet

    do{ // attendre la fin du traitement : le flag passe à 1
        LCD_statut = SPI0SR;
      }while(LCD_statut < 0x80);

    LCD_statut = SP0DR;		    		// reception de l'octet
}
/********************************************/
void lcd_ecrire_4bits(char LCDdata)
{
    // merge lower 4 bits of LCDdata with upper 4 bits of LCDBuf (control bits)
    LCD_buffer &= 0xF0;
    LCD_buffer |= LCDdata;

    LCD_buffer &= ~EN;  				// enable low
    LCD_envoi();  						// send the data
    LCD_buffer |= EN;  					// enable high
    LCD_envoi();  						// send the data
    LCD_buffer &= ~EN;  				// enable low
    LCD_envoi();  						// send the data
}
/********************************************/
void lcd_ecrire_tempo(char LCDdata)
{
    lcd_ecrire_4bits(LCDdata);
    LCD_tempo_micro(50);
}
/********************************************/
void LCD_ecrire_8bits(unsigned char lcdval)
{
    lcd_ecrire_4bits(lcdval >> 4);      // envoi les bits de poids fort
    lcd_ecrire_4bits(lcdval & 0x0F);    // les 4 bits de poids faible 
}
/********************************************/
void lcd_commande(unsigned char cmdval)
{
    LCDBuf &= ~RS; 						// clear RS to select LCD Command mode
    LCD_ecrire_8bits(cmdval);
    LCD_tempo_micro(10);
}
/********************************************/
void LCD_put_char(unsigned char datval)
{
    LCDBuf |= RS; 						// set RS to select LCD Data mode
    LCD_ecrire_8bits(datval); 			// write a DATA byte to the LCD
}
/********************************************/
void LCD_put_string(char *sptr)
{
	// la chaine doit 
	
	while(*sptr)
	     {LCD_put_char(*sptr);
		  ++sptr;
	     }
}
/********************************************/
void LCD_init()
{
	// démarage de la liaison SPI
    SPI0CR1 = 0x52;				// active le module 
    SPI0CR2 = 0x10; 			// enable /SS
    SPI0BR = 0x00;			  	// set up Spi baud clock rate
    LCD_buffer = (WR + EN); 	// set WR and EN bits
    LCD_envoi();		  		// send status to LCD

    // initialise l'afficheur 
    LCD_buffer &= ~(RS + EN); 	// efface les bits RS et EN 
    LCD_envoi();				// send status to LCD

    LCD_tempo_micro(50);

    // passe en mode 4 bits 
    lcd_ecrire_tempo(3);  		// send 3
    lcd_ecrire_tempo(3);  		// send 3
    lcd_ecrire_tempo(3);  		// send 3
    lcd_ecrire_tempo(2);  		// send 2

    lcd_commande(0x2c);  		// 2x40 display  ------>>>> modification à faire pour 2*16
    lcd_commande(0x06);  		// display and cursor on
    lcd_commande(0x0e);  		// shift cursor right
    lcd_commande(0x01);  		// clear display and home cursor
    lcd_commande(0x80);

    LCD_buffer = 0; 			// Reset Lcd states to rest
    LCD_envoi(); 	 			// send status to LCD
}
/********************************************/

