// Code Funkmodul RFM12B - SENDEN (03.04.2013)

// *************************************************************
// **************  Einbindung weiterer Funktionen  *************
// *************************************************************

#include <C:\cc5\16F627A.H>
#include <C:\cc5\int16CXX.H>

// *************************************************************
// ***********  Einstellung Konfiguration Prozessor  ***********
// *************************************************************

#pragma config |= 0b.10.0001.0011.0000

// Globale Konstanten

bit MOSI @ PORTA.0;     	// SDI (Output)
bit nSEL @ PORTA.2;     	// nSEL (Output)
bit SCK @ PORTA.1;      	// SCK (Output)
bit MISO @ PORTA.7;     	// SDO (Input)
bit NIRQ @ PORTA.6;     	// NIRQ (Input)
bit LED1 @ PORTB.7;			// LED 1
bit LED2 @ PORTB.5;			// LED 2
bit Switch @ PORTB.6;   	// Schalter
bit UntenRechts @ PORTB.4;	// Kontroll-Pin unten rechts

// *************************************************************
// *********************  Prozedur: Pause  *********************
// *************************************************************

void pause(uns16 ms)			// Unterprogramm zum Abwarten einer
	{					// angegebenen Anzahl von Millisekunden
	
	while(ms)			// Schleife verlassen, wenn ms=0 ist
   		{
		OPTION = 2;		// Vorteiler auf 8 einstellen
		TMR0 = 131;		// 125 * 8 = 1000 (= 1 ms)
		while (TMR0);		// Abwarten einer Millisekunde
		ms--;			// "ms" mit jeder Millisekunde erniedrigen
		}
	}

// *************************************************************
// ***************  Prozedur: RFM12B_PORT_INIT  ****************
// *************************************************************

void RFM12B_PORT_INIT(void)
	{
	nSEL = 1;
	SCK = 0;
    MOSI = 0;
    pause(100);
	}

// *************************************************************
// ******************  Funktion: RFM12B_CMD  *******************
// *************  Send commands and receive data  **************
// *************************************************************

int16 RFM12B_CMD(uns16 cmd)
	{
	uns8 i;
    int16 temp;

    temp = 0;
    SCK = 0;
    nSEL = 0;

    for (i=0;i<16;i++)
   		{
		if (cmd & 0x8000)
			{
        	MOSI = 1;
      		}
      	else
      		{
         	MOSI = 0;
      		}

		#asm
			nop
			nop
			nop
			nop
		#endasm
   
   		SCK = 1;

    	#asm
			nop
			nop
			nop
			nop
		#endasm
      
   		temp = temp << 1;
      
   		if (MISO)
   			{
        	temp |= 0x0001;
        	}

		SCK = 0;
      	cmd = cmd << 1;
   		}

	nSEL = 1;

	return temp;
	}

// *************************************************************
// **************  Funktion: RFM12B_WAIT_READY  ****************
// ***********  Wait for RFM12B to be ready (FFIT)  ************
// *************************************************************

void RFM12B_WAIT_READY(void)
	{
	nSEL = 0;
    while(MISO); // Wait for Statusbit (FFIT) ready
	}

// *************************************************************
// *****************  Funktion: RFM12B_READ  *******************
// *************  Wait and read a byte from FIFO  **************
// *************************************************************

int16 RFM12B_READ(void)
	{
    int16 data;
   
    RFM12B_WAIT_READY();
    data = RFM12B_CMD(0xB000); // Read Data

    return(data & 0x00FF);
	}

// *************************************************************
// *****************  Funktion: RFM12B_WRITE  ******************
// **********************  Write a byte  ***********************
// *************************************************************

void RFM12B_WRITE(int abyte)
	{
    RFM12B_WAIT_READY();
    RFM12B_CMD(0xB800 + abyte); // Write Data
	}

// *************************************************************
// *****************  Funktion: RFM12B_INIT  *******************
// ***********  Initalise as a sender or a receiver  ***********
// *************************************************************

void RFM12B_INIT(int type)
	{
    RFM12B_PORT_INIT();

    if (type)
		{
		// Init Sender
		RFM12B_CMD(0x80A7); // Configuration Command
   		}
	else
   		{
		// Init Receive
		RFM12B_CMD(0x8067); // Configuration Command   
		}

    // General Init
	RFM12B_CMD(0x8208); // Power Management Command
    RFM12B_CMD(0xA680); // Frequency Command
    RFM12B_CMD(0xC647); // Datarate Command
    RFM12B_CMD(0x94A0); // Receiver Control Command
    RFM12B_CMD(0xC2AB); // Datafilter Command
    RFM12B_CMD(0xCA81); // FIFO / Reset Mode Command
    RFM12B_CMD(0xCED4); // Synchron Pattern Command
    RFM12B_CMD(0xC4F7); // AFC Command
    RFM12B_CMD(0x9850); // TX Configuration Command
    RFM12B_CMD(0xCC77); // PLL Command
    RFM12B_CMD(0xE000); // Wake-Up Timer Command
    RFM12B_CMD(0xC800); // Low Duty-Cycle Command
    RFM12B_CMD(0xC040); // LB Det./Clock Div. Command
	}

// *************************************************************
// *****************  Funktion: RFM12B_SEND  *******************
// *******************  Send multiple bytes  *******************
// *************************************************************

// void RFM12B_SEND(int8 ptr, int8 size)
void RFM12B_SEND(const char *ptr, int8 size)
	{
    int16 i;

    RFM12B_CMD(0x8238); // Enable Sender
   
    RFM12B_WRITE(0xAA); // Preamble
    RFM12B_WRITE(0xAA); // Preamble
    RFM12B_WRITE(0xAA); // Preamble
   
    RFM12B_WRITE(0x2D); // Sync HighByte
    RFM12B_WRITE(0xD4); // Sync LowByte
   
    for (i=0;i<size;i++)
		{
		RFM12B_WRITE(*ptr); // DATA Byte
		ptr++;
   		}
   
	RFM12B_WRITE(0xAA); // Dummy Byte
	RFM12B_WRITE(0xAA); // Dummy Byte
	RFM12B_WRITE(0xAA); // Dummy Byte
    RFM12B_WAIT_READY();
    RFM12B_CMD(0x8208); // Disable Sender
	}

// *************************************************************
// ***************  Funktion: RFM12B_RECEIVE  ******************
// *****************  Receive multiple bytes  ******************
// *************************************************************

void RFM12B_RECEIVE(int8 *ptr, int8 size)
	{
    int16 i;

    RFM12B_CMD(0x82C8); // Init Receiver
    RFM12B_CMD(0xCA81); // Enable FIFO
    RFM12B_CMD(0xCA83); // Clear FIFO
   
    for (i=0;i<size;i++)
    	{
		*ptr = RFM12B_READ(); // Send Data <= CC5X Compiler
						// meckert, Syntax richtig aber
	}                     	// Code kann nicht kompiliert
						// werden
   
	RFM12B_CMD(0x8208); // Disable Receiver
	}

// *************************************************************
// *************************************************************
// *********************  Hauptroutine  ************************
// *************************************************************
// *************************************************************
void main(void)
	{
	OSCF = 1;     // interner Takt: 4 MHz
	CMCON = 0b.111;

	PORTA = 0;
	PORTB = 0;

	TRISA = 0b.1100.0000;
	TRISB = 0b.0100.0001;

// CODE FÜR SENDER: /////////////////////////////////////////////

	RFM12B_INIT(1);		// Parametrierung als Sender

	pause(100);

	while(1)
		{
		LED1 = 1;

		RFM12B_SEND("Hallo",5);

		pause(2000);

		LED1 = 0;

		pause(2000);
		}

// CODE FÜR EMPFÄNGER: //////////////////////////////////////////

	RFM12B_INIT(0);		// Parametrierung als Sender

	pause(100);

	int buffi[5];

	while(1)
		{
		RFM12B_RECEIVE(buffi,5);

		if (buffi == "Hallo")
			{
			LED1 = 1;
			pause(5000);
			}
		else
			{
			LED1 = 0;
			}
		}
	}