LoRa/WiFi Gateway Code, MAX32620FTHR Side

Committer:
gov1
Date:
Tue Jul 31 16:36:17 2018 +0000
Revision:
0:b24cccf38c35
LoRa/WiFi Gateway Code, MAX32620FTHR Side

Who changed what in which revision?

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