2013-07-14 04:49:26 +01:00
// **********************************************************************************
2014-08-13 03:03:19 +01:00
// Driver definition for HopeRF RFM69W/RFM69HW/RFM69CW/RFM69HCW, Semtech SX1231/1231H
2013-07-14 04:49:26 +01:00
// **********************************************************************************
2014-08-13 03:03:19 +01:00
// Copyright Felix Rusu (2014), felix@lowpowerlab.com
// http://lowpowerlab.com/
// **********************************************************************************
// License
// **********************************************************************************
// This program is free software; you can redistribute it
// and/or modify it under the terms of the GNU General
// Public License as published by the Free Software
2014-11-14 20:25:45 +00:00
// Foundation; either version 3 of the License, or
2014-08-13 03:03:19 +01:00
// (at your option) any later version.
//
// This program is distributed in the hope that it will
// be useful, but WITHOUT ANY WARRANTY; without even the
// implied warranty of MERCHANTABILITY or FITNESS FOR A
2014-11-14 20:25:45 +00:00
// PARTICULAR PURPOSE. See the GNU General Public
2014-08-13 03:03:19 +01:00
// License for more details.
//
// You should have received a copy of the GNU General
2014-11-14 20:25:45 +00:00
// Public License along with this program.
// If not, see <http://www.gnu.org/licenses/>.
2014-08-13 03:03:19 +01:00
//
// Licence can be viewed at
2014-11-14 20:25:45 +00:00
// http://www.gnu.org/licenses/gpl-3.0.txt
2014-08-13 03:03:19 +01:00
//
// Please maintain this license information along with authorship
// and copyright notices in any redistribution of this code
2013-07-14 04:49:26 +01:00
// **********************************************************************************
2013-06-20 22:06:39 +01:00
# ifndef RFM69_h
# define RFM69_h
2015-01-06 14:25:29 +00:00
# include <Arduino.h> // assumes Arduino IDE v1.0 or greater
2013-06-20 22:06:39 +01:00
2015-01-06 13:46:04 +00:00
# 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)
# define RF69_SPI_CS SS // SS is the SPI slave select pin, for instance D10 on atmega328
2014-08-13 03:03:19 +01:00
// INT0 on AVRs should be connected to RFM69's DIO0 (ex on Atmega328 it's D2, on Atmega644/1284 it's D2)
2014-11-14 20:25:45 +00:00
# if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
2014-08-13 03:03:19 +01:00
# define RF69_IRQ_PIN 2
# define RF69_IRQ_NUM 0
# elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__)
# define RF69_IRQ_PIN 2
# define RF69_IRQ_NUM 2
2014-11-14 20:25:45 +00:00
# elif defined(__AVR_ATmega32U4__)
# define RF69_IRQ_PIN 3
# define RF69_IRQ_NUM 0
2014-08-13 03:03:19 +01:00
# endif
2014-11-14 20:25:45 +00:00
2015-01-06 13:46:04 +00:00
# define CSMA_LIMIT -90 // upper RX signal sensitivity threshold in dBm for carrier sense access
# define RF69_MODE_SLEEP 0 // XTAL OFF
# define RF69_MODE_STANDBY 1 // XTAL ON
# define RF69_MODE_SYNTH 2 // PLL ON
# define RF69_MODE_RX 3 // RX MODE
# define RF69_MODE_TX 4 // TX MODE
2013-06-20 22:06:39 +01:00
2015-01-06 14:25:29 +00:00
// available frequency bands
2015-01-06 13:46:04 +00:00
# define RF69_315MHZ 31 // non trivial values to avoid misconfiguration
# define RF69_433MHZ 43
# define RF69_868MHZ 86
# define RF69_915MHZ 91
2013-06-20 22:06:39 +01:00
2014-02-02 02:13:40 +00:00
# define null 0
# define COURSE_TEMP_COEF -90 // puts the temperature reading in the ballpark, user can fine tune the returned value
# define RF69_BROADCAST_ADDR 255
2014-08-13 03:03:19 +01:00
# define RF69_CSMA_LIMIT_MS 1000
2015-01-06 13:46:04 +00:00
# define RF69_TX_LIMIT_MS 1000
# define RF69_FSTEP 61.03515625 // == FXOSC/2^19 = 32mhz/2^19 (p13 in DS)
2013-06-20 22:06:39 +01:00
class RFM69 {
public :
2015-01-06 13:46:04 +00:00
static volatile byte DATA [ RF69_MAX_DATA_LEN ] ; // recv/xmit buf, including hdr & crc bytes
2013-07-14 04:49:26 +01:00
static volatile byte DATALEN ;
static volatile byte SENDERID ;
2015-01-06 14:25:29 +00:00
static volatile byte TARGETID ; // should match _address
2013-07-14 04:49:26 +01:00
static volatile byte PAYLOADLEN ;
static volatile byte ACK_REQUESTED ;
2015-01-06 14:25:29 +00:00
static volatile byte ACK_RECEIVED ; // Should be polled immediately after sending a packet with ACK request
static volatile int RSSI ; // most accurate RSSI during reception (closest to the reception)
static volatile byte _mode ; // should be protected?
2015-01-06 13:46:04 +00:00
2014-08-13 03:03:19 +01:00
RFM69 ( byte slaveSelectPin = RF69_SPI_CS , byte interruptPin = RF69_IRQ_PIN , bool isRFM69HW = false , byte interruptNum = RF69_IRQ_NUM ) {
2013-06-20 22:06:39 +01:00
_slaveSelectPin = slaveSelectPin ;
_interruptPin = interruptPin ;
2014-08-13 03:03:19 +01:00
_interruptNum = interruptNum ;
2013-06-20 22:06:39 +01:00
_mode = RF69_MODE_STANDBY ;
_promiscuousMode = false ;
_powerLevel = 31 ;
_isRFM69HW = isRFM69HW ;
}
2013-07-30 21:50:37 +01:00
bool initialize ( byte freqBand , byte ID , byte networkID = 1 ) ;
2013-06-20 22:06:39 +01:00
void setAddress ( byte addr ) ;
2014-11-14 20:25:45 +00:00
void setNetwork ( byte networkID ) ;
2013-06-20 22:06:39 +01:00
bool canSend ( ) ;
void send ( byte toAddress , const void * buffer , byte bufferSize , bool requestACK = false ) ;
2015-01-06 14:25:29 +00:00
bool sendWithRetry ( byte toAddress , const void * buffer , byte bufferSize , byte retries = 2 , byte retryWaitTime = 40 ) ; // 40ms roundtrip req for 61byte packets
2013-06-20 22:06:39 +01:00
bool receiveDone ( ) ;
bool ACKReceived ( byte fromNodeID ) ;
2014-08-13 03:03:19 +01:00
bool ACKRequested ( ) ;
2013-06-20 22:06:39 +01:00
void sendACK ( const void * buffer = " " , uint8_t bufferSize = 0 ) ;
2014-11-14 20:25:45 +00:00
uint32_t getFrequency ( ) ;
void setFrequency ( uint32_t freqHz ) ;
2013-06-20 22:06:39 +01:00
void encrypt ( const char * key ) ;
void setCS ( byte newSPISlaveSelect ) ;
int readRSSI ( bool forceTrigger = false ) ;
void promiscuous ( bool onOff = true ) ;
2015-01-06 14:25:29 +00:00
void setHighPower ( bool onOFF = true ) ; // have to call it after initialize for RFM69HW
void setPowerLevel ( byte level ) ; // reduce/increase transmit power level
2013-06-20 22:06:39 +01:00
void sleep ( ) ;
2015-01-06 14:25:29 +00:00
byte readTemperature ( byte calFactor = 0 ) ; // get CMOS temperature (8bit)
void rcCalibration ( ) ; // calibrate the internal RC oscillator for use in wide temperature variations - see datasheet section [4.3.5. RC Timer Accuracy]
2013-09-06 00:32:11 +01:00
2013-06-20 22:06:39 +01:00
// allow hacking registers by making these public
byte readReg ( byte addr ) ;
void writeReg ( byte addr , byte val ) ;
void readAllRegs ( ) ;
2014-02-02 02:13:40 +00:00
2013-06-20 22:06:39 +01:00
protected :
static void isr0 ( ) ;
2013-09-06 00:32:11 +01:00
void virtual interruptHandler ( ) ;
2013-06-20 22:06:39 +01:00
void sendFrame ( byte toAddress , const void * buffer , byte size , bool requestACK = false , bool sendACK = false ) ;
static RFM69 * selfPointer ;
byte _slaveSelectPin ;
byte _interruptPin ;
2014-08-13 03:03:19 +01:00
byte _interruptNum ;
2013-06-20 22:06:39 +01:00
byte _address ;
bool _promiscuousMode ;
2013-07-14 04:49:26 +01:00
byte _powerLevel ;
2013-06-20 22:06:39 +01:00
bool _isRFM69HW ;
2014-08-13 03:03:19 +01:00
byte _SPCR ;
byte _SPSR ;
2013-06-20 22:06:39 +01:00
void receiveBegin ( ) ;
void setMode ( byte mode ) ;
void setHighPowerRegs ( bool onOff ) ;
void select ( ) ;
void unselect ( ) ;
} ;
2015-01-06 14:25:29 +00:00
# endif