/****************************************************************************/
/* Copyright 2010 MBARI.                                                    */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/

#include <p24fxxxx.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "delay.h"

#define RS_HIGH()        LATDbits.LATD4 = 1
#define RS_LOW()         LATDbits.LATD4 = 0

#define E_HIGH()         LATDbits.LATD5 = 1
#define E_LOW()          LATDbits.LATD5 = 0

//#define MR_HIGH()        LATBbits.LATB0 = 1
//#define MR_LOW()         LATBbits.LATB0 = 0

#define LCD4          LATEbits.LATE4
#define LCD5          LATEbits.LATE5
#define LCD6          LATEbits.LATE6
#define LCD7          LATEbits.LATE7

/*
 Functions above this line must be redefined for
 your particular PICmicro-to-LCD interface
*/

//Configure 4-bit data bus for output
/*void configBusAsOutLCD(void) {
  RW_LOW();                  //RW=0 to stop LCD from driving pins
 
}

//Configure 4-bit data bus for input
void configBusAsInLCD(void) {
 
  RW_HIGH();                   // R/W = 1, for read
}*/

//Output lower 4-bits of u8_c to LCD data lines
void outputToBusLCD(int u8_c)
{
    LCD4 =  u8_c & 0x01;          //D4
    LCD5 = (u8_c >> 1)& 0x01;    //D5
    LCD6 = (u8_c >> 2)& 0x01;    //D6
    LCD7 = (u8_c >> 3)& 0x01;    //D7
}

//Configure the control lines for the LCD
void configControlLCD(void) 
{

    //RW_LOW();
    Nop();
    Nop();
    Nop();
    Nop();
    E_LOW();
    Nop();
    Nop();
    Nop();
    Nop();
    RS_LOW();
    Nop();
    Nop();
    Nop();
    Nop();
}

//Pulse the E clock, 1 us delay around edges for
//setup/hold times
void pulseE(void) 
{
    Nop();
    E_HIGH();
    Nop();
    Nop();
    E_LOW();
    Nop();
}

/* Write a byte (u8_Cmd) to the LCD.
u8_DataFlag is '1' if data byte, '0' if command byte
u8_Send8Bits is '1' if must send all 8 bits, else send only upper 4-bits
*/
void writeLCD(int u8_Cmd, int u8_DataFlag, int u8_Send8Bits) 
{
    delay_ms(1); // don't use busy, just delay

    //configBusAsOutLCD();
    if (u8_DataFlag) RS_HIGH();   // RS=1, data byte
    else    RS_LOW();             // RS=0, command byte
    outputToBusLCD(u8_Cmd >> 4);  // send upper 4 bits
    pulseE();
    if (u8_Send8Bits)
    {
        outputToBusLCD(u8_Cmd);     // send lower 4 bits
        pulseE();
    }
}

// Initialize the LCD, modify to suit your application and LCD
void initLCD(void) 
{
    outputToBusLCD(0x00);
    delay_ms(500);          //wait for device to settle
    writeLCD(0x30,0,1); // command 0x30 = Wake up
    delay_ms(350);
    writeLCD(0x30,0,1); // command 0x30 = Wake up
    delay_us(260);
    writeLCD(0x30,0,1); // command 0x30 = Wake up
    delay_us(260);
    writeLCD(0x20,0,1); // 4 bit interface
    delay_us(160);
    writeLCD(0x20,0,1); // 4 bit interface
    delay_us(160);

    writeLCD(0x28,0,1); // Function set: 4-bit/2-line
    Nop();
    writeLCD(0x01,0,1); // Clear
    Nop();
    writeLCD(0x10,0,1); // Set cursor
    Nop();
    writeLCD(0x0C,0,1); // Display ON; Blinking cursor off
    Nop();
    writeLCD(0x06,0,1); // Entry Mode set

    delay_ms(1);
}

//Output a string to the LCD
void outStringLCD(char *psz_s) 
{
    int i = 0;

    while ((*psz_s) && (++i < 50))
    {
        writeLCD(*psz_s, 1,1);
        psz_s++;
    }
}
//***************End of LCD Write**************/

