/*********************************************************************
 *                    Flowcode Switch Component Code
 *
 * File: PIC_SWITCH.c
 *
 * (c) 2011 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
 * -------+----+-----------------------------------------------------
 * 110607 | BR | Created
 * 040707 | ST | Fixes to code
 * 050707 | ST | Added "GetDefines" and optimised code
 * 120309 | BR | Removed WhichSwitch parameter from macros
 * 180309 | BR | Changed delays to be WDT compatible
 * 200409 | BR | Fixed small bug in WUH and WUL macros
 * 130509 | BR | Added % definitions to DefinesCode section
 * 270110 | BR | Added a method for the 10F to allow the tris to work correctly
 * 270511 | SK | Support for MIAC expansion system added
 * 190911 | BR | Converted to Universal Switch Component Code File
 * 011211 | BR | Updated FC_CAL_Bit functions
 ********************************************************************/

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

 Return & parameter types:
   void
   MX_UINT8
   MX_SINT16
   MX_STRING

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

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

[Settings]
CLSID={88991F1C-EEEB-4D28-A149-1E7E8DDA65FD}
IsAnalogue=0
MultipleAllowed=1
Description=Switch Flowcode Component

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

NOTE: For simulation to work, these macros _MUST_ remain at the indicated index:
	1=ReadState
	2=WaitUntilHigh
	3=WaitUntilLow


[MacroNames]
Count=3
1=ReadState
2=WaitUntilHigh
3=WaitUntilLow

[MacroReturns]
1=MX_UINT8
2=void
3=void

[MacroIsPrivate]
1=0
2=0
3=0

[MacroParameters_ReadState]
Count=0

[MacroParamTypes_ReadState]


[MacroParameters_WaitUntilHigh]
Count=0

[MacroParamTypes_WaitUntilHigh]


[MacroParameters_WaitUntilLow]
Count=0

[MacroParamTypes_WaitUntilLow]


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

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

/*DefinesCode_Start*/

/**** Macro Substitutions ****
a = Unique Reference
b = Switch Port Letter
c = Switch Pin Number
d = Switch Polarity Control
e = Switch Debounce Delay Value (us)
******************************/

#define %a_SW_PORT		port%b
#define %a_SW_TRIS		tris%b
#define %a_SW_PIN		%c
#define %a_SW_POLE		1 - %d
#define %a_SW_DELAY		%e * 1000

/*DefinesCode_End*/

/*InitialisationCode_Start*/
/*InitialisationCode_End*/

/*InterruptCode_Start*/
/*InterruptCode_End*/

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

MX_UINT8 ReadState( void )
{
/*Macro_ReadState_Start*/

	MX_UINT8 switchval, old_switchval;
  #if %a_SW_DELAY > 0
	MX_UINT16 del_count = 0;
  #endif

	FC_CAL_Bit_In_DDR( %a_SW_PORT , %a_SW_TRIS , %a_SW_PIN );
	switchval = FC_CAL_Bit_In( %a_SW_PORT , %a_SW_PIN );			//Convert pin to input
	old_switchval = switchval;

  #if %a_SW_DELAY > 0
	while (del_count < %a_SW_DELAY)									//Debounce input
	{
		delay_us(1);
		FC_CAL_Bit_In_DDR( %a_SW_PORT , %a_SW_TRIS , %a_SW_PIN );
		switchval = FC_CAL_Bit_In( %a_SW_PORT , %a_SW_PIN );		//Sample input

		if (switchval == old_switchval)								//Is switch the same state?
			del_count = del_count + 1;								//Increment counter
		else
			del_count = 0;											//Else reset counter

		old_switchval = switchval;									//Update the old state
	}
  #endif

	#if %a_SW_POLE == 0
		if (switchval)												//Invert logic if required
			switchval = 0;
		else
			switchval = 1;
	#endif

	return (switchval);												//Return state of switch as least significant bit

/*Macro_ReadState_End*/
}


void WaitUntilHigh( void )
{
/*Macro_WaitUntilHigh_Start*/

	MX_UINT8 switchval, old_switchval;
  #if %a_SW_DELAY > 0
	MX_UINT16 del_count = 0;
  #endif

	do
	{
		FC_CAL_Bit_In_DDR ( %a_SW_PORT , %a_SW_TRIS , %a_SW_PIN );
		switchval = FC_CAL_Bit_In ( %a_SW_PORT, %a_SW_PIN );		//Convert pin to input
		old_switchval = switchval;

	  #if %a_SW_DELAY > 0
		while (del_count < %a_SW_DELAY)									//Debounce input
		{
			delay_us(1);
			FC_CAL_Bit_In_DDR ( %a_SW_PORT , %a_SW_TRIS , %a_SW_PIN );
			switchval = FC_CAL_Bit_In ( %a_SW_PORT , %a_SW_PIN );	//Sample input

			if (switchval == old_switchval)								//Is switch the same state?
				del_count = del_count + 1;								//Increment counter
			else
				del_count = 0;											//Else reset counter

			old_switchval = switchval;									//Update the old state
		}
	  #endif

	} while (switchval != %a_SW_POLE);									//While state not active

	#if %a_SW_POLE == 0
		if (switchval)													//Invert logic if required
			switchval = 0;
		else
			switchval = 1;
	#endif

	//return (switchval);												//Return state of switch as least significant bit

/*Macro_WaitUntilHigh_End*/
}


void WaitUntilLow( void )
{
/*Macro_WaitUntilLow_Start*/

	MX_UINT8 switchval, old_switchval;
  #if %a_SW_DELAY > 0
	MX_UINT16 del_count = 0;
  #endif

	do
	{
		FC_CAL_Bit_In_DDR ( %a_SW_PORT, %a_SW_TRIS , %a_SW_PIN );
		switchval = FC_CAL_Bit_In ( %a_SW_PORT, %a_SW_PIN );			//Convert pin to input
		old_switchval = switchval;

	  #if %a_SW_DELAY > 0
		while (del_count < %a_SW_DELAY)									//Debounce input
		{
			delay_us(1);
			FC_CAL_Bit_In_DDR ( %a_SW_PORT, %a_SW_TRIS , %a_SW_PIN );
			switchval = FC_CAL_Bit_In ( %a_SW_PORT, %a_SW_PIN );		//Sample input

			if (switchval == old_switchval)								//Is switch the same state?
				del_count = del_count + 1;								//Increment counter
			else
				del_count = 0;											//Else reset counter

			old_switchval = switchval;									//Update the old state
		}
	  #endif

	} while (switchval == %a_SW_POLE);									//While state active

	#if %a_SW_POLE == 0
		if (switchval)													//Invert logic if required
			switchval = 0;
		else
			switchval = 1;
	#endif

	//return (switchval);												//Return state of switch as least significant bit

/*Macro_WaitUntilLow_End*/
}