#include <avr/io.h>
#include <util/delay.h>


#define nSEL        (1<<2)      //PD2
#define nIRQ        (1<<2)      //PB2
#define RF_SDO      (1<<4)      //PB4
#define LCD_SDIN    (1<<3)
#define LCD_SCK     (1<<5)

#define PORT_nSEL PORTB
#define PORT_nIRQ PORTD
#define PORT_SDIN PORTB
#define PORT_RF_SDO PORTB
#define PORT_SCK PORTB
#define PORT_RF_nIRQ PORTB

#define RF_SDO_HI()	PORT_RF_SDO & RF_SDO
#define nIRQ_HI()	PORT_RF_nIRQ & nIRQ

#define setb_nsel()	PORT_nSEL |= nSEL
#define clrb_nsel()	PORT_nSEL &= ~nSEL

#define setb_sck()	PORT_SCK |= LCD_SCK
#define clrb_sck()	PORT_SCK &= ~LCD_SCK

#define setb_rf_sdi()	PORT_SDIN |= LCD_SDIN
#define clrb_rf_sdi()	PORT_SDIN &= ~LCD_SDIN


#define BPS_4800	71
#define BPS_9600	35
#define BPS_19200	17
#define BPS_28800	11
#define BPS_38400	8
#define BPS_57600	5
#define BPS_115200	2

#define RGIT_FITT	32768
#define POR		16384
#define FFOV_RGUR	8192
#define WKUP		4096
#define EXT		2048
#define LBD		1024
#define FFEM		512
#define RSSI_ATS	256
#define DQD		128
#define CRL		64
#define ATGL		32



unsigned short rfxx_wrt_cmd(unsigned short aCmd) {
	unsigned char i;
	unsigned short temp=0;

	clrb_sck();
	clrb_nsel();
	for(i=0;i<16;i++) {
		if(aCmd&0x8000) {
			setb_rf_sdi();
		} else {
			clrb_rf_sdi();
		}
		setb_sck();
		temp<<=1;
		if(RF_SDO_HI()) temp |= 1;
		clrb_sck();
		aCmd<<=1;
	}
	setb_nsel();
	return temp;
}

void rf12_init (void) {
	rfxx_wrt_cmd(0x80d7);
	rfxx_wrt_cmd(0x8239+4);	// *8239 for Tx, 82D9 for Rx (+4 eb, LowBattEn)
	rfxx_wrt_cmd(0xa640);	// Frequency Setting Command	/96-3903/
	rfxx_wrt_cmd(0xc647);	// Data Rate Command		/kbps/
	rfxx_wrt_cmd(0x94a0);	// Receiver Control Command	/BandWidth/
	rfxx_wrt_cmd(0xc2ac);	// Data Filter Command 0xc2ac
	rfxx_wrt_cmd(0xca81);
	rfxx_wrt_cmd(0xced4);
	rfxx_wrt_cmd(0xc483);	// AFC 0xc483
	rfxx_wrt_cmd(0x9850);	// Tx Control Command		/deviation/
	rfxx_wrt_cmd(0xcc17);
	rfxx_wrt_cmd(0xe000);
	rfxx_wrt_cmd(0xc800);
	rfxx_wrt_cmd(0xc040);
}

void rf12_freq(unsigned short f)
{
	rfxx_wrt_cmd( (0xa640 & 0xf000) | f );	// Frequency Setting Command	/96-3903 (0x0F3F)/
}

void rf12_speed(unsigned char r)
{
	unsigned char i, m;

	if(r > 0x08) { i = 0xc0; m = 0x20; }
	if(r > 0x04 && r < 0x09) { i = 0xa0; m = 0x50; }
	if(r < 0x03) { i = 0x80; m = 0x70; }

	rfxx_wrt_cmd(0xc600 | (r & 0x7f));				// Data Rate Command
	rfxx_wrt_cmd( (0x94a0 & 0b1111111100011111) | i );		//Receiver Control Command	/BandWidth/
	rfxx_wrt_cmd( (0x9850 & 0xff0f) | m);				//Tx Control Command		/deviation/
	_delay_ms(1);

/*
	Data Rate [bps]	Bandwidth [KHz]	Modulation (Deviation) [KHz]
		1200		67		45
		2400		67		45
		4800		67		45	R = 0x47	i = 0xc0	m = 2
		9600		67		45	R = 0x23	i = 0xc0	m = 2
		19200		67		45	R = 0x11	i = 0xc0	m = 2
		38400		134		90	R = 0x08	i = 0xa0	m = 5
		57600		134		90	R = 0x05	i = 0xa0	m = 5
		115200		200		120	R = 0x02	i = 0x80	m = 7
*/
}

void tx_mode(void) {
	rfxx_wrt_cmd(0x8239);	//*8239 for Tx, 82D9 for Rx (+4 eb, LowBattEn)
}

void rx_mode(void) {
	rfxx_wrt_cmd(0x82D9);	//*8239 for Tx, 82D9 for Rx (+4 eb, LowBattEn)
}

void rf12_off(void) {
	rfxx_wrt_cmd(0x8201);	//Stand By
}

void rf12_send(unsigned char aByte) {
	while(nIRQ_HI());
	rfxx_wrt_cmd(0xb800+aByte);
}

unsigned char rf12_recv(void) {
	unsigned short fifo_data=0;
	while(nIRQ_HI());
		rfxx_wrt_cmd(0);
		fifo_data=rfxx_wrt_cmd(0xb000);
	return (fifo_data & 0x00ff);
}


int main()
{
	DDRD = (1<<PD0) | (1<<PD1); // PD0, PD1 Output for LEDs
	DDRB |= nSEL | RF_SDO | LCD_SCK; // For FRM12B Pins
	PORTC |= (1<<PC4) | (1<<PC5); // Pullup resistor on PC4, PC5
	PORTD |= (1<<PD2);


	rf12_init();
	tx_mode();

	while(1)
	{

		if(!(PINC & (1<<PC4)))
		{
			PORTD |= (1<<PD0);
			rf12_send(0x32);
		}else
		PORTD &=~(1<<PD0);
		
	
		if(!(PINC & (1<<PC5)))
		{
			PORTD |= (1<<PD1);
			rf12_send(0x7F);
		}else
		PORTD &=~(1<<PD1);

	}
	return 0;
}
