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