/*********************************************************************
 *                  Flowcode CAL IO File
 *
 * File: PIC_CAL_IO.h
 *
 * (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
 * -------+----+-----------------------------------------------------
 * 010911 | SK | Created
 * 050911 | BR | Added Bit manipulation expressions
 * 220812 | BR | Minor bug fix to allow 10F port pin access to work
 * 030413 | LM | FC6 Port/Pin macros
 * 220413 | LM | FC6 Port/Pin macros update
 * 220413 | LM | Use Latch for port reading, if we have one
 * 210613 | BR | Fixed an issue with outputting 0 to a single bit using the Output Icon - BoostC () Bug
 * 250913 | LM | FC6 Port/Pin macros update
 */


// FC6 Port/Pin macros


#define FCP_GET(Type, Port, Mask, Shift) FCP_GET_##Type(##Port, Mask, Shift)
#define FCP_SET(Type, Port, Mask, Shift, Source) FCP_SET_##Type(##Port, Mask, Shift, Source)

#define FCP_GET_B(Port, Mask, Shift)   (FC_CAL_Port_In_DDR__x((&FCP_PORT_##Port), (&FCP_TRIS_##Port), (Mask), (Shift)))
#define FCP_GET_M(Port, Mask, Shift)   (FC_CAL_Port_In_DDR__x((&FCP_PORT_##Port), (&FCP_TRIS_##Port), (Mask), (Shift)))
#define FCP_GET_F(Port, Mask, Shift)   (FC_CAL_Port_In_DDR__x((&FCP_PORT_##Port), (&FCP_TRIS_##Port), (Mask), (Shift)))

#ifdef FC_USEGPIO
  #define FCP_SET_B(p, m, b, v) {FC_CAL_Port_Out_DDR__x((&FCP_PORT_##p), (m), (v) << (b))}
  #define FCP_SET_M(p, m, b, v) {FC_CAL_Port_Out_DDR__x((&FCP_PORT_##p), (m), (v) << (b))}
  #define FCP_SET_F(p, m, b, v) {FC_CAL_Port_Out_DDR__x((&FCP_PORT_##p), (m), (v) << (b))}
#else
  #ifdef FC_USE10F
    #define FCP_SET_B(p, m, b, v) {FC_CAL_Port_Out_DDR__x((&FCP_PORT_##p), (m), (v) << (b))}
    #define FCP_SET_M(p, m, b, v) {FC_CAL_Port_Out_DDR__x((&FCP_PORT_##p), (m), (v) << (b))}
    #define FCP_SET_F(p, m, b, v) {FC_CAL_Port_Out_DDR__x((&FCP_PORT_##p), (m), (v) << (b))}
  #else
    #define FCP_SET_B(Port, Mask, Shift, Source)    {MX_UINT8 ptmp = (Source); FCP_TRIS_##Port &= ~Mask; (ptmp) ? (FCP_PORT_##Port = FCP_LAT_##Port | Mask) : (FCP_PORT_##Port = FCP_LAT_##Port & ~Mask);}
    #define FCP_SET_M(Port, Mask, Shift, Source)    {MX_UINT8 ptmp = (Source); FCP_TRIS_##Port &= ~Mask; FCP_PORT_##Port = (FCP_LAT_##Port & ~Mask) | (((ptmp) << Shift) & Mask);}
    #define FCP_SET_F(Port, Mask, Shift, Source)    {MX_UINT8 ptmp = (Source); FCP_TRIS_##Port = 0; FCP_PORT_##Port = (ptmp);}
  #endif
#endif


//Port Functions
void FC_CAL_Port_Out__x (char* Port, MX_UINT8 OutMask, MX_UINT8 OutValue);
void FC_CAL_Port_Out_DDR__x (char* Port, char* Tris, MX_UINT8 OutMask, MX_UINT8 OutValue);
MX_UINT8 FC_CAL_Port_In__x (MX_UINT8* Port, MX_UINT8 InMask, MX_UINT8 Shift);
MX_UINT8 FC_CAL_Port_In_DDR__x (MX_UINT8* Port, MX_UINT8* Tris, MX_UINT8 InMask, MX_UINT8 Shift);


//Pin Functions
#ifndef MX_10F_TRIS
 #define FC_CAL_Bit_In(A, B)				test_bit(A, B)
 #define FC_CAL_Bit_In_DDR(A, B, C)			set_bit(B, C)
 #define FC_CAL_Bit_High(A, B)				set_bit(A, B)
 #define FC_CAL_Bit_High_DDR(A, B, C)		{clear_bit(B, C); set_bit(A, C);}
 #define FC_CAL_Bit_Low(A, B)				clear_bit(A, B)
 #define FC_CAL_Bit_Low_DDR(A, B, C)		{clear_bit(B, C); clear_bit(A, C);}
#else
 #define FC_CAL_Bit_In(A, B)				test_bit(A, B)
 #define FC_CAL_Bit_In_DDR(A, B, C)			{set_bit(tvar, C); asm("movf(_tvar),w"); asm("tris 6");}
 #define FC_CAL_Bit_High(A, B)				set_bit(A, B)
 #define FC_CAL_Bit_High_DDR(A, B, C)		{clear_bit(tvar, C); asm("movf(_tvar),w"); asm("tris 6"); set_bit(A, C);}
 #define FC_CAL_Bit_Low(A, B)				clear_bit(A, B)
 #define FC_CAL_Bit_Low_DDR(A, B, C)		{clear_bit(tvar, C); asm("movf(_tvar),w"); asm("tris 6"); clear_bit(A, C);}
#endif

MX_UINT8 FC_CAL_Bit_I(MX_UINT8 prt, MX_UINT8 bt, MX_UINT8 ddr);
void FC_CAL_Bit_O(MX_UINT8 prt, MX_UINT8 bt, MX_UINT8 ddr, MX_UINT8 data);

//Pointer Functions
#define FC_CAL_Port_Out(p, v, m)     	FC_CAL_Port_Out__x(&port##p, (v), (m))
#define FC_CAL_Port_Out_DDR(p, v, m) 	FC_CAL_Port_Out_DDR__x(&port##p, &tris##p, (v), (m))
#define FC_CAL_Port_In(p, m)		 	FC_CAL_Port_In__x(&port##p, (m))
#define FC_CAL_Port_In_DDR (p, m)	 	FC_CAL_Port_In_DDR__x(&port##p, &tris##p, (m))

#ifdef _BOOSTC
	#ifdef LATA
		#define FCP_LAT_A lata
	#else
		#define FCP_LAT_A FCP_PORT_A
	#endif
	#ifdef PORTA
		#define FCP_PORT_A porta
		#define FCP_TRIS_A trisa
	#endif
	#ifdef GPIO
	  #ifndef FCP_PORT_A
		#define FCP_PORT_A gpio
		#define FCP_TRIS_A trisio
	  #endif
	#endif
	#ifdef LATB
		#define FCP_LAT_B latb
	#else
		#define FCP_LAT_B FCP_PORT_B
	#endif
	#ifdef PORTB
		#define FCP_PORT_B portb
		#define FCP_TRIS_B trisb
	#endif
	#ifdef LATC
		#define FCP_LAT_C latc
	#else
		#define FCP_LAT_C FCP_PORT_C
	#endif
	#ifdef PORTC
		#define FCP_PORT_C portc
		#define FCP_TRIS_C trisc
	#endif
	#ifdef LATD
		#define FCP_LAT_D latd
	#else
		#define FCP_LAT_D FCP_PORT_D
	#endif
	#ifdef PORTD
		#define FCP_PORT_D portd
		#define FCP_TRIS_D trisd
	#endif
	#ifdef LATE
		#define FCP_LAT_E late
	#else
		#define FCP_LAT_E FCP_PORT_E
	#endif
	#ifdef PORTE
		#define FCP_PORT_E porte
		#define FCP_TRIS_E trise
	#endif
	#ifdef LATF
		#define FCP_LAT_F latf
	#else
		#define FCP_LAT_F FCP_PORT_F
	#endif
	#ifdef PORTF
		#define FCP_PORT_F portf
		#define FCP_TRIS_F trisf
	#endif
	#ifdef LATG
		#define FCP_LAT_G latg
	#else
		#define FCP_LAT_G FCP_PORT_G
	#endif
	#ifdef PORTG
		#define FCP_PORT_G portg
		#define FCP_TRIS_G trisg
	#endif
	#ifdef LATH
		#define FCP_LAT_H lath
	#else
		#define FCP_LAT_H FCP_PORT_H
	#endif
	#ifdef PORTH
		#define FCP_PORT_H porth
		#define FCP_TRIS_H trish
	#endif
	#ifdef LATJ
		#define FCP_LAT_J latj
	#else
		#define FCP_LAT_J FCP_PORT_J
	#endif
	#ifdef PORTJ
		#define FCP_PORT_J portj
		#define FCP_TRIS_J trisj
	#endif
#endif

#ifdef HI_TECH_C
	#ifdef lata
		#define FCP_LAT_A LATA
	#else
		#define FCP_LAT_A FCP_PORT_A
	#endif
	#ifdef porta
		#define FCP_PORT_A PORTA
		#define FCP_TRIS_A TRISA
	#endif
	#ifdef gpio
	  #ifndef FCP_PORT_A
		#define FCP_PORT_A GPIO
		#define FCP_TRIS_A TRISIO
	  #endif
	#endif
	#ifdef latb
		#define FCP_LAT_B LATB
	#else
		#define FCP_LAT_B FCP_PORT_B
	#endif
	#ifdef portb
		#define FCP_PORT_B PORTB
		#define FCP_TRIS_B TRISB
	#endif
	#ifdef latc
		#define FCP_LAT_C LATC
	#else
		#define FCP_LAT_C FCP_PORT_C
	#endif
	#ifdef portc
		#define FCP_PORT_C PORTC
		#define FCP_TRIS_C TRISC
	#endif
	#ifdef latd
		#define FCP_LAT_D LATD
	#else
		#define FCP_LAT_D FCP_PORT_D
	#endif
	#ifdef portd
		#define FCP_PORT_D PORTD
		#define FCP_TRIS_D TRISD
	#endif
	#ifdef late
		#define FCP_LAT_E LATE
	#else
		#define FCP_LAT_E FCP_PORT_E
	#endif
	#ifdef porte
		#define FCP_PORT_E PORTE
		#define FCP_TRIS_E TRISE
	#endif
	#ifdef latf
		#define FCP_LAT_F LATF
	#else
		#define FCP_LAT_F FCP_PORT_F
	#endif
	#ifdef portf
		#define FCP_PORT_F PORTF
		#define FCP_TRIS_F TRISF
	#endif
	#ifdef latg
		#define FCP_LAT_G LATG
	#else
		#define FCP_LAT_G FCP_PORT_G
	#endif
	#ifdef portg
		#define FCP_PORT_G PORTG
		#define FCP_TRIS_G TRISG
	#endif
	#ifdef lath
		#define FCP_LAT_H LATH
	#else
		#define FCP_LAT_H FCP_PORT_H
	#endif
	#ifdef porth
		#define FCP_PORT_H PORTH
		#define FCP_TRIS_H TRISH
	#endif
	#ifdef latj
		#define FCP_LAT_J LATJ
	#else
		#define FCP_LAT_J FCP_PORT_J
	#endif
	#ifdef portj
		#define FCP_PORT_J PORTJ
		#define FCP_TRIS_J TRISJ
	#endif
#endif

