MySensors Library & Examples  9ecb785
RFM69.h
1 // **********************************************************************************
2 // Driver definition for HopeRF RFM69W/RFM69HW/RFM69CW/RFM69HCW, Semtech SX1231/1231H
3 // **********************************************************************************
4 // Copyright Felix Rusu (2014), [email protected]
5 // http://lowpowerlab.com/
6 // **********************************************************************************
7 // License
8 // **********************************************************************************
9 // This program is free software; you can redistribute it
10 // and/or modify it under the terms of the GNU General
11 // Public License as published by the Free Software
12 // Foundation; either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // This program is distributed in the hope that it will
16 // be useful, but WITHOUT ANY WARRANTY; without even the
17 // implied warranty of MERCHANTABILITY or FITNESS FOR A
18 // PARTICULAR PURPOSE. See the GNU General Public
19 // License for more details.
20 //
21 // You should have received a copy of the GNU General
22 // Public License along with this program.
23 // If not, see <http://www.gnu.org/licenses/>.
24 //
25 // Licence can be viewed at
26 // http://www.gnu.org/licenses/gpl-3.0.txt
27 //
28 // Please maintain this license information along with authorship
29 // and copyright notices in any redistribution of this code
30 // **********************************************************************************
31 #ifndef RFM69_h
32 #define RFM69_h
33 #include <Arduino.h> // assumes Arduino IDE v1.0 or greater
34 
35 #define RF69_MAX_DATA_LEN 61 // to take advantage of the built in AES/CRC we want to limit the frame size to the internal FIFO size (66 bytes - 3 bytes overhead - 2 bytes crc)
36 #define RF69_SPI_CS SS // SS is the SPI slave select pin, for instance D10 on ATmega328
37 
38 // INT0 on AVRs should be connected to RFM69's DIO0 (ex on ATmega328 it's D2, on ATmega644/1284 it's D2)
39 #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
40 #define RF69_IRQ_PIN 2
41 #define RF69_IRQ_NUM 0
42 #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
43 #define RF69_IRQ_PIN 2
44 #define RF69_IRQ_NUM 2
45 #elif defined(__AVR_ATmega32U4__)
46 #define RF69_IRQ_PIN 3
47 #define RF69_IRQ_NUM 0
48 #elif defined(__arm__)//Use pin 10 or any pin you want
49 #define RF69_IRQ_PIN 10
50 #define RF69_IRQ_NUM 10
51 #else
52 #define RF69_IRQ_PIN 2
53 #define RF69_IRQ_NUM 0
54 #endif
55 
56 
57 #define CSMA_LIMIT -90 // upper RX signal sensitivity threshold in dBm for carrier sense access
58 #define RF69_MODE_SLEEP 0 // XTAL OFF
59 #define RF69_MODE_STANDBY 1 // XTAL ON
60 #define RF69_MODE_SYNTH 2 // PLL ON
61 #define RF69_MODE_RX 3 // RX MODE
62 #define RF69_MODE_TX 4 // TX MODE
63 
64 // available frequency bands
65 #define RF69_315MHZ 31 // non trivial values to avoid misconfiguration
66 #define RF69_433MHZ 43
67 #define RF69_868MHZ 86
68 #define RF69_915MHZ 91
69 
70 #define null 0
71 #define COURSE_TEMP_COEF -90 // puts the temperature reading in the ballpark, user can fine tune the returned value
72 #define RF69_BROADCAST_ADDR 255
73 #define RF69_CSMA_LIMIT_MS 1000
74 #define RF69_TX_LIMIT_MS 1000
75 #define RF69_FSTEP 61.03515625 // == FXOSC / 2^19 = 32MHz / 2^19 (p13 in datasheet)
76 
77 // TWS: define CTLbyte bits
78 #define RFM69_CTL_SENDACK 0x80
79 #define RFM69_CTL_REQACK 0x40
80 
82 class RFM69
83 {
84 public:
85  static volatile uint8_t DATA[RF69_MAX_DATA_LEN];
86  static volatile uint8_t DATALEN;
87  static volatile uint8_t SENDERID;
88  static volatile uint8_t TARGETID;
89  static volatile uint8_t PAYLOADLEN;
90  static volatile uint8_t ACK_REQUESTED;
91  static volatile uint8_t
93  static volatile int16_t RSSI;
94  static volatile uint8_t _mode;
95 
104  RFM69(uint8_t slaveSelectPin=RF69_SPI_CS, uint8_t interruptPin=RF69_IRQ_PIN, bool isRFM69HW=false,
105  uint8_t interruptNum=RF69_IRQ_NUM)
106  {
107  _slaveSelectPin = slaveSelectPin;
108  _interruptPin = interruptPin;
109  _interruptNum = interruptNum;
110  _mode = RF69_MODE_STANDBY;
111  _promiscuousMode = false;
112  _powerLevel = 31;
113  _isRFM69HW = isRFM69HW;
114  _address = RF69_BROADCAST_ADDR;
115 #if defined (SPCR) && defined (SPSR)
116  _SPCR = 0;
117  _SPSR = 0;
118 #endif
119  }
120 
121  bool initialize(uint8_t freqBand, uint8_t ID, uint8_t networkID=1);
122  void setAddress(uint8_t addr);
123  void setNetwork(uint8_t networkID);
124  bool canSend();
125  virtual void send(uint8_t toAddress, const void* buffer, uint8_t bufferSize,
126  bool requestACK=false);
127  virtual bool sendWithRetry(uint8_t toAddress, const void* buffer, uint8_t bufferSize,
128  uint8_t retries=2, uint8_t retryWaitTime=
129  40);
130  virtual bool receiveDone();
131  bool ACKReceived(uint8_t fromNodeID);
132  bool ACKRequested();
133  virtual void sendACK(const void* buffer = "", uint8_t bufferSize=0);
134  uint32_t getFrequency();
135  void setFrequency(uint32_t freqHz);
136  void encrypt(const char* key);
137  void setCS(uint8_t newSPISlaveSelect);
138  int16_t readRSSI(bool forceTrigger=false);
139  void promiscuous(bool onOff=true);
140  virtual void setHighPower(bool onOFF=
141  true);
142  virtual void setPowerLevel(uint8_t level);
143  void sleep();
144  uint8_t readTemperature(uint8_t calFactor=0);
145  void rcCalibration();
146 
147  // allow hacking registers by making these public
148  uint8_t readReg(uint8_t addr);
149  void writeReg(uint8_t addr, uint8_t val);
150  void readAllRegs();
151 
152 protected:
153  static void isr0();
154  void virtual interruptHandler();
155  virtual void interruptHook(uint8_t CTLbyte);
156  virtual void sendFrame(uint8_t toAddress, const void* buffer, uint8_t size, bool requestACK=false,
157  bool sendACK=false);
158 
159  static RFM69* selfPointer;
160  uint8_t _slaveSelectPin;
161  uint8_t _interruptPin;
162  uint8_t _interruptNum;
163  uint8_t _address;
165  uint8_t _powerLevel;
166  bool _isRFM69HW;
167 #if defined (SPCR) && defined (SPSR)
168  uint8_t _SPCR;
169  uint8_t _SPSR;
170 #endif
171 
172  virtual void receiveBegin();
173  virtual void setMode(uint8_t mode);
174  virtual void setHighPowerRegs(bool onOff);
175  virtual void select();
176  virtual void unselect();
177 };
178 
179 #endif
uint8_t readReg(uint8_t addr)
readReg
bool ACKRequested()
ACKRequested.
uint8_t _interruptNum
_interruptNum
Definition: RFM69.h:162
static volatile uint8_t SENDERID
SENDERID.
Definition: RFM69.h:87
virtual bool receiveDone()
receiveDone
Definition: RFM69.h:82
void readAllRegs()
readAllRegs
virtual void receiveBegin()
receiveBegin
virtual void interruptHandler()
interruptHandler
uint8_t _interruptPin
_interruptPin
Definition: RFM69.h:161
void rcCalibration()
rcCalibration (calibrate the internal RC oscillator for use in wide temperature variations - see data...
static volatile uint8_t PAYLOADLEN
PAYLOADLEN.
Definition: RFM69.h:89
bool ACKReceived(uint8_t fromNodeID)
ACKReceived.
static volatile uint8_t DATALEN
DATALEN.
Definition: RFM69.h:86
virtual void unselect()
unselect
virtual void select()
select
virtual void setHighPowerRegs(bool onOff)
setHighPowerRegs
bool _promiscuousMode
_promiscuousMode
Definition: RFM69.h:164
static volatile uint8_t _mode
should be protected?
Definition: RFM69.h:94
static volatile int16_t RSSI
most accurate RSSI during reception (closest to the reception)
Definition: RFM69.h:93
uint8_t readTemperature(uint8_t calFactor=0)
readTemperature (get CMOS temperature (8bit))
static volatile uint8_t ACK_RECEIVED
Should be polled immediately after sending a packet with ACK requestwith ACK request.
Definition: RFM69.h:92
bool initialize(uint8_t freqBand, uint8_t ID, uint8_t networkID=1)
initialize
static RFM69 * selfPointer
selfPointer
Definition: RFM69.h:159
uint8_t _address
_address
Definition: RFM69.h:163
void setCS(uint8_t newSPISlaveSelect)
setCS
void setFrequency(uint32_t freqHz)
setFrequency
RFM69(uint8_t slaveSelectPin=RF69_SPI_CS, uint8_t interruptPin=RF69_IRQ_PIN, bool isRFM69HW=false, uint8_t interruptNum=RF69_IRQ_NUM)
Constructor.
Definition: RFM69.h:104
virtual bool sendWithRetry(uint8_t toAddress, const void *buffer, uint8_t bufferSize, uint8_t retries=2, uint8_t retryWaitTime=40)
sendWithRetry (40ms roundtrip req for 61byte packets)
virtual void setMode(uint8_t mode)
setMode
bool _isRFM69HW
_isRFM69HW
Definition: RFM69.h:166
static volatile uint8_t ACK_REQUESTED
ACK_REQUESTED.
Definition: RFM69.h:90
void setNetwork(uint8_t networkID)
setNetwork
void promiscuous(bool onOff=true)
promiscuous
static volatile uint8_t DATA[RF69_MAX_DATA_LEN]
recv/xmit buf, including hdr & crc bytes
Definition: RFM69.h:85
virtual void setHighPower(bool onOFF=true)
setHighPower (have to call it after initialize for RFM69HW)
virtual void sendFrame(uint8_t toAddress, const void *buffer, uint8_t size, bool requestACK=false, bool sendACK=false)
sendFrame
int16_t readRSSI(bool forceTrigger=false)
readRSSI
virtual void sendACK(const void *buffer="", uint8_t bufferSize=0)
sendACK
virtual void setPowerLevel(uint8_t level)
setPowerLevel (reduce/increase transmit power level)
virtual void send(uint8_t toAddress, const void *buffer, uint8_t bufferSize, bool requestACK=false)
send
virtual void interruptHook(uint8_t CTLbyte)
interruptHook
void writeReg(uint8_t addr, uint8_t val)
writeReg
static void isr0()
isr0
uint8_t _powerLevel
_powerLevel
Definition: RFM69.h:165
uint32_t getFrequency()
getFrequency
uint8_t _slaveSelectPin
_slaveSelectPin
Definition: RFM69.h:160
void setAddress(uint8_t addr)
setAddress
void sleep()
sleep
void encrypt(const char *key)
encrypt
static volatile uint8_t TARGETID
should match _address
Definition: RFM69.h:88
bool canSend()
canSend