|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628 |
- // RH_MRF89.h
- //
- // Definitions for Microchip MRF89XA family radios radios per:
- // http://ww1.microchip.com/downloads/en/DeviceDoc/70622C.pdf
- // http://ww1.microchip.com/downloads/en/DeviceDoc/75017B.pdf
- //
- // Author: Mike McCauley (mikem@airspayce.com)
- // Copyright (C) 2015 Mike McCauley
- // $Id: RH_MRF89.h,v 1.6 2015/12/17 10:58:13 mikem Exp $
- //
-
- #ifndef RH_RF95_h
- #define RH_RF95_h
-
- #include <RHNRFSPIDriver.h>
-
- // This is the maximum number of interrupts the driver can support
- // Most Arduinos can handle 2, Megas can handle more
- #define RH_MRF89_NUM_INTERRUPTS 3
-
- // Max number of octets the MRF89XA Rx/Tx FIFO can hold
- #define RH_MRF89_FIFO_SIZE 64
-
- // This is the maximum number of bytes that can be carried by the MRF89XA.
- // We use some for headers, keeping fewer for RadioHead messages
- #define RH_MRF89_MAX_PAYLOAD_LEN RH_MRF89_FIFO_SIZE
-
- // The length of the headers we add.
- // The headers are inside the MRF89XA payload
- #define RH_MRF89_HEADER_LEN 4
-
- // This is the maximum user message length that can be supported by this driver.
- // Can be pre-defined to a smaller size (to save SRAM) prior to including this header
- // Here we allow for 4 bytes headers, user data. Message length and CRC are automatically encoded and decoded by
- // the MRF89XA
- #ifndef RH_MRF89_MAX_MESSAGE_LEN
- #define RH_MRF89_MAX_MESSAGE_LEN (RH_MRF89_MAX_PAYLOAD_LEN - RH_MRF89_HEADER_LEN)
- #endif
-
- // Bits that must be set to do a SPI read
- #define RH_MRF89_SPI_READ_MASK 0x40
-
- // The MRF89XA crystal frequency in MHz
- #define RH_MRF89_XTAL_FREQ 12.8
-
- // Register names from Figure 2-18
- #define RH_MRF89_REG_00_GCONREG 0x00
- #define RH_MRF89_REG_01_DMODREG 0x01
- #define RH_MRF89_REG_02_FDEVREG 0x02
- #define RH_MRF89_REG_03_BRSREG 0x03
- #define RH_MRF89_REG_04_FLTHREG 0x04
- #define RH_MRF89_REG_05_FIFOCREG 0x05
- #define RH_MRF89_REG_06_R1CREG 0x06
- #define RH_MRF89_REG_07_P1CREG 0x07
- #define RH_MRF89_REG_08_S1CREG 0x08
- #define RH_MRF89_REG_09_R2CREG 0x09
- #define RH_MRF89_REG_0A_P2CREG 0x0a
- #define RH_MRF89_REG_0B_S2CREG 0x0b
- #define RH_MRF89_REG_0C_PACREG 0x0c
- #define RH_MRF89_REG_0D_FTXRXIREG 0x0d
- #define RH_MRF89_REG_0E_FTPRIREG 0x0e
- #define RH_MRF89_REG_0F_RSTHIREG 0x0f
- #define RH_MRF89_REG_10_FILCREG 0x10
- #define RH_MRF89_REG_11_PFCREG 0x11
- #define RH_MRF89_REG_12_SYNCREG 0x12
- // Hmm the addresses of the next 2 is ambiguous in the docs
- // this seems to agree with whats in the chip:
- #define RH_MRF89_REG_13_RSVREG 0x13
- #define RH_MRF89_REG_14_RSTSREG 0x14
- #define RH_MRF89_REG_15_OOKCREG 0x15
- #define RH_MRF89_REG_16_SYNCV31REG 0x16
- #define RH_MRF89_REG_17_SYNCV23REG 0x17
- #define RH_MRF89_REG_18_SYNCV15REG 0x18
- #define RH_MRF89_REG_19_SYNCV07REG 0x19
- #define RH_MRF89_REG_1A_TXCONREG 0x1a
- #define RH_MRF89_REG_1B_CLKOREG 0x1b
- #define RH_MRF89_REG_1C_PLOADREG 0x1c
- #define RH_MRF89_REG_1D_NADDSREG 0x1d
- #define RH_MRF89_REG_1E_PKTCREG 0x1e
- #define RH_MRF89_REG_1F_FCRCREG 0x1f
-
- // Register bitfield definitions
- //#define RH_MRF89_REG_00_GCONREG 0x00
- #define RH_MRF89_CMOD 0xe0
- #define RH_MRF89_CMOD_TRANSMIT 0x80
- #define RH_MRF89_CMOD_RECEIVE 0x60
- #define RH_MRF89_CMOD_FS 0x40
- #define RH_MRF89_CMOD_STANDBY 0x20
- #define RH_MRF89_CMOD_SLEEP 0x00
-
- #define RH_MRF89_FBS 0x18
- #define RH_MRF89_FBS_950_960 0x10
- #define RH_MRF89_FBS_915_928 0x08
- #define RH_MRF89_FBS_902_915 0x00
-
- #define RH_MRF89_VCOT 0x06
- #define RH_MRF89_VCOT_180MV 0x06
- #define RH_MRF89_VCOT_120MV 0x04
- #define RH_MRF89_VCOT_60MV 0x02
- #define RH_MRF89_VCOT_TANK 0x00
-
- #define RH_MRF89_RPS 0x01
-
- //#define RH_MRF89_REG_01_DMODREG 0x01
- #define RH_MRF89_MODSEL 0xc0
- #define RH_MRF89_MODSEL_FSK 0x80
- #define RH_MRF89_MODSEL_OOK 0x40
-
- #define RH_MRF89_DMODE0 0x20
-
- #define RH_MRF89_OOKTYP 0x18
- #define RH_MRF89_OOKTYP_AVERAGE 0x10
- #define RH_MRF89_OOKTYP_PEAK 0x08
- #define RH_MRF89_OOKTYP_FIXED 0x00
-
- #define RH_MRF89_DMODE1 0x04
-
- #define RH_MRF89_IFGAIN 0x03
- #define RH_MRF89_IFGAIN_M13P5 0x03
- #define RH_MRF89_IFGAIN_M9 0x02
- #define RH_MRF89_IFGAIN_M4P5 0x01
- #define RH_MRF89_IFGAIN_0 0x00
-
- // DMODE1 and DMODE1:
- #define RH_MRF89_OPMODE_CONTINUOUS 0x00
- #define RH_MRF89_OPMODE_BUFFER RH_MRF89_DMODE0
- #define RH_MRF89_OPMODE_PACKET RH_MRF89_DMODE1
-
- //#define RH_MRF89_REG_03_BRSREG 0x03
- #define RH_MRF89_BRVAL 0x7f
-
- //#define RH_MRF89_REG_05_FIFOCREG 0x05
- #define RH_MRF89_FSIZE 0xc0
- #define RH_MRF89_FSIZE_64 0xc0
- #define RH_MRF89_FSIZE_48 0x80
- #define RH_MRF89_FSIZE_32 0x40
- #define RH_MRF89_FSIZE_16 0x00
-
- #define RH_MRF89_FTINT 0x3f
-
- //#define RH_MRF89_REG_0C_PACREG 0x0c
- #define RH_MRF89_PARC 0x18
- #define RH_MRF89_PARC_23 0x18
- #define RH_MRF89_PARC_15 0x10
- #define RH_MRF89_PARC_8P5 0x08
- #define RH_MRF89_PARC_3 0x00
-
- //#define RH_MRF89_REG_0D_FTXRXIREG 0x0d
- #define RH_MRF89_IRQ0RXS 0xc0
- #define RH_MRF89_IRQ0RXS_CONT_RSSI 0x40
- #define RH_MRF89_IRQ0RXS_CONT_SYNC 0x00
- #define RH_MRF89_IRQ0RXS_BUFFER_SYNC 0xc0
- #define RH_MRF89_IRQ0RXS_BUFFER_FIFOEMPTY 0x80
- #define RH_MRF89_IRQ0RXS_BUFFER_WRITEBYTE 0x40
- #define RH_MRF89_IRQ0RXS_BUFFER_NONE 0x00
- #define RH_MRF89_IRQ0RXS_PACKET_SYNC 0xc0
- #define RH_MRF89_IRQ0RXS_PACKET_FIFOEMPTY 0x80
- #define RH_MRF89_IRQ0RXS_PACKET_WRITEBYTE 0x40
- #define RH_MRF89_IRQ0RXS_PACKET_PLREADY 0x00
-
- #define RH_MRF89_IRQ1RXS 0x30
- #define RH_MRF89_IRQ1RXS_CONT_DCLK 0x00
- #define RH_MRF89_IRQ1RXS_BUFFER_FIFO_THRESH 0x30
- #define RH_MRF89_IRQ1RXS_BUFFER_RSSI 0x20
- #define RH_MRF89_IRQ1RXS_BUFFER_FIFOFULL 0x10
- #define RH_MRF89_IRQ1RXS_BUFFER_NONE 0x00
- #define RH_MRF89_IRQ1RXS_PACKET_FIFO_THRESH 0x30
- #define RH_MRF89_IRQ1RXS_PACKET_RSSI 0x20
- #define RH_MRF89_IRQ1RXS_PACKET_FIFOFULL 0x10
- #define RH_MRF89_IRQ1RXS_PACKET_CRCOK 0x00
-
- #define RH_MRF89_IRQ1TX 0x08
- #define RH_MRF89_FIFOFULL 0x04
- #define RH_MRF89_FIFOEMPTY 0x02
- #define RH_MRF89_FOVRUN 0x01
-
- //#define RH_MRF89_REG_0E_FTPRIREG 0x0e
- #define RH_MRF89_FIFOFM 0x80
- #define RH_MRF89_FIFOFSC 0x40
- #define RH_MRF89_TXDONE 0x20
- #define RH_MRF89_IRQ0TXST 0x10
- #define RH_MRF89_RIRQS 0x04
- #define RH_MRF89_LSTSPLL 0x02
- #define RH_MRF89_LENPLL 0x01
-
- //#define RH_MRF89_REG_10_FILCREG 0x10
- #define RH_MRF89_PASFILV 0xf0
- #define RH_MRF89_PASFILV_987KHZ 0xf0
- #define RH_MRF89_PASFILV_676KHZ 0xe0
- #define RH_MRF89_PASFILV_514KHZ 0xd0
- #define RH_MRF89_PASFILV_458KHZ 0xc0
- #define RH_MRF89_PASFILV_414KHZ 0xb0
- #define RH_MRF89_PASFILV_378KHZ 0xa0
- #define RH_MRF89_PASFILV_321KHZ 0x90
- #define RH_MRF89_PASFILV_262KHZ 0x80
- #define RH_MRF89_PASFILV_234KHZ 0x70
- #define RH_MRF89_PASFILV_211KHZ 0x60
- #define RH_MRF89_PASFILV_184KHZ 0x50
- #define RH_MRF89_PASFILV_157KHZ 0x40
- #define RH_MRF89_PASFILV_137KHZ 0x30
- #define RH_MRF89_PASFILV_109KHZ 0x20
- #define RH_MRF89_PASFILV_82KHZ 0x10
- #define RH_MRF89_PASFILV_65KHZ 0x00
-
- #define RH_MRF89_BUTFILV 0x0f
- #define RH_MRF89_BUTFILV_25KHZ 0x00
- #define RH_MRF89_BUTFILV_50KHZ 0x01
- #define RH_MRF89_BUTFILV_75KHZ 0x02
- #define RH_MRF89_BUTFILV_100KHZ 0x03
- #define RH_MRF89_BUTFILV_125KHZ 0x04
- #define RH_MRF89_BUTFILV_150KHZ 0x05
- #define RH_MRF89_BUTFILV_175KHZ 0x06
- #define RH_MRF89_BUTFILV_200KHZ 0x07
- #define RH_MRF89_BUTFILV_225KHZ 0x08
- #define RH_MRF89_BUTFILV_250KHZ 0x09
- #define RH_MRF89_BUTFILV_275KHZ 0x0a
- #define RH_MRF89_BUTFILV_300KHZ 0x0b
- #define RH_MRF89_BUTFILV_325KHZ 0x0c
- #define RH_MRF89_BUTFILV_350KHZ 0x0d
- #define RH_MRF89_BUTFILV_375KHZ 0x0e
- #define RH_MRF89_BUTFILV_400KHZ 0x0f
-
- //#define RH_MRF89_REG_11_PFCREG 0x11
- #define RH_MRF89_POLCFV 0xf0
-
- //#define RH_MRF89_REG_12_SYNCREG 0x12
- #define RH_MRF89_POLFILEN 0x80
- #define RH_MRF89_BSYNCEN 0x40
- #define RH_MRF89_SYNCREN 0x20
- #define RH_MRF89_SYNCWSZ 0x18
- #define RH_MRF89_SYNCWSZ_32 0x18
- #define RH_MRF89_SYNCWSZ_24 0x10
- #define RH_MRF89_SYNCWSZ_16 0x08
- #define RH_MRF89_SYNCWSZ_8 0x00
- #define RH_MRF89_SYNCTEN 0x06
- #define RH_MRF89_SYNCTEN_3 0x06
- #define RH_MRF89_SYNCTEN_2 0x04
- #define RH_MRF89_SYNCTEN_1 0x02
- #define RH_MRF89_SYNCTEN_0 0x00
-
- //#define RH_MRF89_REG_15_OOKCREG 0x15
- #define RH_MRF89_OOTHSV 0xe0
- #define RH_MRF89_OOTHSV_6P0DB 0xe0
- #define RH_MRF89_OOTHSV_5P0DB 0xc0
- #define RH_MRF89_OOTHSV_4P0DB 0xa0
- #define RH_MRF89_OOTHSV_3P0DB 0x80
- #define RH_MRF89_OOTHSV_2P0DB 0x60
- #define RH_MRF89_OOTHSV_1P5DB 0x40
- #define RH_MRF89_OOTHSV_1P0DB 0x20
- #define RH_MRF89_OOTHSV_0P5DB 0x00
-
- #define RH_MRF89_OOKTHPV 0x1c
- #define RH_MRF89_OOKTHPV_16 0x1c
- #define RH_MRF89_OOKTHPV_8 0x18
- #define RH_MRF89_OOKTHPV_4 0x14
- #define RH_MRF89_OOKTHPV_2 0x10
- #define RH_MRF89_OOKTHPV_1_IN_8 0x0c
- #define RH_MRF89_OOKTHPV_1_IN_4 0x08
- #define RH_MRF89_OOKTHPV_1_IN_2 0x04
- #define RH_MRF89_OOKTHPV_1_IN_1 0x00
-
- #define RH_MRF89_OOKATHC 0x03
- #define RH_MRF89_OOKATHC_32PI 0x03
- #define RH_MRF89_OOKATHC_8PI 0x00
-
- //#define RH_MRF89_REG_1A_TXCONREG 0x1a
- #define RH_MRF89_TXIPOLFV 0xf0
-
- #define RH_MRF89_TXOPVAL 0x0e
- #define RH_MRF89_TXOPVAL_M8DBM 0x0e
- #define RH_MRF89_TXOPVAL_M5DBM 0x0c
- #define RH_MRF89_TXOPVAL_M2DBM 0x0a
- #define RH_MRF89_TXOPVAL_1DBM 0x08
- #define RH_MRF89_TXOPVAL_4DBM 0x06
- #define RH_MRF89_TXOPVAL_7DBM 0x04
- #define RH_MRF89_TXOPVAL_10DBM 0x02
- #define RH_MRF89_TXOPVAL_13DBM 0x00
-
- //#define RH_MRF89_REG_1B_CLKOREG 0x1b
- #define RH_MRF89_CLKOCNTRL 0x80
- #define RH_MRF89_CLKOFREQ 0x7c
-
- //#define RH_MRF89_REG_1C_PLOADREG 0x1c
- #define RH_MRF89_MCHSTREN 0x80
- #define RH_MRF89_PLDPLEN 0x7f
-
- //#define RH_MRF89_REG_1E_PKTCREG 0x1e
- #define RH_MRF89_PKTLENF 0x80
-
- #define RH_MRF89_PRESIZE 0x60
- #define RH_MRF89_PRESIZE_4 0x60
- #define RH_MRF89_PRESIZE_3 0x40
- #define RH_MRF89_PRESIZE_2 0x20
- #define RH_MRF89_PRESIZE_1 0x00
-
- #define RH_MRF89_WHITEON 0x10
- #define RH_MRF89_CHKCRCEN 0x08
-
- #define RH_MRF89_ADDFIL 0x06
- #define RH_MRF89_ADDFIL_NODEADDR_00_FF 0x06
- #define RH_MRF89_ADDFIL_NODEADDR_00 0x04
- #define RH_MRF89_ADDFIL_NODEADDR 0x02
- #define RH_MRF89_ADDFIL_OFF 0x00
-
- #define RH_MRF89_STSCRCEN 0x01
-
- //#define RH_MRF89_REG_1F_FCRCREG 0x1f
- #define RH_MRF89_ACFCRC 0x80
- #define RH_MRF89_FRWAXS 0x40
-
-
- /////////////////////////////////////////////////////////////////////
- /// \class RH_MRF89 RH_MRF89.h <RH_MRF89.h>
- /// \brief Send and receive addressed, reliable, acknowledged datagrams by Microchip MRF89XA and compatible transceivers.
- /// and modules.
- ///
- /// The Microchip MRF89XA http://ww1.microchip.com/downloads/en/DeviceDoc/70622C.pdf is a low cost 900MHz
- /// bancd transceiver chip.
- /// It is commonly used on preassembled modules with supporting circcuits and antennas, such as
- /// the MRF89XAM9A http://www.microchip.com/wwwproducts/Devices.aspx?product=MRF89XAM9A
- /// This class supports all such modules
- ///
- /// This base class provides basic functions for sending and receiving unaddressed, unreliable datagrams
- /// of arbitrary length to 59 octets per packet. Use one of the Manager classes to get addressing and
- /// acknowledgement reliability, routing, meshes etc.
- ///
- /// Several MRF89XA modules can be connected to an Arduino, permitting the construction of translators
- /// and frequency changers, etc. Each instance requires 2 chip select pins, and interrupt pin the standard 3 SPI pins.
- ///
- /// Naturally, for any 2 radios to communicate that must be configured to use the same frequency and
- /// data rate, and with identical network addresses.
- ///
- /// Example Arduino programs are included to show the main modes of use.
- ///
- /// All messages sent and received by this class conform to this packet format:
- ///
- /// - 3 octets PREAMBLE
- /// - 2 to 4 octets NETWORK ADDRESS (also call Sync Word)
- /// - 1 octet message length bits packet control field
- /// - 4 to 63 octets PAYLOAD, consisting of:
- /// - 1 octet TO header
- /// - 1 octet FROM header
- /// - 1 octet ID header
- /// - 1 octet FLAGS header
- /// - 0 to 59 octets of user message
- /// - 2 octets CRC
- ///
- /// The payload is whitened. No Manchester encoding is used.
- ///
- /// \par Connecting MRF89XA to Arduino
- ///
- /// The electrical connection between the MRF89XA and the Arduino require 3.3V, the 3 x SPI pins (SCK, SDI, SDO),
- /// a 2 Chip Select pins (/CSCON and /CSDAT) and an interrupt.
- ///
- /// Caution: the MRF89XA is a 3.3V part and is not tolerant of 5V inputs. Connecting MRF89XA directly to a 5V
- /// MCU such as most Arduinos will damage the MRF89XA.
- ///
- /// Connect the MRF89XA to most 3.3V Arduinos or Teensy 3.1 like this (use 3.3V not 5V).
- /// \code
- /// Teensy MRF89XAM9A
- /// 3.3V-----------VIN (3.3V in)
- /// pin D9-----------/CSDAT (data chip select in)
- /// SS pin D10----------/CSCON (configuration chip select in)
- /// SCK pin D13----------SCK (SPI clock in)
- /// MOSI pin D11----------SDI (SPI Data in)
- /// MISO pin D12----------SDO (SPI data out)
- /// D2-----------IRQ1 (Interrupt 1 output)
- /// IRQ0 (Interrupt 0 output, not connected)
- /// GND----------GND (ground in)
- /// \endcode
- /// You can use other pins for /CSDAT, /CSCON, IRQ1 by passing appropriate arguments to the constructor.
- ///
- /// \par Example programs
- ///
- /// Several example programs are provided.
- ///
- class RH_MRF89 : public RHNRFSPIDriver
- {
- public:
-
- /// \brief Defines register configuration values for a desired modulation
- ///
- /// Defines values for various configuration fields and registers to
- /// achieve a desired modulation speed and frequency deviation.
- typedef struct
- {
- uint8_t MODSEL; ///< Value for MODSEL in RH_MRF89_REG_01_DMODREG
- uint8_t FDVAL; ///< Value for FDVAL in RH_MRF89_REG_02_FDEVREG
- uint8_t BRVAL; ///< Value for BRVAL RH_MRF89_REG_03_BRSREG
- uint8_t FILCREG; ///< Value for PASFILV | BUTFILV in RH_MRF89_REG_10_FILCREG
- uint8_t TXIPOLFV; ///< Value for TXIPOLFV in RH_MRF89_REG_1A_TXCONREG
- } ModemConfig;
-
- /// Choices for setModemConfig() for a selected subset of common
- /// data rates and frequency deviations.
- /// Rb is the data rate in kbps. Fd is the FSK Frequency deviation in kHz.
- /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic
- /// definitions and not their integer equivalents: its possible that new values will be
- /// introduced in later versions (though we will try to avoid it).
- /// OOK is not yet supported.
- /// Based on sample configs in MRF89XA.h from Microchip
- typedef enum
- {
- FSK_Rb2Fd33 = 0, ///< FSK, No Manchester, Whitened, Rb = 2kbs, Fd = 33kHz
- FSK_Rb5Fd33, ///< FSK, No Manchester, Whitened, Rb = 5kbs, Fd = 33kHz
- FSK_Rb10Fd33, ///< FSK, No Manchester, Whitened, Rb = 10kbs, Fd = 33kHz
- FSK_Rb20Fd40, ///< FSK, No Manchester, Whitened, Rb = 20kbs, Fd = 40kHz
- FSK_Rb40Fd80, ///< FSK, No Manchester, Whitened, Rb = 40kbs, Fd = 80kHz
- FSK_Rb50Fd100, ///< FSK, No Manchester, Whitened, Rb = 50kbs, Fd = 100kHz
- FSK_Rb66Fd133, ///< FSK, No Manchester, Whitened, Rb = 66kbs, Fd = 133kHz
- FSK_Rb100Fd200, ///< FSK, No Manchester, Whitened, Rb = 100kbs, Fd = 200kHz
- FSK_Rb200Fd200 ///< FSK, No Manchester, Whitened, Rb = 200kbs, Fd = 200kHz
- } ModemConfigChoice;
-
- /// Constructor.
- /// Constructor. You can have multiple instances, but each instance must have its own
- /// interrupt and 2 slave select pins. After constructing, you must call init() to initialise the interface
- /// and the radio module. A maximum of 3 instances can co-exist on one processor, provided there are sufficient
- /// distinct interrupt lines, one for each instance.
- /// \param[in] csconPin the Arduino pin number connected to the CSCON pin of the MRF89XA.
- /// Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega, D10 for Maple)
- /// \param[in] csdatPin the Arduino pin number connected to the CSDAT pin of the MRF89XA.
- /// Defaults to 9.
- /// \param[in] interruptPin The interrupt Pin number that is connected to the IRQ1 pin of the MRF89XA.
- /// Defaults to pin 2. (IRQ0 pin of the MRF89XA does not need to be connected).
- /// \param[in] spi Pointer to the SPI interface object to use.
- /// Defaults to the standard Arduino hardware SPI interface
- RH_MRF89(uint8_t csconPin = SS, uint8_t csdatPin = 9, uint8_t interruptPin = 2, RHGenericSPI& spi = hardware_spi);
-
- /// Initialise the Driver transport hardware and software.
- /// Make sure the Driver is properly configured before calling init().
- /// \return true if initialisation succeeded.
- virtual bool init();
-
- /// Prints the value of all chip registers
- /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
- /// For debugging purposes only.
- /// \return true on success
- bool printRegisters();
-
- /// Sets the radio into low-power sleep mode.
- /// If successful, the transport will stay in sleep mode until woken by
- /// changing mode to idle, transmit or receive (eg by calling send(), recv(), available() etc)
- /// Caution: there is a time penalty as the radio takes a finite time to wake from sleep mode.
- /// \return true if sleep mode was successfully entered.
- virtual bool sleep();
-
- /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,
- /// disables them.
- void setModeIdle();
-
- /// If current mode is Tx or Idle, changes it to Rx.
- /// Starts the receiver in the radio.
- // the next valid packet received will cause available() to be true.
- void setModeRx();
-
- /// If current mode is Rx or Idle, changes it to Rx. F
- /// Starts the transmitter in the radio.
- void setModeTx();
-
- /// Sets the transmitter power output level in register RH_MRF89_REG_1A_TXCONREG.
- /// Be a good neighbour and set the lowest power level you need.
- /// After init(), the power will be set to RH_MRF89_TXOPVAL_1DBM (1dBm)
- /// The highest power available is RH_MRF89_TXOPVAL_13DBM (13dBm)
- /// Caution: In some countries you may only select certain higher power levels if you
- /// are also using frequency hopping. Make sure you are aware of the legal
- /// limitations and regulations in your region.
- /// Caution: in some countries the maximum permitted power level may depend on the Bit rate
- /// \param[in] power Transmitter power level, one of RH_MRF89_TXOPVAL*
- void setTxPower(uint8_t power);
-
- /// Select one of the predefined modem configurations. If you need a modem configuration not provided
- /// here, use setModemRegisters() with your own ModemConfig.
- /// \param[in] index The configuration choice.
- /// \return true if index is a valid choice.
- bool setModemConfig(ModemConfigChoice index);
-
- /// Tests whether a new message is available
- /// from the Driver.
- /// On most drivers, this will also put the Driver into RHModeRx mode until
- /// a message is actually received by the transport, when it will be returned to RHModeIdle.
- /// This can be called multiple times in a timeout loop
- /// \return true if a new, complete, error-free uncollected message is available to be retreived by recv()
- virtual bool available();
-
- /// Turns the receiver on if it not already on.
- /// If there is a valid message available, copy it to buf and return true
- /// else return false.
- /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
- /// You should be sure to call this function frequently enough to not miss any messages
- /// It is recommended that you call it in your main loop.
- /// \param[in] buf Location to copy the received message
- /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.
- /// \return true if a valid message was copied to buf
- virtual bool recv(uint8_t* buf, uint8_t* len);
-
- /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
- /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
- /// of 0 is permitted.
- /// \param[in] data Array of data to be sent
- /// \param[in] len Number of bytes of data to send
- /// \return true if the message length was valid and it was correctly queued for transmit
- virtual bool send(const uint8_t* data, uint8_t len);
-
- /// Returns the maximum message length
- /// available in this Driver.
- /// \return The maximum legal message length
- virtual uint8_t maxMessageLength();
-
- /// Sets the centre frequency in MHz.
- /// Permitted ranges are: 902.0 to 928.0 and 950.0 to 960.0 (inclusive)
- /// Caution not all freqs are supported on all modules: check your module specifications
- /// Caution: not all available and supported frequencies are legal in every country: check
- /// Regulatory Approval eg for MRF89XAM9A (in 75015B.pdf)
- /// Australia 915.0 to 928.0
- bool setFrequency(float centre);
-
- /// Sets the length of the preamble
- /// in bytes.
- /// Caution: this should be set to the same
- /// value on all nodes in your network. Default is 4.
- /// Sets the message preamble length in RH_MRF89_REG_1E_PKTCREG
- /// \param[in] bytes Preamble length in bytes of 8 bits each.
- void setPreambleLength(uint8_t bytes);
-
- /// Sets the sync words for transmit and receive in registers RH_MRF89_REG_16_SYNCV31REG
- /// et seq.
- /// Caution: SyncWords should be set to the same
- /// value on all nodes in your network. Nodes with different SyncWords set will never receive
- /// each others messages, so different SyncWords can be used to isolate different
- /// networks from each other. Default is { 0x69, 0x81, 0x7e, 0x96 }.
- /// Caution, sync words of 2 bytes and less do not work well with this chip.
- /// \param[in] syncWords Array of sync words, 1 to 4 octets long
- /// \param[in] len Number of sync words to set, 1 to 4.
- void setSyncWords(const uint8_t* syncWords = NULL, uint8_t len = 0);
-
- protected:
-
- /// Called automatically when a CRCOK or TXDONE interrupt occurs.
- /// Handles the interrupt.
- void handleInterrupt();
-
- /// Reads a single register from the MRF89XA
- /// \param[in] reg Register number, one of RH_MRF89_REG
- /// \return The value of the register
- uint8_t spiReadRegister(uint8_t reg);
-
- /// Writes to a single single register on the MRF89XA
- /// \param[in] reg Register number, one of RH_MRF89_REG_*
- /// \param[in] val The value to write
- /// \return the current value of RH_MRF89_REG_00_GCONREG (read while the command is sent)
- uint8_t spiWriteRegister(uint8_t reg, uint8_t val);
-
- /// Writes a single byte to the MRF89XA data FIFO.
- /// \param[in] data The data value to write
- /// \return 0
- uint8_t spiWriteData(uint8_t data);
-
- /// Write a number of bytes from a buffer to the MRF89XA data FIFO.
- /// \param[in] data Pointer to a buffer containing the len bytes to be written
- /// \param[in] len The number of bytes to write to teh FIFO
- /// \return 0;
- uint8_t spiWriteData(const uint8_t* data, uint8_t len);
-
- /// Reads a single byte from the MRF89XA data FIFO.
- /// \return The next data byte in the FIFO
- uint8_t spiReadData();
-
- /// Sets the operating mode in the CMOD bits in RH_MRF89_REG_00_GCONREG
- /// which controls what mode the MRF89XA is running in
- /// \param[in] mode One of RH_MRF89_CMOD_*
- void setOpMode(uint8_t mode);
-
- /// Verifies that the MRF89XA PLL has locked on the slected frequency.
- /// This needs to be called if the frequency is changed
- bool verifyPLLLock();
-
- /// Examine the revceive buffer to determine whether the message is for this node
- void validateRxBuf();
-
- /// Clear our local receive buffer
- void clearRxBuf();
-
-
- private:
- /// Low level interrupt service routine for device connected to interrupt 0
- static void isr0();
-
- /// Low level interrupt service routine for device connected to interrupt 1
- static void isr1();
-
- /// Low level interrupt service routine for device connected to interrupt 1
- static void isr2();
-
- /// Array of instances connected to interrupts 0 and 1
- static RH_MRF89* _deviceForInterrupt[];
-
- /// Index of next interrupt number to use in _deviceForInterrupt
- static uint8_t _interruptCount;
-
- // Sigh: this chip has 2 differnt chip selects.
- // We have to set one or the other as the SPI slave select pin depending
- // on which block of registers we are accessing
- uint8_t _csconPin;
- uint8_t _csdatPin;
-
- /// The configured interrupt pin connected to this instance
- uint8_t _interruptPin;
-
- /// The index into _deviceForInterrupt[] for this device (if an interrupt is already allocated)
- /// else 0xff
- uint8_t _myInterruptIndex;
-
- /// Number of octets in the buffer
- volatile uint8_t _bufLen;
-
- /// The receiver/transmitter buffer
- uint8_t _buf[RH_MRF89_MAX_PAYLOAD_LEN];
-
- /// True when there is a valid message in the buffer
- volatile bool _rxBufValid;
-
- };
-
- /// @example mrf89_client.pde
- /// @example mrf89_server.pde
-
- #endif
|