154 lines
3.8 KiB
C++
154 lines
3.8 KiB
C++
/*
|
||
* rfm12.hpp
|
||
*
|
||
* Created: 08.05.2014 00:06:49
|
||
* Author: netz
|
||
*/
|
||
|
||
|
||
#ifndef RFM12_H_
|
||
#define RFM12_H_
|
||
|
||
template <typename Spi, uint8_t bandwidth, uint8_t gain, uint8_t drssi, uint32_t frequenz, uint16_t baud, uint8_t power, uint8_t mod>
|
||
class Rfm12 {
|
||
public:
|
||
Rfm12() {
|
||
this->init();
|
||
}
|
||
|
||
void ready(void) {
|
||
s.CSOn();
|
||
while(s.has_data()); // wait until FIFO ready
|
||
}
|
||
|
||
void beginasyncrx() {
|
||
this->send(0x82C8); // RX on
|
||
this->send(0xCA81); // set FIFO mode
|
||
this->send(0xCA83); // enable FIFO
|
||
}
|
||
|
||
uint8_t hasdata() {
|
||
s.CSOn();
|
||
return s.has_data();
|
||
}
|
||
|
||
uint8_t rxbyte() {
|
||
return this->send(0xB000);
|
||
}
|
||
|
||
void endasyncrx() {
|
||
this->send(0x8208); // RX off
|
||
}
|
||
|
||
void txdata(uint8_t *data, uint8_t number) {
|
||
uint8_t i;
|
||
this->send(0x8238); // TX on
|
||
this->ready();
|
||
this->send(0xB8AA);
|
||
this->ready();
|
||
this->send(0xB8AA);
|
||
this->ready();
|
||
this->send(0xB8AA);
|
||
this->ready();
|
||
this->send(0xB82D);
|
||
this->ready();
|
||
this->send(0xB8D4);
|
||
for (i=0; i<number; i++)
|
||
{
|
||
this->ready();
|
||
this->send(0xB800|(*data++));
|
||
}
|
||
this->ready();
|
||
this->send(0x8208); // TX off
|
||
}
|
||
|
||
void rxdata(uint8_t *data, uint8_t number) {
|
||
uint8_t i;
|
||
this->send(0x82C8); // RX on
|
||
this->send(0xCA81); // set FIFO mode
|
||
this->send(0xCA83); // enable FIFO
|
||
for (i=0; i<number; i++)
|
||
{
|
||
this->ready();
|
||
*data++=this->send(0xB000);
|
||
}
|
||
this->send(0x8208); // RX off
|
||
}
|
||
|
||
void txpacket(uint8_t addr, uint8_t from, uint8_t data) {
|
||
this->send(0x8238); // TX on
|
||
this->ready();
|
||
this->send(0xB8AA);
|
||
this->ready();
|
||
this->send(0xB8AA);
|
||
this->ready();
|
||
this->send(0xB8AA);
|
||
this->ready();
|
||
this->send(0xB82D);
|
||
this->ready();
|
||
this->send(0xB8D4);
|
||
this->ready();
|
||
this->send(0xB800|addr);
|
||
this->ready();
|
||
this->send(0xB800|from);
|
||
this->ready();
|
||
this->send(0xB800|data);
|
||
this->ready();
|
||
this->send(0xB800);
|
||
this->ready();
|
||
this->send(0x8208); // TX off
|
||
_delay_ms(100);
|
||
}
|
||
private:
|
||
Spi s;
|
||
uint16_t send(uint16_t wert) {
|
||
s.CSOn();
|
||
uint16_t werti = s.send((uint8_t)(wert >> 8)) << 8;
|
||
werti |= s.send((uint8_t)wert);
|
||
s.CSOff();
|
||
return werti;
|
||
}
|
||
void init(void) {
|
||
_delay_ms(100);
|
||
|
||
this->send(0xC0E0); // AVR CLK: 10MHz
|
||
this->send(0x80D7); // Enable FIFO
|
||
this->send(0xC2AB); // Data Filter: internal
|
||
this->send(0xCA81); // Set FIFO mode
|
||
this->send(0xE000); // disable wakeuptimer
|
||
this->send(0xC800); // disable low duty cycle
|
||
this->send(0xC4F7); // AFC settings: autotuning: -10kHz...+7,5kHz
|
||
|
||
this->setfreq(); // Sende/Empfangsfrequenz auf 433,92MHz einstellen
|
||
this->setbandwidth(); // 400kHz Bandbreite, 0dB Verst<73>rkung, DRSSI threshold: -61dBm
|
||
this->setbaud(); // 19200 baud
|
||
this->setpower(); // 1mW Ausgangsleistung, 120kHz Frequenzshift
|
||
}
|
||
void setbandwidth() {
|
||
this->send( 0x9400 | ( ( bandwidth & 7 ) << 5 ) | ( ( gain & 3 ) << 3 ) | ( drssi & 7 ) );
|
||
}
|
||
void setfreq() {
|
||
uint16_t freq = (uint16_t)(((float)(frequenz-430000)/1000)/0.0025); // macro for calculating frequency value out of frequency in kHz
|
||
if( freq < 96 ) { // 430,2400MHz
|
||
this->send( 0xA000 | 96 );
|
||
} else if( freq > 3903 ) { // 439,7575MHz
|
||
this->send( 0xA000 | 3903 );
|
||
}
|
||
this->send( 0xA000 | freq );
|
||
}
|
||
void setbaud() {
|
||
if (baud < 663) {
|
||
return;
|
||
}
|
||
if (baud < 5400) { // Baudrate= 344827,58621/(R+1)/(1+CS*7)
|
||
this->send(0xC680 | ( ( 43104 / baud ) - 1 ) );
|
||
} else {
|
||
this->send(0xC600 | ( ( 344828UL / baud ) - 1 ) );
|
||
}
|
||
}
|
||
void setpower() {
|
||
this->send( 0x9800 | ( power & 7 ) | ( ( mod & 15 ) << 4 ) );
|
||
}
|
||
};
|
||
|
||
#endif /* RFM12_H_ */ |