/*----------------------------------------------------------------------------
 Copyright:      
 Author:         
 Remarks:        
 known Problems: none
 Version:        16.12.2009
 Description:    RF22 Funkmodule
------------------------------------------------------------------------------*/
#include "rfm22b-23b_registers.h"

#include "rf22.h"


//###############################################################################################################
static inline unsigned char rf22_trans(unsigned char addr, unsigned char data)
{	
	RF22_PORT &= ~(1<<CS);
	SPDR = addr;
	while(!(SPSR & (1<<SPIF)));
	SPDR = data;
	while(!(SPSR & (1<<SPIF)));
	RF22_PORT |= (1<<CS);
	return SPDR;
}


//###############################################################################################################
void rf22_write(unsigned char addr, unsigned char data)
{
	rf22_trans(128|addr, data);
}


//###############################################################################################################
unsigned char rf22_read(unsigned char addr)
{
	return rf22_trans(addr&127,0);
}


//###############################################################################################################
void rf22_init(void)
{
//	DDRB |= 44;
//	DDRB |=  4 | 8 | 32;
//	DDRB |=  (1<<2) | (1<<3) | (1<<5);
	DDRB |=  (1<<CS) | (1<<SDI) | (1<<SCK);
//	SPCR=(1<<SPE)|(1<<MSTR);
//	SPSR|=(1<<SPI2X);
SPCR=0x53;
SPSR=0x00;
	
	//for(unsigned long a = 0;a<100 000;a++){asm("nop");}; // wait until POR done
    delay_ms(50);//por (16ms)
    
    rf22_write(REGISTER_OPERATING_FUNCTION_CONTROL_1,                   0x80);		// software reset
	//for(unsigned long a = 0;a<100000;a++){asm("nop");}; // wait until software reset done
    delay_ms(10);//soft reset: 100 us

    rf22_write(REGISTER_INTERRUPT_ENABLE_1,                             0x02);		// valid packed received interrupt on

    rf22_write(REGISTER_INTERRUPT_ENABLE_2,                             0x00);		// all interrupts off
    rf22_write(REGISTER_OPERATING_FUNCTION_CONTROL_1,                   0x01);		// operating mode: ready mode
    rf22_write(REGISTER_CRYSTAL_OSCILLATOR_LOAD_CAPACITANCE,            0x7f);		// xtal load capacitance
    rf22_write(REGISTER_MICROCONTROLLER_OUTPUT_CLOCK,                   0x02);		// uC CLK: 10MHz
    
    rf22_write(REGISTER_GPIO_0_CONFIGURATION,                           0xf2);		// GPIO0: TX_ANT - f2 
    rf22_write(REGISTER_GPIO_1_CONFIGURATION,                           0xf5);		// GPIO1: RX ANT - f5
    rf22_write(REGISTER_GPIO_2_CONFIGURATION,                           0x00);		// GPIO2: uC Clock out
    rf22_write(REGISTER_IO_PORT_CONFIGURATION,                          0x00);		
    rf22_write(REGISTER_ADC_CONFIGURATION,                              0x70);		// ADC Input: GND
    rf22_write(REGISTER_ADC_SENSOR_AMPLIFIER_OFFSET,                    0x00);		// ADC offset: 0
    rf22_write(REGISTER_TEMPERATURE_SENSOR_CONTROL,                     0x00);		// temp sensor calibration off
    rf22_write(REGISTER_TEMPERATURE_VALUE_OFFSET,                       0x00);		// temp sensor offset: 0
    rf22_write(REGISTER_AFC_LOOP_GEARSHIFT_OVERRIDE,                    0x40);		// enable AFC
    rf22_write(REGISTER_AFC_TIMING_CONTROL,                             0x0A);		// afc timing
	rf22_write(REGISTER_CLOCK_RECOVERY_GEARSHIFT_OVERRIDE,              0x03);		// afc timing

	rf22_write(REGISTER_IF_FILTER_BANDWIDTH,                            0x05);		// IF bandwidth
	rf22_write(REGISTER_CLOCK_RECOVERY_OVERSAMPLING_RATIO,              0x83);		// Clock Recovery Oversampling Rate
	rf22_write(REGISTER_CLOCK_RECOVERY_OFFSET_2,                        0xC0);		// Clock Recovery Offset 2
	rf22_write(REGISTER_CLOCK_RECOVERY_OFFSET_1,                        0x13);		// Clock Recovery Offset 1
	rf22_write(REGISTER_CLOCK_RECOVERY_OFFSET_0,                        0xA9);		// Clock Recovery Offset 0
	rf22_write(REGISTER_CLOCK_RECOVERY_TIMING_LOOP_GAIN_1,              0x00);		// Clock Recovery Timing Loop Gain 1
	rf22_write(REGISTER_CLOCK_RECOVERY_TIMING_LOOP_GAIN_0,              0x04);		// Clock Recovery Timing Loop Gain 0
	rf22_write(REGISTER_AFC_LIMITER,                                    0x24);

	rf22_write(REGISTER_RSSI_THRESHOLD_FOR_CLEAR_CHANNEL_INDICATOR,     0x10);		// RSSI Threashold: -120dB

    rf22_write(REGISTER_DATA_ACCESS_CONTROL,                            0x8c);		// data access: RX/TX packet handling, enable crc: CCIT
    rf22_write(REGISTER_HEADER_CONTROL_1,                               0xff);		// header check enable
    rf22_write(REGISTER_HEADER_CONTROL_2,                               0x42);		// 2 word synchronisation
    rf22_write(REGISTER_PREAMBLE_LENGTH,                                0x10);		// preamble length: 16 nibbles, = 64bits
    rf22_write(REGISTER_PREAMBLE_DETECTION_CONTROL,                     0x30);		// preamble detection control: 6 nibbles = 24bits
    rf22_write(REGISTER_SYNC_WORD_3,                                    0x2d);		// sync word 3
    rf22_write(REGISTER_SYNC_WORD_2,                                    0xd4);		// sync word 2
    rf22_write(REGISTER_SYNC_WORD_1,                                    0xAA);		// sync word 1
    rf22_write(REGISTER_SYNC_WORD_0,                                    0xAA);		// sync word 0
    rf22_write(REGISTER_TRANSMIT_HEADER_3,                              'h');		// transmit header 3
    rf22_write(REGISTER_TRANSMIT_HEADER_2,                              'o');		// transmit header 2
    rf22_write(REGISTER_TRANSMIT_HEADER_1,                              'p');		// transmit header 1
    rf22_write(REGISTER_TRANSMIT_HEADER_0,                              'e');		// transmit header 0
    rf22_write(REGISTER_TRANSMIT_PACKET_LENGTH,                         17);		// packet length
    rf22_write(REGISTER_CHECK_HEADER_3,                                 'h');		// check header 3
    rf22_write(REGISTER_CHECK_HEADER_2,                                 'o');		// check header 2
    rf22_write(REGISTER_CHECK_HEADER_1,                                 'p');		// check header 1
    rf22_write(REGISTER_CHECK_HEADER_0,                                 'e');		// check header 0
    rf22_write(REGISTER_HEADER_ENABLE_3,                                0xff);		// header enable mask 3
    rf22_write(REGISTER_HEADER_ENABLE_2,                                0xff);		// header enable mask 2
    rf22_write(REGISTER_HEADER_ENABLE_1,                                0xff);		// header enable mask 1
    rf22_write(REGISTER_HEADER_ENABLE_0,                                0xff);		// header enable mask 0

//	rf22_write(0x69,                                                    0x60);		// AGC on
	rf22_write(REGISTER_AGC_OVERRIDE,                                   0x60);		// AGC on
    rf22_write(0x6a,                                                    0x0b);		// agc override 2 [!????????!!!!!!!]
	rf22_write(REGISTER_TX_POWER,                                       0x0F);		// tx power: +17dBm
	
	rf22_write(REGISTER_TX_DATA_RATE_1,                                 0x13);		// set baud high
	rf22_write(REGISTER_TX_DATA_RATE_0,                                 0xa9);		// set baud low

    rf22_write(REGISTER_MODULATION_MODE_CONTROL_1,                      0x2C);		// modulation control
    rf22_write(REGISTER_MODULATION_MODE_CONTROL_2,                      0x22);		// modulation control 2: FIFO mode, OOK  //0x21 / 0x00
	
    rf22_write(REGISTER_FREQUENCY_DEVIATION,                            0x50);		// frequency deviation: 45kHz
	rf22_write(REGISTER_FREQUENCY_OFFSET_1,                             0x00);		// offset: 0
	rf22_write(REGISTER_FREQUENCY_OFFSET_2,                             0x00);		// offset: 0
	
	rf22_write(REGISTER_FREQUENCY_HOPPING_CHANNEL_SELECT,               0x0);		// frequency hopping off
    rf22_write(REGISTER_FREQUENCY_HOPPING_STEP_SIZE,                    0x0);		// frequency hopping off
	
#ifdef BAND_868
	rf22_write(REGISTER_FREQUENCY_BAND_SELECT,                          0x73);		// 860-880MHz range
#else
	rf22_write(REGISTER_FREQUENCY_BAND_SELECT,                          0x53);		// 430-440MHz range
#endif


}


//###############################################################################################################
void rf22_rxmode(void)
{	
	rf22_read(REGISTER_INTERRUPT_STATUS_1);			                            // clear interrupt status
    rf22_read(REGISTER_INTERRUPT_STATUS_2);			                            // clear interrupt status
	rf22_write(REGISTER_OPERATING_FUNCTION_CONTROL_1,               0x01);		// to_ready_mode();
	
	rf22_write(REGISTER_OPERATING_FUNCTION_CONTROL_1,               0x01);		// to_ready_mode();
	rf22_write(REGISTER_RX_FIFO_CONTROL,                            0x17);		// threshold for rx almost full, interrupt when 1 byte received
	
	rf22_write(REGISTER_OPERATING_FUNCTION_CONTROL_2,               0x03);		// clear RX fifo
	rf22_write(REGISTER_OPERATING_FUNCTION_CONTROL_2,               0x00);		// clear fifo, disable multi packet
	
	rf22_write(REGISTER_OPERATING_FUNCTION_CONTROL_1,               0x05);		// RX on
	
    rf22_read(REGISTER_INTERRUPT_STATUS_1);			                            // clear interrupt status
    rf22_read(REGISTER_INTERRUPT_STATUS_2);			                            // clear interrupt status
}


//###############################################################################################################
void rf22_setfreq(unsigned short freq)
{	
    rf22_write(REGISTER_NOMINAL_CARRIER_FREQUENCY_1,                (freq&0xFF00)>>8);
    rf22_write(REGISTER_NOMINAL_CARRIER_FREQUENCY_0,                (freq&0x00FF));
}

//###############################################################################################################
void rf22_sendpacket(unsigned char *data, unsigned char size)
{	
	unsigned char i;

	if (size>64) size=64;
	
	rf22_write(REGISTER_OPERATING_FUNCTION_CONTROL_1,               0x03);		// switch to ready mode
	rf22_read(REGISTER_INTERRUPT_STATUS_1);			                            // clear interrupt status
	rf22_read(REGISTER_INTERRUPT_STATUS_2);			                            // clear interrupt status

	rf22_write(REGISTER_OPERATING_FUNCTION_CONTROL_2,               0x01);		// clear TX fifo
	rf22_write(REGISTER_OPERATING_FUNCTION_CONTROL_2,               0x00);		// clear TX fifo
	
	rf22_write(REGISTER_PREAMBLE_LENGTH,                            32);		// premable length: 32 nibbles -> 128 Bits
	rf22_write(REGISTER_TRANSMIT_PACKET_LENGTH,                     size);		// packet length
	
	for (i = 0; i<size; i++)
	{    
		rf22_write(REGISTER_FIFO_ACCESS, *data++);
	}
	
	rf22_write(REGISTER_INTERRUPT_ENABLE_1,                         0x04);		// enable packet send
	rf22_write(REGISTER_OPERATING_FUNCTION_CONTROL_1,               0x09);		// TX on
	
	while (nIRQ);
	
	rf22_write(REGISTER_OPERATING_FUNCTION_CONTROL_1,               0x01);		//	switch to ready mode
}


//###############################################################################################################
unsigned char rf22_getpacket(unsigned char *data)
{	
	unsigned char i, cnt;

	if(rf22_read(REGISTER_EZMAC_STATUS)&0x1A)		// receiving a packet
	{
		if ((rf22_read(REGISTER_INTERRUPT_STATUS_1)&2)&&(!(rf22_read(REGISTER_DEVICE_STATUS)&32)))	// packet received & not read
		{
			cnt=rf22_read(REGISTER_RECEIVER_PACKET_LENGTH);		// packet length
			
			for (i=0; i<cnt; i++)		// Daten (cnt - 2 für CRC)
			{
				*data++=rf22_read(REGISTER_FIFO_ACCESS);
			}
			
			rf22_rxmode();	
			return (cnt);
		}
		return 0;
	}
	return 0;
}
