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