/*********************************************************************
 *                    Flowcode RF Component Code
 *
 * File: PIC16BIT_RF.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
 * -------+----+-----------------------------------------------------
 * 201010 | BR | Created
 * 140111 | BR | Modification to code to fix a number of minor definition bugs
 ********************************************************************/

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

 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=0
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=18
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

[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

[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

[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=2
1=Data
2=Length

[MacroParamTypes_Send_String]
1=char*
2=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]

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

/********************************************************************
 * 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 MX_RF_SPI_HW  	%a			//SPI Hardware or Bitbanged Port Control
#define MX_RF_PORT		PORT%b		//Port Connection
#define MX_RF_TRIS		TRIS%b		//DDR Connection
#define MX_RF_FSEL  	%c			//RFmodule - FSEL
#define MX_RF_SDO		%d			//SPI - Data Out
#define MX_RF_SDI	  	%e			//SPI - Data In
#define MX_RF_SCK  		%f			//SPI - Clock
#define MX_RF_SCS  		%g			//SPI - Chip Select
#define MX_RF_FREQ  	%h			//Module Frequency
#define MX_RF_CFREQ		%i			//Central Frequency 96 <-> 3903
#define MX_RF_BAUD		%j			//Data Baud Rate
#define MX_RF_BWIDTH	%k			//Bandwithd 0= / 6=
#define MX_RF_GAIN		%l			//Gain 0= / 3=
#define MX_RF_THRESH	%m			//Threshold 0= / 5=
#define MX_RF_DVN		%n			//Deviation 0=15KHz / 15=240KHz
#define MX_RF_PWR		%o			//Power 0=0dB / 7=-17.5dB
#define MX_RF_DATAMODE	%q			//Data mode - I/O or Data
#define MX_RF_ID		%r			//Sync ID
#define MX_RF_EXTID		%s			//Extended Sync 0x00=Off / 0x08=On
#define MX_RF_DUTY		%p


//--------------------------------------------------------------------
// MRF49XA Static Defines:
//--------------------------------------------------------------------
#define NODATA 			0
#define DATA_RECEIVED 	1
#define PACKET_RECEIVED	2
#define	PAYLOAD_MAX		20

//--------------------------------------------------------------------
// MRF49XA SPI commands:
//--------------------------------------------------------------------

// General commands
#define GENCREG 	(0x8008 | (MX_RF_FREQ << 4))	//RF_Frequency does not change....
#define PMCREG 		0x8208
#define CFSREG		0xA000

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

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

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

// Preloaded commands with data
#define TXCREGPRE	((TXCREG | (MX_RF_DVN << 4)) | MX_RF_PWR)
#define CFSREGPRE	(CFSREG | MX_RF_CFREQ)
#define SYNCHPRE	(SYNCHRON | MX_RF_ID)
#define FIFORSPRE	(FIFORSTREG | MX_RF_EXTID)

#define PDOWN		0x8201

char RX_Mode = 0;

/*DefinesCode_End*/

/*InitialisationCode_Start*/
/*InitialisationCode_End*/

/*InterruptCode_Start*/
/*InterruptCode_End*/

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

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

	char retVal = 0;

	#if (MX_RF_SPI_HW == 0)
		char idx;
		for (idx = 0; idx < 8; idx++)
		{
			if (test_bit(Data, 7))
				set_bit(MX_RF_PORT, MX_RF_SDO);		// Set SDO bit
			else
				clear_bit(MX_RF_PORT, MX_RF_SDO);	// Clear SDO bit

			Data = Data << 1;

			set_bit(MX_RF_PORT, MX_RF_SCK);			// SCK Output 1

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

			if(test_bit(MX_RF_PORT, MX_RF_SDI))
				retVal = retVal | 0x01;
			else
				retVal = retVal & 0xFE;

			clear_bit(MX_RF_PORT, MX_RF_SCK);		// SCK Output 0
		}
	#endif

	#if (MX_RF_SPI_HW == 1)
		SPI1BUF = Data;							//send a dummy byte
		while (SPI1STATbits.SPIRBF == 0);		//wait until data has been sent
		retVal = SPI1BUF;						//receive the byte
	#endif

	#if (MX_RF_SPI_HW == 2)
		SPI2BUF = Data;							//send a dummy byte
		while (SPI2STATbits.SPIRBF == 0);		//wait until data has been sent
		retVal = SPI2BUF;						//receive the byte
	#endif

	#if (MX_RF_SPI_HW == 3)
		SPI3BUF = Data;							//send a dummy byte
		while (SPI3STATbits.SPIRBF == 0);		//wait until data has been sent
		retVal = SPI3BUF;						//receive the byte
	#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(MX_RF_PORT,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(MX_RF_PORT,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*/

	while(test_bit(MX_RF_PORT, MX_RF_SDI) == 0);			//Wait for SDI Input

/*Macro_Wait_For_SDI_End*/
}


short Init_RF_Module()
{
/*Macro_Init_RF_Module_Start*/

	unsigned int Retval;

	#if (MX_RF_SPI_HW == 0)

		// Configure the I/O Pins
		set_bit(MX_RF_PORT, MX_RF_SCS);
		clear_bit(MX_RF_TRIS, MX_RF_SCS);

		clear_bit(MX_RF_TRIS, MX_RF_SDO);
		clear_bit(MX_RF_PORT, MX_RF_SDO);

		clear_bit(MX_RF_TRIS, MX_RF_SCK);
		clear_bit(MX_RF_PORT, MX_RF_SCK);

		set_bit(MX_RF_TRIS, MX_RF_SDI);

	#endif

	#if (MX_RF_SPI_HW == 1)
		#ifndef MX_SPI1
			#error Chip does not have SPI port 1 capability
		#endif
		#ifdef MX_SPI1_PORT_FREEALLOC
			#ifdef MX_SPI1_ALT
				//configure remapping
				RPINR20 = (RPINR20 & 0xFF00) | 0x0E;	//Assign SDI - RP14 / PORTB14
				RPOR4 = (RPOR4 & 0x00FF) | 0x0800;		//Assign SCK - RP9  / PORTB9
				RPOR7 = (RPOR7 & 0x00FF) | 0x0700;		//Assign SDO - RP15 / PORTB15
			#else
				//configure remapping
				RPINR20 = (RPINR20 & 0xFF00) | 0x04;	//Assign SDI - RP4 / PORTB4
				RPOR1 = (RPOR1 & 0x00FF) | 0x0800;		//Assign SCK - RP3 / PORTB3
				RPOR2 = (RPOR2 & 0x00FF) | 0x0700;		//Assign SDO - RP5 / PORTB5
			#endif
		#else
			#ifdef MX_SPI1_PORT_E16ALLOC
				//configure remapping
				RPINR20 = (RPINR20 & 0xFF00) | 0x11;	//Assign SDI - RP17 / PORTC1
				RPOR7 = (RPOR7 & 0x00FF) | 0x0800;		//Assign SCK - RP15 / PORTB15
				RPOR8 = (RPOR8 & 0xFF00) | 0x0007;		//Assign SDO - RP16 / PORTC0
			#else
				#ifdef dsPIC30
					#define SPI1CON1		SPI1CON
					#define SPI1CON1bits	SPI1CONbits
				#endif
			#endif
		#endif
		SPI1CON1 = 0x011F;
		SPI1CON1bits.MSTEN = 1;		//master mode
		SPI1STATbits.SPIROV = 0;	//clear unread data flag
		SPI1STATbits.SPIEN = 1;		//enable SPI peripheral
	#endif

	#if (MX_RF_SPI_HW == 2)
		#ifndef MX_SPI2
			#error Chip does not have SPI port 2 capability
		#endif
		#ifdef MX_SPI2_PORT_FREEALLOC
			//configure remapping
			RPINR22 = (RPINR22 & 0xFF00) | 0x0E;	//Assign SDI - RP14 / PORTB14
			RPOR6 = (RPOR6 & 0x00FF) | 0x0B00;		//Assign SCK - RP13 / PORTB13
			RPOR7 = (RPOR7 & 0x00FF) | 0x0A00;		//Assign SDO - RP15 / PORTB15
		#else
			#ifdef MX_SPI2_PORT_E16ALLOC
				//configure remapping
				RPINR22 = (RPINR22 & 0xFF00) | 0x14;	//Assign SDI - RP20 / PORTC4
				RPOR12 = (RPOR12 & 0xFF00) | 0x000B;	//Assign SCK - RP24 / PORTC8
				RPOR10 = (RPOR10 & 0x00FF) | 0x0A00;	//Assign SDO - RP21 / PORTC5
			#else
				#ifdef dsPIC30
					#define SPI2CON1		SPI2CON
					#define SPI2CON1bits	SPI2CONbits
				#endif
			#endif
		#endif
		SPI2CON1 = 0x011F;
		SPI2CON1bits.MSTEN = 1;		//master mode
		SPI2STATbits.SPIROV = 0;	//clear unread data flag
		SPI2STATbits.SPIEN = 1;		//enable SPI peripheral
	#endif

	#if (MX_RF_SPI_HW == 3)
		#ifndef MX_SPI3
			#error Chip does not have SPI port 3 capability
		#endif
		#ifdef MX_SPI3_PORT_FREEALLOC
			//configure remapping
			RPINR28 = (RPINR28 & 0xFF00) | 0x19;	//Assign SDI - RP25 / PORTD4
			RPOR11 = (RPOR11 & 0xFF00) | 0x21;		//Assign SCK - RP22 / PORTD5
			RPOR10 = (RPOR10 & 0xFF00) | 0x20;		//Assign SDO - RP20 / PORTD3
		#endif
		SPI3CON1 = 0x011F;
		SPI3CON1bits.MSTEN = 1;		//master mode
		SPI3STATbits.SPIROV = 0;	//clear unread data flag
		SPI3STATbits.SPIEN = 1;		//enable SPI peripheral
	#endif

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

	// Configuring the RF link
	SPI_Command(FIFORSPRE);						//Disable (Sensitive) Reset Mode
	SPI_Command(FIFORSPRE | 0x02);				//Restart Synchronous character pattern recognition
	SPI_Command(GENCREG);						//Assign frequency band and set load capacitance
	//SPI_Command(AFCCREG);						//Enable AFC function
	SPI_Command(CFSREG  | MX_RF_CFREQ);			//Set Channel Center Frequency
	SPI_Command(DATARATE | MX_RF_BAUD);			//Set Data Rate
	SPI_Command(PMCREG);						//Turn Off TX and RX controller chains

	Retval = RXCREG;							//Enable Data RX Output / Set signal strengths and gain
	Retval = Retval | (MX_RF_BWIDTH << 5);
	Retval = Retval | (MX_RF_GAIN << 3);
	Retval = Retval | MX_RF_THRESH;
	SPI_Command(Retval);

	SPI_Command(SYNCHPRE);
	SPI_Command(TXCREG | 0x0030);				//Set TX modulation to 60khz

	// 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
	SPI_Command(GENCREG | 0x0040);				//Enable the FIFO
	SPI_Command(FIFORSPRE);
	SPI_Command(FIFORSPRE | 0x02);				//Restart Synchronous character pattern recognition

	set_bit(MX_RF_PORT, MX_RF_FSEL);
	clear_bit(MX_RF_TRIS, MX_RF_FSEL);

	//Need a better way of confirming initialisation

	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*/

	if (RX_Mode == 0)			//If we are in receive mode
		Activate_TX_Mode();		//Switch to transmit mode

	Send_String (&Data, 1, 1);

/*Macro_Send_Byte_End*/
}


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

	unsigned int idx = 0;

	if (RX_Mode == 0)			//If we are in receive mode
		Activate_TX_Mode();		//Switch to transmit mode

	clear_bit(MX_RF_PORT, MX_RF_SCS);					// Clear Chip Select bit

	//delay_us(1);

	SPI_Byte16(TXBREG | 0xAA);							// preamble
	Wait_For_SDI();										//Wait for SDI Input
	SPI_Byte(0x2D);										// sync pattern 1st byte
	Wait_For_SDI();										//Wait for SDI Input
	SPI_Byte(0xD4);										// sync pattern 2nd byte
	Wait_For_SDI();										//Wait for SDI Input
	SPI_Byte(Length);

	for (idx=0; idx<Length; idx++)
	{													// send payload
		Wait_For_SDI();									//Wait for SDI Input
		SPI_Byte(Data[idx]); 							// write a byte to tx register
	}

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

	Wait_For_SDI();										//Wait for SDI Input

	set_bit(MX_RF_PORT, MX_RF_SCS);					// Chip select high, end transmission

/*Macro_Send_String_End*/
}


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

	char retVal;

	if (RX_Mode == 1)						//If we are in transmit mode
		Activate_RX_Mode();					//Switch to receive mode

	Receive_String(&retVal, 1, 1, Timeout);

	return retVal;

/*Macro_Receive_Byte_End*/
}


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

	static char PacketLen = 0;
	static unsigned int nrbytes = 0;
	char bl;

	if (RX_Mode == 1)						//If we are in transmit mode
		Activate_RX_Mode();					//Switch to receive mode

	//delay_us(1);

	clear_bit(MX_RF_PORT, MX_RF_SCS);								// Clear Chip Select bit

	//delay_us(1);

	if (test_bit(MX_RF_PORT, MX_RF_SDI))
	{

		set_bit(MX_RF_PORT, MX_RF_SCS);								// Set Chip Select bit
		clear_bit(MX_RF_PORT, MX_RF_FSEL);							// FSEL Output 0

		if(PacketLen)												// is this the first byte?
		{
			FCR_RETVAL[(nrbytes++)] = SPI_Byte(0);					// number of bytes in payload is the first byte

			if (nrbytes >= PacketLen)								// end of packet?
			{
				SPI_Command(FIFORSPRE);								// reset FIFO
				set_bit(MX_RF_PORT, MX_RF_FSEL);					// FSEL Output 1
				Length = nrbytes;
				nrbytes = 0;
				PacketLen = 0;
				return;
			}
		}
		else														// First byte already received
		{
			bl = SPI_Byte(0);

			if((bl > 0) && (bl < PAYLOAD_MAX))						// Check if correct number of bytes in payload
			{
				PacketLen = bl;
				nrbytes = 0;
			}
			else
			{
				set_bit(MX_RF_PORT, MX_RF_FSEL);					// FSEL Output 1

				SPI_Command(PMCREG);								// turn off tx and rx
				SPI_Command(FIFORSPRE);								// reset FIFO
				SPI_Command(GENCREG);								// disable FIFO , Tx_latch
				SPI_Command(GENCREG | 0x0040);						// enable the FIFO
				SPI_Command(PMCREG | 0x0080);						// turn on receiver
				SPI_Command(FIFORSPRE | 0x02);   					// FIFO syncron latch re-enable
				Length = 0;
				return;
			}
		}

		set_bit(MX_RF_PORT, MX_RF_FSEL);							// FSEL Output 1
		return;
	}
	else
	{
		set_bit(MX_RF_PORT, MX_RF_SCS);								// Set Chip Select bit
		Length = 0;
		return;
	}

/*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
	SPI_Command(GENCREG | 0x0040);			// disable the Tx register, Enable the FIFO

	RX_Mode = 0;							//Clear software mode flag

/*Macro_Activate_RX_Mode_End*/
}


void Activate_TX_Mode (void)
{
/*Macro_Activate_TX_Mode_Start*/

	SPI_Command(PMCREG);					// Turn off the transmitter and receiver
	SPI_Command(GENCREG | 0x0080);			// Enable the Tx register
	SPI_Command(PMCREG  | 0x0020);			// Turn on tx

	RX_Mode = 1;							//Set software mode flag

/*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*/

	if (Mode)
		Mode = 0x08;

	#undef FIFORSPRE
	#define FIFORSPRE	(FIFORSTREG | Mode)

	if (Mode)
	{
		//Word type synchronisation
		FCD_RF0_SPI_Command(FIFORSPRE);
		FCD_RF0_SPI_Command(SYNCHRON | Pattern);
	}
	else
	{
		//Byte type synchronisation
		FCD_RF0_SPI_Command(FIFORSPRE);
		FCD_RF0_SPI_Command(SYNCHRON | Pattern);
	}

/*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*/

	unsigned int TuneVals;

	if (Deviation > 15)
		Deviation = 15;

	if (Power > 7)
		Power = 7;

	TuneVals = TXCREG;
	TuneVals = TuneVals | (Deviation << 4);
	TuneVals = TuneVals | Power;

	SPI_Command(TuneVals);

/*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 += 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 >> 7;						//Rotate so that data we want is one bits 0 and 1
	test = test & 0x03;						//Mask off any unwanted values

	return (test);

/*Macro_Read_RX_Signal_Strength_End*/
}
