//************************************************************************************
//**  
//**  File name:     C:\Documents and Settings\Rob\Desktop\robs flowfiles\doorbell3.c
//**  Generated by:  Flowcode v4.2.3.58
//**  Date:          Friday, March 12, 2010 19:01:15
//**  Licence:       Student
//**  Registered to: Rob Onkenhout
//**  
//**  
//**     NOT FOR COMMERCIAL USE
//**  
//**  http://www.matrixmultimedia.com
//************************************************************************************


#define MX_PIC

//Defines for microcontroller
#define P16F877A
#define MX_EE
#define MX_EE_TYPE2
#define MX_EE_SIZE 256
#define MX_SPI
#define MX_SPI_C
#define MX_SPI_SDI 4
#define MX_SPI_SDO 5
#define MX_SPI_SCK 3
#define MX_UART
#define MX_UART_C
#define MX_UART_TX 6
#define MX_UART_RX 7
#define MX_I2C
#define MX_MI2C
#define MX_I2C_C
#define MX_I2C_SDA 4
#define MX_I2C_SCL 3
#define MX_PWM
#define MX_PWM_CNT 2
#define MX_PWM_TRIS1 trisc
#define MX_PWM_1 2
#define MX_PWM_TRIS2 trisc
#define MX_PWM_2 1

//Functions
#define MX_CLK_SPEED 19660800
#ifdef _BOOSTC
#include <system.h>
#endif
#ifdef HI_TECH_C
#include <pic.h>
#endif

//Configuration data

//Internal functions
#include "C:\Program Files\Matrix Multimedia\Flowcode V4\FCD\internals.h"

//Macro function declarations


//Variable declarations
char FCV_KEY;


//Defines:

/**** Macro Substitutions ****
{'1','4','7','*','2','5','8','0','3','6','9','#'} = Key List (Numbers)
{1,4,7,10,2,5,8,0,3,6,9,11} = Key List (Characters)
tris` = Row Data Direction Register
port` = Row Port Register
3 = Number Of Columns
4 = Number Of Rows
tris` = Column Data Direction Register
port` = Column Port Register
1 = Column 1 mask
1 = Column 2 mask
1 = Column 3 mask
1 = Column 4 mask
1 = Row 1 mask
1 = Row 2 mask
1 = Row 3 mask
1 = Row 4 mask
******************************/




//KeyPad0: //Macro function declarations

char FCD_KeyPad0_GetKeypadNumber();
char FCD_KeyPad0_GetKeypadAscii();
//Defines:

/**** Macro Substitutions ****
portb = D1 Port
trisb = D1 Data Direction
portb = D2 Port
trisb = D2 Data Direction
portb = D3 Port
trisb = D3 Data Direction
portb = D4 Port
trisb = D4 Data Direction
portb = RS Port
trisb = RS Data Direction
portb = E Port
trisb = E Data Direction
0 = Data 1_Pin
1 = Data 2 Pin
2 = Data 3 Pin
3 = Data 4 Pin
4 = RS Pin
5 = Enable Pin
LCD_7276236 = Unique Component Reference Number
2 = Row Count
16 = Column Count
******************************/

	//component connections
	#define LCD_7276236_PORT0    portb
	#define LCD_7276236_TRIS0    trisb
	#define LCD_7276236_PORT1    portb
	#define LCD_7276236_TRIS1    trisb
	#define LCD_7276236_PORT2    portb
	#define LCD_7276236_TRIS2    trisb
	#define LCD_7276236_PORT3    portb
	#define LCD_7276236_TRIS3    trisb
	#define LCD_7276236_PORT4    portb
	#define LCD_7276236_TRIS4    trisb
	#define LCD_7276236_PORT5    portb
	#define LCD_7276236_TRIS5    trisb
	#define LCD_7276236_BIT0    	0
	#define LCD_7276236_BIT1    	1
	#define LCD_7276236_BIT2    	2
	#define LCD_7276236_BIT3    	3
	#define LCD_7276236_RS      	4
	#define LCD_7276236_E       	5
	#define LCD_7276236_ROWCNT	2
	#define LCD_7276236_COLCNT	16

	#ifdef _BOOSTC
	  #define LCD_7276236_DELAY   delay_10us(10)
	#endif
	#ifdef _C2C_
	  #define LCD_7276236_DELAY   delay_us(100)
	#endif
	#ifdef HI_TECH_C
	  #define LCD_7276236_DELAY   __delay_us(120)
	#endif
	#ifndef LCD_7276236_DELAY
	  #define LCD_7276236_DELAY   delay_us(100)
	#endif




//LCDDisplay0: //Macro function declarations

void FCD_LCDDisplay0_RawSend(char in, char mask);
void FCD_LCDDisplay0_Start();
void FCD_LCDDisplay0_Clear();
void FCD_LCDDisplay0_PrintASCII(char Character);
void FCD_LCDDisplay0_Command(char in);
void FCD_LCDDisplay0_Cursor(char x, char y);
void FCD_LCDDisplay0_PrintNumber(short Number);
void FCD_LCDDisplay0_PrintString(char* String, char MSZ_String);
void FCD_LCDDisplay0_ScrollDisplay(char Direction, char Num_Positions);
void FCD_LCDDisplay0_ClearLine(char Line);
void FCD_LCDDisplay0_RAM_Write(char nIdx, char d0, char d1, char d2, char d3, char d4, char d5, char d6, char d7);



//KeyPad0: //Macro implementations


char FCD_KeyPad0_GetKeypadNumber()
{
		//get matrices for rows and columns
		#if (3 == 1)
			#define KPAD_COL_MTX {1}
			#define KPAD_COL_MASK (1)
		#endif
		#if (3 == 2)
			#define KPAD_COL_MTX {1,1}
			#define KPAD_COL_MASK (1|1)
		#endif
		#if (3 == 3)
			#define KPAD_COL_MTX {1,1,1}
			#define KPAD_COL_MASK (1|1|1)
		#endif
		#if (3 == 4)
			#define KPAD_COL_MTX {1,1,1,1}
			#define KPAD_COL_MASK (1|1|1|1)
		#endif
		#if (4 == 1)
			#define KPAD_ROW_MTX {1}
			#define KPAD_ROW_MASK (1)
		#endif
		#if (4 == 2)
			#define KPAD_ROW_MTX {1,1}
			#define KPAD_ROW_MASK (1|1)
		#endif
		#if (4 == 3)
			#define KPAD_ROW_MTX {1,1,1}
			#define KPAD_ROW_MASK (1|1|1)
		#endif
		#if (4 == 4)
			#define KPAD_ROW_MTX {1,1,1,1}
			#define KPAD_ROW_MASK (1|1|1|1)
		#endif

		#ifndef KPAD_COL_MTX
			#pragma error Keypad error: column count is not 1-4
		#endif
		#ifndef KPAD_ROW_MTX
			#pragma error Keypad error: row count is not 1-4
		#endif

		//store keys and pin connections into a constant array
		#ifdef _BOOSTC
			rom char* mtxKeysAsNumbers = {1,4,7,10,2,5,8,0,3,6,9,11};
			rom char* mtxCols = KPAD_COL_MTX;
			rom char* mtxRows = KPAD_ROW_MTX;
		#endif
		#ifdef HI_TECH_C
			const char mtxKeysAsNumbers[] = {1,4,7,10,2,5,8,0,3,6,9,11};
			const char mtxCols[] = KPAD_COL_MTX;
			const char mtxRows[] = KPAD_ROW_MTX;
		#endif

		//set up i/o of port (rows = inputs, columns = outputs)
		tris` = (tris` | KPAD_ROW_MASK);
		tris` = (tris` & ~KPAD_COL_MASK);		//BR

		char iCol;
		char iRow;
		char c_ip;
		for (iCol=0; iCol<3; iCol++)
		{
			//output the appropriate column high
			port` = mtxCols[iCol];

			//delay
			delay_us(10);

			//read the port
			c_ip = port`;

			//check for a hit
			for (iRow=0; iRow<4; iRow++)
			{
				if ((c_ip & mtxRows[iRow]) != 0)
				{
					//found it!
					goto found_key;
				}
			}
		}

		//if it gets here, it has not been found...
		return (255);

	  found_key:
		return (mtxKeysAsNumbers[(iCol*4) + iRow]);

	  #undef KPAD_COL_MTX
	  #undef KPAD_ROW_MTX
	  #undef KPAD_COL_MASK
	  #undef KPAD_ROW_MASK

}

char FCD_KeyPad0_GetKeypadAscii()
{
		//get matrices for rows and columns
		#if (3 == 1)
			#define KPAD_COL_MTX {1}
			#define KPAD_COL_MASK (1)
		#endif
		#if (3 == 2)
			#define KPAD_COL_MTX {1,1}
			#define KPAD_COL_MASK (1|1)
		#endif
		#if (3 == 3)
			#define KPAD_COL_MTX {1,1,1}
			#define KPAD_COL_MASK (1|1|1)
		#endif
		#if (3 == 4)
			#define KPAD_COL_MTX {1,1,1,1}
			#define KPAD_COL_MASK (1|1|1|1)
		#endif
		#if (4 == 1)
			#define KPAD_ROW_MTX {1}
			#define KPAD_ROW_MASK (1)
		#endif
		#if (4 == 2)
			#define KPAD_ROW_MTX {1,1}
			#define KPAD_ROW_MASK (1|1)
		#endif
		#if (4 == 3)
			#define KPAD_ROW_MTX {1,1,1}
			#define KPAD_ROW_MASK (1|1|1)
		#endif
		#if (4 == 4)
			#define KPAD_ROW_MTX {1,1,1,1}
			#define KPAD_ROW_MASK (1|1|1|1)
		#endif

		#ifndef KPAD_COL_MTX
			#pragma error Keypad error: column count is not 1-4
		#endif
		#ifndef KPAD_ROW_MTX
			#pragma error Keypad error: row count is not 1-4
		#endif

		//store keys and pin connections into a constant array
		#ifdef _BOOSTC
			rom char* mtxKeysAsChars = {'1','4','7','*','2','5','8','0','3','6','9','#'};
			rom char* mtxCols = KPAD_COL_MTX;
			rom char* mtxRows = KPAD_ROW_MTX;
		#endif
		#ifdef HI_TECH_C
			const char mtxKeysAsChars[] = {'1','4','7','*','2','5','8','0','3','6','9','#'};
			const char mtxCols[] = KPAD_COL_MTX;
			const char mtxRows[] = KPAD_ROW_MTX;
		#endif

		//set up i/o of port (rows = inputs, columns = outputs)
		tris` = (tris` | KPAD_ROW_MASK);
		tris` = (tris` & ~KPAD_COL_MASK);

		char iCol;
		char iRow;
		char c_ip;
		for (iCol=0; iCol<3; iCol++)
		{
			//output the appropriate column high
			port` = mtxCols[iCol];

			//delay
			delay_us(10);

			//read the port
			c_ip = port`;

			//check for a hit
			for (iRow=0; iRow<4; iRow++)
			{
				if ((c_ip & mtxRows[iRow]) != 0)
				{
					//found it!
					goto found_key;
				}
			}
		}

		//if it gets here, it has not been found...
		return (255);

	  found_key:
		return (mtxKeysAsChars[(iCol*4) + iRow]);

	  #undef KPAD_COL_MTX
	  #undef KPAD_ROW_MTX
	  #undef KPAD_COL_MASK
	  #undef KPAD_ROW_MASK

}



//LCDDisplay0: //Macro implementations


void FCD_LCDDisplay0_RawSend(char in, char mask)
{
		unsigned char pt;

		clear_bit(LCD_7276236_PORT0, LCD_7276236_BIT0);
		clear_bit(LCD_7276236_PORT1, LCD_7276236_BIT1);
		clear_bit(LCD_7276236_PORT2, LCD_7276236_BIT2);
		clear_bit(LCD_7276236_PORT3, LCD_7276236_BIT3);
		clear_bit(LCD_7276236_PORT4, LCD_7276236_RS);
		clear_bit(LCD_7276236_PORT5, LCD_7276236_E);
		pt = ((in >> 4) & 0x0f);
		if (pt & 0x01)
		    set_bit(LCD_7276236_PORT0, LCD_7276236_BIT0);
		if (pt & 0x02)
		    set_bit(LCD_7276236_PORT1, LCD_7276236_BIT1);
		if (pt & 0x04)
		    set_bit(LCD_7276236_PORT2, LCD_7276236_BIT2);
		if (pt & 0x08)
		    set_bit(LCD_7276236_PORT3, LCD_7276236_BIT3);
		if (mask)
		    set_bit(LCD_7276236_PORT4, LCD_7276236_RS);
		LCD_7276236_DELAY;
		set_bit (LCD_7276236_PORT5, LCD_7276236_E);
		LCD_7276236_DELAY;
		clear_bit (LCD_7276236_PORT5, LCD_7276236_E);
		pt = (in & 0x0f);
		LCD_7276236_DELAY;
		clear_bit(LCD_7276236_PORT0, LCD_7276236_BIT0);
		clear_bit(LCD_7276236_PORT1, LCD_7276236_BIT1);
		clear_bit(LCD_7276236_PORT2, LCD_7276236_BIT2);
		clear_bit(LCD_7276236_PORT3, LCD_7276236_BIT3);
		clear_bit(LCD_7276236_PORT4, LCD_7276236_RS);
		clear_bit(LCD_7276236_PORT5, LCD_7276236_E);
		if (pt & 0x01)
		    set_bit(LCD_7276236_PORT0, LCD_7276236_BIT0);
		if (pt & 0x02)
		    set_bit(LCD_7276236_PORT1, LCD_7276236_BIT1);
		if (pt & 0x04)
		    set_bit(LCD_7276236_PORT2, LCD_7276236_BIT2);
		if (pt & 0x08)
		    set_bit(LCD_7276236_PORT3, LCD_7276236_BIT3);
		if (mask)
		    set_bit(LCD_7276236_PORT4, LCD_7276236_RS);
		LCD_7276236_DELAY;
		set_bit (LCD_7276236_PORT5, LCD_7276236_E);
		LCD_7276236_DELAY;
		clear_bit (LCD_7276236_PORT5, LCD_7276236_E);
		LCD_7276236_DELAY;
}

void FCD_LCDDisplay0_Start()
{
	
		clear_bit(LCD_7276236_TRIS0, LCD_7276236_BIT0);
		clear_bit(LCD_7276236_TRIS1, LCD_7276236_BIT1);
		clear_bit(LCD_7276236_TRIS2, LCD_7276236_BIT2);
		clear_bit(LCD_7276236_TRIS3, LCD_7276236_BIT3);
		clear_bit(LCD_7276236_TRIS4, LCD_7276236_RS);
		clear_bit(LCD_7276236_TRIS5, LCD_7276236_E);

		Wdt_Delay_Ms(12);

		FCD_LCDDisplay0_RawSend(0x33, 0);
		Wdt_Delay_Ms(2);
		FCD_LCDDisplay0_RawSend(0x33, 0);
		Wdt_Delay_Ms(2);
		FCD_LCDDisplay0_RawSend(0x32, 0);
		Wdt_Delay_Ms(2);
		FCD_LCDDisplay0_RawSend(0x2c, 0);
		Wdt_Delay_Ms(2);
		FCD_LCDDisplay0_RawSend(0x06, 0);
		Wdt_Delay_Ms(2);
		FCD_LCDDisplay0_RawSend(0x0c, 0);
		Wdt_Delay_Ms(2);

		//clear the display
		FCD_LCDDisplay0_RawSend(0x01, 0);
		Wdt_Delay_Ms(2);
		FCD_LCDDisplay0_RawSend(0x02, 0);
		Wdt_Delay_Ms(2);

}

void FCD_LCDDisplay0_Clear()
{
	
		FCD_LCDDisplay0_RawSend(0x01, 0);
		Wdt_Delay_Ms(2);
		FCD_LCDDisplay0_RawSend(0x02, 0);
		Wdt_Delay_Ms(2);

}

void FCD_LCDDisplay0_PrintASCII(char Character)
{
	
		FCD_LCDDisplay0_RawSend(Character, 0x10);

}

void FCD_LCDDisplay0_Command(char in)
{
	
		FCD_LCDDisplay0_RawSend(in, 0);
		Wdt_Delay_Ms(2);

}

void FCD_LCDDisplay0_Cursor(char x, char y)
{
	
	  #if (LCD_7276236_ROWCNT == 1)
	    y=0x80;
	  #endif

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

	  #if (LCD_7276236_ROWCNT == 4)
		if (y==0)
			y=0x80;
		else if (y==1)
			y=0xc0;

		#if (LCD_7276236_COLCNT == 16)
			else if (y==2)
				y=0x90;
			else
				y=0xd0;
		#endif

		#if (LCD_7276236_COLCNT == 20)
			else if (y==2)
				y=0x94;
			else
				y=0xd4;
		#endif
	  #endif

		FCD_LCDDisplay0_RawSend(y+x, 0);
		Wdt_Delay_Ms(2);

}

void FCD_LCDDisplay0_PrintNumber(short Number)
{
	
		short tmp_int;
		char tmp_byte;
		if (Number < 0)
		{
			FCD_LCDDisplay0_RawSend('-', 0x10);
			Number = 0 - Number;
		}

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

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

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

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

			while (tmp_byte > 0)
			{
				tmp_int = tmp_int - 10;
				tmp_byte--;
			}
		}
		FCD_LCDDisplay0_RawSend('0' + tmp_int, 0x10);

}

void FCD_LCDDisplay0_PrintString(char* String, char MSZ_String)
{
	
		char idx = 0;

		for (idx=0; idx<MSZ_String; idx++)
		{
			#ifdef _BOOSTC
				if (String[idx] == 0)
				{
					break;
				}
				FCD_LCDDisplay0_RawSend(String[idx], 0x10);
			#endif

			#ifdef HI_TECH_C
				if (*String == 0)
				{
					break;
				}
				FCD_LCDDisplay0_RawSend(*String, 0x10);
				String++;
			#endif
		}

}

void FCD_LCDDisplay0_ScrollDisplay(char Direction, char Num_Positions)
{
	
		char cmd = 0;
		char count;

		//Choose the direction
		switch (Direction)
		{
			case 0:
			case 'l':
			case 'L':

				cmd = 0x18;
				break;

			case 1:
			case 'r':
			case 'R':

				cmd = 0x1C;
				break;

			default:
				break;
		}

		//If direction accepted then scroll the specified amount
		if (cmd)
		{
			for (count = 0; count < Num_Positions; count++)
				FCD_LCDDisplay0_Command(cmd);
		}

}

void FCD_LCDDisplay0_ClearLine(char Line)
{
	
		char count;
		char rowcount;

		//Define number of columns per line
		#if (LCD_7276236_ROWCNT == 1)
			rowcount=80;
		#endif

		#if (LCD_7276236_ROWCNT == 2)
			rowcount=40;
		#endif

		#if (LCD_7276236_ROWCNT == 4)
			#if (LCD_7276236_COLCNT == 16)
				rowcount=16;
			#endif
			#if (LCD_7276236_COLCNT == 20)
				rowcount=20;
			#endif
		#endif

		//Start at beginning of the line
		FCD_LCDDisplay0_Cursor (0, Line);

		//Send out spaces to clear line
		for (count = 0; count < rowcount; count++)
			FCD_LCDDisplay0_RawSend(' ', 0x10);

		//Move back to the beginning of the line.
		FCD_LCDDisplay0_Cursor (0, Line);

}

void FCD_LCDDisplay0_RAM_Write(char nIdx, char d0, char d1, char d2, char d3, char d4, char d5, char d6, char d7)
{
	   //set CGRAM address
	   FCD_LCDDisplay0_RawSend(64 + (nIdx << 3), 0);
	   delay_ms(2);

	   //write CGRAM data
	   FCD_LCDDisplay0_RawSend(d0, 0x10);
	   FCD_LCDDisplay0_RawSend(d1, 0x10);
	   FCD_LCDDisplay0_RawSend(d2, 0x10);
	   FCD_LCDDisplay0_RawSend(d3, 0x10);
	   FCD_LCDDisplay0_RawSend(d4, 0x10);
	   FCD_LCDDisplay0_RawSend(d5, 0x10);
	   FCD_LCDDisplay0_RawSend(d6, 0x10);
	   FCD_LCDDisplay0_RawSend(d7, 0x10);

	   //Clear the display
	   FCD_LCDDisplay0_RawSend(0x01, 0);
	   delay_ms(2);
	   FCD_LCDDisplay0_RawSend(0x02, 0);
	   delay_ms(2);
}

//Macro implementations

void main()
{
	
	//Initialisation
	adcon1 = 0x07;


	//Interrupt initialisation code
	option_reg = 0xC0;


	//Call Component Macro
	//Call Component Macro: LCDDisplay(0)::Start
	FCD_LCDDisplay0_Start();


	//Loop
	//Loop: While 1
	while (1)
	{
		//Delay
		//Delay: 150 ms
		delay_ms(150);


		//Call Component Macro
		//Call Component Macro: key=KeyPad(0)::GetKeypadAscii
		FCV_KEY = FCD_KeyPad0_GetKeypadAscii();


		//Key pressed?
		//Decision: key<>255?
		if (FCV_KEY!=255)
		{
			//Decision
			//Decision: key = 35?
			if (FCV_KEY == 35)
			{
				//Call Component Macro
				//Call Component Macro: LCDDisplay(0)::Clear
				FCD_LCDDisplay0_Clear();


			} else {
				//Call Component Macro
				//Call Component Macro: LCDDisplay(0)::PrintASCII(key)
				FCD_LCDDisplay0_PrintASCII(FCV_KEY);


				//Calculation
				//Calculation:
				//  key = key-48
				FCV_KEY = FCV_KEY-48;
				

			}


		}


	}


	mainendloop: goto mainendloop;
}

void MX_INTERRUPT_MACRO(void)
{
}



