acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
SX127x.cpp (48170B)
1 #include "SX127x.h" 2 #if !defined(RADIOLIB_EXCLUDE_SX127X) 3 4 SX127x::SX127x(Module* mod) : PhysicalLayer(RADIOLIB_SX127X_FREQUENCY_STEP_SIZE, RADIOLIB_SX127X_MAX_PACKET_LENGTH) { 5 _mod = mod; 6 } 7 8 Module* SX127x::getMod() { 9 return(_mod); 10 } 11 12 int16_t SX127x::begin(uint8_t chipVersion, uint8_t syncWord, uint16_t preambleLength) { 13 // set module properties 14 _mod->init(); 15 _mod->pinMode(_mod->getIrq(), INPUT); 16 _mod->pinMode(_mod->getGpio(), INPUT); 17 18 // try to find the SX127x chip 19 if(!SX127x::findChip(chipVersion)) { 20 RADIOLIB_DEBUG_PRINTLN(F("No SX127x found!")); 21 _mod->term(); 22 return(RADIOLIB_ERR_CHIP_NOT_FOUND); 23 } 24 RADIOLIB_DEBUG_PRINTLN(F("M\tSX127x")); 25 26 // set mode to standby 27 int16_t state = standby(); 28 RADIOLIB_ASSERT(state); 29 30 // configure settings not accessible by API 31 state = config(); 32 RADIOLIB_ASSERT(state); 33 34 // check active modem 35 if(getActiveModem() != RADIOLIB_SX127X_LORA) { 36 // set LoRa mode 37 state = setActiveModem(RADIOLIB_SX127X_LORA); 38 RADIOLIB_ASSERT(state); 39 } 40 41 // set LoRa sync word 42 state = SX127x::setSyncWord(syncWord); 43 RADIOLIB_ASSERT(state); 44 45 // set over current protection 46 state = SX127x::setCurrentLimit(60); 47 RADIOLIB_ASSERT(state); 48 49 // set preamble length 50 state = SX127x::setPreambleLength(preambleLength); 51 RADIOLIB_ASSERT(state); 52 53 // initialize internal variables 54 _dataRate = 0.0; 55 56 return(state); 57 } 58 59 int16_t SX127x::beginFSK(uint8_t chipVersion, float br, float freqDev, float rxBw, uint16_t preambleLength, bool enableOOK) { 60 // set module properties 61 _mod->init(); 62 _mod->pinMode(_mod->getIrq(), INPUT); 63 64 // try to find the SX127x chip 65 if(!SX127x::findChip(chipVersion)) { 66 RADIOLIB_DEBUG_PRINTLN(F("No SX127x found!")); 67 _mod->term(); 68 return(RADIOLIB_ERR_CHIP_NOT_FOUND); 69 } 70 RADIOLIB_DEBUG_PRINTLN(F("M\tSX127x")); 71 72 // set mode to standby 73 int16_t state = standby(); 74 RADIOLIB_ASSERT(state); 75 76 // check currently active modem 77 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 78 // set FSK mode 79 state = setActiveModem(RADIOLIB_SX127X_FSK_OOK); 80 RADIOLIB_ASSERT(state); 81 } 82 83 // enable/disable OOK 84 state = setOOK(enableOOK); 85 RADIOLIB_ASSERT(state); 86 87 // set bit rate 88 state = SX127x::setBitRate(br); 89 RADIOLIB_ASSERT(state); 90 91 // set frequency deviation 92 state = SX127x::setFrequencyDeviation(freqDev); 93 RADIOLIB_ASSERT(state); 94 95 // set AFC bandwidth 96 state = SX127x::setAFCBandwidth(rxBw); 97 RADIOLIB_ASSERT(state); 98 99 // set AFC&AGC trigger to RSSI (both in OOK and FSK) 100 state = SX127x::setAFCAGCTrigger(RADIOLIB_SX127X_RX_TRIGGER_RSSI_INTERRUPT); 101 RADIOLIB_ASSERT(state); 102 103 // enable AFC 104 state = SX127x::setAFC(false); 105 RADIOLIB_ASSERT(state); 106 107 // set receiver bandwidth 108 state = SX127x::setRxBandwidth(rxBw); 109 RADIOLIB_ASSERT(state); 110 111 // set over current protection 112 state = SX127x::setCurrentLimit(60); 113 RADIOLIB_ASSERT(state); 114 115 // set preamble length 116 state = SX127x::setPreambleLength(preambleLength); 117 RADIOLIB_ASSERT(state); 118 119 // set default sync word 120 uint8_t syncWord[] = {0x12, 0xAD}; 121 state = setSyncWord(syncWord, 2); 122 RADIOLIB_ASSERT(state); 123 124 // disable address filtering 125 state = disableAddressFiltering(); 126 RADIOLIB_ASSERT(state); 127 128 // set default RSSI measurement config 129 state = setRSSIConfig(2); 130 RADIOLIB_ASSERT(state); 131 132 // set default encoding 133 state = setEncoding(RADIOLIB_ENCODING_NRZ); 134 RADIOLIB_ASSERT(state); 135 136 // set default packet length mode 137 state = variablePacketLengthMode(); 138 139 return(state); 140 } 141 142 int16_t SX127x::transmit(uint8_t* data, size_t len, uint8_t addr) { 143 // set mode to standby 144 int16_t state = setMode(RADIOLIB_SX127X_STANDBY); 145 RADIOLIB_ASSERT(state); 146 147 int16_t modem = getActiveModem(); 148 uint32_t start = 0; 149 if(modem == RADIOLIB_SX127X_LORA) { 150 // calculate timeout (150 % of expected time-on-air) 151 uint32_t timeout = getTimeOnAir(len) * 1.5; 152 153 // start transmission 154 state = startTransmit(data, len, addr); 155 RADIOLIB_ASSERT(state); 156 157 // wait for packet transmission or timeout 158 start = _mod->micros(); 159 while(!_mod->digitalRead(_mod->getIrq())) { 160 _mod->yield(); 161 if(_mod->micros() - start > timeout) { 162 clearIRQFlags(); 163 return(RADIOLIB_ERR_TX_TIMEOUT); 164 } 165 } 166 167 } else if(modem == RADIOLIB_SX127X_FSK_OOK) { 168 // calculate timeout (5ms + 500 % of expected time-on-air) 169 uint32_t timeout = 5000 + getTimeOnAir(len) * 5; 170 171 // start transmission 172 state = startTransmit(data, len, addr); 173 RADIOLIB_ASSERT(state); 174 175 // wait for transmission end or timeout 176 start = _mod->micros(); 177 while(!_mod->digitalRead(_mod->getIrq())) { 178 _mod->yield(); 179 if(_mod->micros() - start > timeout) { 180 clearIRQFlags(); 181 standby(); 182 return(RADIOLIB_ERR_TX_TIMEOUT); 183 } 184 } 185 } else { 186 return(RADIOLIB_ERR_UNKNOWN); 187 } 188 189 // update data rate 190 uint32_t elapsed = _mod->micros() - start; 191 _dataRate = (len*8.0)/((float)elapsed/1000000.0); 192 193 // clear interrupt flags 194 clearIRQFlags(); 195 196 // set mode to standby to disable transmitter 197 return(standby()); 198 } 199 200 int16_t SX127x::receive(uint8_t* data, size_t len) { 201 // set mode to standby 202 int16_t state = setMode(RADIOLIB_SX127X_STANDBY); 203 RADIOLIB_ASSERT(state); 204 205 int16_t modem = getActiveModem(); 206 if(modem == RADIOLIB_SX127X_LORA) { 207 // set mode to receive 208 state = startReceive(len, RADIOLIB_SX127X_RXSINGLE); 209 RADIOLIB_ASSERT(state); 210 211 // wait for packet reception or timeout (100 LoRa symbols) 212 while(!_mod->digitalRead(_mod->getIrq())) { 213 _mod->yield(); 214 if(_mod->digitalRead(_mod->getGpio())) { 215 clearIRQFlags(); 216 return(RADIOLIB_ERR_RX_TIMEOUT); 217 } 218 } 219 220 } else if(modem == RADIOLIB_SX127X_FSK_OOK) { 221 // calculate timeout (500 % of expected time-on-air) 222 uint32_t timeout = getTimeOnAir(len) * 5; 223 224 // set mode to receive 225 state = startReceive(len, RADIOLIB_SX127X_RX); 226 RADIOLIB_ASSERT(state); 227 228 // wait for packet reception or timeout 229 uint32_t start = _mod->micros(); 230 while(!_mod->digitalRead(_mod->getIrq())) { 231 _mod->yield(); 232 if(_mod->micros() - start > timeout) { 233 clearIRQFlags(); 234 return(RADIOLIB_ERR_RX_TIMEOUT); 235 } 236 } 237 } 238 239 // read the received data 240 state = readData(data, len); 241 242 return(state); 243 } 244 245 int16_t SX127x::scanChannel() { 246 // start CAD 247 int16_t state = startChannelScan(); 248 RADIOLIB_ASSERT(state); 249 250 // wait for channel activity detected or timeout 251 while(!_mod->digitalRead(_mod->getIrq())) { 252 _mod->yield(); 253 if(_mod->digitalRead(_mod->getGpio())) { 254 clearIRQFlags(); 255 return(RADIOLIB_PREAMBLE_DETECTED); 256 } 257 } 258 259 // clear interrupt flags 260 clearIRQFlags(); 261 262 return(RADIOLIB_CHANNEL_FREE); 263 } 264 265 int16_t SX127x::sleep() { 266 // set RF switch (if present) 267 _mod->setRfSwitchState(LOW, LOW); 268 269 // set mode to sleep 270 return(setMode(RADIOLIB_SX127X_SLEEP)); 271 } 272 273 int16_t SX127x::standby() { 274 // set RF switch (if present) 275 _mod->setRfSwitchState(LOW, LOW); 276 277 // set mode to standby 278 return(setMode(RADIOLIB_SX127X_STANDBY)); 279 } 280 281 int16_t SX127x::transmitDirect(uint32_t frf) { 282 // check modem 283 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 284 return(RADIOLIB_ERR_WRONG_MODEM); 285 } 286 287 // set RF switch (if present) 288 _mod->setRfSwitchState(LOW, HIGH); 289 290 // user requested to start transmitting immediately (required for RTTY) 291 if(frf != 0) { 292 _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FRF_MSB, (frf & 0xFF0000) >> 16); 293 _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FRF_MID, (frf & 0x00FF00) >> 8); 294 _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FRF_LSB, frf & 0x0000FF); 295 296 return(setMode(RADIOLIB_SX127X_TX)); 297 } 298 299 // activate direct mode 300 int16_t state = directMode(); 301 RADIOLIB_ASSERT(state); 302 303 // apply fixes to errata 304 RADIOLIB_ERRATA_SX127X(false); 305 306 // start transmitting 307 return(setMode(RADIOLIB_SX127X_TX)); 308 } 309 310 int16_t SX127x::receiveDirect() { 311 // check modem 312 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 313 return(RADIOLIB_ERR_WRONG_MODEM); 314 } 315 316 // set RF switch (if present) 317 _mod->setRfSwitchState(HIGH, LOW); 318 319 // activate direct mode 320 int16_t state = directMode(); 321 RADIOLIB_ASSERT(state); 322 323 // apply fixes to errata 324 RADIOLIB_ERRATA_SX127X(true); 325 326 // start receiving 327 return(setMode(RADIOLIB_SX127X_RX)); 328 } 329 330 int16_t SX127x::directMode() { 331 // set mode to standby 332 int16_t state = setMode(RADIOLIB_SX127X_STANDBY); 333 RADIOLIB_ASSERT(state); 334 335 // set DIO mapping 336 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_CONT_DCLK | RADIOLIB_SX127X_DIO2_CONT_DATA, 5, 2); 337 RADIOLIB_ASSERT(state); 338 339 // enable receiver startup without preamble or RSSI 340 state = SX127x::setAFCAGCTrigger(RADIOLIB_SX127X_RX_TRIGGER_NONE); 341 RADIOLIB_ASSERT(state); 342 343 // set continuous mode 344 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_2, RADIOLIB_SX127X_DATA_MODE_CONTINUOUS, 6, 6)); 345 } 346 347 int16_t SX127x::packetMode() { 348 // check modem 349 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 350 return(RADIOLIB_ERR_WRONG_MODEM); 351 } 352 353 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_2, RADIOLIB_SX127X_DATA_MODE_PACKET, 6, 6)); 354 } 355 356 int16_t SX127x::startReceive(uint8_t len, uint8_t mode) { 357 // set mode to standby 358 int16_t state = setMode(RADIOLIB_SX127X_STANDBY); 359 RADIOLIB_ASSERT(state); 360 361 int16_t modem = getActiveModem(); 362 if(modem == RADIOLIB_SX127X_LORA) { 363 // set DIO pin mapping 364 if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) { 365 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_RX_DONE | RADIOLIB_SX127X_DIO1_LORA_FHSS_CHANGE_CHANNEL, 7, 4); 366 } 367 else { 368 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_RX_DONE | RADIOLIB_SX127X_DIO1_LORA_RX_TIMEOUT, 7, 4); 369 } 370 371 // set expected packet length for SF6 372 if(_sf == 6) { 373 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, len); 374 } 375 376 // apply fixes to errata 377 RADIOLIB_ERRATA_SX127X(true); 378 379 // clear interrupt flags 380 clearIRQFlags(); 381 382 // set FIFO pointers 383 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_RX_BASE_ADDR, RADIOLIB_SX127X_FIFO_RX_BASE_ADDR_MAX); 384 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_ADDR_PTR, RADIOLIB_SX127X_FIFO_RX_BASE_ADDR_MAX); 385 RADIOLIB_ASSERT(state); 386 387 } else if(modem == RADIOLIB_SX127X_FSK_OOK) { 388 // set DIO pin mapping 389 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_PACK_PAYLOAD_READY, 7, 6); 390 RADIOLIB_ASSERT(state); 391 392 // clear interrupt flags 393 clearIRQFlags(); 394 395 // FSK modem does not distinguish between Rx single and continuous 396 if(mode == RADIOLIB_SX127X_RXCONTINUOUS) { 397 // set RF switch (if present) 398 _mod->setRfSwitchState(HIGH, LOW); 399 return(setMode(RADIOLIB_SX127X_RX)); 400 } 401 } 402 403 // set RF switch (if present) 404 _mod->setRfSwitchState(HIGH, LOW); 405 406 // set mode to receive 407 return(setMode(mode)); 408 } 409 410 void SX127x::setDio0Action(void (*func)(void)) { 411 _mod->attachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getIrq()), func, RISING); 412 } 413 414 void SX127x::clearDio0Action() { 415 _mod->detachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getIrq())); 416 } 417 418 void SX127x::setDio1Action(void (*func)(void)) { 419 if(_mod->getGpio() == RADIOLIB_NC) { 420 return; 421 } 422 _mod->attachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio()), func, RISING); 423 } 424 425 void SX127x::clearDio1Action() { 426 if(_mod->getGpio() == RADIOLIB_NC) { 427 return; 428 } 429 _mod->detachInterrupt(RADIOLIB_DIGITAL_PIN_TO_INTERRUPT(_mod->getGpio())); 430 } 431 432 void SX127x::setFifoEmptyAction(void (*func)(void)) { 433 // set DIO1 to the FIFO empty event (the register setting is done in startTransmit) 434 setDio1Action(func); 435 } 436 437 void SX127x::clearFifoEmptyAction() { 438 clearDio1Action(); 439 } 440 441 void SX127x::setFifoFullAction(void (*func)(void)) { 442 // set the interrupt 443 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_THRESH, RADIOLIB_SX127X_FIFO_THRESH, 5, 0); 444 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_PACK_FIFO_LEVEL, 5, 4); 445 446 // set DIO1 to the FIFO full event 447 setDio1Action(func); 448 } 449 450 void SX127x::clearFifoFullAction() { 451 clearDio1Action(); 452 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, 0x00, 5, 4); 453 } 454 455 bool SX127x::fifoAdd(uint8_t* data, int totalLen, volatile int* remLen) { 456 // subtract first (this may be the first time we get to modify the remaining length) 457 *remLen -= RADIOLIB_SX127X_FIFO_THRESH - 1; 458 459 // check if there is still something left to send 460 if(*remLen <= 0) { 461 // we're done 462 return(true); 463 } 464 465 // calculate the number of bytes we can copy 466 int len = *remLen; 467 if(len > RADIOLIB_SX127X_FIFO_THRESH - 1) { 468 len = RADIOLIB_SX127X_FIFO_THRESH - 1; 469 } 470 471 // clear interrupt flags 472 clearIRQFlags(); 473 474 // copy the bytes to the FIFO 475 _mod->SPIwriteRegisterBurst(RADIOLIB_SX127X_REG_FIFO, &data[totalLen - *remLen], len); 476 477 // this is a hack, but it seems Rx FIFO level is getting triggered 1 byte before it should 478 // we just add a padding byte that we can drop without consequence 479 _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, '/'); 480 481 // we're not done yet 482 return(false); 483 } 484 485 bool SX127x::fifoGet(volatile uint8_t* data, int totalLen, volatile int* rcvLen) { 486 // get pointer to the correct position in data buffer 487 uint8_t* dataPtr = (uint8_t*)&data[*rcvLen]; 488 489 // check how much data are we still expecting 490 uint8_t len = RADIOLIB_SX127X_FIFO_THRESH - 1; 491 if(totalLen - *rcvLen < len) { 492 // we're nearly at the end 493 len = totalLen - *rcvLen; 494 } 495 496 // get the data 497 _mod->SPIreadRegisterBurst(RADIOLIB_SX127X_REG_FIFO, len, dataPtr); 498 (*rcvLen) += (len); 499 500 // dump the padding byte 501 _mod->SPIreadRegister(RADIOLIB_SX127X_REG_FIFO); 502 503 // clear flags 504 clearIRQFlags(); 505 506 // check if we're done 507 if(*rcvLen >= totalLen) { 508 return(true); 509 } 510 return(false); 511 } 512 513 int16_t SX127x::startTransmit(uint8_t* data, size_t len, uint8_t addr) { 514 // set mode to standby 515 int16_t state = setMode(RADIOLIB_SX127X_STANDBY); 516 517 int16_t modem = getActiveModem(); 518 if(modem == RADIOLIB_SX127X_LORA) { 519 // check packet length 520 if(len > RADIOLIB_SX127X_MAX_PACKET_LENGTH) { 521 return(RADIOLIB_ERR_PACKET_TOO_LONG); 522 } 523 524 // set DIO mapping 525 if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) > RADIOLIB_SX127X_HOP_PERIOD_OFF) { 526 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_TX_DONE | RADIOLIB_SX127X_DIO1_LORA_FHSS_CHANGE_CHANNEL, 7, 4); 527 } else { 528 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_TX_DONE, 7, 6); 529 } 530 531 // apply fixes to errata 532 RADIOLIB_ERRATA_SX127X(false); 533 534 // clear interrupt flags 535 clearIRQFlags(); 536 537 // set packet length 538 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH, len); 539 540 // set FIFO pointers 541 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_TX_BASE_ADDR, RADIOLIB_SX127X_FIFO_TX_BASE_ADDR_MAX); 542 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_ADDR_PTR, RADIOLIB_SX127X_FIFO_TX_BASE_ADDR_MAX); 543 544 } else if(modem == RADIOLIB_SX127X_FSK_OOK) { 545 // clear interrupt flags 546 clearIRQFlags(); 547 548 // set DIO mapping 549 if(len > RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK) { 550 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO1_PACK_FIFO_EMPTY, 5, 4); 551 } else { 552 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_PACK_PACKET_SENT, 7, 6); 553 } 554 555 // set packet length 556 if (_packetLengthConfig == RADIOLIB_SX127X_PACKET_VARIABLE) { 557 _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, len); 558 } 559 560 // check address filtering 561 uint8_t filter = _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, 2, 1); 562 if((filter == RADIOLIB_SX127X_ADDRESS_FILTERING_NODE) || (filter == RADIOLIB_SX127X_ADDRESS_FILTERING_NODE_BROADCAST)) { 563 _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, addr); 564 } 565 } 566 567 // write packet to FIFO 568 size_t packetLen = len; 569 if((modem == RADIOLIB_SX127X_FSK_OOK) && (len > RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK)) { 570 packetLen = RADIOLIB_SX127X_FIFO_THRESH - 1; 571 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_THRESH, RADIOLIB_SX127X_TX_START_FIFO_NOT_EMPTY, 7, 7); 572 } 573 _mod->SPIwriteRegisterBurst(RADIOLIB_SX127X_REG_FIFO, data, packetLen); 574 575 // this is a hack, but it seems than in Stream mode, Rx FIFO level is getting triggered 1 byte before it should 576 // just add a padding byte that can be dropped without consequence 577 if((modem == RADIOLIB_SX127X_FSK_OOK) && (len > RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK)) { 578 _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_FIFO, '/'); 579 } 580 581 // set RF switch (if present) 582 _mod->setRfSwitchState(LOW, HIGH); 583 584 // start transmission 585 state |= setMode(RADIOLIB_SX127X_TX); 586 RADIOLIB_ASSERT(state); 587 588 return(RADIOLIB_ERR_NONE); 589 } 590 591 int16_t SX127x::readData(uint8_t* data, size_t len) { 592 int16_t modem = getActiveModem(); 593 594 // put module to standby 595 standby(); 596 597 // get packet length 598 size_t length = getPacketLength(); 599 size_t dumpLen = 0; 600 if((len != 0) && (len < length)) { 601 // user requested less data than we got, only return what was requested 602 dumpLen = length - len; 603 length = len; 604 } 605 606 if(modem == RADIOLIB_SX127X_LORA) { 607 // check packet header integrity 608 if(_crcEnabled && (_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 6, 6)) == 0) { 609 // CRC is disabled according to packet header and enabled according to user 610 // most likely damaged packet header 611 clearIRQFlags(); 612 return(RADIOLIB_ERR_LORA_HEADER_DAMAGED); 613 } 614 615 // check payload CRC 616 if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_IRQ_FLAGS, 5, 5) == RADIOLIB_SX127X_CLEAR_IRQ_FLAG_PAYLOAD_CRC_ERROR) { 617 // clear interrupt flags 618 clearIRQFlags(); 619 return(RADIOLIB_ERR_CRC_MISMATCH); 620 } 621 622 } else if(modem == RADIOLIB_SX127X_FSK_OOK) { 623 // check address filtering 624 uint8_t filter = _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, 2, 1); 625 if((filter == RADIOLIB_SX127X_ADDRESS_FILTERING_NODE) || (filter == RADIOLIB_SX127X_ADDRESS_FILTERING_NODE_BROADCAST)) { 626 _mod->SPIreadRegister(RADIOLIB_SX127X_REG_FIFO); 627 } 628 } 629 630 // read packet data 631 _mod->SPIreadRegisterBurst(RADIOLIB_SX127X_REG_FIFO, length, data); 632 633 // dump the bytes that weren't requested 634 if(dumpLen != 0) { 635 clearFIFO(dumpLen); 636 } 637 638 // clear internal flag so getPacketLength can return the new packet length 639 _packetLengthQueried = false; 640 641 // clear interrupt flags 642 clearIRQFlags(); 643 644 return(RADIOLIB_ERR_NONE); 645 } 646 647 int16_t SX127x::startChannelScan() { 648 // check active modem 649 if(getActiveModem() != RADIOLIB_SX127X_LORA) { 650 return(RADIOLIB_ERR_WRONG_MODEM); 651 } 652 653 // set mode to standby 654 int16_t state = setMode(RADIOLIB_SX127X_STANDBY); 655 RADIOLIB_ASSERT(state); 656 657 // set DIO pin mapping 658 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, RADIOLIB_SX127X_DIO0_LORA_CAD_DONE | RADIOLIB_SX127X_DIO1_LORA_CAD_DETECTED, 7, 4); 659 RADIOLIB_ASSERT(state); 660 661 // clear interrupt flags 662 clearIRQFlags(); 663 664 // set RF switch (if present) 665 _mod->setRfSwitchState(HIGH, LOW); 666 667 // set mode to CAD 668 state = setMode(RADIOLIB_SX127X_CAD); 669 return(state); 670 } 671 672 int16_t SX127x::setSyncWord(uint8_t syncWord) { 673 // check active modem 674 if(getActiveModem() != RADIOLIB_SX127X_LORA) { 675 return(RADIOLIB_ERR_WRONG_MODEM); 676 } 677 678 // set mode to standby 679 setMode(RADIOLIB_SX127X_STANDBY); 680 681 // write register 682 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYNC_WORD, syncWord)); 683 } 684 685 int16_t SX127x::setCurrentLimit(uint8_t currentLimit) { 686 // check allowed range 687 if(!(((currentLimit >= 45) && (currentLimit <= 240)) || (currentLimit == 0))) { 688 return(RADIOLIB_ERR_INVALID_CURRENT_LIMIT); 689 } 690 691 // set mode to standby 692 int16_t state = setMode(RADIOLIB_SX127X_STANDBY); 693 694 // set OCP limit 695 uint8_t raw; 696 if(currentLimit == 0) { 697 // limit set to 0, disable OCP 698 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OCP, RADIOLIB_SX127X_OCP_OFF, 5, 5); 699 } else if(currentLimit <= 120) { 700 raw = (currentLimit - 45) / 5; 701 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OCP, RADIOLIB_SX127X_OCP_ON | raw, 5, 0); 702 } else if(currentLimit <= 240) { 703 raw = (currentLimit + 30) / 10; 704 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OCP, RADIOLIB_SX127X_OCP_ON | raw, 5, 0); 705 } 706 return(state); 707 } 708 709 int16_t SX127x::setPreambleLength(uint16_t preambleLength) { 710 // set mode to standby 711 int16_t state = setMode(RADIOLIB_SX127X_STANDBY); 712 RADIOLIB_ASSERT(state); 713 714 // check active modem 715 uint8_t modem = getActiveModem(); 716 if(modem == RADIOLIB_SX127X_LORA) { 717 // check allowed range 718 if(preambleLength < 6) { 719 return(RADIOLIB_ERR_INVALID_PREAMBLE_LENGTH); 720 } 721 722 // set preamble length 723 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_MSB, (uint8_t)((preambleLength >> 8) & 0xFF)); 724 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_LSB, (uint8_t)(preambleLength & 0xFF)); 725 return(state); 726 727 } else if(modem == RADIOLIB_SX127X_FSK_OOK) { 728 // set preamble length (in bytes) 729 uint16_t numBytes = preambleLength / 8; 730 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_MSB_FSK, (uint8_t)((numBytes >> 8) & 0xFF)); 731 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_LSB_FSK, (uint8_t)(numBytes & 0xFF)); 732 return(state); 733 } 734 735 return(RADIOLIB_ERR_UNKNOWN); 736 } 737 738 float SX127x::getFrequencyError(bool autoCorrect) { 739 int16_t modem = getActiveModem(); 740 if(modem == RADIOLIB_SX127X_LORA) { 741 // get raw frequency error 742 uint32_t raw = (uint32_t)_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_FEI_MSB, 3, 0) << 16; 743 raw |= (uint16_t)_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_FEI_MID) << 8; 744 raw |= _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_FEI_LSB); 745 746 uint32_t base = (uint32_t)2 << 23; 747 float error; 748 749 // check the first bit 750 if(raw & 0x80000) { 751 // frequency error is negative 752 raw |= (uint32_t)0xFFF00000; 753 raw = ~raw + 1; 754 error = (((float)raw * (float)base)/32000000.0) * (_bw/500.0) * -1.0; 755 } else { 756 error = (((float)raw * (float)base)/32000000.0) * (_bw/500.0); 757 } 758 759 if(autoCorrect) { 760 // adjust LoRa modem data rate 761 float ppmOffset = 0.95 * (error/32.0); 762 _mod->SPIwriteRegister(0x27, (uint8_t)ppmOffset); 763 } 764 765 return(error); 766 767 } else if(modem == RADIOLIB_SX127X_FSK_OOK) { 768 // get raw frequency error 769 uint16_t raw = (uint16_t)_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_FEI_MSB_FSK) << 8; 770 raw |= _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_FEI_LSB_FSK); 771 772 uint32_t base = 1; 773 float error; 774 775 // check the first bit 776 if(raw & 0x8000) { 777 // frequency error is negative 778 raw |= (uint32_t)0xFFF00000; 779 raw = ~raw + 1; 780 error = (float)raw * (32000000.0 / (float)(base << 19)) * -1.0; 781 } else { 782 error = (float)raw * (32000000.0 / (float)(base << 19)); 783 } 784 785 return(error); 786 } 787 788 return(RADIOLIB_ERR_UNKNOWN); 789 } 790 791 float SX127x::getAFCError() 792 { 793 // check active modem 794 int16_t modem = getActiveModem(); 795 if(modem != RADIOLIB_SX127X_FSK_OOK) { 796 return 0; 797 } 798 799 // get raw frequency error 800 int16_t raw = (uint16_t)_mod->SPIreadRegister(RADIOLIB_SX127X_REG_AFC_MSB) << 8; 801 raw |= _mod->SPIreadRegister(RADIOLIB_SX127X_REG_AFC_LSB); 802 803 uint32_t base = 1; 804 return raw * (32000000.0 / (float)(base << 19)); 805 } 806 807 float SX127x::getSNR() { 808 // check active modem 809 if(getActiveModem() != RADIOLIB_SX127X_LORA) { 810 return(0); 811 } 812 813 // get SNR value 814 int8_t rawSNR = (int8_t)_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PKT_SNR_VALUE); 815 return(rawSNR / 4.0); 816 } 817 818 float SX127x::getDataRate() const { 819 return(_dataRate); 820 } 821 822 int16_t SX127x::setBitRate(float br) { 823 // check active modem 824 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 825 return(RADIOLIB_ERR_WRONG_MODEM); 826 } 827 828 // check allowed bit rate 829 if(_ook) { 830 RADIOLIB_CHECK_RANGE(br, 1.2, 32.768002, RADIOLIB_ERR_INVALID_BIT_RATE); // Found that 32.768 is 32.768002 831 } else { 832 RADIOLIB_CHECK_RANGE(br, 1.2, 300.0, RADIOLIB_ERR_INVALID_BIT_RATE); 833 } 834 835 // set mode to STANDBY 836 int16_t state = setMode(RADIOLIB_SX127X_STANDBY); 837 RADIOLIB_ASSERT(state); 838 839 // set bit rate 840 uint16_t bitRate = (RADIOLIB_SX127X_CRYSTAL_FREQ * 1000.0) / br; 841 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BITRATE_MSB, (bitRate & 0xFF00) >> 8, 7, 0); 842 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BITRATE_LSB, bitRate & 0x00FF, 7, 0); 843 844 /// \todo fractional part of bit rate setting (not in OOK) 845 if(state == RADIOLIB_ERR_NONE) { 846 SX127x::_br = br; 847 } 848 return(state); 849 } 850 851 int16_t SX127x::setFrequencyDeviation(float freqDev) { 852 // check active modem 853 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 854 return(RADIOLIB_ERR_WRONG_MODEM); 855 } 856 857 // set frequency deviation to lowest available setting (required for digimodes) 858 float newFreqDev = freqDev; 859 if(freqDev < 0.0) { 860 newFreqDev = 0.6; 861 } 862 863 // check frequency deviation range 864 if(!((newFreqDev + _br/2.0 <= 250.0) && (freqDev <= 200.0))) { 865 return(RADIOLIB_ERR_INVALID_FREQUENCY_DEVIATION); 866 } 867 868 // set mode to STANDBY 869 int16_t state = setMode(RADIOLIB_SX127X_STANDBY); 870 RADIOLIB_ASSERT(state); 871 872 // set allowed frequency deviation 873 uint32_t base = 1; 874 uint32_t FDEV = (newFreqDev * (base << 19)) / 32000; 875 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FDEV_MSB, (FDEV & 0xFF00) >> 8, 5, 0); 876 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FDEV_LSB, FDEV & 0x00FF, 7, 0); 877 return(state); 878 } 879 880 uint8_t SX127x::calculateBWManExp(float bandwidth) 881 { 882 for(uint8_t e = 7; e >= 1; e--) { 883 for(int8_t m = 2; m >= 0; m--) { 884 float point = (RADIOLIB_SX127X_CRYSTAL_FREQ * 1000000.0)/(((4 * m) + 16) * ((uint32_t)1 << (e + 2))); 885 if(fabs(bandwidth - ((point / 1000.0) + 0.05)) <= 0.5) { 886 return((m << 3) | e); 887 } 888 } 889 } 890 return 0; 891 } 892 893 int16_t SX127x::setRxBandwidth(float rxBw) { 894 // check active modem 895 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 896 return(RADIOLIB_ERR_WRONG_MODEM); 897 } 898 899 RADIOLIB_CHECK_RANGE(rxBw, 2.6, 250.0, RADIOLIB_ERR_INVALID_RX_BANDWIDTH); 900 901 // set mode to STANDBY 902 int16_t state = setMode(RADIOLIB_SX127X_STANDBY); 903 RADIOLIB_ASSERT(state); 904 905 // set Rx bandwidth 906 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_BW, calculateBWManExp(rxBw), 4, 0)); 907 } 908 909 int16_t SX127x::setAFCBandwidth(float rxBw) { 910 // check active modem 911 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK){ 912 return(RADIOLIB_ERR_WRONG_MODEM); 913 } 914 915 RADIOLIB_CHECK_RANGE(rxBw, 2.6, 250.0, RADIOLIB_ERR_INVALID_RX_BANDWIDTH); 916 917 // set mode to STANDBY 918 int16_t state = setMode(RADIOLIB_SX127X_STANDBY); 919 RADIOLIB_ASSERT(state); 920 921 // set AFC bandwidth 922 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_AFC_BW, calculateBWManExp(rxBw), 4, 0)); 923 } 924 925 int16_t SX127x::setAFC(bool isEnabled) { 926 // check active modem 927 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 928 return(RADIOLIB_ERR_WRONG_MODEM); 929 } 930 931 //set AFC auto on/off 932 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_CONFIG, isEnabled ? RADIOLIB_SX127X_AFC_AUTO_ON : RADIOLIB_SX127X_AFC_AUTO_OFF, 4, 4)); 933 } 934 935 int16_t SX127x::setAFCAGCTrigger(uint8_t trigger) { 936 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 937 return(RADIOLIB_ERR_WRONG_MODEM); 938 } 939 940 //set AFC&AGC trigger 941 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_CONFIG, trigger, 2, 0)); 942 } 943 944 int16_t SX127x::setSyncWord(uint8_t* syncWord, size_t len) { 945 // check active modem 946 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 947 return(RADIOLIB_ERR_WRONG_MODEM); 948 } 949 950 RADIOLIB_CHECK_RANGE(len, 1, 8, RADIOLIB_ERR_INVALID_SYNC_WORD); 951 952 // sync word must not contain value 0x00 953 for(size_t i = 0; i < len; i++) { 954 if(syncWord[i] == 0x00) { 955 return(RADIOLIB_ERR_INVALID_SYNC_WORD); 956 } 957 } 958 959 // enable sync word recognition 960 int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYNC_CONFIG, RADIOLIB_SX127X_SYNC_ON, 4, 4); 961 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYNC_CONFIG, len - 1, 2, 0); 962 RADIOLIB_ASSERT(state); 963 964 // set sync word 965 _mod->SPIwriteRegisterBurst(RADIOLIB_SX127X_REG_SYNC_VALUE_1, syncWord, len); 966 return(RADIOLIB_ERR_NONE); 967 } 968 969 int16_t SX127x::setNodeAddress(uint8_t nodeAddr) { 970 // check active modem 971 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 972 return(RADIOLIB_ERR_WRONG_MODEM); 973 } 974 975 // enable address filtering (node only) 976 int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_ADDRESS_FILTERING_NODE, 2, 1); 977 RADIOLIB_ASSERT(state); 978 979 // set node address 980 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_NODE_ADRS, nodeAddr)); 981 } 982 983 int16_t SX127x::setBroadcastAddress(uint8_t broadAddr) { 984 // check active modem 985 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 986 return(RADIOLIB_ERR_WRONG_MODEM); 987 } 988 989 // enable address filtering (node + broadcast) 990 int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_ADDRESS_FILTERING_NODE_BROADCAST, 2, 1); 991 RADIOLIB_ASSERT(state); 992 993 // set broadcast address 994 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BROADCAST_ADRS, broadAddr)); 995 } 996 997 int16_t SX127x::disableAddressFiltering() { 998 // check active modem 999 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 1000 return(RADIOLIB_ERR_WRONG_MODEM); 1001 } 1002 1003 // disable address filtering 1004 int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_ADDRESS_FILTERING_OFF, 2, 1); 1005 RADIOLIB_ASSERT(state); 1006 1007 // set node address to default (0x00) 1008 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_NODE_ADRS, 0x00); 1009 RADIOLIB_ASSERT(state); 1010 1011 // set broadcast address to default (0x00) 1012 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_BROADCAST_ADRS, 0x00)); 1013 } 1014 1015 int16_t SX127x::setOokThresholdType(uint8_t type) { 1016 // check active modem 1017 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 1018 return(RADIOLIB_ERR_WRONG_MODEM); 1019 } 1020 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OOK_PEAK, type, 4, 3, 5)); 1021 } 1022 1023 int16_t SX127x::setOokFixedOrFloorThreshold(uint8_t value) { 1024 // check active modem 1025 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 1026 return(RADIOLIB_ERR_WRONG_MODEM); 1027 } 1028 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OOK_FIX, value, 7, 0, 5)); 1029 } 1030 1031 int16_t SX127x::setOokPeakThresholdDecrement(uint8_t value) { 1032 // check active modem 1033 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 1034 return(RADIOLIB_ERR_WRONG_MODEM); 1035 } 1036 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OOK_AVG, value, 7, 5, 5)); 1037 } 1038 1039 int16_t SX127x::setOokPeakThresholdStep(uint8_t value) { 1040 // check active modem 1041 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 1042 return(RADIOLIB_ERR_WRONG_MODEM); 1043 } 1044 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OOK_PEAK, value, 2, 0, 5)); 1045 } 1046 1047 int16_t SX127x::enableBitSync() { 1048 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OOK_PEAK, RADIOLIB_SX127X_BIT_SYNC_ON, 5, 5, 5)); 1049 } 1050 1051 int16_t SX127x::disableBitSync() { 1052 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OOK_PEAK, RADIOLIB_SX127X_BIT_SYNC_OFF, 5, 5, 5)); 1053 } 1054 1055 int16_t SX127x::setOOK(bool enableOOK) { 1056 // check active modem 1057 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 1058 return(RADIOLIB_ERR_WRONG_MODEM); 1059 } 1060 1061 // set OOK and if successful, save the new setting 1062 int16_t state = RADIOLIB_ERR_NONE; 1063 if(enableOOK) { 1064 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, RADIOLIB_SX127X_MODULATION_OOK, 6, 5, 5); 1065 state |= SX127x::setAFCAGCTrigger(RADIOLIB_SX127X_RX_TRIGGER_RSSI_INTERRUPT); 1066 } else { 1067 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, RADIOLIB_SX127X_MODULATION_FSK, 6, 5, 5); 1068 state |= SX127x::setAFCAGCTrigger(RADIOLIB_SX127X_RX_TRIGGER_BOTH); 1069 } 1070 if(state == RADIOLIB_ERR_NONE) { 1071 _ook = enableOOK; 1072 } 1073 1074 return(state); 1075 } 1076 1077 int16_t SX127x::setFrequencyRaw(float newFreq) { 1078 int16_t state = RADIOLIB_ERR_NONE; 1079 1080 // set mode to standby if not FHSS 1081 if(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD) == RADIOLIB_SX127X_HOP_PERIOD_OFF) { 1082 state = setMode(RADIOLIB_SX127X_STANDBY); 1083 } 1084 1085 // calculate register values 1086 uint32_t FRF = (newFreq * (uint32_t(1) << RADIOLIB_SX127X_DIV_EXPONENT)) / RADIOLIB_SX127X_CRYSTAL_FREQ; 1087 1088 // write registers 1089 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FRF_MSB, (FRF & 0xFF0000) >> 16); 1090 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FRF_MID, (FRF & 0x00FF00) >> 8); 1091 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FRF_LSB, FRF & 0x0000FF); 1092 return(state); 1093 } 1094 1095 size_t SX127x::getPacketLength(bool update) { 1096 int16_t modem = getActiveModem(); 1097 1098 if(modem == RADIOLIB_SX127X_LORA) { 1099 if(_sf != 6) { 1100 // get packet length for SF7 - SF12 1101 return(_mod->SPIreadRegister(RADIOLIB_SX127X_REG_RX_NB_BYTES)); 1102 1103 } else { 1104 // return the cached value for SF6 1105 return(_packetLength); 1106 } 1107 1108 } else if(modem == RADIOLIB_SX127X_FSK_OOK) { 1109 // get packet length 1110 if(!_packetLengthQueried && update) { 1111 if (_packetLengthConfig == RADIOLIB_SX127X_PACKET_VARIABLE) { 1112 _packetLength = _mod->SPIreadRegister(RADIOLIB_SX127X_REG_FIFO); 1113 } else { 1114 _packetLength = _mod->SPIreadRegister(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH_FSK); 1115 } 1116 _packetLengthQueried = true; 1117 } 1118 } 1119 1120 return(_packetLength); 1121 } 1122 1123 int16_t SX127x::fixedPacketLengthMode(uint8_t len) { 1124 return(SX127x::setPacketMode(RADIOLIB_SX127X_PACKET_FIXED, len)); 1125 } 1126 1127 int16_t SX127x::variablePacketLengthMode(uint8_t maxLen) { 1128 return(SX127x::setPacketMode(RADIOLIB_SX127X_PACKET_VARIABLE, maxLen)); 1129 } 1130 1131 uint32_t SX127x::getTimeOnAir(size_t len) { 1132 // check active modem 1133 uint8_t modem = getActiveModem(); 1134 if (modem == RADIOLIB_SX127X_LORA) { 1135 // Get symbol length in us 1136 float symbolLength = (float) (uint32_t(1) << _sf) / (float) _bw; 1137 // Get Low Data Rate optimization flag 1138 float de = 0; 1139 if (symbolLength >= 16.0) { 1140 de = 1; 1141 } 1142 // Get explicit/implicit header enabled flag 1143 float ih = (float) _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_1, 0, 0); 1144 // Get CRC enabled flag 1145 float crc = (float) (_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_MODEM_CONFIG_2, 2, 2) >> 2); 1146 // Get number of bits preamble 1147 float n_pre = (float) ((_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_MSB) << 8) | _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_LSB)); 1148 // Get number of bits payload 1149 float n_pay = 8.0 + max(ceil((8.0 * (float) len - 4.0 * (float) _sf + 28.0 + 16.0 * crc - 20.0 * ih) / (4.0 * (float) _sf - 8.0 * de)) * (float) _cr, 0.0); 1150 1151 // Get time-on-air in us 1152 return ceil(symbolLength * (n_pre + n_pay + 4.25)) * 1000; 1153 } else if(modem == RADIOLIB_SX127X_FSK_OOK) { 1154 // Get number of bits preamble 1155 float n_pre = (float) ((_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_MSB_FSK) << 8) | _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_LSB_FSK)) * 8; 1156 //Get the number of bits of the sync word 1157 float n_syncWord = (float) (_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_SYNC_CONFIG, 2, 0) + 1) * 8; 1158 //Get CRC bits 1159 float crc = (_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, 4, 4) == RADIOLIB_SX127X_CRC_ON) * 16; 1160 1161 if (_packetLengthConfig == RADIOLIB_SX127X_PACKET_FIXED) { 1162 //If Packet size fixed -> len = fixed packet length 1163 len = _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH_FSK); 1164 } else { 1165 //if packet variable -> Add 1 extra byte for payload length 1166 len += 1; 1167 } 1168 1169 // Calculate time-on-air in us {[(length in bytes) * (8 bits / 1 byte)] / [(Bit Rate in kbps) * (1000 bps / 1 kbps)]} * (1000000 us in 1 sec) 1170 return (uint32_t) (((crc + n_syncWord + n_pre + (float) (len * 8)) / (_br * 1000.0)) * 1000000.0); 1171 } else { 1172 return(RADIOLIB_ERR_UNKNOWN); 1173 } 1174 1175 } 1176 1177 int16_t SX127x::setCrcFiltering(bool crcOn) { 1178 _crcOn = crcOn; 1179 1180 if (crcOn == true) { 1181 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_CRC_ON, 4, 4)); 1182 } else { 1183 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_CRC_OFF, 4, 4)); 1184 } 1185 } 1186 1187 int16_t SX127x::setRSSIThreshold(float dbm) { 1188 RADIOLIB_CHECK_RANGE(dbm, -127.5, 0, RADIOLIB_ERR_INVALID_RSSI_THRESHOLD); 1189 1190 return _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RSSI_THRESH, (uint8_t)(-2.0 * dbm), 7, 0); 1191 } 1192 1193 int16_t SX127x::setRSSIConfig(uint8_t smoothingSamples, int8_t offset) { 1194 // check active modem 1195 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 1196 return(RADIOLIB_ERR_WRONG_MODEM); 1197 } 1198 1199 // set mode to standby 1200 int16_t state = standby(); 1201 RADIOLIB_ASSERT(state); 1202 1203 // check provided values 1204 if(!(smoothingSamples <= 7)) { 1205 return(RADIOLIB_ERR_INVALID_NUM_SAMPLES); 1206 } 1207 1208 RADIOLIB_CHECK_RANGE(offset, -16, 15, RADIOLIB_ERR_INVALID_RSSI_OFFSET); 1209 1210 // set new register values 1211 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RSSI_CONFIG, offset << 3, 7, 3); 1212 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RSSI_CONFIG, smoothingSamples, 2, 0); 1213 return(state); 1214 } 1215 1216 int16_t SX127x::setEncoding(uint8_t encoding) { 1217 // check active modem 1218 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 1219 return(RADIOLIB_ERR_WRONG_MODEM); 1220 } 1221 1222 // set encoding 1223 switch(encoding) { 1224 case RADIOLIB_ENCODING_NRZ: 1225 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_DC_FREE_NONE, 6, 5)); 1226 case RADIOLIB_ENCODING_MANCHESTER: 1227 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_DC_FREE_MANCHESTER, 6, 5)); 1228 case RADIOLIB_ENCODING_WHITENING: 1229 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_DC_FREE_WHITENING, 6, 5)); 1230 default: 1231 return(RADIOLIB_ERR_INVALID_ENCODING); 1232 } 1233 } 1234 1235 uint16_t SX127x::getIRQFlags() { 1236 // check active modem 1237 if(getActiveModem() == RADIOLIB_SX127X_LORA) { 1238 // LoRa, just 8-bit value 1239 return((uint16_t)_mod->SPIreadRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS)); 1240 1241 } else { 1242 // FSK, the IRQ flags are 16 bits in total 1243 uint16_t flags = ((uint16_t)_mod->SPIreadRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_2)) << 8; 1244 flags |= (uint16_t)_mod->SPIreadRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_1); 1245 return(flags); 1246 } 1247 1248 } 1249 1250 uint8_t SX127x::getModemStatus() { 1251 // check active modem 1252 if(getActiveModem() != RADIOLIB_SX127X_LORA) { 1253 return(0x00); 1254 } 1255 1256 // read the register 1257 return(_mod->SPIreadRegister(RADIOLIB_SX127X_REG_MODEM_STAT)); 1258 } 1259 1260 void SX127x::setRfSwitchPins(RADIOLIB_PIN_TYPE rxEn, RADIOLIB_PIN_TYPE txEn) { 1261 _mod->setRfSwitchPins(rxEn, txEn); 1262 } 1263 1264 uint8_t SX127x::randomByte() { 1265 // check active modem 1266 uint8_t rssiValueReg = RADIOLIB_SX127X_REG_RSSI_WIDEBAND; 1267 if(getActiveModem() == RADIOLIB_SX127X_FSK_OOK) { 1268 rssiValueReg = RADIOLIB_SX127X_REG_RSSI_VALUE_FSK; 1269 } 1270 1271 // set mode to Rx 1272 setMode(RADIOLIB_SX127X_RX); 1273 1274 // wait a bit for the RSSI reading to stabilise 1275 _mod->delay(10); 1276 1277 // read RSSI value 8 times, always keep just the least significant bit 1278 uint8_t randByte = 0x00; 1279 for(uint8_t i = 0; i < 8; i++) { 1280 randByte |= ((_mod->SPIreadRegister(rssiValueReg) & 0x01) << i); 1281 } 1282 1283 // set mode to standby 1284 setMode(RADIOLIB_SX127X_STANDBY); 1285 1286 return(randByte); 1287 } 1288 1289 int16_t SX127x::getChipVersion() { 1290 return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_VERSION)); 1291 } 1292 1293 int8_t SX127x::getTempRaw() { 1294 int8_t temp = 0; 1295 uint8_t previousOpMode; 1296 uint8_t ival; 1297 1298 // save current Op Mode 1299 previousOpMode = _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_OP_MODE); 1300 1301 // check if we need to step out of LoRa mode first 1302 if ((previousOpMode & RADIOLIB_SX127X_LORA) == RADIOLIB_SX127X_LORA) { 1303 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, (RADIOLIB_SX127X_LORA | RADIOLIB_SX127X_SLEEP)); 1304 } 1305 1306 // put device in FSK sleep 1307 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, (RADIOLIB_SX127X_FSK_OOK | RADIOLIB_SX127X_SLEEP)); 1308 1309 // put device in FSK RxSynth 1310 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, (RADIOLIB_SX127X_FSK_OOK | RADIOLIB_SX127X_FSRX)); 1311 1312 // enable temperature reading 1313 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_IMAGE_CAL, RADIOLIB_SX127X_TEMP_MONITOR_ON, 0, 0); 1314 1315 // wait 1316 _mod->delayMicroseconds(200); 1317 1318 // disable temperature reading 1319 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_IMAGE_CAL, RADIOLIB_SX127X_TEMP_MONITOR_OFF, 0, 0); 1320 1321 // put device in FSK sleep 1322 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, (RADIOLIB_SX127X_FSK_OOK | RADIOLIB_SX127X_SLEEP)); 1323 1324 // read temperature 1325 ival = _mod->SPIgetRegValue(RADIOLIB_SX127X_REG_TEMP); 1326 1327 // convert very raw value 1328 if ((ival & 0x80) == 0x80) { 1329 temp = 255 - ival; 1330 } else { 1331 temp = -1 * ival; 1332 } 1333 1334 // check if we need to step back into LoRa mode 1335 if ((previousOpMode & RADIOLIB_SX127X_LORA) == RADIOLIB_SX127X_LORA) { 1336 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, (RADIOLIB_SX127X_LORA | RADIOLIB_SX127X_SLEEP)); 1337 } 1338 1339 // reload previous Op Mode 1340 _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, previousOpMode); 1341 1342 return(temp); 1343 } 1344 1345 int16_t SX127x::config() { 1346 // turn off frequency hopping 1347 int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, RADIOLIB_SX127X_HOP_PERIOD_OFF); 1348 return(state); 1349 } 1350 1351 int16_t SX127x::configFSK() { 1352 // set RSSI threshold 1353 int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RSSI_THRESH, RADIOLIB_SX127X_RSSI_THRESHOLD); 1354 RADIOLIB_ASSERT(state); 1355 1356 // reset FIFO flag 1357 _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_2, RADIOLIB_SX127X_FLAG_FIFO_OVERRUN); 1358 1359 // set packet configuration 1360 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, RADIOLIB_SX127X_PACKET_VARIABLE | RADIOLIB_SX127X_DC_FREE_NONE | RADIOLIB_SX127X_CRC_ON | RADIOLIB_SX127X_CRC_AUTOCLEAR_ON | RADIOLIB_SX127X_ADDRESS_FILTERING_OFF | RADIOLIB_SX127X_CRC_WHITENING_TYPE_CCITT, 7, 0); 1361 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_2, RADIOLIB_SX127X_DATA_MODE_PACKET | RADIOLIB_SX127X_IO_HOME_OFF, 6, 5); 1362 RADIOLIB_ASSERT(state); 1363 1364 // set preamble polarity 1365 state =_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_SYNC_CONFIG, RADIOLIB_SX127X_PREAMBLE_POLARITY_55, 5, 5); 1366 RADIOLIB_ASSERT(state); 1367 1368 // set FIFO threshold 1369 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_THRESH, RADIOLIB_SX127X_TX_START_FIFO_NOT_EMPTY, 7, 7); 1370 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_FIFO_THRESH, RADIOLIB_SX127X_FIFO_THRESH, 5, 0); 1371 RADIOLIB_ASSERT(state); 1372 1373 // disable Rx timeouts 1374 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_TIMEOUT_1, RADIOLIB_SX127X_TIMEOUT_RX_RSSI_OFF); 1375 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_TIMEOUT_2, RADIOLIB_SX127X_TIMEOUT_RX_PREAMBLE_OFF); 1376 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_RX_TIMEOUT_3, RADIOLIB_SX127X_TIMEOUT_SIGNAL_SYNC_OFF); 1377 RADIOLIB_ASSERT(state); 1378 1379 // enable preamble detector 1380 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PREAMBLE_DETECT, RADIOLIB_SX127X_PREAMBLE_DETECTOR_ON | RADIOLIB_SX127X_PREAMBLE_DETECTOR_2_BYTE | RADIOLIB_SX127X_PREAMBLE_DETECTOR_TOL); 1381 1382 return(state); 1383 } 1384 1385 int16_t SX127x::setPacketMode(uint8_t mode, uint8_t len) { 1386 // check packet length 1387 if (len > RADIOLIB_SX127X_MAX_PACKET_LENGTH_FSK) { 1388 return(RADIOLIB_ERR_PACKET_TOO_LONG); 1389 } 1390 1391 // check active modem 1392 if(getActiveModem() != RADIOLIB_SX127X_FSK_OOK) { 1393 return(RADIOLIB_ERR_WRONG_MODEM); 1394 } 1395 1396 // set to fixed packet length 1397 int16_t state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PACKET_CONFIG_1, mode, 7, 7); 1398 RADIOLIB_ASSERT(state); 1399 1400 // set length to register 1401 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_PAYLOAD_LENGTH_FSK, len); 1402 RADIOLIB_ASSERT(state); 1403 1404 // update cached value 1405 _packetLengthConfig = mode; 1406 return(state); 1407 } 1408 1409 bool SX127x::findChip(uint8_t ver) { 1410 uint8_t i = 0; 1411 bool flagFound = false; 1412 while((i < 10) && !flagFound) { 1413 // reset the module 1414 reset(); 1415 1416 // check version register 1417 int16_t version = getChipVersion(); 1418 if(version == ver) { 1419 flagFound = true; 1420 } else { 1421 #if defined(RADIOLIB_DEBUG) 1422 RADIOLIB_DEBUG_PRINT(F("SX127x not found! (")); 1423 RADIOLIB_DEBUG_PRINT(i + 1); 1424 RADIOLIB_DEBUG_PRINT(F(" of 10 tries) RADIOLIB_SX127X_REG_VERSION == ")); 1425 1426 char buffHex[12]; 1427 sprintf(buffHex, "0x%04X", version); 1428 RADIOLIB_DEBUG_PRINT(buffHex); 1429 RADIOLIB_DEBUG_PRINT(F(", expected 0x00")); 1430 RADIOLIB_DEBUG_PRINTLN(ver, HEX); 1431 #endif 1432 _mod->delay(10); 1433 i++; 1434 } 1435 } 1436 1437 return(flagFound); 1438 } 1439 1440 int16_t SX127x::setMode(uint8_t mode) { 1441 uint8_t checkMask = 0xFF; 1442 if((getActiveModem() == RADIOLIB_SX127X_FSK_OOK) && (mode == RADIOLIB_SX127X_RX)) { 1443 // disable checking of RX bit in FSK RX mode, as it sometimes seem to fail (#276) 1444 checkMask = 0xFE; 1445 } 1446 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, mode, 2, 0, 5, checkMask)); 1447 } 1448 1449 int16_t SX127x::getActiveModem() { 1450 return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_OP_MODE, 7, 7)); 1451 } 1452 1453 int16_t SX127x::setActiveModem(uint8_t modem) { 1454 // set mode to SLEEP 1455 int16_t state = setMode(RADIOLIB_SX127X_SLEEP); 1456 1457 // set modem 1458 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_OP_MODE, modem, 7, 7, 5); 1459 1460 // set mode to STANDBY 1461 state |= setMode(RADIOLIB_SX127X_STANDBY); 1462 return(state); 1463 } 1464 1465 void SX127x::clearIRQFlags() { 1466 int16_t modem = getActiveModem(); 1467 if(modem == RADIOLIB_SX127X_LORA) { 1468 _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, 0b11111111); 1469 } else if(modem == RADIOLIB_SX127X_FSK_OOK) { 1470 _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_1, 0b11111111); 1471 _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS_2, 0b11111111); 1472 } 1473 } 1474 1475 void SX127x::clearFIFO(size_t count) { 1476 while(count) { 1477 _mod->SPIreadRegister(RADIOLIB_SX127X_REG_FIFO); 1478 count--; 1479 } 1480 } 1481 1482 int16_t SX127x::invertIQ(bool invertIQ) { 1483 // check active modem 1484 if(getActiveModem() != RADIOLIB_SX127X_LORA) { 1485 return(RADIOLIB_ERR_WRONG_MODEM); 1486 } 1487 1488 int16_t state; 1489 if(invertIQ) { 1490 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_INVERT_IQ, RADIOLIB_SX127X_INVERT_IQ_RXPATH_ON, 6, 6); 1491 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_INVERT_IQ, RADIOLIB_SX127X_INVERT_IQ_TXPATH_ON, 0, 0); 1492 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_INVERT_IQ2, RADIOLIB_SX127X_IQ2_ENABLE); 1493 } else { 1494 state = _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_INVERT_IQ, RADIOLIB_SX127X_INVERT_IQ_RXPATH_OFF, 6, 6); 1495 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_INVERT_IQ, RADIOLIB_SX127X_INVERT_IQ_TXPATH_OFF, 0, 0); 1496 state |= _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_INVERT_IQ2, RADIOLIB_SX127X_IQ2_DISABLE); 1497 } 1498 1499 return(state); 1500 } 1501 1502 #if !defined(RADIOLIB_EXCLUDE_DIRECT_RECEIVE) 1503 void SX127x::setDirectAction(void (*func)(void)) { 1504 setDio1Action(func); 1505 } 1506 1507 void SX127x::readBit(RADIOLIB_PIN_TYPE pin) { 1508 updateDirectBuffer((uint8_t)digitalRead(pin)); 1509 } 1510 #endif 1511 1512 int16_t SX127x::setFHSSHoppingPeriod(uint8_t freqHoppingPeriod) { 1513 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD, freqHoppingPeriod)); 1514 } 1515 1516 uint8_t SX127x::getFHSSHoppingPeriod(void) { 1517 return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_PERIOD)); 1518 } 1519 1520 uint8_t SX127x::getFHSSChannel(void) { 1521 return(_mod->SPIgetRegValue(RADIOLIB_SX127X_REG_HOP_CHANNEL, 5, 0)); 1522 } 1523 1524 void SX127x::clearFHSSInt(void) { 1525 int16_t modem = getActiveModem(); 1526 if(modem == RADIOLIB_SX127X_LORA) { 1527 _mod->SPIwriteRegister(RADIOLIB_SX127X_REG_IRQ_FLAGS, getIRQFlags() | RADIOLIB_SX127X_CLEAR_IRQ_FLAG_FHSS_CHANGE_CHANNEL); 1528 } else if(modem == RADIOLIB_SX127X_FSK_OOK) { 1529 return; //These are not the interrupts you are looking for 1530 } 1531 } 1532 1533 int16_t SX127x::setDIOMapping(RADIOLIB_PIN_TYPE pin, uint8_t value) { 1534 if (pin > 5) 1535 return RADIOLIB_ERR_INVALID_DIO_PIN; 1536 1537 if (pin < 4) 1538 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_1, value, 7 - 2 * pin, 6 - 2 * pin)); 1539 else 1540 return(_mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_2, value, 15 - 2 * pin, 14 - 2 * pin)); 1541 } 1542 1543 int16_t SX127x::setDIOPreambleDetect(bool usePreambleDetect) { 1544 return _mod->SPIsetRegValue(RADIOLIB_SX127X_REG_DIO_MAPPING_2, (usePreambleDetect) ? RADIOLIB_SX127X_DIO_MAP_PREAMBLE_DETECT : RADIOLIB_SX127X_DIO_MAP_RSSI, 0, 0); 1545 } 1546 1547 #endif