/* This code was modified and taylored for use on a NetBurner MOD5234
 * for University of Alberta CMPE 401 lab sections 
 * Justin Smalley, 2008 */
 
/*****************************************************************************/ 
/********************** GUIDE TO USING LCD CLASS ***************************** 

	1) Connect the LCD hardware
	2) Check the pins defines in "pinmap.h" to match up with wiring.
		- Note that the pins must be initialized to gpio outside the class
	3) Construct class.
		Lcd myLcd();
	4) Call setup function: i.e.
		myLcd.setup();
	5) enjoy!  

	Useful Functionalities
	a) wraps around at the end of line
	b) '\n' (ASCII 10) will move to the next line
	c) display hex, decimal, octal and binary values
	
	Semaphores:
	The LCD uses a semaphore, which allows only one task to use it. 
	All public functions pend and post on the semaphore, and private functions do not
	Becuase of this, public functions only call private ones.

******************************************************************************/ 


#ifndef _LCD_H_
#define _LCD_H_

/********************* LCD USER DEFINES *************************************/

#define LCD_COLS		(COLUMN_40)

/******** Display Debug Information ***********/
//#define LCD_DEBUG(x) (x)
#define LCD_DEBUG(x)

/**** Echo Characters sent to LCD over serial *****/
#define LCD_ECHO(x) (x)
//#define LCD_ECHO(x)

//********************** LCD CLASS CONTROLS **********************************

/* List of available commands */
#define CMD_CLEAR		0x01
#define CMD_HOME		0x02
#define CMD_ENTRY_MODE	0x04
#define CMD_DISPLAY		0x08
#define CMD_SHIFT		0x10
#define CMD_FUNCTION	0x20
#define CMD_CGRAM_ADR	0x40
#define CMD_DGRAM_ADR	0x80

// Function constants passed to constructor, can be OR'd together
#define FUNCTION_8BIT	0x10 // enable 8 pin mode
#define FUNCTION_4BIT	0x00 // enable 4 pin mode (not supported)
#define FUNCTION_2LINE	0x08 // LCD has two lines, line two starts at addr 0x40
#define FUNCTION_1LINE	0x00 // LCD has one continues line
#define FUNCTION_5x11	0x04 // use 5x11 custom characters
#define FUNCTION_5x8	0x00 // use 5x8 custom characters

// CMD_DISPLAY parameters, can be OR'd together
#define DISPLAY_ON			0x04	// display on
#define DISPLAY_OFF			0x00	// display off
#define DISPLAY_CURSOR		0x02	// cursor on
#define DISPLAY_NOCURSOR	0x00	// cursor off
#define DISPLAY_BLINK		0x01	// cursor blink on
#define DISPLAY_NOBLINK		0x00	// curson blink off

// CMD_ENTRY_MODE parameters, can be OR'd together
#define ENTRY_CURSOR_INC	0x02 // increment cursor position
#define ENTRY_CURSOR_DEC	0x00 // decrement curson position
#define ENTRY_SHIFT			0x01 // shift entire display
#define ENTRY_NOSHIFT		0x00 // don't shift display

// CMD_SHIFT parameters, can be OR'd together
#define SHIFT_SCREEN	0x08 // shift display 
#define SHIFT_CURSOR	0x00 // shift cursor
#define SHIFT_RIGHT		0x04 // to the right
#define SHIFT_LEFT		0x00 // to the left

// number of Columns, to be used in constructor
#define COLUMN_40		40
#define COLUMN_24		24
#define COLUMN_20		20
#define COLUMN_10		10

// Defines for second parameter of print function other bases
#define BASE_16			0x10
#define BASE_8			0x08
#define BASE_4			0x04
#define BASE_2			0x02

// Defines for second parameter of print function for base 10
#define BASE_10			0x01
#define DISP_SIGNED		0x00
#define DISP_UNSIGNED	0x80

// Modes of Writing and Ram setting
#define MODE_WRITE 1
#define MODE_CTRL  0
#define MODE_DDRAM 1
#define MODE_CGRAM 0

class Lcd;

//********************* LCD CLASS *********************************************
class Lcd {
	
//******************* PROTECTED ***********************************************	
protected:
	
	unsigned char	position;		// current position of cursor
	unsigned char	ram_mode;		// = 1 if currently writing to ddram
	unsigned int	lcd_time_out;	// semaphore timeout time
	unsigned char	rs_status;		// current status of RS
	
	/* pulses the enable pin to signal the LCD to read data pins */
	void enable();
	
	/* print a character, and echo if enabled */
	void print_char(char data);
	
	/* Move the cursor to a given column and row.
	 * columns range from 0 to 39
	 * rows range from 0 to 3 */
	void move(unsigned char col, unsigned char row);
	
	/* Create a custom character:
	 * index: index in cgram to for new charactor. values are from 0 - 7
	 * data[]: an array of 8 bytes, containing the character data
	 */
	void define_char(unsigned short index, unsigned char data[]);
	
	/* changes modes for different actions
	 * rs: write = 0, ctrl = 1, reflecting the RS line
	 */
	void change_rs_mode(int rs);
	
	/* Sends bits to the lcd over data line*/
	void send(unsigned char data);
	
//*********************** PUBLIC *********************************************
public:

	OS_SEM		internal_sem;	//internal semaphore
	OS_SEM		external_sem;	//external semaphore

	//unsigned char CharBuffer[160];
	//unsigned char BlinkBuffer[160];
	
	/* Creates the Lcd class. 
	 * all lines are set to output and = 0
	 */
	Lcd();
	
	/* initialize LCD module.*/
	void Setup();
	
	/* Sets entry mode parameters.  Combination of ENTRY_* defines. */
	void EntryMode(unsigned char entry);
	
	/* Sets display mode parameters.  Combination of DISPAY_* defines. */
	void DisplayMode(unsigned char display);

	/* Sets cursor or display shift dehaviour.  Combination of SHIFT_* defines. */
	void ShiftMode(unsigned char shift);

	/* Clear the display. */
	void Clear();

	/* Move cursor to home position (top/left). */
	void Home();
	
	/* Move the cursor to a given column and row.
	 * columns range from 0 to 39
	 * rows range from 0 to 3 */
	void MoveCursor(unsigned char col, unsigned char row);

	/* Print an unsigned number with the chosen base */
	void Print(unsigned long n, int base);
	
	/* Print a single ASCII character to the LCD screen at the current cursor position. */
	void Print(char c);

	/* Print a string of ASCII characters to the LCD screen at the current cursor position. */
	void Print(char* str);
	
	/* Create a custom character: currently only works for char 0 to 7
	 * \param location in CGRAM of char
	 * \param data character data array */
	void DefineChar(unsigned short index, unsigned char data[]);
	
};

#endif

