#include <avr/io.h>
#include <avr/interrupt.h>
#include "global.h"
#include "rf12.h"

#define F_CPU 8000000UL
#include <util/delay.h>

#define RF_PORT	PORTB
#define RF_DDR	DDRB
#define RF_PIN	PINB

#define SDO		2
#define SDI		3
#define SCK		4
#define CS		5

unsigned short rf12_trans(unsigned short wert)
{	unsigned char i;

	cbi(RF_PORT, CS);
	for (i=0; i<16; i++)
	{	if (wert&32768)
			sbi(RF_PORT, SDI);
		else
			cbi(RF_PORT, SDI);
		wert<<=1;
		if (RF_PIN&(1<<SDO))
			wert|=1;
		sbi(RF_PORT, SCK);
		asm("nop");
		asm("nop");
		cbi(RF_PORT, SCK);
	}
	sbi(RF_PORT, CS);
	return wert;
}

void rf12_init(void)
{
	RF_DDR=(1<<SDI)|(1<<SCK)|(1<<CS);
	RF_PORT=(1<<CS);

	for (unsigned char i=0; i<50; i++)
		_delay_ms(10);			// wait until POR done
	rf12_trans(0xC0E0);			// AVR CLK: 10MHz
	rf12_trans(0x80E7);			// Enable FIFO
	rf12_trans(0xC2AB);			// Data Filter: internal
	rf12_trans(0xCA81);			// Set FIFO mode
	rf12_trans(0xE000);			// disable wakeuptimer
	rf12_trans(0xC800);			// disable low duty cycle
	rf12_trans(0xC4F7);			// AFC settings: autotuning: -10kHz...+7,5kHz
	rf12_trans(0xA6F8);
	rf12_trans(0x948C);
	rf12_trans(0xC610);
	rf12_trans(0x9870);
}

void rf12_ready(void)
{	cbi(RF_PORT, SDI);
	cbi(RF_PORT, CS);
	asm("nop");
	while (!(RF_PIN&(1<<SDO))); // wait until FIFO ready
}

void rf12_txdata(unsigned char *data, unsigned char number)
{	unsigned char i;
	rf12_trans(0x8238);			// TX on
	rf12_ready();
	rf12_trans(0xB8AA);
	rf12_ready();
	rf12_trans(0xB8AA);
	rf12_ready();
	rf12_trans(0xB8AA);
	rf12_ready();
	rf12_trans(0xB82D);
	rf12_ready();
	rf12_trans(0xB8D4);
	for (i=0; i<number; i++)
	{		rf12_ready();
		rf12_trans(0xB800|(*data++));
	}
	rf12_ready();
	_delay_us(10);
	rf12_trans(0x8208);			// TX off
}

void rf12_rxdata(unsigned char *data, unsigned char number)
{	unsigned char i;
	rf12_trans(0x82C8);			// RX on
	rf12_trans(0xCA81);			// set FIFO mode
	rf12_trans(0xCA83);			// enable FIFO
	for (i=0; i<number; i++)
	{	rf12_ready();
		*data++=rf12_trans(0xB000);
	}
	rf12_trans(0x8208);			// RX off
}

