/*********************************************************************
 *                Flowcode Graphical LCD Component Code
 *
 * File: PIC_gLCD.c
 *
 * (c) 2009 Matrix Multimedia Ltd.
 * http://www.matrixmultimedia.com
 *
 * Software License Agreement
 *
 * The software supplied herewith by Matrix Multimedia Ltd (the
 * “Company”) for its Flowcode graphical programming language is
 * intended and supplied to you, the Company’s customer, for use
 * solely and exclusively on the Company's products. The software
 * is owned by the Company, and is protected under applicable
 * copyright laws. All rights are reserved. Any use in violation
 * of the foregoing restrictions may subject the user to criminal
 * sanctions under applicable laws, as well as to civil liability
 * for the breach of the terms and conditions of this licence.
 *
 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 * Changelog:
 *
 *  date  | by | description
 * -------+----+-----------------------------------------------------
 * 240407 | ST | Created
 * 220108 | BR | Edited for GfxLCD
 * 300108 | ST | Minor edits to function names, etc.
 * 300108 | ST | Addition of pin info
 * 300108 | BR | Edited to include global color functions
 * 300108 | ST | Removed tabs, fixed a few errors & added extra properties
 * 010208 | BR | Edited Print fonts, Added DrawBox fill functionality
 * 040208 | ST | Removed "BackPlot" function and renamed "ForePlot" to "Plot"
 * 080408 | BR | Added PrintNumber Function
 * 230309 | BR | Moves private functions from Add Defines section
 * 130509 | BR | Added % definitions to DefinesCode section
 * 100909 | BR | Added HiTECH compatible defines
 * 200909 | BR | Fixed small bug with print string routine for HITECH
 * 280110 | BR | Updated to work with the EB057 GLCD module.
 * 290110 | BR | Fixed a window size bug with the EB043.
 * 040210 | BR | Added a S65 type display controller
 * 300410 | BR | fixed a problem where the ports were swapped on the EB057 module.
 * 020211 | BR | Fixed a bug where EB057 colour data was being output incorrectly
 * 020311 | BR | Added bit banged SPI support for the EB057 gLCD
 * 230311 | BR | Changed code to work for hitech and boostc without ifdefs
 * 190511 | BR | Added 4D Display Compatibility to standard functions
 ********************************************************************/

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

 Return & Parameter types:
   void
   char
   short
   char*

 Pin directions:
   0 = OUTPUT
   2 = INPUT
   3 = BIDIRECTIONAL

**********************************************************************

[Settings]
CLSID={2606B13A-2EA4-48AE-8A94-AE55337E6284}
IsAnalogue=0
MultipleAllowed=0
Description=Graphical LCD Flowcode Component

**********************************************************************

[Port]
DesiredPort=0
PortMandatory=0
SamePortAsID=0

[Pins]
Count=4
1=Reset / SDI
2=Chip Select
3=Clock / SCK
4=Data / SDO

[PinPort]
# PORTA = 0
# PORTB = 1
# PORTC = 2
# PORTD = 3
# PORTE = 4
1=0
2=0
3=0
4=0

[PinDesiredBit]
1=4
2=0
3=3
4=5

[PinDirection]
# DIR_INPUT = 2
# DIR_OUTPUT = 0
# DIR_BIDIRECTIONAL = 3
1=0
2=0
3=0
4=0

[PinMustUsePort]
# boolean
1=1
2=1
3=1
4=1

[SamePortAsPinX]
# -1 = any pin
# otherwise, the pin number
1=-1
2=0
3=0
4=0

[PinMustUsePin]
# boolean
1=1
2=1
3=1
4=1

[PinValue]
# boolean (0 = off, 1 = on)
1=0
2=0
3=0
4=0

**********************************************************************

[MacroNames]
Count=19
1=gLCD_Window
2=gLCD_SendByte
3=Init
4=Clear
5=Print
6=PrintNumber
7=Plot
8=DrawLine
9=DrawBox
10=SetForeColor
11=SetBackColor
12=SPI_Init
13=SPI_Send_Char
14=Set_Data_Direction
15=StrobeE
16=Update_Slave
17=CommandWithData
18=CommandWith2Data
19=ReceiveByte

[MacroReturns]
1=void
2=void
3=void
4=void
5=void
6=void
7=void
8=void
9=void
10=void
11=void
12=void
13=char
14=void
15=void
16=void
17=void
18=void
19=char

[MacroIsPrivate]
1=1
2=1
3=0
4=0
5=0
6=0
7=0
8=0
9=0
10=0
11=0
12=1
13=1
14=1
15=1
16=1
17=1
18=1
19=1

[MacroParameters_gLCD_Window]
Count=4
1=X1
2=Y1
3=X2
4=Y2

[MacroParamTypes_gLCD_Window]
1=char
2=char
3=char
4=char

[MacroParameters_gLCD_SendByte]
Count=2
1=Command
2=Lcdout

[MacroParamTypes_gLCD_SendByte]
1=char
2=unsigned int

[MacroParameters_Init]
Count=0

[MacroParamTypes_Init]


[MacroParameters_Clear]
Count=0

[MacroParamTypes_Clear]

[MacroParameters_Print]
Count=5
1=String
2=X
3=Y
4=Font
5=Transparent

[MacroParamTypes_Print]
1=char*
2=short
3=short
4=char
5=char

[MacroParameters_PrintNumber]
Count=5
1=Number
2=X
3=Y
4=Font
5=Transparent

[MacroParamTypes_PrintNumber]
1=short
2=short
3=short
4=char
5=char

[MacroParameters_Plot]
Count=2
1=X1
2=Y1

[MacroParamTypes_Plot]
1=short
2=short

[MacroParameters_DrawLine]
Count=4
1=X1
2=Y1
3=X2
4=Y2

[MacroParamTypes_DrawLine]
1=short
2=short
3=short
4=short

[MacroParameters_DrawBox]
Count=6
1=X1
2=Y1
3=X2
4=Y2
5=Transparent
6=Solid

[MacroParamTypes_DrawBox]
1=short
2=short
3=short
4=short
5=char
6=char

[MacroParameters_SetForeColor]
Count=3
1=Red
2=Green
3=Blue

[MacroParamTypes_SetForeColor]
1=char
2=char
3=char

[MacroParameters_SetBackColor]
Count=3
1=Red
2=Green
3=Blue

[MacroParamTypes_SetBackColor]
1=char
2=char
3=char

[MacroParameters_SPI_Init]
Count=0

[MacroParamTypes_SPI_Init]

[MacroParameters_SPI_Send_Char]
Count=1
1=Char

[MacroParamTypes_SPI_Send_Char]
1=char

[MacroParameters_Set_Data_Direction]
Count=1
1=mode

[MacroParamTypes_Set_Data_Direction]
1=char

[MacroParameters_StrobeE]
Count=0

[MacroParamTypes_StrobeE]

[MacroParameters_Update_Slave]
Count=0

[MacroParamTypes_Update_Slave]

[MacroParameters_CommandWithData]
Count=2
1=Command
2=Data

[MacroParamTypes_CommandWithData]
1=char
2=char

[MacroParameters_CommandWith2Data]
Count=3
1=Command
2=Data1
3=Data2

[MacroParamTypes_CommandWith2Data]
1=char
2=char
3=char

[MacroParameters_ReceiveByte]
Count=1
1=nTimeout

[MacroParamTypes_ReceiveByte]
1=char


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

/********************************************************************
 * ADDITIONAL CODE
 ********************************************************************/

/*DefinesCode_Start*/

/**** Macro Substitutions ****
%a = gLCD Port Register
%b = gLCD Data Direction Register
%c = Reset Pin
%d = Chip Select Pin
%e = Serial Clock Pin
%f = Serial Data Pin
%g = Default Background Colour
%h = Default Foreground Colour
%i = Size of display
%j, %k, %l, %m, %n, %o, %p, %q = ASCII Pixel data
%r = LCD Type
%s = software / hardware SPI - Currently unused
******************************/

#include <string.h>

//Common Defines
#define MX_GFXLCD_PORT       %a            //portc   I/O port
#define MX_GFXLCD_TRIS       %b            //trisc   I/O direction register
#define MX_GFXLCD_RS         %c            //3       Reset
#define MX_GFXLCD_CS         %d            //2       Chip Select
#define MX_GFXLCD_SCLK       %e            //1       Serial Clock
#define MX_GFXLCD_SDATA      %f            //0       Serial Data
#define MX_GFXLCD_BCOL       %g            //255     Background Color - White
#define MX_GFXLCD_FCOL       %h            //0       Foreground Color - Black
#define MX_GFXLCD_SIZE       %i            //0       0 = 132x132
#define MX_GFXLCD_TYPE	 	 %r			   //0       0 = EB043, 1 = EB057, 2 = EB043v2, 3 = Goldelox, 4 = Picaso

#if MX_GFXLCD_TYPE < 3					//Standard Display Controllers
	#ifdef _BOOSTC						//ASCII Pixel data BoostC
		rom char* ASCII1 =
		%j
		rom char* ASCII2 =
		%k
		rom char* ASCII3 =
		%l
		rom char* ASCII4 =
		%m
		rom char* ASCII5 =
		%n
		rom char* ASCII6 =
		%o
		rom char* ASCII7 =
		%p
		rom char* ASCII8 =
		%q
	#endif

	#ifdef HI_TECH_C					//ASCII Pixel data HiTech
		const char ASCII1[] =
		%j
		const char ASCII2[] =
		%k
		const char ASCII3[] =
		%l
		const char ASCII4[] =
		%m
		const char ASCII5[] =
		%n
		const char ASCII6[] =
		%o
		const char ASCII7[] =
		%p
		const char ASCII8[] =
		%q
	#endif

	#define MX_GFXLCD_CMD       0        //A "0" tells the display: now a Command is following
	#define MX_GFXLCD_PARAM     1        //A "1" tells the display: now a Parameter is following

	#if MX_GFXLCD_TYPE == 0				//EB043 ONLY
		char DataInit[20] = {0x00,0x02,0x04,0x06,0x09,0x0B,0x0D,0x0F,0x00,0x02,0x04,0x06,0x09,0x0B,0x0D,0x0F,0x00,0x04,0x0B,0x0F};	//Color Data
		char GFX_Fore_Color = MX_GFXLCD_FCOL;
		char GFX_Back_Color = MX_GFXLCD_BCOL;
	#endif

	#if MX_GFXLCD_TYPE == 1				//EB057 ONLY

		#define MX_GFXLCD_BUS		0					//0 - Hw / 1 - Sw

		short GFX_Fore_Color;
		short GFX_Back_Color;
		#define DDR		0x00			//I2C I/O Expander Command Defines
		#define PORT	0x12
		#define CONF	0x0A
		#define EN		0x01			//Pin Definitions  -- These have changed BR 05 05 10
		#define RW		0x02
		#define RS		0x04
		#define CS		0x08
		#define RESET	0x10
		char Data = 0;					//global variables
		char Control = RESET | CS;
		#define LCD_Data		Control = Control | RS;			//Set DC			//LCD Command Defines
		#define LCD_Command		Control = Control & ~RS;		//Clear DC
		#define LCD_Read		Control = Control | RW;			//Set DC
		#define LCD_Write		Control = Control & ~RW;		//Clear DC
		#if MX_GFXLCD_BUS == 0
			#define SPI_SSPM 	0			//SPI COMPONENT DEFINES
			#define SPI_CKP 	0
			#define SPI_CKE 	64
			#define SPI_SMP 	0
			#ifdef MX_SPI_B
				#define SPI_CS_TRIS		trisb
				#define SPI_CS_PORT		portb
			#endif
			#ifdef MX_SPI_C
				#define SPI_CS_TRIS		trisc
				#define SPI_CS_PORT		portc
			#endif
			#ifdef MX_SPI_BCB
				#define SPI_CS_TRIS		trisb
				#define SPI_CS_PORT		portb
			#endif
		#else
			#define SPI_CS_TRIS		MX_GFXLCD_TRIS
			#define SPI_CS_PORT		MX_GFXLCD_PORT
		#endif
	#endif

	#if MX_GFXLCD_TYPE == 2			//EB043 v2 ONLY
		char GFX_Fore_Color = MX_GFXLCD_FCOL;
		char GFX_Back_Color = MX_GFXLCD_BCOL;
	#endif

#else				//4D Display controllers

	#define MX_GLCD_UART		1

	#if (MX_GLCD_UART == 0)
		#define MX_GLCD_RX_PORT
		#define MX_GLCD_RX_TRIS
		#define MX_GLCD_SW_RX
		#define MX_GLCD_SW_TX
		#define MX_GLCD_TX_PORT
		#define MX_GLCD_TX_TRIS
	#else
		#define MX_GLCD_TXSTA_VAL  	4
		#define MX_GLCD_SPBRG_VAL  	127
		#define MX_GLCD_SW_BAUD		0
	#endif

	#define MX_GLCD_STATUS_LOOP		0
	#define MX_GLCD_STATUS_TIMEOUT	1
	#define MX_GLCD_STATUS_RXBYTE	2

	short GFX_Fore_Color;
	short GFX_Back_Color;

#endif

/*DefinesCode_End*/

/*InitialisationCode_Start*/
/*InitialisationCode_End*/

/*InterruptCode_Start*/
/*InterruptCode_End*/

/********************************************************************
 * FUNCTIONS
 ********************************************************************/

//------------------------------------------------------------------------------
//Open output windows with coordinatex x1,y1 and x2,y2
//------------------------------------------------------------------------------
void gLCD_Window (short X1, short Y1, short X2, short Y2)
{
/*Macro_gLCD_Window_Start*/

	#if MX_GFXLCD_TYPE == 2

		gLCD_SendByte(MX_GFXLCD_CMD, 0xEF90);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0500);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0800 | X1);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0900 | X2);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0A00 | Y1);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0B00 | Y2);

	#endif

	#if MX_GFXLCD_TYPE < 2

		gLCD_SendByte(MX_GFXLCD_CMD, 0x2A);        //Column adress
		gLCD_SendByte(MX_GFXLCD_PARAM, X1);        //X-Position upper left corner
		gLCD_SendByte(MX_GFXLCD_PARAM, X2);        //y-Position upper left corner
		gLCD_SendByte(MX_GFXLCD_CMD, 0x2B);        //Page adressing
		gLCD_SendByte(MX_GFXLCD_PARAM, Y1);        //x-Position of lower right corner
		gLCD_SendByte(MX_GFXLCD_PARAM, Y2);        //y-Position of lower right corner
		gLCD_SendByte(MX_GFXLCD_CMD, 0x2C);

	#endif

/*Macro_gLCD_Window_End*/
}


//-------------------------------------------------------------------------------
//Send Commands or MX_GFXLCD_PARAMeter or data byte
//-------------------------------------------------------------------------------
void gLCD_SendByte (char Command, unsigned int Lcdout)
{
/*Macro_gLCD_SendByte_Start*/

   #if MX_GFXLCD_TYPE == 0									//EB043 ONLY
		char i;
		clear_bit(MX_GFXLCD_PORT, MX_GFXLCD_CS);              //MX_GFXLCD_CS 0 start of sequence
		clear_bit(MX_GFXLCD_PORT, MX_GFXLCD_SCLK);            //Clock 0
		if (Command == MX_GFXLCD_CMD)
			clear_bit(MX_GFXLCD_PORT, MX_GFXLCD_SDATA);       //0 = MX_GFXLCD_CMD
		else
			set_bit(MX_GFXLCD_PORT, MX_GFXLCD_SDATA);         //1 = MX_GFXLCD_PARAMeter
		set_bit(MX_GFXLCD_PORT, MX_GFXLCD_SCLK);
		for (i=0;i<8;i++)
		{
			clear_bit(MX_GFXLCD_PORT, MX_GFXLCD_SCLK);        //Clock 0
			if (Lcdout & 0x80)
				set_bit(MX_GFXLCD_PORT, MX_GFXLCD_SDATA);     //Output MSB
			else
				clear_bit(MX_GFXLCD_PORT, MX_GFXLCD_SDATA);
			set_bit(MX_GFXLCD_PORT, MX_GFXLCD_SCLK);          //Clock 1
			Lcdout = Lcdout << 1;                             //Shift Data to left
		}
		set_bit(MX_GFXLCD_PORT, MX_GFXLCD_CS);                //MX_GFXLCD_CS to 1 at end of sequence
	#endif

	#if MX_GFXLCD_TYPE == 1									//EB057 ONLY
		if (Command == MX_GFXLCD_CMD)
			LCD_Command;
		else
			LCD_Data;
		LCD_Write;
		Data = Lcdout;
		StrobeE();
	#endif

	#if MX_GFXLCD_TYPE == 2									//EB043 v2 ONLY
		char i, j;
		unsigned int mask;
		if (Command == MX_GFXLCD_CMD)
		{
			set_bit(MX_GFXLCD_PORT, MX_GFXLCD_RS);       	  //1 = MX_GFXLCD_CMD
			j = 16;
			mask = 0x8000;
		}
		else
		{
			clear_bit(MX_GFXLCD_PORT, MX_GFXLCD_RS);          //0 = MX_GFXLCD_PARAMeter
			j = 8;
			mask = 0x80;
		}
		clear_bit(MX_GFXLCD_PORT, MX_GFXLCD_CS);              //MX_GFXLCD_CS 0 start of sequence
		for (i=0;i<j;i++)
		{
			clear_bit(MX_GFXLCD_PORT, MX_GFXLCD_SCLK);        //Clock 0
			if (Lcdout & mask)
				set_bit(MX_GFXLCD_PORT, MX_GFXLCD_SDATA);     //Output MSB
			else
				clear_bit(MX_GFXLCD_PORT, MX_GFXLCD_SDATA);
			set_bit(MX_GFXLCD_PORT, MX_GFXLCD_SCLK);          //Clock 1
			Lcdout = Lcdout << 1;                             //Shift Data to left
		}
		set_bit(MX_GFXLCD_PORT, MX_GFXLCD_CS);                //MX_GFXLCD_CS to 1 at end of sequence
	#endif

	#if MX_GFXLCD_TYPE > 2										//4D Displays

		#if (MX_GLCD_UART == 0)
			char dMask;
			char idx;
			char count = 8;
			clear_bit( MX_GLCD_TX_PORT, MX_GLCD_SW_TX);			// Send Start bit
			delay_us(52);										// 19200 Baud Bit Period
			for (idx = 0; idx < count; idx++)
			{
				dMask = Command & 0x01;							// Mask off data bit
				if (dMask)
					set_bit( MX_GLCD_TX_PORT, MX_GLCD_SW_TX);
				else
					clear_bit( MX_GLCD_TX_PORT, MX_GLCD_SW_TX);
				delay_us(52);									// 19200 Baud Bit Period
				Command = Command >> 1;							// Move to next data bit
			}
			set_bit( MX_GLCD_TX_PORT, MX_GLCD_SW_TX);			// Send Stop bit
			delay_us(52);										// 19200 Baud Bit Period
		#endif

		#if (MX_GLCD_UART == 1)
			#ifndef MX_UART
				#error "Chip does not have second UART capability"
			#endif
			while (ts_bit(pir1, TXIF) == 0);
			txreg = Command;
		#endif

		#if (MX_GLCD_UART == 2)
			#ifndef MX_UART2
				#error "Chip does not have second UART capability"
			#endif
			while (ts_bit(pir3, TX2IF) == 0);
			txreg2 = Command;
		#endif
	#endif

/*Macro_gLCD_SendByte_End*/
}


//-------------------------------------------------------------------------------
//Initializing of the display
//-------------------------------------------------------------------------------
void Init (void)
{
/*Macro_Init_Start*/

	#if MX_GFXLCD_TYPE == 0								//EB043 ONLY
		char i;
		clear_bit(MX_GFXLCD_TRIS, MX_GFXLCD_RS);       	//Configure I/O
		clear_bit(MX_GFXLCD_TRIS, MX_GFXLCD_CS);
		clear_bit(MX_GFXLCD_TRIS, MX_GFXLCD_SDATA);
		clear_bit(MX_GFXLCD_TRIS, MX_GFXLCD_SCLK);
		clear_bit(MX_GFXLCD_PORT, MX_GFXLCD_RS);       //Reset LCD
		delay_ms(10);                                  //Always wait after a Reset
		set_bit(MX_GFXLCD_PORT, MX_GFXLCD_RS);         //Startup LCD
		set_bit(MX_GFXLCD_PORT, MX_GFXLCD_CS);         //Select LCD
		set_bit(MX_GFXLCD_PORT, MX_GFXLCD_SDATA);      //Set Data Pin High
		set_bit(MX_GFXLCD_PORT, MX_GFXLCD_SCLK);       //Set Clock Pin High
		gLCD_SendByte(MX_GFXLCD_CMD, 0x01);
		delay_ms(10);                                  //Wait after Reset
		gLCD_SendByte(MX_GFXLCD_CMD, 0x11);            //Sleep Out
		delay_ms(40);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x29);            //Display On
		delay_ms(40);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x3A);            //Interface Pixel Format....
		gLCD_SendByte(MX_GFXLCD_PARAM, 0x02);          //....data format: 8 bit for each Pixel
		gLCD_SendByte(MX_GFXLCD_CMD, 0x20);            //No inveMX_GFXLCD_RSion, 0x21 would be inverted display (different coloMX_GFXLCD_RS!)
		gLCD_SendByte(MX_GFXLCD_CMD, 0x2D);            //RGB-Table for the 256 out of 4096 color mode
		for (i=0;i<20;i++)
		{
			gLCD_SendByte(MX_GFXLCD_PARAM, DataInit[i]);    //read predefined color table for 256 color mode
		}
	#endif

	#if MX_GFXLCD_TYPE == 1								//EB057 Only
		char Red, Green, Blue;
		GFX_Fore_Color = MX_GFXLCD_FCOL;
		GFX_Back_Color = MX_GFXLCD_BCOL;
		Green = (GFX_Fore_Color >> 2) & 0x07;			//Convert Foreground to 16-bit colour
		Green = Green << 2;
		Red = (GFX_Fore_Color >> 5) & 0x07;
		Red = Red << 3;
		Blue = (GFX_Fore_Color) & 0x03;
		Blue = Blue << 3;
		GFX_Fore_Color = Blue | (Green << 5);
		GFX_Fore_Color = GFX_Fore_Color | (Red << 11);
		Green = (GFX_Back_Color >> 2) & 0x07;			//Convert Background to 16-bit colour
		Green = Green << 2;
		Red = (GFX_Back_Color >> 5) & 0x07;
		Red = Red << 3;
		Blue = (GFX_Back_Color) & 0x03;
		Blue = Blue << 3;
		GFX_Back_Color = Blue | (Green << 5);
		GFX_Back_Color = GFX_Back_Color | (Red << 11);
		SPI_Init();										//Initialise SPI hardware
		delay_us(10);
		Set_Data_Direction(0);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x01);				//Software Reset
		delay_us(100);
		CommandWithData(0xFD, 0x12);					//Unlock Basic Commands
		CommandWithData(0xFD, 0xB3);					//Unlock Supplementary Commands
		gLCD_SendByte(MX_GFXLCD_CMD, 0x10);				//Sleep In
		CommandWithData(0xD2, 0x10);					//Set Display Clock
		CommandWithData(0xCA, 0x7F);					//Set Multiplex Ratio
		CommandWithData(0xC8, 0x00);					//Set Display Offset
		CommandWith2Data(0x36, 0x88, 0x01);				//Memory Access Control
		CommandWithData(0x3A, 0x05);					//Pixel Format
		CommandWithData(0x35, 0x00);					//Tearing Effect Line On
		CommandWithData(0xB3, 0x03);					//Function Selection
		CommandWithData(0xCC, 0xB0);					//-Enable External VSL
		CommandWithData(0xD6, 0x07);					//-High Power Protection
		CommandWithData(0xBA, 0x43);					//Set Contrast A
		CommandWithData(0xBB, 0x55);					//Set Contrast B
		CommandWithData(0xBC, 0x87);					//Set Contrast C
		CommandWith2Data(0xD1, 0x00, 0x00);				//-Set Contrast Compensation
		CommandWithData(0x51, 0xF0);					//Write Luminence
		CommandWithData(0xE3, 0x02);					//Grey Scale Enhance
		CommandWithData(0xCD, 0x32);					//Phase Length
		CommandWithData(0xBD, 0x09);					//Precharge Voltage
		CommandWith2Data(0xD0, 0x04, 0x3F);				//-Pre Charge Compensation
		CommandWithData(0xCE, 0x0B);					//2nd Precharge Period
		CommandWithData(0xCF, 0x03);					//2nd Precharge Speed
		CommandWithData(0xD3, 0x04);					//Set VCOMH
		gLCD_SendByte(MX_GFXLCD_CMD, 0x29);				//Disable Pixels On / Off
		gLCD_SendByte(MX_GFXLCD_CMD, 0x20);				//Display Inversion Off
		gLCD_SendByte(MX_GFXLCD_CMD, 0x13);				//Display Normal Mode
		gLCD_SendByte(MX_GFXLCD_CMD, 0x11);				//Sleep Out
		delay_ms(200);
	#endif

	#if MX_GFXLCD_TYPE == 2								//EB043 v2 Only
		clear_bit(MX_GFXLCD_TRIS, MX_GFXLCD_RS);       //Configure I/O
		clear_bit(MX_GFXLCD_TRIS, MX_GFXLCD_CS);
		clear_bit(MX_GFXLCD_TRIS, MX_GFXLCD_SDATA);
		clear_bit(MX_GFXLCD_TRIS, MX_GFXLCD_SCLK);
		delay_ms(10);
		set_bit(MX_GFXLCD_PORT, MX_GFXLCD_SCLK);       //Set Clock Pin High
		set_bit(MX_GFXLCD_PORT, MX_GFXLCD_RS);         //Command LCD
		set_bit(MX_GFXLCD_PORT, MX_GFXLCD_CS);         //Select LCD
		set_bit(MX_GFXLCD_PORT, MX_GFXLCD_SDATA);      //Set Data Pin High
		delay_ms(10);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xFDFD);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xFDFD);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xEF00);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xEE04);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x1B04);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xFEFE);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xFEFE);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xEF90);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x4A04);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x7F3F);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xEE04);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x4306);
		delay_ms(7);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xEF90);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0983);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0800);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0BAF);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0A00);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0500);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0600);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0700);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xEF00);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xEE0C);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xEF90);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0080);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xEFB0);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x4902);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xEF00);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x7F01);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xE181);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xE202);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xE276);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xE183);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x8001);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xEF90);
		gLCD_SendByte(MX_GFXLCD_CMD, 0x0000);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xEF90);
		gLCD_SendByte(MX_GFXLCD_CMD, 0xE801);
	#endif

	#if MX_GFXLCD_TYPE > 2										// 4D Displays Only
		char Red, Green, Blue;
		GFX_Fore_Color = MX_GFXLCD_FCOL;
		GFX_Back_Color = MX_GFXLCD_BCOL;
		Green = (GFX_Fore_Color >> 2) & 0x07;			//Convert Foreground to 16-bit colour
		Green = Green << 2;
		Red = (GFX_Fore_Color >> 5) & 0x07;
		Red = Red << 3;
		Blue = (GFX_Fore_Color) & 0x03;
		Blue = Blue << 3;
		GFX_Fore_Color = Blue | (Green << 5);
		GFX_Fore_Color = GFX_Fore_Color | (Red << 11);
		Green = (GFX_Back_Color >> 2) & 0x07;			//Convert Background to 16-bit colour
		Green = Green << 2;
		Red = (GFX_Back_Color >> 5) & 0x07;
		Red = Red << 3;
		Blue = (GFX_Back_Color) & 0x03;
		Blue = Blue << 3;
		GFX_Back_Color = Blue | (Green << 5);
		GFX_Back_Color = GFX_Back_Color | (Red << 11);
		clear_bit(MX_GFXLCD_TRIS, MX_GFXLCD_RS);       			//Configure I/O
		clear_bit(MX_GFXLCD_PORT, MX_GFXLCD_RS);       			//Reset LCD
		delay_us(10);                                  			//Wait for Reset
		set_bit(MX_GFXLCD_PORT, MX_GFXLCD_RS);         			//Startup LCD
		delay_ms(250);                                  		//Wait for Reset
		delay_ms(250);
		delay_ms(250);

		#if MX_GFXLCD_TYPE == 4
			delay_s(2);											//Extra 2 seconds delay for Picaso
		#endif


		#if (MX_GLCD_UART == 0)									// SW UART
			set_bit(MX_GLCD_RX_TRIS, MX_GLCD_SW_RX);			// Receive pin is a input
			clear_bit(MX_GLCD_TX_TRIS, MX_GLCD_SW_TX);			// Transmit pin is a output
			set_bit(MX_GLCD_TX_PORT, MX_GLCD_SW_TX);			// Transmit pin is default high
		#endif
		#if (MX_GLCD_UART == 1)									// HW UART 1
			txsta = MX_GLCD_TXSTA_VAL;   						// 8-bit, async, low speed, off
			spbrg = MX_GLCD_SPBRG_VAL;   						// set the baud rate
			rcsta = 0;                    						// 8-bit, disabled

			st_bit(rcsta, SPEN);         						// turn on serial interface
			st_bit(txsta, TXEN);
			st_bit(rcsta, CREN);
		#endif
		#if (MX_GLCD_UART == 2)									// HW UART 2

			txsta2 = MX_GLCD_TXSTA_VAL;   						// 8-bit, async, low speed, off
			spbrg2 = MX_GLCD_SPBRG_VAL;   						// set the baud rate
			rcsta2 = 0;                    						// 8-bit, disabled

			st_bit(rcsta2, SPEN);         						// turn on serial interface
			st_bit(txsta2, TXEN);
			st_bit(rcsta2, CREN);
		#endif

		ReceiveByte(10);
		ReceiveByte(10);

		gLCD_SendByte(0x55, 0);									// Send autobaud command
		ReceiveByte(255);										//Try to collect Ack

	#endif

	Clear();

/*Macro_Init_End*/
}



//------------------------------------------------------------------------------
//Configures the color of the foreground
//------------------------------------------------------------------------------
void SetForeColor (char Red, char Green, char Blue)
{
/*Macro_SetForeColor_Start*/

	#if MX_GFXLCD_TYPE == 1
		Red = Red >> 2;
		Green = Green >> 3;
		Blue = Blue >> 3;
		GFX_Fore_Color = Blue | (Green << 5);
		GFX_Fore_Color = GFX_Fore_Color | (Red << 11);
	#else
		#if MX_GFXLCD_TYPE < 3
			Red = Red >> 5;
			Green = Green >> 5;
			Blue = Blue >> 6;
			Green = Green << 2;
			Red = Red << 5;
			GFX_Fore_Color = (Blue | Red) | Green;
		#else
			char msb, lsb;
			Red = Red >> 3;
			Green = Green >> 2;
			Blue = Blue >> 3;
			lsb = Blue | (Green << 5);
			msb = (Green >> 3) | (Red << 3);
			GFX_Fore_Color = lsb | (msb << 8);
		#endif
	#endif

/*Macro_SetForeColor_End*/
}



//------------------------------------------------------------------------------
//Configures the color of the background
//------------------------------------------------------------------------------
void SetBackColor (char Red, char Green, char Blue)
{
/*Macro_SetBackColor_Start*/

	#if MX_GFXLCD_TYPE == 1
		Red = Red >> 2;
		Green = Green >> 3;
		Blue = Blue >> 3;
		GFX_Back_Color = Blue | (Green << 5);
		GFX_Back_Color = GFX_Back_Color | (Red << 11);
	#else
		#if MX_GFXLCD_TYPE < 3
			Red = Red >> 5;
			Green = Green >> 5;
			Blue = Blue >> 6;
			Green = Green << 2;
			Red = Red << 5;
			GFX_Back_Color = (Blue | Red | Green);
		#else
			char msb, lsb;
			Red = Red >> 3;
			Green = Green >> 2;
			Blue = Blue >> 3;
			lsb = Blue | (Green << 5);
			msb = (Green >> 3) | (Red << 3);
			gLCD_SendByte(msb, 0);							// Send msb
			gLCD_SendByte(lsb, 0);							// Send lsb
			ReceiveByte(255);								// Try to collect Ack
			GFX_Back_Color = lsb | (msb << 8);
		#endif
	#endif

/*Macro_SetBackColor_End*/
}



//------------------------------------------------------------------------------
//Defines window area and fills with color
//------------------------------------------------------------------------------
void DrawBox (short X1, short Y1, short X2, short Y2, char Transparent, char Solid)
{
/*Macro_DrawBox_Start*/

	#if MX_GFXLCD_TYPE < 3
		short X,Y;
		short Pixel,Count,Color;

		DrawLine(X1, Y1, X2, Y1);    //draw border
		DrawLine(X2, Y1, X2, Y2);
		DrawLine(X1, Y2, X2, Y2);
		DrawLine(X1, Y1, X1, Y2);

		if (!Transparent)
		{
			X1 = X1 + 2;    //srink box to make room for border
			Y1 = Y1 + 2;
			gLCD_Window(X1,Y1,X2,Y2);        //define window

			X = X2 - X1;
			X++;                            //# of X-Pixel
			Y = Y2 - Y1;
			Y++;                               //# of Y-Pixel
			Pixel = X * Y;                   //# of total pixel

			if (Solid)
				Color = GFX_Fore_Color;
			else
				Color = GFX_Back_Color;

			for (Count=0;Count<Pixel;Count++)
			{
				//ForePlot each pixel in the defined output window
				#if MX_GFXLCD_TYPE == 1
					gLCD_SendByte(MX_GFXLCD_PARAM, Color>>8);
					gLCD_SendByte(MX_GFXLCD_PARAM, Color);
				#else
					gLCD_SendByte(MX_GFXLCD_PARAM, Color);
				#endif
			}
		}
	#else

		if (Transparent == 0 && Solid == 0)				// In this case we need to draw solid shape in bg colour and then overlay with wire frame
		{
			gLCD_SendByte(0x70, 0);						// Configure Pen Size
			gLCD_SendByte(0x00, 0);						// Solid
			ReceiveByte(255);							// Try to collect Ack

			gLCD_SendByte(0x72, 0);						// CMD - Draw Rectangle
			#if MX_GFXLCD_TYPE == 4
				gLCD_SendByte((X1 >> 8), 0);			// X1
			#endif
			gLCD_SendByte(X1, 0);						// X1
			#if MX_GFXLCD_TYPE == 4
				gLCD_SendByte((Y1 >> 8), 0);			// X1
			#endif
			gLCD_SendByte(Y1, 0);						// Y1
			#if MX_GFXLCD_TYPE == 4
				gLCD_SendByte((X2 >> 8), 0);			// X1
			#endif
			gLCD_SendByte(X2, 0);						// X2
			#if MX_GFXLCD_TYPE == 4
				gLCD_SendByte((Y2 >> 8), 0);			// X1
			#endif
			gLCD_SendByte(Y2, 0);						// Y2
			gLCD_SendByte((GFX_Back_Color >> 8), 0);	// BGND Colour
			gLCD_SendByte(GFX_Back_Color, 0);			// BGND Colour
			ReceiveByte(255);							// Try to collect Ack
		}

		gLCD_SendByte(0x70, 0);							// Configure Pen Size
		if (Solid)
			gLCD_SendByte(0x00, 0);						// Solid
		else
			gLCD_SendByte(0x01, 0);						// Wire Frame
		ReceiveByte(255);								// Try to collect Ack

		gLCD_SendByte(0x72, 0);							// CMD - Draw Rectangle
		#if MX_GFXLCD_TYPE == 4
			gLCD_SendByte((X1 >> 8), 0);				// X1
		#endif
		gLCD_SendByte(X1, 0);							// X1
		#if MX_GFXLCD_TYPE == 4
			gLCD_SendByte((Y1 >> 8), 0);				// X1
		#endif
		gLCD_SendByte(Y1, 0);							// Y1
		#if MX_GFXLCD_TYPE == 4
			gLCD_SendByte((X2 >> 8), 0);				// X1
		#endif
		gLCD_SendByte(X2, 0);							// X2
		#if MX_GFXLCD_TYPE == 4
			gLCD_SendByte((Y2 >> 8), 0);				// X1
		#endif
		gLCD_SendByte(Y2, 0);							// Y2
		gLCD_SendByte((GFX_Fore_Color >> 8), 0);		// FGND Colour
		gLCD_SendByte(GFX_Fore_Color, 0);				// FGND Colour
		ReceiveByte(255);								// Try to collect Ack

	#endif
/*Macro_DrawBox_End*/
}


//-------------------------------------------------------------------------------
//Clear screen
//-------------------------------------------------------------------------------
void Clear (void)
{
/*Macro_Clear_Start*/

	#if MX_GFXLCD_TYPE < 3
		char X,Y;
		short Pixel,Count;

		#if MX_GFXLCD_TYPE == 0
			X = 132;                        	//# of X-Pixel
			Y = 132;                           	//# of Y-Pixel
		#else
			#if MX_GFXLCD_TYPE == 1
				X = 128;                        	//# of X-Pixel
				Y = 128;                           	//# of Y-Pixel
			#else
				X = 132;                        	//# of X-Pixel
				Y = 176;                           	//# of Y-Pixel
			#endif
		#endif

		gLCD_Window(0,0,(X-1),(Y-1));			//define window
		Pixel = X * Y;                   		//# of total pixel

		for (Count=0;Count<Pixel;Count++)
		{
			//Plot each pixel in the defined output window
			#if MX_GFXLCD_TYPE == 1
				gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Back_Color>>8);
				gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Back_Color);
			#else
				gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Back_Color);
			#endif
		}
	#else

		gLCD_SendByte(0x42, 0);					// Replace Background colour
		gLCD_SendByte((GFX_Back_Color>>8), 0);
		gLCD_SendByte(GFX_Back_Color, 0);
		ReceiveByte(255);						// Try to collect Ack

		gLCD_SendByte(0x45, 0);					// Clear Command
		ReceiveByte(255);						// Try to collect Ack

	#endif

/*Macro_Clear_End*/
}



//-------------------------------------------------------------------------------
//Routine for displaying characters
//-------------------------------------------------------------------------------
void Print (char* String, short X, short Y, char Font, char Transparent)
{
/*Macro_Print_Start*/

	#if MX_GFXLCD_TYPE < 3
		char xpix, ypix, pos_Str, length_Str, count, xcount, ycount, height, width, i;
		char Fontwidth = 1;                //First we assume small font
		char Fontheight = 1;
		char position;

		char temp[6];
		temp[5] = 0x00;                        //Spacing Line

		length_Str = strlen(String);       //Get length of string

		if (Font == 1)                     //Double Height Sizes //Double Width
		{
			Fontwidth = 2;
		}
		if (Font == 2)                         //Double Height and Width Sizes
		{
			Fontwidth = 2;
			Fontheight = 2;
		}
		if (Font == 3)                         //Double Height Sizes
		{
			Fontheight = 2;
		}

		xcount = 0;
		for (i=0;i<length_Str;i++)         //Start at beginning of string and work along
		{

			pos_Str = *(String + i) - 32;      //Calculate place in ASCII memory

			for (count = 0; count < 5; count++)        //Use correct buffer location
			{
				if (pos_Str < 12)
				{
					position = (pos_Str * 5) + count;
					temp[count]=ASCII1[position];
				}
				else if (pos_Str < 24)
				{
					position = ((pos_Str - 12)*5) + count;
					temp[count]=ASCII2[position];
				}
				else if (pos_Str < 36)
				{
					position = ((pos_Str - 24)*5) + count;
					temp[count]=ASCII3[position];
				}
				else if (pos_Str < 48)
				{
					position = ((pos_Str - 36)*5) + count;
					temp[count]=ASCII4[position];
				}
				else if (pos_Str < 60)
				{
					position = ((pos_Str - 48)*5) + count;
					temp[count]=ASCII5[position];
				}
				else if (pos_Str < 72)
				{
					position = ((pos_Str - 60)*5) + count;
					temp[count]=ASCII6[position];
				}
				else if (pos_Str < 84)
				{
					position = ((pos_Str - 72)*5) + count;
					temp[count]=ASCII7[position];
				}
				else if (pos_Str < 95)
				{
					position = ((pos_Str - 84)*5) + count;
					temp[count]=ASCII8[position];
				}
			}

			for (xpix=0;xpix<6;xpix++)    //For 6 ASCII bytes 0 - 5
			{
				for (width=0;width<Fontwidth;width++)
				{
					ycount = 0;
					for (ypix=0;ypix<8;ypix++)    //For 8 data bits in bytes 0 - 7
					{
						for (height=0;height<Fontheight;height++)
						{
							if (test_bit(temp[xpix],ypix))
							{
								Plot(X + xcount, Y + ycount);
							}
							else if (Transparent == 0)
							{
								gLCD_Window(X+xcount+1, Y+ycount+1, X+xcount+1, Y+ycount+1);

								#if MX_GFXLCD_TYPE == 1
									gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Back_Color>>8);
									gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Back_Color);
								#else
									gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Back_Color);
								#endif
							}
							ycount++;
						}
					}
					xcount++;
				}
			}
		}
	#else

		char idx;

		gLCD_SendByte(0x4F, 0);						// Set Text Transparancy command
		if(Transparent)
			gLCD_SendByte(0, 0);					// Transparancy on
		else
			gLCD_SendByte(1, 0);					// Transparancy off
		ReceiveByte(255);							// Try to collect Ack

		gLCD_SendByte(0x53, 0);						// Send String Command
		#if MX_GFXLCD_TYPE == 4
			gLCD_SendByte((X >> 8), 0);				// X MSB
		#endif
		gLCD_SendByte(X, 0);						// X LSB
		#if MX_GFXLCD_TYPE == 4
			gLCD_SendByte((Y >> 8), 0);				// Y MSB
		#endif
		gLCD_SendByte(Y, 0);						// Y LSB

		gLCD_SendByte(Font, 0);						// Font
		gLCD_SendByte((GFX_Fore_Color >> 8), 0);	// Colour MSB
		gLCD_SendByte(GFX_Fore_Color, 0);			// Colour LSB

		gLCD_SendByte(1, 0);						// Width
		gLCD_SendByte(1, 0);						// Height

		for (idx = 0; idx < MSZ_String; idx++)
		{
			if (String[idx] == 0)
				break;
			gLCD_SendByte(String[idx], 0);			// Send byte from string
		}
		gLCD_SendByte(0, 0);						// Send null termination
		ReceiveByte(255);							// Try to collect Ack

    #endif

/*Macro_Print_End*/
}


//-------------------------------------------------------------------------------
//Routine for Printing Numbers
//-------------------------------------------------------------------------------
void PrintNumber (short Number, short X, short Y, char Font, char Transparent)
{
/*Macro_PrintNumber_Start*/
	char temp_str[6];
	FCI_TOSTRING(Number,temp_str,6);					//Convert number to String
	Print (temp_str, 6, X, Y, Font, Transparent);		//Send string to Print function
/*Macro_PrintNumber_End*/
}


//---------------------------------------------------------------------------
//Outputs one pixel onto the screen
//---------------------------------------------------------------------------
void Plot (short X1, short Y1)
{
/*Macro_Plot_Start*/

	#if MX_GFXLCD_TYPE < 3

		gLCD_Window(X1,Y1,X1,Y1);                            //Creates output window of 1 pixel

		#if MX_GFXLCD_TYPE == 1
			gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Fore_Color>>8);
			gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Fore_Color);
		#else
			gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Fore_Color);      //set color of pixel
		#endif

	#else

		gLCD_SendByte(0x50, 0);						// Draw Pixel Command

		#if MX_GFXLCD_TYPE == 4
			gLCD_SendByte((X1 >> 8), 0);			// X MSB
		#endif
		gLCD_SendByte(X1, 0);						// X LSB
		#if MX_GFXLCD_TYPE == 4
			gLCD_SendByte((Y1 >> 8), 0);			// Y MSB
		#endif
		gLCD_SendByte(Y1, 0);						// Y LSB
		gLCD_SendByte((GFX_Fore_Color >> 8), 0);	// Colour MSB
		gLCD_SendByte(GFX_Fore_Color, 0);			// Colour LSB
		ReceiveByte(255);							// Try to collect Ack

	#endif

/*Macro_Plot_End*/
}


//---------------------------------------------------------------------------
//Draws a line from one point to another
//---------------------------------------------------------------------------
void DrawLine (short X1, short Y1, short X2, short Y2)
{
/*Macro_DrawLine_Start*/

	#if MX_GFXLCD_TYPE < 3

		int C1, M1;
		signed int D1 = 0;
		signed int Pixelx = X2 - X1;    //number of X-pixels;
		signed int Pixely = Y2 - Y1;    //Number of Y-pixels
		signed char Xinc = 1;
		signed char Yinc = 1;

		if (Pixelx < 0)        //If negative X direction
		{
			Xinc = -1;
			Pixelx = Pixelx * -1;
		}
		if (Pixely < 0)        //If negative Y direction
		{
			Yinc = -1;
			Pixely = Pixely * -1;
		}
		if (Pixely <= Pixelx)
		{
			C1 = 2 * Pixelx;
			M1 = 2 * Pixely;
			while (X1 != X2)
			{
				Plot(X1, Y1);    //ForePlot line
				X1 = X1 + Xinc;
				D1 = D1 + M1;
				if (D1 > Pixelx)
				{
					Y1 = Y1 + Yinc;
					D1 = D1 - C1;
				}
			}
		}
		else
		{
			C1 = 2 * Pixely;
			M1 = 2 * Pixelx;
			while (Y1 != Y2)
			{
				Plot(X1, Y1);    //ForePlot Line
				Y1 = Y1 + Yinc;
				D1 = D1 + M1;
				if (D1 > Pixely)
				{
					X1 = X1 + Xinc;
					D1 = D1 - C1;
				}
			}
			Plot(X1, Y1);
		}

	#else

		gLCD_SendByte(0x4C, 0);						// Draw Line Command

		#if MX_GFXLCD_TYPE == 4
			gLCD_SendByte((X1 >> 8), 0);			// X1 MSB
		#endif
		gLCD_SendByte(X1, 0);						// X1 LSB
		#if MX_GFXLCD_TYPE == 4
			gLCD_SendByte((Y1 >> 8), 0);			// Y1 MSB
		#endif
		gLCD_SendByte(Y1, 0);						// Y1 LSB
		#if MX_GFXLCD_TYPE == 4
			gLCD_SendByte((X2 >> 8), 0);			// X2 MSB
		#endif
		gLCD_SendByte(X2, 0);						// X2 LSB
		#if MX_GFXLCD_TYPE == 4
			gLCD_SendByte((Y2 >> 8), 0);			// Y2 MSB
		#endif
		gLCD_SendByte(Y2, 0);						// Y2 LSB
		gLCD_SendByte((GFX_Fore_Color >> 8), 0);	// Colour MSB
		gLCD_SendByte(GFX_Fore_Color, 0);			// Colour LSB
		ReceiveByte(255);							// Try to collect Ack

	#endif

/*Macro_DrawLine_End*/
}



//---------------------------------------------------------------------------
//EB057 Specific Functions
//---------------------------------------------------------------------------
void SPI_Init()
{
/*Macro_SPI_Init_Start*/

	#if MX_GFXLCD_TYPE == 1

		#if MX_GFXLCD_BUS == 0

			//GetSPI_InitCode
			#ifndef MX_SPI
				#error "Chip does not have SPI capability"
			#endif

			//initialise spi
			#ifdef MX_SPI_B
				set_bit(trisb,MX_SPI_SDI);
				clear_bit(trisb,MX_SPI_SDO);
				clear_bit(trisb,MX_SPI_SCK);
				clear_bit(SPI_CS_TRIS,MX_GFXLCD_CS);

				//disable SPI devices
				set_bit(SPI_CS_PORT, MX_GFXLCD_CS);
			#endif

			#ifdef MX_SPI_C
				set_bit(trisc,MX_SPI_SDI);
				clear_bit(trisc,MX_SPI_SDO);
				clear_bit(trisc,MX_SPI_SCK);
				clear_bit(SPI_CS_TRIS,MX_GFXLCD_CS);

				//disable SPI devices
				set_bit(SPI_CS_PORT, MX_GFXLCD_CS);
			#endif

			#ifdef MX_SPI_BCB
				set_bit(trisb,MX_SPI_SDI);
				clear_bit(trisc,MX_SPI_SDO);
				clear_bit(trisb,MX_SPI_SCK);
				clear_bit(SPI_CS_TRIS,MX_GFXLCD_CS);

				//disable SPI devices
				set_bit(SPI_CS_PORT, MX_GFXLCD_CS);
			#endif

			sspstat = SPI_CKE | SPI_SMP;

			#ifdef _BOOSTC
				#ifdef SSPCON							// SPI Speed Initialise
					sspcon = SPI_SSPM | SPI_CKP;
					st_bit(sspcon, SSPEN);
				#endif
				#ifdef SSPCON1
					sspcon1 = SPI_SSPM | SPI_CKP;
					st_bit(sspcon1, SSPEN);
				#endif
			#endif

			#ifdef HI_TECH_C
				#ifdef sspcon							// SPI Speed Initialise
					sspcon = SPI_SSPM | SPI_CKP;
					st_bit(sspcon, SSPEN);
				#endif
				#ifdef sspcon1
					sspcon1 = SPI_SSPM | SPI_CKP;
					st_bit(sspcon1, SSPEN);
				#endif
			#endif

		#else

			cr_bit(SPI_CS_TRIS, MX_GFXLCD_SDATA);	//SDO
			cr_bit(SPI_CS_TRIS, MX_GFXLCD_SCLK);	//SCK
			st_bit(SPI_CS_TRIS, MX_GFXLCD_RS);		//SDI
			cr_bit(SPI_CS_TRIS, MX_GFXLCD_CS);		//CS

			st_bit(SPI_CS_PORT, MX_GFXLCD_CS);		//disable SPI devices
			cr_bit(SPI_CS_PORT, MX_GFXLCD_SCLK);

		#endif

	#endif

/*Macro_SPI_Init_End*/
}


char SPI_Send_Char(char Char)
{
/*Macro_SPI_Send_Char_Start*/

	#if MX_GFXLCD_TYPE == 1

		#if MX_GFXLCD_BUS == 0

			//GetSPI_Send_CharCode
			#ifndef MX_SPI
				#error "Chip does not have SPI capability"
			#endif

			//send the Char
			sspbuf = Char;

			//wait until sspbuf is empty
			while ((sspstat & 0x01) == 0);

			return sspbuf;

		#else

			char loop;
			for (loop=0; loop<8; loop++)
			{
				if (Char & 0x80)
					st_bit(MX_GFXLCD_PORT, MX_GFXLCD_SDATA);
				else
					cr_bit(MX_GFXLCD_PORT, MX_GFXLCD_SDATA);

				Char = Char << 1;

				st_bit(MX_GFXLCD_PORT, MX_GFXLCD_SCLK);
				//delay_us(1);

				if (ts_bit(MX_GFXLCD_PORT, MX_GFXLCD_RS))
					Char = Char | 0x01;

				cr_bit(MX_GFXLCD_PORT, MX_GFXLCD_SCLK);
			}

			return Char;

		#endif
	#endif

/*Macro_SPI_Send_Char_End*/
}


void Set_Data_Direction (char mode)
{
/*Macro_Set_Data_Direction_Start*/

	#if MX_GFXLCD_TYPE == 1

		//Configure Non Incremental and pair swapping
		clear_bit(SPI_CS_PORT, MX_GFXLCD_CS);			//CS Low

		SPI_Send_Char(0x40);
		SPI_Send_Char(CONF);
		SPI_Send_Char(0x20);
		SPI_Send_Char(0x20);

		set_bit(SPI_CS_PORT, MX_GFXLCD_CS);				//CS High

		//Configure DDRs
		delay_us(10);
		clear_bit(SPI_CS_PORT, MX_GFXLCD_CS);			//CS Low

		SPI_Send_Char(0x40);
		SPI_Send_Char(DDR);
		if(mode)
			SPI_Send_Char(0xFF);
		else
			SPI_Send_Char(0x00);
		SPI_Send_Char(0x00);

		set_bit(SPI_CS_PORT, MX_GFXLCD_CS);				//CS High

	#endif

/*Macro_Set_Data_Direction_End*/
}


void StrobeE (void)
{
/*Macro_StrobeE_Start*/

	#if MX_GFXLCD_TYPE == 1

		Control = Control & ~CS;		//Clear CS
		Control = Control | EN;			//Set EN
		Update_Slave ();
		Control = Control & ~EN;		//Clear EN
		Control = Control | CS;			//Set CS
		Update_Slave ();

	#endif

/*Macro_StrobeE_End*/
}


void Update_Slave ()
{
/*Macro_Update_Slave_Start*/

	#if MX_GFXLCD_TYPE == 1

		clear_bit(SPI_CS_PORT, MX_GFXLCD_CS);			//CS Low

		SPI_Send_Char(0x40);
		SPI_Send_Char(PORT);
		SPI_Send_Char(Data);		// -- The Order of this has changed BR 05 05 10
		SPI_Send_Char(Control);		// -- The Order of this has changed BR 05 05 10

		set_bit(SPI_CS_PORT, MX_GFXLCD_CS);				//CS High

	#endif

/*Macro_Update_Slave_End*/
}


void CommandWithData (char Command, char Data)
{
/*Macro_CommandWithData_Start*/

	#if MX_GFXLCD_TYPE == 1

		gLCD_SendByte(MX_GFXLCD_CMD, Command);
		gLCD_SendByte(MX_GFXLCD_PARAM, Data);

	#endif

/*Macro_CommandWithData_End*/
}


void CommandWith2Data (char Command, char Data1, char Data2)
{
/*Macro_CommandWith2Data_Start*/

	#if MX_GFXLCD_TYPE == 1

		gLCD_SendByte(MX_GFXLCD_CMD, Command);
		gLCD_SendByte(MX_GFXLCD_PARAM, Data1);
		gLCD_SendByte(MX_GFXLCD_PARAM, Data2);

	#endif

/*Macro_CommandWith2Data_End*/
}



char ReceiveByte(char nTimeout)
{
/*Macro_ReceiveByte_Start*/

	#if MX_GFXLCD_TYPE > 2

		char delay1 = 0;
		char delay2 = 0;
		char regcheck = 0;
		char dummy = 0;
		char retVal = 255;
		char bWaitForever = 0;
		char rxStatus = MX_GLCD_STATUS_LOOP;
		char idx;
		char count = 8;

		#if ( MX_GLCD_UART == 1)
			#ifndef MX_UART
				#error "Chip does not have UART1 capability"
			#endif
		#endif

		#if ( MX_GLCD_UART == 2)
			#ifndef MX_UART2
				#error "Chip does not have UART2 capability"
			#endif
		#endif

		if (nTimeout == 255)
			bWaitForever = 1;

		while (rxStatus == MX_GLCD_STATUS_LOOP)
		{
			if (bWaitForever == 0)
			{
				//don't wait forever, so do timeout thing...
				if (nTimeout == 0)
				{
					rxStatus = MX_GLCD_STATUS_TIMEOUT;
				}
				else
				{
					delay_us(10);
					delay1 = delay1 + 1;
					if(delay1 == 100)
					{
						nTimeout = nTimeout - 1;
						delay1 = 0;
					}
				}
			}
			#if ( MX_GLCD_UART == 0)
				regcheck = test_bit(MX_GLCD_RX_PORT, MX_GLCD_SW_RX);	//Test for start bit
				if (regcheck == 0)
					rxStatus = MX_GLCD_STATUS_RXBYTE;
			#endif
			#if ( MX_GLCD_UART == 1)
				regcheck = ts_bit(pir1, RCIF);
				if (regcheck != 0)
					rxStatus = MX_GLCD_STATUS_RXBYTE;
			#endif
			#if ( MX_GLCD_UART == 2)
				regcheck = ts_bit(pir3, RC2IF);
				if (regcheck != 0)
					rxStatus = MX_GLCD_STATUS_RXBYTE;
			#endif
		}

		if (rxStatus == MX_GLCD_STATUS_RXBYTE)
		{
			#if ( MX_GLCD_UART > 0)

				#if ( MX_GLCD_UART == 1)
					regcheck = ts_bit(rcsta, FERR);
				#endif

				#if ( MX_GLCD_UART == 2)
					regcheck = ts_bit(rcsta2, FERR);
				#endif

				if (regcheck != 0)
				{
					#if ( MX_GLCD_UART == 1)
						dummy = rcreg;      //need to read the rcreg to clear FERR
					#endif

					#if ( MX_GLCD_UART == 2)
						dummy = rcreg2;      //need to read the rcreg to clear FERR
					#endif
				}
				else
				{
					#if ( MX_GLCD_UART == 1)
						regcheck = ts_bit(rcsta, OERR);
					#endif

					#if ( MX_GLCD_UART == 2)
						regcheck = ts_bit(rcsta2, OERR);
					#endif

					if (regcheck != 0)
					{
						//need to read the rcreg to clear error
						#if ( MX_GLCD_UART == 1)
							cr_bit(rcsta, CREN);
							st_bit(rcsta, CREN);
						#endif

						#if ( MX_GLCD_UART == 2)
							cr_bit(rcsta2, CREN);
							st_bit(rcsta2, CREN);
						#endif
					}
					else
					{
						retVal = 0;
						#if ( MX_GLCD_UART == 1)
							retVal = retVal | rcreg; 			//no error, so rx byte is valid
						#endif
						#if ( MX_GLCD_UART == 2)
							retVal = retVal | rcreg2; 			//no error, so rx byte is valid
						#endif
					}
				}
			#else
				delay_us(52);									// 19200 Baud Bit Period
				for (idx = 0; idx < count; idx++)
				{
					retVal = retVal >> 1;
					if (test_bit( MX_GLCD_RX_PORT, MX_GLCD_SW_RX))
						retVal = retVal | 0x80;
					delay_us(52);								// 19200 Baud Bit Period
				}
			#endif
		}
		return (retVal);
	#endif
	return (0);
/*Macro_ReceiveByte_End*/
}

