/*********************************************
*
* 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, 2010, june
*
*
*********************************************/


#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
 
 #include <string.h>
 
#include "rf02.h"
#include <util/delay.h>

#define F_CPU 16000000UL
 
#define RF_PORT	PORTB
#define RF_DDR	DDRB
#define RF_PIN	PINB

#define LED_PORT	PORTD
#define LED_DDR		DDRD
#define LED_PIN		PIND

#define LED0	4 -- PD4
#define LED1	2 -- PD2

#define SDI		0	// SDI,  -> RF02   Atmega PB0 Arduino 8
#define SCK		1	// SCK,  -> RF02   Atmega PB1 Arduino 9 
#define CS		2	// nSEL, -> RF02   Atmega PB2 Arduino 10 
#define IRQ		4	// nIRQ, <- RF02   Atmega PB4 Arduino 12
//------------------// FSK: Pullupto 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

#ifndef cLED0
#define cLED0()     (LED_PORT &= ~(1<<LED0)) 
#endif
#ifndef sLED0
#define sLED0()     (LED_PORT |= (1<<LED0) )  
#endif

#ifndef cLED1
#define cLED1()     (LED_PORT &= ~(1<<LED1)) 
#endif
#ifndef sLED1
#define sLED1()     (LED_PORT |= (1<<LED1) )  
#endif



unsigned char test[32]="     55555      \n";

void rf02_changeText( unsigned char* ptr, uint8_t number){

	if (number> 32)number = 32;
		memcpy( test, ptr, number);
 
}

void rf02_prepAll434(){

	rf02_init();					// ein paar Register setzen (z.B. CLK auf 10MHz)
	rf02_setfreq(RF02FREQ(434));	// 433,92MHz
	rf02_setpower(1);				// -12dBm Ausgangangsleistung
	rf02_setmodfreq(3);				// 120kHz Frequenzshift
	rf02_setbaud(19200);			// 19200 Baud

}//

void rf02_prepAll(unsigned short freq, uint8_t setPower,uint8_t modFreq,unsigned short baudRate){

	rf02_init();					// ein paar Register setzen (z.B. CLK auf 10MHz)
	rf02_setfreq( RF02FREQ(freq) );	// Sende/Empfangsfrequenz auf 433,92MHz einstellen
	
	if ( setPower < 0 ) setPower = 0;
	if ( setPower > 4 ) setPower = 4;
	rf02_setpower(setPower);				// -12dBm Ausgangangsleistung
	
	if ( modFreq < 0 ) modFreq = 0;
	if ( modFreq > 8 ) modFreq = 8;
	rf02_setmodfreq(modFreq);				// 120kHz Frequenzshift
	
	rf02_setbaud(baudRate);			// 19200 Baud

}//


void rf02_sendData(){

	rf02_txdata( test, sizeof test);
}



void rf02_trans(unsigned short  value)
{	uint8_t i;

	cbi(RF_PORT, CS);

	for (i=0; i<16; i++)
	{	if (value&0x8000) //0x8000
			sbi(RF_PORT, SDI);
		else
			cbi(RF_PORT, SDI);

		sbi(RF_PORT, SCK);
		value<<=1;
		_delay_us(0.3);
		cbi(RF_PORT, SCK);
	}
	sbi(RF_PORT, CS);
}



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

	for (unsigned char i=0; i<15; i++)
		_delay_ms(10);			// wait until POR done
	rf02_trans(0xC0E0);			// power settings
	rf02_trans(0x8A75);// fsk in rfm02 = afc in rf12
//		rf02_trans(0x80C7);
	rf02_trans(0xC2A0);			// enable tx sync bit, disable low bat detector

	//LED_DDR= 0xFF;
}

void rf02_setmodfreq(uint8_t bandwidth)
{
	rf02_trans(0x8F80|(bandwidth&7));
	//rf02_trans(0x8F70);
}

void rf02_setfreq(unsigned short freq)
{	if (freq<96)				// 430,2400MHz
		freq=96;
	else if (freq>3903)			// 439,7575MHz
		freq=3903;
	rf02_trans(0xA000|freq);

	//rf02_trans(0xA640); //= 434 MHz
}

void rf02_setpower(uint8_t power)
{
	rf02_trans(0xB000|((power&7)<<8));
}

void rf02_setbaud(unsigned short baud)
{
 
	if (baud<1345)
		baud=1345;
	if (baud<19000)
		rf02_trans(0xD240);		// 25% PLL current
	else if (baud<37000)
		rf02_trans(0xD2C0);		// 33% PLL current
	else
		rf02_trans(0xD200);		// 50% PLL current

	//rf02_trans(0xC800|((344828UL/baud)-1));	// Baudrate= 344827,59/(R+1)
 
	rf02_trans(0xC806);
}

void rf02_txdata( unsigned char * data, uint8_t number)
{	
	uint8_t i,value;
	value=0xC6;          //1100 0110
	cbi(RF_PORT, CS);   //nSel

	for (i=0; i<8; i++)
		{	if (value&0x80)   //1000 0000 = 80
				sbi(RF_PORT, SDI);
			else
				cbi(RF_PORT, SDI);

			sbi(RF_PORT, SCK);
			value<<=1;
			_delay_us(0.2);
			cbi(RF_PORT, SCK);
		}

	rf02_shiftout(0xAA);//10101010
	rf02_shiftout(0xAA);
	rf02_shiftout(0xAA);
	rf02_shiftout(0x2D);//00101101
	rf02_shiftout(0xD4);//11010100
	
	// no checkbit, in experimenting some letters were transmitted wrong!

	for (i=0; i<number; i++)
		rf02_shiftout(*data++);

	sbi(RF_PORT, CS);
	while(RF_PIN&(1<<IRQ));		// wait until transfer done
	rf02_trans(0xC464);				// TX off after 10us

}

void rf02_shiftout(unsigned char value)
{	uint8_t j;
	for (j=0; j<8; j++)
	{	while(RF_PIN&(1<<IRQ));
    	while(!(RF_PIN&(1<<IRQ)));

		if (value&128)             //100101000
    		sbi(RF_PORT, SDI);
    	else
    		cbi(RF_PORT, SDI);
    	value<<=1;
    }
}
 
