/*********************************************
*
* draft version v 0.1, experimental
*
* code based on the code of "benedikt k."
* this was an avr project from the site: http://www.mikrocontroller.net/topic/65984#541030
*
*
* code should be matched with RF01
*
* up to now no transmission between the RF12 modules and Jeelabs.com RF12 lib
*
* this code has worked: transmitting using atmega168 and atmega328 in combination with RF01s and RF02s
*
* arduino 18
*
* five march, contrechoc.com, june 2010 , october 2010
*
*
*********************************************/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <stdlib.h>

#include "rf01.h"

#define F_CPU 16000000UL
#include <util/delay.h>

#define RF_PORT	PORTB
#define RF_DDR	DDRB
#define RF_PIN	PINB

#define SDI		5	// RF01  SDI,  arduino  13 cannot be changed
#define SCK		4	// RF01  SCK,  arduino  12 cannot be changed
#define CS		3	// RF01  nSEL, arduino  11 cannot be changed
#define SDO		2	// RF01  SDO,  arduino  10 cannot be changed
//----------------- // RF01  niRQ, arduino  02 cannot be changed
//------------------// RF01  nFFS: 1-10k Pullup too Vcc


#ifndef cbi
#define cbi(sfr, bit)     (_SFR_BYTE(sfr) &= ~_BV(bit)) 
#endif
#ifndef sbi
#define sbi(sfr, bit)     (_SFR_BYTE(sfr) |= _BV(bit))  
#endif

// maximum receive buffer
#define RF_MAX   32
unsigned char  rf01_buf[RF_MAX];  // recv buf

#include <util/delay.h>

void rf01_receive(){
	rf01_rxdata(rf01_data, 23); //!!!32
}

static unsigned char sdrssi, sgain;

void rf01_prepAll()
{
	RF_PORT=(1<<CS);
	RF_DDR=(1<<SDI)|(1<<SCK)|(1<<CS);

	for (unsigned char i=0; i<11; i++) _delay_ms(10);			// wait until POR done

//	rf01_trans(0xC2E0);			// AVR CLK: 10MHz
//	rf01_trans(0xC42B);			// Data Filter: internal
//	rf01_trans(0xC6F7);			// AFC settings: autotuning: -10kHz...+7,5kHz
//	rf01_trans(0xE000);			// disable wakeuptimer
//	rf01_trans(0xCC00);			// disable low duty cycle
//	rf01_trans(0x8978); // band 433MHz, enable crystal + 12pF, 200kHz bandwidth

	rf01_trans(0x0000); 
//	rf01_trans(0x898A); // band 433MHz, 134kHz bandwidth
	rf01_trans(0x8000|0x1000|0x70|0x02); //band
	rf01_trans(0xA640); //434MHz	
	rf01_trans(0xC823); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 9600 Bd
	rf01_trans(0xC69B);	
	rf01_trans(0xC42A);			
	rf01_trans(0xC240); //*			
	rf01_trans(0xC080);	 //*		
	rf01_trans(0xCE88);	// FIFO mode
	rf01_trans(0xCE8B);	    //*
	rf01_trans(0xC081);	    //*
}

void rf01_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);
		sbi(RF_PORT, SCK);
		wert<<=1;
		_delay_us(0.2);
		cbi(RF_PORT, SCK);
	}
	sbi(RF_PORT, CS);
}

void rf01_rxdata(unsigned char *data, unsigned char number)
{	unsigned char i,j,c;

  //!!!	
//	sgain=2;                      //2,4 -6dB LNA gain, DRSSI threshold: -79dBm
//	sdrssi=4;
//!!!	rf01_trans(0xC0C1|((sgain&3)<<4)|((sdrssi&7)<<1));	// RX on
	rf01_trans(0xCE89);			// set FIFO mode
	rf01_trans(0xCE8B);			// enable FIFO
	cbi(RF_PORT, SDI);
			asm("nop");
			asm("nop");
			asm("nop");
	for (i=0; i<number; i++)
	{	cbi(RF_PORT, CS);
			asm("nop");
			asm("nop");
			asm("nop");
		while (!(RF_PIN&(1<<SDO))); // wait until data in FIFO
		for (j=0; j<16; j++)	// read and discard status register
		{	
      sbi(RF_PORT, SCK);
			asm("nop");
			asm("nop");
			asm("nop");
			cbi(RF_PORT, SCK);
			asm("nop");
			asm("nop");
			asm("nop");
		}
		c=0;
		for (j=0; j<8; j++)
		{	c<<=1;
			if (RF_PIN&(1<<SDO))
				c|=1;
			sbi(RF_PORT, SCK);
			asm("nop");
			asm("nop");
			asm("nop");
//!!!			_delay_us(0.2);
			cbi(RF_PORT, SCK);
			asm("nop");
			asm("nop");
			asm("nop");
		}
		*data++=c;
		sbi(RF_PORT, CS);
			asm("nop");
			asm("nop");
			asm("nop");
	}
//!!!	rf01_trans(0xC0C0|((sgain&3)<<4)|((sdrssi&7)<<1));	// RX off
}
