#include "Elmu.h"

/* ========================================== **
**                                            **
** ElmuLcd.c                                  **
**                                            **
** Auteur : Stephane Caron                    **
** Date :   Janvier 2006                      **
** Projet : PPE - ELMU                        **
**                                            **
**   Implementation de la commande d'un affi- **
** cheur  LCD  connecte  au  portb du  micro- **
** controleur.                                **
**                                            **
** ========================================== */

// ElmuLCDStart
// 
// Initialiser l'afficheur LCD.
// 
void ElmuLCDStart()
{
    ElmuLCDCommand(0x33);
    ElmuLCDCommand(0x32);
    ElmuLCDCommand(0x2c);
    ElmuLCDCommand(0x06);
    ElmuLCDCommand(0x0c);
    ElmuLCDClear();
}

// ElmuLCDRawSend
// 
// Envoyer une sequence d'informations a l'afficheur LCD.
// 
void ElmuLCDRawSend(char in, char mask)
{
    unsigned char pt;
    
    // On commence par envoyer un premier quartet d'informations
    // issu de la variable caractère en entrée.
    
    pt = ((in >> 4) & 0x0f) | mask;
    pt = pt | (portb & 0xc0);
    portb = pt;
    delay_ms(1);
    
    // On donne l'impulsion avant de passer au quartet suivant.
    
    set_bit(portb, 0x05);
    delay_ms(1);
    clear_bit(portb, 0x05);
    
    // Enfin, on envoye le dernier quartet d'informations, toujours
    // en appliquant un masque au caractère fourni en entrée.
    
    pt = (in & 0x0f) | mask;
    pt = pt | (portb & 0xc0);
    portb = pt;
    delay_ms(1);
    
    // Et on donne l'impulsion finale, suivie d'une temporisation.
    
    set_bit(portb, 0x05);
    delay_ms(1);
    clear_bit(portb, 0x05);
    delay_ms(1);
}

// ElmuLCDCommand
// 
// Envoyer une sequence ordre a l'afficheur.
// 
void ElmuLCDCommand(char cmd)
{
    ElmuLCDRawSend(cmd, 0);
}

// ElmuLCDClear
// 
// Effacer l'ecran de l'afficheur LCD.
// 
void ElmuLCDClear()
{
    ElmuLCDCommand(0x01);
    delay_ms(1);
    ElmuLCDCommand(0x02);
    delay_ms(1);
}

// ElmuLCDCursor
// 
// Deplacer le curseur de l'afficheur a la position (x,y).
// 
void ElmuLCDCursor(char x, char y)
{
    if (y == 0)
        y = 0x80;
    else // (y != 0)
        y = 0xc0;
    ElmuLCDCommand(y + x);
}

// ElmuLCDPrintASCII
// 
// Ecrire un caractere à l'écran de l'afficheur
// à la position actuelle du curseur.
// 
void ElmuLCDPrintASCII(char c)
{
    ElmuLCDRawSend(c, 0x10);
}

// ElmuLCDPrintNum
// 
// Ecrire un nombre à l'ecran de l'afficheur
// à la position actuelle du curseur.
// 
void ElmuLCDPrintNum(char num)
{
    // On commence par traiter le chiffre des centaines,
    // s'il y a lieu, ainsi que le suivant dans la foulée.
    
    if (((num / 100) % 10) != 0) {
        ElmuLCDRawSend(0x30 + ((num / 100) % 10), 0x10);
        ElmuLCDRawSend(0x30 + ((num / 10) % 10), 0x10);
    }

    // Sinon, s'il existe un chiffre des dizaines, il faut
    // le traiter de la même manière.
    
    else if (((num / 10) % 10) != 0)
        ElmuLCDRawSend(0x30 + ((num / 10) % 10), 0x10);
        
    // Et enfin, il y a toujours un chiffre des unités.
    
    ElmuLCDRawSend(0x30 + (num % 10), 0x10);
}

// ElmuLCDPrintString
// 
// Ecrire une chaîne de caractères à l'écran de
// l'afficheur depuis la position actuelle du curseur.
// 
void ElmuLCDPrintString(const char *str)
{
    char pos;
    for (pos = 0; str[pos] != 0; pos++)
        ElmuLCDPrintASCII(str[pos]);
}
