├── .gitignore ├── library.properties ├── PacketFifo.h ├── keywords.txt ├── PacketFifo.cpp ├── README.md ├── SerialCommand.h ├── SerialCommand.cpp ├── FeatherM0_Davis_ISS_rx.ino ├── DavisRFM69.h ├── DavisRFM69.cpp └── RFM69registers.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Object files 2 | *.o 3 | *.ko 4 | *.obj 5 | *.elf 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Libraries 12 | *.lib 13 | *.a 14 | *.la 15 | *.lo 16 | 17 | # Shared objects (inc. Windows DLLs) 18 | *.dll 19 | *.so 20 | *.so.* 21 | *.dylib 22 | 23 | # Executables 24 | *.exe 25 | *.out 26 | *.app 27 | *.i*86 28 | *.x86_64 29 | *.hex 30 | 31 | # Debug files 32 | *.dSYM/ 33 | *.su 34 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=FeatherM0_Davis_ISS_rx 2 | version=1.0.0 3 | author=Alan Marchiori 4 | maintainer=Alan Marchiori 5 | sentence=Receive packets from Davis ISS weather station with an Adafruit Feather M0 + RFM69 6 | paragraph=Receive packets from Davis ISS weather station with an Adafruit Feather M0 + RFM69
7 | category=Communication 8 | url=https://github.com/HydroSense/FeatherM0_Davis_ISS_rx 9 | architectures=avr, sam 10 | -------------------------------------------------------------------------------- /PacketFifo.h: -------------------------------------------------------------------------------- 1 | #ifndef _PACKETFIFO_H 2 | #define _PACKETFIFO_H 3 | 4 | #include 5 | 6 | #define FIFO_SIZE 8 7 | #define PACKET_LEN 10 8 | 9 | struct __attribute__((packed)) RadioData { 10 | byte packet[PACKET_LEN]; 11 | byte channel; 12 | byte rssi; 13 | int16_t fei; 14 | uint32_t delta; 15 | }; 16 | 17 | class PacketFifo { 18 | public: 19 | bool queue(byte* packet, byte channel, byte rssi, int16_t fei, uint32_t delta); 20 | RadioData* dequeue(); 21 | void flush(); 22 | bool hasElements(); 23 | 24 | private: 25 | RadioData packetFifo[FIFO_SIZE]; 26 | byte packetIn, packetOut, qLen; 27 | }; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map 3 | ####################################### 4 | # Class 5 | ####################################### 6 | 7 | DavisRFM69 KEYWORD1 GSM 8 | GSMVoiceCall KEYWORD1 GSMVCSConstructor 9 | GSM_SMS KEYWORD1 GSMSMSConstructor 10 | GPRS KEYWORD1 GPRSConstructor 11 | GSMClient KEYWORD1 GSMClientConstructor 12 | GSMServer KEYWORD1 GSMServerConstructor 13 | GSMModem KEYWORD1 GSMModemConstructor 14 | GSMScanner KEYWORD1 GSMScannerConstructor 15 | GSMPIN KEYWORD1 GSMPINConstructor 16 | GSMBand KEYWORD1 GSMBandConstructor 17 | 18 | ####################################### 19 | # Methods and Functions 20 | ####################################### 21 | 22 | 23 | ####################################### 24 | # Constants 25 | ####################################### 26 | 27 | SM_IDLE LITERAL1 28 | SM_SEARCHING LITERAL1 29 | SM_SYNCHRONIZED LITERAL1 30 | SM_RECEIVING LITERAL1 31 | -------------------------------------------------------------------------------- /PacketFifo.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "PacketFifo.h" 3 | 4 | bool PacketFifo::queue(byte* packet, byte channel, byte rssi, int16_t fei, uint32_t delta) { 5 | if (qLen < FIFO_SIZE) { 6 | memcpy(&packetFifo[packetIn].packet, packet, PACKET_LEN); 7 | packetFifo[packetIn].channel = channel; 8 | packetFifo[packetIn].rssi = rssi; 9 | packetFifo[packetIn].fei = fei; 10 | packetFifo[packetIn].delta = delta; 11 | if (++packetIn == FIFO_SIZE) packetIn = 0; 12 | qLen++; 13 | return true; 14 | } else { 15 | return false; 16 | } 17 | } 18 | 19 | RadioData* PacketFifo::dequeue() { 20 | if (qLen > 0) { 21 | qLen--; 22 | RadioData* rv = &packetFifo[packetOut]; 23 | if (++packetOut == FIFO_SIZE) packetOut = 0; 24 | return rv; 25 | } else { 26 | return NULL; 27 | } 28 | } 29 | 30 | void PacketFifo::flush() { 31 | packetIn = packetOut = qLen = 0; 32 | } 33 | 34 | bool PacketFifo::hasElements() { 35 | return qLen > 0; 36 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Intro 2 | ----- 3 | Source modified from [kobuki's VPTools](https://github.com/kobuki/VPTools) to run on the Adafruit Feather M0 board by Alan Marchiori. 4 | 5 | The main modification was to poll the radio rather than use a timer because timers the M0 are not yet well supported by Arduino (and/or me). 6 | 7 | The file FeatherM0_Davis_ISS_rx.ino is based on VPTools ISSRx sketch and shows how to receive ISS packets. I did not port the other sketches by kobuki. 8 | 9 | Indications 10 | ----------- 11 | Led flashing rapidly = searching for a station. 12 | One short led flash = packet received from ISS. 13 | Led off = in sync with all stations and currently sleeping or waiting for a packet from the ISS. 14 | 15 | Notes 16 | ------------- 17 | The main radio poll loop was rewritten to be polled from the arduino main loop. When in sync with all stations, the radio is put into standby when possible to save power. The radio is turned on just before a station is expected to transmit. This should help reduce power consumption on battery powered systems. However, I only have one ISS so was not able to verify this works as expected with multiple stations. 18 | 19 | License 20 | ------- 21 | Portions of this code are GNU GPL and others are CC-BY-SA, see the individual files for details. 22 | 23 | Modified from VPTools 24 | ------- 25 | 26 | VPTools is a Davis(TM) weather station compatible transceiver library. It is a work in progress. It can receive from multiple RF transmitters (ISS, ATK, etc.) It tries to serve as a basis for similar hobby projects. Example sketches provide simple, parseable and RAW packet output among others. 27 | 28 | * The ISSRx sketch is a receiver with a simple interface configurable in source code. 29 | * The AnemometerTX sketch is a simple anemometer transmitter for Davis anemometers. It's a work in progress and needs optimisations for low power operation, but can serve as a base for doing so. It can easily be adapted to emulate any Davis transmitter. 30 | * The WxReceiver sketch is a receiver compatible with the [WeeWx driver](https://github.com/matthewwall/weewx-meteostick) written by Matthew Wall et al for the Meteostick. 31 | 32 | Originally based on [code by DeKay](https://github.com/dekay/DavisRFM69) - for technical details on packet formats, etc. see his (now outdated) [wiki](https://github.com/dekay/DavisRFM69/wiki) and the source code of this repo. 33 | -------------------------------------------------------------------------------- /SerialCommand.h: -------------------------------------------------------------------------------- 1 | /** 2 | * SerialCommand - A Wiring/Arduino library to tokenize and parse commands 3 | * received over a serial port. 4 | * 5 | * Copyright (C) 2012 Stefan Rado 6 | * Copyright (C) 2011 Steven Cogswell 7 | * http://husks.wordpress.com 8 | * 9 | * Version 20120522 10 | * 11 | * This library is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Lesser General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This library is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Lesser General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with this library. If not, see . 23 | */ 24 | #ifndef SerialCommand_h 25 | #define SerialCommand_h 26 | 27 | #if defined(WIRING) && WIRING >= 100 28 | #include 29 | #elif defined(ARDUINO) && ARDUINO >= 100 30 | #include 31 | #else 32 | #include 33 | #endif 34 | #include 35 | 36 | // Size of the input buffer in bytes (maximum length of one command plus arguments) 37 | #define SERIALCOMMAND_BUFFER 32 38 | // Maximum length of a command excluding the terminating null 39 | #define SERIALCOMMAND_MAXCOMMANDLENGTH 8 40 | #define SERIALCOMMAND_MAXCOMMANDS 10 41 | 42 | // Uncomment the next line to run the library in debug mode (verbose messages) 43 | //#define SERIALCOMMAND_DEBUG 44 | 45 | 46 | class SerialCommand { 47 | public: 48 | SerialCommand(); // Constructor 49 | void addCommand(const char *command, void(*function)()); // Add a command to the processing dictionary. 50 | void setDefaultHandler(void (*function)(const char *)); // A handler to call when no valid command received. 51 | 52 | void readSerial(); // Main entry point. 53 | void clearBuffer(); // Clears the input buffer. 54 | char *next(); // Returns pointer to next token found in command buffer (for getting arguments to commands). 55 | void enableEcho(bool value); 56 | 57 | private: 58 | // Command/handler dictionary 59 | struct SerialCommandCallback { 60 | char command[SERIALCOMMAND_MAXCOMMANDLENGTH + 1]; 61 | void (*function)(); 62 | }; // Data structure to hold Command/Handler function key-value pairs 63 | SerialCommandCallback commandList[SERIALCOMMAND_MAXCOMMANDS]; // Actual definition for command/handler array 64 | byte commandCount; 65 | bool echo; 66 | 67 | // Pointer to the default handler function 68 | void (*defaultHandler)(const char *); 69 | 70 | char delim[2]; // null-terminated list of character to be used as delimeters for tokenizing (default " ") 71 | char term; // Character that signals end of command (default '\n') 72 | 73 | char buffer[SERIALCOMMAND_BUFFER + 1]; // Buffer of stored characters while waiting for terminator character 74 | byte bufPos; // Current position in the buffer 75 | char *last; // State variable used by strtok_r during processing 76 | }; 77 | 78 | #endif //SerialCommand_h 79 | -------------------------------------------------------------------------------- /SerialCommand.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * SerialCommand - A Wiring/Arduino library to tokenize and parse commands 3 | * received over a serial port. 4 | * 5 | * Copyright (C) 2012 Stefan Rado 6 | * Copyright (C) 2011 Steven Cogswell 7 | * http://husks.wordpress.com 8 | * 9 | * Version 20120522 10 | * 11 | * This library is free software: you can redistribute it and/or modify 12 | * it under the terms of the GNU Lesser General Public License as published by 13 | * the Free Software Foundation, either version 3 of the License, or 14 | * (at your option) any later version. 15 | * 16 | * This library is distributed in the hope that it will be useful, 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | * GNU Lesser General Public License for more details. 20 | * 21 | * You should have received a copy of the GNU General Public License 22 | * along with this library. If not, see . 23 | */ 24 | #include "SerialCommand.h" 25 | 26 | /** 27 | * Constructor makes sure some things are set. 28 | */ 29 | SerialCommand::SerialCommand() 30 | : commandCount(0), 31 | defaultHandler(NULL), 32 | term('\r'), // default terminator for commands, newline character 33 | last(NULL), 34 | echo(true) 35 | { 36 | strcpy(delim, " "); // strtok_r needs a null-terminated string 37 | clearBuffer(); 38 | } 39 | 40 | /** 41 | * Adds a "command" and a handler function to the list of available commands. 42 | * This is used for matching a found token in the buffer, and gives the pointer 43 | * to the handler function to deal with it. 44 | */ 45 | void SerialCommand::addCommand(const char *command, void (*function)()) { 46 | strncpy(commandList[commandCount].command, command, SERIALCOMMAND_MAXCOMMANDLENGTH); 47 | commandList[commandCount].function = function; 48 | commandCount++; 49 | } 50 | 51 | /** 52 | * This sets up a handler to be called in the event that the receveived command string 53 | * isn't in the list of commands. 54 | */ 55 | void SerialCommand::setDefaultHandler(void (*function)(const char *)) { 56 | defaultHandler = function; 57 | } 58 | 59 | 60 | /** 61 | * This checks the Serial stream for characters, and assembles them into a buffer. 62 | * When the terminator character (default '\n') is seen, it starts parsing the 63 | * buffer for a prefix command, and calls handlers setup by addCommand() member 64 | */ 65 | void SerialCommand::readSerial() { 66 | while (Serial.available() > 0) { 67 | char inChar = Serial.read(); // Read single available character, there may be more waiting 68 | if (echo) Serial.print(inChar); 69 | if (inChar == term) { // Check for the terminator (default '\r') meaning end of command 70 | Serial.print('\n'); 71 | char *command = strtok_r(buffer, delim, &last); // Search for command at start of buffer 72 | if (command != NULL) { 73 | boolean matched = false; 74 | for (int i = 0; i < commandCount; i++) { 75 | // Compare the found command against the list of known commands for a match 76 | if (strncmp(command, commandList[i].command, SERIALCOMMAND_MAXCOMMANDLENGTH) == 0) { 77 | // Execute the stored handler function for the command 78 | (*commandList[i].function)(); 79 | matched = true; 80 | break; 81 | } 82 | } 83 | if (!matched && (defaultHandler != NULL)) { 84 | (*defaultHandler)(command); 85 | } 86 | } 87 | clearBuffer(); 88 | } 89 | else if (isprint(inChar)) { // Only printable characters into the buffer 90 | if (bufPos < SERIALCOMMAND_BUFFER) { 91 | buffer[bufPos++] = inChar; // Put character into buffer 92 | buffer[bufPos] = '\0'; // Null terminate 93 | } 94 | } 95 | } 96 | } 97 | 98 | /* 99 | * Clear the input buffer. 100 | */ 101 | void SerialCommand::clearBuffer() { 102 | buffer[0] = '\0'; 103 | bufPos = 0; 104 | } 105 | 106 | /** 107 | * Retrieve the next token ("word" or "argument") from the command buffer. 108 | * Returns NULL if no more tokens exist. 109 | */ 110 | char *SerialCommand::next() { 111 | return strtok_r(NULL, delim, &last); 112 | } 113 | 114 | void SerialCommand::enableEcho(bool value) { 115 | echo = value; 116 | } 117 | -------------------------------------------------------------------------------- /FeatherM0_Davis_ISS_rx.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | //#include 5 | 6 | #include 7 | 8 | #include 9 | 10 | #include "DavisRFM69.h" 11 | #include "PacketFifo.h" 12 | 13 | #define LED 13 14 | #define SERIAL_BAUD 19200 15 | 16 | DavisRFM69 radio(8, 3, true, 3); 17 | 18 | // id, type, active 19 | Station stations[1] = { 20 | { .id = 0, 21 | .type = STYPE_VUE, 22 | .active = true} 23 | }; 24 | 25 | void setup() { 26 | Serial.begin(SERIAL_BAUD); 27 | delay(1000); 28 | 29 | pinMode(LED, OUTPUT); 30 | digitalWrite(LED, LOW); 31 | 32 | radio.setStations(stations, 1); 33 | radio.initialize(FREQ_BAND_US); 34 | //radio.setBandwidth(RF69_DAVIS_BW_NARROW); 35 | radio.setBandwidth(RF69_DAVIS_BW_WIDE); 36 | 37 | Serial.println("Boot complete!"); 38 | } 39 | 40 | 41 | void loop() { 42 | 43 | /* 44 | static uint32_t last_print = 0; 45 | 46 | if (millis() - last_print > 1000){ 47 | // print performance DC stats 48 | uint32_t sum = 0; 49 | for (uint8_t i = 0; i < COUNT_RF69_MODES; i++){ 50 | sum += radio.rfm69_mode_counts[i]; 51 | } 52 | for (uint8_t i = 0; i < COUNT_RF69_MODES; i++){ 53 | Serial.print(RFM69_MODE_STRINGS[i]); 54 | Serial.print(": "); 55 | Serial.print(radio.rfm69_mode_counts[i]); 56 | Serial.print(" "); 57 | Serial.print(radio.rfm69_mode_counts[i]/ (sum / 100.0)); 58 | Serial.println("\%"); 59 | } 60 | 61 | last_print = millis(); 62 | } 63 | */ 64 | if (radio.fifo.hasElements()) { 65 | decode_packet(radio.fifo.dequeue()); 66 | } 67 | 68 | if (radio.mode == SM_RECEIVING) { 69 | digitalWrite(LED, HIGH); 70 | } else if (radio.mode == SM_SEARCHING){ 71 | Blink(LED, 15); 72 | Blink(LED, 15); 73 | Blink(LED, 15); 74 | delay(100); 75 | }else{ 76 | digitalWrite(LED, LOW); 77 | } 78 | 79 | radio.loop(); 80 | 81 | } 82 | 83 | void Blink(byte PIN, int DELAY_MS) 84 | { 85 | pinMode(PIN, OUTPUT); 86 | digitalWrite(PIN,HIGH); 87 | delay(DELAY_MS); 88 | digitalWrite(PIN,LOW); 89 | } 90 | 91 | void print_value(char* vname, char* value, const __FlashStringHelper* sep) { 92 | Serial.print(vname); Serial.print(F(":")); Serial.print(value); Serial.print(sep); 93 | } 94 | 95 | void print_value(char* vname, int value, const __FlashStringHelper* sep) { 96 | Serial.print(vname); Serial.print(F(":")); Serial.print(value); Serial.print(sep); 97 | } 98 | 99 | void print_value(char* vname, float value, const __FlashStringHelper* sep) { 100 | Serial.print(vname); Serial.print(F(":")); Serial.print(value, 1); Serial.print(sep); 101 | } 102 | 103 | void print_value(char* vname, long value, const __FlashStringHelper* sep) { 104 | Serial.print(vname); Serial.print(F(":")); Serial.print(value); Serial.print(sep); 105 | } 106 | 107 | void print_value(char* vname, uint32_t value, const __FlashStringHelper* sep) { 108 | Serial.print(vname); Serial.print(F(":")); Serial.print(value); Serial.print(sep); 109 | } 110 | 111 | void decode_packet(RadioData* rd) { 112 | 113 | // for more about the protocol see: 114 | // https://github.com/dekay/DavisRFM69/wiki/Message-Protocol 115 | int val; 116 | byte* packet = rd->packet; 117 | 118 | Serial.print(F("raw:")); 119 | printHex(packet, 10); 120 | Serial.print(F(", ")); 121 | print_value("station", packet[0] & 0x7, F(", ")); 122 | 123 | 124 | Serial.print(F("packets:")); 125 | Serial.print(radio.packets); 126 | Serial.print('/'); 127 | Serial.print(radio.lostPackets); 128 | Serial.print('/'); 129 | Serial.print((float)(radio.packets * 100.0 / (radio.packets + radio.lostPackets))); 130 | Serial.print(F(", ")); 131 | 132 | print_value("channel", rd->channel, F(", ")); 133 | print_value("rssi", -rd->rssi, F(", ")); 134 | 135 | print_value("batt", (char*)(packet[0] & 0x8 ? "err" : "ok"), F(", ")); 136 | 137 | // All packet payload values are printed unconditionally, either properly 138 | // calculated or flagged with a special "missing sensor" value, mostly -1. 139 | // It's the CPE's responsibility to interpret our output accordingly. 140 | 141 | byte id = radio.DATA[0] & 7; 142 | int stIx = radio.findStation(id); 143 | 144 | // wind data is present in every packet, windd == 0 (packet[2] == 0) means there's no anemometer 145 | if (packet[2] != 0) { 146 | if (stations[stIx].type == STYPE_VUE) { 147 | val = (packet[2] << 1) | (packet[4] & 2) >> 1; 148 | val = round(val * 360 / 512); 149 | } else { 150 | val = 9 + round((packet[2] - 1) * 342.0 / 255.0); 151 | } 152 | } else { 153 | val = 0; 154 | } 155 | print_value("windv", packet[1], F(", ")); 156 | print_value("winddraw", packet[2], F(", ")); 157 | print_value("windd", val, F(", ")); 158 | 159 | switch (packet[0] >> 4) { 160 | 161 | case VP2P_UV: 162 | val = word(packet[3], packet[4]) >> 6; 163 | if (val < 0x3ff) { 164 | print_value("uv", (float)(val / 50.0), F(", ")); 165 | } else { 166 | print_value("uv", -1, F(", ")); 167 | } 168 | break; 169 | 170 | case VP2P_SOLAR: 171 | val = word(packet[3], packet[4]) >> 6; 172 | if (val < 0x3fe) { 173 | print_value("solar", (float)(val * 1.757936), F(", ")); 174 | } else { 175 | print_value("solar", -1, F(", ")); 176 | } 177 | break; 178 | 179 | case VP2P_RAIN: 180 | if (packet[3] == 0x80) { 181 | print_value("rain", -1, F(", ")); 182 | } else { 183 | print_value("rain", packet[3], F(", ")); 184 | } 185 | break; 186 | 187 | case VP2P_RAINSECS: 188 | // light rain: byte4[5:4] as value[9:8] and byte3[7:0] as value[7:0] - 10 bits total 189 | // strong rain: byte4[5:4] as value[5:4] and byte3[7:4] as value[3:0] - 6 bits total 190 | val = (packet[4] & 0x30) << 4 | packet[3]; 191 | if (val == 0x3ff) { 192 | print_value("rainsecs", -1, F(", ")); 193 | } else { 194 | if ((packet[4] & 0x40) == 0) val >>= 4; // packet[4] bit 6: strong == 0, light == 1 195 | print_value("rainsecs", val, F(", ")); 196 | } 197 | break; 198 | 199 | case VP2P_TEMP: 200 | //if (packet[3] == 0xff) { 201 | // print_value("temp", -100, F(", ")); 202 | //} else { 203 | { 204 | //val = (int)packet[3] << 4 | packet[4] >> 4; 205 | //val = (packet[3]* 256 + packet[4]) / 160; 206 | val = ((int16_t)((packet[3]<<8) | packet[4])) / 16; 207 | print_value("temp", (float)(val / 10.0), F(", ")); 208 | } 209 | break; 210 | 211 | case VP2P_HUMIDITY: 212 | val = ((packet[4] >> 4) << 8 | packet[3]) / 10; // 0 -> no sensor 213 | print_value("rh", (float)val, F(", ")); 214 | break; 215 | 216 | case VP2P_WINDGUST: 217 | print_value("windgust", packet[3], F(", ")); 218 | // gustref is the index of the last message 9 packet containing the gust (max wind speed). 219 | if (packet[3] != 0) { 220 | print_value("gustref", packet[5] & 0xf0 >> 4, F(", ")); 221 | } 222 | break; 223 | 224 | case VP2P_SOIL_LEAF: 225 | // currently not processed but algorithm is known 226 | // see https://github.com/matthewwall/weewx-meteostick/blob/master/bin/user/meteostick.py 227 | print_value("soilleaf", -1, F(", ")); 228 | break; 229 | 230 | case VUEP_VCAP: 231 | val = (packet[3] << 2) | (packet[4] & 0xc0) >> 6; 232 | print_value("vcap", (float)(val / 100.0), F(", ")); 233 | break; 234 | 235 | case VUEP_VSOLAR: 236 | val = (packet[3] << 2) | (packet[4] & 0xc0) >> 6; 237 | print_value("vsolar", (float)(val / 100.0), F(", ")); 238 | } 239 | 240 | print_value("fei", round(rd->fei * RF69_FSTEP / 1000), F(", ")); 241 | print_value("delta", rd->delta, F("")); 242 | 243 | Serial.println(); 244 | } 245 | 246 | void printHex(volatile byte* packet, byte len) { 247 | for (byte i = 0; i < len; i++) { 248 | if (!(packet[i] & 0xf0)) Serial.print('0'); 249 | Serial.print(packet[i], HEX); 250 | if (i < len - 1) Serial.print('-'); 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /DavisRFM69.h: -------------------------------------------------------------------------------- 1 | // Driver definition for HopeRF RFM69W/RFM69HW, Semtech SX1231/1231H used for 2 | // compatibility with the frequency hopped, spread spectrum signals from a Davis Instrument 3 | // wireless Integrated Sensor Suite (ISS) 4 | // 5 | // This is part of the DavisRFM69 library from https://github.com/dekay/DavisRFM69 6 | // (C) DeKay 2014 dekaymail@gmail.com 7 | // 8 | // As I consider this to be a derived work from the RFM69W library from LowPowerLab, 9 | // it is released under the same Creative Commons Attrib Share-Alike License 10 | // You are free to use/extend this library but please abide with the CC-BY-SA license: 11 | // http://creativecommons.org/licenses/by-sa/3.0/ 12 | // 13 | // In accordance with the CC-BY-SA, many modifications by GitHub user "kobuki". 14 | 15 | #ifndef DAVISRFM69_h 16 | #define DAVISRFM69_h 17 | 18 | #include //assumes Arduino IDE v1.0 or greater 19 | 20 | #include "PacketFifo.h" 21 | 22 | #define DAVIS_PACKET_LEN 10 // ISS has fixed packet lengths of eight bytes, including CRC and trailing repeater info 23 | #define SPI_CS SS // SS is the SPI slave select pin, for instance D10 on atmega328 24 | 25 | #define RF69_SPI_CS 8 26 | 27 | //#define RF69_IRQ_PIN 2 // INT0 on AVRs should be connected to DIO0 (ex on Atmega328 it's D2) 28 | // INT0 on AVRs should be connected to RFM69's DIO0 (ex on ATmega328 it's D2, on ATmega644/1284 it's D2) 29 | #if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__) 30 | #define RF69_IRQ_PIN 2 31 | #define RF69_IRQ_NUM 0 32 | #elif defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284P__) 33 | #define RF69_IRQ_PIN 2 34 | #define RF69_IRQ_NUM 2 35 | #elif defined(__AVR_ATmega32U4__) 36 | #define RF69_IRQ_PIN 3 37 | #define RF69_IRQ_NUM 0 38 | #else 39 | // for Adafruit Feather M0 Radio 40 | #define RF69_IRQ_PIN 3 41 | #define RF69_IRQ_NUM 3 42 | #endif 43 | 44 | #define CSMA_LIMIT -100 // upper RX signal sensitivity threshold in dBm for carrier sense access 45 | #define RF69_MODE_SLEEP 0 // XTAL OFF 46 | #define RF69_MODE_STANDBY 1 // XTAL ON 47 | #define RF69_MODE_SYNTH 2 // PLL ON 48 | #define RF69_MODE_RX 3 // RX MODE 49 | #define RF69_MODE_TX 4 // TX MODE 50 | #define RF69_MODE_INIT 0xff // USED ONLY FOR INIT THIS IS NOT VALID OTHERWISE 51 | #define COUNT_RF69_MODES 5 // Number of distinct radio modes (for stats tracking) 52 | 53 | static const __attribute__((progmem)) char RFM69_MODE_STRINGS[COUNT_RF69_MODES][8] = { 54 | "SLEEP", 55 | "STANDBY", 56 | "SYNTH", 57 | "RX", 58 | "TX" 59 | }; 60 | 61 | #define RF69_DAVIS_BW_NARROW 1 62 | #define RF69_DAVIS_BW_WIDE 2 63 | 64 | #define null 0 65 | #define COURSE_TEMP_COEF -90 // puts the temperature reading in the ballpark, user can fine tune the returned value 66 | #define RF69_FSTEP 61.03515625 // == FXOSC/2^19 = 32mhz/2^19 (p13 in DS) 67 | 68 | #define RESYNC_THRESHOLD 50 // max. number of lost packets from a station before rediscovery 69 | #define LATE_PACKET_THRESH 5000 // packet is considered missing after this many micros 70 | #define POST_RX_WAIT 2000 // RX "settle" delay 71 | #define MAX_STATIONS 8 // max. stations this code is able to handle 72 | 73 | #define TUNEIN_USEC 10000L // 10 milliseconds, amount of time before an expect TX to tune the radio in. 74 | // this includes possible radio turnaround tx->rx or sleep->rx transitions 75 | // 10 ms is reliable, should be able to get this faster but 76 | // the loop is polled, so slow loop calls will cause missed packets 77 | 78 | #define DISCOVERY_MINGAP 70000L // 70 milliseconds 79 | #define DISCOVERY_GUARD 60000L // 60 milliseconds 80 | #define DISCOVERY_STEP 150000000L // 150 seconds 81 | 82 | /** DavisRFM69 state machine modes */ 83 | enum sm_mode { 84 | SM_IDLE = 0, // no stations configured 85 | SM_SEARCHING = 1, // searching for station(s) 86 | SM_SYNCHRONIZED = 2, // in sync with all stations 87 | SM_RECEIVING = 3, // receiving from a station 88 | }; 89 | 90 | // Station data structure for managing radio reception 91 | typedef struct __attribute__((packed)) Station { 92 | byte id; // station ID (set with the DIP switch on original equipment) 93 | // set it ONE LESS than advertised station id, eg. 0 for station 1 (default) etc. 94 | byte type; // STYPE_XXX station type, eg. ISS, standalone anemometer transmitter, etc. 95 | bool active; // true when the station is actively listened and will queue packets 96 | byte repeaterId; // repeater id when packet is coming via a repeater, otherwise 0 97 | // repeater IDs A..H are stored as 0x8..0xf here 98 | 99 | uint32_t lastRx; // last time a packet is seen or should have been seen when missed 100 | uint32_t lastSeen; // last factual reception time 101 | uint32_t interval; // packet transmit interval for the station: (41 + id) / 16 * 1M microsecs 102 | uint32_t numResyncs; // number of times discovery of this station started because of packet loss 103 | uint32_t packets; // total number of received packets after (re)restart 104 | uint32_t missedPackets; // total number of misssed packets after (re)restart 105 | uint32_t lostPackets; // missed packets since a packet was last seen from this station 106 | uint32_t syncBegan; // time sync began for this station. 107 | uint32_t recvBegan; // time we tuned in to receive 108 | uint32_t earlyAmt; // microseconds from when we turned on rx to when the last packet was rx'ed (for tuning, we want this small) 109 | byte progress; // search(sync) progress in percent. 110 | byte channel; // rx channel the next packet of the station is expected on (moved by amm for packing on 32 bit machines) 111 | }; 112 | 113 | class DavisRFM69 { 114 | public: 115 | static volatile byte DATA[DAVIS_PACKET_LEN]; // recv/xmit buf, including header, CRC, and RSSI value 116 | static volatile byte _mode; //should be protected? 117 | static volatile bool _packetReceived; 118 | static volatile byte CHANNEL; 119 | static volatile int RSSI; 120 | static volatile int16_t FEI; 121 | static volatile byte band; 122 | 123 | static volatile uint32_t packets; 124 | static volatile uint32_t lostPackets; 125 | static volatile uint32_t numResyncs; 126 | static volatile uint32_t lostStations; 127 | static volatile byte stationsFound; 128 | static volatile byte curStation; 129 | static volatile byte numStations; 130 | static volatile byte hopIndex; 131 | static volatile byte discChannel; 132 | static volatile uint32_t lastDiscStep; 133 | static volatile uint32_t int_ticks; 134 | 135 | volatile uint32_t rfm69_mode_timer; 136 | volatile uint32_t rfm69_mode_counts[COUNT_RF69_MODES]; 137 | 138 | 139 | static PacketFifo fifo; 140 | static Station *stations; 141 | 142 | static enum sm_mode mode; 143 | 144 | 145 | DavisRFM69(byte slaveSelectPin=SPI_CS, byte interruptPin=RF69_IRQ_PIN, bool isRFM69HW=false, byte interruptNum=RF69_IRQ_NUM) { 146 | _slaveSelectPin = slaveSelectPin; 147 | _interruptPin = interruptPin; 148 | _interruptNum = interruptNum; 149 | _mode = RF69_MODE_STANDBY; 150 | _packetReceived = false; 151 | _powerLevel = 31; 152 | _isRFM69HW = isRFM69HW; 153 | } 154 | 155 | void setChannel(byte channel); 156 | void hop(); 157 | static uint16_t crc16_ccitt(volatile byte *buf, byte len, uint16_t initCrc = 0); 158 | 159 | void initialize(byte freqBand); 160 | bool canSend(); 161 | void send(const void* buffer); 162 | bool receiveDone(); 163 | void setFrequency(uint32_t FRF); 164 | void setCS(byte newSPISlaveSelect); 165 | int readRSSI(bool forceTrigger=false); 166 | void setHighPower(bool onOFF=true); //have to call it after initialize for RFM69HW 167 | void setPowerLevel(byte level); //reduce/increase transmit power level 168 | void sleep(); 169 | byte readTemperature(byte calFactor=0); //get CMOS temperature (8bit) 170 | void rcCalibration(); //calibrate the internal RC oscillator for use in wide temperature variations - see datasheet section [4.3.5. RC Timer Accuracy] 171 | 172 | // allow hacking registers by making these public 173 | byte readReg(byte addr); 174 | void writeReg(byte addr, byte val); 175 | void readAllRegs(); 176 | void setTxMode(bool txMode); 177 | void setBand(byte newBand); 178 | void setBandwidth(byte bw); 179 | byte getBandTabLength(); 180 | 181 | byte nextChannel(byte channel); 182 | int findStation(byte id); 183 | void handleRadioInt(); 184 | 185 | uint32_t difftime(uint32_t after, uint32_t before); 186 | void loop(); // like handleRadioInt but for systems that want to poll rather than run a hardware timer to tick the radio system. 187 | 188 | void initStations(); 189 | void nextStation(); 190 | 191 | static void handleTimerInt(); 192 | 193 | static void setStations(Station *_stations, byte n); 194 | void stopReceiver(); 195 | void setRssiThreshold(int rssiThreshold); 196 | void setRssiThresholdRaw(int rssiThresholdRaw); 197 | 198 | protected: 199 | static volatile bool txMode; 200 | void (*userInterrupt)(); 201 | 202 | void virtual interruptHandler(); 203 | void sendFrame(const void* buffer); 204 | byte reverseBits(byte b); 205 | 206 | static void isr0(); 207 | 208 | static DavisRFM69* selfPointer; 209 | byte _slaveSelectPin; 210 | byte _interruptPin; 211 | byte _interruptNum; 212 | byte _powerLevel; 213 | bool _isRFM69HW; 214 | 215 | void receiveBegin(); 216 | void setMode(byte mode); 217 | void setHighPowerRegs(bool onOff); 218 | void select(); 219 | void unselect(); 220 | }; 221 | 222 | // FRF_MSB, FRF_MID, and FRF_LSB for the 51 North American, Australian, New Zealander & 5 European channels 223 | // used by Davis in frequency hopping 224 | 225 | #define FREQ_TABLE_LENGTH_US 51 226 | #define FREQ_TABLE_LENGTH_AU 51 227 | #define FREQ_TABLE_LENGTH_EU 5 228 | #define FREQ_TABLE_LENGTH_NZ 51 229 | 230 | #define FREQ_BAND_US 0 231 | #define FREQ_BAND_AU 1 232 | #define FREQ_BAND_EU 2 233 | #define FREQ_BAND_NZ 3 234 | 235 | typedef uint8_t FRF_ITEM[3]; 236 | 237 | static const __attribute__((progmem)) FRF_ITEM FRF_US[FREQ_TABLE_LENGTH_US] = 238 | { 239 | {0xE3, 0xDA, 0x7C}, 240 | {0xE1, 0x98, 0x71}, 241 | {0xE3, 0xFA, 0x92}, 242 | {0xE6, 0xBD, 0x01}, 243 | {0xE4, 0xBB, 0x4D}, 244 | {0xE2, 0x99, 0x56}, 245 | {0xE7, 0x7D, 0xBC}, 246 | {0xE5, 0x9C, 0x0E}, 247 | {0xE3, 0x39, 0xE6}, 248 | {0xE6, 0x1C, 0x81}, 249 | {0xE4, 0x5A, 0xE8}, 250 | {0xE1, 0xF8, 0xD6}, 251 | {0xE5, 0x3B, 0xBF}, 252 | {0xE7, 0x1D, 0x5F}, 253 | {0xE3, 0x9A, 0x3C}, 254 | {0xE2, 0x39, 0x00}, 255 | {0xE4, 0xFB, 0x77}, 256 | {0xE6, 0x5C, 0xB2}, 257 | {0xE2, 0xD9, 0x90}, 258 | {0xE7, 0xBD, 0xEE}, 259 | {0xE4, 0x3A, 0xD2}, 260 | {0xE1, 0xD8, 0xAA}, 261 | {0xE5, 0x5B, 0xCD}, 262 | {0xE6, 0xDD, 0x34}, 263 | {0xE3, 0x5A, 0x0A}, 264 | {0xE7, 0x9D, 0xD9}, 265 | {0xE2, 0x79, 0x41}, 266 | {0xE4, 0x9B, 0x28}, 267 | {0xE5, 0xDC, 0x40}, 268 | {0xE7, 0x3D, 0x74}, 269 | {0xE1, 0xB8, 0x9C}, 270 | {0xE3, 0xBA, 0x60}, 271 | {0xE6, 0x7C, 0xC8}, 272 | {0xE4, 0xDB, 0x62}, 273 | {0xE2, 0xB9, 0x7A}, 274 | {0xE5, 0x7B, 0xE2}, 275 | {0xE7, 0xDE, 0x12}, 276 | {0xE6, 0x3C, 0x9D}, 277 | {0xE3, 0x19, 0xC9}, 278 | {0xE4, 0x1A, 0xB6}, 279 | {0xE5, 0xBC, 0x2B}, 280 | {0xE2, 0x18, 0xEB}, 281 | {0xE6, 0xFD, 0x42}, 282 | {0xE5, 0x1B, 0xA3}, 283 | {0xE3, 0x7A, 0x2E}, 284 | {0xE5, 0xFC, 0x64}, 285 | {0xE2, 0x59, 0x16}, 286 | {0xE6, 0x9C, 0xEC}, 287 | {0xE2, 0xF9, 0xAC}, 288 | {0xE4, 0x7B, 0x0C}, 289 | {0xE7, 0x5D, 0x98} 290 | }; 291 | 292 | static const __attribute__((progmem)) FRF_ITEM FRF_AU[FREQ_TABLE_LENGTH_AU] = 293 | { 294 | {0xE5, 0x84, 0xDD}, 295 | {0xE6, 0x43, 0x43}, 296 | {0xE7, 0x1F, 0xCE}, 297 | {0xE6, 0x7F, 0x7C}, 298 | {0xE5, 0xD5, 0x0E}, 299 | {0xE7, 0x5B, 0xF7}, 300 | {0xE6, 0xC5, 0x81}, 301 | {0xE6, 0x07, 0x2B}, 302 | {0xE6, 0xED, 0xA1}, 303 | {0xE6, 0x61, 0x58}, 304 | {0xE5, 0xA3, 0x02}, 305 | {0xE6, 0xA7, 0x8D}, 306 | {0xE7, 0x3D, 0xB2}, 307 | {0xE6, 0x25, 0x3F}, 308 | {0xE5, 0xB7, 0x0A}, 309 | {0xE6, 0x93, 0x85}, 310 | {0xE7, 0x01, 0xDB}, 311 | {0xE5, 0xE9, 0x26}, 312 | {0xE7, 0x70, 0x00}, 313 | {0xE6, 0x57, 0x6C}, 314 | {0xE5, 0x98, 0xF5}, 315 | {0xE6, 0xB1, 0x99}, 316 | {0xE7, 0x29, 0xDB}, 317 | {0xE6, 0x11, 0x37}, 318 | {0xE7, 0x65, 0xE3}, 319 | {0xE5, 0xCB, 0x33}, 320 | {0xE6, 0x75, 0x60}, 321 | {0xE6, 0xD9, 0xA9}, 322 | {0xE7, 0x47, 0xDF}, 323 | {0xE5, 0x8E, 0xF9}, 324 | {0xE6, 0x2F, 0x4B}, 325 | {0xE7, 0x0B, 0xB6}, 326 | {0xE6, 0x89, 0x68}, 327 | {0xE5, 0xDF, 0x2B}, 328 | {0xE6, 0xBB, 0xA5}, 329 | {0xE7, 0x79, 0xFB}, 330 | {0xE6, 0xF7, 0xAE}, 331 | {0xE5, 0xFD, 0x2F}, 332 | {0xE6, 0x4D, 0x4F}, 333 | {0xE6, 0xCF, 0x8D}, 334 | {0xE5, 0xAD, 0x0E}, 335 | {0xE7, 0x33, 0xD7}, 336 | {0xE6, 0x9D, 0x91}, 337 | {0xE6, 0x1B, 0x33}, 338 | {0xE6, 0xE3, 0xA5}, 339 | {0xE5, 0xC1, 0x16}, 340 | {0xE7, 0x15, 0xC2}, 341 | {0xE5, 0xF3, 0x33}, 342 | {0xE6, 0x6B, 0x64}, 343 | {0xE7, 0x51, 0xDB}, 344 | {0xE6, 0x39, 0x58} 345 | }; 346 | 347 | static const __attribute__((progmem)) FRF_ITEM FRF_EU[FREQ_TABLE_LENGTH_EU] = 348 | { 349 | {0xD9, 0x04, 0x45}, 350 | {0xD9, 0x13, 0x04}, 351 | {0xD9, 0x21, 0xC2}, 352 | {0xD9, 0x0B, 0xA4}, 353 | {0xD9, 0x1A, 0x63} 354 | }; 355 | 356 | static const __attribute__((progmem)) FRF_ITEM FRF_NZ[FREQ_TABLE_LENGTH_NZ] = 357 | { 358 | {0xE6, 0x45, 0x0E}, 359 | {0xE7, 0x43, 0xC7}, 360 | {0xE6, 0xF4, 0xAC}, 361 | {0xE6, 0x9C, 0xEE}, 362 | {0xE7, 0xA4, 0x7B}, 363 | {0xE6, 0xC0, 0x31}, 364 | {0xE7, 0xD0, 0x52}, 365 | {0xE7, 0x20, 0x93}, 366 | {0xE6, 0x68, 0x31}, 367 | {0xE7, 0x67, 0x0A}, 368 | {0xE6, 0xDA, 0x5E}, 369 | {0xE7, 0xE1, 0xEC}, 370 | {0xE7, 0x8A, 0x0C}, 371 | {0xE6, 0x82, 0xA0}, 372 | {0xE7, 0x0F, 0x1B}, 373 | {0xE7, 0xBE, 0xE9}, 374 | {0xE6, 0xB7, 0x3B}, 375 | {0xE7, 0x4C, 0x6A}, 376 | {0xE7, 0xFC, 0x5A}, 377 | {0xE6, 0x4D, 0xF4}, 378 | {0xE7, 0x92, 0xD1}, 379 | {0xE6, 0xEB, 0xF8}, 380 | {0xE6, 0x94, 0x39}, 381 | {0xE7, 0xEA, 0xC1}, 382 | {0xE7, 0x29, 0x79}, 383 | {0xE6, 0x5F, 0x7D}, 384 | {0xE7, 0x5E, 0x35}, 385 | {0xE6, 0xC8, 0xC5}, 386 | {0xE7, 0xB6, 0x25}, 387 | {0xE6, 0xA5, 0xB2}, 388 | {0xE6, 0xFD, 0x81}, 389 | {0xE7, 0x6F, 0xCF}, 390 | {0xE6, 0x79, 0xCB}, 391 | {0xE7, 0x9B, 0xB6}, 392 | {0xE7, 0x32, 0x2D}, 393 | {0xE7, 0xC7, 0x7D}, 394 | {0xE6, 0x8B, 0x54}, 395 | {0xE7, 0x81, 0x37}, 396 | {0xE6, 0xD1, 0x89}, 397 | {0xE7, 0x55, 0x60}, 398 | {0xE7, 0xD9, 0x17}, 399 | {0xE6, 0x56, 0xA8}, 400 | {0xE7, 0x06, 0x35}, 401 | {0xE7, 0xAD, 0x2F}, 402 | {0xE6, 0xAE, 0x77}, 403 | {0xE7, 0x3B, 0x12}, 404 | {0xE7, 0xF3, 0x85}, 405 | {0xE6, 0x71, 0x06}, 406 | {0xE7, 0x17, 0xCF}, 407 | {0xE6, 0xE3, 0x12}, 408 | {0xE7, 0x78, 0xA4} 409 | }; 410 | 411 | static const FRF_ITEM *bandTab[4] = { 412 | FRF_US, 413 | FRF_AU, 414 | FRF_EU, 415 | FRF_NZ 416 | }; 417 | 418 | static const uint8_t bandTabLengths[4] = { 419 | FREQ_TABLE_LENGTH_US, 420 | FREQ_TABLE_LENGTH_AU, 421 | FREQ_TABLE_LENGTH_EU, 422 | FREQ_TABLE_LENGTH_NZ 423 | }; 424 | 425 | // added these here because upstream removed them 426 | #define REG_TESTAFC 0x71 427 | 428 | #define RF_FDEVMSB_9900 0x00 429 | #define RF_FDEVLSB_9900 0xa1 430 | 431 | #define RF_AFCLOWBETA_ON 0x20 432 | #define RF_AFCLOWBETA_OFF 0x00 // Default 433 | 434 | // Davis VP2 standalone station types 435 | #define STYPE_ISS 0x0 // ISS 436 | #define STYPE_TEMP_ONLY 0x1 // Temperature Only Station 437 | #define STYPE_HUM_ONLY 0x2 // Humidity Only Station 438 | #define STYPE_TEMP_HUM 0x3 // Temperature/Humidity Station 439 | #define STYPE_WLESS_ANEMO 0x4 // Wireless Anemometer Station 440 | #define STYPE_RAIN 0x5 // Rain Station 441 | #define STYPE_LEAF 0x6 // Leaf Station 442 | #define STYPE_SOIL 0x7 // Soil Station 443 | #define STYPE_SOIL_LEAF 0x8 // Soil/Leaf Station 444 | #define STYPE_SENSORLINK 0x9 // SensorLink Station (not supported for the VP2) 445 | #define STYPE_OFF 0xA // No station OFF 446 | #define STYPE_VUE 0x10 // pseudo station type for the Vue ISS 447 | // since the Vue also has a type of 0x0 448 | 449 | // Below are known, publicly documented packet types for the VP2 and the Vue. 450 | 451 | // VP2 packet types 452 | #define VP2P_UV 0x4 // UV index 453 | #define VP2P_RAINSECS 0x5 // seconds between rain bucket tips 454 | #define VP2P_SOLAR 0x6 // solar irradiation 455 | #define VP2P_TEMP 0x8 // outside temperature 456 | #define VP2P_WINDGUST 0x9 // 10-minute wind gust 457 | #define VP2P_HUMIDITY 0xA // outside humidity 458 | #define VP2P_RAIN 0xE // rain bucket tips counter 459 | #define VP2P_SOIL_LEAF 0xF // soil/leaf station 460 | 461 | // Vue packet types 462 | #define VUEP_VCAP 0x2 // supercap voltage 463 | #define VUEP_VSOLAR 0x7 // solar panel voltage 464 | 465 | #endif // DAVISRFM_h 466 | -------------------------------------------------------------------------------- /DavisRFM69.cpp: -------------------------------------------------------------------------------- 1 | // Driver implementation for HopeRF RFM69W/RFM69HW, Semtech SX1231/1231H used for 2 | // compatibility with the frequency hopped, spread spectrum signals from a Davis Instrument 3 | // wireless Integrated Sensor Suite (ISS) 4 | // 5 | // Modified for the Adafruit feather M0 by Alan Marchiori 2016 amm042@bucknell.edu. 6 | // 7 | // This is part of the DavisRFM69 library from https://github.com/dekay/DavisRFM69 8 | // (C) DeKay 2014 dekaymail@gmail.com 9 | // 10 | // As I consider this to be a derived work for now from the RFM69W library from LowPowerLab, 11 | // it is released under the same Creative Commons Attrib Share-Alike License 12 | // You are free to use/extend this library but please abide with the CC-BY-SA license: 13 | // http://creativecommons.org/licenses/by-sa/3.0/ 14 | // 15 | // In accordance with the CC-BY-SA, many modifications by GitHub user "kobuki". 16 | 17 | #include "DavisRFM69.h" 18 | #include "RFM69registers.h" 19 | //#include "TimerOne.h" 20 | //#include "Adafruit_ZeroTimer.h" 21 | #include "PacketFifo.h" 22 | 23 | #include 24 | 25 | //#define DAVISRFM69_DEBUG 26 | 27 | volatile byte DavisRFM69::DATA[DAVIS_PACKET_LEN]; 28 | volatile byte DavisRFM69::_mode = RF69_MODE_INIT; // current transceiver state 29 | volatile bool DavisRFM69::_packetReceived = false; 30 | volatile byte DavisRFM69::CHANNEL = 0; 31 | volatile byte DavisRFM69::band = 0; 32 | volatile int DavisRFM69::RSSI = 0; // RSSI measured immediately after payload reception 33 | volatile int16_t DavisRFM69::FEI = 0; 34 | volatile bool DavisRFM69::txMode = false; 35 | 36 | volatile uint32_t DavisRFM69::packets = 0; 37 | volatile uint32_t DavisRFM69::lostPackets = 0; 38 | volatile uint32_t DavisRFM69::numResyncs = 0; 39 | volatile uint32_t DavisRFM69::lostStations = 0; 40 | volatile byte DavisRFM69::stationsFound = 0; 41 | volatile byte DavisRFM69::curStation = 0; 42 | volatile byte DavisRFM69::numStations = 0; 43 | volatile byte DavisRFM69::discChannel = 0; 44 | volatile uint32_t DavisRFM69::lastDiscStep; 45 | volatile uint32_t DavisRFM69::int_ticks = 0; 46 | volatile uint32_t rfm69_mode_counts[COUNT_RF69_MODES] = {}; 47 | volatile uint32_t rfm69_mode_timer = 0; 48 | 49 | enum sm_mode DavisRFM69::mode = SM_IDLE; 50 | PacketFifo DavisRFM69::fifo; 51 | Station *DavisRFM69::stations; 52 | DavisRFM69* DavisRFM69::selfPointer; 53 | 54 | //Adafruit_ZeroTimer zt = Adafruit_ZeroTimer(6); 55 | 56 | void DavisRFM69::initialize(byte freqBand) 57 | { 58 | const byte CONFIG[][2] = 59 | { 60 | /* 0x01 */ { REG_OPMODE, RF_OPMODE_SEQUENCER_ON | RF_OPMODE_LISTEN_OFF | RF_OPMODE_STANDBY }, 61 | /* 0x02 */ { REG_DATAMODUL, RF_DATAMODUL_DATAMODE_PACKET | RF_DATAMODUL_MODULATIONTYPE_FSK | RF_DATAMODUL_MODULATIONSHAPING_10 }, // Davis uses Gaussian shaping with BT=0.5 62 | /* 0x03 */ { REG_BITRATEMSB, RF_BITRATEMSB_19200}, // Davis uses a datarate of 19.2 KBPS 63 | /* 0x04 */ { REG_BITRATELSB, RF_BITRATELSB_19200}, 64 | /* 0x05 */ { REG_FDEVMSB, RF_FDEVMSB_9900}, // Davis uses a deviation of 9.9 kHz 65 | /* 0x06 */ { REG_FDEVLSB, RF_FDEVLSB_9900}, 66 | /* 0x07 to 0x09 are REG_FRFMSB to LSB. No sense setting them here. Done in main routine. 67 | /* 0x0B */ { REG_AFCCTRL, RF_AFCLOWBETA_OFF }, // TODO: Should use LOWBETA_ON, but having trouble getting it working 68 | /* 0x12 */ { REG_PARAMP, RF_PARAMP_25 }, // xxx 69 | // looks like PA1 and PA2 are not implemented on RFM69W, hence the max output power is 13dBm 70 | // +17dBm and +20dBm are possible on RFM69HW 71 | // +13dBm formula: Pout=-18+OutputPower (with PA0 or PA1**) 72 | // +17dBm formula: Pout=-14+OutputPower (with PA1 and PA2)** 73 | // +20dBpaym formula: Pout=-11+OutputPower (with PA1 and PA2)** and high power PA settings (section 3.3.7 in datasheet) 74 | ///* 0x11 */ { REG_PALEVEL, RF_PALEVEL_PA0_ON | RF_PALEVEL_PA1_OFF | RF_PALEVEL_PA2_OFF | RF_PALEVEL_OUTPUTPOWER_11111}, 75 | ///* 0x13 */ { REG_OCP, RF_OCP_ON | RF_OCP_TRIM_95 }, //over current protection (default is 95mA) 76 | /* 0x18 */ { REG_LNA, RF_LNA_ZIN_50 | RF_LNA_GAINSELECT_AUTO }, // Not sure which is correct! 77 | // REG_RXBW 50 kHz fixes console retransmit reception but seems worse for SIM transmitters (to be confirmed with more testing) 78 | // Defaulting to narrow BW, since console retransmits are rarely used - use setBandwidth() to change this 79 | /* 0x19 */ { REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_20 | RF_RXBW_EXP_4 }, // Use 25 kHz BW (BitRate < 2 * RxBw) 80 | /* 0x1A */ { REG_AFCBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_20 | RF_RXBW_EXP_3 }, // Use double the bandwidth during AFC as reception 81 | /* 0x1B - 0x1D These registers are for OOK. Not used */ 82 | /* 0x1E */ { REG_AFCFEI, RF_AFCFEI_AFCAUTOCLEAR_ON | RF_AFCFEI_AFCAUTO_ON }, 83 | /* 0x1F & 0x20 AFC MSB and LSB values, respectively */ 84 | /* 0x21 & 0x22 FEI MSB and LSB values, respectively */ 85 | /* 0x23 & 0x24 RSSI MSB and LSB values, respectively */ 86 | /* 0x25 */ { REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01 }, //DIO0 is the only IRQ we're using 87 | /* 0x26 RegDioMapping2 */ 88 | /* 0x27 RegIRQFlags1 */ 89 | /* 0x28 */ { REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN }, // Reset the FIFOs. Fixes a problem I had with bad first packet. 90 | /* 0x29 */ { REG_RSSITHRESH, 190 }, // real dBm = -(REG_RSSITHRESH / 2) -> 190 raw = -95 dBm 91 | /* 0x2a & 0x2b RegRxTimeout1 and 2, respectively */ 92 | /* 0x2c RegPreambleMsb - use zero default */ 93 | /* 0x2d */ { REG_PREAMBLELSB, 0x4 }, // Davis has four preamble bytes 0xAAAAAAAA -- use 6 for TX for this setup 94 | /* 0x2e */ { REG_SYNCCONFIG, RF_SYNC_ON | RF_SYNC_FIFOFILL_AUTO | RF_SYNC_SIZE_2 | RF_SYNC_TOL_2 }, // Allow a couple erros in the sync word 95 | /* 0x2f */ { REG_SYNCVALUE1, 0xcb }, // Davis ISS first sync byte. http://madscientistlabs.blogspot.ca/2012/03/first-you-get-sugar.html 96 | /* 0x30 */ { REG_SYNCVALUE2, 0x89 }, // Davis ISS second sync byte. 97 | /* 0x31 - 0x36 REG_SYNCVALUE3 - 8 not used */ 98 | /* 0x37 */ { REG_PACKETCONFIG1, RF_PACKET1_FORMAT_FIXED | RF_PACKET1_DCFREE_OFF | RF_PACKET1_CRC_OFF | RF_PACKET1_CRCAUTOCLEAR_OFF | RF_PACKET1_ADRSFILTERING_OFF }, // Fixed packet length and we'll check our own CRC 99 | /* 0x38 */ { REG_PAYLOADLENGTH, DAVIS_PACKET_LEN }, // Davis sends 8 bytes of payload, including CRC that we check manually. 100 | //* 0x39 */ { REG_NODEADRS, nodeID }, // Turned off because we're not using address filtering 101 | //* 0x3a */ { REG_BROADCASTADRS, RF_BROADCASTADDRESS_VALUE }, // Not using this 102 | /* 0x3b REG_AUTOMODES - Automatic modes are not used in this implementation. */ 103 | /* 0x3c */ { REG_FIFOTHRESH, RF_FIFOTHRESH_TXSTART_FIFOTHRESH | 0x07 }, // TX on FIFO having more than seven bytes 104 | /* 0x3d */ { REG_PACKETCONFIG2, RF_PACKET2_RXRESTARTDELAY_2BITS | RF_PACKET2_AUTORXRESTART_ON | RF_PACKET2_AES_OFF }, //RXRESTARTDELAY must match transmitter PA ramp-down time (bitrate dependent) 105 | /* 0x3e - 0x4d AES Key not used in this implementation */ 106 | /* 0x6F */ { REG_TESTDAGC, RF_DAGC_IMPROVED_LOWBETA0 }, // // TODO: Should use LOWBETA_ON, but having trouble getting it working 107 | /* 0x71 */ { REG_TESTAFC, 0 }, // AFC Offset for low mod index systems 108 | {255, 0} 109 | }; 110 | 111 | digitalWrite(_slaveSelectPin, HIGH); 112 | pinMode(_slaveSelectPin, OUTPUT); 113 | //SPI.setDataMode(SPI_MODE0); 114 | //SPI.setBitOrder(MSBFIRST); 115 | //SPI.setClockDivider(SPI_CLOCK_DIV8); //max speed, except on Due which can run at system clock speed 116 | SPI.begin(); 117 | 118 | 119 | do writeReg(REG_SYNCVALUE1, 0xaa); while (readReg(REG_SYNCVALUE1) != 0xaa); 120 | do writeReg(REG_SYNCVALUE1, 0x55); while (readReg(REG_SYNCVALUE1) != 0x55); 121 | 122 | for (byte i = 0; CONFIG[i][0] != 255; i++) 123 | writeReg(CONFIG[i][0], CONFIG[i][1]); 124 | 125 | setHighPower(_isRFM69HW); //called regardless if it's a RFM69W or RFM69HW 126 | setMode(RF69_MODE_STANDBY); 127 | while ((readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); // Wait for ModeReady 128 | attachInterrupt(_interruptNum, DavisRFM69::isr0, RISING); 129 | 130 | selfPointer = this; 131 | userInterrupt = NULL; 132 | 133 | mode = SM_IDLE; 134 | 135 | setBand(freqBand); 136 | setChannel(discChannel); 137 | 138 | fifo.flush(); 139 | initStations(); 140 | lastDiscStep = micros(); 141 | 142 | //Timer1.initialize(2000L); // periodical interrupts every 2 ms for missed packet detection and other checks 143 | //Timer1.attachInterrupt(DavisRFM69::handleTimerInt, 0); 144 | 145 | /* 146 | Serial.println("About to enable timer."); 147 | Serial.flush(); 148 | delay(500); 149 | 150 | enum status_code sc = zt.configure (TC_CLOCK_PRESCALER_DIV8, 151 | TC_COUNTER_SIZE_16BIT, 152 | TC_WAVE_GENERATION_NORMAL_FREQ 153 | ); 154 | Serial.print("config status: "); 155 | Serial.print(sc == STATUS_OK); 156 | Serial.print(" "); 157 | Serial.println(sc); 158 | 159 | //zt4.setPeriodMatch(12000, 1, 0); 160 | zt.setCallback(true, TC_CALLBACK_OVERFLOW, DavisRFM69::handleTimerInt); 161 | zt.enable(true); 162 | */ 163 | } 164 | 165 | void DavisRFM69::stopReceiver() { 166 | //Timer1.detachInterrupt(); 167 | //zt.enable(false); 168 | setMode(RF69_MODE_SLEEP); 169 | mode = SM_IDLE; 170 | } 171 | 172 | void DavisRFM69::setStations(Station *_stations, byte n) { 173 | stations = _stations; 174 | numStations = n; 175 | } 176 | 177 | /** 178 | * compute a 32bit time difference assuming the first argument 179 | * happend after the second. (ie accounting for wrap around). 180 | */ 181 | uint32_t DavisRFM69::difftime(uint32_t after, uint32_t before){ 182 | if (after >= before){ 183 | return after - before; 184 | } else { 185 | // counter wrapped 186 | return (0xffffffff - before) + after + 1; 187 | } 188 | } 189 | 190 | /** 191 | * Called by the main arduino loop, used when not using a timer (handleTimerInt) 192 | * this will check for lost packets and tune the radio to the proper channel 193 | * hopefully at the proper time. Added by AMM. 194 | */ 195 | void DavisRFM69::loop(){ 196 | uint8_t i; 197 | 198 | // first see if we have tuned into receive a station previously and failed to actually receive a packet 199 | if (mode == SM_RECEIVING){ 200 | // packet was lost 201 | if (difftime(micros(), stations[curStation].recvBegan) > (1+stations[curStation].lostPackets)*(LATE_PACKET_THRESH + TUNEIN_USEC)){ 202 | //#ifdef DAVISRFM69_DEBUG 203 | Serial.print(micros()); 204 | Serial.print(": missed packet from station "); 205 | Serial.print(stations[curStation].id); 206 | Serial.print(" channel "); 207 | Serial.println(stations[curStation].channel); 208 | //#endif 209 | lostPackets++; 210 | stations[curStation].missedPackets ++; 211 | stations[curStation].lostPackets ++; 212 | stations[curStation].lastRx += stations[curStation].interval; 213 | stations[curStation].channel = nextChannel(stations[curStation].channel); 214 | 215 | // lost a station 216 | if (stations[curStation].lostPackets > RESYNC_THRESHOLD){ 217 | //#ifdef DAVISRFM69_DEBUG 218 | Serial.print(micros()); 219 | Serial.print(": station "); 220 | Serial.print(stations[curStation].id); 221 | Serial.println(" is lost."); 222 | //#endif 223 | stations[curStation].lostPackets = 0; 224 | stations[curStation].interval = 0; 225 | 226 | lostStations++; 227 | stationsFound--; 228 | } 229 | 230 | curStation = -1; 231 | mode = SM_IDLE; 232 | setMode(RF69_MODE_STANDBY); 233 | } else { 234 | // waiting to receive and it hasn't timed out yet. 235 | // do nothing. 236 | return; 237 | } 238 | } //if (mode == SM_RECEIVING) 239 | 240 | // next check for any station that's about to transmit 241 | // if found, tune in 242 | for (i = 0; i < numStations; i++) { 243 | // interval is filled in once we discover a station 244 | if (stations[i].interval > 0){ 245 | if (difftime(stations[i].lastRx + stations[i].interval, micros()) < ( (1+stations[i].lostPackets)*TUNEIN_USEC)){ 246 | #ifdef DAVISRFM69_DEBUG 247 | Serial.print(micros()); 248 | Serial.print(": tune to station "); 249 | Serial.print(stations[i].id); 250 | Serial.print(" channel "); 251 | Serial.println(stations[i].channel); 252 | #endif 253 | stations[i].recvBegan = micros(); 254 | setChannel(stations[i].channel); 255 | 256 | // we are now set to receive from this station. 257 | mode = SM_RECEIVING; 258 | curStation = i; 259 | return; 260 | } 261 | } 262 | } 263 | 264 | // if no transmitter is about to transmit, check for any 265 | // station that we are not synchonized with, if there are 266 | // any stations not synchronized, turn on the receiver and 267 | // hope we get lucky. 268 | bool all_sync = true; 269 | for (i = 0; i < numStations; i++) { 270 | // unknown stations will have interval of zero, the radio interrupt will 271 | // fill this in if we receive a packet from the given station. 272 | if (stations[i].interval == 0){ 273 | mode = SM_SEARCHING; 274 | all_sync = false; 275 | if (stations[i].syncBegan == 0){ 276 | // we have never tried to sync to this station 277 | #ifdef DAVISRFM69_DEBUG 278 | Serial.print(micros()); 279 | Serial.print(": begin sync to station "); 280 | Serial.print(stations[i].id); 281 | Serial.print(" channel "); 282 | Serial.println(stations[i].channel); 283 | #endif 284 | stations[i].syncBegan = micros(); 285 | stations[i].progress = 0; 286 | setChannel(stations[i].channel); 287 | }else if (difftime(micros(), stations[i].syncBegan) > DISCOVERY_STEP){ 288 | // we tried and failed to sync, try the next channel 289 | 290 | stations[i].channel = nextChannel(stations[i].channel); 291 | #ifdef DAVISRFM69_DEBUG 292 | Serial.print(micros()); 293 | Serial.print(": sync fail, begin sync to station "); 294 | Serial.print(stations[i].id); 295 | Serial.print(" channel "); 296 | Serial.println(stations[i].channel); 297 | #endif 298 | stations[i].syncBegan = micros(); 299 | stations[i].progress = 0; 300 | setChannel(stations[i].channel); 301 | } else { 302 | // we're waiting to hear from this station, don't tune away! 303 | #ifdef DAVISRFM69_DEBUG 304 | byte p = difftime(micros(), stations[i].syncBegan) / (DISCOVERY_STEP/100); 305 | 306 | if (stations[i].progress != p){ 307 | Serial.print(micros()); 308 | Serial.print(": listen progress "); 309 | Serial.print(p); 310 | Serial.println("\%"); 311 | stations[i].progress = p; 312 | } 313 | #endif 314 | break; 315 | } 316 | } 317 | } 318 | 319 | if (all_sync) { 320 | mode = SM_SYNCHRONIZED; 321 | 322 | // if we got here, no stations are about to TX and all stations are in sync, 323 | // we can disable our radio to save power. 324 | if (_mode != RF69_MODE_SLEEP){ 325 | #ifdef DAVISRFM69_DEBUG 326 | Serial.print(micros()); 327 | Serial.println(": Nothing to do, going to sleep"); 328 | #endif 329 | setMode(RF69_MODE_SLEEP); 330 | } 331 | } 332 | } 333 | 334 | /* 335 | // Handle missed packets. Called from Timer1 ISR every 2 ms 336 | void DavisRFM69::handleTimerInt() { 337 | 338 | uint32_t lastRx = micros(); 339 | bool readjust = false; 340 | 341 | int_ticks ++; 342 | if (stations[curStation].interval > 0 343 | && stations[curStation].lastRx + stations[curStation].interval - lastRx < DISCOVERY_GUARD 344 | && CHANNEL != stations[curStation].channel) { 345 | Serial.println("op1"); 346 | selfPointer->setChannel(stations[curStation].channel); 347 | return; 348 | } 349 | 350 | if (lastRx - lastDiscStep > DISCOVERY_STEP) { 351 | discChannel = selfPointer->nextChannel(discChannel); 352 | lastDiscStep = lastRx; 353 | } 354 | 355 | // find and adjust 'last seen' rx time on all stations with older reception timestamp than their period + threshold 356 | // that is, find missed packets 357 | for (byte i = 0; i < numStations; i++) { 358 | if (stations[i].interval > 0 && (lastRx - stations[i].lastRx) > stations[i].interval + LATE_PACKET_THRESH) { 359 | if (stations[curStation].active) lostPackets++; 360 | stations[i].lostPackets++; 361 | stations[i].missedPackets++; 362 | if (stations[i].lostPackets > RESYNC_THRESHOLD) { 363 | stations[i].numResyncs++; 364 | stations[i].interval = 0; 365 | stations[i].lostPackets = 0; 366 | lostStations++; 367 | stationsFound--; 368 | if (lostStations == numStations) { 369 | Serial.println("lost stations."); 370 | numResyncs++; 371 | stationsFound = 0; 372 | lostStations = 0; 373 | selfPointer->initStations(); 374 | selfPointer->setChannel(discChannel); 375 | return; 376 | } 377 | } else { 378 | stations[i].lastRx += stations[i].interval; // when packet should have been received 379 | stations[i].channel = selfPointer->nextChannel(stations[i].channel); // skip station's next channel in hop seq 380 | readjust = true; 381 | } 382 | } 383 | } 384 | 385 | if (readjust) { 386 | Serial.println("readjust."); 387 | selfPointer->nextStation(); 388 | selfPointer->setChannel(stations[curStation].channel); 389 | } 390 | } 391 | */ 392 | 393 | // Handle received packets, called from RFM69 ISR 394 | void DavisRFM69::handleRadioInt() { 395 | 396 | uint32_t lastRx = micros(); 397 | uint16_t rxCrc = word(DATA[6], DATA[7]); // received CRC 398 | uint16_t calcCrc = DavisRFM69::crc16_ccitt(DATA, 6); // calculated CRC 399 | 400 | bool repeaterCrcTried = false; 401 | 402 | // repeater packets checksum bytes (0..5) and (8..9), so try this at mismatch 403 | if (calcCrc != rxCrc) { 404 | calcCrc = DavisRFM69::crc16_ccitt(DATA + 8, 2, calcCrc); 405 | repeaterCrcTried = true; 406 | } 407 | 408 | delayMicroseconds(POST_RX_WAIT); // we need this, no idea why, but makes reception almost perfect 409 | // probably needed by the module to settle something after RX 410 | 411 | // fifo.queue((byte*)DATA, CHANNEL, -RSSI, FEI, lastRx - stations[curStation].lastRx); 412 | 413 | // packet passed crc? 414 | if (calcCrc == rxCrc && rxCrc != 0) { 415 | 416 | // station id is byte 0:0-2 417 | byte id = DATA[0] & 7; 418 | int stIx = findStation(id); 419 | 420 | // if we have no station cofigured for this id (at all; can still be be !active), ignore the packet 421 | // OR packet passed the repeater crc check, but no repeater is set for the station 422 | // OR packet passed the normal crc check, and repeater is set for the station 423 | if (stIx < 0 424 | || (repeaterCrcTried && stations[stIx].repeaterId == 0) 425 | || (!repeaterCrcTried && stations[stIx].repeaterId != 0)) { 426 | setChannel(CHANNEL); 427 | return; 428 | } 429 | 430 | if (stationsFound < numStations && stations[stIx].interval == 0) { 431 | stations[stIx].interval = (41 + id) * 1000000 / 16; // Davis' official tx interval in us 432 | 433 | stationsFound++; 434 | #ifdef DAVISRFM69_DEBUG 435 | Serial.print("found station "); 436 | Serial.print(stIx); 437 | Serial.print(" interval "); 438 | Serial.println(stations[stIx].interval); 439 | #endif 440 | if (lostStations > 0) lostStations--; 441 | } 442 | 443 | packets++; 444 | if (stations[stIx].active) { 445 | 446 | stations[stIx].packets++; 447 | fifo.queue((byte*)DATA, CHANNEL, -RSSI, FEI, stations[curStation].lastSeen > 0 ? lastRx - stations[curStation].lastSeen : 0); 448 | } 449 | 450 | stations[stIx].earlyAmt = difftime(lastRx, stations[stIx].recvBegan); 451 | stations[stIx].lostPackets = 0; 452 | stations[stIx].lastRx = stations[stIx].lastSeen = lastRx; 453 | stations[stIx].channel = nextChannel(CHANNEL); 454 | #ifdef DAVISRFM69_DEBUG 455 | Serial.print("early amt = "); 456 | Serial.println(stations[stIx].earlyAmt); 457 | #endif 458 | // no longer waiting to RX (if we were at all anwyay) 459 | mode = SM_IDLE; 460 | // standby the radio 461 | setMode (RF69_MODE_STANDBY); 462 | 463 | } else { 464 | // bad CRC, go back to RX on this channel 465 | setChannel(CHANNEL); // this always has to be done somewhere right after reception, even for ignored/bogus packets 466 | } 467 | 468 | } 469 | 470 | // Calculate the next hop of the specified channel 471 | byte DavisRFM69::nextChannel(byte channel) { 472 | return ++channel % getBandTabLength(); 473 | } 474 | 475 | // Find the station index in stations[] for station expected to tx the earliest and update curStation 476 | void DavisRFM69::nextStation() { 477 | uint32_t earliest = 0xffffffff; 478 | uint32_t now = micros(); 479 | for (int i = 0; i < numStations; i++) { 480 | uint32_t current = stations[i].lastRx + stations[i].interval - now; 481 | if (stations[i].interval > 0 && current < earliest) { 482 | earliest = current; 483 | curStation = i; 484 | } 485 | } 486 | } 487 | 488 | // Find station index in stations[] for a station ID (-1 if doesn't exist) 489 | int DavisRFM69::findStation(byte id) { 490 | for (byte i = 0; i < numStations; i++) { 491 | if (stations[i].id == id) return i; 492 | } 493 | return -1; 494 | } 495 | 496 | // Reset station array to safe defaults 497 | void DavisRFM69::initStations() { 498 | for (byte i = 0; i < numStations; i++) { 499 | stations[i].channel = 0; 500 | stations[i].lastRx = 0; 501 | stations[i].interval = 0; 502 | stations[i].lostPackets = 0; 503 | stations[i].lastRx = 0; 504 | stations[i].lastSeen = 0; 505 | stations[i].packets = 0; 506 | stations[i].missedPackets = 0; 507 | stations[i].syncBegan = 0; 508 | } 509 | } 510 | 511 | void DavisRFM69::interruptHandler() { 512 | RSSI = readRSSI(); // Read up front when it is most likely the carrier is still up 513 | if (_mode == RF69_MODE_RX && (readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PAYLOADREADY)) 514 | { 515 | FEI = word(readReg(REG_FEIMSB), readReg(REG_FEILSB)); 516 | setMode(RF69_MODE_STANDBY); 517 | select(); // Select RFM69 module, disabling interrupts 518 | SPI.transfer(REG_FIFO & 0x7f); 519 | 520 | for (byte i = 0; i < DAVIS_PACKET_LEN; i++) DATA[i] = reverseBits(SPI.transfer(0)); 521 | 522 | _packetReceived = true; 523 | 524 | handleRadioInt(); 525 | 526 | unselect(); // Unselect RFM69 module, enabling interrupts 527 | } 528 | } 529 | 530 | bool DavisRFM69::canSend() 531 | { 532 | if (_mode == RF69_MODE_RX && readRSSI() < CSMA_LIMIT) //if signal stronger than -100dBm is detected assume channel activity 533 | { 534 | setMode(RF69_MODE_STANDBY); 535 | return true; 536 | } 537 | return false; 538 | } 539 | 540 | // IMPORTANT: make sure buffer is at least 6 bytes 541 | void DavisRFM69::send(const void* buffer) 542 | { 543 | writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks 544 | sendFrame(buffer); 545 | } 546 | 547 | // IMPORTANT: make sure buffer is at least 6 bytes 548 | void DavisRFM69::sendFrame(const void* buffer) 549 | { 550 | setMode(RF69_MODE_STANDBY); //turn off receiver to prevent reception while filling fifo 551 | while ((readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); // Wait for ModeReady 552 | writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00); // DIO0 is "Packet Sent" 553 | 554 | // calculate crc on first 6 bytes (no repeater info) 555 | uint16_t crc = crc16_ccitt((volatile byte *)buffer, 6); 556 | // write to FIFO 557 | select(); 558 | SPI.transfer(REG_FIFO | 0x80); 559 | 560 | // The following byte sequence is an attempt to emulate the original Davis packet structure. 561 | 562 | // carrier on/start 563 | SPI.transfer(0xff); 564 | SPI.transfer(0xff); 565 | SPI.transfer(0xff); 566 | SPI.transfer(0xff); 567 | 568 | // preamble 569 | SPI.transfer(0xaa); 570 | SPI.transfer(0xaa); 571 | SPI.transfer(0xaa); 572 | SPI.transfer(0xaa); 573 | 574 | // sync word 575 | SPI.transfer(0xcb); 576 | SPI.transfer(0x89); 577 | 578 | // transmit first 6 byte of the buffer 579 | for (byte i = 0; i < 6; i++) 580 | SPI.transfer(reverseBits(((byte*)buffer)[i])); 581 | 582 | // transmit crc of first 6 bytes 583 | SPI.transfer(reverseBits(crc >> 8)); 584 | SPI.transfer(reverseBits(crc & 0xff)); 585 | 586 | // transmit dummy repeater info (always 0xff, 0xff for a normal packet without repeaters) 587 | SPI.transfer(0xff); 588 | SPI.transfer(0xff); 589 | 590 | unselect(); 591 | 592 | /* no need to wait for transmit mode to be ready since its handled by the radio */ 593 | setMode(RF69_MODE_TX); 594 | while (digitalRead(_interruptPin) == 0); //wait for DIO0 to turn HIGH signalling transmission finish 595 | setMode(RF69_MODE_STANDBY); 596 | } 597 | 598 | void DavisRFM69::setChannel(byte channel) 599 | { 600 | 601 | #ifdef DAVISRFM69_DEBUG 602 | Serial.print("CH->>"); 603 | Serial.println(channel); 604 | #endif 605 | 606 | CHANNEL = channel; 607 | if (CHANNEL > bandTabLengths[band] - 1) CHANNEL = 0; 608 | writeReg(REG_FRFMSB, pgm_read_byte(&bandTab[band][CHANNEL][0])); 609 | writeReg(REG_FRFMID, pgm_read_byte(&bandTab[band][CHANNEL][1])); 610 | writeReg(REG_FRFLSB, pgm_read_byte(&bandTab[band][CHANNEL][2])); 611 | if (!txMode) receiveBegin(); 612 | } 613 | 614 | void DavisRFM69::hop() 615 | { 616 | setChannel(++CHANNEL); 617 | } 618 | 619 | // The data bytes come over the air from the ISS least significant bit first. Fix them as we go. From 620 | // http://www.ocf.berkeley.edu/~wwu/cgi-bin/yabb/YaBB.cgi?board=riddles_cs;action=display;num=1103355188 621 | byte DavisRFM69::reverseBits(byte b) 622 | { 623 | b = ((b & 0b11110000) >>4 ) | ((b & 0b00001111) << 4); 624 | b = ((b & 0b11001100) >>2 ) | ((b & 0b00110011) << 2); 625 | b = ((b & 0b10101010) >>1 ) | ((b & 0b01010101) << 1); 626 | 627 | return(b); 628 | } 629 | 630 | // Davis CRC calculation from http://www.menie.org/georges/embedded/ 631 | uint16_t DavisRFM69::crc16_ccitt(volatile byte *buf, byte len, uint16_t initCrc) 632 | { 633 | uint16_t crc = initCrc; 634 | while( len-- ) { 635 | int i; 636 | crc ^= *(char *)buf++ << 8; 637 | for( i = 0; i < 8; ++i ) { 638 | if( crc & 0x8000 ) 639 | crc = (crc << 1) ^ 0x1021; 640 | else 641 | crc = crc << 1; 642 | } 643 | } 644 | return crc; 645 | } 646 | 647 | void DavisRFM69::setMode(byte newMode) 648 | { 649 | //Serial.println(newMode); 650 | if (newMode == _mode) return; 651 | 652 | if (_mode < COUNT_RF69_MODES){ 653 | rfm69_mode_counts[_mode] += difftime(micros(), rfm69_mode_timer); 654 | rfm69_mode_timer = micros(); 655 | #ifdef DAVISRFM69_DEBUG 656 | Serial.print(RFM69_MODE_STRINGS[_mode]); 657 | Serial.print(" -> "); 658 | Serial.println(RFM69_MODE_STRINGS[newMode]); 659 | #endif 660 | }else{ 661 | Serial.println("INVALID MODE CHANGE."); 662 | } 663 | switch (newMode) { 664 | case RF69_MODE_TX: 665 | writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_TRANSMITTER); 666 | if (_isRFM69HW) setHighPowerRegs(true); 667 | break; 668 | case RF69_MODE_RX: 669 | writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_RECEIVER); 670 | if (_isRFM69HW) setHighPowerRegs(false); 671 | break; 672 | case RF69_MODE_SYNTH: 673 | writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_SYNTHESIZER); 674 | break; 675 | case RF69_MODE_STANDBY: 676 | writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_STANDBY); 677 | break; 678 | case RF69_MODE_SLEEP: 679 | writeReg(REG_OPMODE, (readReg(REG_OPMODE) & 0xE3) | RF_OPMODE_SLEEP); 680 | break; 681 | default: return; 682 | } 683 | 684 | // we are using packet mode, so this check is not really needed 685 | // but waiting for mode ready is necessary when going from sleep because the FIFO may not be immediately available from previous mode 686 | while (_mode == RF69_MODE_SLEEP && (readReg(REG_IRQFLAGS1) & RF_IRQFLAGS1_MODEREADY) == 0x00); // Wait for ModeReady 687 | 688 | _mode = newMode; 689 | //Serial.print("Mode set to "); 690 | //Serial.println(_mode); 691 | } 692 | 693 | void DavisRFM69::sleep() { 694 | setMode(RF69_MODE_SLEEP); 695 | } 696 | 697 | void DavisRFM69::isr0() { selfPointer->interruptHandler(); } 698 | 699 | void DavisRFM69::receiveBegin() { 700 | _packetReceived = false; 701 | if (readReg(REG_IRQFLAGS2) & RF_IRQFLAGS2_PAYLOADREADY) 702 | writeReg(REG_PACKETCONFIG2, (readReg(REG_PACKETCONFIG2) & 0xFB) | RF_PACKET2_RXRESTART); // avoid RX deadlocks 703 | 704 | writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01); //set DIO0 to "PAYLOADREADY" in receive mode 705 | setMode(RF69_MODE_RX); 706 | } 707 | 708 | bool DavisRFM69::receiveDone() { 709 | return _packetReceived; 710 | } 711 | 712 | void DavisRFM69::setRssiThreshold(int rssiThreshold) { 713 | writeReg(REG_RSSIVALUE, abs(rssiThreshold) << 1); 714 | } 715 | 716 | void DavisRFM69::setRssiThresholdRaw(int rssiThresholdRaw) { 717 | writeReg(REG_RSSIVALUE, rssiThresholdRaw); 718 | } 719 | 720 | int DavisRFM69::readRSSI(bool forceTrigger) { 721 | int rssi = 0; 722 | if (forceTrigger) 723 | { 724 | //RSSI trigger not needed if DAGC is in continuous mode 725 | writeReg(REG_RSSICONFIG, RF_RSSI_START); 726 | while ((readReg(REG_RSSICONFIG) & RF_RSSI_DONE) == 0x00); // Wait for RSSI_Ready 727 | } 728 | rssi = -readReg(REG_RSSIVALUE); 729 | rssi >>= 1; 730 | return rssi; 731 | } 732 | 733 | byte DavisRFM69::readReg(byte addr) 734 | { 735 | select(); 736 | SPI.transfer(addr & 0x7F); 737 | byte regval = SPI.transfer(0); 738 | unselect(); 739 | return regval; 740 | } 741 | 742 | void DavisRFM69::writeReg(byte addr, byte value) 743 | { 744 | select(); 745 | SPI.transfer(addr | 0x80); 746 | SPI.transfer(value); 747 | unselect(); 748 | } 749 | 750 | /// Select the transceiver 751 | void DavisRFM69::select() { 752 | noInterrupts(); 753 | digitalWrite(_slaveSelectPin, LOW); 754 | } 755 | 756 | /// Unselect the transceiver chip 757 | void DavisRFM69::unselect() { 758 | digitalWrite(_slaveSelectPin, HIGH); 759 | interrupts(); 760 | } 761 | 762 | void DavisRFM69::setHighPower(bool onOff) { 763 | _isRFM69HW = onOff; 764 | writeReg(REG_OCP, _isRFM69HW ? RF_OCP_OFF : RF_OCP_ON); 765 | if (_isRFM69HW) //turning ON 766 | writeReg(REG_PALEVEL, (readReg(REG_PALEVEL) & 0x1F) | RF_PALEVEL_PA1_ON | RF_PALEVEL_PA2_ON); //enable P1 & P2 amplifier stages 767 | else 768 | writeReg(REG_PALEVEL, RF_PALEVEL_PA0_ON | RF_PALEVEL_PA1_OFF | RF_PALEVEL_PA2_OFF | _powerLevel); //enable P0 only 769 | } 770 | 771 | void DavisRFM69::setHighPowerRegs(bool onOff) { 772 | writeReg(REG_TESTPA1, onOff ? 0x5D : 0x55); 773 | writeReg(REG_TESTPA2, onOff ? 0x7C : 0x70); 774 | } 775 | 776 | void DavisRFM69::setCS(byte newSPISlaveSelect) { 777 | _slaveSelectPin = newSPISlaveSelect; 778 | pinMode(_slaveSelectPin, OUTPUT); 779 | } 780 | 781 | //for debugging 782 | void DavisRFM69::readAllRegs() 783 | { 784 | byte regVal; 785 | 786 | for (byte regAddr = 1; regAddr <= 0x4F; regAddr++) 787 | { 788 | select(); 789 | SPI.transfer(regAddr & 0x7f); // send address + r/w bit 790 | regVal = SPI.transfer(0); 791 | unselect(); 792 | 793 | Serial.print(regAddr, HEX); 794 | Serial.print(" - "); 795 | Serial.print(regVal,HEX); 796 | Serial.print(" - "); 797 | Serial.println(regVal,BIN); 798 | } 799 | unselect(); 800 | } 801 | 802 | byte DavisRFM69::readTemperature(byte calFactor) //returns centigrade 803 | { 804 | setMode(RF69_MODE_STANDBY); 805 | writeReg(REG_TEMP1, RF_TEMP1_MEAS_START); 806 | while ((readReg(REG_TEMP1) & RF_TEMP1_MEAS_RUNNING)) Serial.print('*'); 807 | return ~readReg(REG_TEMP2) + COURSE_TEMP_COEF + calFactor; //'complement'corrects the slope, rising temp = rising val 808 | } // COURSE_TEMP_COEF puts reading in the ballpark, user can add additional correction 809 | 810 | void DavisRFM69::rcCalibration() 811 | { 812 | writeReg(REG_OSC1, RF_OSC1_RCCAL_START); 813 | while ((readReg(REG_OSC1) & RF_OSC1_RCCAL_DONE) == 0x00); 814 | } 815 | 816 | void DavisRFM69::setTxMode(bool txMode) 817 | { 818 | DavisRFM69::txMode = txMode; 819 | if (txMode) { 820 | writeReg(REG_PREAMBLELSB, 0); 821 | writeReg(REG_SYNCCONFIG, RF_SYNC_OFF); 822 | // +10 = 4 bytes "carrier" (0xff) + 4 bytes preamble (0xaa) + 2 bytes sync 823 | writeReg(REG_PAYLOADLENGTH, DAVIS_PACKET_LEN + 10); 824 | writeReg(REG_FIFOTHRESH, RF_FIFOTHRESH_TXSTART_FIFOTHRESH | (DAVIS_PACKET_LEN + 10 - 1)); 825 | } else { 826 | writeReg(REG_PREAMBLELSB, 4); 827 | writeReg(REG_SYNCCONFIG, RF_SYNC_ON | RF_SYNC_FIFOFILL_AUTO | RF_SYNC_SIZE_2 | RF_SYNC_TOL_2); 828 | writeReg(REG_PAYLOADLENGTH, DAVIS_PACKET_LEN); 829 | writeReg(REG_FIFOTHRESH, RF_FIFOTHRESH_TXSTART_FIFOTHRESH | (DAVIS_PACKET_LEN - 1)); 830 | } 831 | } 832 | 833 | void DavisRFM69::setBand(byte newBand) 834 | { 835 | band = newBand; 836 | } 837 | 838 | void DavisRFM69::setBandwidth(byte bw) 839 | { 840 | switch (bw) { 841 | case RF69_DAVIS_BW_NARROW: 842 | writeReg(REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_20 | RF_RXBW_EXP_4); // Use 25 kHz BW (BitRate < 2 * RxBw) 843 | writeReg(REG_AFCBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_20 | RF_RXBW_EXP_3); // Use double the bandwidth during AFC as reception 844 | break; 845 | case RF69_DAVIS_BW_WIDE: 846 | // REG_RXBW 50 kHz fixes console retransmit reception but seems worse for SIM transmitters (to be confirmed with more testing) 847 | writeReg(REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_20 | RF_RXBW_EXP_3); // Use 50 kHz BW (BitRate < 2 * RxBw) 848 | writeReg(REG_AFCBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_20 | RF_RXBW_EXP_2); // Use double the bandwidth during AFC as reception 849 | break; 850 | default: 851 | return; 852 | } 853 | } 854 | 855 | byte DavisRFM69::getBandTabLength() 856 | { 857 | return bandTabLengths[band]; 858 | } 859 | -------------------------------------------------------------------------------- /RFM69registers.h: -------------------------------------------------------------------------------- 1 | // ********************************************************************************** 2 | // Registers used in driver definition for HopeRF RFM69W/RFM69HW, Semtech SX1231/1231H 3 | // ********************************************************************************** 4 | // Copyright Felix Rusu (2014), felix@lowpowerlab.com 5 | // http://lowpowerlab.com/ 6 | // ********************************************************************************** 7 | // License 8 | // ********************************************************************************** 9 | // This program is free software; you can redistribute it 10 | // and/or modify it under the terms of the GNU General 11 | // Public License as published by the Free Software 12 | // Foundation; either version 2 of the License, or 13 | // (at your option) any later version. 14 | // 15 | // This program is distributed in the hope that it will 16 | // be useful, but WITHOUT ANY WARRANTY; without even the 17 | // implied warranty of MERCHANTABILITY or FITNESS FOR A 18 | // PARTICULAR PURPOSE. See the GNU General Public 19 | // License for more details. 20 | // 21 | // You should have received a copy of the GNU General 22 | // Public License along with this program; if not, write 23 | // to the Free Software Foundation, Inc., 24 | // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 25 | // 26 | // Licence can be viewed at 27 | // http://www.fsf.org/licenses/gpl.txt 28 | // 29 | // Please maintain this license information along with authorship 30 | // and copyright notices in any redistribution of this code 31 | // ********************************************************************************** 32 | // RFM69/SX1231 Internal registers addresses 33 | //************************************************** 34 | #define REG_FIFO 0x00 35 | #define REG_OPMODE 0x01 36 | #define REG_DATAMODUL 0x02 37 | #define REG_BITRATEMSB 0x03 38 | #define REG_BITRATELSB 0x04 39 | #define REG_FDEVMSB 0x05 40 | #define REG_FDEVLSB 0x06 41 | #define REG_FRFMSB 0x07 42 | #define REG_FRFMID 0x08 43 | #define REG_FRFLSB 0x09 44 | #define REG_OSC1 0x0A 45 | #define REG_AFCCTRL 0x0B 46 | #define REG_LOWBAT 0x0C 47 | #define REG_LISTEN1 0x0D 48 | #define REG_LISTEN2 0x0E 49 | #define REG_LISTEN3 0x0F 50 | #define REG_VERSION 0x10 51 | #define REG_PALEVEL 0x11 52 | #define REG_PARAMP 0x12 53 | #define REG_OCP 0x13 54 | #define REG_AGCREF 0x14 55 | #define REG_AGCTHRESH1 0x15 56 | #define REG_AGCTHRESH2 0x16 57 | #define REG_AGCTHRESH3 0x17 58 | #define REG_LNA 0x18 59 | #define REG_RXBW 0x19 60 | #define REG_AFCBW 0x1A 61 | #define REG_OOKPEAK 0x1B 62 | #define REG_OOKAVG 0x1C 63 | #define REG_OOKFIX 0x1D 64 | #define REG_AFCFEI 0x1E 65 | #define REG_AFCMSB 0x1F 66 | #define REG_AFCLSB 0x20 67 | #define REG_FEIMSB 0x21 68 | #define REG_FEILSB 0x22 69 | #define REG_RSSICONFIG 0x23 70 | #define REG_RSSIVALUE 0x24 71 | #define REG_DIOMAPPING1 0x25 72 | #define REG_DIOMAPPING2 0x26 73 | #define REG_IRQFLAGS1 0x27 74 | #define REG_IRQFLAGS2 0x28 75 | #define REG_RSSITHRESH 0x29 76 | #define REG_RXTIMEOUT1 0x2A 77 | #define REG_RXTIMEOUT2 0x2B 78 | #define REG_PREAMBLEMSB 0x2C 79 | #define REG_PREAMBLELSB 0x2D 80 | #define REG_SYNCCONFIG 0x2E 81 | #define REG_SYNCVALUE1 0x2F 82 | #define REG_SYNCVALUE2 0x30 83 | #define REG_SYNCVALUE3 0x31 84 | #define REG_SYNCVALUE4 0x32 85 | #define REG_SYNCVALUE5 0x33 86 | #define REG_SYNCVALUE6 0x34 87 | #define REG_SYNCVALUE7 0x35 88 | #define REG_SYNCVALUE8 0x36 89 | #define REG_PACKETCONFIG1 0x37 90 | #define REG_PAYLOADLENGTH 0x38 91 | #define REG_NODEADRS 0x39 92 | #define REG_BROADCASTADRS 0x3A 93 | #define REG_AUTOMODES 0x3B 94 | #define REG_FIFOTHRESH 0x3C 95 | #define REG_PACKETCONFIG2 0x3D 96 | #define REG_AESKEY1 0x3E 97 | #define REG_AESKEY2 0x3F 98 | #define REG_AESKEY3 0x40 99 | #define REG_AESKEY4 0x41 100 | #define REG_AESKEY5 0x42 101 | #define REG_AESKEY6 0x43 102 | #define REG_AESKEY7 0x44 103 | #define REG_AESKEY8 0x45 104 | #define REG_AESKEY9 0x46 105 | #define REG_AESKEY10 0x47 106 | #define REG_AESKEY11 0x48 107 | #define REG_AESKEY12 0x49 108 | #define REG_AESKEY13 0x4A 109 | #define REG_AESKEY14 0x4B 110 | #define REG_AESKEY15 0x4C 111 | #define REG_AESKEY16 0x4D 112 | #define REG_TEMP1 0x4E 113 | #define REG_TEMP2 0x4F 114 | #define REG_TESTPA1 0x5A //only present on RFM69HW/SX1231H 115 | #define REG_TESTPA2 0x5C //only present on RFM69HW/SX1231H 116 | #define REG_TESTDAGC 0x6F 117 | 118 | //****************************************************** 119 | // RF69/SX1231 bit control definition 120 | //****************************************************** 121 | // RegOpMode 122 | #define RF_OPMODE_SEQUENCER_OFF 0x80 123 | #define RF_OPMODE_SEQUENCER_ON 0x00 // Default 124 | 125 | #define RF_OPMODE_LISTEN_ON 0x40 126 | #define RF_OPMODE_LISTEN_OFF 0x00 // Default 127 | 128 | #define RF_OPMODE_LISTENABORT 0x20 129 | 130 | #define RF_OPMODE_SLEEP 0x00 131 | #define RF_OPMODE_STANDBY 0x04 // Default 132 | #define RF_OPMODE_SYNTHESIZER 0x08 133 | #define RF_OPMODE_TRANSMITTER 0x0C 134 | #define RF_OPMODE_RECEIVER 0x10 135 | 136 | // RegDataModul 137 | #define RF_DATAMODUL_DATAMODE_PACKET 0x00 // Default 138 | #define RF_DATAMODUL_DATAMODE_CONTINUOUS 0x40 139 | #define RF_DATAMODUL_DATAMODE_CONTINUOUSNOBSYNC 0x60 140 | 141 | #define RF_DATAMODUL_MODULATIONTYPE_FSK 0x00 // Default 142 | #define RF_DATAMODUL_MODULATIONTYPE_OOK 0x08 143 | 144 | #define RF_DATAMODUL_MODULATIONSHAPING_00 0x00 // Default 145 | #define RF_DATAMODUL_MODULATIONSHAPING_01 0x01 146 | #define RF_DATAMODUL_MODULATIONSHAPING_10 0x02 147 | #define RF_DATAMODUL_MODULATIONSHAPING_11 0x03 148 | 149 | // RegBitRate (bits/sec) example bit rates 150 | #define RF_BITRATEMSB_1200 0x68 151 | #define RF_BITRATELSB_1200 0x2B 152 | #define RF_BITRATEMSB_2400 0x34 153 | #define RF_BITRATELSB_2400 0x15 154 | #define RF_BITRATEMSB_4800 0x1A // Default 155 | #define RF_BITRATELSB_4800 0x0B // Default 156 | #define RF_BITRATEMSB_9600 0x0D 157 | #define RF_BITRATELSB_9600 0x05 158 | #define RF_BITRATEMSB_19200 0x06 159 | #define RF_BITRATELSB_19200 0x83 160 | #define RF_BITRATEMSB_38400 0x03 161 | #define RF_BITRATELSB_38400 0x41 162 | 163 | #define RF_BITRATEMSB_38323 0x03 164 | #define RF_BITRATELSB_38323 0x43 165 | 166 | #define RF_BITRATEMSB_34482 0x03 167 | #define RF_BITRATELSB_34482 0xA0 168 | 169 | #define RF_BITRATEMSB_76800 0x01 170 | #define RF_BITRATELSB_76800 0xA1 171 | #define RF_BITRATEMSB_153600 0x00 172 | #define RF_BITRATELSB_153600 0xD0 173 | #define RF_BITRATEMSB_57600 0x02 174 | #define RF_BITRATELSB_57600 0x2C 175 | #define RF_BITRATEMSB_115200 0x01 176 | #define RF_BITRATELSB_115200 0x16 177 | #define RF_BITRATEMSB_12500 0x0A 178 | #define RF_BITRATELSB_12500 0x00 179 | #define RF_BITRATEMSB_25000 0x05 180 | #define RF_BITRATELSB_25000 0x00 181 | #define RF_BITRATEMSB_50000 0x02 182 | #define RF_BITRATELSB_50000 0x80 183 | #define RF_BITRATEMSB_100000 0x01 184 | #define RF_BITRATELSB_100000 0x40 185 | #define RF_BITRATEMSB_150000 0x00 186 | #define RF_BITRATELSB_150000 0xD5 187 | #define RF_BITRATEMSB_200000 0x00 188 | #define RF_BITRATELSB_200000 0xA0 189 | #define RF_BITRATEMSB_250000 0x00 190 | #define RF_BITRATELSB_250000 0x80 191 | #define RF_BITRATEMSB_300000 0x00 192 | #define RF_BITRATELSB_300000 0x6B 193 | #define RF_BITRATEMSB_32768 0x03 194 | #define RF_BITRATELSB_32768 0xD1 195 | //custom bit rates 196 | #define RF_BITRATEMSB_55555 0x02 197 | #define RF_BITRATELSB_55555 0x40 198 | #define RF_BITRATEMSB_200KBPS 0x00 199 | #define RF_BITRATELSB_200KBPS 0xa0 200 | 201 | // RegFdev - frequency deviation (Hz) 202 | #define RF_FDEVMSB_2000 0x00 203 | #define RF_FDEVLSB_2000 0x21 204 | #define RF_FDEVMSB_5000 0x00 // Default 205 | #define RF_FDEVLSB_5000 0x52 // Default 206 | #define RF_FDEVMSB_7500 0x00 207 | #define RF_FDEVLSB_7500 0x7B 208 | #define RF_FDEVMSB_10000 0x00 209 | #define RF_FDEVLSB_10000 0xA4 210 | #define RF_FDEVMSB_15000 0x00 211 | #define RF_FDEVLSB_15000 0xF6 212 | #define RF_FDEVMSB_20000 0x01 213 | #define RF_FDEVLSB_20000 0x48 214 | #define RF_FDEVMSB_25000 0x01 215 | #define RF_FDEVLSB_25000 0x9A 216 | #define RF_FDEVMSB_30000 0x01 217 | #define RF_FDEVLSB_30000 0xEC 218 | #define RF_FDEVMSB_35000 0x02 219 | #define RF_FDEVLSB_35000 0x3D 220 | #define RF_FDEVMSB_40000 0x02 221 | #define RF_FDEVLSB_40000 0x8F 222 | #define RF_FDEVMSB_45000 0x02 223 | #define RF_FDEVLSB_45000 0xE1 224 | #define RF_FDEVMSB_50000 0x03 225 | #define RF_FDEVLSB_50000 0x33 226 | #define RF_FDEVMSB_55000 0x03 227 | #define RF_FDEVLSB_55000 0x85 228 | #define RF_FDEVMSB_60000 0x03 229 | #define RF_FDEVLSB_60000 0xD7 230 | #define RF_FDEVMSB_65000 0x04 231 | #define RF_FDEVLSB_65000 0x29 232 | #define RF_FDEVMSB_70000 0x04 233 | #define RF_FDEVLSB_70000 0x7B 234 | #define RF_FDEVMSB_75000 0x04 235 | #define RF_FDEVLSB_75000 0xCD 236 | #define RF_FDEVMSB_80000 0x05 237 | #define RF_FDEVLSB_80000 0x1F 238 | #define RF_FDEVMSB_85000 0x05 239 | #define RF_FDEVLSB_85000 0x71 240 | #define RF_FDEVMSB_90000 0x05 241 | #define RF_FDEVLSB_90000 0xC3 242 | #define RF_FDEVMSB_95000 0x06 243 | #define RF_FDEVLSB_95000 0x14 244 | #define RF_FDEVMSB_100000 0x06 245 | #define RF_FDEVLSB_100000 0x66 246 | #define RF_FDEVMSB_110000 0x07 247 | #define RF_FDEVLSB_110000 0x0A 248 | #define RF_FDEVMSB_120000 0x07 249 | #define RF_FDEVLSB_120000 0xAE 250 | #define RF_FDEVMSB_130000 0x08 251 | #define RF_FDEVLSB_130000 0x52 252 | #define RF_FDEVMSB_140000 0x08 253 | #define RF_FDEVLSB_140000 0xF6 254 | #define RF_FDEVMSB_150000 0x09 255 | #define RF_FDEVLSB_150000 0x9A 256 | #define RF_FDEVMSB_160000 0x0A 257 | #define RF_FDEVLSB_160000 0x3D 258 | #define RF_FDEVMSB_170000 0x0A 259 | #define RF_FDEVLSB_170000 0xE1 260 | #define RF_FDEVMSB_180000 0x0B 261 | #define RF_FDEVLSB_180000 0x85 262 | #define RF_FDEVMSB_190000 0x0C 263 | #define RF_FDEVLSB_190000 0x29 264 | #define RF_FDEVMSB_200000 0x0C 265 | #define RF_FDEVLSB_200000 0xCD 266 | #define RF_FDEVMSB_210000 0x0D 267 | #define RF_FDEVLSB_210000 0x71 268 | #define RF_FDEVMSB_220000 0x0E 269 | #define RF_FDEVLSB_220000 0x14 270 | #define RF_FDEVMSB_230000 0x0E 271 | #define RF_FDEVLSB_230000 0xB8 272 | #define RF_FDEVMSB_240000 0x0F 273 | #define RF_FDEVLSB_240000 0x5C 274 | #define RF_FDEVMSB_250000 0x10 275 | #define RF_FDEVLSB_250000 0x00 276 | #define RF_FDEVMSB_260000 0x10 277 | #define RF_FDEVLSB_260000 0xA4 278 | #define RF_FDEVMSB_270000 0x11 279 | #define RF_FDEVLSB_270000 0x48 280 | #define RF_FDEVMSB_280000 0x11 281 | #define RF_FDEVLSB_280000 0xEC 282 | #define RF_FDEVMSB_290000 0x12 283 | #define RF_FDEVLSB_290000 0x8F 284 | #define RF_FDEVMSB_300000 0x13 285 | #define RF_FDEVLSB_300000 0x33 286 | 287 | // RegFrf (MHz) - carrier frequency 288 | // 315Mhz band 289 | #define RF_FRFMSB_314 0x4E 290 | #define RF_FRFMID_314 0x80 291 | #define RF_FRFLSB_314 0x00 292 | #define RF_FRFMSB_315 0x4E 293 | #define RF_FRFMID_315 0xC0 294 | #define RF_FRFLSB_315 0x00 295 | #define RF_FRFMSB_316 0x4F 296 | #define RF_FRFMID_316 0x00 297 | #define RF_FRFLSB_316 0x00 298 | // 433mhz band 299 | #define RF_FRFMSB_433 0x6C 300 | #define RF_FRFMID_433 0x40 301 | #define RF_FRFLSB_433 0x00 302 | #define RF_FRFMSB_434 0x6C 303 | #define RF_FRFMID_434 0x80 304 | #define RF_FRFLSB_434 0x00 305 | #define RF_FRFMSB_435 0x6C 306 | #define RF_FRFMID_435 0xC0 307 | #define RF_FRFLSB_435 0x00 308 | // 868Mhz band 309 | #define RF_FRFMSB_863 0xD7 310 | #define RF_FRFMID_863 0xC0 311 | #define RF_FRFLSB_863 0x00 312 | #define RF_FRFMSB_864 0xD8 313 | #define RF_FRFMID_864 0x00 314 | #define RF_FRFLSB_864 0x00 315 | #define RF_FRFMSB_865 0xD8 316 | #define RF_FRFMID_865 0x40 317 | #define RF_FRFLSB_865 0x00 318 | #define RF_FRFMSB_866 0xD8 319 | #define RF_FRFMID_866 0x80 320 | #define RF_FRFLSB_866 0x00 321 | #define RF_FRFMSB_867 0xD8 322 | #define RF_FRFMID_867 0xC0 323 | #define RF_FRFLSB_867 0x00 324 | #define RF_FRFMSB_868 0xD9 325 | #define RF_FRFMID_868 0x00 326 | #define RF_FRFLSB_868 0x00 327 | #define RF_FRFMSB_869 0xD9 328 | #define RF_FRFMID_869 0x40 329 | #define RF_FRFLSB_869 0x00 330 | #define RF_FRFMSB_870 0xD9 331 | #define RF_FRFMID_870 0x80 332 | #define RF_FRFLSB_870 0x00 333 | // 915Mhz band 334 | #define RF_FRFMSB_902 0xE1 335 | #define RF_FRFMID_902 0x80 336 | #define RF_FRFLSB_902 0x00 337 | #define RF_FRFMSB_903 0xE1 338 | #define RF_FRFMID_903 0xC0 339 | #define RF_FRFLSB_903 0x00 340 | #define RF_FRFMSB_904 0xE2 341 | #define RF_FRFMID_904 0x00 342 | #define RF_FRFLSB_904 0x00 343 | #define RF_FRFMSB_905 0xE2 344 | #define RF_FRFMID_905 0x40 345 | #define RF_FRFLSB_905 0x00 346 | #define RF_FRFMSB_906 0xE2 347 | #define RF_FRFMID_906 0x80 348 | #define RF_FRFLSB_906 0x00 349 | #define RF_FRFMSB_907 0xE2 350 | #define RF_FRFMID_907 0xC0 351 | #define RF_FRFLSB_907 0x00 352 | #define RF_FRFMSB_908 0xE3 353 | #define RF_FRFMID_908 0x00 354 | #define RF_FRFLSB_908 0x00 355 | #define RF_FRFMSB_909 0xE3 356 | #define RF_FRFMID_909 0x40 357 | #define RF_FRFLSB_909 0x00 358 | #define RF_FRFMSB_910 0xE3 359 | #define RF_FRFMID_910 0x80 360 | #define RF_FRFLSB_910 0x00 361 | #define RF_FRFMSB_911 0xE3 362 | #define RF_FRFMID_911 0xC0 363 | #define RF_FRFLSB_911 0x00 364 | #define RF_FRFMSB_912 0xE4 365 | #define RF_FRFMID_912 0x00 366 | #define RF_FRFLSB_912 0x00 367 | #define RF_FRFMSB_913 0xE4 368 | #define RF_FRFMID_913 0x40 369 | #define RF_FRFLSB_913 0x00 370 | #define RF_FRFMSB_914 0xE4 371 | #define RF_FRFMID_914 0x80 372 | #define RF_FRFLSB_914 0x00 373 | #define RF_FRFMSB_915 0xE4 // Default 374 | #define RF_FRFMID_915 0xC0 // Default 375 | #define RF_FRFLSB_915 0x00 // Default 376 | #define RF_FRFMSB_916 0xE5 377 | #define RF_FRFMID_916 0x00 378 | #define RF_FRFLSB_916 0x00 379 | #define RF_FRFMSB_917 0xE5 380 | #define RF_FRFMID_917 0x40 381 | #define RF_FRFLSB_917 0x00 382 | #define RF_FRFMSB_918 0xE5 383 | #define RF_FRFMID_918 0x80 384 | #define RF_FRFLSB_918 0x00 385 | #define RF_FRFMSB_919 0xE5 386 | #define RF_FRFMID_919 0xC0 387 | #define RF_FRFLSB_919 0x00 388 | #define RF_FRFMSB_920 0xE6 389 | #define RF_FRFMID_920 0x00 390 | #define RF_FRFLSB_920 0x00 391 | #define RF_FRFMSB_921 0xE6 392 | #define RF_FRFMID_921 0x40 393 | #define RF_FRFLSB_921 0x00 394 | #define RF_FRFMSB_922 0xE6 395 | #define RF_FRFMID_922 0x80 396 | #define RF_FRFLSB_922 0x00 397 | #define RF_FRFMSB_923 0xE6 398 | #define RF_FRFMID_923 0xC0 399 | #define RF_FRFLSB_923 0x00 400 | #define RF_FRFMSB_924 0xE7 401 | #define RF_FRFMID_924 0x00 402 | #define RF_FRFLSB_924 0x00 403 | #define RF_FRFMSB_925 0xE7 404 | #define RF_FRFMID_925 0x40 405 | #define RF_FRFLSB_925 0x00 406 | #define RF_FRFMSB_926 0xE7 407 | #define RF_FRFMID_926 0x80 408 | #define RF_FRFLSB_926 0x00 409 | #define RF_FRFMSB_927 0xE7 410 | #define RF_FRFMID_927 0xC0 411 | #define RF_FRFLSB_927 0x00 412 | #define RF_FRFMSB_928 0xE8 413 | #define RF_FRFMID_928 0x00 414 | #define RF_FRFLSB_928 0x00 415 | 416 | 417 | // RegOsc1 418 | #define RF_OSC1_RCCAL_START 0x80 419 | #define RF_OSC1_RCCAL_DONE 0x40 420 | 421 | // RegLowBat 422 | #define RF_LOWBAT_MONITOR 0x10 423 | #define RF_LOWBAT_ON 0x08 424 | #define RF_LOWBAT_OFF 0x00 // Default 425 | 426 | #define RF_LOWBAT_TRIM_1695 0x00 427 | #define RF_LOWBAT_TRIM_1764 0x01 428 | #define RF_LOWBAT_TRIM_1835 0x02 // Default 429 | #define RF_LOWBAT_TRIM_1905 0x03 430 | #define RF_LOWBAT_TRIM_1976 0x04 431 | #define RF_LOWBAT_TRIM_2045 0x05 432 | #define RF_LOWBAT_TRIM_2116 0x06 433 | #define RF_LOWBAT_TRIM_2185 0x07 434 | 435 | 436 | // RegListen1 437 | #define RF_LISTEN1_RESOL_64 0x50 438 | #define RF_LISTEN1_RESOL_4100 0xA0 // Default 439 | #define RF_LISTEN1_RESOL_262000 0xF0 440 | 441 | #define RF_LISTEN1_CRITERIA_RSSI 0x00 // Default 442 | #define RF_LISTEN1_CRITERIA_RSSIANDSYNC 0x08 443 | 444 | #define RF_LISTEN1_END_00 0x00 445 | #define RF_LISTEN1_END_01 0x02 // Default 446 | #define RF_LISTEN1_END_10 0x04 447 | 448 | 449 | // RegListen2 450 | #define RF_LISTEN2_COEFIDLE_VALUE 0xF5 // Default 451 | 452 | // RegListen3 453 | #define RF_LISTEN3_COEFRX_VALUE 0x20 // Default 454 | 455 | // RegPaLevel 456 | #define RF_PALEVEL_PA0_ON 0x80 // Default 457 | #define RF_PALEVEL_PA0_OFF 0x00 458 | #define RF_PALEVEL_PA1_ON 0x40 459 | #define RF_PALEVEL_PA1_OFF 0x00 // Default 460 | #define RF_PALEVEL_PA2_ON 0x20 461 | #define RF_PALEVEL_PA2_OFF 0x00 // Default 462 | 463 | #define RF_PALEVEL_OUTPUTPOWER_00000 0x00 464 | #define RF_PALEVEL_OUTPUTPOWER_00001 0x01 465 | #define RF_PALEVEL_OUTPUTPOWER_00010 0x02 466 | #define RF_PALEVEL_OUTPUTPOWER_00011 0x03 467 | #define RF_PALEVEL_OUTPUTPOWER_00100 0x04 468 | #define RF_PALEVEL_OUTPUTPOWER_00101 0x05 469 | #define RF_PALEVEL_OUTPUTPOWER_00110 0x06 470 | #define RF_PALEVEL_OUTPUTPOWER_00111 0x07 471 | #define RF_PALEVEL_OUTPUTPOWER_01000 0x08 472 | #define RF_PALEVEL_OUTPUTPOWER_01001 0x09 473 | #define RF_PALEVEL_OUTPUTPOWER_01010 0x0A 474 | #define RF_PALEVEL_OUTPUTPOWER_01011 0x0B 475 | #define RF_PALEVEL_OUTPUTPOWER_01100 0x0C 476 | #define RF_PALEVEL_OUTPUTPOWER_01101 0x0D 477 | #define RF_PALEVEL_OUTPUTPOWER_01110 0x0E 478 | #define RF_PALEVEL_OUTPUTPOWER_01111 0x0F 479 | #define RF_PALEVEL_OUTPUTPOWER_10000 0x10 480 | #define RF_PALEVEL_OUTPUTPOWER_10001 0x11 481 | #define RF_PALEVEL_OUTPUTPOWER_10010 0x12 482 | #define RF_PALEVEL_OUTPUTPOWER_10011 0x13 483 | #define RF_PALEVEL_OUTPUTPOWER_10100 0x14 484 | #define RF_PALEVEL_OUTPUTPOWER_10101 0x15 485 | #define RF_PALEVEL_OUTPUTPOWER_10110 0x16 486 | #define RF_PALEVEL_OUTPUTPOWER_10111 0x17 487 | #define RF_PALEVEL_OUTPUTPOWER_11000 0x18 488 | #define RF_PALEVEL_OUTPUTPOWER_11001 0x19 489 | #define RF_PALEVEL_OUTPUTPOWER_11010 0x1A 490 | #define RF_PALEVEL_OUTPUTPOWER_11011 0x1B 491 | #define RF_PALEVEL_OUTPUTPOWER_11100 0x1C 492 | #define RF_PALEVEL_OUTPUTPOWER_11101 0x1D 493 | #define RF_PALEVEL_OUTPUTPOWER_11110 0x1E 494 | #define RF_PALEVEL_OUTPUTPOWER_11111 0x1F // Default 495 | 496 | 497 | // RegPaRamp 498 | #define RF_PARAMP_3400 0x00 499 | #define RF_PARAMP_2000 0x01 500 | #define RF_PARAMP_1000 0x02 501 | #define RF_PARAMP_500 0x03 502 | #define RF_PARAMP_250 0x04 503 | #define RF_PARAMP_125 0x05 504 | #define RF_PARAMP_100 0x06 505 | #define RF_PARAMP_62 0x07 506 | #define RF_PARAMP_50 0x08 507 | #define RF_PARAMP_40 0x09 // Default 508 | #define RF_PARAMP_31 0x0A 509 | #define RF_PARAMP_25 0x0B 510 | #define RF_PARAMP_20 0x0C 511 | #define RF_PARAMP_15 0x0D 512 | #define RF_PARAMP_12 0x0E 513 | #define RF_PARAMP_10 0x0F 514 | 515 | 516 | // RegOcp 517 | #define RF_OCP_OFF 0x0F 518 | #define RF_OCP_ON 0x1A // Default 519 | 520 | #define RF_OCP_TRIM_45 0x00 521 | #define RF_OCP_TRIM_50 0x01 522 | #define RF_OCP_TRIM_55 0x02 523 | #define RF_OCP_TRIM_60 0x03 524 | #define RF_OCP_TRIM_65 0x04 525 | #define RF_OCP_TRIM_70 0x05 526 | #define RF_OCP_TRIM_75 0x06 527 | #define RF_OCP_TRIM_80 0x07 528 | #define RF_OCP_TRIM_85 0x08 529 | #define RF_OCP_TRIM_90 0x09 530 | #define RF_OCP_TRIM_95 0x0A 531 | #define RF_OCP_TRIM_100 0x0B // Default 532 | #define RF_OCP_TRIM_105 0x0C 533 | #define RF_OCP_TRIM_110 0x0D 534 | #define RF_OCP_TRIM_115 0x0E 535 | #define RF_OCP_TRIM_120 0x0F 536 | 537 | 538 | // RegAgcRef 539 | #define RF_AGCREF_AUTO_ON 0x40 // Default 540 | #define RF_AGCREF_AUTO_OFF 0x00 541 | 542 | #define RF_AGCREF_LEVEL_MINUS80 0x00 // Default 543 | #define RF_AGCREF_LEVEL_MINUS81 0x01 544 | #define RF_AGCREF_LEVEL_MINUS82 0x02 545 | #define RF_AGCREF_LEVEL_MINUS83 0x03 546 | #define RF_AGCREF_LEVEL_MINUS84 0x04 547 | #define RF_AGCREF_LEVEL_MINUS85 0x05 548 | #define RF_AGCREF_LEVEL_MINUS86 0x06 549 | #define RF_AGCREF_LEVEL_MINUS87 0x07 550 | #define RF_AGCREF_LEVEL_MINUS88 0x08 551 | #define RF_AGCREF_LEVEL_MINUS89 0x09 552 | #define RF_AGCREF_LEVEL_MINUS90 0x0A 553 | #define RF_AGCREF_LEVEL_MINUS91 0x0B 554 | #define RF_AGCREF_LEVEL_MINUS92 0x0C 555 | #define RF_AGCREF_LEVEL_MINUS93 0x0D 556 | #define RF_AGCREF_LEVEL_MINUS94 0x0E 557 | #define RF_AGCREF_LEVEL_MINUS95 0x0F 558 | #define RF_AGCREF_LEVEL_MINUS96 0x10 559 | #define RF_AGCREF_LEVEL_MINUS97 0x11 560 | #define RF_AGCREF_LEVEL_MINUS98 0x12 561 | #define RF_AGCREF_LEVEL_MINUS99 0x13 562 | #define RF_AGCREF_LEVEL_MINUS100 0x14 563 | #define RF_AGCREF_LEVEL_MINUS101 0x15 564 | #define RF_AGCREF_LEVEL_MINUS102 0x16 565 | #define RF_AGCREF_LEVEL_MINUS103 0x17 566 | #define RF_AGCREF_LEVEL_MINUS104 0x18 567 | #define RF_AGCREF_LEVEL_MINUS105 0x19 568 | #define RF_AGCREF_LEVEL_MINUS106 0x1A 569 | #define RF_AGCREF_LEVEL_MINUS107 0x1B 570 | #define RF_AGCREF_LEVEL_MINUS108 0x1C 571 | #define RF_AGCREF_LEVEL_MINUS109 0x1D 572 | #define RF_AGCREF_LEVEL_MINUS110 0x1E 573 | #define RF_AGCREF_LEVEL_MINUS111 0x1F 574 | #define RF_AGCREF_LEVEL_MINUS112 0x20 575 | #define RF_AGCREF_LEVEL_MINUS113 0x21 576 | #define RF_AGCREF_LEVEL_MINUS114 0x22 577 | #define RF_AGCREF_LEVEL_MINUS115 0x23 578 | #define RF_AGCREF_LEVEL_MINUS116 0x24 579 | #define RF_AGCREF_LEVEL_MINUS117 0x25 580 | #define RF_AGCREF_LEVEL_MINUS118 0x26 581 | #define RF_AGCREF_LEVEL_MINUS119 0x27 582 | #define RF_AGCREF_LEVEL_MINUS120 0x28 583 | #define RF_AGCREF_LEVEL_MINUS121 0x29 584 | #define RF_AGCREF_LEVEL_MINUS122 0x2A 585 | #define RF_AGCREF_LEVEL_MINUS123 0x2B 586 | #define RF_AGCREF_LEVEL_MINUS124 0x2C 587 | #define RF_AGCREF_LEVEL_MINUS125 0x2D 588 | #define RF_AGCREF_LEVEL_MINUS126 0x2E 589 | #define RF_AGCREF_LEVEL_MINUS127 0x2F 590 | #define RF_AGCREF_LEVEL_MINUS128 0x30 591 | #define RF_AGCREF_LEVEL_MINUS129 0x31 592 | #define RF_AGCREF_LEVEL_MINUS130 0x32 593 | #define RF_AGCREF_LEVEL_MINUS131 0x33 594 | #define RF_AGCREF_LEVEL_MINUS132 0x34 595 | #define RF_AGCREF_LEVEL_MINUS133 0x35 596 | #define RF_AGCREF_LEVEL_MINUS134 0x36 597 | #define RF_AGCREF_LEVEL_MINUS135 0x37 598 | #define RF_AGCREF_LEVEL_MINUS136 0x38 599 | #define RF_AGCREF_LEVEL_MINUS137 0x39 600 | #define RF_AGCREF_LEVEL_MINUS138 0x3A 601 | #define RF_AGCREF_LEVEL_MINUS139 0x3B 602 | #define RF_AGCREF_LEVEL_MINUS140 0x3C 603 | #define RF_AGCREF_LEVEL_MINUS141 0x3D 604 | #define RF_AGCREF_LEVEL_MINUS142 0x3E 605 | #define RF_AGCREF_LEVEL_MINUS143 0x3F 606 | 607 | 608 | // RegAgcThresh1 609 | #define RF_AGCTHRESH1_SNRMARGIN_000 0x00 610 | #define RF_AGCTHRESH1_SNRMARGIN_001 0x20 611 | #define RF_AGCTHRESH1_SNRMARGIN_010 0x40 612 | #define RF_AGCTHRESH1_SNRMARGIN_011 0x60 613 | #define RF_AGCTHRESH1_SNRMARGIN_100 0x80 614 | #define RF_AGCTHRESH1_SNRMARGIN_101 0xA0 // Default 615 | #define RF_AGCTHRESH1_SNRMARGIN_110 0xC0 616 | #define RF_AGCTHRESH1_SNRMARGIN_111 0xE0 617 | 618 | #define RF_AGCTHRESH1_STEP1_0 0x00 619 | #define RF_AGCTHRESH1_STEP1_1 0x01 620 | #define RF_AGCTHRESH1_STEP1_2 0x02 621 | #define RF_AGCTHRESH1_STEP1_3 0x03 622 | #define RF_AGCTHRESH1_STEP1_4 0x04 623 | #define RF_AGCTHRESH1_STEP1_5 0x05 624 | #define RF_AGCTHRESH1_STEP1_6 0x06 625 | #define RF_AGCTHRESH1_STEP1_7 0x07 626 | #define RF_AGCTHRESH1_STEP1_8 0x08 627 | #define RF_AGCTHRESH1_STEP1_9 0x09 628 | #define RF_AGCTHRESH1_STEP1_10 0x0A 629 | #define RF_AGCTHRESH1_STEP1_11 0x0B 630 | #define RF_AGCTHRESH1_STEP1_12 0x0C 631 | #define RF_AGCTHRESH1_STEP1_13 0x0D 632 | #define RF_AGCTHRESH1_STEP1_14 0x0E 633 | #define RF_AGCTHRESH1_STEP1_15 0x0F 634 | #define RF_AGCTHRESH1_STEP1_16 0x10 // Default 635 | #define RF_AGCTHRESH1_STEP1_17 0x11 636 | #define RF_AGCTHRESH1_STEP1_18 0x12 637 | #define RF_AGCTHRESH1_STEP1_19 0x13 638 | #define RF_AGCTHRESH1_STEP1_20 0x14 639 | #define RF_AGCTHRESH1_STEP1_21 0x15 640 | #define RF_AGCTHRESH1_STEP1_22 0x16 641 | #define RF_AGCTHRESH1_STEP1_23 0x17 642 | #define RF_AGCTHRESH1_STEP1_24 0x18 643 | #define RF_AGCTHRESH1_STEP1_25 0x19 644 | #define RF_AGCTHRESH1_STEP1_26 0x1A 645 | #define RF_AGCTHRESH1_STEP1_27 0x1B 646 | #define RF_AGCTHRESH1_STEP1_28 0x1C 647 | #define RF_AGCTHRESH1_STEP1_29 0x1D 648 | #define RF_AGCTHRESH1_STEP1_30 0x1E 649 | #define RF_AGCTHRESH1_STEP1_31 0x1F 650 | 651 | 652 | // RegAgcThresh2 653 | #define RF_AGCTHRESH2_STEP2_0 0x00 654 | #define RF_AGCTHRESH2_STEP2_1 0x10 655 | #define RF_AGCTHRESH2_STEP2_2 0x20 656 | #define RF_AGCTHRESH2_STEP2_3 0x30 // XXX wrong -- Default 657 | #define RF_AGCTHRESH2_STEP2_4 0x40 658 | #define RF_AGCTHRESH2_STEP2_5 0x50 659 | #define RF_AGCTHRESH2_STEP2_6 0x60 660 | #define RF_AGCTHRESH2_STEP2_7 0x70 // default 661 | #define RF_AGCTHRESH2_STEP2_8 0x80 662 | #define RF_AGCTHRESH2_STEP2_9 0x90 663 | #define RF_AGCTHRESH2_STEP2_10 0xA0 664 | #define RF_AGCTHRESH2_STEP2_11 0xB0 665 | #define RF_AGCTHRESH2_STEP2_12 0xC0 666 | #define RF_AGCTHRESH2_STEP2_13 0xD0 667 | #define RF_AGCTHRESH2_STEP2_14 0xE0 668 | #define RF_AGCTHRESH2_STEP2_15 0xF0 669 | 670 | #define RF_AGCTHRESH2_STEP3_0 0x00 671 | #define RF_AGCTHRESH2_STEP3_1 0x01 672 | #define RF_AGCTHRESH2_STEP3_2 0x02 673 | #define RF_AGCTHRESH2_STEP3_3 0x03 674 | #define RF_AGCTHRESH2_STEP3_4 0x04 675 | #define RF_AGCTHRESH2_STEP3_5 0x05 676 | #define RF_AGCTHRESH2_STEP3_6 0x06 677 | #define RF_AGCTHRESH2_STEP3_7 0x07 678 | #define RF_AGCTHRESH2_STEP3_8 0x08 679 | #define RF_AGCTHRESH2_STEP3_9 0x09 680 | #define RF_AGCTHRESH2_STEP3_10 0x0A 681 | #define RF_AGCTHRESH2_STEP3_11 0x0B // Default 682 | #define RF_AGCTHRESH2_STEP3_12 0x0C 683 | #define RF_AGCTHRESH2_STEP3_13 0x0D 684 | #define RF_AGCTHRESH2_STEP3_14 0x0E 685 | #define RF_AGCTHRESH2_STEP3_15 0x0F 686 | 687 | 688 | // RegAgcThresh3 689 | #define RF_AGCTHRESH3_STEP4_0 0x00 690 | #define RF_AGCTHRESH3_STEP4_1 0x10 691 | #define RF_AGCTHRESH3_STEP4_2 0x20 692 | #define RF_AGCTHRESH3_STEP4_3 0x30 693 | #define RF_AGCTHRESH3_STEP4_4 0x40 694 | #define RF_AGCTHRESH3_STEP4_5 0x50 695 | #define RF_AGCTHRESH3_STEP4_6 0x60 696 | #define RF_AGCTHRESH3_STEP4_7 0x70 697 | #define RF_AGCTHRESH3_STEP4_8 0x80 698 | #define RF_AGCTHRESH3_STEP4_9 0x90 // Default 699 | #define RF_AGCTHRESH3_STEP4_10 0xA0 700 | #define RF_AGCTHRESH3_STEP4_11 0xB0 701 | #define RF_AGCTHRESH3_STEP4_12 0xC0 702 | #define RF_AGCTHRESH3_STEP4_13 0xD0 703 | #define RF_AGCTHRESH3_STEP4_14 0xE0 704 | #define RF_AGCTHRESH3_STEP4_15 0xF0 705 | 706 | #define RF_AGCTHRESH3_STEP5_0 0x00 707 | #define RF_AGCTHRESH3_STEP5_1 0x01 708 | #define RF_AGCTHRESH3_STEP5_2 0x02 709 | #define RF_AGCTHRESH3_STEP5_3 0x03 710 | #define RF_AGCTHRESH3_STEP5_4 0x04 711 | #define RF_AGCTHRESH3_STEP5_5 0x05 712 | #define RF_AGCTHRESH3_STEP5_6 0x06 713 | #define RF_AGCTHRESH3_STEP5_7 0x07 714 | #define RF_AGCTHRES33_STEP5_8 0x08 715 | #define RF_AGCTHRESH3_STEP5_9 0x09 716 | #define RF_AGCTHRESH3_STEP5_10 0x0A 717 | #define RF_AGCTHRESH3_STEP5_11 0x0B // Default 718 | #define RF_AGCTHRESH3_STEP5_12 0x0C 719 | #define RF_AGCTHRESH3_STEP5_13 0x0D 720 | #define RF_AGCTHRESH3_STEP5_14 0x0E 721 | #define RF_AGCTHRESH3_STEP5_15 0x0F 722 | 723 | 724 | // RegLna 725 | #define RF_LNA_ZIN_50 0x00 726 | #define RF_LNA_ZIN_200 0x80 // Default 727 | 728 | #define RF_LNA_LOWPOWER_OFF 0x00 // Default 729 | #define RF_LNA_LOWPOWER_ON 0x40 730 | 731 | #define RF_LNA_CURRENTGAIN 0x08 732 | 733 | #define RF_LNA_GAINSELECT_AUTO 0x00 // Default 734 | #define RF_LNA_GAINSELECT_MAX 0x01 735 | #define RF_LNA_GAINSELECT_MAXMINUS6 0x02 736 | #define RF_LNA_GAINSELECT_MAXMINUS12 0x03 737 | #define RF_LNA_GAINSELECT_MAXMINUS24 0x04 738 | #define RF_LNA_GAINSELECT_MAXMINUS36 0x05 739 | #define RF_LNA_GAINSELECT_MAXMINUS48 0x06 740 | 741 | 742 | // RegRxBw 743 | #define RF_RXBW_DCCFREQ_000 0x00 744 | #define RF_RXBW_DCCFREQ_001 0x20 745 | #define RF_RXBW_DCCFREQ_010 0x40 // Default 746 | #define RF_RXBW_DCCFREQ_011 0x60 747 | #define RF_RXBW_DCCFREQ_100 0x80 748 | #define RF_RXBW_DCCFREQ_101 0xA0 749 | #define RF_RXBW_DCCFREQ_110 0xC0 750 | #define RF_RXBW_DCCFREQ_111 0xE0 751 | 752 | #define RF_RXBW_MANT_16 0x00 753 | #define RF_RXBW_MANT_20 0x08 754 | #define RF_RXBW_MANT_24 0x10 // Default 755 | 756 | #define RF_RXBW_EXP_0 0x00 757 | #define RF_RXBW_EXP_1 0x01 758 | #define RF_RXBW_EXP_2 0x02 759 | #define RF_RXBW_EXP_3 0x03 760 | #define RF_RXBW_EXP_4 0x04 761 | #define RF_RXBW_EXP_5 0x05 // Default 762 | #define RF_RXBW_EXP_6 0x06 763 | #define RF_RXBW_EXP_7 0x07 764 | 765 | 766 | // RegAfcBw 767 | #define RF_AFCBW_DCCFREQAFC_000 0x00 768 | #define RF_AFCBW_DCCFREQAFC_001 0x20 769 | #define RF_AFCBW_DCCFREQAFC_010 0x40 770 | #define RF_AFCBW_DCCFREQAFC_011 0x60 771 | #define RF_AFCBW_DCCFREQAFC_100 0x80 // Default 772 | #define RF_AFCBW_DCCFREQAFC_101 0xA0 773 | #define RF_AFCBW_DCCFREQAFC_110 0xC0 774 | #define RF_AFCBW_DCCFREQAFC_111 0xE0 775 | 776 | #define RF_AFCBW_MANTAFC_16 0x00 777 | #define RF_AFCBW_MANTAFC_20 0x08 // Default 778 | #define RF_AFCBW_MANTAFC_24 0x10 779 | 780 | #define RF_AFCBW_EXPAFC_0 0x00 781 | #define RF_AFCBW_EXPAFC_1 0x01 782 | #define RF_AFCBW_EXPAFC_2 0x02 783 | #define RF_AFCBW_EXPAFC_3 0x03 // Default 784 | #define RF_AFCBW_EXPAFC_4 0x04 785 | #define RF_AFCBW_EXPAFC_5 0x05 786 | #define RF_AFCBW_EXPAFC_6 0x06 787 | #define RF_AFCBW_EXPAFC_7 0x07 788 | 789 | 790 | // RegOokPeak 791 | #define RF_OOKPEAK_THRESHTYPE_FIXED 0x00 792 | #define RF_OOKPEAK_THRESHTYPE_PEAK 0x40 // Default 793 | #define RF_OOKPEAK_THRESHTYPE_AVERAGE 0x80 794 | 795 | #define RF_OOKPEAK_PEAKTHRESHSTEP_000 0x00 // Default 796 | #define RF_OOKPEAK_PEAKTHRESHSTEP_001 0x08 797 | #define RF_OOKPEAK_PEAKTHRESHSTEP_010 0x10 798 | #define RF_OOKPEAK_PEAKTHRESHSTEP_011 0x18 799 | #define RF_OOKPEAK_PEAKTHRESHSTEP_100 0x20 800 | #define RF_OOKPEAK_PEAKTHRESHSTEP_101 0x28 801 | #define RF_OOKPEAK_PEAKTHRESHSTEP_110 0x30 802 | #define RF_OOKPEAK_PEAKTHRESHSTEP_111 0x38 803 | 804 | #define RF_OOKPEAK_PEAKTHRESHDEC_000 0x00 // Default 805 | #define RF_OOKPEAK_PEAKTHRESHDEC_001 0x01 806 | #define RF_OOKPEAK_PEAKTHRESHDEC_010 0x02 807 | #define RF_OOKPEAK_PEAKTHRESHDEC_011 0x03 808 | #define RF_OOKPEAK_PEAKTHRESHDEC_100 0x04 809 | #define RF_OOKPEAK_PEAKTHRESHDEC_101 0x05 810 | #define RF_OOKPEAK_PEAKTHRESHDEC_110 0x06 811 | #define RF_OOKPEAK_PEAKTHRESHDEC_111 0x07 812 | 813 | 814 | // RegOokAvg 815 | #define RF_OOKAVG_AVERAGETHRESHFILT_00 0x00 816 | #define RF_OOKAVG_AVERAGETHRESHFILT_01 0x40 817 | #define RF_OOKAVG_AVERAGETHRESHFILT_10 0x80 // Default 818 | #define RF_OOKAVG_AVERAGETHRESHFILT_11 0xC0 819 | 820 | 821 | // RegOokFix 822 | #define RF_OOKFIX_FIXEDTHRESH_VALUE 0x06 // Default 823 | 824 | 825 | // RegAfcFei 826 | #define RF_AFCFEI_FEI_DONE 0x40 827 | #define RF_AFCFEI_FEI_START 0x20 828 | #define RF_AFCFEI_AFC_DONE 0x10 829 | #define RF_AFCFEI_AFCAUTOCLEAR_ON 0x08 830 | #define RF_AFCFEI_AFCAUTOCLEAR_OFF 0x00 // Default 831 | 832 | #define RF_AFCFEI_AFCAUTO_ON 0x04 833 | #define RF_AFCFEI_AFCAUTO_OFF 0x00 // Default 834 | 835 | #define RF_AFCFEI_AFC_CLEAR 0x02 836 | #define RF_AFCFEI_AFC_START 0x01 837 | 838 | // RegRssiConfig 839 | #define RF_RSSI_FASTRX_ON 0x08 840 | #define RF_RSSI_FASTRX_OFF 0x00 // Default 841 | #define RF_RSSI_DONE 0x02 842 | #define RF_RSSI_START 0x01 843 | 844 | 845 | // RegDioMapping1 846 | #define RF_DIOMAPPING1_DIO0_00 0x00 // Default 847 | #define RF_DIOMAPPING1_DIO0_01 0x40 848 | #define RF_DIOMAPPING1_DIO0_10 0x80 849 | #define RF_DIOMAPPING1_DIO0_11 0xC0 850 | 851 | #define RF_DIOMAPPING1_DIO1_00 0x00 // Default 852 | #define RF_DIOMAPPING1_DIO1_01 0x10 853 | #define RF_DIOMAPPING1_DIO1_10 0x20 854 | #define RF_DIOMAPPING1_DIO1_11 0x30 855 | 856 | #define RF_DIOMAPPING1_DIO2_00 0x00 // Default 857 | #define RF_DIOMAPPING1_DIO2_01 0x04 858 | #define RF_DIOMAPPING1_DIO2_10 0x08 859 | #define RF_DIOMAPPING1_DIO2_11 0x0C 860 | 861 | #define RF_DIOMAPPING1_DIO3_00 0x00 // Default 862 | #define RF_DIOMAPPING1_DIO3_01 0x01 863 | #define RF_DIOMAPPING1_DIO3_10 0x02 864 | #define RF_DIOMAPPING1_DIO3_11 0x03 865 | 866 | 867 | // RegDioMapping2 868 | #define RF_DIOMAPPING2_DIO4_00 0x00 // Default 869 | #define RF_DIOMAPPING2_DIO4_01 0x40 870 | #define RF_DIOMAPPING2_DIO4_10 0x80 871 | #define RF_DIOMAPPING2_DIO4_11 0xC0 872 | 873 | #define RF_DIOMAPPING2_DIO5_00 0x00 // Default 874 | #define RF_DIOMAPPING2_DIO5_01 0x10 875 | #define RF_DIOMAPPING2_DIO5_10 0x20 876 | #define RF_DIOMAPPING2_DIO5_11 0x30 877 | 878 | #define RF_DIOMAPPING2_CLKOUT_32 0x00 879 | #define RF_DIOMAPPING2_CLKOUT_16 0x01 880 | #define RF_DIOMAPPING2_CLKOUT_8 0x02 881 | #define RF_DIOMAPPING2_CLKOUT_4 0x03 882 | #define RF_DIOMAPPING2_CLKOUT_2 0x04 883 | #define RF_DIOMAPPING2_CLKOUT_1 0x05 884 | #define RF_DIOMAPPING2_CLKOUT_RC 0x06 885 | #define RF_DIOMAPPING2_CLKOUT_OFF 0x07 // Default 886 | 887 | 888 | // RegIrqFlags1 889 | #define RF_IRQFLAGS1_MODEREADY 0x80 890 | #define RF_IRQFLAGS1_RXREADY 0x40 891 | #define RF_IRQFLAGS1_TXREADY 0x20 892 | #define RF_IRQFLAGS1_PLLLOCK 0x10 893 | #define RF_IRQFLAGS1_RSSI 0x08 894 | #define RF_IRQFLAGS1_TIMEOUT 0x04 895 | #define RF_IRQFLAGS1_AUTOMODE 0x02 896 | #define RF_IRQFLAGS1_SYNCADDRESSMATCH 0x01 897 | 898 | // RegIrqFlags2 899 | #define RF_IRQFLAGS2_FIFOFULL 0x80 900 | #define RF_IRQFLAGS2_FIFONOTEMPTY 0x40 901 | #define RF_IRQFLAGS2_FIFOLEVEL 0x20 902 | #define RF_IRQFLAGS2_FIFOOVERRUN 0x10 903 | #define RF_IRQFLAGS2_PACKETSENT 0x08 904 | #define RF_IRQFLAGS2_PAYLOADREADY 0x04 905 | #define RF_IRQFLAGS2_CRCOK 0x02 906 | #define RF_IRQFLAGS2_LOWBAT 0x01 907 | 908 | // RegRssiThresh 909 | #define RF_RSSITHRESH_VALUE 0xE4 // Default 910 | 911 | // RegRxTimeout1 912 | #define RF_RXTIMEOUT1_RXSTART_VALUE 0x00 // Default 913 | 914 | // RegRxTimeout2 915 | #define RF_RXTIMEOUT2_RSSITHRESH_VALUE 0x00 // Default 916 | 917 | // RegPreamble 918 | #define RF_PREAMBLESIZE_MSB_VALUE 0x00 // Default 919 | #define RF_PREAMBLESIZE_LSB_VALUE 0x03 // Default 920 | 921 | 922 | // RegSyncConfig 923 | #define RF_SYNC_ON 0x80 // Default 924 | #define RF_SYNC_OFF 0x00 925 | 926 | #define RF_SYNC_FIFOFILL_AUTO 0x00 // Default -- when sync interrupt occurs 927 | #define RF_SYNC_FIFOFILL_MANUAL 0x40 928 | 929 | #define RF_SYNC_SIZE_1 0x00 930 | #define RF_SYNC_SIZE_2 0x08 931 | #define RF_SYNC_SIZE_3 0x10 932 | #define RF_SYNC_SIZE_4 0x18 // Default 933 | #define RF_SYNC_SIZE_5 0x20 934 | #define RF_SYNC_SIZE_6 0x28 935 | #define RF_SYNC_SIZE_7 0x30 936 | #define RF_SYNC_SIZE_8 0x38 937 | 938 | #define RF_SYNC_TOL_0 0x00 // Default 939 | #define RF_SYNC_TOL_1 0x01 940 | #define RF_SYNC_TOL_2 0x02 941 | #define RF_SYNC_TOL_3 0x03 942 | #define RF_SYNC_TOL_4 0x04 943 | #define RF_SYNC_TOL_5 0x05 944 | #define RF_SYNC_TOL_6 0x06 945 | #define RF_SYNC_TOL_7 0x07 946 | 947 | 948 | // RegSyncValue1-8 949 | #define RF_SYNC_BYTE1_VALUE 0x00 // Default 950 | #define RF_SYNC_BYTE2_VALUE 0x00 // Default 951 | #define RF_SYNC_BYTE3_VALUE 0x00 // Default 952 | #define RF_SYNC_BYTE4_VALUE 0x00 // Default 953 | #define RF_SYNC_BYTE5_VALUE 0x00 // Default 954 | #define RF_SYNC_BYTE6_VALUE 0x00 // Default 955 | #define RF_SYNC_BYTE7_VALUE 0x00 // Default 956 | #define RF_SYNC_BYTE8_VALUE 0x00 // Default 957 | 958 | 959 | // RegPacketConfig1 960 | #define RF_PACKET1_FORMAT_FIXED 0x00 // Default 961 | #define RF_PACKET1_FORMAT_VARIABLE 0x80 962 | 963 | #define RF_PACKET1_DCFREE_OFF 0x00 // Default 964 | #define RF_PACKET1_DCFREE_MANCHESTER 0x20 965 | #define RF_PACKET1_DCFREE_WHITENING 0x40 966 | 967 | #define RF_PACKET1_CRC_ON 0x10 // Default 968 | #define RF_PACKET1_CRC_OFF 0x00 969 | 970 | #define RF_PACKET1_CRCAUTOCLEAR_ON 0x00 // Default 971 | #define RF_PACKET1_CRCAUTOCLEAR_OFF 0x08 972 | 973 | #define RF_PACKET1_ADRSFILTERING_OFF 0x00 // Default 974 | #define RF_PACKET1_ADRSFILTERING_NODE 0x02 975 | #define RF_PACKET1_ADRSFILTERING_NODEBROADCAST 0x04 976 | 977 | 978 | // RegPayloadLength 979 | #define RF_PAYLOADLENGTH_VALUE 0x40 // Default 980 | 981 | // RegBroadcastAdrs 982 | #define RF_BROADCASTADDRESS_VALUE 0x00 983 | 984 | 985 | // RegAutoModes 986 | #define RF_AUTOMODES_ENTER_OFF 0x00 // Default 987 | #define RF_AUTOMODES_ENTER_FIFONOTEMPTY 0x20 988 | #define RF_AUTOMODES_ENTER_FIFOLEVEL 0x40 989 | #define RF_AUTOMODES_ENTER_CRCOK 0x60 990 | #define RF_AUTOMODES_ENTER_PAYLOADREADY 0x80 991 | #define RF_AUTOMODES_ENTER_SYNCADRSMATCH 0xA0 992 | #define RF_AUTOMODES_ENTER_PACKETSENT 0xC0 993 | #define RF_AUTOMODES_ENTER_FIFOEMPTY 0xE0 994 | 995 | #define RF_AUTOMODES_EXIT_OFF 0x00 // Default 996 | #define RF_AUTOMODES_EXIT_FIFOEMPTY 0x04 997 | #define RF_AUTOMODES_EXIT_FIFOLEVEL 0x08 998 | #define RF_AUTOMODES_EXIT_CRCOK 0x0C 999 | #define RF_AUTOMODES_EXIT_PAYLOADREADY 0x10 1000 | #define RF_AUTOMODES_EXIT_SYNCADRSMATCH 0x14 1001 | #define RF_AUTOMODES_EXIT_PACKETSENT 0x18 1002 | #define RF_AUTOMODES_EXIT_RXTIMEOUT 0x1C 1003 | 1004 | #define RF_AUTOMODES_INTERMEDIATE_SLEEP 0x00 // Default 1005 | #define RF_AUTOMODES_INTERMEDIATE_STANDBY 0x01 1006 | #define RF_AUTOMODES_INTERMEDIATE_RECEIVER 0x02 1007 | #define RF_AUTOMODES_INTERMEDIATE_TRANSMITTER 0x03 1008 | 1009 | 1010 | // RegFifoThresh 1011 | #define RF_FIFOTHRESH_TXSTART_FIFOTHRESH 0x00 1012 | #define RF_FIFOTHRESH_TXSTART_FIFONOTEMPTY 0x80 // Default 1013 | 1014 | #define RF_FIFOTHRESH_VALUE 0x0F // Default 1015 | 1016 | 1017 | // RegPacketConfig2 1018 | #define RF_PACKET2_RXRESTARTDELAY_1BIT 0x00 // Default 1019 | #define RF_PACKET2_RXRESTARTDELAY_2BITS 0x10 1020 | #define RF_PACKET2_RXRESTARTDELAY_4BITS 0x20 1021 | #define RF_PACKET2_RXRESTARTDELAY_8BITS 0x30 1022 | #define RF_PACKET2_RXRESTARTDELAY_16BITS 0x40 1023 | #define RF_PACKET2_RXRESTARTDELAY_32BITS 0x50 1024 | #define RF_PACKET2_RXRESTARTDELAY_64BITS 0x60 1025 | #define RF_PACKET2_RXRESTARTDELAY_128BITS 0x70 1026 | #define RF_PACKET2_RXRESTARTDELAY_256BITS 0x80 1027 | #define RF_PACKET2_RXRESTARTDELAY_512BITS 0x90 1028 | #define RF_PACKET2_RXRESTARTDELAY_1024BITS 0xA0 1029 | #define RF_PACKET2_RXRESTARTDELAY_2048BITS 0xB0 1030 | #define RF_PACKET2_RXRESTARTDELAY_NONE 0xC0 1031 | #define RF_PACKET2_RXRESTART 0x04 1032 | 1033 | #define RF_PACKET2_AUTORXRESTART_ON 0x02 // Default 1034 | #define RF_PACKET2_AUTORXRESTART_OFF 0x00 1035 | 1036 | #define RF_PACKET2_AES_ON 0x01 1037 | #define RF_PACKET2_AES_OFF 0x00 // Default 1038 | 1039 | 1040 | // RegAesKey1-16 1041 | #define RF_AESKEY1_VALUE 0x00 // Default 1042 | #define RF_AESKEY2_VALUE 0x00 // Default 1043 | #define RF_AESKEY3_VALUE 0x00 // Default 1044 | #define RF_AESKEY4_VALUE 0x00 // Default 1045 | #define RF_AESKEY5_VALUE 0x00 // Default 1046 | #define RF_AESKEY6_VALUE 0x00 // Default 1047 | #define RF_AESKEY7_VALUE 0x00 // Default 1048 | #define RF_AESKEY8_VALUE 0x00 // Default 1049 | #define RF_AESKEY9_VALUE 0x00 // Default 1050 | #define RF_AESKEY10_VALUE 0x00 // Default 1051 | #define RF_AESKEY11_VALUE 0x00 // Default 1052 | #define RF_AESKEY12_VALUE 0x00 // Default 1053 | #define RF_AESKEY13_VALUE 0x00 // Default 1054 | #define RF_AESKEY14_VALUE 0x00 // Default 1055 | #define RF_AESKEY15_VALUE 0x00 // Default 1056 | #define RF_AESKEY16_VALUE 0x00 // Default 1057 | 1058 | 1059 | // RegTemp1 1060 | #define RF_TEMP1_MEAS_START 0x08 1061 | #define RF_TEMP1_MEAS_RUNNING 0x04 1062 | #define RF_TEMP1_ADCLOWPOWER_ON 0x01 // Default 1063 | #define RF_TEMP1_ADCLOWPOWER_OFF 0x00 1064 | 1065 | // RegTestDagc 0x6F: demodulator config and IO mode config 1066 | #define RF_DAGC_NORMAL 0x00 // Reset value 1067 | #define RF_DAGC_IMPROVED_LOWBETA1 0x20 // 1068 | #define RF_DAGC_IMPROVED_LOWBETA0 0x30 // Recommended default 1069 | 1070 | --------------------------------------------------------------------------------