Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Tue Jul 12 2022 18:05:55 by
