/*********************************************************************
 *                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.
 ********************************************************************/

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

 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
2=Chip Select
3=Clock
4=Data

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

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

[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=18
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

[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=void
14=void
15=void
16=void
17=void
18=void

[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

[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=char
3=char
4=char
5=char

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

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

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

[MacroParamTypes_Plot]
1=char
2=char

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

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

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

[MacroParamTypes_DrawBox]
1=char
2=char
3=char
4=char
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

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

/********************************************************************
 * 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
******************************/

#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_GCXLCD_TYPE	 	 %r			   //0       0 = EB043, 1 = EB057

//ASCII Pixel data
#ifdef _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
	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_GCXLCD_TYPE == 0

	//EB043 ONLY

	//Color Data
	char DataInit[20] = {0x00,0x02,0x04,0x06,0x09,0x0B,0x0D,0x0F,0x00,0x02,0x04,0x06,0x09,0x0B,0x0D,0x0F,0x00,0x04,0x0B,0x0F};

	char GFX_Fore_Color = MX_GFXLCD_FCOL;
	char GFX_Back_Color = MX_GFXLCD_BCOL;

#else

	#if MX_GCXLCD_TYPE == 2

		char GFX_Fore_Color = MX_GFXLCD_FCOL;
		char GFX_Back_Color = MX_GFXLCD_BCOL;

	#else

		short GFX_Fore_Color;
		short GFX_Back_Color;

		//EB057 ONLY

		//I2C I/O Expander Command Defines
		#define DDR		0x00
		#define PORT	0x12
		#define CONF	0x0A

		//Pin Definitions
		#define EN		0x01
		#define RW		0x02
		#define RS		0x04
		#define CS		0x08
		#define RESET	0x10

		//global variables
		char Data = 0;
		char Control = RESET | CS;

		//LCD Command Defines
		#define LCD_Data		Control = Control | RS;			//Set DC
		#define LCD_Command		Control = Control & ~RS;		//Clear DC
		#define LCD_Read		Control = Control | RW;			//Set DC
		#define LCD_Write		Control = Control & ~RW;		//Clear DC

		//SPI COMPONENT DEFINES
		#define SPI_SSPM 	0
		#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

	#endif

#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 (char X1, char Y1, char X2, char Y2)
{
/*Macro_gLCD_Window_Start*/

	#if MX_GCXLCD_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);

	#else

		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_GCXLCD_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

	#else

		#if MX_GCXLCD_TYPE == 2

			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


		#else

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

		#endif

	#endif
/*Macro_gLCD_SendByte_End*/
}


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

	#if MX_GCXLCD_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
		}

	#else

		#if MX_GCXLCD_TYPE == 2

			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);

		#else

			char Red, Green, Blue;

			GFX_Fore_Color = MX_GFXLCD_FCOL;
			GFX_Back_Color = MX_GFXLCD_BCOL;

			//Convert Foreground to 16-bit colour
			Green = (GFX_Fore_Color >> 2) & 0x07;
			Green = Green << 2;
			Red = (GFX_Fore_Color >> 5) & 0x07;
			Red = Red << 3;
			Blue = (GFX_Fore_Color) & 0x03;
			Blue = Blue << 3;
			GFX_Fore_Color = Green | (Red << 5);
			GFX_Fore_Color = GFX_Fore_Color | (Blue << 11);

			//Convert Background to 16-bit colour
			Green = (GFX_Back_Color >> 2) & 0x07;
			Green = Green << 2;
			Red = (GFX_Back_Color >> 5) & 0x07;
			Red = Red << 3;
			Blue = (GFX_Back_Color) & 0x03;
			Blue = Blue << 3;
			GFX_Back_Color = Green | (Red << 5);
			GFX_Back_Color = GFX_Back_Color | (Blue << 11);

			//EB057 Initialise
			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

	#endif
	Clear();

/*Macro_Init_End*/
}



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

	#if MX_GCXLCD_TYPE == 1

		if (Red > 0x3F)
			Red = 0x3F;

		if (Green > 0x1F)
			Green = 0x1F;

		if (Blue > 0x1F)
			Blue = 0x1F;

		GFX_Fore_Color = Green | (Red << 5);
		GFX_Fore_Color = GFX_Fore_Color | (Blue << 11);

	#else

		if (Red > 7)
			Red = 7;

		if (Green > 7)
			Green = 7;

		if (Blue > 3)
			Blue = 3;

		Green = Green << 2;
		Red = Red << 5;
		GFX_Fore_Color = (Blue | Red) | Green;

	#endif



/*Macro_SetForeColor_End*/
}



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

	#if MX_GCXLCD_TYPE == 1

		if (Red > 0x3F)
			Red = 0x3F;

		if (Green > 0x1F)
			Green = 0x1F;

		if (Blue > 0x1F)
			Blue = 0x1F;

		GFX_Back_Color = Green | (Red << 5);
		GFX_Back_Color = GFX_Fore_Color | (Blue << 11);

	#else

		if (Red > 7)
			Red = 7;

		if (Green > 7)
			Green = 7;

		if (Blue > 3)
			Blue = 3;

		Green = Green << 2;
		Red = Red << 5;
		GFX_Back_Color = (Blue | Red | Green);

	#endif



/*Macro_SetBackColor_End*/
}



//------------------------------------------------------------------------------
//Defines window area and fills with color
//------------------------------------------------------------------------------
void DrawBox (char X1, char Y1, char X2, char Y2, char Transparent, char Solid)
{
/*Macro_DrawBox_Start*/
    char 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_GCXLCD_TYPE == 1
				gLCD_SendByte(MX_GFXLCD_PARAM, Color);
				gLCD_SendByte(MX_GFXLCD_PARAM, Color>>8);
			#else
				gLCD_SendByte(MX_GFXLCD_PARAM, Color);
			#endif
        }
    }
/*Macro_DrawBox_End*/
}


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

	char X,Y;
	short Pixel,Count;

	#if MX_GCXLCD_TYPE == 0
		X = 132;                        	//# of X-Pixel
		Y = 132;                           	//# of Y-Pixel
	#else
		#if MX_GCXLCD_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_GCXLCD_TYPE == 1
			gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Back_Color);
			gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Back_Color>>8);
		#else
			gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Back_Color);
		#endif
	}

/*Macro_Clear_End*/
}



//-------------------------------------------------------------------------------
//Routine for displaying characters
//-------------------------------------------------------------------------------
void Print (char* String, char X, char Y, char Font, char Transparent)
{
/*Macro_Print_Start*/
    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_GCXLCD_TYPE == 1
								gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Back_Color);
								gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Back_Color>>8);
							#else
								gLCD_SendByte(MX_GFXLCD_PARAM, GFX_Back_Color);
							#endif
                        }
                        ycount++;
                    }
                }
                xcount++;
            }
        }
    }
/*Macro_Print_End*/
}


//-------------------------------------------------------------------------------
//Routine for Printing Numbers
//-------------------------------------------------------------------------------
void PrintNumber (short Number, char X, char 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 (char X1, char Y1)
{
/*Macro_Plot_Start*/
    X1 = X1 + 1;
    Y1 = Y1 + 1;

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

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


//---------------------------------------------------------------------------
//Draws a line from one point to another
//---------------------------------------------------------------------------
void DrawLine (char X1, char Y1, char X2, char Y2)
{
/*Macro_DrawLine_Start*/
    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);
    }
/*Macro_DrawLine_End*/
}



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

	#if MX_GCXLCD_TYPE == 1

		//GetSPI_InitCode
		#ifndef MX_SPI
			#ifdef _BOOSTC
				#pragma error "Chip does not have SPI capability"
			#endif
			#ifdef HI_TECH_C
				#error Chip does not have SPI capability
			#endif
		#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

	#endif

/*Macro_SPI_Init_End*/
}


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

	#if MX_GCXLCD_TYPE == 1

		//GetSPI_Send_CharCode
		#ifndef MX_SPI
			#ifdef _BOOSTC
				#pragma error "Chip does not have SPI capability"
			#endif
			#ifdef HI_TECH_C
				#error Chip does not have SPI capability
			#endif
		#endif

		//send the Char
		sspbuf = Char;

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

	#endif

/*Macro_SPI_Send_Char_End*/
}


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

	#if MX_GCXLCD_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_GCXLCD_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_GCXLCD_TYPE == 1

		clear_bit(SPI_CS_PORT, MX_GFXLCD_CS);			//CS Low

		SPI_Send_Char(0x40);
		SPI_Send_Char(PORT);
		SPI_Send_Char(Data);
		SPI_Send_Char(Control);

		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_GCXLCD_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_GCXLCD_TYPE == 1

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

	#endif

/*Macro_CommandWith2Data_End*/
}

