LCOV - code coverage report
Current view: top level - src/modules/LR11x0 - LR11x0_commands.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 442 0.0 %
Date: 2025-10-24 15:14:50 Functions: 0 87 0.0 %

          Line data    Source code
       1             : #include "LR11x0.h"
       2             : 
       3             : #include "../../utils/CRC.h"
       4             : #include "../../utils/Cryptography.h"
       5             : 
       6             : #include <string.h>
       7             : #include <math.h>
       8             : 
       9             : #if !RADIOLIB_EXCLUDE_LR11X0
      10             : 
      11           0 : int16_t LR11x0::writeRegMem32(uint32_t addr, const uint32_t* data, size_t len) {
      12             :   // check maximum size
      13           0 :   if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
      14           0 :     return(RADIOLIB_ERR_SPI_CMD_INVALID);
      15             :   }
      16           0 :   return(this->writeCommon(RADIOLIB_LR11X0_CMD_WRITE_REG_MEM, addr, data, len, false));
      17             : }
      18             : 
      19           0 : int16_t LR11x0::readRegMem32(uint32_t addr, uint32_t* data, size_t len) {
      20             :   // check maximum size
      21           0 :   if(len >= (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
      22           0 :     return(RADIOLIB_ERR_SPI_CMD_INVALID);
      23             :   }
      24             : 
      25             :   // the request contains the address and length
      26             :   uint8_t reqBuff[5] = {
      27           0 :     (uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF),
      28           0 :     (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF),
      29             :     (uint8_t)len,
      30           0 :   };
      31             : 
      32             :   // build buffers - later we need to ensure endians are correct, 
      33             :   // so there is probably no way to do this without copying buffers and iterating
      34             :   #if RADIOLIB_STATIC_ONLY
      35             :     uint8_t rplBuff[RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
      36             :   #else
      37           0 :     uint8_t* rplBuff = new uint8_t[len*sizeof(uint32_t)];
      38             :   #endif
      39             : 
      40           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_READ_REG_MEM, false, rplBuff, len*sizeof(uint32_t), reqBuff, sizeof(reqBuff));
      41             : 
      42             :   // convert endians
      43           0 :   if(data && (state == RADIOLIB_ERR_NONE)) {
      44           0 :     for(size_t i = 0; i < len; i++) {
      45           0 :       data[i] = ((uint32_t)rplBuff[2 + i*sizeof(uint32_t)] << 24) | ((uint32_t)rplBuff[3 + i*sizeof(uint32_t)] << 16) | ((uint32_t)rplBuff[4 + i*sizeof(uint32_t)] << 8) | (uint32_t)rplBuff[5 + i*sizeof(uint32_t)];
      46             :     }
      47             :   }
      48             : 
      49             :   #if !RADIOLIB_STATIC_ONLY
      50           0 :     delete[] rplBuff;
      51             :   #endif
      52             :   
      53           0 :   return(state);
      54             : }
      55             : 
      56           0 : int16_t LR11x0::writeBuffer8(const uint8_t* data, size_t len) {
      57             :   // check maximum size
      58           0 :   if(len > RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN) {
      59           0 :     return(RADIOLIB_ERR_SPI_CMD_INVALID);
      60             :   }
      61           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_WRITE_BUFFER, true, const_cast<uint8_t*>(data), len));
      62             : }
      63             : 
      64           0 : int16_t LR11x0::readBuffer8(uint8_t* data, size_t len, size_t offset) {
      65             :   // check maximum size
      66           0 :   if(len > RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN) {
      67           0 :     return(RADIOLIB_ERR_SPI_CMD_INVALID);
      68             :   }
      69             : 
      70             :   // build buffers
      71           0 :   size_t reqLen = 2*sizeof(uint8_t) + len;
      72             :   #if RADIOLIB_STATIC_ONLY
      73             :     uint8_t reqBuff[sizeof(uint32_t) + RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
      74             :   #else
      75           0 :     uint8_t* reqBuff = new uint8_t[reqLen];
      76             :   #endif
      77             : 
      78             :   // set the offset and length
      79           0 :   reqBuff[0] = (uint8_t)offset;
      80           0 :   reqBuff[1] = (uint8_t)len;
      81             : 
      82             :   // send the request
      83           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_READ_BUFFER, false, data, len, reqBuff, reqLen);
      84             :   #if !RADIOLIB_STATIC_ONLY
      85           0 :     delete[] reqBuff;
      86             :   #endif
      87           0 :   return(state);
      88             : }
      89             : 
      90           0 : int16_t LR11x0::clearRxBuffer(void) {
      91           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CLEAR_RX_BUFFER, true, NULL, 0));
      92             : }
      93             : 
      94           0 : int16_t LR11x0::writeRegMemMask32(uint32_t addr, uint32_t mask, uint32_t data) {
      95             :   uint8_t buff[12] = {
      96           0 :     (uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF),
      97           0 :     (uint8_t)((mask >> 24) & 0xFF), (uint8_t)((mask >> 16) & 0xFF), (uint8_t)((mask >> 8) & 0xFF), (uint8_t)(mask & 0xFF),
      98           0 :     (uint8_t)((data >> 24) & 0xFF), (uint8_t)((data >> 16) & 0xFF), (uint8_t)((data >> 8) & 0xFF), (uint8_t)(data & 0xFF),
      99           0 :   };
     100           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_WRITE_REG_MEM_MASK, true, buff, sizeof(buff)));
     101             : }
     102             : 
     103           0 : int16_t LR11x0::getStatus(uint8_t* stat1, uint8_t* stat2, uint32_t* irq) {
     104           0 :   uint8_t buff[6] = { 0 };
     105             : 
     106             :   // the status check command doesn't return status in the same place as other read commands
     107             :   // but only as the first byte (as with any other command), hence LR11x0::SPIcommand can't be used
     108             :   // it also seems to ignore the actual command, and just sending in bunch of NOPs will work 
     109           0 :   int16_t state = this->mod->SPItransferStream(NULL, 0, false, NULL, buff, sizeof(buff), true);
     110             : 
     111             :   // pass the replies
     112           0 :   if(stat1) { *stat1 = buff[0]; }
     113           0 :   if(stat2) { *stat2 = buff[1]; }
     114           0 :   if(irq)   { *irq = ((uint32_t)(buff[2]) << 24) | ((uint32_t)(buff[3]) << 16) | ((uint32_t)(buff[4]) << 8) | (uint32_t)buff[5]; }
     115             : 
     116           0 :   return(state);
     117             : }
     118             : 
     119           0 : int16_t LR11x0::getVersion(uint8_t* hw, uint8_t* device, uint8_t* major, uint8_t* minor) {
     120           0 :   uint8_t buff[4] = { 0 };
     121           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_VERSION, false, buff, sizeof(buff));
     122             : 
     123             :   // pass the replies
     124           0 :   if(hw)      { *hw = buff[0]; }
     125           0 :   if(device)  { *device = buff[1]; }
     126           0 :   if(major)   { *major = buff[2]; }
     127           0 :   if(minor)   { *minor = buff[3]; }
     128             : 
     129           0 :   return(state);
     130             : }
     131             : 
     132           0 : int16_t LR11x0::getErrors(uint16_t* err) {
     133           0 :   uint8_t buff[2] = { 0 };
     134           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_ERRORS, false, buff, sizeof(buff));
     135             : 
     136             :   // pass the replies
     137           0 :   if(err) { *err = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1];  }
     138             : 
     139           0 :   return(state);
     140             : }
     141             : 
     142           0 : int16_t LR11x0::clearErrors(void) {
     143           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CLEAR_ERRORS, true, NULL, 0));
     144             : }
     145             : 
     146           0 : int16_t LR11x0::calibrate(uint8_t params) {
     147           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CALIBRATE, true, &params, 1));
     148             : }
     149             : 
     150           0 : int16_t LR11x0::setRegMode(uint8_t mode) {
     151           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_REG_MODE, true, &mode, 1));
     152             : }
     153             : 
     154           0 : int16_t LR11x0::calibrateImageRejection(float freqMin, float freqMax) {
     155             :   uint8_t buff[2] = {
     156           0 :     (uint8_t)floor((freqMin - 1.0f) / 4.0f),
     157           0 :     (uint8_t)ceil((freqMax + 1.0f) / 4.0f)
     158           0 :   };
     159           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CALIB_IMAGE, true, buff, sizeof(buff)));
     160             : }
     161             : 
     162           0 : int16_t LR11x0::setDioAsRfSwitch(uint8_t en, uint8_t stbyCfg, uint8_t rxCfg, uint8_t txCfg, uint8_t txHpCfg, uint8_t txHfCfg, uint8_t gnssCfg, uint8_t wifiCfg) {
     163           0 :   uint8_t buff[8] = { en, stbyCfg, rxCfg, txCfg, txHpCfg, txHfCfg, gnssCfg, wifiCfg };
     164           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_DIO_AS_RF_SWITCH, true, buff, sizeof(buff)));
     165             : }
     166             : 
     167           0 : int16_t LR11x0::setDioIrqParams(uint32_t irq1, uint32_t irq2) {
     168             :   uint8_t buff[8] = {
     169           0 :     (uint8_t)((irq1 >> 24) & 0xFF), (uint8_t)((irq1 >> 16) & 0xFF), (uint8_t)((irq1 >> 8) & 0xFF), (uint8_t)(irq1 & 0xFF),
     170           0 :     (uint8_t)((irq2 >> 24) & 0xFF), (uint8_t)((irq2 >> 16) & 0xFF), (uint8_t)((irq2 >> 8) & 0xFF), (uint8_t)(irq2 & 0xFF),
     171           0 :   };
     172           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_DIO_IRQ_PARAMS, true, buff, sizeof(buff)));
     173             : }
     174             : 
     175           0 : int16_t LR11x0::setDioIrqParams(uint32_t irq) {
     176           0 :   return(setDioIrqParams(irq, this->gnss ? 0 : irq));
     177             : }
     178             : 
     179           0 : int16_t LR11x0::clearIrqState(uint32_t irq) {
     180             :   uint8_t buff[4] = {
     181           0 :     (uint8_t)((irq >> 24) & 0xFF), (uint8_t)((irq >> 16) & 0xFF), (uint8_t)((irq >> 8) & 0xFF), (uint8_t)(irq & 0xFF),
     182           0 :   };
     183           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CLEAR_IRQ, true, buff, sizeof(buff)));
     184             : }
     185             : 
     186           0 : int16_t LR11x0::configLfClock(uint8_t setup) {
     187           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_CONFIG_LF_CLOCK, true, &setup, 1));
     188             : }
     189             : 
     190           0 : int16_t LR11x0::setTcxoMode(uint8_t tune, uint32_t delay) {
     191             :   uint8_t buff[4] = {
     192           0 :     tune, (uint8_t)((delay >> 16) & 0xFF), (uint8_t)((delay >> 8) & 0xFF), (uint8_t)(delay & 0xFF),
     193           0 :   };
     194           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_TCXO_MODE, true, buff, sizeof(buff)));
     195             : }
     196             : 
     197           0 : int16_t LR11x0::reboot(bool stay) {
     198           0 :   uint8_t buff[1] = { (uint8_t)(stay*3) };
     199           0 :   return(this->mod->SPIwriteStream(RADIOLIB_LR11X0_CMD_REBOOT, buff, sizeof(buff), true, false));
     200             : }
     201             : 
     202           0 : int16_t LR11x0::getVbat(float* vbat) {
     203           0 :   uint8_t buff[1] = { 0 };
     204           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_VBAT, false, buff, sizeof(buff));
     205             : 
     206             :   // pass the replies
     207           0 :   if(vbat) { *vbat = (((float)buff[0]/51.0f) - 1.0f)*1.35f; }
     208             : 
     209           0 :   return(state);
     210             : }
     211             : 
     212           0 : int16_t LR11x0::getTemp(float* temp) {
     213           0 :   uint8_t buff[2] = { 0 };
     214           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_TEMP, false, buff, sizeof(buff));
     215             : 
     216             :   // pass the replies
     217           0 :   if(temp) {
     218           0 :     uint16_t raw = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1];
     219           0 :     raw = raw & 0x07FF; //According LR1121 datasheet we need [0..10] bits
     220           0 :     *temp = 25.0f - (1000.0f/1.7f)*(((float)raw/2047.0f)*1.35f - 0.7295f); //According LR1121 datasheet 1.35
     221             :   }
     222             : 
     223           0 :   return(state);
     224             : }
     225             : 
     226           0 : int16_t LR11x0::setFs(void) {
     227           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_FS, true, NULL, 0));
     228             : }
     229             : 
     230           0 : int16_t LR11x0::getRandomNumber(uint32_t* rnd) {
     231           0 :   uint8_t buff[4] = { 0 };
     232           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_RANDOM_NUMBER, false, buff, sizeof(buff));
     233             : 
     234             :   // pass the replies
     235           0 :   if(rnd) { *rnd = ((uint32_t)(buff[0]) << 24) | ((uint32_t)(buff[1]) << 16) | ((uint32_t)(buff[2]) << 8) | (uint32_t)buff[3];  }
     236             : 
     237           0 :   return(state);
     238             : }
     239             : 
     240           0 : int16_t LR11x0::eraseInfoPage(void) {
     241             :   // only page 1 can be erased
     242           0 :   uint8_t buff[1] = { RADIOLIB_LR11X0_INFO_PAGE };
     243           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_ERASE_INFO_PAGE, true, buff, sizeof(buff)));
     244             : }
     245             : 
     246           0 : int16_t LR11x0::writeInfoPage(uint16_t addr, const uint32_t* data, size_t len) {
     247             :   // check maximum size
     248           0 :   if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
     249           0 :     return(RADIOLIB_ERR_SPI_CMD_INVALID);
     250             :   }
     251             : 
     252             :   // build buffers - later we need to ensure endians are correct, 
     253             :   // so there is probably no way to do this without copying buffers and iterating
     254           0 :   size_t buffLen = sizeof(uint8_t) + sizeof(uint16_t) + len*sizeof(uint32_t);
     255             :   #if RADIOLIB_STATIC_ONLY
     256             :     uint8_t dataBuff[sizeof(uint8_t) + sizeof(uint16_t) + RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
     257             :   #else
     258           0 :     uint8_t* dataBuff = new uint8_t[buffLen];
     259             :   #endif
     260             : 
     261             :   // set the address
     262           0 :   dataBuff[0] = RADIOLIB_LR11X0_INFO_PAGE;
     263           0 :   dataBuff[1] = (uint8_t)((addr >> 8) & 0xFF);
     264           0 :   dataBuff[2] = (uint8_t)(addr & 0xFF);
     265             : 
     266             :   // convert endians
     267           0 :   for(size_t i = 0; i < len; i++) {
     268           0 :     dataBuff[3 + i] = (uint8_t)((data[i] >> 24) & 0xFF);
     269           0 :     dataBuff[4 + i] = (uint8_t)((data[i] >> 16) & 0xFF);
     270           0 :     dataBuff[5 + i] = (uint8_t)((data[i] >> 8) & 0xFF);
     271           0 :     dataBuff[6 + i] = (uint8_t)(data[i] & 0xFF);
     272             :   }
     273             : 
     274           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_WRITE_INFO_PAGE, true, dataBuff, buffLen);
     275             :   #if !RADIOLIB_STATIC_ONLY
     276           0 :     delete[] dataBuff;
     277             :   #endif
     278           0 :   return(state);
     279             : }
     280             : 
     281           0 : int16_t LR11x0::readInfoPage(uint16_t addr, uint32_t* data, size_t len) {
     282             :   // check maximum size
     283           0 :   if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
     284           0 :     return(RADIOLIB_ERR_SPI_CMD_INVALID);
     285             :   }
     286             : 
     287             :   // the request contains the address and length
     288           0 :   uint8_t reqBuff[4] = {
     289             :     RADIOLIB_LR11X0_INFO_PAGE,
     290           0 :     (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF),
     291             :     (uint8_t)len,
     292           0 :   };
     293             : 
     294             :   // build buffers - later we need to ensure endians are correct, 
     295             :   // so there is probably no way to do this without copying buffers and iterating
     296             :   #if RADIOLIB_STATIC_ONLY
     297             :     uint8_t rplBuff[RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
     298             :   #else
     299           0 :     uint8_t* rplBuff = new uint8_t[len*sizeof(uint32_t)];
     300             :   #endif
     301             : 
     302           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_READ_INFO_PAGE, false, rplBuff, len*sizeof(uint32_t), reqBuff, sizeof(reqBuff));
     303             : 
     304             :   // convert endians
     305           0 :   if(data && (state == RADIOLIB_ERR_NONE)) {
     306           0 :     for(size_t i = 0; i < len; i++) {
     307           0 :       data[i] = ((uint32_t)rplBuff[2 + i*sizeof(uint32_t)] << 24) | ((uint32_t)rplBuff[3 + i*sizeof(uint32_t)] << 16) | ((uint32_t)rplBuff[4 + i*sizeof(uint32_t)] << 8) | (uint32_t)rplBuff[5 + i*sizeof(uint32_t)];
     308             :     }
     309             :   }
     310             :   
     311             :   #if !RADIOLIB_STATIC_ONLY
     312           0 :     delete[] rplBuff;
     313             :   #endif
     314             :   
     315           0 :   return(state);
     316             : }
     317             : 
     318           0 : int16_t LR11x0::getChipEui(uint8_t* eui) {
     319           0 :   RADIOLIB_ASSERT_PTR(eui);
     320           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_CHIP_EUI, false, eui, RADIOLIB_LR11X0_EUI_LEN));
     321             : }
     322             : 
     323           0 : int16_t LR11x0::getSemtechJoinEui(uint8_t* eui) {
     324           0 :   RADIOLIB_ASSERT_PTR(eui);
     325           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_SEMTECH_JOIN_EUI, false, eui, RADIOLIB_LR11X0_EUI_LEN));
     326             : }
     327             : 
     328           0 : int16_t LR11x0::deriveRootKeysAndGetPin(uint8_t* pin) {
     329           0 :   RADIOLIB_ASSERT_PTR(pin);
     330           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_DERIVE_ROOT_KEYS_AND_GET_PIN, false, pin, RADIOLIB_LR11X0_PIN_LEN));
     331             : }
     332             : 
     333           0 : int16_t LR11x0::enableSpiCrc(bool en) {
     334             :   // TODO implement this
     335             :   (void)en;
     336             :   // LR11X0 CRC is gen 0xA6 (0x65 but reflected), init 0xFF, input and result reflected
     337             :   /*RadioLibCRCInstance.size = 8;
     338             :   RadioLibCRCInstance.poly = 0xA6;
     339             :   RadioLibCRCInstance.init = 0xFF;
     340             :   RadioLibCRCInstance.out = 0x00;
     341             :   RadioLibCRCInstance.refIn = true;
     342             :   RadioLibCRCInstance.refOut = true;*/
     343           0 :   return(RADIOLIB_ERR_UNSUPPORTED);
     344             : }
     345             : 
     346           0 : int16_t LR11x0::driveDiosInSleepMode(bool en) {
     347           0 :   uint8_t buff[1] = { (uint8_t)en };
     348           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_DRIVE_DIOS_IN_SLEEP_MODE, true, buff, sizeof(buff)));
     349             : }
     350             : 
     351           0 : int16_t LR11x0::resetStats(void) {
     352           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_RESET_STATS, true, NULL, 0));
     353             : }
     354             : 
     355           0 : int16_t LR11x0::getStats(uint16_t* nbPktReceived, uint16_t* nbPktCrcError, uint16_t* data1, uint16_t* data2) {
     356           0 :   uint8_t buff[8] = { 0 };
     357           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_STATS, false, buff, sizeof(buff));
     358             : 
     359             :   // pass the replies
     360           0 :   if(nbPktReceived) { *nbPktReceived = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
     361           0 :   if(nbPktCrcError) { *nbPktCrcError = ((uint16_t)(buff[2]) << 8) | (uint16_t)buff[3]; }
     362           0 :   if(data1) { *data1 = ((uint16_t)(buff[4]) << 8) | (uint16_t)buff[5]; }
     363           0 :   if(data2) { *data2 = ((uint16_t)(buff[6]) << 8) | (uint16_t)buff[7]; }
     364             : 
     365           0 :   return(state);
     366             : }
     367             : 
     368           0 : int16_t LR11x0::getPacketType(uint8_t* type) {
     369           0 :   uint8_t buff[1] = { 0 };
     370           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_PACKET_TYPE, false, buff, sizeof(buff));
     371             : 
     372             :   // pass the replies
     373           0 :   if(type) { *type = buff[0]; }
     374             : 
     375           0 :   return(state);
     376             : }
     377             : 
     378           0 : int16_t LR11x0::getRxBufferStatus(uint8_t* len, uint8_t* startOffset) {
     379           0 :   uint8_t buff[2] = { 0 };
     380           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_RX_BUFFER_STATUS, false, buff, sizeof(buff));
     381             : 
     382             :   // pass the replies
     383           0 :   if(len) { *len = buff[0]; }
     384           0 :   if(startOffset) { *startOffset = buff[1]; }
     385             : 
     386           0 :   return(state);
     387             : }
     388             : 
     389           0 : int16_t LR11x0::getPacketStatusLoRa(float* rssiPkt, float* snrPkt, float* signalRssiPkt) {
     390           0 :   uint8_t buff[3] = { 0 };
     391           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_PACKET_STATUS, false, buff, sizeof(buff));
     392             : 
     393             :   // pass the replies
     394           0 :   if(rssiPkt) { *rssiPkt = (float)buff[0] / -2.0f; }
     395           0 :   if(snrPkt) { *snrPkt = (float)((int8_t)buff[1]) / 4.0f; }
     396           0 :   if(signalRssiPkt) { *signalRssiPkt = buff[2]; }
     397             : 
     398           0 :   return(state);
     399             : }
     400             : 
     401           0 : int16_t LR11x0::getPacketStatusGFSK(float* rssiSync, float* rssiAvg, uint8_t* rxLen, uint8_t* stat) {
     402           0 :   uint8_t buff[4] = { 0 };
     403           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_PACKET_STATUS, false, buff, sizeof(buff));
     404             : 
     405             :   // pass the replies
     406           0 :   if(rssiSync) { *rssiSync = (float)buff[0] / -2.0f; }
     407           0 :   if(rssiAvg) { *rssiAvg = (float)buff[1] / -2.0f; }
     408           0 :   if(rxLen) { *rxLen = buff[2]; }
     409           0 :   if(stat) { *stat = buff[3]; }
     410             : 
     411           0 :   return(state);
     412             : }
     413             : 
     414           0 : int16_t LR11x0::getRssiInst(float* rssi) {
     415           0 :   uint8_t buff[1] = { 0 };
     416           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_RSSI_INST, false, buff, sizeof(buff));
     417             : 
     418             :   // pass the replies
     419           0 :   if(rssi) { *rssi = (float)buff[0] / -2.0f; }
     420             : 
     421           0 :   return(state);
     422             : }
     423             : 
     424           0 : int16_t LR11x0::setGfskSyncWord(uint8_t* sync) {
     425           0 :   RADIOLIB_ASSERT_PTR(sync);
     426           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_GFSK_SYNC_WORD, true, sync, RADIOLIB_LR11X0_GFSK_SYNC_WORD_LEN));
     427             : }
     428             : 
     429           0 : int16_t LR11x0::setLoRaPublicNetwork(bool pub) {
     430           0 :   uint8_t buff[1] = { (uint8_t)pub };
     431           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_LORA_PUBLIC_NETWORK, true, buff, sizeof(buff)));
     432             : }
     433             : 
     434           0 : int16_t LR11x0::setRx(uint32_t timeout) {
     435             :   uint8_t buff[3] = {
     436           0 :     (uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF),
     437           0 :   };
     438           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_RX, true, buff, sizeof(buff)));
     439             : }
     440             : 
     441           0 : int16_t LR11x0::setTx(uint32_t timeout) {
     442             :   uint8_t buff[3] = {
     443           0 :     (uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF),
     444           0 :   };
     445           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_TX, true, buff, sizeof(buff)));
     446             : }
     447             : 
     448           0 : int16_t LR11x0::setRfFrequency(uint32_t rfFreq) {
     449             :   uint8_t buff[4] = {
     450           0 :     (uint8_t)((rfFreq >> 24) & 0xFF), (uint8_t)((rfFreq >> 16) & 0xFF),
     451           0 :     (uint8_t)((rfFreq >> 8) & 0xFF), (uint8_t)(rfFreq & 0xFF),
     452           0 :   };
     453           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_RF_FREQUENCY, true, buff, sizeof(buff)));
     454             : }
     455             : 
     456           0 : int16_t LR11x0::autoTxRx(uint32_t delay, uint8_t intMode, uint32_t timeout) {
     457             :   uint8_t buff[7] = {
     458           0 :     (uint8_t)((delay >> 16) & 0xFF), (uint8_t)((delay >> 8) & 0xFF), (uint8_t)(delay & 0xFF), intMode,
     459           0 :     (uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF),
     460           0 :   };
     461           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_AUTO_TX_RX, true, buff, sizeof(buff)));
     462             : }
     463             : 
     464           0 : int16_t LR11x0::setCadParams(uint8_t symNum, uint8_t detPeak, uint8_t detMin, uint8_t cadExitMode, uint32_t timeout) {
     465             :   uint8_t buff[7] = {
     466             :     symNum, detPeak, detMin, cadExitMode,
     467           0 :     (uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF),
     468           0 :   };
     469           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_CAD_PARAMS, true, buff, sizeof(buff)));
     470             : }
     471             : 
     472           0 : int16_t LR11x0::setPacketType(uint8_t type) {
     473           0 :   uint8_t buff[1] = { type };
     474           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_PACKET_TYPE, true, buff, sizeof(buff)));
     475             : }
     476             : 
     477           0 : int16_t LR11x0::setModulationParamsLoRa(uint8_t sf, uint8_t bw, uint8_t cr, uint8_t ldro) {
     478             :   // calculate symbol length and enable low data rate optimization, if auto-configuration is enabled
     479           0 :   if(this->ldroAuto) {
     480           0 :     float symbolLength = (float)(uint32_t(1) << this->spreadingFactor) / (float)this->bandwidthKhz;
     481           0 :     if(symbolLength >= 16.0f) {
     482           0 :       this->ldrOptimize = RADIOLIB_LR11X0_LORA_LDRO_ENABLED;
     483             :     } else {
     484           0 :       this->ldrOptimize = RADIOLIB_LR11X0_LORA_LDRO_DISABLED;
     485             :     }
     486             :   } else {
     487           0 :     this->ldrOptimize = ldro;
     488             :   }
     489             : 
     490           0 :   uint8_t buff[4] = { sf, bw, cr, this->ldrOptimize };
     491           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_MODULATION_PARAMS, true, buff, sizeof(buff)));
     492             : }
     493             : 
     494           0 : int16_t LR11x0::setModulationParamsGFSK(uint32_t br, uint8_t sh, uint8_t rxBw, uint32_t freqDev) {
     495             :   uint8_t buff[10] = { 
     496           0 :     (uint8_t)((br >> 24) & 0xFF), (uint8_t)((br >> 16) & 0xFF),
     497           0 :     (uint8_t)((br >> 8) & 0xFF), (uint8_t)(br & 0xFF), sh, rxBw,
     498           0 :     (uint8_t)((freqDev >> 24) & 0xFF), (uint8_t)((freqDev >> 16) & 0xFF),
     499           0 :     (uint8_t)((freqDev >> 8) & 0xFF), (uint8_t)(freqDev & 0xFF)
     500           0 :   };
     501           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_MODULATION_PARAMS, true, buff, sizeof(buff)));
     502             : }
     503             : 
     504           0 : int16_t LR11x0::setModulationParamsLrFhss(uint32_t br, uint8_t sh) {
     505             :   uint8_t buff[5] = { 
     506           0 :     (uint8_t)((br >> 24) & 0xFF), (uint8_t)((br >> 16) & 0xFF),
     507           0 :     (uint8_t)((br >> 8) & 0xFF), (uint8_t)(br & 0xFF), sh
     508           0 :   };
     509           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_MODULATION_PARAMS, true, buff, sizeof(buff)));
     510             : }
     511             : 
     512           0 : int16_t LR11x0::setModulationParamsSigfox(uint32_t br, uint8_t sh) {
     513             :   // same as for LR-FHSS
     514           0 :   return(this->setModulationParamsLrFhss(br, sh));
     515             : }
     516             : 
     517           0 : int16_t LR11x0::setPacketParamsLoRa(uint16_t preambleLen, uint8_t hdrType, uint8_t payloadLen, uint8_t crcType, uint8_t invertIQ) {
     518             :   uint8_t buff[6] = { 
     519           0 :     (uint8_t)((preambleLen >> 8) & 0xFF), (uint8_t)(preambleLen & 0xFF),
     520             :     hdrType, payloadLen, crcType, invertIQ
     521           0 :   };
     522           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_PACKET_PARAMS, true, buff, sizeof(buff)));
     523             : }
     524             : 
     525           0 : int16_t LR11x0::setPacketParamsGFSK(uint16_t preambleLen, uint8_t preambleDetectorLen, uint8_t syncWordLen, uint8_t addrCmp, uint8_t packType, uint8_t payloadLen, uint8_t crcType, uint8_t whiten) {
     526             :   uint8_t buff[9] = { 
     527           0 :     (uint8_t)((preambleLen >> 8) & 0xFF), (uint8_t)(preambleLen & 0xFF),
     528             :     preambleDetectorLen, syncWordLen, addrCmp, packType, payloadLen, crcType, whiten
     529           0 :   };
     530           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_PACKET_PARAMS, true, buff, sizeof(buff)));
     531             : }
     532             : 
     533           0 : int16_t LR11x0::setPacketParamsSigfox(uint8_t payloadLen, uint16_t rampUpDelay, uint16_t rampDownDelay, uint16_t bitNum) {
     534             :   uint8_t buff[7] = { 
     535           0 :     payloadLen, (uint8_t)((rampUpDelay >> 8) & 0xFF), (uint8_t)(rampUpDelay & 0xFF),
     536           0 :     (uint8_t)((rampDownDelay >> 8) & 0xFF), (uint8_t)(rampDownDelay & 0xFF),
     537           0 :     (uint8_t)((bitNum >> 8) & 0xFF), (uint8_t)(bitNum & 0xFF),
     538           0 :   };
     539           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_PACKET_PARAMS, true, buff, sizeof(buff)));
     540             : }
     541             : 
     542           0 : int16_t LR11x0::setTxParams(int8_t pwr, uint8_t ramp) {
     543           0 :   uint8_t buff[2] = { (uint8_t)pwr, ramp };
     544           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_TX_PARAMS, true, buff, sizeof(buff)));
     545             : }
     546             : 
     547           0 : int16_t LR11x0::setPacketAdrs(uint8_t node, uint8_t broadcast) {
     548           0 :   uint8_t buff[2] = { node, broadcast };
     549           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_PACKET_ADRS, true, buff, sizeof(buff)));
     550             : }
     551             : 
     552           0 : int16_t LR11x0::setRxTxFallbackMode(uint8_t mode) {
     553           0 :   uint8_t buff[1] = { mode };
     554           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_RX_TX_FALLBACK_MODE, true, buff, sizeof(buff)));
     555             : }
     556             : 
     557           0 : int16_t LR11x0::setRxDutyCycle(uint32_t rxPeriod, uint32_t sleepPeriod, uint8_t mode) {
     558             :   uint8_t buff[7] = {
     559           0 :     (uint8_t)((rxPeriod >> 16) & 0xFF), (uint8_t)((rxPeriod >> 8) & 0xFF), (uint8_t)(rxPeriod & 0xFF),
     560           0 :     (uint8_t)((sleepPeriod >> 16) & 0xFF), (uint8_t)((sleepPeriod >> 8) & 0xFF), (uint8_t)(sleepPeriod & 0xFF),
     561             :     mode
     562           0 :   };
     563           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_RX_DUTY_CYCLE, true, buff, sizeof(buff)));
     564             : }
     565             : 
     566           0 : int16_t LR11x0::setPaConfig(uint8_t paSel, uint8_t regPaSupply, uint8_t paDutyCycle, uint8_t paHpSel) {
     567           0 :   uint8_t buff[4] = { paSel, regPaSupply, paDutyCycle, paHpSel };
     568           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_PA_CONFIG, true, buff, sizeof(buff)));
     569             : }
     570             : 
     571           0 : int16_t LR11x0::stopTimeoutOnPreamble(bool stop) {
     572           0 :   uint8_t buff[1] = { (uint8_t)stop };
     573           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_STOP_TIMEOUT_ON_PREAMBLE, true, buff, sizeof(buff)));
     574             : }
     575             : 
     576           0 : int16_t LR11x0::setCad(void) {
     577           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_CAD, true, NULL, 0));
     578             : }
     579             : 
     580           0 : int16_t LR11x0::setTxCw(void) {
     581           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_TX_CW, true, NULL, 0));
     582             : }
     583             : 
     584           0 : int16_t LR11x0::setTxInfinitePreamble(void) {
     585           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_TX_INFINITE_PREAMBLE, true, NULL, 0));
     586             : }
     587             : 
     588           0 : int16_t LR11x0::setLoRaSynchTimeout(uint8_t symbolNum) {
     589           0 :   uint8_t buff[1] = { symbolNum };
     590           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_LORA_SYNCH_TIMEOUT, true, buff, sizeof(buff)));
     591             : }
     592             : 
     593           0 : int16_t LR11x0::setRangingAddr(uint32_t addr, uint8_t checkLen) {
     594             :   uint8_t buff[5] = {
     595           0 :     (uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF),
     596           0 :     (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF), checkLen
     597           0 :   };
     598           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_RANGING_ADDR, true, buff, sizeof(buff)));
     599             : }
     600             : 
     601           0 : int16_t LR11x0::setRangingReqAddr(uint32_t addr) {
     602             :   uint8_t buff[4] = {
     603           0 :     (uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF),
     604           0 :     (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF)
     605           0 :   };
     606           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_RANGING_REQ_ADDR, true, buff, sizeof(buff)));
     607             : }
     608             : 
     609           0 : int16_t LR11x0::getRangingResult(uint8_t type, float* res) {
     610           0 :   uint8_t reqBuff[1] = { type };
     611           0 :   uint8_t rplBuff[4] = { 0 };
     612           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_RANGING_RESULT, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff));
     613           0 :   RADIOLIB_ASSERT(state);
     614             : 
     615           0 :   if(res) { 
     616           0 :     if(type == RADIOLIB_LR11X0_RANGING_RESULT_DISTANCE) {
     617           0 :       uint32_t raw = ((uint32_t)(rplBuff[0]) << 24) | ((uint32_t)(rplBuff[1]) << 16) | ((uint32_t)(rplBuff[2]) << 8) | (uint32_t)rplBuff[3];
     618           0 :       *res = ((float)(raw*3e8))/((float)(4096*this->bandwidthKhz*1000));
     619             :     } else {
     620           0 :       *res = (float)rplBuff[3]/2.0f;
     621             :     }
     622             :   }
     623             : 
     624           0 :   return(state);
     625             : }
     626             : 
     627           0 : int16_t LR11x0::setRangingTxRxDelay(uint32_t delay) {
     628             :   uint8_t buff[4] = {
     629           0 :     (uint8_t)((delay >> 24) & 0xFF), (uint8_t)((delay >> 16) & 0xFF),
     630           0 :     (uint8_t)((delay >> 8) & 0xFF), (uint8_t)(delay & 0xFF)
     631           0 :   };
     632           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_RANGING_TX_RX_DELAY, true, buff, sizeof(buff)));
     633             : }
     634             : 
     635           0 : int16_t LR11x0::setGfskCrcParams(uint32_t init, uint32_t poly) {
     636             :   uint8_t buff[8] = {
     637           0 :     (uint8_t)((init >> 24) & 0xFF), (uint8_t)((init >> 16) & 0xFF),
     638           0 :     (uint8_t)((init >> 8) & 0xFF), (uint8_t)(init & 0xFF),
     639           0 :     (uint8_t)((poly >> 24) & 0xFF), (uint8_t)((poly >> 16) & 0xFF),
     640           0 :     (uint8_t)((poly >> 8) & 0xFF), (uint8_t)(poly & 0xFF)
     641           0 :   };
     642           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_GFSK_CRC_PARAMS, true, buff, sizeof(buff)));
     643             :   
     644             : }
     645             : 
     646           0 : int16_t LR11x0::setGfskWhitParams(uint16_t seed) {
     647             :   uint8_t buff[2] = {
     648           0 :     (uint8_t)((seed >> 8) & 0xFF), (uint8_t)(seed & 0xFF)
     649           0 :   };
     650           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_GFSK_WHIT_PARAMS, true, buff, sizeof(buff)));
     651             : }
     652             : 
     653           0 : int16_t LR11x0::setRangingParameter(uint8_t symbolNum) {
     654             :   // the first byte is reserved
     655           0 :   uint8_t buff[2] = { 0x00, symbolNum };
     656           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_RANGING_PARAMETER, true, buff, sizeof(buff)));
     657             : }
     658             : 
     659           0 : int16_t LR11x0::setRssiCalibration(const int8_t* tune, int16_t gainOffset) {
     660             :   uint8_t buff[11] = {
     661           0 :     (uint8_t)((tune[0] & 0x0F) | (uint8_t)(tune[1] & 0x0F) << 4),
     662           0 :     (uint8_t)((tune[2] & 0x0F) | (uint8_t)(tune[3] & 0x0F) << 4),
     663           0 :     (uint8_t)((tune[4] & 0x0F) | (uint8_t)(tune[5] & 0x0F) << 4),
     664           0 :     (uint8_t)((tune[6] & 0x0F) | (uint8_t)(tune[7] & 0x0F) << 4),
     665           0 :     (uint8_t)((tune[8] & 0x0F) | (uint8_t)(tune[9] & 0x0F) << 4),
     666           0 :     (uint8_t)((tune[10] & 0x0F) | (uint8_t)(tune[11] & 0x0F) << 4),
     667           0 :     (uint8_t)((tune[12] & 0x0F) | (uint8_t)(tune[13] & 0x0F) << 4),
     668           0 :     (uint8_t)((tune[14] & 0x0F) | (uint8_t)(tune[15] & 0x0F) << 4),
     669           0 :     (uint8_t)((tune[16] & 0x0F) | (uint8_t)(tune[17] & 0x0F) << 4),
     670           0 :     (uint8_t)(((uint16_t)gainOffset >> 8) & 0xFF), (uint8_t)(gainOffset & 0xFF),
     671           0 :   };
     672           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_RSSI_CALIBRATION, true, buff, sizeof(buff)));
     673             : }
     674             : 
     675           0 : int16_t LR11x0::setLoRaSyncWord(uint8_t sync) {
     676           0 :   uint8_t buff[1] = { sync };
     677           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_SET_LORA_SYNC_WORD, true, buff, sizeof(buff)));
     678             : }
     679             : 
     680           0 : int16_t LR11x0::lrFhssBuildFrame(uint8_t hdrCount, uint8_t cr, uint8_t grid, bool hop, uint8_t bw, uint16_t hopSeq, int8_t devOffset, const uint8_t* payload, size_t len) {
     681             :   // check maximum size
     682           0 :   const uint8_t maxLen[4][4] = {
     683             :     { 189, 178, 167, 155, },
     684             :     { 151, 142, 133, 123, },
     685             :     { 112, 105,  99,  92, },
     686             :     {  74,  69,  65,  60, },
     687             :   };
     688           0 :   if((cr > RADIOLIB_LR11X0_LR_FHSS_CR_1_3) || ((hdrCount - 1) > (int)sizeof(maxLen[0])) || (len > maxLen[cr][hdrCount - 1])) {
     689           0 :     return(RADIOLIB_ERR_SPI_CMD_INVALID);
     690             :   }
     691             : 
     692             :   // build buffers
     693           0 :   size_t buffLen = 9 + len;
     694             :   #if RADIOLIB_STATIC_ONLY
     695             :     uint8_t dataBuff[9 + 190];
     696             :   #else
     697           0 :     uint8_t* dataBuff = new uint8_t[buffLen];
     698             :   #endif
     699             : 
     700             :   // set properties of the packet
     701           0 :   dataBuff[0] = hdrCount;
     702           0 :   dataBuff[1] = cr;
     703           0 :   dataBuff[2] = RADIOLIB_LR11X0_LR_FHSS_MOD_TYPE_GMSK;
     704           0 :   dataBuff[3] = grid;
     705           0 :   dataBuff[4] = (uint8_t)hop;
     706           0 :   dataBuff[5] = bw;
     707           0 :   dataBuff[6] = (uint8_t)((hopSeq >> 8) & 0x01);
     708           0 :   dataBuff[7] = (uint8_t)(hopSeq & 0xFF);
     709           0 :   dataBuff[8] = devOffset;
     710           0 :   memcpy(&dataBuff[9], payload, len);
     711             : 
     712           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_LR_FHSS_BUILD_FRAME, true, dataBuff, buffLen);
     713             :   #if !RADIOLIB_STATIC_ONLY
     714           0 :     delete[] dataBuff;
     715             :   #endif
     716           0 :   return(state);
     717             : }
     718             : 
     719           0 : int16_t LR11x0::lrFhssSetSyncWord(uint32_t sync) {
     720             :   uint8_t buff[4] = {
     721           0 :     (uint8_t)((sync >> 24) & 0xFF), (uint8_t)((sync >> 16) & 0xFF),
     722           0 :     (uint8_t)((sync >> 8) & 0xFF), (uint8_t)(sync & 0xFF)
     723           0 :   };
     724           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_LR_FHSS_SET_SYNC_WORD, true, buff, sizeof(buff)));
     725             : }
     726             : 
     727           0 : int16_t LR11x0::configBleBeacon(uint8_t chan, const uint8_t* payload, size_t len) {
     728           0 :   return(this->bleBeaconCommon(RADIOLIB_LR11X0_CMD_CONFIG_BLE_BEACON, chan, payload, len));
     729             : }
     730             : 
     731           0 : int16_t LR11x0::getLoRaRxHeaderInfo(uint8_t* cr, bool* hasCRC) {
     732             :   // check if in explicit header mode
     733           0 :   if(this->headerType == RADIOLIB_LR11X0_LORA_HEADER_IMPLICIT) {
     734           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
     735             :   }
     736             : 
     737           0 :   uint8_t buff[1] = { 0 };
     738           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR11X0_CMD_GET_LORA_RX_HEADER_INFOS, false, buff, sizeof(buff));
     739             : 
     740             :   // pass the replies
     741           0 :   if(cr) { *cr = (buff[0] & 0x70) >> 4; }
     742           0 :   if(hasCRC) { *hasCRC = (buff[0] & RADIOLIB_LR11X0_LAST_HEADER_CRC_ENABLED) != 0; }
     743             : 
     744           0 :   return(state);
     745             : }
     746             : 
     747           0 : int16_t LR11x0::bleBeaconSend(uint8_t chan, const uint8_t* payload, size_t len) {
     748           0 :   return(this->bleBeaconCommon(RADIOLIB_LR11X0_CMD_BLE_BEACON_SEND, chan, payload, len));
     749             : }
     750             : 
     751           0 : int16_t LR11x0::bleBeaconCommon(uint16_t cmd, uint8_t chan, const uint8_t* payload, size_t len) {
     752             :   // check maximum size
     753             :   // TODO what is the actual maximum?
     754           0 :   if(len > RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN) {
     755           0 :     return(RADIOLIB_ERR_SPI_CMD_INVALID);
     756             :   }
     757             : 
     758             :   // build buffers
     759             :   #if RADIOLIB_STATIC_ONLY
     760             :     uint8_t dataBuff[sizeof(uint8_t) + RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
     761             :   #else
     762           0 :     uint8_t* dataBuff = new uint8_t[sizeof(uint8_t) + len];
     763             :   #endif
     764             : 
     765             :   // set the channel
     766           0 :   dataBuff[0] = chan;
     767           0 :   memcpy(&dataBuff[1], payload, len);
     768             : 
     769           0 :   int16_t state = this->SPIcommand(cmd, true, dataBuff, sizeof(uint8_t) + len);
     770             :   #if !RADIOLIB_STATIC_ONLY
     771           0 :     delete[] dataBuff;
     772             :   #endif
     773           0 :   return(state);
     774             : }
     775             : 
     776           0 : int16_t LR11x0::bootEraseFlash(void) {
     777             :   // erasing flash takes about 2.5 seconds, temporarily tset SPI timeout to 3 seconds
     778           0 :   RadioLibTime_t timeout = this->mod->spiConfig.timeout;
     779           0 :   this->mod->spiConfig.timeout = 3000;
     780           0 :   int16_t state = this->mod->SPIwriteStream(RADIOLIB_LR11X0_CMD_BOOT_ERASE_FLASH, NULL, 0, false, false);
     781           0 :   this->mod->spiConfig.timeout = timeout;
     782           0 :   return(state);
     783             : }
     784             : 
     785           0 : int16_t LR11x0::bootWriteFlashEncrypted(uint32_t offset, const uint32_t* data, size_t len, bool nonvolatile) {
     786             :   // check maximum size
     787           0 :   if(len > (RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
     788           0 :     return(RADIOLIB_ERR_SPI_CMD_INVALID);
     789             :   }
     790           0 :   return(this->writeCommon(RADIOLIB_LR11X0_CMD_BOOT_WRITE_FLASH_ENCRYPTED, offset, data, len, nonvolatile));
     791             : }
     792             : 
     793           0 : int16_t LR11x0::bootGetHash(uint8_t hash[RADIOLIB_LR11X0_HASH_LEN]) {
     794           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_BOOT_GET_HASH, false, hash, RADIOLIB_LR11X0_HASH_LEN));
     795             : }
     796             : 
     797           0 : int16_t LR11x0::bootReboot(bool stay) {
     798           0 :   uint8_t buff[1] = { (uint8_t)stay };
     799           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_BOOT_REBOOT, true, buff, sizeof(buff)));
     800             : }
     801             : 
     802           0 : int16_t LR11x0::bootGetPin(uint8_t* pin) {
     803           0 :   RADIOLIB_ASSERT_PTR(pin);
     804           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_BOOT_GET_PIN, false, pin, RADIOLIB_LR11X0_PIN_LEN));
     805             : }
     806             : 
     807           0 : int16_t LR11x0::bootGetChipEui(uint8_t* eui) {
     808           0 :   RADIOLIB_ASSERT_PTR(eui);
     809           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_BOOT_GET_CHIP_EUI, false, eui, RADIOLIB_LR11X0_EUI_LEN));
     810             : }
     811             : 
     812           0 : int16_t LR11x0::bootGetJoinEui(uint8_t* eui) {
     813           0 :   RADIOLIB_ASSERT_PTR(eui);
     814           0 :   return(this->SPIcommand(RADIOLIB_LR11X0_CMD_BOOT_GET_JOIN_EUI, false, eui, RADIOLIB_LR11X0_EUI_LEN));
     815             : }
     816             : 
     817           0 : int16_t LR11x0::writeCommon(uint16_t cmd, uint32_t addrOffset, const uint32_t* data, size_t len, bool nonvolatile) {
     818             :   // build buffers - later we need to ensure endians are correct, 
     819             :   // so there is probably no way to do this without copying buffers and iterating
     820           0 :   size_t buffLen = sizeof(uint32_t) + len*sizeof(uint32_t);
     821             :   #if RADIOLIB_STATIC_ONLY
     822             :     uint8_t dataBuff[sizeof(uint32_t) + RADIOLIB_LR11X0_SPI_MAX_READ_WRITE_LEN];
     823             :   #else
     824           0 :     uint8_t* dataBuff = new uint8_t[buffLen];
     825             :   #endif
     826             : 
     827             :   // set the address or offset
     828           0 :   dataBuff[0] = (uint8_t)((addrOffset >> 24) & 0xFF);
     829           0 :   dataBuff[1] = (uint8_t)((addrOffset >> 16) & 0xFF);
     830           0 :   dataBuff[2] = (uint8_t)((addrOffset >> 8) & 0xFF);
     831           0 :   dataBuff[3] = (uint8_t)(addrOffset & 0xFF);
     832             : 
     833             :   // convert endians
     834           0 :   for(size_t i = 0; i < len; i++) {
     835           0 :     uint32_t bin = 0;
     836           0 :     if(nonvolatile) {
     837           0 :       uint32_t* ptr = const_cast<uint32_t*>(data) + i;
     838           0 :       bin = RADIOLIB_NONVOLATILE_READ_DWORD(ptr);
     839             :     } else {
     840           0 :       bin = data[i];
     841             :     }
     842           0 :     dataBuff[4 + i*sizeof(uint32_t)] = (uint8_t)((bin >> 24) & 0xFF);
     843           0 :     dataBuff[5 + i*sizeof(uint32_t)] = (uint8_t)((bin >> 16) & 0xFF);
     844           0 :     dataBuff[6 + i*sizeof(uint32_t)] = (uint8_t)((bin >> 8) & 0xFF);
     845           0 :     dataBuff[7 + i*sizeof(uint32_t)] = (uint8_t)(bin & 0xFF);
     846             :   }
     847             : 
     848           0 :   int16_t state = this->mod->SPIwriteStream(cmd, dataBuff, buffLen, true, false);
     849             :   #if !RADIOLIB_STATIC_ONLY
     850           0 :     delete[] dataBuff;
     851             :   #endif
     852           0 :   return(state);
     853             : }
     854             : 
     855             : #endif

Generated by: LCOV version 1.14