/*********************************************************************
 *                    Flowcode LCD Display Component Code
 *
 * File: LCDDisplay_Code.c
 *
 * (c) 2007 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
 * -------+----+-----------------------------------------------------
 * 300307 | ST | Created
 * 150807 | ST | Added a missing delay to <RawSend> function
 * 100608 | BR | Modified <Cursor> addressing on 4-line displays
 *        |    |
 *        |    |
 *
 *
 *
 ********************************************************************/

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

 Return & parameter types:
   void
   char
   short
   char*

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

 Macro substitutions:
   %a = PORT_VAL
   %b = TRIS_VAL
   %c = DATA1_PIN_VAL
   %d = DATA2_PIN_VAL
   %e = DATA3_PIN_VAL
   %f = DATA4_PIN_VAL
   %g = RS_PIN_VAL
   %h = ENABLE_PIN_VAL
   %i = COMP_X
   %j = ROW_CNT

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

[Settings]
CLSID={E91B80A4-9610-4C9E-A116-9726E2FAF73E}

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


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

/*InitialisationCode_Start*/
/*InitialisationCode_End*/

/*InterruptCode_Start*/
/*InterruptCode_End*/




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


void GetDefines()
{
/*Macro_GetDefines_Start*/

}  //Dummy end of function to allow defines to be added correctly

//component connections
#define %i_PORT    %a
#define %i_TRIS    %b
#define %i_BIT0    %c
#define %i_BIT1    %d
#define %i_BIT2    %e
#define %i_BIT3    %f
#define %i_RS      %g
#define %i_E       %h

#ifdef _BOOSTC
  #define %i_DELAY   delay_10us(10)
#endif
#ifdef _C2C_
  #define %i_DELAY   delay_us(100)
#endif
#ifndef %i_DELAY
  #define %i_DELAY   delay_us(100)
#endif



//internal function prototypes
void %i_RawSend(char nIn, char nMask);

//internal function implementations
void %i_RawSend(char nIn, char nMask)
{
	unsigned char pt;
	unsigned char outVal;
	outVal = %i_PORT;
	clear_bit(outVal, %i_BIT0);
	clear_bit(outVal, %i_BIT1);
	clear_bit(outVal, %i_BIT2);
	clear_bit(outVal, %i_BIT3);
	clear_bit(outVal, %i_RS);
	clear_bit(outVal, %i_E);
	pt = ((nIn >> 4) & 0x0f);
	if (pt & 0x01)
	    set_bit(outVal, %i_BIT0);
	if (pt & 0x02)
	    set_bit(outVal, %i_BIT1);
	if (pt & 0x04)
	    set_bit(outVal, %i_BIT2);
	if (pt & 0x08)
	    set_bit(outVal, %i_BIT3);
	if (nMask)
	    set_bit(outVal, %i_RS);
	%i_PORT = outVal;
	%i_DELAY;
	set_bit (%i_PORT, %i_E);
	%i_DELAY;
	clear_bit (%i_PORT, %i_E);
	pt = (nIn & 0x0f);
	%i_DELAY;
	outVal = %i_PORT;
	clear_bit(outVal, %i_BIT0);
	clear_bit(outVal, %i_BIT1);
	clear_bit(outVal, %i_BIT2);
	clear_bit(outVal, %i_BIT3);
	clear_bit(outVal, %i_RS);
	clear_bit(outVal, %i_E);
	if (pt & 0x01)
	    set_bit(outVal, %i_BIT0);
	if (pt & 0x02)
	    set_bit(outVal, %i_BIT1);
	if (pt & 0x04)
	    set_bit(outVal, %i_BIT2);
	if (pt & 0x08)
	    set_bit(outVal, %i_BIT3);
	if (nMask)
	    set_bit(outVal, %i_RS);
	%i_PORT = outVal;
	%i_DELAY;
	set_bit (%i_PORT, %i_E);
	%i_DELAY;
	clear_bit (%i_PORT, %i_E);
	%i_DELAY;
}

// Dummy function to close the defines section off
void %i_Dummy_Function();
void %i_Dummy_Function()
{

/*Macro_GetDefines_End*/
}



void Start()
{
/*Macro_Iniciar_Start*/
/*Macro_Init_Start*/
/*Macro_Start_Start*/

	clear_bit(%i_TRIS, %i_BIT0);
	clear_bit(%i_TRIS, %i_BIT1);
	clear_bit(%i_TRIS, %i_BIT2);
	clear_bit(%i_TRIS, %i_BIT3);
	clear_bit(%i_TRIS, %i_RS);
	clear_bit(%i_TRIS, %i_E);

	delay_ms(12);

	%i_RawSend(0x33, 0);
	delay_ms(2);
	%i_RawSend(0x32, 0);
	delay_ms(2);
	%i_RawSend(0x2c, 0);
	delay_ms(2);
	%i_RawSend(0x06, 0);
	delay_ms(2);
	%i_RawSend(0x0c, 0);
	delay_ms(2);

	//clear the display
	%i_RawSend(0x01, 0);
	delay_ms(2);
	%i_RawSend(0x02, 0);
	delay_ms(2);

/*Macro_Start_End*/
/*Macro_Init_End*/
/*Macro_Iniciar_End*/
}




void Clear()
{
/*Macro_Anular_Start*/
/*Macro_Efface_Start*/
/*Macro_Clear_Start*/

	%i_RawSend(0x01, 0);
	delay_ms(2);
	%i_RawSend(0x02, 0);
	delay_ms(2);

/*Macro_Clear_End*/
/*Macro_Efface_End*/
/*Macro_Anular_End*/
}




void PrintASCII(char Character)
{
/*Macro_ImprimirASCII_Start*/
/*Macro_Écrit_Car_Start*/
/*Macro_PrintASCII_Start*/

	trisb = trisb & 0x0F;       //Sets the high nibble to an output
        %i_RawSend(Character, 0x10);
        trisb = trisb | 0xF0;       //Sets the high nibble to an input

/*Macro_PrintASCII_End*/
/*Macro_Écrit_Car_End*/
/*Macro_ImprimirASCII_End*/
}




void Command(char in)
{
/*Macro_Comando_Start*/
/*Macro_Command_Start*/

	%i_RawSend(in, 0);
	delay_ms(2);

/*Macro_Command_End*/
/*Macro_Comando_End*/
}






void Cursor(char x, char y)
{
/*Macro_Curseur_Start*/
/*Macro_Cursor_Start*/

  trisb = trisb & 0x0F;       //Sets the high nibble to an output
  #if (%j == 1)
    y=0x80;
  #endif

  #if (%j == 2)
	if (y==0)
		y=0x80;
	else
		y=0xc0;
  #endif

  #if (%j == 4)
	if (y==0)
		y=0x80;
	else if (y==1)
		y=0xc0;
	else if (y==2)
		y=0x90;
	else
		y=0xd0;
  #endif

	%i_RawSend(y+x, 0);
	delay_ms(2);
  trisb = trisb | 0xF0;       //Sets the high nibble to an input

/*Macro_Cursor_End*/
/*Macro_Curseur_End*/
}






void PrintNumber(short Number)
{
/*Macro_ImprimirNumero_Start*/
/*Macro_Écrit_Num_Start*/
/*Macro_PrintNumber_Start*/

	trisb = trisb & 0xF0;       //Sets the high nibble to an output
        short tmp_int;
	char tmp_byte;
	if (Number < 0)
	{
		%i_RawSend('-', 0x10);
		Number = 0 - Number;
	}

	tmp_int = Number;
	if (Number >= 10000)
	{
		tmp_byte = tmp_int / 10000;
		%i_RawSend('0' + tmp_byte, 0x10);

		while (tmp_byte > 0)
		{
			tmp_int = tmp_int - 10000;
			tmp_byte--;
		}
	}
	if (Number >= 1000)
	{
		tmp_byte = tmp_int / 1000;
		%i_RawSend('0' + tmp_byte, 0x10);

		while (tmp_byte > 0)
		{
			tmp_int = tmp_int - 1000;
			tmp_byte--;
		}
	}
	if (Number >= 100)
	{
		tmp_byte = tmp_int / 100;
		%i_RawSend('0' + tmp_byte, 0x10);

		while (tmp_byte > 0)
		{
			tmp_int = tmp_int - 100;
			tmp_byte--;
		}
	}
	if (Number >= 10)
	{
		tmp_byte = tmp_int / 10;
		%i_RawSend('0' + tmp_byte, 0x10);

		while (tmp_byte > 0)
		{
			tmp_int = tmp_int - 10;
			tmp_byte--;
		}
	}
	%i_RawSend('0' + tmp_int, 0x10);
        trisb = trisb | 0xF0;       //Sets the high nibble to an input

/*Macro_PrintNumber_End*/
/*Macro_Écrit_Num_End*/
/*Macro_ImprimirNumero_End*/
}




void PrintString(char* String, char MSZ_String)
{
/*Macro_ImprimirCadena_Start*/
/*Macro_Écrit_Chaîne_Start*/
/*Macro_PrintString_Start*/

	trisb = trisb & 0xF0;       //Sets the high nibble to an output
        char idx;
	for (idx=0; idx<MSZ_String; idx++)
	{
		if (String[idx]==0)
		{
			break;
		}
		%i_RawSend(String[idx], 0x10);
	}
        trisb = trisb | 0xF0;       //Sets the high nibble to an input

/*Macro_PrintString_End*/
/*Macro_Écrit_Chaîne_End*/
/*Macro_ImprimirCadena_End*/
}



