/Designs/duckweed_collector/SW/library/RF01/RF01.cpp
0,0 → 1,220
/*********************************************
*
* 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
 
#define LED_PORT PORTD
#define LED_DDR DDRD
#define LED_PIN PIND
 
#define LED0 5
#define LED1 6 //not used
 
// nFFS: 1-10k Pullup an 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
 
// 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, 32);
}
 
void rf01_prepAll(){
rf01_init(); // ein paar Register setzen (z.B. CLK auf 10MHz)
rf01_setfreq(RF01FREQ(434)); // Sende/Empfangsfrequenz auf 433,92MHz einstellen
rf01_setbandwidth(4); // 4 200kHz Bandbreite
rf01_setreceiver(2,4); //2,4 -6dB Verstärkung, DRSSI threshold: -79dBm
rf01_setbaud(57600); // 19200 Baud
 
}
 
static unsigned char sdrssi, sgain;
 
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_init(void)
{ unsigned char i;
 
RF_PORT=(1<<CS);
RF_DDR=(1<<SDI)|(1<<SCK)|(1<<CS);
 
for (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(0xCE88); // FIFO mode
rf01_trans(0xC6F7); // AFC settings: autotuning: -10kHz...+7,5kHz
rf01_trans(0xE000); // disable wakeuptimer
rf01_trans(0xCC00); // disable low duty cycle
 
LED_DDR= 0xFF;//(1<<LED0)|(1<<LED1);
blinkLED();
 
}
 
void rf01_setbandwidth(unsigned char bandwidth)
{
rf01_trans(0x8970|((bandwidth&7)<<1));
}
 
void rf01_setreceiver(unsigned char gain, unsigned char drssi)
{
sdrssi=drssi;
sgain=gain;
}
 
void rf01_setfreq(unsigned short freq)
{ if (freq<96) // 430,2400MHz
freq=96;
else if (freq>3903) // 439,7575MHz
freq=3903;
rf01_trans(0xA000|freq);
}
 
void rf01_setbaud(unsigned short baud)
{
if (baud<336)
return;
if (baud<5400) // Baudrate= 344827,58621/(R+1)/(1+CS*7)
rf01_trans(0xC880|((43104/baud)-1));
else
rf01_trans(0xC800|((344828UL/baud)-1));
 
rf01_trans(0xC806);
}
 
void rf01_rxdata(unsigned char *data, unsigned char number)
{ unsigned char i,j,c;
 
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);
for (i=0; i<number; i++)
{ cbi(RF_PORT, CS);
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");
cbi(RF_PORT, SCK);
}
c=0;
for (j=0; j<8; j++)
{ c<<=1;
if (RF_PIN&(1<<SDO))
c|=1;
sbi(RF_PORT, SCK);
_delay_us(0.2);
cbi(RF_PORT, SCK);
}
*data++=c;
sbi(RF_PORT, CS);
}
//blinkLED();
rf01_trans(0xC0C0|((sgain&3)<<4)|((sdrssi&7)<<1)); // RX off
}
 
void blinkLED(void){
for (unsigned char i=0; i<15; i++)
_delay_ms(5);
sLED1();
 
for (unsigned char i=0; i<15; i++)
_delay_ms(5);
cLED1();
 
}
 
void makePulse(int numberOfPulses){
if ( numberOfPulses > 0)
{
for (unsigned char i=0; i<numberOfPulses; i++)
{
_delay_ms(20);
sLED0();
_delay_ms(20);
cLED0();
}
_delay_ms(50);
}
 
}