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_ */
|