/*	mija 2008
      	demo for RFM01 - RX 868MHz
		
	  	CPU ATMEGA8
      	fcpu = 1MHz

	  	!! define PIN,PORT,DDR for IOpin !!

		tested with module RFM12B - TX,9600,Fdev 15kHz
*/

#include <avr/io.h>
#include <util/delay.h>
#include "RFM01.h"

//************************************************************************

#define SDI    		PB3
 #define SDI_PORT	PORTB
 #define SDI_DDR	DDRB

#define FSK    		PC1
 #define FSK_PORT	PORTC
 #define FSK_DDR	DDRC

#define SDO    		PB4		// input for mega
 #define SDO_PORT	PORTB
 #define SDO_DDR	DDRB
 #define SDO_PIN	PINB

#define SCK    		PB5
 #define SCK_PORT	PORTB
 #define SCK_DDR	DDRB

#define nIRQ   		PD2      // input for mega
 #define nIRQ_PORT	PORTD
 #define nIRQ_DDR	DDRD
 #define nIRQ_PIN	PIND

#define nSEL   		PB2
 #define nSEL_PORT	PORTB
 #define nSEL_DDR	DDRB

#define LED   		PD3
 #define LED_PORT	PORTD
 #define LED_DDR	DDRD

// interni
#define SDI_H		SDI_PORT |= _BV(SDI)
#define SDI_L		SDI_PORT &= (~(_BV(SDI)))
#define SDI_INIT	SDI_DDR |= _BV(SDI)

#define FSK_H		FSK_PORT |= _BV(FSK)
#define FSK_L		FSK_PORT &= (~(_BV(FSK)))
#define FSK_INIT	FSK_DDR |= _BV(FSK)

#define SDO_INPUT	(SDO_PIN & _BV(SDO))
#define SDO_INIT	SDO_DDR &= (~(_BV(SDO)))

#define SCK_H		SCK_PORT |= _BV(SCK)
#define SCK_L		SCK_PORT &= (~(_BV(SCK)))
#define SCK_INIT	SCK_DDR |= _BV(SCK)

#define nIRQ_INPUT	(nIRQ_PIN & _BV(nIRQ))
#define nIRQ_INIT	nIRQ_DDR &= (~(_BV(nIRQ)))

#define nSEL_H		nSEL_PORT |= _BV(nSEL)
#define nSEL_L		nSEL_PORT &= (~(_BV(nSEL)))
#define nSEL_INIT	nSEL_DDR |= _BV(nSEL)

#define LED_H		LED_PORT |= _BV(LED)
#define LED_L		LED_PORT &= (~(_BV(LED)))
#define LED_INIT	LED_DDR |= _BV(LED)

#define START_FIFO	RF_WRITE_CMD(CMD_FIFO|FIFO_8|FIFO_VDI_WORD|FIFO_FF|FIFO_FE)
#define STOP_FIFO	RF_WRITE_CMD(CMD_FIFO)

//************************************************************************

uint8_t rx_buf[16];

//************************************************************************

void delay_ms(uint16_t time)
{
	while(time--) _delay_ms(1);
}

void IO_INIT(void)
{
	SDI_INIT;
	SDO_INIT;
	SCK_INIT;
	nIRQ_INIT;
	nSEL_INIT;
	FSK_INIT;
	LED_INIT;
}

void RF_INIT(void)
{
   nSEL_H;
   SDI_H;
   SCK_L;
   nIRQ_INPUT;
   SDO_INPUT;
   FSK_H;
}

uint16_t RF_WRITE_CMD(uint16_t cmd)
{
   uint8_t i;
   uint16_t temp;

   SCK_L;
   nSEL_L;
   temp=0;
   for (i=0;i<16;i++)
   {
      if (cmd & 0x8000) SDI_H;
      else SDI_L;
	  SCK_H;
      cmd <<= 1;
	  temp <<= 1;
	  if(SDO_INPUT) temp |= 0x0001;
	  SCK_L;
   }
   SCK_L;
   nSEL_H;
   return (temp);
}

void RF_WRITE_DATA(uint8_t data)
{
	  while (nIRQ_INPUT);
      RF_WRITE_CMD(0xB800 + data);
}

uint8_t RF_READ_DATA(void)
{
	uint8_t i,result;

	while (nIRQ_INPUT);
	SCK_L;
	nSEL_L;
	SDI_L;
	result=0;
	for (i=0;i<24;i++)
	{
		result <<= 1;
		if (SDO_INPUT) result |= 0x01;
		SCK_H;
		SCK_L;
	}
	nSEL_H;
	return (result);
}

void RS232_INIT(void)
{	
	//set baud rate 9600 8N1 for Fosc 1MHz
	UBRRH = 0;
	UBRRL = 12;
	UCSRB = (1<<RXEN)|(1<<TXEN);	//enable RX TX	
	UCSRC = (1<<URSEL) |(3<<UCSZ0);	//8N1
	UCSRA  |= _BV(U2X);
}

void put_rs232(char data)
{
	// Wait for empty transmit buffer
	while ( !( UCSRA & (1<<UDRE)) );
	// Put data into buffer, sends the data
	UDR = data;
}

int main()
{
   	uint8_t i,ChkSum;
   	uint8_t LED_TRG;
   	uint8_t b;

   	IO_INIT();
	RS232_INIT();
   	RF_INIT();
	delay_ms(100);
   	LED_L;
   	LED_TRG=0;

	
	
	RF_WRITE_CMD(CMD_SETTING	|BAND_868 | C_12pF | BANDWIDTH_67 | SETTING_DC);
   	RF_WRITE_CMD(CMD_FREQUENCY	|FREQUENCY_868);
   	RF_WRITE_CMD(CMD_RATE		|RATE_9600);
   	RF_WRITE_CMD(CMD_FILTER		|FILTER_AL | FILTER_S0 | DQD_4);
	RF_WRITE_CMD(CMD_AFC		|AFC_POWER_ON | AFC_RANG_8 | AFC_ST | AFC_OE | AFC_EN);
	RF_WRITE_CMD(CMD_RX);
   	RF_WRITE_CMD(CMD_RX			|VDI_CLOCK | LNA_GAIN_0 | DRSSI_103 | RX_EN);
	RF_WRITE_CMD(CMD_FIFO);

	while (1)
   	{
		
		START_FIFO;
      	ChkSum = 0;
      	for (i=0;i<16;i++) 
	  	{
	  		b = RF_READ_DATA();
			rx_buf[i] = b;
			ChkSum += b;
	  	}
	  	b = RF_READ_DATA();
	  	RF_READ_DATA();
		STOP_FIFO;
	  
	  	for (i=0;i<16;i++)
	  	{
	  		put_rs232(rx_buf[i]);
			delay_ms(2);
	  	}
	  	if (ChkSum == b) 
		{
			LED_TRG = ~ LED_TRG;
			put_rs232(' ');
			put_rs232('o');
			put_rs232('k');
		}
	  	else 
		{
			put_rs232('\n');
			delay_ms(2);
			put_rs232('\r');
			delay_ms(2);
			put_rs232('e');
			put_rs232('r');
			put_rs232('r');
	  	}
		if (LED_TRG) LED_H;
	  	else LED_L; 
   	}
   	return 0;
}



