/*********************************************
*
* 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;
}
}