
#include <avr/io.h>
#include <util/delay.h>

#define PORT	PORTA
#define PIN		PINA
#define DDR		DDRA

#define SS		0	//Slave Select Pin
#define SDI		1	//Serial Data In Pin -> MOSI
#define SDO		2	//Serial Data Out Pin -> MISO
#define SCK		3	//Serial Clock Bit Pin
#define NIRQ	4	//Input Request Out
#define FSK		6	//FSK/DATA/nFFS
#define DCLK	7	//DCLK/CFIL/FFIT


void setBit(unsigned char bit) {
    PORT |= (1 << bit);
}

void clearBit(unsigned char bit) {
	PORT &= (0xff ^ (1 << bit));
}

unsigned char readBit(unsigned char bit) {
	return(PIN & (0x00 | (1 << bit)));
}

void init_ports(){

	PORT = 0x00;
	DDR =  	0b00001011;

	setBit(SS);
	//_delay_us(0.01);	//warten bis SS angekommen ist
	for (unsigned char i=0;i<10;i++)
		_delay_ms(10);			// warten bis Power on Reset(POR) durchgeführt ist
}

unsigned short SDIO16(unsigned short data){	//16Bit senden und empfangen
	unsigned char i;
	unsigned short x;

	clearBit(SS);		//ChipSelect aus
	_delay_us(0.01);

	for(i=15;i>0;i--){
		x=data;
		if((x & (1 << i))>0)			//Bit i senden
			setBit(SDI);
		else
			clearBit(SDI);
		_delay_us(0.01);			//SDI braucht 5ns zum übernehmen, SDO 10ns bis es nach SCK anliegt
		x=readBit(SDO);
		if(x != 0x00){				//Bit i empfangen
			data |= (1 << i);
		}
		else{
			data &= (0xffff ^ (1 << i));
		}

		_delay_us(0.015);			//SCK muss mind. 25ns gleich bleiben
		setBit(SCK);
		_delay_us(0.03);		//mind. 25ns warten bis Register geschoben
		clearBit(SCK);
	}

	setBit(SS);			//ChipSelect an
	_delay_us(0.01);

	return(data);
}


void init_RFM12() {


	//Setzen der Umgebungsvariablen die vom POR abweichen
	SDIO16(0x80A7);			// aktiviert internes Dataregister, 868MHz Freqenzband, el=1, 80D7?
	SDIO16(0xC060);			// AVR CLK: 2MHz
	//SDIO16(0xC2AC);			// Data Filter: internal, DQD Thresholdparameter=4
	//SDIO16(0xCA81);			// FIFO 8Bit-IT, FIFO-SyncPatternStart aus, deaktiviert Resetmode (weil zu empfindlich auf Spannungsschwankungen)
	//SDIO16(0xE000);			// disable wakeuptimer
	//SDIO16(0xC800);			// deaktiviert Stromsparmodus
	//SDIO16(0xA680);			// Frequenzfeintuning
	//SDIO16(0x948C);			// VDI output, fast VDI, 200kHz Bandbreite, -6dB Verstärkung, -79dB Threshold
	//SDIO16(0xC610);			// Übertragungsgeschwindigkeit
	SDIO16(0x9860);			// 105 kHz Frequenzshift, volle Sendeleistung


}


void rf12_ready(void)		// Bit0 vom Statusregister lesen (TX ready)
{	
	clearBit(SS);
	_delay_us(1);
	while (!(PIN & (1<<SDO))); 	// warten bis FIFO fertig
	setBit(SS);
	_delay_us(1);
}


void rf12_txdata(unsigned char *data, unsigned char number)
{	
	unsigned char i;

	//SDIO16(0xB8AA);
	//rf12_ready();
	//SDIO16(0xB8AA);
	//rf12_ready();
	SDIO16(0x8238);			// TX an
	rf12_ready();

	SDIO16(0xB8AA);
	rf12_ready();
	SDIO16(0xB8AA);
	rf12_ready();
	SDIO16(0xB8AA);
	rf12_ready();
	SDIO16(0xB82D);
	rf12_ready();
	SDIO16(0xB8D4);
	for (i=0; i<number; i++)
	{		rf12_ready();
		SDIO16(0xB800|(*data++));
	}
	rf12_ready();
	SDIO16(0x8208);			// TX aus
}

void rf12_rxdata(unsigned char *data, unsigned char number)
{	unsigned char i;
	SDIO16(0x82C8);			// RX an
	SDIO16(0xCA81);			// FIFO mode setzen
	SDIO16(0xCA83);			// FIFO an
	for (i=0; i<number; i++)
	{	rf12_ready();
		*data++=SDIO16(0xB000);
	}
	SDIO16(0x8208);			// RX aus
}


void receive(void)
{	unsigned char test[32];	
	rf12_rxdata(test,32);	
	// daten verarbeiten
	/*for (unsigned char i=0; i<50; i++)
			_delay_ms(10);
	*/
}

void send(void)
{	
	unsigned char test[]="Dies ist ein 868MHz Test !!!\n   ";	
	rf12_txdata(test,32);
	//for (unsigned char i=0; i<5; i++)
	//		_delay_ms(10);
}


int main( void ) {
	
	init_ports();
	init_RFM12();

	for (;;)
	{
		send();
		//receive();

		SDIO16(0x0000);		//Statusregister auslesen (Anzeige per LEDs hier nicht drin)
		_delay_ms(50);		
	}
}
