David Rimer / RadioHead-148
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RH_RF22.h Source File

RH_RF22.h

00001 // RH_RF22.h
00002 // Author: Mike McCauley (mikem@airspayce.com)
00003 // Copyright (C) 2011 Mike McCauley
00004 // $Id: RH_RF22.h,v 1.27 2015/05/17 00:11:26 mikem Exp $
00005 //
00006 
00007 #ifndef RH_RF22_h
00008 #define RH_RF22_h
00009 
00010 #include <RHGenericSPI.h>
00011 #include <RHSPIDriver.h>
00012 
00013 // This is the maximum number of interrupts the library can support
00014 // Most Arduinos can handle 2, Megas can handle more
00015 #define RH_RF22_NUM_INTERRUPTS 3
00016 
00017 // This is the bit in the SPI address that marks it as a write
00018 #define RH_RF22_SPI_WRITE_MASK 0x80
00019 
00020 // This is the maximum message length that can be supported by this library. Limited by
00021 // the single message length octet in the header. 
00022 // Yes, 255 is correct even though the FIFO size in the RF22 is only
00023 // 64 octets. We use interrupts to refill the Tx FIFO during transmission and to empty the
00024 // Rx FIFO during reception
00025 // Can be pre-defined to a smaller size (to save SRAM) prior to including this header
00026 #ifndef RH_RF22_MAX_MESSAGE_LEN
00027 //#define RH_RF22_MAX_MESSAGE_LEN 255
00028 #define RH_RF22_MAX_MESSAGE_LEN 50
00029 #endif
00030 
00031 // Max number of octets the RF22 Rx and Tx FIFOs can hold
00032 #define RH_RF22_FIFO_SIZE 64
00033 
00034 // These values we set for FIFO thresholds (4, 55) are actually the same as the POR values
00035 #define RH_RF22_TXFFAEM_THRESHOLD 4
00036 #define RH_RF22_RXFFAFULL_THRESHOLD 55
00037 
00038 // Number of registers to be passed to setModemConfig(). Obsolete.
00039 #define RH_RF22_NUM_MODEM_CONFIG_REGS 18
00040 
00041 // Register names
00042 #define RH_RF22_REG_00_DEVICE_TYPE                         0x00
00043 #define RH_RF22_REG_01_VERSION_CODE                        0x01
00044 #define RH_RF22_REG_02_DEVICE_STATUS                       0x02
00045 #define RH_RF22_REG_03_INTERRUPT_STATUS1                   0x03
00046 #define RH_RF22_REG_04_INTERRUPT_STATUS2                   0x04
00047 #define RH_RF22_REG_05_INTERRUPT_ENABLE1                   0x05
00048 #define RH_RF22_REG_06_INTERRUPT_ENABLE2                   0x06
00049 #define RH_RF22_REG_07_OPERATING_MODE1                     0x07
00050 #define RH_RF22_REG_08_OPERATING_MODE2                     0x08
00051 #define RH_RF22_REG_09_OSCILLATOR_LOAD_CAPACITANCE         0x09
00052 #define RH_RF22_REG_0A_UC_OUTPUT_CLOCK                     0x0a
00053 #define RH_RF22_REG_0B_GPIO_CONFIGURATION0                 0x0b
00054 #define RH_RF22_REG_0C_GPIO_CONFIGURATION1                 0x0c
00055 #define RH_RF22_REG_0D_GPIO_CONFIGURATION2                 0x0d
00056 #define RH_RF22_REG_0E_IO_PORT_CONFIGURATION               0x0e
00057 #define RH_RF22_REG_0F_ADC_CONFIGURATION                   0x0f
00058 #define RH_RF22_REG_10_ADC_SENSOR_AMP_OFFSET               0x10
00059 #define RH_RF22_REG_11_ADC_VALUE                           0x11
00060 #define RH_RF22_REG_12_TEMPERATURE_SENSOR_CALIBRATION      0x12
00061 #define RH_RF22_REG_13_TEMPERATURE_VALUE_OFFSET            0x13
00062 #define RH_RF22_REG_14_WAKEUP_TIMER_PERIOD1                0x14
00063 #define RH_RF22_REG_15_WAKEUP_TIMER_PERIOD2                0x15
00064 #define RH_RF22_REG_16_WAKEUP_TIMER_PERIOD3                0x16
00065 #define RH_RF22_REG_17_WAKEUP_TIMER_VALUE1                 0x17
00066 #define RH_RF22_REG_18_WAKEUP_TIMER_VALUE2                 0x18
00067 #define RH_RF22_REG_19_LDC_MODE_DURATION                   0x19
00068 #define RH_RF22_REG_1A_LOW_BATTERY_DETECTOR_THRESHOLD      0x1a
00069 #define RH_RF22_REG_1B_BATTERY_VOLTAGE_LEVEL               0x1b
00070 #define RH_RF22_REG_1C_IF_FILTER_BANDWIDTH                 0x1c
00071 #define RH_RF22_REG_1D_AFC_LOOP_GEARSHIFT_OVERRIDE         0x1d
00072 #define RH_RF22_REG_1E_AFC_TIMING_CONTROL                  0x1e
00073 #define RH_RF22_REG_1F_CLOCK_RECOVERY_GEARSHIFT_OVERRIDE   0x1f
00074 #define RH_RF22_REG_20_CLOCK_RECOVERY_OVERSAMPLING_RATE    0x20
00075 #define RH_RF22_REG_21_CLOCK_RECOVERY_OFFSET2              0x21
00076 #define RH_RF22_REG_22_CLOCK_RECOVERY_OFFSET1              0x22
00077 #define RH_RF22_REG_23_CLOCK_RECOVERY_OFFSET0              0x23
00078 #define RH_RF22_REG_24_CLOCK_RECOVERY_TIMING_LOOP_GAIN1    0x24
00079 #define RH_RF22_REG_25_CLOCK_RECOVERY_TIMING_LOOP_GAIN0    0x25
00080 #define RH_RF22_REG_26_RSSI                                0x26
00081 #define RH_RF22_REG_27_RSSI_THRESHOLD                      0x27
00082 #define RH_RF22_REG_28_ANTENNA_DIVERSITY1                  0x28
00083 #define RH_RF22_REG_29_ANTENNA_DIVERSITY2                  0x29
00084 #define RH_RF22_REG_2A_AFC_LIMITER                         0x2a
00085 #define RH_RF22_REG_2B_AFC_CORRECTION_READ                 0x2b
00086 #define RH_RF22_REG_2C_OOK_COUNTER_VALUE_1                 0x2c
00087 #define RH_RF22_REG_2D_OOK_COUNTER_VALUE_2                 0x2d
00088 #define RH_RF22_REG_2E_SLICER_PEAK_HOLD                    0x2e
00089 #define RH_RF22_REG_30_DATA_ACCESS_CONTROL                 0x30
00090 #define RH_RF22_REG_31_EZMAC_STATUS                        0x31
00091 #define RH_RF22_REG_32_HEADER_CONTROL1                     0x32
00092 #define RH_RF22_REG_33_HEADER_CONTROL2                     0x33
00093 #define RH_RF22_REG_34_PREAMBLE_LENGTH                     0x34
00094 #define RH_RF22_REG_35_PREAMBLE_DETECTION_CONTROL1         0x35
00095 #define RH_RF22_REG_36_SYNC_WORD3                          0x36
00096 #define RH_RF22_REG_37_SYNC_WORD2                          0x37
00097 #define RH_RF22_REG_38_SYNC_WORD1                          0x38
00098 #define RH_RF22_REG_39_SYNC_WORD0                          0x39
00099 #define RH_RF22_REG_3A_TRANSMIT_HEADER3                    0x3a
00100 #define RH_RF22_REG_3B_TRANSMIT_HEADER2                    0x3b
00101 #define RH_RF22_REG_3C_TRANSMIT_HEADER1                    0x3c
00102 #define RH_RF22_REG_3D_TRANSMIT_HEADER0                    0x3d
00103 #define RH_RF22_REG_3E_PACKET_LENGTH                       0x3e
00104 #define RH_RF22_REG_3F_CHECK_HEADER3                       0x3f
00105 #define RH_RF22_REG_40_CHECK_HEADER2                       0x40
00106 #define RH_RF22_REG_41_CHECK_HEADER1                       0x41
00107 #define RH_RF22_REG_42_CHECK_HEADER0                       0x42
00108 #define RH_RF22_REG_43_HEADER_ENABLE3                      0x43
00109 #define RH_RF22_REG_44_HEADER_ENABLE2                      0x44
00110 #define RH_RF22_REG_45_HEADER_ENABLE1                      0x45
00111 #define RH_RF22_REG_46_HEADER_ENABLE0                      0x46
00112 #define RH_RF22_REG_47_RECEIVED_HEADER3                    0x47
00113 #define RH_RF22_REG_48_RECEIVED_HEADER2                    0x48
00114 #define RH_RF22_REG_49_RECEIVED_HEADER1                    0x49
00115 #define RH_RF22_REG_4A_RECEIVED_HEADER0                    0x4a
00116 #define RH_RF22_REG_4B_RECEIVED_PACKET_LENGTH              0x4b
00117 #define RH_RF22_REG_50_ANALOG_TEST_BUS_SELECT              0x50
00118 #define RH_RF22_REG_51_DIGITAL_TEST_BUS_SELECT             0x51
00119 #define RH_RF22_REG_52_TX_RAMP_CONTROL                     0x52
00120 #define RH_RF22_REG_53_PLL_TUNE_TIME                       0x53
00121 #define RH_RF22_REG_55_CALIBRATION_CONTROL                 0x55
00122 #define RH_RF22_REG_56_MODEM_TEST                          0x56
00123 #define RH_RF22_REG_57_CHARGE_PUMP_TEST                    0x57
00124 #define RH_RF22_REG_58_CHARGE_PUMP_CURRENT_TRIMMING        0x58
00125 #define RH_RF22_REG_59_DIVIDER_CURRENT_TRIMMING            0x59
00126 #define RH_RF22_REG_5A_VCO_CURRENT_TRIMMING                0x5a
00127 #define RH_RF22_REG_5B_VCO_CALIBRATION                     0x5b
00128 #define RH_RF22_REG_5C_SYNTHESIZER_TEST                    0x5c
00129 #define RH_RF22_REG_5D_BLOCK_ENABLE_OVERRIDE1              0x5d
00130 #define RH_RF22_REG_5E_BLOCK_ENABLE_OVERRIDE2              0x5e
00131 #define RH_RF22_REG_5F_BLOCK_ENABLE_OVERRIDE3              0x5f
00132 #define RH_RF22_REG_60_CHANNEL_FILTER_COEFFICIENT_ADDRESS  0x60
00133 #define RH_RF22_REG_61_CHANNEL_FILTER_COEFFICIENT_VALUE    0x61
00134 #define RH_RF22_REG_62_CRYSTAL_OSCILLATOR_POR_CONTROL      0x62
00135 #define RH_RF22_REG_63_RC_OSCILLATOR_COARSE_CALIBRATION    0x63
00136 #define RH_RF22_REG_64_RC_OSCILLATOR_FINE_CALIBRATION      0x64
00137 #define RH_RF22_REG_65_LDO_CONTROL_OVERRIDE                0x65
00138 #define RH_RF22_REG_66_LDO_LEVEL_SETTINGS                  0x66
00139 #define RH_RF22_REG_67_DELTA_SIGMA_ADC_TUNING1             0x67
00140 #define RH_RF22_REG_68_DELTA_SIGMA_ADC_TUNING2             0x68
00141 #define RH_RF22_REG_69_AGC_OVERRIDE1                       0x69
00142 #define RH_RF22_REG_6A_AGC_OVERRIDE2                       0x6a
00143 #define RH_RF22_REG_6B_GFSK_FIR_FILTER_COEFFICIENT_ADDRESS 0x6b
00144 #define RH_RF22_REG_6C_GFSK_FIR_FILTER_COEFFICIENT_VALUE   0x6c
00145 #define RH_RF22_REG_6D_TX_POWER                            0x6d
00146 #define RH_RF22_REG_6E_TX_DATA_RATE1                       0x6e
00147 #define RH_RF22_REG_6F_TX_DATA_RATE0                       0x6f
00148 #define RH_RF22_REG_70_MODULATION_CONTROL1                 0x70
00149 #define RH_RF22_REG_71_MODULATION_CONTROL2                 0x71
00150 #define RH_RF22_REG_72_FREQUENCY_DEVIATION                 0x72
00151 #define RH_RF22_REG_73_FREQUENCY_OFFSET1                   0x73
00152 #define RH_RF22_REG_74_FREQUENCY_OFFSET2                   0x74
00153 #define RH_RF22_REG_75_FREQUENCY_BAND_SELECT               0x75
00154 #define RH_RF22_REG_76_NOMINAL_CARRIER_FREQUENCY1          0x76
00155 #define RH_RF22_REG_77_NOMINAL_CARRIER_FREQUENCY0          0x77
00156 #define RH_RF22_REG_79_FREQUENCY_HOPPING_CHANNEL_SELECT    0x79
00157 #define RH_RF22_REG_7A_FREQUENCY_HOPPING_STEP_SIZE         0x7a
00158 #define RH_RF22_REG_7C_TX_FIFO_CONTROL1                    0x7c
00159 #define RH_RF22_REG_7D_TX_FIFO_CONTROL2                    0x7d
00160 #define RH_RF22_REG_7E_RX_FIFO_CONTROL                     0x7e
00161 #define RH_RF22_REG_7F_FIFO_ACCESS                         0x7f
00162 
00163 // These register masks etc are named wherever possible
00164 // corresponding to the bit and field names in the RF-22 Manual
00165 // RH_RF22_REG_00_DEVICE_TYPE                      0x00
00166 #define RH_RF22_DEVICE_TYPE_RX_TRX                 0x08
00167 #define RH_RF22_DEVICE_TYPE_TX                     0x07
00168 
00169 // RH_RF22_REG_02_DEVICE_STATUS                    0x02
00170 #define RH_RF22_FFOVL                              0x80
00171 #define RH_RF22_FFUNFL                             0x40
00172 #define RH_RF22_RXFFEM                             0x20
00173 #define RH_RF22_HEADERR                            0x10
00174 #define RH_RF22_FREQERR                            0x08
00175 #define RH_RF22_LOCKDET                            0x04
00176 #define RH_RF22_CPS                                0x03
00177 #define RH_RF22_CPS_IDLE                           0x00
00178 #define RH_RF22_CPS_RX                             0x01
00179 #define RH_RF22_CPS_TX                             0x10
00180 
00181 // RH_RF22_REG_03_INTERRUPT_STATUS1                0x03
00182 #define RH_RF22_IFFERROR                           0x80
00183 #define RH_RF22_ITXFFAFULL                         0x40
00184 #define RH_RF22_ITXFFAEM                           0x20
00185 #define RH_RF22_IRXFFAFULL                         0x10
00186 #define RH_RF22_IEXT                               0x08
00187 #define RH_RF22_IPKSENT                            0x04
00188 #define RH_RF22_IPKVALID                           0x02
00189 #define RH_RF22_ICRCERROR                          0x01
00190 
00191 // RH_RF22_REG_04_INTERRUPT_STATUS2                0x04
00192 #define RH_RF22_ISWDET                             0x80
00193 #define RH_RF22_IPREAVAL                           0x40
00194 #define RH_RF22_IPREAINVAL                         0x20
00195 #define RH_RF22_IRSSI                              0x10
00196 #define RH_RF22_IWUT                               0x08
00197 #define RH_RF22_ILBD                               0x04
00198 #define RH_RF22_ICHIPRDY                           0x02
00199 #define RH_RF22_IPOR                               0x01
00200 
00201 // RH_RF22_REG_05_INTERRUPT_ENABLE1                0x05
00202 #define RH_RF22_ENFFERR                            0x80
00203 #define RH_RF22_ENTXFFAFULL                        0x40
00204 #define RH_RF22_ENTXFFAEM                          0x20
00205 #define RH_RF22_ENRXFFAFULL                        0x10
00206 #define RH_RF22_ENEXT                              0x08
00207 #define RH_RF22_ENPKSENT                           0x04
00208 #define RH_RF22_ENPKVALID                          0x02
00209 #define RH_RF22_ENCRCERROR                         0x01
00210 
00211 // RH_RF22_REG_06_INTERRUPT_ENABLE2                0x06
00212 #define RH_RF22_ENSWDET                            0x80
00213 #define RH_RF22_ENPREAVAL                          0x40
00214 #define RH_RF22_ENPREAINVAL                        0x20
00215 #define RH_RF22_ENRSSI                             0x10
00216 #define RH_RF22_ENWUT                              0x08
00217 #define RH_RF22_ENLBDI                             0x04
00218 #define RH_RF22_ENCHIPRDY                          0x02
00219 #define RH_RF22_ENPOR                              0x01
00220 
00221 // RH_RF22_REG_07_OPERATING_MODE                   0x07
00222 #define RH_RF22_SWRES                              0x80
00223 #define RH_RF22_ENLBD                              0x40
00224 #define RH_RF22_ENWT                               0x20
00225 #define RH_RF22_X32KSEL                            0x10
00226 #define RH_RF22_TXON                               0x08
00227 #define RH_RF22_RXON                               0x04
00228 #define RH_RF22_PLLON                              0x02
00229 #define RH_RF22_XTON                               0x01
00230 
00231 // RH_RF22_REG_08_OPERATING_MODE2                  0x08
00232 #define RH_RF22_ANTDIV                             0xc0
00233 #define RH_RF22_RXMPK                              0x10
00234 #define RH_RF22_AUTOTX                             0x08
00235 #define RH_RF22_ENLDM                              0x04
00236 #define RH_RF22_FFCLRRX                            0x02
00237 #define RH_RF22_FFCLRTX                            0x01
00238 
00239 // RH_RF22_REG_0F_ADC_CONFIGURATION                0x0f
00240 #define RH_RF22_ADCSTART                           0x80
00241 #define RH_RF22_ADCDONE                            0x80
00242 #define RH_RF22_ADCSEL                             0x70
00243 #define RH_RF22_ADCSEL_INTERNAL_TEMPERATURE_SENSOR 0x00
00244 #define RH_RF22_ADCSEL_GPIO0_SINGLE_ENDED          0x10
00245 #define RH_RF22_ADCSEL_GPIO1_SINGLE_ENDED          0x20
00246 #define RH_RF22_ADCSEL_GPIO2_SINGLE_ENDED          0x30
00247 #define RH_RF22_ADCSEL_GPIO0_GPIO1_DIFFERENTIAL    0x40
00248 #define RH_RF22_ADCSEL_GPIO1_GPIO2_DIFFERENTIAL    0x50
00249 #define RH_RF22_ADCSEL_GPIO0_GPIO2_DIFFERENTIAL    0x60
00250 #define RH_RF22_ADCSEL_GND                         0x70
00251 #define RH_RF22_ADCREF                             0x0c
00252 #define RH_RF22_ADCREF_BANDGAP_VOLTAGE             0x00
00253 #define RH_RF22_ADCREF_VDD_ON_3                    0x08
00254 #define RH_RF22_ADCREF_VDD_ON_2                    0x0c
00255 #define RH_RF22_ADCGAIN                            0x03
00256 
00257 // RH_RF22_REG_10_ADC_SENSOR_AMP_OFFSET            0x10
00258 #define RH_RF22_ADCOFFS                            0x0f
00259 
00260 // RH_RF22_REG_12_TEMPERATURE_SENSOR_CALIBRATION   0x12
00261 #define RH_RF22_TSRANGE                            0xc0
00262 #define RH_RF22_TSRANGE_M64_64C                    0x00
00263 #define RH_RF22_TSRANGE_M64_192C                   0x40
00264 #define RH_RF22_TSRANGE_0_128C                     0x80
00265 #define RH_RF22_TSRANGE_M40_216F                   0xc0
00266 #define RH_RF22_ENTSOFFS                           0x20
00267 #define RH_RF22_ENTSTRIM                           0x10
00268 #define RH_RF22_TSTRIM                             0x0f
00269 
00270 // RH_RF22_REG_14_WAKEUP_TIMER_PERIOD1             0x14
00271 #define RH_RF22_WTR                                0x3c
00272 #define RH_RF22_WTD                                0x03
00273 
00274 // RH_RF22_REG_1D_AFC_LOOP_GEARSHIFT_OVERRIDE      0x1d
00275 #define RH_RF22_AFBCD                              0x80
00276 #define RH_RF22_ENAFC                              0x40
00277 #define RH_RF22_AFCGEARH                           0x38
00278 #define RH_RF22_AFCGEARL                           0x07
00279 
00280 // RH_RF22_REG_1E_AFC_TIMING_CONTROL               0x1e
00281 #define RH_RF22_SWAIT_TIMER                        0xc0
00282 #define RH_RF22_SHWAIT                             0x38
00283 #define RH_RF22_ANWAIT                             0x07
00284 
00285 // RH_RF22_REG_30_DATA_ACCESS_CONTROL              0x30
00286 #define RH_RF22_ENPACRX                            0x80
00287 #define RH_RF22_MSBFRST                            0x00
00288 #define RH_RF22_LSBFRST                            0x40
00289 #define RH_RF22_CRCHDRS                            0x00
00290 #define RH_RF22_CRCDONLY                           0x20
00291 #define RH_RF22_SKIP2PH                            0x10
00292 #define RH_RF22_ENPACTX                            0x08
00293 #define RH_RF22_ENCRC                              0x04
00294 #define RH_RF22_CRC                                0x03
00295 #define RH_RF22_CRC_CCITT                          0x00
00296 #define RH_RF22_CRC_CRC_16_IBM                     0x01
00297 #define RH_RF22_CRC_IEC_16                         0x02
00298 #define RH_RF22_CRC_BIACHEVA                       0x03
00299 
00300 // RH_RF22_REG_32_HEADER_CONTROL1                  0x32
00301 #define RH_RF22_BCEN                               0xf0
00302 #define RH_RF22_BCEN_NONE                          0x00
00303 #define RH_RF22_BCEN_HEADER0                       0x10
00304 #define RH_RF22_BCEN_HEADER1                       0x20
00305 #define RH_RF22_BCEN_HEADER2                       0x40
00306 #define RH_RF22_BCEN_HEADER3                       0x80
00307 #define RH_RF22_HDCH                               0x0f
00308 #define RH_RF22_HDCH_NONE                          0x00
00309 #define RH_RF22_HDCH_HEADER0                       0x01
00310 #define RH_RF22_HDCH_HEADER1                       0x02
00311 #define RH_RF22_HDCH_HEADER2                       0x04
00312 #define RH_RF22_HDCH_HEADER3                       0x08
00313 
00314 // RH_RF22_REG_33_HEADER_CONTROL2                  0x33
00315 #define RH_RF22_HDLEN                              0x70
00316 #define RH_RF22_HDLEN_0                            0x00
00317 #define RH_RF22_HDLEN_1                            0x10
00318 #define RH_RF22_HDLEN_2                            0x20
00319 #define RH_RF22_HDLEN_3                            0x30
00320 #define RH_RF22_HDLEN_4                            0x40
00321 #define RH_RF22_VARPKLEN                           0x00
00322 #define RH_RF22_FIXPKLEN                           0x08
00323 #define RH_RF22_SYNCLEN                            0x06
00324 #define RH_RF22_SYNCLEN_1                          0x00
00325 #define RH_RF22_SYNCLEN_2                          0x02
00326 #define RH_RF22_SYNCLEN_3                          0x04
00327 #define RH_RF22_SYNCLEN_4                          0x06
00328 #define RH_RF22_PREALEN8                           0x01
00329 
00330 // RH_RF22_REG_6D_TX_POWER                         0x6d
00331 // https://www.sparkfun.com/datasheets/Wireless/General/RFM22B.pdf
00332 #define RH_RF22_PAPEAKVAL                          0x80
00333 #define RH_RF22_PAPEAKEN                           0x40
00334 #define RH_RF22_PAPEAKLVL                          0x30
00335 #define RH_RF22_PAPEAKLVL6_5                       0x00
00336 #define RH_RF22_PAPEAKLVL7                         0x10
00337 #define RH_RF22_PAPEAKLVL7_5                       0x20
00338 #define RH_RF22_PAPEAKLVL8                         0x30
00339 #define RH_RF22_LNA_SW                             0x08
00340 #define RH_RF22_TXPOW                              0x07
00341 #define RH_RF22_TXPOW_4X31                         0x08 // Not used in RFM22B
00342 // For RFM22B:
00343 #define RH_RF22_TXPOW_1DBM                         0x00
00344 #define RH_RF22_TXPOW_2DBM                         0x01
00345 #define RH_RF22_TXPOW_5DBM                         0x02
00346 #define RH_RF22_TXPOW_8DBM                         0x03
00347 #define RH_RF22_TXPOW_11DBM                        0x04
00348 #define RH_RF22_TXPOW_14DBM                        0x05 
00349 #define RH_RF22_TXPOW_17DBM                        0x06 
00350 #define RH_RF22_TXPOW_20DBM                        0x07 
00351 // RFM23B only:
00352 #define RH_RF22_RF23B_TXPOW_M8DBM                  0x00 // -8dBm
00353 #define RH_RF22_RF23B_TXPOW_M5DBM                  0x01 // -5dBm
00354 #define RH_RF22_RF23B_TXPOW_M2DBM                  0x02 // -2dBm
00355 #define RH_RF22_RF23B_TXPOW_1DBM                   0x03 // 1dBm
00356 #define RH_RF22_RF23B_TXPOW_4DBM                   0x04 // 4dBm
00357 #define RH_RF22_RF23B_TXPOW_7DBM                   0x05 // 7dBm
00358 #define RH_RF22_RF23B_TXPOW_10DBM                  0x06 // 10dBm
00359 #define RH_RF22_RF23B_TXPOW_13DBM                  0x07 // 13dBm
00360 // RFM23BP only:
00361 #define RH_RF22_RF23BP_TXPOW_28DBM                 0x05 // 28dBm
00362 #define RH_RF22_RF23BP_TXPOW_29DBM                 0x06 // 29dBm
00363 #define RH_RF22_RF23BP_TXPOW_30DBM                 0x07 // 30dBm
00364 
00365 // RH_RF22_REG_71_MODULATION_CONTROL2              0x71
00366 #define RH_RF22_TRCLK                              0xc0
00367 #define RH_RF22_TRCLK_NONE                         0x00
00368 #define RH_RF22_TRCLK_GPIO                         0x40
00369 #define RH_RF22_TRCLK_SDO                          0x80
00370 #define RH_RF22_TRCLK_NIRQ                         0xc0
00371 #define RH_RF22_DTMOD                              0x30
00372 #define RH_RF22_DTMOD_DIRECT_GPIO                  0x00
00373 #define RH_RF22_DTMOD_DIRECT_SDI                   0x10
00374 #define RH_RF22_DTMOD_FIFO                         0x20
00375 #define RH_RF22_DTMOD_PN9                          0x30
00376 #define RH_RF22_ENINV                              0x08
00377 #define RH_RF22_FD8                                0x04
00378 #define RH_RF22_MODTYP                             0x30
00379 #define RH_RF22_MODTYP_UNMODULATED                 0x00
00380 #define RH_RF22_MODTYP_OOK                         0x01
00381 #define RH_RF22_MODTYP_FSK                         0x02
00382 #define RH_RF22_MODTYP_GFSK                        0x03
00383 
00384 
00385 // RH_RF22_REG_75_FREQUENCY_BAND_SELECT            0x75
00386 #define RH_RF22_SBSEL                              0x40
00387 #define RH_RF22_HBSEL                              0x20
00388 #define RH_RF22_FB                                 0x1f
00389 
00390 // Define this to include Serial printing in diagnostic routines
00391 #define RH_RF22_HAVE_SERIAL
00392 
00393 /////////////////////////////////////////////////////////////////////
00394 /// \class RH_RF22 RH_RF22.h <RH_RF22.h>
00395 /// \brief Driver to send and receive unaddressed, unreliable datagrams via an RF22 and compatible radio transceiver.
00396 ///
00397 /// Works with RF22, RF23 based radio modules, and compatible chips and modules, including:
00398 /// - RF22 bare module: http://www.sparkfun.com/products/10153
00399 ///   (Caution, that is a 3.3V part, and requires a 3.3V CPU such as Teensy etc or level shifters)
00400 /// - RF22 shield: http://www.sparkfun.com/products/11018 
00401 /// - RF22 integrated board http://www.anarduino.com/miniwireless
00402 /// - RFM23BP bare module: http://www.anarduino.com/details.jsp?pid=130 
00403 /// - Silicon Labs Si4430/31/32 based modules. S4432 is equivalent to RF22. Si4431/30 is equivalent to RF23.
00404 ///
00405 /// Data based on https://www.sparkfun.com/datasheets/Wireless/General/RFM22B.pdf
00406 ///
00407 /// \par Overview
00408 ///
00409 /// This base class provides basic functions for sending and receiving unaddressed, 
00410 /// unreliable datagrams of arbitrary length to 255 octets per packet.
00411 ///
00412 /// Manager classes may use this class to implement reliable, addressed datagrams and streams, 
00413 /// mesh routers, repeaters, translators etc.
00414 ///
00415 /// On transmission, the TO and FROM addresses default to 0x00, unless changed by a subclass. 
00416 /// On reception the TO addressed is checked against the node address (defaults to 0x00) or the
00417 /// broadcast address (which is 0xff). The ID and FLAGS are set to 0, and not checked by this class.
00418 /// This permits use of the this base RH_RF22 class as an 
00419 /// unaddressed, unreliable datagram service without the use of one the RadioHead Manager classes.
00420 ///
00421 /// Naturally, for any 2 radios to communicate that must be configured to use the same frequency and 
00422 /// modulation scheme.
00423 ///
00424 /// \par Details
00425 ///
00426 /// This Driver provides an object-oriented interface for sending and receiving data messages with Hope-RF
00427 /// RF22 and RF23 based radio modules, and compatible chips and modules, 
00428 /// including the RFM22B transceiver module such as 
00429 /// this bare module: http://www.sparkfun.com/products/10153
00430 /// and this shield: http://www.sparkfun.com/products/11018
00431 /// and this module: http://www.hoperfusa.com/details.jsp?pid=131
00432 /// and this integrated board: http://www.anarduino.com/miniwireless
00433 /// and RF23BP modules such as this http://www.anarduino.com/details.jsp?pid=130
00434 ///
00435 /// The Hope-RF (http://www.hoperf.com) RFM22B (http://www.hoperf.com/rf_fsk/fsk/RFM22B.htm) 
00436 /// is a low-cost ISM transceiver module. It supports FSK, GFSK, OOK over a wide 
00437 /// range of frequencies and programmable data rates.
00438 /// Manual can be found at https://www.sparkfun.com/datasheets/Wireless/General/RFM22.PDF
00439 ///
00440 /// This library provides functions for sending and receiving messages of up to 255 octets on any 
00441 /// frequency supported by the RF22B, in a range of predefined data rates and frequency deviations. 
00442 /// Frequency can be set with 312Hz precision to any frequency from 240.0MHz to 960.0MHz.
00443 ///
00444 /// Up to 3 RF22B modules can be connected to an Arduino, permitting the construction of translators
00445 /// and frequency changers, etc.
00446 ///
00447 /// The following modulation types are suppported with a range of modem configurations for 
00448 /// common data rates and frequency deviations:
00449 /// - GFSK Gaussian Frequency Shift Keying
00450 /// - FSK Frequency Shift Keying
00451 /// - OOK On-Off Keying
00452 ///
00453 /// Support for other RF22B features such as on-chip temperature measurement, analog-digital 
00454 /// converter, transmitter power control etc is also provided.
00455 ///
00456 /// Tested on Arduino Diecimila, Uno and Mega with arduino-0021, 1.0.5
00457 /// on OpenSuSE 13.1 and avr-libc-1.6.1-1.15,
00458 /// cross-avr-binutils-2.19-9.1, cross-avr-gcc-4.1.3_20080612-26.5.
00459 /// With HopeRF RFM22 modules that appear to have RF22B chips on board:
00460 ///    - Device Type Code = 0x08 (RX/TRX)
00461 ///    - Version Code = 0x06
00462 /// Works on Duo. Works with Sparkfun RFM22 Wireless shields. Works with RFM22 modules from http://www.hoperfusa.com/
00463 /// Works with Arduino 1.0 to at least 1.0.5. Works on Maple, Flymaple, Uno32.
00464 ///
00465 /// \par Packet Format
00466 ///
00467 /// All messages sent and received by this Driver must conform to this packet format:
00468 ///
00469 /// - 8 nibbles (4 octets) PREAMBLE
00470 /// - 2 octets SYNC 0x2d, 0xd4
00471 /// - 4 octets HEADER: (TO, FROM, ID, FLAGS)
00472 /// - 1 octet LENGTH (0 to 255), number of octets in DATA
00473 /// - 0 to 255 octets DATA
00474 /// - 2 octets CRC computed with CRC16(IBM), computed on HEADER, LENGTH and DATA
00475 ///
00476 /// For technical reasons, the message format is not protocol compatible with the 
00477 /// 'HopeRF Radio Transceiver Message Library for Arduino' http://www.airspayce.com/mikem/arduino/HopeRF from the same author. Nor is it compatible with 
00478 /// 'Virtual Wire' http://www.airspayce.com/mikem/arduino/VirtualWire.pdf also from the same author.
00479 ///
00480 /// \par Connecting RFM-22 to Arduino
00481 ///
00482 /// If you have the Sparkfun RFM22 Shield (https://www.sparkfun.com/products/11018)
00483 /// the connections described below are done for you on the shield, no changes required, 
00484 /// just add headers and plug it in to an Arduino (but not and Arduino Mega, see below)
00485 ///
00486 /// The physical connection between the RF22B and the Arduino requires 3.3V,
00487 /// the 3 x SPI pins (SCK, SDI, SDO), a Slave Select pin and an interrupt pin.
00488 ///
00489 /// Note also that on the RFM22B (but not the RFM23B), it is required to control the TX_ANT and
00490 /// RX_ANT pins of the RFM22 in order to control the antenna connection properly. The RH_RF22
00491 /// driver is configured by default so that GPIO0 and GPIO1 outputs can
00492 /// control TX_ANT and RX_ANT input pins respectively automatically. On RFM22, 
00493 /// you must connect GPIO0
00494 /// to TX_ANT and GPIO1 to RX_ANT for this automatic antenna switching to
00495 /// occur.  See setGpioReversed() for more details. These connections are not required on RFM23B.
00496 ///
00497 /// If you are using the Sparkfun RF22 shield, it will work with any 5V arduino without modification.
00498 /// Connect the RFM-22 module to most Arduino's like this (Caution, Arduino Mega has different pins for SPI, 
00499 /// see below).
00500 /// \code
00501 ///                 Arduino      RFM-22B
00502 ///                 GND----------GND-\ (ground in)
00503 ///                              SDN-/ (shutdown in)
00504 ///                 3V3----------VCC   (3.3V in)
00505 /// interrupt 0 pin D2-----------NIRQ  (interrupt request out)
00506 ///          SS pin D10----------NSEL  (chip select in)
00507 ///         SCK pin D13----------SCK   (SPI clock in)
00508 ///        MOSI pin D11----------SDI   (SPI Data in)
00509 ///        MISO pin D12----------SDO   (SPI data out)
00510 ///                           /--GPIO0 (GPIO0 out to control transmitter antenna TX_ANT)
00511 ///                           \--TX_ANT (TX antenna control in) RFM22B only
00512 ///                           /--GPIO1 (GPIO1 out to control receiver antenna RX_ANT)
00513 ///                           \--RX_ANT (RX antenna control in) RFM22B only
00514 /// \endcode
00515 /// For an Arduino Mega:
00516 /// \code
00517 ///                 Mega         RFM-22B
00518 ///                 GND----------GND-\ (ground in)
00519 ///                              SDN-/ (shutdown in)
00520 ///                 3V3----------VCC   (3.3V in)
00521 /// interrupt 0 pin D2-----------NIRQ  (interrupt request out)
00522 ///          SS pin D53----------NSEL  (chip select in)
00523 ///         SCK pin D52----------SCK   (SPI clock in)
00524 ///        MOSI pin D51----------SDI   (SPI Data in)
00525 ///        MISO pin D50----------SDO   (SPI data out)
00526 ///                           /--GPIO0 (GPIO0 out to control transmitter antenna TX_ANT)
00527 ///                           \--TX_ANT (TX antenna control in) RFM22B only
00528 ///                           /--GPIO1 (GPIO1 out to control receiver antenna RX_ANT)
00529 ///                           \--RX_ANT (RX antenna control in) RFM22B only
00530 /// \endcode
00531 /// For Chipkit Uno32. Caution: you must also ensure jumper JP4 on the Uno32 is set to RD4
00532 /// \code
00533 ///                 Arduino      RFM-22B
00534 ///                 GND----------GND-\ (ground in)
00535 ///                              SDN-/ (shutdown in)
00536 ///                 3V3----------VCC   (3.3V in)
00537 /// interrupt 0 pin D38----------NIRQ  (interrupt request out)
00538 ///          SS pin D10----------NSEL  (chip select in)
00539 ///         SCK pin D13----------SCK   (SPI clock in)
00540 ///        MOSI pin D11----------SDI   (SPI Data in)
00541 ///        MISO pin D12----------SDO   (SPI data out)
00542 ///                           /--GPIO0 (GPIO0 out to control transmitter antenna TX_ANT)
00543 ///                           \--TX_ANT (TX antenna control in) RFM22B only
00544 ///                           /--GPIO1 (GPIO1 out to control receiver antenna RX_ANT)
00545 ///                           \--RX_ANT (RX antenna control in) RFM22B only
00546 /// \endcode
00547 /// For Teensy 3.1
00548 /// \code
00549 ///                 Teensy      RFM-22B
00550 ///                 GND----------GND-\ (ground in)
00551 ///                              SDN-/ (shutdown in)
00552 ///                 3V3----------VCC   (3.3V in)
00553 /// interrupt 2 pin D2-----------NIRQ  (interrupt request out)
00554 ///          SS pin D10----------NSEL  (chip select in)
00555 ///         SCK pin D13----------SCK   (SPI clock in)
00556 ///        MOSI pin D11----------SDI   (SPI Data in)
00557 ///        MISO pin D12----------SDO   (SPI data out)
00558 ///                           /--GPIO0 (GPIO0 out to control transmitter antenna TX_ANT)
00559 ///                           \--TX_ANT (TX antenna control in) RFM22B only
00560 ///                           /--GPIO1 (GPIO1 out to control receiver antenna RX_ANT)
00561 ///                           \--RX_ANT (RX antenna control in) RFM22B only
00562 /// \endcode
00563 /// For connecting an Arduino to an RFM23BP module. Note that the antenna control pins are reversed 
00564 /// compared to the RF22.
00565 /// \code
00566 ///                 Arduino      RFM-23BP
00567 ///                 GND----------GND-\ (ground in)
00568 ///                              SDN-/ (shutdown in)
00569 ///                 5V-----------VCC   (5V in)
00570 /// interrupt 0 pin D2-----------NIRQ  (interrupt request out)
00571 ///          SS pin D10----------NSEL  (chip select in)
00572 ///         SCK pin D13----------SCK   (SPI clock in)
00573 ///        MOSI pin D11----------SDI   (SPI Data in)
00574 ///        MISO pin D12----------SDO   (SPI data out)
00575 ///                           /--GPIO0 (GPIO0 out to control receiver antenna RXON)
00576 ///                           \--RXON   (RX antenna control in)
00577 ///                           /--GPIO1 (GPIO1 out to control transmitter antenna TXON)
00578 ///                           \--TXON   (TX antenna control in)
00579 /// \endcode
00580 ///
00581 /// and you can then use the default constructor RH_RF22(). 
00582 /// You can override the default settings for the SS pin and the interrupt 
00583 /// in the RH_RF22 constructor if you wish to connect the slave select SS to other than the normal one for your 
00584 /// Arduino (D10 for Diecimila, Uno etc and D53 for Mega)
00585 /// or the interrupt request to other than pin D2 (Caution, different processors have different constraints as to the 
00586 /// pins available for interrupts).
00587 ///
00588 /// It is possible to have 2 radios connected to one Arduino, provided each radio has its own 
00589 /// SS and interrupt line (SCK, SDI and SDO are common to both radios)
00590 ///
00591 /// Caution: on some Arduinos such as the Mega 2560, if you set the slave select pin to be other than the usual SS 
00592 /// pin (D53 on  Mega 2560), you may need to set the usual SS pin to be an output to force the Arduino into SPI 
00593 /// master mode.
00594 ///
00595 /// Caution: Power supply requirements of the RF22 module may be relevant in some circumstances: 
00596 /// RF22 modules are capable of pulling 80mA+ at full power, where Arduino's 3.3V line can
00597 /// give 50mA. You may need to make provision for alternate power supply for
00598 /// the RF22, especially if you wish to use full transmit power, and/or you have
00599 /// other shields demanding power. Inadequate power for the RF22 is reported to cause symptoms such as:
00600 /// - reset's/bootups terminate with "init failed" messages
00601 /// -random termination of communication after 5-30 packets sent/received
00602 /// -"fake ok" state, where initialization passes fluently, but communication doesn't happen
00603 /// -shields hang Arduino boards, especially during the flashing
00604 ///
00605 /// Caution: some RF22 breakout boards (such as the HAB-RFM22B-BOA  HAB-RFM22B-BO) reportedly 
00606 /// have the TX_ANT and RX_ANT pre-connected to GPIO0 and GPIO1 round the wrong way. You can work with this
00607 /// if you use setGpioReversed().
00608 ///
00609 /// Caution: If you are using a bare RF22 module without IO level shifters, you may have difficulty connecting
00610 /// to a 5V arduino. The RF22 module is 3.3V and its IO pins are 3.3V not 5V. Some Arduinos (Diecimila and
00611 /// Uno) seem to work OK with this, and some (Mega) do not always work reliably. Your Mileage May Vary.
00612 /// For best result, use level shifters, or use a RF22 shield or board with level shifters built in, 
00613 /// such as the Sparkfun RFM22 shield http://www.sparkfun.com/products/11018. 
00614 /// You could also use a 3.3V IO Arduino such as a Pro. 
00615 /// It is recognised that it is difficult to connect 
00616 /// the Sparkfun RFM22 shield to a Mega, since the SPI pins on the Mega are different to other Arduinos, 
00617 /// But it is possible, by bending the SPI pins (D10, D11, D12, D13) on the 
00618 /// shield out of the way before plugging it in to the Mega and jumpering the shield pins to the Mega like this:
00619 /// \code
00620 ///   RF22 Shield        Mega
00621 ///     D10              D53
00622 ///     D13              D52
00623 ///     D11              D51
00624 ///     D12              D50
00625 /// \endcode
00626 /// 
00627 /// \par Interrupts
00628 ///
00629 /// The Driver uses interrupts to react to events in the RF22 module, 
00630 /// such as the reception of a new packet, or the completion of transmission of a packet. 
00631 /// The RH_RF22 interrupt service routine reads status from and writes data
00632 /// to the the RF22 module via the SPI interface. It is very important therefore,
00633 /// that if you are using the RF22 library with another SPI based deviced, that you
00634 /// disable interrupts while you transfer data to and from that other device.
00635 /// Use cli() to disable interrupts and sei() to reenable them.
00636 ///
00637 /// \par SPI Interface
00638 ///
00639 /// The RF22 module uses the SPI bus to communicate with the Arduino. Arduino
00640 /// IDE includes a hardware SPI class to communicate with SPI devices using
00641 /// the SPI facilities built into the Atmel chips, over the standard designated
00642 /// SPI pins MOSI, MISO, SCK, which are usually on Arduino pins 11, 12 and 13
00643 /// respectively (or 51, 50, 52 on a Mega).
00644 ///
00645 /// By default, the RH_RF22 Driver uses the Hardware SPI interface to
00646 /// communicate with the RF22 module. However, if your RF22 SPI is connected to
00647 /// the Arduino through non-standard pins, or the standard Hardware SPI
00648 /// interface will not work for you, you can instead use a bit-banged Software
00649 /// SPI class RHSoftwareSPI, which can be configured to work on any Arduino digital IO pins.
00650 /// See the documentation of RHSoftwareSPI for details.
00651 ///
00652 /// The advantages of the Software SPI interface are that it can be used on
00653 /// any Arduino pins, not just the usual dedicated hardware pins. The
00654 /// disadvantage is that it is significantly slower then hardware.
00655 /// If you observe reliable behaviour with the default hardware SPI RHHardwareSPI, but unreliable behaviour 
00656 /// with Software SPI RHSoftwareSPI, it may be due to slow CPU performance.
00657 ///
00658 /// Initialisation example with hardware SPI
00659 /// \code
00660 /// #include <RH_RF22.h>
00661 /// RH_RF22 driver;
00662 /// RHReliableDatagram manager(driver, CLIENT_ADDRESS);
00663 /// \endcode
00664 ///
00665 /// Initialisation example with software SPI
00666 /// \code
00667 /// #include <RH_RF22.h>
00668 /// #include <RHSoftwareSPI.h>
00669 /// RHSoftwareSPI spi;
00670 /// RH_RF22 driver(10, 2, spi);
00671 /// RHReliableDatagram manager(driver, CLIENT_ADDRESS);
00672 /// \endcode
00673 ///
00674 /// \par Memory
00675 ///
00676 /// The RH_RF22 Driver requires non-trivial amounts of memory. The sample programs all compile to 
00677 /// about 9 to 14kbytes each on Arduino, which will fit in the flash proram memory of most Arduinos. However, 
00678 /// the RAM requirements are more critical. Most sample programs above will run on Duemilanova, 
00679 /// but not on Diecimila. Even on Duemilanova, the RAM requirements are very close to the 
00680 /// available memory of 2kbytes. Therefore, you should be vary sparing with RAM use in programs that use 
00681 /// the RH_RF22 Driver on Duemilanova.
00682 ///
00683 /// The sample RHRouter and RHMesh programs compile to about 14kbytes, 
00684 /// and require more RAM than the others. 
00685 /// They will not run on Duemilanova or Diecimila, but will run on Arduino Mega.
00686 ///
00687 /// It is often hard to accurately identify when you are hitting RAM limits on Arduino. 
00688 /// The symptoms can include:
00689 /// - Mysterious crashes and restarts
00690 /// - Changes in behaviour when seemingly unrelated changes are made (such as adding print() statements)
00691 /// - Hanging
00692 /// - Output from Serial.print() not appearing
00693 /// 
00694 /// With an Arduino Mega, with 8 kbytes of SRAM, there is much more RAM headroom for 
00695 /// your own elaborate programs. 
00696 /// This library is reported to work with Arduino Pro Mini, but that has not been tested by me.
00697 ///
00698 /// The RF22M modules use an inexpensive crystal to control the frequency synthesizer, and therfore you can expect 
00699 /// the transmitter and receiver frequencies to be subject to the usual inaccuracies of such crystals. The RF22
00700 /// contains an AFC circuit to compensate for differences in transmitter and receiver frequencies. 
00701 /// It does this by altering the receiver frequency during reception by up to the pull-in frequency range. 
00702 /// This RF22 library enables the AFC and by default sets the pull-in frequency range to
00703 /// 0.05MHz, which should be sufficient to handle most situations. However, if you observe unexplained packet losses
00704 /// or failure to operate correctly all the time it may be because your modules have a wider frequency difference, and
00705 /// you may need to set the afcPullInRange to a different value, using setFrequency();
00706 ///
00707 /// \par Transmitter Power
00708 ///
00709 /// You can control the transmitter power on the RF22 and RF23 transceivers
00710 /// with the RH_RF22::setTxPower() function. The argument can be any of the
00711 /// RH_RF22_TXPOW_* (for RFM22) or RH_RF22_RF23B_TXPOW_* (for RFM23) values. 
00712 /// The default is RH_RF22_TXPOW_8DBM/RH_RF22_RF23B_TXPOW_1DBM . Eg:
00713 /// \code
00714 /// driver.setTxPower(RH_RF22_TXPOW_2DBM);
00715 /// \endcode
00716 ///
00717 /// The RF23BP has higher power capability, there are
00718 /// several power settings that are specific to the RF23BP only:
00719 ///
00720 /// - RH_RF22_RF23BP_TXPOW_28DBM
00721 /// - RH_RF22_RF23BP_TXPOW_29DBM
00722 /// - RH_RF22_RF23BP_TXPOW_38DBM
00723 ///
00724 /// CAUTION: the high power settings available on the RFM23BP require
00725 /// significant power supply current.  For example at +30dBm, the typical chip
00726 /// supply current is 550mA. This will overwhelm some small CPU board power
00727 /// regulators and USB supplies. If you use this chip at high power make sure
00728 /// you have an adequate supply current providing full 5V to the RFM23BP (and
00729 /// the CPU if required), otherwise you can expect strange behaviour like
00730 /// hanging, stopping, incorrect power levels, RF power amp overheating etc.
00731 /// You must also ensure that the RFM23BP GPIO pins are connected to the
00732 /// antenna switch control pins like so:
00733 ////
00734 /// \code
00735 /// GPIO0 <-> RXON
00736 /// GPIO1 <-> TXON
00737 /// \endcode
00738 ///
00739 /// The RF output impedance of the RFM22BP module is 50 ohms.  In our
00740 /// experiments we found that the most critical issue (besides a suitable
00741 /// power supply) is to ensure that the antenna impedance is also near 50
00742 /// ohms. Connecting a simple 1/4 wavelength (ie a 17.3cm single wire)
00743 /// directly to the antenna output <b>will not work at full 30dBm power</b>,
00744 /// and will result in the transmitter hanging and/or the power amp
00745 /// overheating. Connect a proper 50 ohm impedance transmission line or
00746 /// antenna, and prevent RF radiation into the radio and arduino modules,
00747 /// in order to get full, reliable power. Our tests show that a 433MHz
00748 /// RFM23BP feeding a 50 ohm transmission line with a VHF discone antenna at
00749 /// the end results in full power output and the power amp transistor on the
00750 /// RFM22BP module runnning slightly warm but not hot. We recommend you use
00751 /// the services of a competent RF engineer when trying to use this high power
00752 /// module.
00753 ///
00754 /// Note: with RFM23BP, the reported maximum possible power when operating on 3.3V is 27dBm.
00755 ///
00756 /// We have made some actual power measurements against
00757 /// programmed power for Sparkfun RFM22 wireless module under the following conditions:
00758 /// - Sparkfun RFM22 wireless module, Duemilanove, USB power
00759 /// - 10cm RG58C/U soldered direct to RFM22 module ANT and GND
00760 /// - bnc connecteor
00761 /// - 12dB attenuator
00762 /// - BNC-SMA adapter
00763 /// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
00764 /// - Tektronix TDS220 scope to measure the Vout from power head
00765 /// \code
00766 /// Program power           Measured Power
00767 ///    dBm                         dBm
00768 ///    1                           -5.6
00769 ///    2                           -3.8
00770 ///    5                           -2.2
00771 ///    8                           -0.6
00772 ///    11                           1.2
00773 ///    14                           11.6
00774 ///    17                           14.4
00775 ///    20                           18.0
00776 /// \endcode
00777 /// (Caution: we dont claim laboratory accuracy for these measurements)
00778 /// You would not expect to get anywhere near these powers to air with a simple 1/4 wavelength wire antenna.
00779 ///
00780 /// \par Performance
00781 ///
00782 /// Some simple speed performance tests have been conducted.
00783 /// In general packet transmission rate will be limited by the modulation scheme.
00784 /// Also, if your code does any slow operations like Serial printing it will also limit performance. 
00785 /// We disabled any printing in the tests below.
00786 /// We tested with RH_RF22::GFSK_Rb125Fd125, which is probably the fastest scheme available.
00787 /// We tested with a 13 octet message length, over a very short distance of 10cm.
00788 ///
00789 /// Transmission (no reply) tests with modulation RH_RF22::GFSK_Rb125Fd125 and a 
00790 /// 13 octet message show about 330 messages per second transmitted.
00791 ///
00792 /// Transmit-and-wait-for-a-reply tests with modulation RH_RF22::GFSK_Rb125Fd125 and a 
00793 /// 13 octet message (send and receive) show about 160 round trips per second.
00794 ///
00795 /// \par Compatibility with RF22 library
00796 /// The RH_RF22 driver is based on our earlier RF22 library http://www.airspayce.com/mikem/arduino/RF22
00797 /// We have tried hard to be as compatible as possible with the earlier RF22 library, but there are some differences:
00798 /// - Different constructor.
00799 /// - Indexes for some modem configurations have changed (we recommend you use the symbolic names, not integer indexes).
00800 ///
00801 /// The major difference is that under RadioHead, you are
00802 /// required to create 2 objects (ie RH_RF22 and a manager) instead of just one object under RF22
00803 /// (ie RHMesh, RHRouter, RHReliableDatagram or RHDatagram).
00804 /// It may be sufficient or you to change for example:
00805 /// \code
00806 /// RF22ReliableDatagram rf22(CLIENT_ADDRESS);
00807 /// \endcode
00808 /// to:
00809 /// \code
00810 /// RH_RF22 driver;
00811 /// RHReliableDatagram rf22(driver, CLIENT_ADDRESS);
00812 /// \endcode
00813 /// and any instance of RF22_MAX_MESSAGE_LEN to RH_RF22_MAX_MESSAGE_LEN
00814 ///
00815 /// RadioHead version 1.6 changed the way the interrupt pin number is
00816 /// specified on Arduino and Uno32 platforms. If your code previously
00817 /// specifed a non-default interrupt pin number in the RH_RF22 constructor,
00818 /// you may need to review your code to specify the correct interrrupt pin
00819 /// (and not the interrupt number as before).
00820 class RH_RF22 : public RHSPIDriver
00821 {
00822 public:
00823 
00824     /// \brief Defines register values for a set of modem configuration registers
00825     ///
00826     /// Defines register values for a set of modem configuration registers
00827     /// that can be passed to setModemConfig()
00828     /// if none of the choices in ModemConfigChoice suit your need
00829     /// setModemConfig() writes the register values to the appropriate RH_RF22 registers
00830     /// to set the desired modulation type, data rate and deviation/bandwidth.
00831     /// Suitable values for these registers can be computed using the register calculator at
00832     /// http://www.hoperf.com/upload/rf/RF22B%2023B%2031B%2042B%2043B%20Register%20Settings_RevB1-v5.xls
00833     typedef struct
00834     {
00835     uint8_t    reg_1c;   ///< Value for register RH_RF22_REG_1C_IF_FILTER_BANDWIDTH
00836     uint8_t    reg_1f;   ///< Value for register RH_RF22_REG_1F_CLOCK_RECOVERY_GEARSHIFT_OVERRIDE
00837     uint8_t    reg_20;   ///< Value for register RH_RF22_REG_20_CLOCK_RECOVERY_OVERSAMPLING_RATE
00838     uint8_t    reg_21;   ///< Value for register RH_RF22_REG_21_CLOCK_RECOVERY_OFFSET2 
00839     uint8_t    reg_22;   ///< Value for register RH_RF22_REG_22_CLOCK_RECOVERY_OFFSET1 
00840     uint8_t    reg_23;   ///< Value for register RH_RF22_REG_23_CLOCK_RECOVERY_OFFSET0
00841     uint8_t    reg_24;   ///< Value for register RH_RF22_REG_24_CLOCK_RECOVERY_TIMING_LOOP_GAIN1
00842     uint8_t    reg_25;   ///< Value for register RH_RF22_REG_25_CLOCK_RECOVERY_TIMING_LOOP_GAIN0 
00843     uint8_t    reg_2c;   ///< Value for register RH_RF22_REG_2C_OOK_COUNTER_VALUE_1 
00844     uint8_t    reg_2d;   ///< Value for register RH_RF22_REG_2D_OOK_COUNTER_VALUE_2
00845     uint8_t    reg_2e;   ///< Value for register RH_RF22_REG_2E_SLICER_PEAK_HOLD 
00846     uint8_t    reg_58;   ///< Value for register RH_RF22_REG_58_CHARGE_PUMP_CURRENT_TRIMMING
00847     uint8_t    reg_69;   ///< Value for register RH_RF22_REG_69_AGC_OVERRIDE1 
00848     uint8_t    reg_6e;   ///< Value for register RH_RF22_REG_6E_TX_DATA_RATE1
00849     uint8_t    reg_6f;   ///< Value for register RH_RF22_REG_6F_TX_DATA_RATE0 
00850     uint8_t    reg_70;   ///< Value for register RH_RF22_REG_70_MODULATION_CONTROL1
00851     uint8_t    reg_71;   ///< Value for register RH_RF22_REG_71_MODULATION_CONTROL2
00852     uint8_t    reg_72;   ///< Value for register RH_RF22_REG_72_FREQUENCY_DEVIATION
00853     } ModemConfig;
00854   
00855     /// Choices for setModemConfig() for a selected subset of common modulation types,
00856     /// and data rates. If you need another configuration, use the register calculator.
00857     /// and call setModemRegisters() with your desired settings.
00858     /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic
00859     /// definitions and not their integer equivalents: its possible that new values will be
00860     /// introduced in later versions (though we will try to avoid it).
00861     typedef enum
00862     {
00863     UnmodulatedCarrier = 0, ///< Unmodulated carrier for testing
00864     FSK_PN9_Rb2Fd5,      ///< FSK, No Manchester, Rb = 2kbs, Fd = 5kHz, PN9 random modulation for testing
00865 
00866     FSK_Rb2Fd5,      ///< FSK, No Manchester, Rb = 2kbs,    Fd = 5kHz
00867     FSK_Rb2_4Fd36,       ///< FSK, No Manchester, Rb = 2.4kbs,  Fd = 36kHz
00868     FSK_Rb4_8Fd45,       ///< FSK, No Manchester, Rb = 4.8kbs,  Fd = 45kHz
00869     FSK_Rb9_6Fd45,       ///< FSK, No Manchester, Rb = 9.6kbs,  Fd = 45kHz
00870     FSK_Rb19_2Fd9_6,     ///< FSK, No Manchester, Rb = 19.2kbs, Fd = 9.6kHz
00871     FSK_Rb38_4Fd19_6,    ///< FSK, No Manchester, Rb = 38.4kbs, Fd = 19.6kHz
00872     FSK_Rb57_6Fd28_8,    ///< FSK, No Manchester, Rb = 57.6kbs, Fd = 28.8kHz
00873     FSK_Rb125Fd125,      ///< FSK, No Manchester, Rb = 125kbs,  Fd = 125kHz
00874     FSK_Rb_512Fd2_5,     ///< FSK, No Manchester, Rb = 512bs,  Fd = 2.5kHz, for POCSAG compatibility
00875     FSK_Rb_512Fd4_5,     ///< FSK, No Manchester, Rb = 512bs,  Fd = 4.5kHz, for POCSAG compatibility
00876 
00877     GFSK_Rb2Fd5,         ///< GFSK, No Manchester, Rb = 2kbs,    Fd = 5kHz
00878     GFSK_Rb2_4Fd36,      ///< GFSK, No Manchester, Rb = 2.4kbs,  Fd = 36kHz
00879     GFSK_Rb4_8Fd45,      ///< GFSK, No Manchester, Rb = 4.8kbs,  Fd = 45kHz
00880     GFSK_Rb9_6Fd45,      ///< GFSK, No Manchester, Rb = 9.6kbs,  Fd = 45kHz
00881     GFSK_Rb19_2Fd9_6,    ///< GFSK, No Manchester, Rb = 19.2kbs, Fd = 9.6kHz
00882     GFSK_Rb38_4Fd19_6,   ///< GFSK, No Manchester, Rb = 38.4kbs, Fd = 19.6kHz
00883     GFSK_Rb57_6Fd28_8,   ///< GFSK, No Manchester, Rb = 57.6kbs, Fd = 28.8kHz
00884     GFSK_Rb125Fd125,     ///< GFSK, No Manchester, Rb = 125kbs,  Fd = 125kHz
00885 
00886     OOK_Rb1_2Bw75,       ///< OOK, No Manchester, Rb = 1.2kbs,  Rx Bandwidth = 75kHz
00887     OOK_Rb2_4Bw335,      ///< OOK, No Manchester, Rb = 2.4kbs,  Rx Bandwidth = 335kHz
00888     OOK_Rb4_8Bw335,      ///< OOK, No Manchester, Rb = 4.8kbs,  Rx Bandwidth = 335kHz
00889     OOK_Rb9_6Bw335,      ///< OOK, No Manchester, Rb = 9.6kbs,  Rx Bandwidth = 335kHz
00890     OOK_Rb19_2Bw335,     ///< OOK, No Manchester, Rb = 19.2kbs, Rx Bandwidth = 335kHz
00891     OOK_Rb38_4Bw335,     ///< OOK, No Manchester, Rb = 38.4kbs, Rx Bandwidth = 335kHz
00892     OOK_Rb40Bw335        ///< OOK, No Manchester, Rb = 40kbs,   Rx Bandwidth = 335kHz
00893 
00894     } ModemConfigChoice;
00895 
00896     /// \brief Defines the available choices for CRC
00897     /// Types of permitted CRC polynomials, to be passed to setCRCPolynomial()
00898     /// They deliberately have the same numeric values as the crc[1:0] field of Register
00899     /// RH_RF22_REG_30_DATA_ACCESS_CONTROL
00900     typedef enum
00901     {
00902     CRC_CCITT = 0,       ///< CCITT
00903     CRC_16_IBM = 1,      ///< CRC-16 (IBM) The default used by RH_RF22 driver
00904     CRC_IEC_16 = 2,      ///< IEC-16
00905     CRC_Biacheva = 3     ///< Biacheva
00906     } CRCPolynomial;
00907 
00908     /// Constructor. You can have multiple instances, but each instance must have its own
00909     /// interrupt and slave select pin. After constructing, you must call init() to initialise the interface
00910     /// and the radio module. A maximum of 3 instances can co-exist on one processor, provided there are sufficient
00911     /// distinct interrupt lines, one for each instance.
00912     /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RH_RF22 before
00913     /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega, D10 for Maple)
00914     /// \param[in] interruptPin The interrupt Pin number that is connected to the RF22 NIRQ interrupt line. 
00915     /// Defaults to pin 2, as required by sparkfun RFM22 module shields.
00916     /// Caution: You must specify an interrupt capable pin.
00917     /// On many Arduino boards, there are limitations as to which pins may be used as interrupts.
00918     /// On Leonardo pins 0, 1, 2 or 3. On Mega2560 pins 2, 3, 18, 19, 20, 21. On Due and Teensy, any digital pin.
00919     /// On other Arduinos pins 2 or 3. 
00920     /// See http://arduino.cc/en/Reference/attachInterrupt for more details.
00921     /// On Chipkit Uno32, pins 38, 2, 7, 8, 35.
00922     /// On other boards, any digital pin may be used.
00923     /// \param[in] spi Pointer to the SPI interface object to use. 
00924     ///                Defaults to the standard Arduino hardware SPI interface
00925     RH_RF22(PINS slaveSelectPin, PINS interruptPin, RHGenericSPI& spi = hardware_spi);
00926   
00927     /// Initialises this instance and the radio module connected to it.
00928     /// The following steps are taken:
00929     /// - Initialise the slave select pin and the SPI interface library
00930     /// - Software reset the RH_RF22 module
00931     /// - Checks the connected RH_RF22 module is either a RH_RF22_DEVICE_TYPE_RX_TRX or a RH_RF22_DEVICE_TYPE_TX
00932     /// - Attaches an interrupt handler
00933     /// - Configures the RH_RF22 module
00934     /// - Sets the frequency to 434.0 MHz
00935     /// - Sets the modem data rate to FSK_Rb2_4Fd36
00936     /// \return  true if everything was successful
00937     bool        init();
00938 
00939     /// Issues a software reset to the 
00940     /// RH_RF22 module. Blocks for 1ms to ensure the reset is complete.
00941     void           reset();
00942 
00943     /// Reads and returns the device status register RH_RF22_REG_02_DEVICE_STATUS
00944     /// \return The value of the device status register
00945     uint8_t        statusRead();
00946   
00947     /// Reads a value from the on-chip analog-digital converter
00948     /// \param[in] adcsel Selects the ADC input to measure. One of RH_RF22_ADCSEL_*. Defaults to the 
00949     /// internal temperature sensor
00950     /// \param[in] adcref Specifies the refernce voltage to use. One of RH_RF22_ADCREF_*. 
00951     /// Defaults to the internal bandgap voltage.
00952     /// \param[in] adcgain Amplifier gain selection. 
00953     /// \param[in] adcoffs Amplifier offseet (0 to 15).
00954     /// \return The analog value. 0 to 255.
00955     uint8_t        adcRead(uint8_t adcsel = RH_RF22_ADCSEL_INTERNAL_TEMPERATURE_SENSOR,
00956                uint8_t adcref = RH_RF22_ADCREF_BANDGAP_VOLTAGE,
00957                uint8_t adcgain = 0, 
00958                uint8_t adcoffs = 0);
00959 
00960     /// Reads the on-chip temperature sensor
00961     /// \param[in] tsrange Specifies the temperature range to use. One of RH_RF22_TSRANGE_*
00962     /// \param[in] tvoffs Specifies the temperature value offset. This is actually signed value 
00963     /// added to the measured temperature value
00964     /// \return The measured temperature.
00965     uint8_t        temperatureRead(uint8_t tsrange = RH_RF22_TSRANGE_M64_64C, uint8_t tvoffs = 0);   
00966 
00967     /// Reads the wakeup timer value in registers RH_RF22_REG_17_WAKEUP_TIMER_VALUE1 
00968     /// and RH_RF22_REG_18_WAKEUP_TIMER_VALUE2
00969     /// \return The wakeup timer value 
00970     uint16_t       wutRead();
00971 
00972     /// Sets the wakeup timer period registers RH_RF22_REG_14_WAKEUP_TIMER_PERIOD1,
00973     /// RH_RF22_REG_15_WAKEUP_TIMER_PERIOD2 and RH_RF22_R<EG_16_WAKEUP_TIMER_PERIOD3
00974     /// \param[in] wtm Wakeup timer mantissa value
00975     /// \param[in] wtr Wakeup timer exponent R value
00976     /// \param[in] wtd Wakeup timer exponent D value
00977     void           setWutPeriod(uint16_t wtm, uint8_t wtr = 0, uint8_t wtd = 0);
00978 
00979     /// Sets the transmitter and receiver centre frequency
00980     /// \param[in] centre Frequency in MHz. 240.0 to 960.0. Caution, some versions of RH_RF22 and derivatives 
00981     /// implemented more restricted frequency ranges.
00982     /// \param[in] afcPullInRange Sets the AF Pull In Range in MHz. Defaults to 0.05MHz (50kHz). 
00983     /// Range is 0.0 to 0.159375
00984     /// for frequencies 240.0 to 480MHz, and 0.0 to 0.318750MHz for  frequencies 480.0 to 960MHz, 
00985     /// \return true if the selected frquency centre + (fhch * fhs) is within range and the afcPullInRange 
00986     /// is within range
00987     bool        setFrequency(float centre, float afcPullInRange = 0.05);
00988 
00989     /// Sets the frequency hopping step size.
00990     /// \param[in] fhs Frequency Hopping step size in 10kHz increments
00991     /// \return true if centre + (fhch * fhs) is within limits
00992     bool        setFHStepSize(uint8_t fhs);
00993 
00994     /// Sets the frequncy hopping channel. Adds fhch * fhs to centre frequency
00995     /// \param[in] fhch The channel number
00996     /// \return true if the selected frquency centre + (fhch * fhs) is within range
00997     bool        setFHChannel(uint8_t fhch);
00998 
00999     /// Reads and returns the current RSSI value from register RH_RF22_REG_26_RSSI. Caution: this is
01000     /// in internal units (see figure 31 of RFM22B/23B documentation), not in dBm. If you want to find the RSSI in dBm
01001     /// of the last received message, use lastRssi() instead.
01002     /// \return The current RSSI value 
01003     uint8_t        rssiRead();
01004 
01005     /// Reads and returns the current EZMAC value from register RH_RF22_REG_31_EZMAC_STATUS
01006     /// \return The current EZMAC value
01007     uint8_t        ezmacStatusRead();
01008 
01009     /// Sets the parameters for the RH_RF22 Idle mode in register RH_RF22_REG_07_OPERATING_MODE. 
01010     /// Idle mode is the mode the RH_RF22 will be in when not transmitting or receiving. The default idle mode 
01011     /// is RH_RF22_XTON ie READY mode. 
01012     /// \param[in] mode Mask of mode bits, using RH_RF22_SWRES, RH_RF22_ENLBD, RH_RF22_ENWT, 
01013     /// RH_RF22_X32KSEL, RH_RF22_PLLON, RH_RF22_XTON.
01014     void           setOpMode(uint8_t mode);
01015 
01016     /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running, 
01017     /// disables them.
01018     void           setModeIdle();
01019 
01020     /// If current mode is Tx or Idle, changes it to Rx. 
01021     /// Starts the receiver in the RH_RF22.
01022     void           setModeRx();
01023 
01024     /// If current mode is Rx or Idle, changes it to Rx. 
01025     /// Starts the transmitter in the RH_RF22.
01026     void           setModeTx();
01027 
01028     /// Sets the transmitter power output level in register RH_RF22_REG_6D_TX_POWER.
01029     /// Be a good neighbour and set the lowest power level you need.
01030     /// After init(), the power will be set to RH_RF22::RH_RF22_TXPOW_8DBM on RF22B
01031     /// or RH_RF22_RF23B_TXPOW_1DBM on an RF23B.
01032     /// The highest power available on RF22B is RH_RF22::RH_RF22_TXPOW_20DBM (20dBm).
01033     /// The highest power available on RF23B is RH_RF22::RH_RF22_RF23B_TXPOW_13DBM (13dBm).
01034     /// Higher powers are available on RF23BP (using RH_RF22_RF23BP_TXPOW_*), 
01035     /// and then only with an adequate power supply. See comments above.
01036     /// Caution: In some countries you may only select certain higher power levels if you
01037     /// are also using frequency hopping. Make sure you are aware of the legal
01038     /// limitations and regulations in your region.
01039     /// \param[in] power Transmitter power level, one of RH_RF22_*TXPOW_*
01040     void           setTxPower(uint8_t power);
01041 
01042     /// Sets all the registered required to configure the data modem in the RH_RF22, including the data rate, 
01043     /// bandwidths etc. You cas use this to configure the modem with custom configuraitons if none of the 
01044     /// canned configurations in ModemConfigChoice suit you.
01045     /// \param[in] config A ModemConfig structure containing values for the modem configuration registers.
01046     void           setModemRegisters(const ModemConfig* config);
01047 
01048     /// Select one of the predefined modem configurations. If you need a modem configuration not provided 
01049     /// here, use setModemRegisters() with your own ModemConfig.
01050     /// \param[in] index The configuration choice.
01051     /// \return true if index is a valid choice.
01052     bool        setModemConfig(ModemConfigChoice index);
01053 
01054     /// Starts the receiver and checks whether a received message is available.
01055     /// This can be called multiple times in a timeout loop
01056     /// \return true if a complete, valid message has been received and is able to be retrieved by
01057     /// recv()
01058     bool        available();
01059 
01060     /// Turns the receiver on if it not already on.
01061     /// If there is a valid message available, copy it to buf and return true
01062     /// else return false.
01063     /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
01064     /// You should be sure to call this function frequently enough to not miss any messages
01065     /// It is recommended that you call it in your main loop.
01066     /// \param[in] buf Location to copy the received message
01067     /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.
01068     /// \return true if a valid message was copied to buf
01069     bool        recv(uint8_t* buf, uint8_t* len);
01070 
01071     /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
01072     /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
01073     /// of 0 is NOT permitted. 
01074     /// \param[in] data Array of data to be sent
01075     /// \param[in] len Number of bytes of data to send (> 0)
01076     /// \return true if the message length was valid and it was correctly queued for transmit
01077     bool        send(const uint8_t* data, uint8_t len);
01078 
01079     /// Sets the length of the preamble
01080     /// in 4-bit nibbles. 
01081     /// Caution: this should be set to the same 
01082     /// value on all nodes in your network. Default is 8.
01083     /// Sets the message preamble length in RH_RF22_REG_34_PREAMBLE_LENGTH
01084     /// \param[in] nibbles Preamble length in nibbles of 4 bits each.  
01085     void           setPreambleLength(uint8_t nibbles);
01086 
01087     /// Sets the sync words for transmit and receive in registers RH_RF22_REG_36_SYNC_WORD3 
01088     /// to RH_RF22_REG_39_SYNC_WORD0
01089     /// Caution: SyncWords should be set to the same 
01090     /// value on all nodes in your network. Nodes with different SyncWords set will never receive
01091     /// each others messages, so different SyncWords can be used to isolate different
01092     /// networks from each other. Default is { 0x2d, 0xd4 }.
01093     /// \param[in] syncWords Array of sync words, 1 to 4 octets long
01094     /// \param[in] len Number of sync words to set, 1 to 4.
01095     void           setSyncWords(const uint8_t* syncWords, uint8_t len);
01096 
01097     /// Tells the receiver to accept messages with any TO address, not just messages
01098     /// addressed to thisAddress or the broadcast address
01099     /// \param[in] promiscuous true if you wish to receive messages with any TO address
01100     virtual void   setPromiscuous(bool promiscuous);
01101 
01102     /// Sets the CRC polynomial to be used to generate the CRC for both receive and transmit
01103     /// otherwise the default of CRC_16_IBM will be used.
01104     /// \param[in] polynomial One of RH_RF22::CRCPolynomial choices CRC_*
01105     /// \return true if polynomial is a valid option for this radio.
01106     bool setCRCPolynomial(CRCPolynomial polynomial);
01107 
01108     /// Configures GPIO pins for reversed GPIO connections to the antenna switch.
01109     /// Normally on RF22 modules, GPIO0(out) is connected to TX_ANT(in) to enable tx antenna during transmit
01110     /// and GPIO1(out) is connected to RX_ANT(in) to enable rx antenna during receive. The RH_RF22 driver
01111     /// configures the GPIO pins during init() so the antenna switch works as expected.
01112     /// However, some RF22 modules, such as HAB-RFM22B-BOA HAB-RFM22B-BO, also Si4432 sold by Dorji.com via Tindie.com
01113     /// have these GPIO pins reversed, so that GPIO0 is connected to RX_ANT.
01114     /// Call this function with a true argument after init() and before transmitting
01115     /// in order to configure the module for reversed GPIO pins.
01116     /// \param[in] gpioReversed Set to true if your RF22 module has reversed GPIO antenna switch connections.
01117     void setGpioReversed(bool gpioReversed = false);
01118 
01119     /// Returns the time in millis since the last preamble was received, and when the last
01120     /// RSSI measurement was made.
01121     uint32_t getLastPreambleTime();
01122 
01123     /// The maximum message length supported by this driver
01124     /// \return The maximum message length supported by this driver
01125     uint8_t maxMessageLength();
01126 
01127     /// Sets the radio into low-power sleep mode.
01128     /// If successful, the transport will stay in sleep mode until woken by 
01129     /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)
01130     /// Caution: there is a time penalty as the radio takes a finite time to wake from sleep mode.
01131     /// \return true if sleep mode was successfully entered.
01132     virtual bool    sleep();
01133 
01134 protected:
01135     /// This is a low level function to handle the interrupts for one instance of RH_RF22.
01136     /// Called automatically by isr*()
01137     /// Should not need to be called.
01138     void           handleInterrupt();
01139 
01140     /// Clears the receiver buffer.
01141     /// Internal use only
01142     void           clearRxBuf();
01143 
01144     /// Clears the transmitter buffer
01145     /// Internal use only
01146     void           clearTxBuf();
01147 
01148     /// Fills the transmitter buffer with the data of a mesage to be sent
01149     /// \param[in] data Array of data bytes to be sent (1 to 255)
01150     /// \param[in] len Number of data bytes in data (> 0)
01151     /// \return true if the message length is valid
01152     bool           fillTxBuf(const uint8_t* data, uint8_t len);
01153 
01154     /// Appends the transmitter buffer with the data of a mesage to be sent
01155     /// \param[in] data Array of data bytes to be sent (0 to 255)
01156     /// \param[in] len Number of data bytes in data
01157     /// \return false if the resulting message would exceed RH_RF22_MAX_MESSAGE_LEN, else true
01158     bool           appendTxBuf(const uint8_t* data, uint8_t len);
01159 
01160     /// Internal function to load the next fragment of 
01161     /// the current message into the transmitter FIFO
01162     /// Internal use only
01163     void           sendNextFragment();
01164 
01165     ///  function to copy the next fragment from 
01166     /// the receiver FIF) into the receiver buffer
01167     void           readNextFragment();
01168 
01169     /// Clears the RF22 Rx and Tx FIFOs
01170     /// Internal use only
01171     void           resetFifos();
01172 
01173     /// Clears the RF22 Rx FIFO
01174     /// Internal use only
01175     void           resetRxFifo();
01176 
01177     /// Clears the RF22 Tx FIFO
01178     /// Internal use only
01179     void           resetTxFifo();
01180 
01181     /// This function will be called by handleInterrupt() if an RF22 external interrupt occurs. 
01182     /// This can only happen if external interrupts are enabled in the RF22 
01183     /// (which they are not by default). 
01184     /// Subclasses may override this function to get control when an RF22 external interrupt occurs. 
01185     virtual void   handleExternalInterrupt();
01186 
01187     /// This function will be called by handleInterrupt() if an RF22 wakeup timer interrupt occurs. 
01188     /// This can only happen if wakeup timer interrupts are enabled in theRF22 
01189     /// (which they are not by default). 
01190     /// Subclasses may override this function to get control when an RF22 wakeup timer interrupt occurs. 
01191     virtual void   handleWakeupTimerInterrupt();
01192 
01193     /// Start the transmission of the contents 
01194     /// of the Tx buffer
01195     void           startTransmit();
01196 
01197     /// ReStart the transmission of the contents 
01198     /// of the Tx buffer after a atransmission failure
01199     void           restartTransmit();
01200 
01201     void           setThisAddress(uint8_t thisAddress);
01202 
01203     /// Sets the radio operating mode for the case when the driver is idle (ie not
01204     /// transmitting or receiving), allowing you to control the idle mode power requirements
01205     /// at the expense of slower transitions to transmit and receive modes.
01206     /// By default, the idle mode is RH_RF22_XTON,
01207     /// but eg setIdleMode(RH_RF22_PLL) will provide a much lower
01208     /// idle current but slower transitions. Call this function after init().
01209     /// \param[in] idleMode The chip operating mode to use when the driver is idle. One of the valid definitions for RH_RF22_REG_07_OPERATING_MODE
01210     void setIdleMode(uint8_t idleMode);
01211 
01212 protected:
01213     /// Low level interrupt service routine for RF22 connected to interrupt 0
01214     static void         isr0();
01215 
01216     /// Low level interrupt service routine for RF22 connected to interrupt 1
01217     static void         isr1();
01218 
01219     /// Low level interrupt service routine for RF22 connected to interrupt 1
01220     static void         isr2();
01221 
01222     /// Array of instances connected to interrupts 0 and 1
01223     static RH_RF22*     _deviceForInterrupt[];
01224 
01225     /// Index of next interrupt number to use in _deviceForInterrupt
01226     static uint8_t      _interruptCount;
01227 
01228 #if (RH_PLATFORM == RH_PLATFORM_MBED)
01229     /// The configured interrupt pin connected to this instance
01230     InterruptIn             _interruptPin;
01231 #else
01232     /// The configured interrupt pin connected to this instance
01233     uint8_t             _interruptPin;
01234 #endif
01235 
01236     /// The index into _deviceForInterrupt[] for this device (if an interrupt is already allocated)
01237     /// else 0xff
01238     uint8_t             _myInterruptIndex;
01239 
01240     /// The radio mode to use when mode is idle
01241     uint8_t             _idleMode; 
01242 
01243     /// The device type reported by the RF22
01244     uint8_t             _deviceType;
01245 
01246     /// The selected CRC polynomial
01247     CRCPolynomial       _polynomial;
01248 
01249     // These volatile members may get changed in the interrupt service routine
01250     /// Number of octets in the receiver buffer
01251     volatile uint8_t    _bufLen;
01252     
01253     /// The receiver buffer
01254     uint8_t             _buf[RH_RF22_MAX_MESSAGE_LEN];
01255 
01256     /// True when there is a valid message in the Rx buffer
01257     volatile bool       _rxBufValid;
01258 
01259     /// Index into TX buffer of the next to send chunk
01260     volatile uint8_t    _txBufSentIndex;
01261   
01262     /// Time in millis since the last preamble was received (and the last time the RSSI was measured)
01263     uint32_t            _lastPreambleTime;
01264 };
01265 
01266 /// @example rf22_client.pde
01267 /// @example rf22_server.pde
01268 
01269 #endif