Port of aduino LoRa library from https://github.com/sandeepmistry/arduino-LoRa
Dependents: WeatherStationRemote
LoRa.cpp@1:8b16ccb7ea3f, 2018-01-24 (annotated)
- Committer:
- fadhlika
- Date:
- Wed Jan 24 10:51:18 2018 +0000
- Revision:
- 1:8b16ccb7ea3f
- Parent:
- 0:c28964675044
enable callback
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
fadhlika | 0:c28964675044 | 1 | #include <LoRa.h> |
fadhlika | 0:c28964675044 | 2 | |
fadhlika | 0:c28964675044 | 3 | // registers |
fadhlika | 0:c28964675044 | 4 | #define REG_FIFO 0x00 |
fadhlika | 0:c28964675044 | 5 | #define REG_OP_MODE 0x01 |
fadhlika | 0:c28964675044 | 6 | #define REG_FRF_MSB 0x06 |
fadhlika | 0:c28964675044 | 7 | #define REG_FRF_MID 0x07 |
fadhlika | 0:c28964675044 | 8 | #define REG_FRF_LSB 0x08 |
fadhlika | 0:c28964675044 | 9 | #define REG_PA_CONFIG 0x09 |
fadhlika | 0:c28964675044 | 10 | #define REG_LNA 0x0c |
fadhlika | 0:c28964675044 | 11 | #define REG_FIFO_ADDR_PTR 0x0d |
fadhlika | 0:c28964675044 | 12 | #define REG_FIFO_TX_BASE_ADDR 0x0e |
fadhlika | 0:c28964675044 | 13 | #define REG_FIFO_RX_BASE_ADDR 0x0f |
fadhlika | 0:c28964675044 | 14 | #define REG_FIFO_RX_CURRENT_ADDR 0x10 |
fadhlika | 0:c28964675044 | 15 | #define REG_IRQ_FLAGS 0x12 |
fadhlika | 0:c28964675044 | 16 | #define REG_RX_NB_BYTES 0x13 |
fadhlika | 0:c28964675044 | 17 | #define REG_PKT_RSSI_VALUE 0x1a |
fadhlika | 0:c28964675044 | 18 | #define REG_PKT_SNR_VALUE 0x1b |
fadhlika | 0:c28964675044 | 19 | #define REG_MODEM_CONFIG_1 0x1d |
fadhlika | 0:c28964675044 | 20 | #define REG_MODEM_CONFIG_2 0x1e |
fadhlika | 0:c28964675044 | 21 | #define REG_PREAMBLE_MSB 0x20 |
fadhlika | 0:c28964675044 | 22 | #define REG_PREAMBLE_LSB 0x21 |
fadhlika | 0:c28964675044 | 23 | #define REG_PAYLOAD_LENGTH 0x22 |
fadhlika | 0:c28964675044 | 24 | #define REG_MODEM_CONFIG_3 0x26 |
fadhlika | 0:c28964675044 | 25 | #define REG_RSSI_WIDEBAND 0x2c |
fadhlika | 0:c28964675044 | 26 | #define REG_DETECTION_OPTIMIZE 0x31 |
fadhlika | 0:c28964675044 | 27 | #define REG_DETECTION_THRESHOLD 0x37 |
fadhlika | 0:c28964675044 | 28 | #define REG_SYNC_WORD 0x39 |
fadhlika | 0:c28964675044 | 29 | #define REG_DIO_MAPPING_1 0x40 |
fadhlika | 0:c28964675044 | 30 | #define REG_VERSION 0x42 |
fadhlika | 0:c28964675044 | 31 | |
fadhlika | 0:c28964675044 | 32 | // modes |
fadhlika | 0:c28964675044 | 33 | #define MODE_LONG_RANGE_MODE 0x80 |
fadhlika | 0:c28964675044 | 34 | #define MODE_SLEEP 0x00 |
fadhlika | 0:c28964675044 | 35 | #define MODE_STDBY 0x01 |
fadhlika | 0:c28964675044 | 36 | #define MODE_TX 0x03 |
fadhlika | 0:c28964675044 | 37 | #define MODE_RX_CONTINUOUS 0x05 |
fadhlika | 0:c28964675044 | 38 | #define MODE_RX_SINGLE 0x06 |
fadhlika | 0:c28964675044 | 39 | |
fadhlika | 0:c28964675044 | 40 | // PA config |
fadhlika | 0:c28964675044 | 41 | #define PA_BOOST 0x80 |
fadhlika | 0:c28964675044 | 42 | |
fadhlika | 0:c28964675044 | 43 | // IRQ masks |
fadhlika | 0:c28964675044 | 44 | #define IRQ_TX_DONE_MASK 0x08 |
fadhlika | 0:c28964675044 | 45 | #define IRQ_PAYLOAD_CRC_ERROR_MASK 0x20 |
fadhlika | 0:c28964675044 | 46 | #define IRQ_RX_DONE_MASK 0x40 |
fadhlika | 0:c28964675044 | 47 | |
fadhlika | 0:c28964675044 | 48 | #define MAX_PKT_LENGTH 255 |
fadhlika | 0:c28964675044 | 49 | |
fadhlika | 0:c28964675044 | 50 | SPI _spi(PA_7, PB_4, PA_5); |
fadhlika | 0:c28964675044 | 51 | |
fadhlika | 0:c28964675044 | 52 | LoRaClass::LoRaClass() : |
fadhlika | 0:c28964675044 | 53 | spi(_spi), |
fadhlika | 0:c28964675044 | 54 | _ss(LORA_DEFAULT_SS_PIN ), _reset(LORA_DEFAULT_RESET_PIN), _dio0(LORA_DEFAULT_DIO0_PIN), |
fadhlika | 0:c28964675044 | 55 | _frequency(0), |
fadhlika | 0:c28964675044 | 56 | _packetIndex(0), |
fadhlika | 0:c28964675044 | 57 | _implicitHeaderMode(0), |
fadhlika | 0:c28964675044 | 58 | _onReceive(NULL) |
fadhlika | 0:c28964675044 | 59 | { |
fadhlika | 0:c28964675044 | 60 | // overide Stream timeout value |
fadhlika | 0:c28964675044 | 61 | //setTimeout(0); |
fadhlika | 0:c28964675044 | 62 | } |
fadhlika | 0:c28964675044 | 63 | |
fadhlika | 0:c28964675044 | 64 | int LoRaClass::begin(long frequency) |
fadhlika | 0:c28964675044 | 65 | { |
fadhlika | 0:c28964675044 | 66 | // perform reset |
fadhlika | 0:c28964675044 | 67 | _reset = 0; |
fadhlika | 0:c28964675044 | 68 | wait(0.010); |
fadhlika | 0:c28964675044 | 69 | _reset = 1; |
fadhlika | 0:c28964675044 | 70 | wait(0.010); |
fadhlika | 0:c28964675044 | 71 | |
fadhlika | 0:c28964675044 | 72 | // set SS high |
fadhlika | 0:c28964675044 | 73 | _ss = 1; |
fadhlika | 0:c28964675044 | 74 | |
fadhlika | 0:c28964675044 | 75 | // check version |
fadhlika | 0:c28964675044 | 76 | uint8_t version = readRegister(REG_VERSION); |
fadhlika | 0:c28964675044 | 77 | if (version != 0x12) { |
fadhlika | 0:c28964675044 | 78 | return 0; |
fadhlika | 0:c28964675044 | 79 | } |
fadhlika | 0:c28964675044 | 80 | |
fadhlika | 0:c28964675044 | 81 | // put in sleep mode |
fadhlika | 0:c28964675044 | 82 | sleep(); |
fadhlika | 0:c28964675044 | 83 | |
fadhlika | 0:c28964675044 | 84 | // set frequency |
fadhlika | 0:c28964675044 | 85 | setFrequency(frequency); |
fadhlika | 0:c28964675044 | 86 | |
fadhlika | 0:c28964675044 | 87 | // set base addresses |
fadhlika | 0:c28964675044 | 88 | writeRegister(REG_FIFO_TX_BASE_ADDR, 0); |
fadhlika | 0:c28964675044 | 89 | writeRegister(REG_FIFO_RX_BASE_ADDR, 0); |
fadhlika | 0:c28964675044 | 90 | |
fadhlika | 0:c28964675044 | 91 | // set LNA boost |
fadhlika | 0:c28964675044 | 92 | writeRegister(REG_LNA, readRegister(REG_LNA) | 0x03); |
fadhlika | 0:c28964675044 | 93 | |
fadhlika | 0:c28964675044 | 94 | // set auto AGC |
fadhlika | 0:c28964675044 | 95 | writeRegister(REG_MODEM_CONFIG_3, 0x04); |
fadhlika | 0:c28964675044 | 96 | |
fadhlika | 0:c28964675044 | 97 | // set output power to 17 dBm |
fadhlika | 0:c28964675044 | 98 | setTxPower(17); |
fadhlika | 0:c28964675044 | 99 | |
fadhlika | 0:c28964675044 | 100 | // put in standby mode |
fadhlika | 0:c28964675044 | 101 | idle(); |
fadhlika | 0:c28964675044 | 102 | |
fadhlika | 0:c28964675044 | 103 | return 1; |
fadhlika | 0:c28964675044 | 104 | } |
fadhlika | 0:c28964675044 | 105 | |
fadhlika | 0:c28964675044 | 106 | void LoRaClass::end() |
fadhlika | 0:c28964675044 | 107 | { |
fadhlika | 0:c28964675044 | 108 | // put in sleep mode |
fadhlika | 0:c28964675044 | 109 | sleep(); |
fadhlika | 0:c28964675044 | 110 | } |
fadhlika | 0:c28964675044 | 111 | |
fadhlika | 0:c28964675044 | 112 | int LoRaClass::beginPacket(int implicitHeader) |
fadhlika | 0:c28964675044 | 113 | { |
fadhlika | 0:c28964675044 | 114 | // put in standby mode |
fadhlika | 0:c28964675044 | 115 | idle(); |
fadhlika | 0:c28964675044 | 116 | |
fadhlika | 0:c28964675044 | 117 | if (implicitHeader) { |
fadhlika | 0:c28964675044 | 118 | implicitHeaderMode(); |
fadhlika | 0:c28964675044 | 119 | } else { |
fadhlika | 0:c28964675044 | 120 | explicitHeaderMode(); |
fadhlika | 0:c28964675044 | 121 | } |
fadhlika | 0:c28964675044 | 122 | |
fadhlika | 0:c28964675044 | 123 | // reset FIFO address and paload length |
fadhlika | 0:c28964675044 | 124 | writeRegister(REG_FIFO_ADDR_PTR, 0); |
fadhlika | 0:c28964675044 | 125 | writeRegister(REG_PAYLOAD_LENGTH, 0); |
fadhlika | 0:c28964675044 | 126 | |
fadhlika | 0:c28964675044 | 127 | return 1; |
fadhlika | 0:c28964675044 | 128 | } |
fadhlika | 0:c28964675044 | 129 | |
fadhlika | 0:c28964675044 | 130 | int LoRaClass::endPacket() |
fadhlika | 0:c28964675044 | 131 | { |
fadhlika | 0:c28964675044 | 132 | // put in TX mode |
fadhlika | 0:c28964675044 | 133 | writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_TX); |
fadhlika | 0:c28964675044 | 134 | |
fadhlika | 0:c28964675044 | 135 | // wait for TX done |
fadhlika | 0:c28964675044 | 136 | while((readRegister(REG_IRQ_FLAGS) & IRQ_TX_DONE_MASK) == 0); |
fadhlika | 0:c28964675044 | 137 | |
fadhlika | 0:c28964675044 | 138 | // clear IRQ's |
fadhlika | 0:c28964675044 | 139 | writeRegister(REG_IRQ_FLAGS, IRQ_TX_DONE_MASK); |
fadhlika | 0:c28964675044 | 140 | |
fadhlika | 0:c28964675044 | 141 | return 1; |
fadhlika | 0:c28964675044 | 142 | } |
fadhlika | 0:c28964675044 | 143 | |
fadhlika | 0:c28964675044 | 144 | int LoRaClass::parsePacket(int size) |
fadhlika | 0:c28964675044 | 145 | { |
fadhlika | 0:c28964675044 | 146 | int packetLength = 0; |
fadhlika | 0:c28964675044 | 147 | int irqFlags = readRegister(REG_IRQ_FLAGS); |
fadhlika | 0:c28964675044 | 148 | |
fadhlika | 0:c28964675044 | 149 | if (size > 0) { |
fadhlika | 0:c28964675044 | 150 | implicitHeaderMode(); |
fadhlika | 0:c28964675044 | 151 | |
fadhlika | 0:c28964675044 | 152 | writeRegister(REG_PAYLOAD_LENGTH, size & 0xff); |
fadhlika | 0:c28964675044 | 153 | } else { |
fadhlika | 0:c28964675044 | 154 | explicitHeaderMode(); |
fadhlika | 0:c28964675044 | 155 | } |
fadhlika | 0:c28964675044 | 156 | |
fadhlika | 0:c28964675044 | 157 | // clear IRQ's |
fadhlika | 0:c28964675044 | 158 | writeRegister(REG_IRQ_FLAGS, irqFlags); |
fadhlika | 0:c28964675044 | 159 | |
fadhlika | 0:c28964675044 | 160 | if ((irqFlags & IRQ_RX_DONE_MASK) && (irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0) { |
fadhlika | 0:c28964675044 | 161 | // received a packet |
fadhlika | 0:c28964675044 | 162 | _packetIndex = 0; |
fadhlika | 0:c28964675044 | 163 | |
fadhlika | 0:c28964675044 | 164 | // read packet length |
fadhlika | 0:c28964675044 | 165 | if (_implicitHeaderMode) { |
fadhlika | 0:c28964675044 | 166 | packetLength = readRegister(REG_PAYLOAD_LENGTH); |
fadhlika | 0:c28964675044 | 167 | } else { |
fadhlika | 0:c28964675044 | 168 | packetLength = readRegister(REG_RX_NB_BYTES); |
fadhlika | 0:c28964675044 | 169 | } |
fadhlika | 0:c28964675044 | 170 | |
fadhlika | 0:c28964675044 | 171 | // set FIFO address to current RX address |
fadhlika | 0:c28964675044 | 172 | writeRegister(REG_FIFO_ADDR_PTR, readRegister(REG_FIFO_RX_CURRENT_ADDR)); |
fadhlika | 0:c28964675044 | 173 | |
fadhlika | 0:c28964675044 | 174 | // put in standby mode |
fadhlika | 0:c28964675044 | 175 | idle(); |
fadhlika | 0:c28964675044 | 176 | } else if (readRegister(REG_OP_MODE) != (MODE_LONG_RANGE_MODE | MODE_RX_SINGLE)) { |
fadhlika | 0:c28964675044 | 177 | // not currently in RX mode |
fadhlika | 0:c28964675044 | 178 | |
fadhlika | 0:c28964675044 | 179 | // reset FIFO address |
fadhlika | 0:c28964675044 | 180 | writeRegister(REG_FIFO_ADDR_PTR, 0); |
fadhlika | 0:c28964675044 | 181 | |
fadhlika | 0:c28964675044 | 182 | // put in single RX mode |
fadhlika | 0:c28964675044 | 183 | writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_SINGLE); |
fadhlika | 0:c28964675044 | 184 | } |
fadhlika | 0:c28964675044 | 185 | |
fadhlika | 0:c28964675044 | 186 | return packetLength; |
fadhlika | 0:c28964675044 | 187 | } |
fadhlika | 0:c28964675044 | 188 | |
fadhlika | 0:c28964675044 | 189 | int LoRaClass::packetRssi() |
fadhlika | 0:c28964675044 | 190 | { |
fadhlika | 0:c28964675044 | 191 | return (readRegister(REG_PKT_RSSI_VALUE) - (_frequency < 868E6 ? 164 : 157)); |
fadhlika | 0:c28964675044 | 192 | } |
fadhlika | 0:c28964675044 | 193 | |
fadhlika | 0:c28964675044 | 194 | float LoRaClass::packetSnr() |
fadhlika | 0:c28964675044 | 195 | { |
fadhlika | 0:c28964675044 | 196 | return ((int8_t)readRegister(REG_PKT_SNR_VALUE)) * 0.25; |
fadhlika | 0:c28964675044 | 197 | } |
fadhlika | 0:c28964675044 | 198 | |
fadhlika | 0:c28964675044 | 199 | int LoRaClass::_putc(int value) |
fadhlika | 0:c28964675044 | 200 | { |
fadhlika | 0:c28964675044 | 201 | char buf = (char) value; |
fadhlika | 0:c28964675044 | 202 | size_t size = sizeof(buf); |
fadhlika | 0:c28964675044 | 203 | int currentLength = readRegister(REG_PAYLOAD_LENGTH); |
fadhlika | 0:c28964675044 | 204 | |
fadhlika | 0:c28964675044 | 205 | // check size |
fadhlika | 0:c28964675044 | 206 | if ((currentLength + size) > MAX_PKT_LENGTH) { |
fadhlika | 0:c28964675044 | 207 | size = MAX_PKT_LENGTH - currentLength; |
fadhlika | 0:c28964675044 | 208 | } |
fadhlika | 0:c28964675044 | 209 | |
fadhlika | 0:c28964675044 | 210 | writeRegister(REG_FIFO, buf); |
fadhlika | 0:c28964675044 | 211 | |
fadhlika | 0:c28964675044 | 212 | // update length |
fadhlika | 0:c28964675044 | 213 | writeRegister(REG_PAYLOAD_LENGTH, currentLength + size); |
fadhlika | 0:c28964675044 | 214 | |
fadhlika | 0:c28964675044 | 215 | return (int) buf; |
fadhlika | 0:c28964675044 | 216 | } |
fadhlika | 0:c28964675044 | 217 | |
fadhlika | 0:c28964675044 | 218 | int LoRaClass::available() |
fadhlika | 0:c28964675044 | 219 | { |
fadhlika | 0:c28964675044 | 220 | return (readRegister(REG_RX_NB_BYTES) - _packetIndex); |
fadhlika | 0:c28964675044 | 221 | } |
fadhlika | 0:c28964675044 | 222 | |
fadhlika | 0:c28964675044 | 223 | int LoRaClass::_getc() |
fadhlika | 0:c28964675044 | 224 | { |
fadhlika | 0:c28964675044 | 225 | if (!available()) { |
fadhlika | 0:c28964675044 | 226 | return -1; |
fadhlika | 0:c28964675044 | 227 | } |
fadhlika | 0:c28964675044 | 228 | |
fadhlika | 0:c28964675044 | 229 | _packetIndex++; |
fadhlika | 0:c28964675044 | 230 | |
fadhlika | 0:c28964675044 | 231 | return readRegister(REG_FIFO); |
fadhlika | 0:c28964675044 | 232 | } |
fadhlika | 0:c28964675044 | 233 | |
fadhlika | 0:c28964675044 | 234 | int LoRaClass::peek() |
fadhlika | 0:c28964675044 | 235 | { |
fadhlika | 0:c28964675044 | 236 | if (!available()) { |
fadhlika | 0:c28964675044 | 237 | return -1; |
fadhlika | 0:c28964675044 | 238 | } |
fadhlika | 0:c28964675044 | 239 | |
fadhlika | 0:c28964675044 | 240 | // store current FIFO address |
fadhlika | 0:c28964675044 | 241 | int currentAddress = readRegister(REG_FIFO_ADDR_PTR); |
fadhlika | 0:c28964675044 | 242 | |
fadhlika | 0:c28964675044 | 243 | // read |
fadhlika | 0:c28964675044 | 244 | uint8_t b = readRegister(REG_FIFO); |
fadhlika | 0:c28964675044 | 245 | |
fadhlika | 0:c28964675044 | 246 | // restore FIFO address |
fadhlika | 0:c28964675044 | 247 | writeRegister(REG_FIFO_ADDR_PTR, currentAddress); |
fadhlika | 0:c28964675044 | 248 | |
fadhlika | 0:c28964675044 | 249 | return b; |
fadhlika | 0:c28964675044 | 250 | } |
fadhlika | 0:c28964675044 | 251 | |
fadhlika | 0:c28964675044 | 252 | void LoRaClass::onReceive(void(*callback)(int)) |
fadhlika | 0:c28964675044 | 253 | { |
fadhlika | 0:c28964675044 | 254 | _onReceive = callback; |
fadhlika | 0:c28964675044 | 255 | |
fadhlika | 0:c28964675044 | 256 | if (callback) { |
fadhlika | 0:c28964675044 | 257 | writeRegister(REG_DIO_MAPPING_1, 0x00); |
fadhlika | 0:c28964675044 | 258 | |
fadhlika | 0:c28964675044 | 259 | //attachInterrupt(digitalPinToInterrupt(_dio0), LoRaClass::onDio0Rise, RISING); |
fadhlika | 1:8b16ccb7ea3f | 260 | _dio0.rise(&LoRaClass::onDio0Rise); |
fadhlika | 0:c28964675044 | 261 | } else { |
fadhlika | 0:c28964675044 | 262 | //detachInterrupt(digitalPinToInterrupt(_dio0)); |
fadhlika | 1:8b16ccb7ea3f | 263 | _dio0.rise(NULL); |
fadhlika | 0:c28964675044 | 264 | } |
fadhlika | 0:c28964675044 | 265 | } |
fadhlika | 0:c28964675044 | 266 | |
fadhlika | 0:c28964675044 | 267 | void LoRaClass::receive(int size) |
fadhlika | 0:c28964675044 | 268 | { |
fadhlika | 0:c28964675044 | 269 | if (size > 0) { |
fadhlika | 0:c28964675044 | 270 | implicitHeaderMode(); |
fadhlika | 0:c28964675044 | 271 | |
fadhlika | 0:c28964675044 | 272 | writeRegister(REG_PAYLOAD_LENGTH, size & 0xff); |
fadhlika | 0:c28964675044 | 273 | } else { |
fadhlika | 0:c28964675044 | 274 | explicitHeaderMode(); |
fadhlika | 0:c28964675044 | 275 | } |
fadhlika | 0:c28964675044 | 276 | |
fadhlika | 0:c28964675044 | 277 | writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_RX_CONTINUOUS); |
fadhlika | 0:c28964675044 | 278 | } |
fadhlika | 0:c28964675044 | 279 | |
fadhlika | 0:c28964675044 | 280 | void LoRaClass::idle() |
fadhlika | 0:c28964675044 | 281 | { |
fadhlika | 0:c28964675044 | 282 | writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_STDBY); |
fadhlika | 0:c28964675044 | 283 | } |
fadhlika | 0:c28964675044 | 284 | |
fadhlika | 0:c28964675044 | 285 | void LoRaClass::sleep() |
fadhlika | 0:c28964675044 | 286 | { |
fadhlika | 0:c28964675044 | 287 | writeRegister(REG_OP_MODE, MODE_LONG_RANGE_MODE | MODE_SLEEP); |
fadhlika | 0:c28964675044 | 288 | } |
fadhlika | 0:c28964675044 | 289 | |
fadhlika | 0:c28964675044 | 290 | void LoRaClass::setTxPower(int level, int outputPin) |
fadhlika | 0:c28964675044 | 291 | { |
fadhlika | 0:c28964675044 | 292 | if (PA_OUTPUT_RFO_PIN == outputPin) { |
fadhlika | 0:c28964675044 | 293 | // RFO |
fadhlika | 0:c28964675044 | 294 | if (level < 0) { |
fadhlika | 0:c28964675044 | 295 | level = 0; |
fadhlika | 0:c28964675044 | 296 | } else if (level > 14) { |
fadhlika | 0:c28964675044 | 297 | level = 14; |
fadhlika | 0:c28964675044 | 298 | } |
fadhlika | 0:c28964675044 | 299 | |
fadhlika | 0:c28964675044 | 300 | writeRegister(REG_PA_CONFIG, 0x70 | level); |
fadhlika | 0:c28964675044 | 301 | } else { |
fadhlika | 0:c28964675044 | 302 | // PA BOOST |
fadhlika | 0:c28964675044 | 303 | if (level < 2) { |
fadhlika | 0:c28964675044 | 304 | level = 2; |
fadhlika | 0:c28964675044 | 305 | } else if (level > 17) { |
fadhlika | 0:c28964675044 | 306 | level = 17; |
fadhlika | 0:c28964675044 | 307 | } |
fadhlika | 0:c28964675044 | 308 | |
fadhlika | 0:c28964675044 | 309 | writeRegister(REG_PA_CONFIG, PA_BOOST | (level - 2)); |
fadhlika | 0:c28964675044 | 310 | } |
fadhlika | 0:c28964675044 | 311 | } |
fadhlika | 0:c28964675044 | 312 | |
fadhlika | 0:c28964675044 | 313 | void LoRaClass::setFrequency(long frequency) |
fadhlika | 0:c28964675044 | 314 | { |
fadhlika | 0:c28964675044 | 315 | _frequency = frequency; |
fadhlika | 0:c28964675044 | 316 | |
fadhlika | 0:c28964675044 | 317 | uint64_t frf = ((uint64_t)frequency << 19) / 32000000; |
fadhlika | 0:c28964675044 | 318 | |
fadhlika | 0:c28964675044 | 319 | writeRegister(REG_FRF_MSB, (uint8_t)(frf >> 16)); |
fadhlika | 0:c28964675044 | 320 | writeRegister(REG_FRF_MID, (uint8_t)(frf >> 8)); |
fadhlika | 0:c28964675044 | 321 | writeRegister(REG_FRF_LSB, (uint8_t)(frf >> 0)); |
fadhlika | 0:c28964675044 | 322 | } |
fadhlika | 0:c28964675044 | 323 | |
fadhlika | 0:c28964675044 | 324 | void LoRaClass::setSpreadingFactor(int sf) |
fadhlika | 0:c28964675044 | 325 | { |
fadhlika | 0:c28964675044 | 326 | if (sf < 6) { |
fadhlika | 0:c28964675044 | 327 | sf = 6; |
fadhlika | 0:c28964675044 | 328 | } else if (sf > 12) { |
fadhlika | 0:c28964675044 | 329 | sf = 12; |
fadhlika | 0:c28964675044 | 330 | } |
fadhlika | 0:c28964675044 | 331 | |
fadhlika | 0:c28964675044 | 332 | if (sf == 6) { |
fadhlika | 0:c28964675044 | 333 | writeRegister(REG_DETECTION_OPTIMIZE, 0xc5); |
fadhlika | 0:c28964675044 | 334 | writeRegister(REG_DETECTION_THRESHOLD, 0x0c); |
fadhlika | 0:c28964675044 | 335 | } else { |
fadhlika | 0:c28964675044 | 336 | writeRegister(REG_DETECTION_OPTIMIZE, 0xc3); |
fadhlika | 0:c28964675044 | 337 | writeRegister(REG_DETECTION_THRESHOLD, 0x0a); |
fadhlika | 0:c28964675044 | 338 | } |
fadhlika | 0:c28964675044 | 339 | |
fadhlika | 0:c28964675044 | 340 | writeRegister(REG_MODEM_CONFIG_2, (readRegister(REG_MODEM_CONFIG_2) & 0x0f) | ((sf << 4) & 0xf0)); |
fadhlika | 0:c28964675044 | 341 | } |
fadhlika | 0:c28964675044 | 342 | |
fadhlika | 0:c28964675044 | 343 | void LoRaClass::setSignalBandwidth(long sbw) |
fadhlika | 0:c28964675044 | 344 | { |
fadhlika | 0:c28964675044 | 345 | int bw; |
fadhlika | 0:c28964675044 | 346 | |
fadhlika | 0:c28964675044 | 347 | if (sbw <= 7.8E3) { |
fadhlika | 0:c28964675044 | 348 | bw = 0; |
fadhlika | 0:c28964675044 | 349 | } else if (sbw <= 10.4E3) { |
fadhlika | 0:c28964675044 | 350 | bw = 1; |
fadhlika | 0:c28964675044 | 351 | } else if (sbw <= 15.6E3) { |
fadhlika | 0:c28964675044 | 352 | bw = 2; |
fadhlika | 0:c28964675044 | 353 | } else if (sbw <= 20.8E3) { |
fadhlika | 0:c28964675044 | 354 | bw = 3; |
fadhlika | 0:c28964675044 | 355 | } else if (sbw <= 31.25E3) { |
fadhlika | 0:c28964675044 | 356 | bw = 4; |
fadhlika | 0:c28964675044 | 357 | } else if (sbw <= 41.7E3) { |
fadhlika | 0:c28964675044 | 358 | bw = 5; |
fadhlika | 0:c28964675044 | 359 | } else if (sbw <= 62.5E3) { |
fadhlika | 0:c28964675044 | 360 | bw = 6; |
fadhlika | 0:c28964675044 | 361 | } else if (sbw <= 125E3) { |
fadhlika | 0:c28964675044 | 362 | bw = 7; |
fadhlika | 0:c28964675044 | 363 | } else if (sbw <= 250E3) { |
fadhlika | 0:c28964675044 | 364 | bw = 8; |
fadhlika | 0:c28964675044 | 365 | } else /*if (sbw <= 250E3)*/ { |
fadhlika | 0:c28964675044 | 366 | bw = 9; |
fadhlika | 0:c28964675044 | 367 | } |
fadhlika | 0:c28964675044 | 368 | |
fadhlika | 0:c28964675044 | 369 | writeRegister(REG_MODEM_CONFIG_1, (readRegister(REG_MODEM_CONFIG_1) & 0x0f) | (bw << 4)); |
fadhlika | 0:c28964675044 | 370 | } |
fadhlika | 0:c28964675044 | 371 | |
fadhlika | 0:c28964675044 | 372 | void LoRaClass::setCodingRate4(int denominator) |
fadhlika | 0:c28964675044 | 373 | { |
fadhlika | 0:c28964675044 | 374 | if (denominator < 5) { |
fadhlika | 0:c28964675044 | 375 | denominator = 5; |
fadhlika | 0:c28964675044 | 376 | } else if (denominator > 8) { |
fadhlika | 0:c28964675044 | 377 | denominator = 8; |
fadhlika | 0:c28964675044 | 378 | } |
fadhlika | 0:c28964675044 | 379 | |
fadhlika | 0:c28964675044 | 380 | int cr = denominator - 4; |
fadhlika | 0:c28964675044 | 381 | |
fadhlika | 0:c28964675044 | 382 | writeRegister(REG_MODEM_CONFIG_1, (readRegister(REG_MODEM_CONFIG_1) & 0xf1) | (cr << 1)); |
fadhlika | 0:c28964675044 | 383 | } |
fadhlika | 0:c28964675044 | 384 | |
fadhlika | 0:c28964675044 | 385 | void LoRaClass::setPreambleLength(long length) |
fadhlika | 0:c28964675044 | 386 | { |
fadhlika | 0:c28964675044 | 387 | writeRegister(REG_PREAMBLE_MSB, (uint8_t)(length >> 8)); |
fadhlika | 0:c28964675044 | 388 | writeRegister(REG_PREAMBLE_LSB, (uint8_t)(length >> 0)); |
fadhlika | 0:c28964675044 | 389 | } |
fadhlika | 0:c28964675044 | 390 | |
fadhlika | 0:c28964675044 | 391 | void LoRaClass::setSyncWord(int sw) |
fadhlika | 0:c28964675044 | 392 | { |
fadhlika | 0:c28964675044 | 393 | writeRegister(REG_SYNC_WORD, sw); |
fadhlika | 0:c28964675044 | 394 | } |
fadhlika | 0:c28964675044 | 395 | |
fadhlika | 0:c28964675044 | 396 | void LoRaClass::enableCrc() |
fadhlika | 0:c28964675044 | 397 | { |
fadhlika | 0:c28964675044 | 398 | writeRegister(REG_MODEM_CONFIG_2, readRegister(REG_MODEM_CONFIG_2) | 0x04); |
fadhlika | 0:c28964675044 | 399 | } |
fadhlika | 0:c28964675044 | 400 | |
fadhlika | 0:c28964675044 | 401 | void LoRaClass::disableCrc() |
fadhlika | 0:c28964675044 | 402 | { |
fadhlika | 0:c28964675044 | 403 | writeRegister(REG_MODEM_CONFIG_2, readRegister(REG_MODEM_CONFIG_2) & 0xfb); |
fadhlika | 0:c28964675044 | 404 | } |
fadhlika | 0:c28964675044 | 405 | |
fadhlika | 0:c28964675044 | 406 | uint8_t LoRaClass::random() |
fadhlika | 0:c28964675044 | 407 | { |
fadhlika | 0:c28964675044 | 408 | return readRegister(REG_RSSI_WIDEBAND); |
fadhlika | 0:c28964675044 | 409 | } |
fadhlika | 0:c28964675044 | 410 | |
fadhlika | 0:c28964675044 | 411 | void LoRaClass::dumpRegisters(Stream& out) |
fadhlika | 0:c28964675044 | 412 | { |
fadhlika | 0:c28964675044 | 413 | for (int i = 0; i < 128; i++) { |
fadhlika | 0:c28964675044 | 414 | out.printf("0x%x: 0x%x", i, readRegister(i)); |
fadhlika | 0:c28964675044 | 415 | } |
fadhlika | 0:c28964675044 | 416 | } |
fadhlika | 0:c28964675044 | 417 | |
fadhlika | 0:c28964675044 | 418 | void LoRaClass::explicitHeaderMode() |
fadhlika | 0:c28964675044 | 419 | { |
fadhlika | 0:c28964675044 | 420 | _implicitHeaderMode = 0; |
fadhlika | 0:c28964675044 | 421 | |
fadhlika | 0:c28964675044 | 422 | writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) & 0xfe); |
fadhlika | 0:c28964675044 | 423 | } |
fadhlika | 0:c28964675044 | 424 | |
fadhlika | 0:c28964675044 | 425 | void LoRaClass::implicitHeaderMode() |
fadhlika | 0:c28964675044 | 426 | { |
fadhlika | 0:c28964675044 | 427 | _implicitHeaderMode = 1; |
fadhlika | 0:c28964675044 | 428 | |
fadhlika | 0:c28964675044 | 429 | writeRegister(REG_MODEM_CONFIG_1, readRegister(REG_MODEM_CONFIG_1) | 0x01); |
fadhlika | 0:c28964675044 | 430 | } |
fadhlika | 0:c28964675044 | 431 | |
fadhlika | 0:c28964675044 | 432 | void LoRaClass::handleDio0Rise() |
fadhlika | 0:c28964675044 | 433 | { |
fadhlika | 0:c28964675044 | 434 | int irqFlags = readRegister(REG_IRQ_FLAGS); |
fadhlika | 0:c28964675044 | 435 | |
fadhlika | 0:c28964675044 | 436 | // clear IRQ's |
fadhlika | 0:c28964675044 | 437 | writeRegister(REG_IRQ_FLAGS, irqFlags); |
fadhlika | 0:c28964675044 | 438 | |
fadhlika | 0:c28964675044 | 439 | if ((irqFlags & IRQ_PAYLOAD_CRC_ERROR_MASK) == 0) { |
fadhlika | 0:c28964675044 | 440 | // received a packet |
fadhlika | 0:c28964675044 | 441 | _packetIndex = 0; |
fadhlika | 0:c28964675044 | 442 | |
fadhlika | 0:c28964675044 | 443 | // read packet length |
fadhlika | 0:c28964675044 | 444 | int packetLength = _implicitHeaderMode ? readRegister(REG_PAYLOAD_LENGTH) : readRegister(REG_RX_NB_BYTES); |
fadhlika | 0:c28964675044 | 445 | |
fadhlika | 0:c28964675044 | 446 | // set FIFO address to current RX address |
fadhlika | 0:c28964675044 | 447 | writeRegister(REG_FIFO_ADDR_PTR, readRegister(REG_FIFO_RX_CURRENT_ADDR)); |
fadhlika | 0:c28964675044 | 448 | |
fadhlika | 0:c28964675044 | 449 | if (_onReceive) { |
fadhlika | 0:c28964675044 | 450 | _onReceive(packetLength); |
fadhlika | 0:c28964675044 | 451 | } |
fadhlika | 0:c28964675044 | 452 | |
fadhlika | 0:c28964675044 | 453 | // reset FIFO address |
fadhlika | 0:c28964675044 | 454 | writeRegister(REG_FIFO_ADDR_PTR, 0); |
fadhlika | 0:c28964675044 | 455 | } |
fadhlika | 0:c28964675044 | 456 | } |
fadhlika | 0:c28964675044 | 457 | |
fadhlika | 0:c28964675044 | 458 | uint8_t LoRaClass::readRegister(uint8_t address) |
fadhlika | 0:c28964675044 | 459 | { |
fadhlika | 0:c28964675044 | 460 | return singleTransfer(address & 0x7f, 0x00); |
fadhlika | 0:c28964675044 | 461 | } |
fadhlika | 0:c28964675044 | 462 | |
fadhlika | 0:c28964675044 | 463 | void LoRaClass::writeRegister(uint8_t address, uint8_t value) |
fadhlika | 0:c28964675044 | 464 | { |
fadhlika | 0:c28964675044 | 465 | singleTransfer(address | 0x80, value); |
fadhlika | 0:c28964675044 | 466 | } |
fadhlika | 0:c28964675044 | 467 | |
fadhlika | 0:c28964675044 | 468 | uint8_t LoRaClass::singleTransfer(uint8_t address, uint8_t value) |
fadhlika | 0:c28964675044 | 469 | { |
fadhlika | 0:c28964675044 | 470 | uint8_t response; |
fadhlika | 0:c28964675044 | 471 | |
fadhlika | 0:c28964675044 | 472 | _ss = 0; |
fadhlika | 0:c28964675044 | 473 | |
fadhlika | 0:c28964675044 | 474 | spi.write(address); |
fadhlika | 0:c28964675044 | 475 | response = spi.write(value); |
fadhlika | 0:c28964675044 | 476 | |
fadhlika | 0:c28964675044 | 477 | _ss = 1; |
fadhlika | 0:c28964675044 | 478 | |
fadhlika | 0:c28964675044 | 479 | return response; |
fadhlika | 0:c28964675044 | 480 | } |
fadhlika | 0:c28964675044 | 481 | |
fadhlika | 0:c28964675044 | 482 | void LoRaClass::onDio0Rise() |
fadhlika | 0:c28964675044 | 483 | { |
fadhlika | 0:c28964675044 | 484 | LoRa.handleDio0Rise(); |
fadhlika | 0:c28964675044 | 485 | } |
fadhlika | 0:c28964675044 | 486 | |
fadhlika | 0:c28964675044 | 487 | LoRaClass LoRa; |