Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of RF22 by
RF22.h
00001 // RF22.h 00002 // Author: Mike McCauley (mikem@open.com.au) 00003 // Copyright (C) 2011 Mike McCauley 00004 // $Id: RF22.h,v 1.23 2013/02/06 21:33:56 mikem Exp mikem $ 00005 // 00006 // ported to mbed by Karl Zweimueller 00007 /// \mainpage RF22 library for Arduino 00008 /// 00009 /// This is the Arduino RF22 library. 00010 /// It provides an object-oriented interface for sending and receiving data messages with Hope-RF 00011 /// RF22B based radio modules, and compatible chips and modules, 00012 /// including the RFM22B transceiver module such as 00013 /// this bare module: http://www.sparkfun.com/products/10153 00014 /// and this shield: https://www.sparkfun.com/products/11018 00015 /// 00016 /// RF22 also supports some of the features of ZigBee and XBee, 00017 /// (such as mesh routing and automatic route discovery), 00018 /// but with a much less complicated system and less expensive radios. 00019 /// 00020 /// The Hope-RF (http://www.hoperf.com) RFM22B (http://www.hoperf.com/rf_fsk/fsk/RFM22B.htm) 00021 /// is a low-cost ISM transceiver module. It supports FSK, GFSK, OOK over a wide 00022 /// range of frequencies and programmable data rates. 00023 /// 00024 /// This library provides functions for sending and receiving messages of up to 255 octets on any 00025 /// frequency supported by the RF22B, in a range of predefined data rates and frequency deviations. 00026 /// Frequency can be set with 312Hz precision to any frequency from 240.0MHz to 960.0MHz. 00027 /// 00028 /// Up to 2 RF22B modules can be connected to an Arduino, permitting the construction of translators 00029 /// and frequency changers, etc. 00030 /// 00031 /// This library provides classes for 00032 /// - RF22: unaddressed, unreliable messages 00033 /// - RF22Datagram: addressed, unreliable messages 00034 /// - RF22ReliableDatagram: addressed, reliable, retransmitted, acknowledged messages. 00035 /// - RF22Router: multi hop delivery from source node to destination node via 0 or more intermediate nodes 00036 /// - RF22Mesh: multi hop delivery with automatic route discovery and rediscovery. 00037 /// 00038 /// The following modulation types are suppported with a range of modem configurations for 00039 /// common data rates and frequency deviations: 00040 /// - GFSK Gaussian Frequency Shift Keying 00041 /// - FSK Frequency Shift Keying 00042 /// - OOK On-Off Keying 00043 /// 00044 /// Support for other RF22B features such as on-chip temperature measurement, analog-digital 00045 /// converter, transmitter power control etc is also provided. 00046 /// 00047 /// The latest version of this documentation can be downloaded from 00048 /// http://www.open.com.au/mikem/arduino/RF22 00049 /// 00050 /// Example Arduino programs are included to show the main modes of use. 00051 /// 00052 /// The version of the package that this documentation refers to can be downloaded 00053 /// from http://www.open.com.au/mikem/arduino/RF22/RF22-1.25.zip 00054 /// You can find the latest version at http://www.open.com.au/mikem/arduino/RF22 00055 /// 00056 /// You can also find online help and disussion at http://groups.google.com/group/rf22-arduino 00057 /// Please use that group for all questions and discussions on this topic. 00058 /// Do not contact the author directly, unless it is to discuss commercial licensing. 00059 /// 00060 /// Tested on Arduino Diecimila and Mega with arduino-0021 00061 /// on OpenSuSE 11.1 and avr-libc-1.6.1-1.15, 00062 /// cross-avr-binutils-2.19-9.1, cross-avr-gcc-4.1.3_20080612-26.5. 00063 /// With HopeRF RFM22 modules that appear to have RF22B chips on board: 00064 /// - Device Type Code = 0x08 (RX/TRX) 00065 /// - Version Code = 0x06 00066 /// It is known not to work on Diecimila. Dont bother trying. 00067 /// 00068 /// \par Packet Format 00069 /// 00070 /// All messages sent and received by this RF22 library must conform to this packet format: 00071 /// 00072 /// - 8 nibbles (4 octets) PREAMBLE 00073 /// - 2 octets SYNC 0x2d, 0xd4 00074 /// - 4 octets HEADER: (TO, FROM, ID, FLAGS) 00075 /// - 1 octet LENGTH (0 to 255), number of octets in DATA 00076 /// - 0 to 255 octets DATA 00077 /// - 2 octets CRC computed with CRC16(IBM), computed on HEADER, LENGTH and DATA 00078 /// 00079 /// For technical reasons, the message format is not compatible with the 00080 /// 'HopeRF Radio Transceiver Message Library for Arduino' http://www.open.com.au/mikem/arduino/HopeRF from the same author. Nor is it compatible with 00081 /// 'Virtual Wire' http://www.open.com.au/mikem/arduino/VirtualWire.pdf also from the same author. 00082 /// 00083 /// \par Connecting RFM-22 to Arduino 00084 /// 00085 /// If you have the Sparkfun RFM22 Shield (https://www.sparkfun.com/products/11018) 00086 /// the connections described below are done for you on the shield, no changes required, 00087 /// just add headers and plug it in to an Arduino (but not and Arduino Mega, see below) 00088 /// 00089 /// The physical connection between the RF22B and the Arduino require 3.3V, the 3 x SPI pins (SCK, SDI, SDO), 00090 /// a Slave Select pin and an interrupt pin. 00091 /// Note also that on the RFF22B, it is required to control the TX_ANT and X_ANT pins of the RFM22 in order to enable the 00092 /// antenna connection. The RF22 library is configured so that GPIO0 and GPIO1 outputs can control TX_ANT and RX_ANT input pins 00093 /// automatically. You must connect GPIO0 to TX_ANT and GPIO1 to RX_ANT for this automatic antenna switching to occur. 00094 /// 00095 /// Connect the RFM-22 to most Arduino's like this (Caution, Arduino Mega has different pins for SPI, 00096 /// see below): 00097 /// \code 00098 /// Arduino RFM-22B 00099 /// GND----------GND-\ (ground in) 00100 /// SDN-/ (shutdown in) 00101 /// 3V3----------VCC (3.3V in) 00102 /// interrupt 0 pin D2-----------NIRQ (interrupt request out) 00103 /// SS pin D10----------NSEL (chip select in) 00104 /// SCK pin D13----------SCK (SPI clock in) 00105 /// MOSI pin D11----------SDI (SPI Data in) 00106 /// MISO pin D12----------SDO (SPI data out) 00107 /// /--GPIO0 (GPIO0 out to control transmitter antenna TX_ANT 00108 /// \--TX_ANT (TX antenna control in) 00109 /// /--GPIO1 (GPIO1 out to control receiver antenna RX_ANT 00110 /// \--RX_ANT (RX antenna control in) 00111 /// \endcode 00112 /// For an Arduino Mega: 00113 /// \code 00114 /// Mega RFM-22B 00115 /// GND----------GND-\ (ground in) 00116 /// SDN-/ (shutdown in) 00117 /// 3V3----------VCC (3.3V in) 00118 /// interrupt 0 pin D2-----------NIRQ (interrupt request out) 00119 /// SS pin D53----------NSEL (chip select in) 00120 /// SCK pin D52----------SCK (SPI clock in) 00121 /// MOSI pin D51----------SDI (SPI Data in) 00122 /// MISO pin D50----------SDO (SPI data out) 00123 /// /--GPIO0 (GPIO0 out to control transmitter antenna TX_ANT 00124 /// \--TX_ANT (TX antenna control in) 00125 /// /--GPIO1 (GPIO1 out to control receiver antenna RX_ANT 00126 /// \--RX_ANT (RX antenna control in) 00127 /// \endcode 00128 /// and you can then use the default constructor RF22(). 00129 /// You can override the default settings for the SS pin and the interrupt 00130 /// in the RF22 constructor if you wish to connect the slave select SS to other than the normal one for your 00131 /// Arduino (D10 for Diecimila, Uno etc and D53 for Mega) 00132 /// or the interrupt request to other than pin D2. 00133 /// 00134 /// It is possible to have 2 radios conected to one arduino, provided each radio has its own 00135 /// SS and interrupt line (SCK, SDI and SDO are common to both radios) 00136 /// 00137 /// Caution: on some Arduinos such as the Mega 2560, if you set the slave select pin to be other than the usual SS 00138 /// pin (D53 on Mega 2560), you may need to set the usual SS pin to be an output to force the Arduino into SPI 00139 /// master mode. 00140 /// 00141 /// Caution: Power supply requirements of the RF22 module may be relevant in some circumstances: 00142 /// RF22 modules are capable of pulling 80mA+ at full power, where Arduino's 3.3V line can 00143 /// give 50mA. You may need to make provision for alternate power supply for 00144 /// the RF22, especially if you wish to use full transmit power, and/or you have 00145 /// other shields demanding power. Inadequate power for the RF22 is reported to cause symptoms such as: 00146 /// - reset's/bootups terminate with "init failed" messages 00147 /// -random termination of communication after 5-30 packets sent/received 00148 /// -"fake ok" state, where initialization passes fluently, but communication doesn't happen 00149 /// -shields hang Arduino boards, especially during the flashing 00150 /// 00151 /// 00152 /// \par Interrupts 00153 /// 00154 /// The RF22 library uses interrupts to react to events in the RF22 module, 00155 /// such as the reception of a new packet, or the completion of transmission of a packet. 00156 /// The RF22 library interrupt service routine reads status from and writes data 00157 /// to the the RF22 module via the SPI interface. It is very important therefore, 00158 /// that if you are using the RF22 library with another SPI based deviced, that you 00159 /// disable interrupts while you transfer data to and from that other device. 00160 /// Use cli() to disable interrupts and sei() to reenable them. 00161 /// 00162 /// \par Memory 00163 /// 00164 /// The RF22 library requires non-trivial amounts of memory. The sample programs above all compile to 00165 /// about 9 to 14kbytes each, which will fit in the flash proram memory of most Arduinos. However, 00166 /// the RAM requirements are more critical. Most sample programs above will run on Duemilanova, 00167 /// but not on Diecimila. Even on Duemilanova, the RAM requirements are very close to the 00168 /// available memory of 2kbytes. Therefore, you should be vary sparing with RAM use in programs that use 00169 /// the RF22 library on Duemilanova. 00170 /// 00171 /// The sample RF22Router and RF22Mesh programs compile to about 14kbytes, 00172 /// and require more RAM than the others. 00173 /// They will not run on Duemilanova or Diecimila, but will run on Arduino Mega. 00174 /// 00175 /// It is often hard to accurately identify when you are hitting RAM limits on Arduino. 00176 /// The symptoms can include: 00177 /// - Mysterious crashes and restarts 00178 /// - Changes in behaviour when seemingly unrelated changes are made (such as adding print() statements) 00179 /// - Hanging 00180 /// - Output from Serial.print() not appearing 00181 /// 00182 /// With an Arduino Mega, with 8 kbytes of SRAM, there is much more RAM headroom for 00183 /// your own elaborate programs. 00184 /// This library is reported to work with Arduino Pro Mini, but that has not been tested by me. 00185 /// 00186 /// The Arduino UNO is now known to work with RF22. 00187 /// 00188 /// \par Automatic Frequency Control (AFC) 00189 /// 00190 /// The RF22M modules use an inexpensive crystal to control the frequency synthesizer, and therfore you can expect 00191 /// the transmitter and receiver frequencies to be subject to the usual inaccuracies of such crystals. The RF22 00192 /// contains an AFC circuit to compensate for differences in transmitter and receiver frequencies. 00193 /// It does this by altering the receiver frequency during reception by up to the pull-in frequency range. 00194 /// This RF22 library enables the AFC and by default sets the pull-in frequency range to 00195 /// 0.05MHz, which should be sufficient to handle most situations. However, if you observe unexplained packet losses 00196 /// or failure to operate correctly all the time it may be because your modules have a wider frequency difference, and 00197 /// you may need to set the afcPullInRange to a differentvalue, using setFrequency(); 00198 /// 00199 /// \par Performance 00200 /// 00201 /// Some simple speed performance tests have been conducted. 00202 /// In general packet transmission rate will be limited by the modulation scheme. 00203 /// Also, if your code does any slow operations like Serial printing it will also limit performance. 00204 /// We disabled any printing in the tests below. 00205 /// We tested with RF22::GFSK_Rb125Fd125, which is probably the fastest scheme available. 00206 /// We tested with a 13 octet message length, over a very short distance of 10cm. 00207 /// 00208 /// Transmission (no reply) tests with modulation RF22::GFSK_Rb125Fd125 and a 00209 /// 13 octet message show about 330 messages per second transmitted. 00210 /// 00211 /// Transmit-and-wait-for-a-reply tests with modulation RF22::GFSK_Rb125Fd125 and a 00212 /// 13 octet message (send and receive) show about 160 round trips per second. 00213 /// 00214 /// \par Installation 00215 /// 00216 /// Install in the usual way: unzip the distribution zip file to the libraries 00217 /// sub-folder of your sketchbook. 00218 /// 00219 /// This software is Copyright (C) 2011 Mike McCauley. Use is subject to license 00220 /// conditions. The main licensing options available are GPL V2 or Commercial: 00221 /// 00222 /// \par Open Source Licensing GPL V2 00223 /// 00224 /// This is the appropriate option if you want to share the source code of your 00225 /// application with everyone you distribute it to, and you also want to give them 00226 /// the right to share who uses it. If you wish to use this software under Open 00227 /// Source Licensing, you must contribute all your source code to the open source 00228 /// community in accordance with the GPL Version 2 when your application is 00229 /// distributed. See http://www.gnu.org/copyleft/gpl.html 00230 /// 00231 /// \par Commercial Licensing 00232 /// 00233 /// This is the appropriate option if you are creating proprietary applications 00234 /// and you are not prepared to distribute and share the source code of your 00235 /// application. Contact info@open.com.au for details. 00236 /// 00237 /// \par Revision History 00238 /// 00239 /// \version 1.0 Initial release 00240 /// 00241 /// \version 1.1 Added rf22_snoop and rf22_specan examples 00242 /// 00243 /// \version 1.2 Changed default modulation to FSK_Rb2_4Fd36 00244 /// Some internal reorganisation. 00245 /// Added RF22Router and RF22Mesh classes plus sample programs to support multi-hop and 00246 /// automatic route discovery. 00247 /// \version 1.3 Removed some unnecessary debug messages. Added virtual doArp and isPhysicalAddress 00248 /// functions to RF22Mesh to support other physical address interpretation schemes (IPV4/IPV6?) 00249 /// \version 1.4 RF22Router and RF22Mesh were inadvertently left out of the distro. 00250 /// \version 1.5 Improvements contributed by Peter Mousley: Modem config table is now in flash rather than SRAM, 00251 /// saving 400 bytes of SRAM. Allow a user-defined buffer size. Thanks Peter. 00252 /// \version 1.6 Fixed some minor typos on doc and clarified that this code is for the RF22B. Fixed errors in the 00253 /// definition of the power output constants which were incorrectly set to the values for the RF22. 00254 /// Reported by Fred Slamen. If you were using a previous version of RF22, you probably were not getting the output 00255 /// power you thought. 00256 /// \version 1.7 Added code to initialise GPIO0 and GPIO1 so they can automatically control the TX_ANT and RX_ANT 00257 /// antenna switching inputs. You must connect GPIO0 to TX_ANT and GPIO1 to RX_ANT for this automatic 00258 /// antenna switching to occur. Updated doc to reflect this new connection requirement 00259 /// \version 1.8 Changed the name of RF22_ENLBD in RF22_REG_06_INTERRUPT_ENABLE2 to RF22_ENLBDI because it collided 00260 /// with a define of the same name in RF22_REG_07_OPERATING_MODE. RF22_REG_05_INTERRUPT_ENABLE1 enable mask 00261 /// incorrectly used RF22_IFFERROR instead of RF22_ENFFERR. Reported by Steffan Woltjer. 00262 /// \version 1.9 Fixed typos in RF22_REG_21_CLOCk*. Reported by Steffan Woltjer. 00263 /// \version 1.10 Fixed a problem where a IFFERR during transmission could cause an infinite loop and a hang. 00264 /// Reported by Raymond Gilbert. 00265 /// \version 1.11 Fixed an innocuous typo in RF22::handleInterrupt. Reported by Zhentao. 00266 /// 00267 /// \version 1.12 Improvements to RF22::init from Guy Molinari to improve compatibility with some 00268 /// Arduinos. Now reported to be working with official Mega 2560 and Uno. 00269 /// Updated so compiles on Arduino 1.0. 00270 /// 00271 /// \version 1.13 Announce google support group 00272 /// 00273 /// \version 1.14 Added definitions for bits and masks in RF22_REG_1D_AFC_LOOP_GEARSHIFT_OVERRIDE 00274 /// and RF22_REG_1E_AFC_TIMING_CONTROL 00275 /// 00276 /// \version 1.15 Small alterations to initialisation code so that SS pin is not set to output: may cause 00277 /// interference with other devices connected to the Arduino. Testing with Uno: OK. 00278 /// 00279 /// \version 1.16 Fixed a problem that prevented building with arduino 0021 00280 /// 00281 /// \version 1.17 Added optional AFC pull-in frequency range argument to setFrequency(). 00282 /// Default AFC pull-in range set to 0.05MHz 00283 /// 00284 /// \version 1.18 Changed default value for slave slect pin in constructor to be SS, ie the normal one for 00285 /// the compiled Arduino (D10 for Diecimila, Uno etc and D53 for Mega). This is because some Arduinos such as Mega 2560 00286 /// reportedly use the type of the SS pin to determine whether to run in slave or master mode. Therfore it 00287 /// is preferred that the slave select pin actually be the normal SS pin. 00288 /// 00289 /// \version 1.19 Added new mode() function. 00290 /// Fixed a potential race condition in RF22Datagram::recvfrom which might cause corrupt from, to, id or flags 00291 /// under extreme circumstances. Improvements to interrupt hygeine by adding cli()_/sei() around all 00292 /// RF22 register acceses. Found that 0 length transmit packets confuses the RF22, so they are now forbidden. 00293 /// Added IPGateway example, which routes UDP messages from an internet connection using an 00294 /// Ethernet Shield and sends them 00295 /// to a radio whose ID is based on the UDP port. Replies are sent back to the originating UDP 00296 /// address and port. 00297 /// 00298 /// \version 1.20 _mode is now volatile. 00299 /// RF22::send() now waits until any previous transmission is complete before sending. 00300 /// RF22::waitPacketSent() now waits for the RF22 to not be in _mode == RF22_MODE_TX 00301 /// _txPacketSent member is now redundant and removed. 00302 /// Improvements to interrupt handling and blocking. Now use ATOMIC_BLOCK(ATOMIC_RESTORESTATE) 00303 /// to prevent reenabling interrupts too soon. Thanks to Roland Mieslinger for this suggestion. 00304 /// Added some performance measurements to documentation. 00305 /// 00306 /// \version 1.21 Fixed a case where a receiver buffer overflow could occur. Reported by Joe Tuttle. 00307 /// 00308 /// \version 1.22 Added documentation after testing with Sparkfun RFM22 Shield DEV-11018. 00309 /// Fixed incorrect link to register calculator excel file, reported by Joey Morin. 00310 /// 00311 /// \version 1.23 Added support for alternative SPI interfaces, with default implementation for the standard 00312 /// Arduino hardware SPI interface. Contributed by Joanna Rutkowska. 00313 /// 00314 /// \version 1.24 Fixed a problem that could cause corrupted receive messages if a transmit interrupted 00315 /// a partial receive (as was common with eg ReliableDatagram with poor reception. 00316 /// Also fixed possible receive buffer overrun. 00317 /// \version 1.25 More rigorous use of const, additional register defines (RF22_CRCHDRS RF22_VARPKLEN) 00318 /// and two methods (setPreambleLength() 00319 /// and setSyncWords())made public. Patch provided by 00320 /// Matthijs Kooijman. 00321 /// \author Mike McCauley (mikem@open.com.au) 00322 00323 #ifndef RF22_h 00324 #define RF22_h 00325 #include "mbed.h" 00326 00327 #define boolean bool 00328 00329 //#include <wiring.h> 00330 // These defs cause trouble on some versions of Arduino 00331 #undef round 00332 #undef double 00333 00334 // This is the bit in the SPI address that marks it as a write 00335 #define RF22_SPI_WRITE_MASK 0x80 00336 00337 // This is the maximum message length that can be supported by this library. Limited by 00338 // the single message length octet in the header. 00339 // Yes, 255 is correct even though the FIFO size in the RF22 is only 00340 // 64 octets. We use interrupts to refill the Tx FIFO during transmission and to empty the 00341 // Rx FIFO during reception 00342 // Can be pre-defined to a smaller size (to save SRAM) prior to including this header 00343 #ifndef RF22_MAX_MESSAGE_LEN 00344 #define RF22_MAX_MESSAGE_LEN 255 00345 //#define RF22_MAX_MESSAGE_LEN 50 00346 #endif 00347 00348 // Max number of octets the RF22 Rx and Tx FIFOs can hold 00349 #define RF22_FIFO_SIZE 64 00350 00351 // Keep track of the mode the RF22 is in 00352 #define RF22_MODE_IDLE 0 00353 #define RF22_MODE_RX 1 00354 #define RF22_MODE_TX 2 00355 00356 // These values we set for FIFO thresholds are actually the same as the POR values 00357 #define RF22_TXFFAEM_THRESHOLD 4 00358 #define RF22_RXFFAFULL_THRESHOLD 55 00359 00360 // This is the default node address, 00361 #define RF22_DEFAULT_NODE_ADDRESS 0 00362 00363 // This address in the TO addreess signifies a broadcast 00364 #define RF22_BROADCAST_ADDRESS 0xff 00365 00366 // Number of registers to be passed to setModemConfig() 00367 #define RF22_NUM_MODEM_CONFIG_REGS 18 00368 00369 // Register names 00370 #define RF22_REG_00_DEVICE_TYPE 0x00 00371 #define RF22_REG_01_VERSION_CODE 0x01 00372 #define RF22_REG_02_DEVICE_STATUS 0x02 00373 #define RF22_REG_03_INTERRUPT_STATUS1 0x03 00374 #define RF22_REG_04_INTERRUPT_STATUS2 0x04 00375 #define RF22_REG_05_INTERRUPT_ENABLE1 0x05 00376 #define RF22_REG_06_INTERRUPT_ENABLE2 0x06 00377 #define RF22_REG_07_OPERATING_MODE1 0x07 00378 #define RF22_REG_08_OPERATING_MODE2 0x08 00379 #define RF22_REG_09_OSCILLATOR_LOAD_CAPACITANCE 0x09 00380 #define RF22_REG_0A_UC_OUTPUT_CLOCK 0x0a 00381 #define RF22_REG_0B_GPIO_CONFIGURATION0 0x0b 00382 #define RF22_REG_0C_GPIO_CONFIGURATION1 0x0c 00383 #define RF22_REG_0D_GPIO_CONFIGURATION2 0x0d 00384 #define RF22_REG_0E_IO_PORT_CONFIGURATION 0x0e 00385 #define RF22_REG_0F_ADC_CONFIGURATION 0x0f 00386 #define RF22_REG_10_ADC_SENSOR_AMP_OFFSET 0x10 00387 #define RF22_REG_11_ADC_VALUE 0x11 00388 #define RF22_REG_12_TEMPERATURE_SENSOR_CALIBRATION 0x12 00389 #define RF22_REG_13_TEMPERATURE_VALUE_OFFSET 0x13 00390 #define RF22_REG_14_WAKEUP_TIMER_PERIOD1 0x14 00391 #define RF22_REG_15_WAKEUP_TIMER_PERIOD2 0x15 00392 #define RF22_REG_16_WAKEUP_TIMER_PERIOD3 0x16 00393 #define RF22_REG_17_WAKEUP_TIMER_VALUE1 0x17 00394 #define RF22_REG_18_WAKEUP_TIMER_VALUE2 0x18 00395 #define RF22_REG_19_LDC_MODE_DURATION 0x19 00396 #define RF22_REG_1A_LOW_BATTERY_DETECTOR_THRESHOLD 0x1a 00397 #define RF22_REG_1B_BATTERY_VOLTAGE_LEVEL 0x1b 00398 #define RF22_REG_1C_IF_FILTER_BANDWIDTH 0x1c 00399 #define RF22_REG_1D_AFC_LOOP_GEARSHIFT_OVERRIDE 0x1d 00400 #define RF22_REG_1E_AFC_TIMING_CONTROL 0x1e 00401 #define RF22_REG_1F_CLOCK_RECOVERY_GEARSHIFT_OVERRIDE 0x1f 00402 #define RF22_REG_20_CLOCK_RECOVERY_OVERSAMPLING_RATE 0x20 00403 #define RF22_REG_21_CLOCK_RECOVERY_OFFSET2 0x21 00404 #define RF22_REG_22_CLOCK_RECOVERY_OFFSET1 0x22 00405 #define RF22_REG_23_CLOCK_RECOVERY_OFFSET0 0x23 00406 #define RF22_REG_24_CLOCK_RECOVERY_TIMING_LOOP_GAIN1 0x24 00407 #define RF22_REG_25_CLOCK_RECOVERY_TIMING_LOOP_GAIN0 0x25 00408 #define RF22_REG_26_RSSI 0x26 00409 #define RF22_REG_27_RSSI_THRESHOLD 0x27 00410 #define RF22_REG_28_ANTENNA_DIVERSITY1 0x28 00411 #define RF22_REG_29_ANTENNA_DIVERSITY2 0x29 00412 #define RF22_REG_2A_AFC_LIMITER 0x2a 00413 #define RF22_REG_2B_AFC_CORRECTION_READ 0x2b 00414 #define RF22_REG_2C_OOK_COUNTER_VALUE_1 0x2c 00415 #define RF22_REG_2D_OOK_COUNTER_VALUE_2 0x2d 00416 #define RF22_REG_2E_SLICER_PEAK_HOLD 0x2e 00417 #define RF22_REG_30_DATA_ACCESS_CONTROL 0x30 00418 #define RF22_REG_31_EZMAC_STATUS 0x31 00419 #define RF22_REG_32_HEADER_CONTROL1 0x32 00420 #define RF22_REG_33_HEADER_CONTROL2 0x33 00421 #define RF22_REG_34_PREAMBLE_LENGTH 0x34 00422 #define RF22_REG_35_PREAMBLE_DETECTION_CONTROL1 0x35 00423 #define RF22_REG_36_SYNC_WORD3 0x36 00424 #define RF22_REG_37_SYNC_WORD2 0x37 00425 #define RF22_REG_38_SYNC_WORD1 0x38 00426 #define RF22_REG_39_SYNC_WORD0 0x39 00427 #define RF22_REG_3A_TRANSMIT_HEADER3 0x3a 00428 #define RF22_REG_3B_TRANSMIT_HEADER2 0x3b 00429 #define RF22_REG_3C_TRANSMIT_HEADER1 0x3c 00430 #define RF22_REG_3D_TRANSMIT_HEADER0 0x3d 00431 #define RF22_REG_3E_PACKET_LENGTH 0x3e 00432 #define RF22_REG_3F_CHECK_HEADER3 0x3f 00433 #define RF22_REG_40_CHECK_HEADER2 0x40 00434 #define RF22_REG_41_CHECK_HEADER1 0x41 00435 #define RF22_REG_42_CHECK_HEADER0 0x42 00436 #define RF22_REG_43_HEADER_ENABLE3 0x43 00437 #define RF22_REG_44_HEADER_ENABLE2 0x44 00438 #define RF22_REG_45_HEADER_ENABLE1 0x45 00439 #define RF22_REG_46_HEADER_ENABLE0 0x46 00440 #define RF22_REG_47_RECEIVED_HEADER3 0x47 00441 #define RF22_REG_48_RECEIVED_HEADER2 0x48 00442 #define RF22_REG_49_RECEIVED_HEADER1 0x49 00443 #define RF22_REG_4A_RECEIVED_HEADER0 0x4a 00444 #define RF22_REG_4B_RECEIVED_PACKET_LENGTH 0x4b 00445 #define RF22_REG_50_ANALOG_TEST_BUS_SELECT 0x50 00446 #define RF22_REG_51_DIGITAL_TEST_BUS_SELECT 0x51 00447 #define RF22_REG_52_TX_RAMP_CONTROL 0x52 00448 #define RF22_REG_53_PLL_TUNE_TIME 0x53 00449 #define RF22_REG_55_CALIBRATION_CONTROL 0x55 00450 #define RF22_REG_56_MODEM_TEST 0x56 00451 #define RF22_REG_57_CHARGE_PUMP_TEST 0x57 00452 #define RF22_REG_58_CHARGE_PUMP_CURRENT_TRIMMING 0x58 00453 #define RF22_REG_59_DIVIDER_CURRENT_TRIMMING 0x59 00454 #define RF22_REG_5A_VCO_CURRENT_TRIMMING 0x5a 00455 #define RF22_REG_5B_VCO_CALIBRATION 0x5b 00456 #define RF22_REG_5C_SYNTHESIZER_TEST 0x5c 00457 #define RF22_REG_5D_BLOCK_ENABLE_OVERRIDE1 0x5d 00458 #define RF22_REG_5E_BLOCK_ENABLE_OVERRIDE2 0x5e 00459 #define RF22_REG_5F_BLOCK_ENABLE_OVERRIDE3 0x5f 00460 #define RF22_REG_60_CHANNEL_FILTER_COEFFICIENT_ADDRESS 0x60 00461 #define RF22_REG_61_CHANNEL_FILTER_COEFFICIENT_VALUE 0x61 00462 #define RF22_REG_62_CRYSTAL_OSCILLATOR_POR_CONTROL 0x62 00463 #define RF22_REG_63_RC_OSCILLATOR_COARSE_CALIBRATION 0x63 00464 #define RF22_REG_64_RC_OSCILLATOR_FINE_CALIBRATION 0x64 00465 #define RF22_REG_65_LDO_CONTROL_OVERRIDE 0x65 00466 #define RF22_REG_66_LDO_LEVEL_SETTINGS 0x66 00467 #define RF22_REG_67_DELTA_SIGMA_ADC_TUNING1 0x67 00468 #define RF22_REG_68_DELTA_SIGMA_ADC_TUNING2 0x68 00469 #define RF22_REG_69_AGC_OVERRIDE1 0x69 00470 #define RF22_REG_6A_AGC_OVERRIDE2 0x6a 00471 #define RF22_REG_6B_GFSK_FIR_FILTER_COEFFICIENT_ADDRESS 0x6b 00472 #define RF22_REG_6C_GFSK_FIR_FILTER_COEFFICIENT_VALUE 0x6c 00473 #define RF22_REG_6D_TX_POWER 0x6d 00474 #define RF22_REG_6E_TX_DATA_RATE1 0x6e 00475 #define RF22_REG_6F_TX_DATA_RATE0 0x6f 00476 #define RF22_REG_70_MODULATION_CONTROL1 0x70 00477 #define RF22_REG_71_MODULATION_CONTROL2 0x71 00478 #define RF22_REG_72_FREQUENCY_DEVIATION 0x72 00479 #define RF22_REG_73_FREQUENCY_OFFSET1 0x73 00480 #define RF22_REG_74_FREQUENCY_OFFSET2 0x74 00481 #define RF22_REG_75_FREQUENCY_BAND_SELECT 0x75 00482 #define RF22_REG_76_NOMINAL_CARRIER_FREQUENCY1 0x76 00483 #define RF22_REG_77_NOMINAL_CARRIER_FREQUENCY0 0x77 00484 #define RF22_REG_79_FREQUENCY_HOPPING_CHANNEL_SELECT 0x79 00485 #define RF22_REG_7A_FREQUENCY_HOPPING_STEP_SIZE 0x7a 00486 #define RF22_REG_7C_TX_FIFO_CONTROL1 0x7c 00487 #define RF22_REG_7D_TX_FIFO_CONTROL2 0x7d 00488 #define RF22_REG_7E_RX_FIFO_CONTROL 0x7e 00489 #define RF22_REG_7F_FIFO_ACCESS 0x7f 00490 00491 // These register masks etc are named wherever possible 00492 // corresponding to the bit and field names in the RF-22 Manual 00493 // RF22_REG_00_DEVICE_TYPE 0x00 00494 #define RF22_DEVICE_TYPE_RX_TRX 0x08 00495 #define RF22_DEVICE_TYPE_TX 0x07 00496 00497 // RF22_REG_02_DEVICE_STATUS 0x02 00498 #define RF22_FFOVL 0x80 00499 #define RF22_FFUNFL 0x40 00500 #define RF22_RXFFEM 0x20 00501 #define RF22_HEADERR 0x10 00502 #define RF22_FREQERR 0x08 00503 #define RF22_LOCKDET 0x04 00504 #define RF22_CPS 0x03 00505 #define RF22_CPS_IDLE 0x00 00506 #define RF22_CPS_RX 0x01 00507 #define RF22_CPS_TX 0x10 00508 00509 // RF22_REG_03_INTERRUPT_STATUS1 0x03 00510 #define RF22_IFFERROR 0x80 00511 #define RF22_ITXFFAFULL 0x40 00512 #define RF22_ITXFFAEM 0x20 00513 #define RF22_IRXFFAFULL 0x10 00514 #define RF22_IEXT 0x08 00515 #define RF22_IPKSENT 0x04 00516 #define RF22_IPKVALID 0x02 00517 #define RF22_ICRCERROR 0x01 00518 00519 // RF22_REG_04_INTERRUPT_STATUS2 0x04 00520 #define RF22_ISWDET 0x80 00521 #define RF22_IPREAVAL 0x40 00522 #define RF22_IPREAINVAL 0x20 00523 #define RF22_IRSSI 0x10 00524 #define RF22_IWUT 0x08 00525 #define RF22_ILBD 0x04 00526 #define RF22_ICHIPRDY 0x02 00527 #define RF22_IPOR 0x01 00528 00529 // RF22_REG_05_INTERRUPT_ENABLE1 0x05 00530 #define RF22_ENFFERR 0x80 00531 #define RF22_ENTXFFAFULL 0x40 00532 #define RF22_ENTXFFAEM 0x20 00533 #define RF22_ENRXFFAFULL 0x10 00534 #define RF22_ENEXT 0x08 00535 #define RF22_ENPKSENT 0x04 00536 #define RF22_ENPKVALID 0x02 00537 #define RF22_ENCRCERROR 0x01 00538 00539 // RF22_REG_06_INTERRUPT_ENABLE2 0x06 00540 #define RF22_ENSWDET 0x80 00541 #define RF22_ENPREAVAL 0x40 00542 #define RF22_ENPREAINVAL 0x20 00543 #define RF22_ENRSSI 0x10 00544 #define RF22_ENWUT 0x08 00545 #define RF22_ENLBDI 0x04 00546 #define RF22_ENCHIPRDY 0x02 00547 #define RF22_ENPOR 0x01 00548 00549 // RF22_REG_07_OPERATING_MODE 0x07 00550 #define RF22_SWRES 0x80 00551 #define RF22_ENLBD 0x40 00552 #define RF22_ENWT 0x20 00553 #define RF22_X32KSEL 0x10 00554 #define RF22_TXON 0x08 00555 #define RF22_RXON 0x04 00556 #define RF22_PLLON 0x02 00557 #define RF22_XTON 0x01 00558 00559 // RF22_REG_08_OPERATING_MODE2 0x08 00560 #define RF22_ANTDIV 0xc0 00561 #define RF22_RXMPK 0x10 00562 #define RF22_AUTOTX 0x08 00563 #define RF22_ENLDM 0x04 00564 #define RF22_FFCLRRX 0x02 00565 #define RF22_FFCLRTX 0x01 00566 00567 // RF22_REG_0F_ADC_CONFIGURATION 0x0f 00568 #define RF22_ADCSTART 0x80 00569 #define RF22_ADCDONE 0x80 00570 #define RF22_ADCSEL 0x70 00571 #define RF22_ADCSEL_INTERNAL_TEMPERATURE_SENSOR 0x00 00572 #define RF22_ADCSEL_GPIO0_SINGLE_ENDED 0x10 00573 #define RF22_ADCSEL_GPIO1_SINGLE_ENDED 0x20 00574 #define RF22_ADCSEL_GPIO2_SINGLE_ENDED 0x30 00575 #define RF22_ADCSEL_GPIO0_GPIO1_DIFFERENTIAL 0x40 00576 #define RF22_ADCSEL_GPIO1_GPIO2_DIFFERENTIAL 0x50 00577 #define RF22_ADCSEL_GPIO0_GPIO2_DIFFERENTIAL 0x60 00578 #define RF22_ADCSEL_GND 0x70 00579 #define RF22_ADCREF 0x0c 00580 #define RF22_ADCREF_BANDGAP_VOLTAGE 0x00 00581 #define RF22_ADCREF_VDD_ON_3 0x08 00582 #define RF22_ADCREF_VDD_ON_2 0x0c 00583 #define RF22_ADCGAIN 0x03 00584 00585 // RF22_REG_10_ADC_SENSOR_AMP_OFFSET 0x10 00586 #define RF22_ADCOFFS 0x0f 00587 00588 // RF22_REG_12_TEMPERATURE_SENSOR_CALIBRATION 0x12 00589 #define RF22_TSRANGE 0xc0 00590 #define RF22_TSRANGE_M64_64C 0x00 00591 #define RF22_TSRANGE_M64_192C 0x40 00592 #define RF22_TSRANGE_0_128C 0x80 00593 #define RF22_TSRANGE_M40_216F 0xc0 00594 #define RF22_ENTSOFFS 0x20 00595 #define RF22_ENTSTRIM 0x10 00596 #define RF22_TSTRIM 0x0f 00597 00598 // RF22_REG_14_WAKEUP_TIMER_PERIOD1 0x14 00599 #define RF22_WTR 0x3c 00600 #define RF22_WTD 0x03 00601 00602 // RF22_REG_1D_AFC_LOOP_GEARSHIFT_OVERRIDE 0x1d 00603 #define RF22_AFBCD 0x80 00604 #define RF22_ENAFC 0x40 00605 #define RF22_AFCGEARH 0x38 00606 #define RF22_AFCGEARL 0x07 00607 00608 // RF22_REG_1E_AFC_TIMING_CONTROL 0x1e 00609 #define RF22_SWAIT_TIMER 0xc0 00610 #define RF22_SHWAIT 0x38 00611 #define RF22_ANWAIT 0x07 00612 00613 // RF22_REG_30_DATA_ACCESS_CONTROL 0x30 00614 #define RF22_ENPACRX 0x80 00615 #define RF22_MSBFRST 0x00 00616 #define RF22_LSBFRST 0x40 00617 #define RF22_CRCHDRS 0x00 00618 #define RF22_CRCDONLY 0x20 00619 #define RF22_ENPACTX 0x08 00620 #define RF22_ENCRC 0x04 00621 #define RF22_CRC 0x03 00622 #define RF22_CRC_CCITT 0x00 00623 #define RF22_CRC_CRC_16_IBM 0x01 00624 #define RF22_CRC_IEC_16 0x02 00625 #define RF22_CRC_BIACHEVA 0x03 00626 00627 // RF22_REG_32_HEADER_CONTROL1 0x32 00628 #define RF22_BCEN 0xf0 00629 #define RF22_BCEN_NONE 0x00 00630 #define RF22_BCEN_HEADER0 0x10 00631 #define RF22_BCEN_HEADER1 0x20 00632 #define RF22_BCEN_HEADER2 0x40 00633 #define RF22_BCEN_HEADER3 0x80 00634 #define RF22_HDCH 0x0f 00635 #define RF22_HDCH_NONE 0x00 00636 #define RF22_HDCH_HEADER0 0x01 00637 #define RF22_HDCH_HEADER1 0x02 00638 #define RF22_HDCH_HEADER2 0x04 00639 #define RF22_HDCH_HEADER3 0x08 00640 00641 // RF22_REG_33_HEADER_CONTROL2 0x33 00642 #define RF22_HDLEN 0x70 00643 #define RF22_HDLEN_0 0x00 00644 #define RF22_HDLEN_1 0x10 00645 #define RF22_HDLEN_2 0x20 00646 #define RF22_HDLEN_3 0x30 00647 #define RF22_HDLEN_4 0x40 00648 #define RF22_VARPKLEN 0x00 00649 #define RF22_FIXPKLEN 0x08 00650 #define RF22_SYNCLEN 0x06 00651 #define RF22_SYNCLEN_1 0x00 00652 #define RF22_SYNCLEN_2 0x02 00653 #define RF22_SYNCLEN_3 0x04 00654 #define RF22_SYNCLEN_4 0x06 00655 #define RF22_PREALEN8 0x01 00656 00657 // RF22_REG_6D_TX_POWER 0x6d 00658 #define RF22_TXPOW 0x07 00659 #define RF22_TXPOW_4X31 0x08 // Not used in RFM22B 00660 #define RF22_TXPOW_1DBM 0x00 00661 #define RF22_TXPOW_2DBM 0x01 00662 #define RF22_TXPOW_5DBM 0x02 00663 #define RF22_TXPOW_8DBM 0x03 00664 #define RF22_TXPOW_11DBM 0x04 00665 #define RF22_TXPOW_14DBM 0x05 00666 #define RF22_TXPOW_17DBM 0x06 00667 #define RF22_TXPOW_20DBM 0x07 00668 // IN RFM23B 00669 #define RF22_TXPOW_LNA_SW 0x08 00670 00671 // RF22_REG_71_MODULATION_CONTROL2 0x71 00672 #define RF22_TRCLK 0xc0 00673 #define RF22_TRCLK_NONE 0x00 00674 #define RF22_TRCLK_GPIO 0x40 00675 #define RF22_TRCLK_SDO 0x80 00676 #define RF22_TRCLK_NIRQ 0xc0 00677 #define RF22_DTMOD 0x30 00678 #define RF22_DTMOD_DIRECT_GPIO 0x00 00679 #define RF22_DTMOD_DIRECT_SDI 0x10 00680 #define RF22_DTMOD_FIFO 0x20 00681 #define RF22_DTMOD_PN9 0x30 00682 #define RF22_ENINV 0x08 00683 #define RF22_FD8 0x04 00684 #define RF22_MODTYP 0x30 00685 #define RF22_MODTYP_UNMODULATED 0x00 00686 #define RF22_MODTYP_OOK 0x01 00687 #define RF22_MODTYP_FSK 0x02 00688 #define RF22_MODTYP_GFSK 0x03 00689 00690 // RF22_REG_75_FREQUENCY_BAND_SELECT 0x75 00691 #define RF22_SBSEL 0x40 00692 #define RF22_HBSEL 0x20 00693 #define RF22_FB 0x1f 00694 00695 // Define this to include Serial printing in diagnostic routines 00696 //#define RF22_HAVE_SERIAL 00697 00698 //#include <GenericSPI.h> 00699 //#include <HardwareSPI.h> 00700 ///////////////////////////////////////////////////////////////////// 00701 /// \class RF22 RF22.h <RF22.h> 00702 /// \brief Send and receive unaddressed, unreliable datagrams. 00703 /// 00704 /// This base class provides basic functions for sending and receiving unaddressed, 00705 /// unreliable datagrams of arbitrary length to 255 octets per packet. 00706 /// 00707 /// Subclasses may use this class to implement reliable, addressed datagrams and streams, 00708 /// mesh routers, repeaters, translators etc. 00709 /// 00710 /// On transmission, the TO and FROM addresses default to 0x00, unless changed by a subclass. 00711 /// On reception the TO addressed is checked against the node address (defaults to 0x00) or the 00712 /// broadcast address (which is 0xff). The ID and FLAGS are set to 0, and not checked by this class. 00713 /// This permits use of the this base RF22 class as an 00714 /// unaddresed, unreliable datagram service. Subclasses are expected to change this behaviour to 00715 /// add node address, ids, retransmission etc 00716 /// 00717 /// Naturally, for any 2 radios to communicate that must be configured to use the same frequence and 00718 /// modulation scheme. 00719 class RF22 00720 { 00721 public: 00722 00723 /// \brief Defines register values for a set of modem configuration registers 00724 /// 00725 /// Defines register values for a set of modem configuration registers 00726 /// that can be passed to setModemConfig() 00727 /// if none of the choices in ModemConfigChoice suit your need 00728 /// setModemConfig() writes the register values to the appropriate RF22 registers 00729 /// to set the desired modulation type, data rate and deviation/bandwidth. 00730 /// Suitable values for these registers can be computed using the register calculator at 00731 /// http://www.hoperf.com/upload/rf/RF22B%2023B%2031B%2042B%2043B%20Register%20Settings_RevB1-v5.xls 00732 typedef struct 00733 { 00734 uint8_t reg_1c; ///< Value for register RF22_REG_1C_IF_FILTER_BANDWIDTH 00735 uint8_t reg_1f; ///< Value for register RF22_REG_1F_CLOCK_RECOVERY_GEARSHIFT_OVERRIDE 00736 uint8_t reg_20; ///< Value for register RF22_REG_20_CLOCK_RECOVERY_OVERSAMPLING_RATE 00737 uint8_t reg_21; ///< Value for register RF22_REG_21_CLOCK_RECOVERY_OFFSET2 00738 uint8_t reg_22; ///< Value for register RF22_REG_22_CLOCK_RECOVERY_OFFSET1 00739 uint8_t reg_23; ///< Value for register RF22_REG_23_CLOCK_RECOVERY_OFFSET0 00740 uint8_t reg_24; ///< Value for register RF22_REG_24_CLOCK_RECOVERY_TIMING_LOOP_GAIN1 00741 uint8_t reg_25; ///< Value for register RF22_REG_25_CLOCK_RECOVERY_TIMING_LOOP_GAIN0 00742 uint8_t reg_2c; ///< Value for register RF22_REG_2C_OOK_COUNTER_VALUE_1 00743 uint8_t reg_2d; ///< Value for register RF22_REG_2D_OOK_COUNTER_VALUE_2 00744 uint8_t reg_2e; ///< Value for register RF22_REG_2E_SLICER_PEAK_HOLD 00745 uint8_t reg_58; ///< Value for register RF22_REG_58_CHARGE_PUMP_CURRENT_TRIMMING 00746 uint8_t reg_69; ///< Value for register RF22_REG_69_AGC_OVERRIDE1 00747 uint8_t reg_6e; ///< Value for register RF22_REG_6E_TX_DATA_RATE1 00748 uint8_t reg_6f; ///< Value for register RF22_REG_6F_TX_DATA_RATE0 00749 uint8_t reg_70; ///< Value for register RF22_REG_70_MODULATION_CONTROL1 00750 uint8_t reg_71; ///< Value for register RF22_REG_71_MODULATION_CONTROL2 00751 uint8_t reg_72; ///< Value for register RF22_REG_72_FREQUENCY_DEVIATION 00752 } ModemConfig; 00753 00754 /// Choices for setModemConfig() for a selected subset of common modulation types, 00755 /// and data rates. If you need another configuration, use the register calculator. 00756 /// and call setModemRegisters() with your desired settings 00757 /// These are indexes into _modemConfig 00758 typedef enum 00759 { 00760 UnmodulatedCarrier = 0, ///< Unmodulated carrier for testing 00761 FSK_PN9_Rb2Fd5, ///< FSK, No Manchester, Rb = 2kbs, Fd = 5kHz, PN9 random modulation for testing 00762 00763 FSK_Rb2Fd5, ///< FSK, No Manchester, Rb = 2kbs, Fd = 5kHz 00764 FSK_Rb2_4Fd36, ///< FSK, No Manchester, Rb = 2.4kbs, Fd = 36kHz 00765 FSK_Rb4_8Fd45, ///< FSK, No Manchester, Rb = 4.8kbs, Fd = 45kHz 00766 FSK_Rb9_6Fd45, ///< FSK, No Manchester, Rb = 9.6kbs, Fd = 45kHz 00767 FSK_Rb19_2Fd9_6, ///< FSK, No Manchester, Rb = 19.2kbs, Fd = 9.6kHz 00768 FSK_Rb38_4Fd19_6, ///< FSK, No Manchester, Rb = 38.4kbs, Fd = 19.6kHz 00769 FSK_Rb57_6Fd28_8, ///< FSK, No Manchester, Rb = 57.6kbs, Fd = 28.8kHz 00770 FSK_Rb125Fd125, ///< FSK, No Manchester, Rb = 125kbs, Fd = 125kHz 00771 00772 GFSK_Rb2Fd5, ///< GFSK, No Manchester, Rb = 2kbs, Fd = 5kHz 00773 GFSK_Rb2_4Fd36, ///< GFSK, No Manchester, Rb = 2.4kbs, Fd = 36kHz 00774 GFSK_Rb4_8Fd45, ///< GFSK, No Manchester, Rb = 4.8kbs, Fd = 45kHz 00775 GFSK_Rb9_6Fd45, ///< GFSK, No Manchester, Rb = 9.6kbs, Fd = 45kHz 00776 GFSK_Rb19_2Fd9_6, ///< GFSK, No Manchester, Rb = 19.2kbs, Fd = 9.6kHz 00777 GFSK_Rb38_4Fd19_6, ///< GFSK, No Manchester, Rb = 38.4kbs, Fd = 19.6kHz 00778 GFSK_Rb57_6Fd28_8, ///< GFSK, No Manchester, Rb = 57.6kbs, Fd = 28.8kHz 00779 GFSK_Rb125Fd125, ///< GFSK, No Manchester, Rb = 125kbs, Fd = 125kHz 00780 00781 OOK_Rb1_2Bw75, ///< OOK, No Manchester, Rb = 1.2kbs, Rx Bandwidth = 75kHz 00782 OOK_Rb2_4Bw335, ///< OOK, No Manchester, Rb = 2.4kbs, Rx Bandwidth = 335kHz 00783 OOK_Rb4_8Bw335, ///< OOK, No Manchester, Rb = 4.8kbs, Rx Bandwidth = 335kHz 00784 OOK_Rb9_6Bw335, ///< OOK, No Manchester, Rb = 9.6kbs, Rx Bandwidth = 335kHz 00785 OOK_Rb19_2Bw335, ///< OOK, No Manchester, Rb = 19.2kbs, Rx Bandwidth = 335kHz 00786 OOK_Rb38_4Bw335, ///< OOK, No Manchester, Rb = 38.4kbs, Rx Bandwidth = 335kHz 00787 OOK_Rb40Bw335 ///< OOK, No Manchester, Rb = 40kbs, Rx Bandwidth = 335kHz 00788 } ModemConfigChoice; 00789 00790 /// Constructor. You can have multiple instances, but each instance must have its own 00791 /// interrupt and slave select pin. After constructing, you must call init() to initialise the intnerface 00792 /// and the radio module 00793 /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RF22 before 00794 /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega) 00795 /// \param[in] interrupt The interrupt number to use. Default is interrupt 0 (Arduino input pin 2) 00796 RF22(PinName slaveSelectPin , PinName mosi, PinName miso, PinName sclk, PinName interrupt ); 00797 00798 /// Initialises this instance and the radio module connected to it. 00799 /// The following steps are taken: 00800 /// - Initialise the slave select pin and the SPI interface library 00801 /// - Software reset the RF22 module 00802 /// - Checks the connected RF22 module is either a RF22_DEVICE_TYPE_RX_TRX or a RF22_DEVICE_TYPE_TX 00803 /// - Attaches an interrupt handler 00804 /// - Configures the RF22 module 00805 /// - Sets the frequncy to 434.0 MHz 00806 /// - Sets the modem data rate to FSK_Rb2_4Fd36 00807 /// \return true if everything was successful 00808 boolean init(); 00809 00810 /// Issues a software reset to the 00811 /// RF22 module. Blocks for 1ms to ensure the reset is complete. 00812 void reset(); 00813 00814 /// Reads a single register from the RF22 00815 /// \param[in] reg Register number, one of RF22_REG_* 00816 /// \return The value of the register 00817 uint8_t spiRead(uint8_t reg); 00818 00819 /// Writes a single byte to the RF22 00820 /// \param[in] reg Register number, one of RF22_REG_* 00821 /// \param[in] val The value to write 00822 void spiWrite(uint8_t reg, uint8_t val); 00823 00824 /// Reads a number of consecutive registers from the RF22 using burst read mode 00825 /// \param[in] reg Register number of the first register, one of RF22_REG_* 00826 /// \param[in] dest Array to write the register values to. Must be at least len bytes 00827 /// \param[in] len Number of bytes to read 00828 void spiBurstRead(uint8_t reg, uint8_t* dest, uint8_t len); 00829 00830 /// Write a number of consecutive registers using burst write mode 00831 /// \param[in] reg Register number of the first register, one of RF22_REG_* 00832 /// \param[in] src Array of new register values to write. Must be at least len bytes 00833 /// \param[in] len Number of bytes to write 00834 void spiBurstWrite(uint8_t reg, const uint8_t* src, uint8_t len); 00835 00836 /// Reads and returns the device status register RF22_REG_02_DEVICE_STATUS 00837 /// \return The value of the device status register 00838 uint8_t statusRead(); 00839 00840 /// Reads a value from the on-chip analog-digital converter 00841 /// \param[in] adcsel Selects the ADC input to measure. One of RF22_ADCSEL_*. Defaults to the 00842 /// internal temperature sensor 00843 /// \param[in] adcref Specifies the refernce voltage to use. One of RF22_ADCREF_*. 00844 /// Defaults to the internal bandgap voltage. 00845 /// \param[in] adcgain Amplifier gain selection. 00846 /// \param[in] adcoffs Amplifier offseet (0 to 15). 00847 /// \return The analog value. 0 to 255. 00848 uint8_t adcRead(uint8_t adcsel = RF22_ADCSEL_INTERNAL_TEMPERATURE_SENSOR, 00849 uint8_t adcref = RF22_ADCREF_BANDGAP_VOLTAGE, 00850 uint8_t adcgain = 0, 00851 uint8_t adcoffs = 0); 00852 00853 /// Reads the on-chip temperature sensoer 00854 /// \param[in] tsrange Specifies the temperature range to use. One of RF22_TSRANGE_* 00855 /// \param[in] tvoffs Specifies the temperature value offset. This is actually signed value 00856 /// added to the measured temperature value 00857 /// \return The measured temperature. 00858 uint8_t temperatureRead(uint8_t tsrange = RF22_TSRANGE_M64_64C, uint8_t tvoffs = 0); 00859 00860 /// Reads the wakeup timer value in registers RF22_REG_17_WAKEUP_TIMER_VALUE1 00861 /// and RF22_REG_18_WAKEUP_TIMER_VALUE2 00862 /// \return The wakeup timer value 00863 uint16_t wutRead(); 00864 00865 /// Sets the wakeup timer period registers RF22_REG_14_WAKEUP_TIMER_PERIOD1, 00866 /// RF22_REG_15_WAKEUP_TIMER_PERIOD2 and RF22_R<EG_16_WAKEUP_TIMER_PERIOD3 00867 /// \param[in] wtm Wakeup timer mantissa value 00868 /// \param[in] wtr Wakeup timer exponent R value 00869 /// \param[in] wtd Wakeup timer exponent D value 00870 void setWutPeriod(uint16_t wtm, uint8_t wtr = 0, uint8_t wtd = 0); 00871 00872 /// Sets the transmitter and receiver centre frequency 00873 /// \param[in] centre Frequency in MHz. 240.0 to 960.0. Caution, some versions of RF22 and derivatives 00874 /// implemented more restricted frequency ranges. 00875 /// \param[in] afcPullInRange Sets the AF Pull In Range in MHz. Defaults to 0.05MHz (50kHz). Range is 0.0 to 0.159375 00876 /// for frequencies 240.0 to 480MHz, and 0.0 to 0.318750MHz for frequencies 480.0 to 960MHz, 00877 /// \return true if the selected frquency centre + (fhch * fhs) is within range and the afcPullInRange is within range 00878 boolean setFrequency(float centre, float afcPullInRange = 0.05); 00879 00880 /// Sets the frequency hopping step size. 00881 /// \param[in] fhs Frequency Hopping step size in 10kHz increments 00882 /// \return true if centre + (fhch * fhs) is within limits 00883 boolean setFHStepSize(uint8_t fhs); 00884 00885 /// Sets the frequncy hopping channel. Adds fhch * fhs to centre frequency 00886 /// \param[in] fhch The channel number 00887 /// \return true if the selected frquency centre + (fhch * fhs) is within range 00888 boolean setFHChannel(uint8_t fhch); 00889 00890 /// Reads and returns the current RSSI value from register RF22_REG_26_RSSI. If you want to find the RSSI 00891 /// of the last received message, use lastRssi() instead. 00892 /// \return The current RSSI value 00893 uint8_t rssiRead(); 00894 00895 /// Reads and returns the current EZMAC value from register RF22_REG_31_EZMAC_STATUS 00896 /// \return The current EZMAC value 00897 uint8_t ezmacStatusRead(); 00898 00899 /// Sets the parameters for the RF22 Idle mode in register RF22_REG_07_OPERATING_MODE. 00900 /// Idle mode is the mode the RF22 will be in when not transmitting or receiving. The default idle mode 00901 /// is RF22_XTON ie READY mode. 00902 /// \param[in] mode Mask of mode bits, using RF22_SWRES, RF22_ENLBD, RF22_ENWT, 00903 /// RF22_X32KSEL, RF22_PLLON, RF22_XTON. 00904 void setMode(uint8_t mode); 00905 00906 /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running, 00907 /// disables them. 00908 void setModeIdle(); 00909 00910 /// If current mode is Tx or Idle, changes it to Rx. 00911 /// Starts the receiver in the RF22. 00912 void setModeRx(); 00913 00914 /// If current mode is Rx or Idle, changes it to Rx. 00915 /// Starts the transmitter in the RF22. 00916 void setModeTx(); 00917 00918 /// Returns the operating mode of the library. 00919 /// \return the current mode, one of RF22_MODE_* 00920 uint8_t mode(); 00921 00922 /// Sets the transmitter power output level in register RF22_REG_6D_TX_POWER. 00923 /// Be a good neighbour and set the lowest power level you need. 00924 /// After init(), the power wil be set to RF22_TXPOW_8DBM. 00925 /// Caution: In some countries you may only select RF22_TXPOW_17DBM if you 00926 /// are also using frequency hopping. 00927 /// \param[in] power Transmitter power level, one of RF22_TXPOW_* 00928 void setTxPower(uint8_t power); 00929 00930 /// Sets all the registered required to configure the data modem in the RF22, including the data rate, 00931 /// bandwidths etc. You cas use this to configure the modem with custom configuraitons if none of the 00932 /// canned configurations in ModemConfigChoice suit you. 00933 /// \param[in] config A ModemConfig structure containing values for the modem configuration registers. 00934 void setModemRegisters(const ModemConfig* config); 00935 00936 /// Select one of the predefined modem configurations. If you need a modem configuration not provided 00937 /// here, use setModemRegisters() with your own ModemConfig. 00938 /// \param[in] index The configuration choice. 00939 /// \return true if index is a valid choice. 00940 boolean setModemConfig(ModemConfigChoice index); 00941 00942 /// Starts the receiver and checks whether a received message is available. 00943 /// This can be called multiple times in a timeout loop 00944 /// \return true if a complete, valid message has been received and is able to be retrieved by 00945 /// recv() 00946 boolean available(); 00947 00948 /// Starts the receiver and blocks until a valid received 00949 /// message is available. 00950 void waitAvailable(); 00951 00952 /// Starts the receiver and blocks until a received message is available or a timeout 00953 /// \param[in] timeout Maximum time to wait in milliseconds. 00954 /// \return true if a message is available 00955 bool waitAvailableTimeout(uint16_t timeout); 00956 00957 /// Turns the receiver on if it not already on. 00958 /// If there is a valid message available, copy it to buf and return true 00959 /// else return false. 00960 /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted). 00961 /// You should be sure to call this function frequently enough to not miss any messages 00962 /// It is recommended that you call it in your main loop. 00963 /// \param[in] buf Location to copy the received message 00964 /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied. 00965 /// \return true if a valid message was copied to buf 00966 boolean recv(uint8_t* buf, uint8_t* len); 00967 00968 /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent(). 00969 /// Then loads a message into the transmitter and starts the transmitter. Note that a message length 00970 /// of 0 is NOT permitted. 00971 /// \param[in] data Array of data to be sent 00972 /// \param[in] len Number of bytes of data to send (> 0) 00973 /// \return true if the message length was valid and it was correctly queued for transmit 00974 boolean send(const uint8_t* data, uint8_t len); 00975 00976 /// Blocks until the RF22 is not in mode RF22_MODE_TX (ie until the RF22 is not transmitting). 00977 /// This effectively waits until any previous transmit packet is finished being transmitted. 00978 void waitPacketSent(); 00979 00980 /// Tells the receiver to accept messages with any TO address, not just messages 00981 /// addressed to this node or the broadcast address 00982 /// \param[in] promiscuous true if you wish to receive messages with any TO address 00983 void setPromiscuous(boolean promiscuous); 00984 00985 /// Returns the TO header of the last received message 00986 /// \return The TO header 00987 uint8_t headerTo(); 00988 00989 /// Returns the FROM header of the last received message 00990 /// \return The FROM header 00991 uint8_t headerFrom(); 00992 00993 /// Returns the ID header of the last received message 00994 /// \return The ID header 00995 uint8_t headerId(); 00996 00997 /// Returns the FLAGS header of the last received message 00998 /// \return The FLAGS header 00999 uint8_t headerFlags(); 01000 01001 /// Returns the RSSI (Receiver Signal Strength Indicator) 01002 /// of the last received message. This measurement is taken when 01003 /// the preamble has been received. It is a (non-linear) measure of the received signal strength. 01004 /// \return The RSSI 01005 uint8_t lastRssi(); 01006 01007 /// Prints a data buffer in HEX. 01008 /// For diagnostic use 01009 /// \param[in] prompt string to preface the print 01010 /// \param[in] buf Location of the buffer to print 01011 /// \param[in] len Length of the buffer in octets. 01012 static void printBuffer(const char* prompt, const uint8_t* buf, uint8_t len); 01013 01014 /// Sets the length of the preamble 01015 /// in 4-bit nibbles. 01016 /// Caution: this should be set to the same 01017 /// value on all nodes in your network. Default is 8. 01018 /// Sets the message preamble length in RF22_REG_34_PREAMBLE_LENGTH 01019 /// \param[in] nibbles Preamble length in nibbles of 4 bits each. 01020 void setPreambleLength(uint8_t nibbles); 01021 01022 /// Sets the sync words for transmit and receive in registers RF22_REG_36_SYNC_WORD3 01023 /// to RF22_REG_39_SYNC_WORD0 01024 /// Caution: this should be set to the same 01025 /// value on all nodes in your network. Default is { 0x2d, 0xd4 } 01026 /// \param[in] syncWords Array of sync words 01027 /// \param[in] len Number of sync words to set 01028 void setSyncWords(const uint8_t* syncWords, uint8_t len); 01029 01030 protected: 01031 /// This is a low level function to handle the interrupts for one instance of RF22. 01032 /// Called automatically by isr0() and isr1() 01033 /// Should not need to be called. 01034 void handleInterrupt(); 01035 01036 /// Clears the receiver buffer. 01037 /// Internal use only 01038 void clearRxBuf(); 01039 01040 /// Clears the transmitter buffer 01041 /// Internal use only 01042 void clearTxBuf(); 01043 01044 /// Fills the transmitter buffer with the data of a mesage to be sent 01045 /// \param[in] data Array of data bytes to be sent (1 to 255) 01046 /// \param[in] len Number of data bytes in data (> 0) 01047 /// \return true if the message length is valid 01048 boolean fillTxBuf(const uint8_t* data, uint8_t len); 01049 01050 /// Appends the transmitter buffer with the data of a mesage to be sent 01051 /// \param[in] data Array of data bytes to be sent (0 to 255) 01052 /// \param[in] len Number of data bytes in data 01053 /// \return false if the resulting message would exceed RF22_MAX_MESSAGE_LEN, else true 01054 boolean appendTxBuf(const uint8_t* data, uint8_t len); 01055 01056 /// Internal function to load the next fragment of 01057 /// the current message into the transmitter FIFO 01058 /// Internal use only 01059 void sendNextFragment(); 01060 01061 /// function to copy the next fragment from 01062 /// the receiver FIF) into the receiver buffer 01063 void readNextFragment(); 01064 01065 /// Clears the RF22 Rx and Tx FIFOs 01066 /// Internal use only 01067 void resetFifos(); 01068 01069 /// Clears the RF22 Rx FIFO 01070 /// Internal use only 01071 void resetRxFifo(); 01072 01073 /// Clears the RF22 Tx FIFO 01074 /// Internal use only 01075 void resetTxFifo(); 01076 01077 /// This function will be called by handleInterrupt() if an RF22 external interrupt occurs. 01078 /// This can only happen if external interrupts are enabled in the RF22 01079 /// (which they are not by default). 01080 /// Subclasses may override this function to get control when an RF22 external interrupt occurs. 01081 virtual void handleExternalInterrupt(); 01082 01083 /// This function will be called by handleInterrupt() if an RF22 wakeup timer interrupt occurs. 01084 /// This can only happen if wakeup timer interrupts are enabled in the RF22 01085 /// (which they are not by default). 01086 /// Subclasses may override this function to get control when an RF22 wakeup timer interrupt occurs. 01087 virtual void handleWakeupTimerInterrupt(); 01088 01089 /// Sets the TO header to be sent in all subsequent messages 01090 /// \param[in] to The new TO header value 01091 void setHeaderTo(uint8_t to); 01092 01093 /// Sets the FROM header to be sent in all subsequent messages 01094 /// \param[in] from The new FROM header value 01095 void setHeaderFrom(uint8_t from); 01096 01097 /// Sets the ID header to be sent in all subsequent messages 01098 /// \param[in] id The new ID header value 01099 void setHeaderId(uint8_t id); 01100 01101 /// Sets the FLAGS header to be sent in all subsequent messages 01102 /// \param[in] flags The new FLAGS header value 01103 void setHeaderFlags(uint8_t flags); 01104 01105 /// Start the transmission of the contents 01106 /// of the Tx buffer 01107 void startTransmit(); 01108 01109 /// ReStart the transmission of the contents 01110 /// of the Tx buffer after a atransmission failure 01111 void restartTransmit(); 01112 01113 protected: 01114 //GenericSPIClass* _spi; 01115 01116 /// Low level interrupt service routine for RF22 connected to interrupt 0 01117 //static void isr0(); 01118 void isr0(); 01119 01120 /// Low level interrupt service routine for RF22 connected to interrupt 1 01121 //static void isr1(); 01122 private: 01123 /// Array of instances connected to interrupts 0 and 1 01124 //static RF22* _RF22ForInterrupt[]; 01125 01126 01127 volatile uint8_t _mode; // One of RF22_MODE_* 01128 01129 uint8_t _idleMode; 01130 DigitalOut _slaveSelectPin; 01131 SPI _spi; 01132 InterruptIn _interrupt; 01133 uint8_t _deviceType; 01134 01135 DigitalOut led1; 01136 DigitalOut led2; 01137 DigitalOut led3; 01138 DigitalOut led4; 01139 01140 // These volatile members may get changed in the interrupt service routine 01141 volatile uint8_t _bufLen; 01142 uint8_t _buf[RF22_MAX_MESSAGE_LEN]; 01143 01144 volatile boolean _rxBufValid; 01145 01146 volatile boolean _txPacketSent; 01147 volatile uint8_t _txBufSentIndex; 01148 01149 volatile uint16_t _rxBad; 01150 volatile uint16_t _rxGood; 01151 volatile uint16_t _txGood; 01152 01153 volatile uint8_t _lastRssi; 01154 }; 01155 01156 /// @example rf22_client.pde 01157 /// Client side of simple client/server pair using RF22 class 01158 01159 /// @example rf22_server.pde 01160 /// Server side of simple client/server pair using RF22 class 01161 01162 /// @example rf22_datagram_client.pde 01163 /// Client side of simple client/server pair using RF22Datagram class 01164 01165 /// @example rf22_datagram_server.pde 01166 /// Server side of simple client/server pair using RF22Datagram class 01167 01168 /// @example rf22_reliable_datagram_client.pde 01169 /// Client side of simple client/server pair using RF22ReliableDatagram class 01170 01171 /// @example rf22_reliable_datagram_server.pde 01172 /// Server side of simple client/server pair using RF22ReliableDatagram class 01173 01174 /// @example rf22_router_client.pde 01175 /// Client side of RF22Router network chain 01176 01177 /// @example rf22_router_server1.pde 01178 /// Server node for RF22Router network chain 01179 01180 /// @example rf22_router_server2.pde 01181 /// Server node for RF22Router network chain 01182 01183 /// @example rf22_router_server3.pde 01184 /// Server node for RF22Router network chain 01185 01186 /// @example rf22_mesh_client.pde 01187 /// Client side of RF22Mesh network chain 01188 01189 /// @example rf22_mesh_server1.pde 01190 /// Server node for RF22Mesh network chain 01191 01192 /// @example rf22_mesh_server2.pde 01193 /// Server node for RF22Mesh network chain 01194 01195 /// @example rf22_mesh_server3.pde 01196 /// Server node for RF22Mesh network chain 01197 01198 /// @example rf22_test.pde 01199 /// Test suite for RF22 library 01200 01201 /// @example rf22_snoop.pde 01202 /// Capture and print RF22 packet from the air 01203 01204 /// @example rf22_specan.pde 01205 /// Simple spectrum analyser using the RSSI measurements of the RF22 01206 /// (see <a href="specan1.png">Sample output</a> showing a plot from 395.0MHz to 396.0MHz of a 01207 /// signal generator at 395.5MHz amplitude modulated at 100% 1kHz) 01208 /// 01209 01210 /// @example IPGateway.pde 01211 /// Sketch to provide an IP gateway for a set of RF22 radios (Datagram, ReliableDatagram, Router or Mesh) 01212 /// Routes UDP messages from an internet connection using an Ethernet Shield and sends them 01213 /// to a radio whose ID is based on the UDP port. Replies are sent back to the originating UDP 01214 /// address and port 01215 01216 01217 #endif
Generated on Wed Jul 13 2022 22:24:22 by
