/*********************************************************************
 *                  Flowcode RS232 Component Code
 *
 * File: RS232.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
 * -------+----+-----------------------------------------------------
 * 230407 | ST | Created
 * 160108 | BR | Added Error messages
 * 260309 | BR | Moves private functions from AddDefines section
 * 260309 | BR | Added 7 & 9 bit functionality  and String functions
 * 170409 | BR | Modified parameter order for RX String function
 * 130509 | BR | Added % definitions to DefinesCode section
 * 100909 | ST | Fixed errors with RTS and CTS definitions (when used in hardware f/c mode)
 * 100909 | BR | Added HiTECH compatible defines
 * 161209 | BR | Fixed the 9-bit reception
 * 010211 | BR | Attempt to fix a bug on some 18F devices where data is not being transferred correctly
 * 230311 | BR | Changed code to work for hitech and boostc without ifdefs
 * 240511 | BR | Updated software UART baud rate to try to get it more reliable
 * 240611 | BR | Added the watchdog clear command to the software UART delay mechanism
 * 270611 | MW | Added extra delay option for clock speeds under 6MHz
 * 110711 | SK | Fixed bug in <ReceiveRS232String>
 * 190711 | ST | Rescued file after a dodgy commit
 * 010911 | BR | Converted to Universal RS232 Component Code File
 * 011211 | BR | Converted to new dynamic defines mechanism
 * 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={7A37AFCE-0B5A-4084-B3D3-C0FD2A50E165}
IsAnalogue=0
MultipleAllowed=1
Description=RS232 Flowcode Component

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

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

[Pins]
Count=2
1=RX
2=TX

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

[PinDesiredBit]
1=0
2=1

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

[PinMustUsePort]
# boolean
1=1
2=1

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

[PinMustUsePin]
# boolean
1=1
2=1

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

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

NOTE: For simulation to work, these macros _MUST_ remain at the indicated index:
	1=SendRS232Char
	2=SendRS232String
	3=ReceiveRS232Char
	4=ReceiveRS232String

[MacroNames]
Count=4
1=SendRS232Char
2=SendRS232String
3=ReceiveRS232Char
4=ReceiveRS232String

[MacroReturns]
1=void
2=void
3=MX_SINT16
4=MX_STRING

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


[MacroParameters_SendRS232Char]
Count=1
1=nChar

[MacroParamTypes_SendRS232Char]
1=MX_SINT16


[MacroParameters_SendRS232String]
Count=1
1=String

[MacroParamTypes_SendRS232String]
1=MX_STRING


[MacroParameters_ReceiveRS232Char]
Count=1
1=nTimeout

[MacroParamTypes_ReceiveRS232Char]
1=MX_SINT16


[MacroParameters_ReceiveRS232String]
Count=2
1=nTimeout
2=NumBytes

[MacroParamTypes_ReceiveRS232String]
1=MX_UINT8
2=MX_UINT8


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

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

/*DefinesCode_Start*/

/**** Macro Substitutions ****
a = Unique Reference
b = Uart Channel		(0-software / 1-4 hardware)
c = tx pin
d = tx port
e = rx pin
f = rx port
g = flow control		(0-Off / 1-On)
h = cts pin
i = cts port
j = rts pin
k = rts port
l = baud rate
m = data bits			(7/8/9) (7 only supported in software modes)
n = return type		(0-byte / 1-MX_UINT16)
o = echo enable		(0-Off / 1-On)
******************************/

//Definitions for RS232 UART slot allocation
#ifndef	MX_UART_REF1
	#define MX_UART_REF1
	#define %a_MX_UART_UREF			1
	#define MX_UART_CHANNEL_1		%b
	#define MX_UART_TX_PIN_1		%c
	#define MX_UART_TX_PORT_1		port%d
	#define MX_UART_TX_TRIS_1		tris%d
	#define MX_UART_RX_PIN_1		%e
	#define MX_UART_RX_PORT_1		port%f
	#define MX_UART_RX_TRIS_1		tris%f
	#define MX_UART_FLOWEN_1		%g
	#define MX_UART_CTS_PIN_1		%h
	#define MX_UART_CTS_PORT_1		port%i
	#define MX_UART_CTS_TRIS_1		tris%i
	#define MX_UART_RTS_PIN_1		%j
	#define MX_UART_RTS_PORT_1		port%k
	#define MX_UART_RTS_TRIS_1		tris%k
	#define MX_UART_BAUD_1			%l
	#define MX_UART_DBITS_1			%m
	#define MX_UART_RETURN_1		%n
	#define MX_UART_ECHO_1			%o
	#define MX_UART_INT_1			0
#else
 #ifndef	MX_UART_REF2
	#define MX_UART_REF2
	#define %a_MX_UART_UREF			2
	#define MX_UART_CHANNEL_2		%b
	#define MX_UART_TX_PIN_2		%c
	#define MX_UART_TX_PORT_2		port%d
	#define MX_UART_TX_TRIS_2		tris%d
	#define MX_UART_RX_PIN_2		%e
	#define MX_UART_RX_PORT_2		port%f
	#define MX_UART_RX_TRIS_2		tris%f
	#define MX_UART_FLOWEN_2		%g
	#define MX_UART_CTS_PIN_2		%h
	#define MX_UART_CTS_PORT_2		port%i
	#define MX_UART_CTS_TRIS_2		tris%i
	#define MX_UART_RTS_PIN_2		%j
	#define MX_UART_RTS_PORT_2		port%k
	#define MX_UART_RTS_TRIS_2		tris%k
	#define MX_UART_BAUD_2			%l
	#define MX_UART_DBITS_2			%m
	#define MX_UART_RETURN_2		%n
	#define MX_UART_ECHO_2			%o
	#define MX_UART_INT_2			0
 #else
  #ifndef	MX_UART_REF3
	#define MX_UART_REF3
	#define %a_MX_UART_UREF			3
	#define MX_UART_CHANNEL_3		%b
	#define MX_UART_TX_PIN_3		%c
	#define MX_UART_TX_PORT_3		port%d
	#define MX_UART_TX_TRIS_3		tris%d
	#define MX_UART_RX_PIN_3		%e
	#define MX_UART_RX_PORT_3		port%f
	#define MX_UART_RX_TRIS_3		tris%f
	#define MX_UART_FLOWEN_3		%g
	#define MX_UART_CTS_PIN_3		%h
	#define MX_UART_CTS_PORT_3		port%i
	#define MX_UART_CTS_TRIS_3		tris%i
	#define MX_UART_RTS_PIN_3		%j
	#define MX_UART_RTS_PORT_3		port%k
	#define MX_UART_RTS_TRIS_3		tris%k
	#define MX_UART_BAUD_3			%l
	#define MX_UART_DBITS_3			%m
	#define MX_UART_RETURN_3		%n
	#define MX_UART_ECHO_3			%o
	#define MX_UART_INT_3			0
  #else
   #ifndef	MX_UART_REF4
	#define MX_UART_REF4
	#define %a_MX_UART_UREF			4
	#define MX_UART_CHANNEL_4		%b
	#define MX_UART_TX_PIN_4		%c
	#define MX_UART_TX_PORT_4		port%d
	#define MX_UART_TX_TRIS_4		tris%d
	#define MX_UART_RX_PIN_4		%e
	#define MX_UART_RX_PORT_4		port%f
	#define MX_UART_RX_TRIS_4		tris%f
	#define MX_UART_FLOWEN_4		%g
	#define MX_UART_CTS_PIN_4		%h
	#define MX_UART_CTS_PORT_4		port%i
	#define MX_UART_CTS_TRIS_4		tris%i
	#define MX_UART_RTS_PIN_4		%j
	#define MX_UART_RTS_PORT_4		port%k
	#define MX_UART_RTS_TRIS_4		tris%k
	#define MX_UART_BAUD_4			%l
	#define MX_UART_DBITS_4			%m
	#define MX_UART_RETURN_4		%n
	#define MX_UART_ECHO_4			%o
	#define MX_UART_INT_4			0
   #endif
  #endif
 #endif
#endif

#define %a_UART_Init		CAL_APPEND(FC_CAL_UART_Init_, %a_MX_UART_UREF)
#define %a_UART_Send		CAL_APPEND(FC_CAL_UART_Send_, %a_MX_UART_UREF)
#define %a_UART_Receive		CAL_APPEND(FC_CAL_UART_Receive_, %a_MX_UART_UREF)

extern void %a_UART_Init();
extern void %a_UART_Send(MX_UINT8 nChar);
extern MX_SINT16 %a_UART_Receive(MX_UINT8 nTimeout);

/*DefinesCode_End*/

/*InitialisationCode_Start*/

	%a_UART_Init( );		//Call initialise function

/*InitialisationCode_End*/

/*InterruptCode_Start*/
/*InterruptCode_End*/


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


void SendRS232Char(MX_SINT16 nChar)
{
/*Macro_SendRS232Char_Start*/

	%a_UART_Send ( nChar);

/*Macro_SendRS232Char_End*/
}


void SendRS232String(MX_STRING String, MX_UINT8 MSZ_String)
{
/*Macro_SendRS232String_Start*/

	MX_UINT8 idx;
	for(idx = 0; idx < MSZ_String; idx++)
	{
		if (String[idx] == 0)
			break;
		else %a_UART_Send ( String[idx] );
	}

/*Macro_SendRS232String_End*/
}


MX_SINT16 ReceiveRS232Char(MX_UINT8 nTimeout)
{
/*Macro_ReceiveRS232Char_Start*/

	return ( %a_UART_Receive ( nTimeout) );

/*Macro_ReceiveRS232Char_End*/
}


void ReceiveRS232String(MX_STRING FCR_RETVAL, MX_UINT8 FCR_RETVAL_SIZE, MX_UINT8 nTimeout, MX_UINT8 NumBytes)
{
/*Macro_ReceiveRS232String_Start*/

	MX_UINT8 idx;
	MX_SINT16 RS232_TO = 255;
	MX_SINT16 in;

	if ( %n != 0 )
		RS232_TO = 256;

	if (NumBytes > FCR_RETVAL_SIZE)
		NumBytes = FCR_RETVAL_SIZE;

	for (idx = 0; idx < NumBytes; idx++)
	{
		in = %a_UART_Receive ( nTimeout);
		if(in < RS232_TO)
			FCR_RETVAL[idx] = in & 0xFF;
		else
			break;
	}

	if (idx < FCR_RETVAL_SIZE)
		FCR_RETVAL[idx] = 0;

/*Macro_ReceiveRS232String_End*/
}

