/*********************************************************************
 *                    Flowcode RF Component Code
 *
 * File: PIC_RF.c
 *
 * (c) 2010 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
 * -------+----+-----------------------------------------------------
 * 201010 | BR | Created
 * 140111 | BR | Modification to code to fix a number of minor definition bugs
 * 110411 | ST | Major rewrite based on AVR code from SK
 * 090511 | BR | Updated to Seans latest version of the component
 * 220711 | BR | Fixed an issue with the RF port DDR being named TRIS
 * 240711 | SK | Fixed timing and shifting errors in code for software SPI.
 * 021111 | BR | Fixed a definitions bug for hardware SPI
 ********************************************************************/

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

 Return & parameter types:
   void
   char
   short
   char*

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

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

[Settings]
CLSID={065099EC-6FF8-4DB4-BEDE-B96B09787B31}
IsAnalogue=0
MultipleAllowed=1
Description=RF Flowcode Component

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

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

[Pins]
Count=0

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

[PinDesiredBit]

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

[PinMustUsePort]
# boolean

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

[PinMustUsePin]
# boolean

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

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

[MacroNames]
Count=25
1=SPI_Byte
2=SPI_Byte16
3=SPI_Command
4=Wait_For_SDI
5=Init_RF_Module
6=Uninit_RF_Module
7=Send_Byte
8=Send_String
9=Receive_Byte
10=Receive_String
11=Activate_RX_Mode
12=Activate_TX_Mode
13=Update_Centre_Frequency
14=Set_Sync_Pattern
15=RX_Tune
16=TX_Tune
17=Set_Data_Rate
18=Read_RX_Signal_Strength
19=FSK_Write
20=FSK_Read
21=Set_Buffer_Data
22=Send_Buffer
23=Check_Buffer
24=Get_Data_Count
25=Get_Buffer_Data

[MacroReturns]
1=char
2=void
3=short
4=void
5=short
6=void
7=void
8=void
9=char
10=char*
11=void
12=void
13=void
14=void
15=void
16=void
17=void
18=char
19=void
20=char
21=void
22=void
23=char
24=char
25=char

[MacroIsPrivate]
1=1
2=1
3=1
4=1
5=0
6=0
7=0
8=0
9=0
10=0
11=1
12=1
13=0
14=0
15=0
16=0
17=0
18=0
19=0
20=0
21=0
22=0
23=0
24=0
25=0

[MacroParameters_SPI_Byte]
Count=1
1=Data

[MacroParamTypes_SPI_Byte]
1=char

[MacroParameters_SPI_Byte16]
Count=1
1=spicmd

[MacroParamTypes_SPI_Byte16]
1=short

[MacroParameters_SPI_Command]
Count=1
1=spicmd

[MacroParamTypes_SPI_Command]
1=short

[MacroParameters_Wait_For_SDI]
Count=0

[MacroParamTypes_Wait_For_SDI]

[MacroParameters_Init_RF_Module]
Count=0

[MacroParamTypes_Init_RF_Module]

[MacroParameters_Uninit_RF_Module]
Count=0

[MacroParamTypes_Uninit_RF_Module]

[MacroParameters_Send_Byte]
Count=1
1=Data

[MacroParamTypes_Send_Byte]
1=char

[MacroParameters_Send_String]
Count=1
1=String

[MacroParamTypes_Send_String]
1=char*

[MacroParameters_Receive_Byte]
Count=1
1=Timeout

[MacroParamTypes_Receive_Byte]
1=char

[MacroParameters_Receive_String]
Count=2
1=Length
2=Timeout

[MacroParamTypes_Receive_String]
1=char
2=char

[MacroParameters_Activate_RX_Mode]
Count=0

[MacroParamTypes_Activate_RX_Mode]

[MacroParameters_Activate_TX_Mode]
Count=0

[MacroParamTypes_Activate_TX_Mode]

[MacroParameters_Update_Centre_Frequency]
Count=1
1=Frequency

[MacroParamTypes_Update_Centre_Frequency]
1=short

[MacroParameters_Set_Sync_Pattern]
Count=2
1=Mode
2=Pattern

[MacroParamTypes_Set_Sync_Pattern]
1=char
2=char

[MacroParameters_RX_Tune]
Count=3
1=Bandwidth
2=Gain
3=Threshold

[MacroParamTypes_RX_Tune]
1=char
2=char
3=char

[MacroParameters_TX_Tune]
Count=2
1=Deviation
2=Power

[MacroParamTypes_TX_Tune]
1=char
2=char

[MacroParameters_Set_Data_Rate]
Count=1
1=Rate

[MacroParamTypes_Set_Data_Rate]
1=char

[MacroParameters_Read_RX_Signal_Strength]
Count=0

[MacroParamTypes_Read_RX_Signal_Strength]

[MacroParameters_FSK_Write]
Count=1
1=State

[MacroParamTypes_FSK_Write]
1=char

[MacroParameters_FSK_Read]
Count=0

[MacroParamTypes_FSK_Read]

[MacroParameters_Set_Buffer_Data]
Count=2
1=Index
2=Data

[MacroParamTypes_Set_Buffer_Data]
1=char
2=char

[MacroParameters_Send_Buffer]
Count=1
1=Count

[MacroParamTypes_Send_Buffer]
1=char

[MacroParameters_Check_Buffer]
Count=1
1=Timeout

[MacroParamTypes_Check_Buffer]
1=char

[MacroParameters_Get_Data_Count]
Count=0

[MacroParamTypes_Get_Data_Count]

[MacroParameters_Get_Buffer_Data]
Count=1
1=Index

[MacroParamTypes_Get_Buffer_Data]
1=char

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

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

/*DefinesCode_Start*/

/**** Macro Substitutions ****
%a = SPI Bus HW / SW mode 0-SW / 1-HW SPI1 / 2-HW SPI2 / 3-HW SPI3
%b = SPI Port Letter
%c = FSEL Pin
%d = SPI MOSI Pin
%e = SPI MISO Pin
%f = SPI Clock Pin
%g = SPI Chip Select Pin
%h = Frequency Selection	1-433MHz  2-868MHz 3-915MHz
%i = Centre Frequency 		Channel selection - 96-3903	See Calculation p28
%j = Baud Rate 				See Calculation p37
%k = Receiver Bandwidth
%l = Receiver Gain
%m = Receiver Threshold
%n = Transmitter Deviation
%o = Transmitter Power Output
%p = Transmitter Duty Cycle Setting
%q = Data Mode
%r = Preamble Sync ID Value
%s = Extended Preamble Sync ID Enable
******************************/

//Duty cycle limit when using the 868MHz band in Europe

//common defines
#define %b_MX_RF_SPI_HW	%a			//SPI Hardware or Bitbanged Port Control
#define %b_MX_RF_PORT		port%b		//Port Connection
//#define MX_RF_PIN		lat%b		//Port Connection
#define %b_MX_RF_TRIS		tris%b		//DDR Connection
#define %b_MX_RF_FSEL		%c			//RFmodule - FSEL

#define %b_MX_RF_SDO		%d			//SPI - Data Out
#define %b_MX_RF_SDI	  	%e			//SPI - Data In
#define %b_MX_RF_SCK  		%f			//SPI - Clock

#define %b_MX_RF_SCS  		%g			//SPI - Chip Select
#define %b_MX_RF_FREQ  	%h			//Module Frequency
#define %b_MX_RF_CFREQ		%i			//Central Frequency 96 <-> 3903		(0x7D0)
#define %b_MX_RF_BAUD		%j			//Data Baud Rate					(0x23)
#define %b_MX_RF_BWIDTH	(%k + 1)	//Bandwithd 0= / 6=
#define %b_MX_RF_GAIN		%l			//Gain 0= / 3=
#define %b_MX_RF_THRESH	%m			//Threshold 0= / 5=
#define %b_MX_RF_DVN		%n			//Deviation 0=15KHz / 15=240KHz
#define %b_MX_RF_PWR		%o			//Power 0=0dB / 7=-17.5dB
#define %b_MX_RF_DATAMODE	%q			//Data mode - I/O or Data
#define %b_MX_RF_ID		%r				//Sync ID
#define %b_MX_RF_EXTID		((1 - %s) * 8)	//Extended Sync 0=Off / 1=On
#define %b_MX_RF_DUTY		%p
#define %b_MX_RF_TXPROP	((%b_MX_RF_DVN << 4) | %b_MX_RF_PWR)

// General commands
#define %b_GENCREG 	(0x8008 | (%b_MX_RF_FREQ << 4))	//RF_Frequency does not change....

#ifndef RFDEFS
	#define RFDEFS

	#define MX_RF_BUFFER_MAX	8

	#define PMCREG 		0x8200
	#define CFSREG		0xA000

	// Data commands
	#define DATARATE	0xC600
	#define SYNCHRON	0xCE00

	// RX commands
	#define RXCREG 		0x9000
	#define RXBREG		0xB000
	#define FIFORSTREG	0xCA81		//0xCA85
	#define BBFCREG 	0xC22C
	#define AFCCREG		0xC4D7

	// TX commands
	#define TXCREG		0x9800
	#define TXBREG 		0xB800

	// Preloaded commands with data

	#define PDOWN		0x8201

	// SPI Defines

	#ifdef MX_SPI_B
		#define %b_MX_RF_SDI_PORT	portb
	#endif

	#ifdef MX_SPI_C
		#define %b_MX_RF_SDI_PORT	portc
	#endif

	#ifdef MX_SPI_BCB
		#define %b_MX_RF_SDI_PORT	portb
	#endif
#endif


char %b_MX_RF_Mode;
char %b_MX_RF_Sync = %b_MX_RF_ID;
char %b_MX_RF_RX_Buffer[MX_RF_BUFFER_MAX + 2];
char %b_MX_RF_RX_Buff1[MX_RF_BUFFER_MAX + 2];
char %b_MX_RF_TX_Buffer[MX_RF_BUFFER_MAX + 2];

/*DefinesCode_End*/

/*InitialisationCode_Start*/
/*InitialisationCode_End*/

/*InterruptCode_Start*/
/*InterruptCode_End*/

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

char SPI_Byte(char Data)
{
/*Macro_SPI_Byte_Start*/

	char retVal = 0;

	#if (%b_MX_RF_SPI_HW == 0)
		char idx;
		for (idx = 0; idx < 8; idx++)
		{
			if (test_bit(Data, 7))
				set_bit(%b_MX_RF_PORT, %b_MX_RF_SDO);		// Set SDO bit
			else
				clear_bit(%b_MX_RF_PORT, %b_MX_RF_SDO);	// Clear SDO bit

			Data = Data << 1;

			set_bit(%b_MX_RF_PORT, %b_MX_RF_SCK);			// SCK Output 1

			delay_us(1);	//Added BR 06/10

			retVal = retVal << 1;

			if(test_bit(%b_MX_RF_PORT, %b_MX_RF_SDI))
				retVal = retVal | 0x01;
			else
				retVal = retVal & 0xFE;

			clear_bit(%b_MX_RF_PORT, %b_MX_RF_SCK);		// SCK Output 0

			delay_us(1);
		}
	#endif

	#if (%b_MX_RF_SPI_HW == 1)

		#ifndef MX_SPI
			#error Chip does not have SPI capability
		#endif

		sspbuf = Data;						//send a Char
		while ((sspstat & 0x01) == 0);		//wait until sspbuf is empty
		retVal = sspbuf;					//receive the Char

	#endif

  return(retVal);

/*Macro_SPI_Byte_End*/
}


void SPI_Byte16(short spicmd)
{
/*Macro_SPI_Byte16_Start*/

	SPI_Byte ((spicmd & 0xFF00) >> 8);					// Send Upper Command Byte
	SPI_Byte ((spicmd & 0x00FF));						// Send Lower Command Byte

/*Macro_SPI_Byte16_End*/
}


short SPI_Command(short spicmd)
{
/*Macro_SPI_Command_Start*/

	unsigned int retval;

	clear_bit(%b_MX_RF_PORT,%b_MX_RF_SCS);							// Clear Chip Select bit
	delay_us(1);
	retval = ( SPI_Byte ((spicmd & 0xFF00) >> 8) << 8);			// Send Upper Command Byte
	retval = retval | SPI_Byte ((spicmd & 0x00FF));				// Send Lower Command Byte
	delay_us(1);
	set_bit(%b_MX_RF_PORT,%b_MX_RF_SCS);								// Set Chip Select bit
	delay_us(1);
	return retval;

/*Macro_SPI_Command_End*/
}


void Wait_For_SDI (void)
{
/*Macro_Wait_For_SDI_Start*/

#if (%b_MX_RF_SPI_HW == 0)
	while(test_bit(%b_MX_RF_PORT, %b_MX_RF_SDI) == 0);			//Wait for SDI Input
#else
	while(test_bit(%b_MX_RF_SDI_PORT, MX_SPI_SDI) == 0);
#endif

/*Macro_Wait_For_SDI_End*/
}


short Init_RF_Module()
{
/*Macro_Init_RF_Module_Start*/

	unsigned int Retval;

	set_bit(%b_MX_RF_PORT, %b_MX_RF_SCS);
	clear_bit(%b_MX_RF_TRIS, %b_MX_RF_SCS);

  #if (%b_MX_RF_SPI_HW == 0)
	// Configure the I/O Pins
	clear_bit(%b_MX_RF_TRIS, %b_MX_RF_SDO);
	clear_bit(%b_MX_RF_TRIS, %b_MX_RF_SCK);
	set_bit(%b_MX_RF_TRIS, %b_MX_RF_SDI);

	clear_bit(%b_MX_RF_PORT, %b_MX_RF_SDO);
	clear_bit(%b_MX_RF_PORT, %b_MX_RF_SCK);
  #else

	//initialise spi
	#ifdef MX_SPI_B
	    set_bit(trisb,MX_SPI_SDI);
	    clear_bit(trisb,MX_SPI_SDO);
	    clear_bit(trisb,MX_SPI_SCK);
	#endif

	#ifdef MX_SPI_C
	    set_bit(trisc,MX_SPI_SDI);
	    clear_bit(trisc,MX_SPI_SDO);
	    clear_bit(trisc,MX_SPI_SCK);
	#endif

	#ifdef MX_SPI_BCB
	    set_bit(trisb,MX_SPI_SDI);
		clear_bit(trisc,MX_SPI_SDO);
		clear_bit(trisb,MX_SPI_SCK);
	#endif

	//configure SPI
	sspstat = 64;							// Configure SPI Peripheral

	#ifdef _BOOSTC
		#ifdef SSPCON							// SPI Low Speed for Initialise
			sspcon = 2;
			st_bit(sspcon, SSPEN);
		#endif
		#ifdef SSPCON1
			sspcon1 = 2;
			st_bit(sspcon1, SSPEN);
		#endif
	#endif

	#ifdef HI_TECH_C
		#ifdef sspcon							// SPI Low Speed for Initialise
			SSPCON = 2;
			st_bit(SSPCON, SSPEN);
		#endif
		#ifdef sspcon1
			SSPCON1 = 2;
			st_bit(SSPCON1, SSPEN);
		#endif
	#endif
  #endif

	delay_ms(100);								//100ms Delay to ensure transceiver has powered up

	// Configuring the RF link
	SPI_Command(FIFORSTREG);						//Disable (Sensitive) Reset Mode
	SPI_Command(FIFORSTREG | %b_MX_RF_EXTID | 0x02);	//Restart Synchronous character pattern recognition
	SPI_Command(%b_GENCREG);						//Assign frequency band and set load capacitance
	SPI_Command(CFSREG  | %b_MX_RF_CFREQ);			//Set Channel Center Frequency
	SPI_Command(DATARATE | %b_MX_RF_BAUD);			//Set Data Rate
	SPI_Command(PMCREG);						//Turn Off TX and RX controller chains

	Retval = (%b_MX_RF_BWIDTH << 5) | (%b_MX_RF_GAIN << 3) | %b_MX_RF_THRESH;
	SPI_Command(RXCREG | Retval);				//Enable Data RX Output / Set signal strengths and gain

	SPI_Command(SYNCHRON | %b_MX_RF_Sync);
	SPI_Command(TXCREG | %b_MX_RF_TXPROP);			//Set TX frequency deviation

	// Antenna Tuning
	SPI_Command( PMCREG | 0x0020);				//Turn on TX baseband circuit
	delay_ms(5);								//Wait for oscillatr to stabilise

	// Set Up The Receiver
	SPI_Command(PMCREG | 0x0080);				//Turn off Tx, turn on receiver

  #if (%b_MX_RF_DATAMODE == 1)
	SPI_Command(%b_GENCREG | 0x0040);				//Enable the FIFO
	SPI_Command(FIFORSTREG);
	SPI_Command(FIFORSTREG | %b_MX_RF_EXTID | 0x02);	//Restart Synchronous character pattern recognition

	set_bit(%b_MX_RF_PORT, %b_MX_RF_FSEL);
	clear_bit(%b_MX_RF_TRIS, %b_MX_RF_FSEL);
	%b_MX_RF_Mode = 0;
  #else
	set_bit(%b_MX_RF_TRIS, %b_MX_RF_FSEL);
	SPI_Command(%b_GENCREG);						//Leave the FIFO disabled
	%b_MX_RF_Mode = 2;
  #endif

	Retval = SPI_Command(0);					//Read back and return STSREG

	return (Retval);

/*Macro_Init_RF_Module_End*/
}


void Uninit_RF_Module (void)
{
/*Macro_Uninit_RF_Module_Start*/

	SPI_Command(PDOWN);

/*Macro_Uninit_RF_Module_End*/
}


void Send_Byte (char Data)
{
/*Macro_Send_Byte_Start*/

	Set_Buffer_Data(0, Data);					//Pass byte into send buffer
	Send_Buffer(1);								//Send buffer

/*Macro_Send_Byte_End*/
}


void Send_String (char* Data, char Length)
{
/*Macro_Send_String_Start*/

	char Ptr;
	char Length;

	Length = MSZ_String;

	for (Ptr = 0; Ptr < Length; Ptr++)		//For each character in string
	{
		Set_Buffer_Data(Ptr, String[Ptr]);	//Pass string into send buffer

		if (String[Ptr] == 0)				//Is there a null byte in the string?
			Length = Ptr;					//If so then we are at the end
	}
	Send_Buffer(Length);					//Send buffer

/*Macro_Send_String_End*/
}


char Receive_Byte (char Timeout)
{
/*Macro_Receive_Byte_Start*/

	char retVal;

	retVal = Check_Buffer(Timeout);				//Check for incoming data

	if (retVal == 1)							//If 1 byte received
		retVal = Get_Buffer_Data(0);			//Collect byte
	else
		return 255;								//Or return timeout err

	return retVal;

/*Macro_Receive_Byte_End*/
}


void Receive_String (char* FCR_RETVAL, char FCR_RETVAL_SIZE, char Length, char Timeout)
{
/*Macro_Receive_String_Start*/

	char dcount, idx;

	FCR_RETVAL[0] = 0;											//Begin by assigning null to string

	dcount = Check_Buffer(Timeout);								//Check for incoming data

	if (dcount < 250)											//Valid packet size received?
	{
		for (idx = 0; idx < Length; idx++)						//Loop through specified received bytes
		{
			if (idx < FCR_RETVAL_SIZE)							//Is there still room in the buffer?
			{
				if (idx < dcount)								//Have we received all available bytes?
				{
					FCR_RETVAL[idx] = Get_Buffer_Data(idx);		//Collect byte and add to string

					if (FCR_RETVAL[idx] == 0)					//If null byte received
						Length = idx;							//Finish collecting bytes
				}
			}
		}

		if (idx < FCR_RETVAL_SIZE)								//If string is not full
			FCR_RETVAL[idx] = 0;								//Then add a null byte just incase there was not one in the received data
	}

/*Macro_Receive_String_End*/
}


void Activate_RX_Mode (void)
{
/*Macro_Activate_RX_Mode_Start*/

	SPI_Command(PMCREG | 0x0080);			// turn off Tx, turn on the receiver

	if (%b_MX_RF_Mode == 0)					//Set system mode value
	{
		SPI_Command(%b_GENCREG | 0x0040);		// disable the Tx register, Enable the FIFO

		SPI_Command(FIFORSTREG);
		SPI_Command(FIFORSTREG | %b_MX_RF_EXTID | 0x0002);		// reset FIFO

		set_bit(%b_MX_RF_PORT, %b_MX_RF_FSEL);
		clear_bit(%b_MX_RF_TRIS, %b_MX_RF_FSEL);	//FSEL pin as output
	}
	else
	{
		set_bit(%b_MX_RF_TRIS, %b_MX_RF_FSEL);	//FSEL pin as input
		SPI_Command(%b_GENCREG);				//Leave the FIFO disabled
	}

/*Macro_Activate_RX_Mode_End*/
}


void Activate_TX_Mode (void)
{
/*Macro_Activate_TX_Mode_Start*/

	SPI_Command(PMCREG);					// Turn off the transmitter and receiver

	if (%b_MX_RF_Mode == 1)
	{
		SPI_Command(%b_GENCREG | 0x0080);		// Enable the Tx register
	}
	else
	{
		SPI_Command(%b_GENCREG);				// disable the Tx register and the FIFO
	}

	SPI_Command(PMCREG | 0x0020);			// Turn on tx

	set_bit(%b_MX_RF_PORT, %b_MX_RF_FSEL);
	clear_bit(%b_MX_RF_TRIS, %b_MX_RF_FSEL);	//FSEL pin as output

/*Macro_Activate_TX_Mode_End*/
}


void Update_Centre_Frequency (short Frequency)
{
/*Macro_Update_Centre_Frequency_Start*/

	if (Frequency < 96)
		Frequency = 96;

	if (Frequency > 3903)
		Frequency = 3903;

	SPI_Command(CFSREG | Frequency);

/*Macro_Update_Centre_Frequency_End*/
}


void Set_Sync_Pattern (char Mode, char Pattern)
{
/*Macro_Set_Sync_Pattern_Start*/

	%b_MX_RF_Sync = Pattern;

	FCD_RF0_SPI_Command(FIFORSTREG);

	if (Mode)
	{
		//Word type synchronisation
		SPI_Command(FIFORSTREG | 0x02);
	}
	else
	{
		//Byte type synchronisation
		SPI_Command(FIFORSTREG | 0x0a);
	}
	SPI_Command(SYNCHRON | %b_MX_RF_Sync);

/*Macro_Set_Sync_Pattern_End*/
}


void RX_Tune (char Bandwidth, char Gain, char Threshold)
{
/*Macro_RX_Tune_Start*/

	unsigned int TuneVals;

	if (Bandwidth > 6)
		Bandwidth = 6;

	if (Bandwidth < 1)
		Bandwidth = 1;

	if (Gain > 3)
		Gain = 3;

	if (Threshold > 5)
		Threshold = 5;

	TuneVals = RXCREG;
	TuneVals = TuneVals | (Bandwidth << 5);
	TuneVals = TuneVals | (Gain << 3);
	TuneVals = TuneVals | Threshold;

	SPI_Command(TuneVals);

/*Macro_RX_Tune_End*/
}


void TX_Tune (char Deviation, char Power)
{
/*Macro_TX_Tune_Start*/

	char %b_MX_RF_TXPROPs;

	if (Deviation > 15)
		Deviation = 15;

	if (Power > 7)
		Power = 7;

	%b_MX_RF_TXPROPs = Deviation << 4;
	%b_MX_RF_TXPROPs = %b_MX_RF_TXPROPs | Power;

	SPI_Command(TXCREG | %b_MX_RF_TXPROPs);

/*Macro_TX_Tune_End*/
}


void Set_Data_Rate (char Rate)
{
/*Macro_Set_Data_Rate_Start*/

	char cs = 0;
	unsigned long r;

	r = 100000 / (29 * Rate);			//10 x data rate value
	r = r + 5;							//round up
	r = r / 10;							//divide by 10

	if (r > 0x80)						//result too large
	{
		cs = 0x80;						//set cs bit
		r >>= 2;						//divide by 4
		if (r & 0x01)
			r = r + 1;					//round up
		r >>= 1;						//divide by 2
	}
	r = r - 1;

	SPI_Command(DATARATE | cs | (char)r);

/*Macro_Set_Data_Rate_End*/
}


char Read_RX_Signal_Strength (void)
{
/*Macro_Read_RX_Signal_Strength_Start*/

	unsigned int test = 0;

	test = SPI_Command(0);					//Read back and return STSREG
	test = test >> 6;						//Rotate so that data we want is one bits 0 and 1
	test = test & 0x07;						//Mask off any unwanted values

	return (test);

/*Macro_Read_RX_Signal_Strength_End*/
}

void FSK_Write (char State)
{
/*Macro_FSK_Write_Start*/

	if(%b_MX_RF_Mode != 3)
	{
		%b_MX_RF_Mode = 3;							//Set system mode value
		Activate_TX_Mode();
	}

	if(State)
		set_bit(%b_MX_RF_PORT, %b_MX_RF_FSEL);
	else
		clear_bit(%b_MX_RF_PORT, %b_MX_RF_FSEL);

/*Macro_FSK_Write_End*/
}

char FSK_Read (void)
{
/*Macro_FSK_Read_Start*/

	if (%b_MX_RF_Mode != 2)
	{
		%b_MX_RF_Mode = 2;
		Activate_RX_Mode();
	}

	return(test_bit(%b_MX_RF_PORT, %b_MX_RF_FSEL));

/*Macro_FSK_Read_End*/
}


void Set_Buffer_Data (char Index, char Data)
{
/*Macro_Set_Buffer_Data_Start*/

	if (Index < MX_RF_BUFFER_MAX)
		%b_MX_RF_TX_Buffer[Index + 1] = Data;

/*Macro_Set_Buffer_Data_End*/
}

void Send_Buffer (char Count)
{
/*Macro_Send_Buffer_Start*/

	char Data;
	char Ptr;
	char NextByte = 1;
	char Csum = 0;

	if (Count < MX_RF_BUFFER_MAX)
	{
		%b_MX_RF_TX_Buffer[0] = Count;

		//Calculate checksum
		for(Ptr = 0; Ptr <= Count; Ptr++)
			Csum = Csum ^ %b_MX_RF_TX_Buffer[Ptr];

		%b_MX_RF_TX_Buffer[Ptr] = Csum;

		//Include count and checksum
		Count = Count + 2;

		//Set Tx mode
		if (%b_MX_RF_Mode != 1)		//If we are in receive mode
		{
			%b_MX_RF_Mode = 1;
			Activate_TX_Mode();		//Switch to transmit mode
		}

		set_bit(%b_MX_RF_PORT, %b_MX_RF_FSEL);		// FSEL Output 1
		clear_bit(%b_MX_RF_PORT, %b_MX_RF_SCS);		// Clear Chip Select bit
		delay_us(1);

//		Wait_For_SDI();
		SPI_Byte16(TXBREG | 0xAA);				// preamble

#if (%b_MX_RF_EXTID == 0)
		Wait_For_SDI();							//Wait for SDI Input
		SPI_Byte16(TXBREG | 0x2D);				// sync pattern 1st byte (optional)
#endif

		Wait_For_SDI();							//Wait for SDI Input
		SPI_Byte16(TXBREG | %b_MX_RF_Sync);		// sync pattern 2nd byte

		Ptr = 0;

		Data = %b_MX_RF_TX_Buffer[Ptr];

		Ptr = Ptr + 1;

		while(NextByte)
		{
			Wait_For_SDI();						//Wait for SDI Input
			SPI_Byte16(TXBREG | Data);			// write byte to tx register

			Data =  %b_MX_RF_TX_Buffer[Ptr];

			Ptr = Ptr + 1;

			if(Ptr == Count)
				NextByte = 0;
		}

		Wait_For_SDI();							//Wait for SDI Input
		SPI_Byte16(TXBREG | 0x00);				// write a dummy byte since the previous byte is still in buffer

		Wait_For_SDI();							//Wait for SDI Input

		set_bit(%b_MX_RF_PORT, %b_MX_RF_SCS);				// Chip select high, end transmission

		%b_MX_RF_Mode = 0;
		Activate_RX_Mode();								//Switch to receive mode
	}

/*Macro_Send_Buffer_End*/
}

char Check_Buffer(char Timeout)
{
/*Macro_Check_Buffer_Start*/

	char ByteRx, Data;
	char LoopCount;
	char Ptr = 0;
	char NextByte = 1;
	char Count;
	char retVal = 255;
	char bCount = 0;
	char Csum = 0;

	/*	Return values
		255 = No data
		254 = Count error (data count > buffer)
		253 = Insufficient data/timeout during reception
		252 = Checksum error (TODO)
	*/

	if (%b_MX_RF_Mode != 0)					//If we are in transmit mode
	{
		%b_MX_RF_Mode = 0;
		Activate_RX_Mode();					//Switch to receive mode
	}

	//Get data count

	LoopCount = 0;
	ByteRx = 0;

	while((LoopCount < Timeout) && (ByteRx == 0))
	{
		clear_bit(%b_MX_RF_PORT, %b_MX_RF_SCS);	// Clear Chip Select bit
		delay_us(1);

		#if (%b_MX_RF_SPI_HW == 0)
			ByteRx = (test_bit(%b_MX_RF_PORT, %b_MX_RF_SDI));
		#else
			ByteRx = (test_bit(%b_MX_RF_PORT, MX_SPI_SDI));
		#endif

		set_bit(%b_MX_RF_PORT, %b_MX_RF_SCS);								// Set Chip Select bit

		if (ByteRx == 0)
			delay_us(100);

		LoopCount++;
	}

	if(ByteRx)
	{
		retVal = 254;		//Count received: default = count error
		clear_bit(%b_MX_RF_PORT, %b_MX_RF_FSEL);		// FSEL Output 0
		delay_us(1);

		Count = SPI_Byte(0);

		set_bit(%b_MX_RF_PORT, %b_MX_RF_FSEL);		// FSEL Output 1

		if (Count <= MX_RF_BUFFER_MAX)
		{
			retVal = 253;		//Receiving data: default = count match error
			%b_MX_RF_RX_Buff1[Ptr] = Count;
			Ptr = Ptr + 1;

			Count = Count + 2;		//Include count and checksum

			while(NextByte)
			{
				LoopCount = 0;
				ByteRx = 0;

				while((LoopCount < Timeout) && (ByteRx == 0))
				{
					set_bit(%b_MX_RF_PORT, %b_MX_RF_FSEL);		// FSEL Output 1
					delay_us(1);

					clear_bit(%b_MX_RF_PORT, %b_MX_RF_SCS);	// Clear Chip Select bit
					delay_us(1);

					#if (%b_MX_RF_SPI_HW == 0)
						ByteRx = (test_bit(%b_MX_RF_PORT, %b_MX_RF_SDI));
					#else
						ByteRx = (test_bit(%b_MX_RF_PORT, MX_SPI_SDI));
					#endif

					set_bit(%b_MX_RF_PORT, %b_MX_RF_SCS);								// Set Chip Select bit

					if (ByteRx == 0)
					{
						delay_us(100);
					}
					LoopCount = LoopCount + 1;
				}

				if(ByteRx)
				{
					clear_bit(%b_MX_RF_PORT, %b_MX_RF_FSEL);		// FSEL Output 0
					delay_us(1);

					%b_MX_RF_RX_Buff1[Ptr] = SPI_Byte(0);
					Ptr = Ptr + 1;

					bCount = 0;
				}
				else
				{
					bCount = bCount + 1;
					if (bCount == 100)
						NextByte = 0;
				}

				if(Ptr == Count)
				{
					NextByte = 0;

					for(Ptr = 0; Ptr < (Count - 1); Ptr++)
					{
						%b_MX_RF_RX_Buffer[Ptr] = %b_MX_RF_RX_Buff1[Ptr];
						Csum ^= %b_MX_RF_RX_Buffer[Ptr];
					}

					if (Csum == %b_MX_RF_RX_Buff1[Ptr])					//Is checksum ok?
						retVal = Count - 2;
					else
					{
						%b_MX_RF_RX_Buffer[1] = Csum;
						retVal = 252;									//Count and packet data received but checksum error
					}
				}
			}
		}
//		set_bit(%b_MX_RF_PORT, %b_MX_RF_FSEL);		// FSEL Output 1

//		SPI_Command(PMCREG);
//		SPI_Command(%b_GENCREG);
//		SPI_Command(%b_GENCREG | 0x0040);
//		SPI_Command(PMCREG | 0x0080);

		SPI_Command(FIFORSTREG);
		SPI_Command(FIFORSTREG | %b_MX_RF_EXTID | 0x0002);		// reset FIFO
	}

	set_bit(%b_MX_RF_PORT, %b_MX_RF_FSEL);			// FSEL Output 1
	set_bit(%b_MX_RF_PORT, %b_MX_RF_SCS);				// Chip select high, end transmission

	return (retVal);

/*Macro_Check_Buffer_End*/
}

char Get_Data_Count (void)
{
/*Macro_Get_Data_Count_Start*/

	return(%b_MX_RF_RX_Buffer[0]);

/*Macro_Get_Data_Count_End*/
}

char Get_Buffer_Data (char Index)
{
/*Macro_Get_Buffer_Data_Start*/

	if (Index < MX_RF_BUFFER_MAX)
		return(%b_MX_RF_RX_Buffer[Index + 1]);
	else
		return(0);

/*Macro_Get_Buffer_Data_End*/
}




