/*********************************************
*
* RFM01 simple library
* 
* $HeadURL: svn://www.mlab.cz/home/MLAB/Designs/duckweed_collector/SW/library/RF02/RF02.cpp $
* $Id: RF02.cpp 2129 2011-08-18 18:40:43Z kakl $
*
* code based on the code of "benedikt k." and "contrechoc" 
*
* tested on arduino 22
*
*********************************************/

#include <avr/io.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 2 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

unsigned char  _rx_buffer[32];  // recv buf

#include <util/delay.h>

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(0x0000);     // cargo cult settings 
	rf01_trans(0x8000|0x1000|0x70|0x02); //band
	rf01_trans(0xA640); // freq
	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);
		sbi(RF_PORT, SCK);
		sbi(RF_PORT, SCK);
		wert<<=1;
		cbi(RF_PORT, SCK);
	}
	sbi(RF_PORT, CS);
}

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

	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");
			cbi(RF_PORT, SCK);
			asm("nop");
			asm("nop");
			asm("nop");
		}
		*data++=c;
		sbi(RF_PORT, CS);
			asm("nop");
			asm("nop");
			asm("nop");
	}
}
