LCOV - code coverage report
Current view: top level - src/modules/LR2021 - LR2021_cmds_chip_control.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 21 179 11.7 %
Date: 2026-02-22 10:42:45 Functions: 5 42 11.9 %

          Line data    Source code
       1             : #include "LR2021.h"
       2             : 
       3             : #include "../LR11x0/LR_common.h"
       4             : 
       5             : #include <string.h>
       6             : #include <math.h>
       7             : 
       8             : #if !RADIOLIB_EXCLUDE_LR2021
       9             : 
      10           0 : int16_t LR2021::readRadioRxFifo(uint8_t* data, size_t len) {
      11             :   // FIFO read is just a single transaction sent without the status code
      12           0 :   this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_0;
      13           0 :   int16_t state = this->mod->SPIreadStream(RADIOLIB_LR2021_CMD_READ_RX_FIFO, data, len, true, false);
      14           0 :   this->mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] = Module::BITS_16;
      15           0 :   return(state);
      16             : }
      17             : 
      18           0 : int16_t LR2021::writeRadioTxFifo(const uint8_t* data, size_t len) {
      19           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_WRITE_TX_FIFO, true, const_cast<uint8_t*>(data), len, NULL, 0));
      20             : }
      21             : 
      22           0 : int16_t LR2021::writeRegMem32(uint32_t addr, const uint32_t* data, size_t len) {
      23             :   // check maximum size
      24           0 :   if(len > (RADIOLIB_LRXXXX_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
      25           0 :     return(RADIOLIB_ERR_SPI_CMD_INVALID);
      26             :   }
      27           0 :   return(this->writeCommon(RADIOLIB_LR2021_CMD_WRITE_REG_MEM_32, addr, data, len, false));
      28             : }
      29             : 
      30           0 : int16_t LR2021::writeRegMemMask32(uint32_t addr, uint32_t mask, uint32_t data) {
      31             :   uint8_t buff[11] = {
      32           0 :     (uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF),
      33           0 :     (uint8_t)((mask >> 24) & 0xFF), (uint8_t)((mask >> 16) & 0xFF), (uint8_t)((mask >> 8) & 0xFF), (uint8_t)(mask & 0xFF),
      34           0 :     (uint8_t)((data >> 24) & 0xFF), (uint8_t)((data >> 16) & 0xFF), (uint8_t)((data >> 8) & 0xFF), (uint8_t)(data & 0xFF),
      35           0 :   };
      36           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_WRITE_REG_MEM_MASK_32, true, buff, sizeof(buff)));
      37             : }
      38             : 
      39           0 : int16_t LR2021::readRegMem32(uint32_t addr, uint32_t* data, size_t len) {
      40             :   // check maximum size
      41           0 :   if(len > (RADIOLIB_LRXXXX_SPI_MAX_READ_WRITE_LEN/sizeof(uint32_t))) {
      42           0 :     return(RADIOLIB_ERR_SPI_CMD_INVALID);
      43             :   }
      44             : 
      45             :   // the request contains the address and length
      46             :   uint8_t reqBuff[4] = {
      47           0 :     (uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 8) & 0xFF),
      48             :     (uint8_t)(addr & 0xFF), (uint8_t)len,
      49           0 :   };
      50             : 
      51             :   // build buffers - later we need to ensure endians are correct, 
      52             :   // so there is probably no way to do this without copying buffers and iterating
      53             :   #if RADIOLIB_STATIC_ONLY
      54             :     uint8_t rplBuff[RADIOLIB_LRXXXX_SPI_MAX_READ_WRITE_LEN];
      55             :   #else
      56           0 :     uint8_t* rplBuff = new uint8_t[len*sizeof(uint32_t)];
      57             :   #endif
      58             : 
      59           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_READ_REG_MEM_32, false, rplBuff, len*sizeof(uint32_t), reqBuff, sizeof(reqBuff));
      60             : 
      61             :   // convert endians
      62           0 :   if(data && (state == RADIOLIB_ERR_NONE)) {
      63           0 :     for(size_t i = 0; i < len; i++) {
      64           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)];
      65             :     }
      66             :   }
      67             : 
      68             :   #if !RADIOLIB_STATIC_ONLY
      69           0 :     delete[] rplBuff;
      70             :   #endif
      71             :   
      72           0 :   return(state);
      73             : }
      74             : 
      75           0 : int16_t LR2021::setFs(void) {
      76           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_FS, true, NULL, 0));
      77             : }
      78             : 
      79           0 : int16_t LR2021::setAdditionalRegToRetain(uint8_t slot, uint32_t addr) {
      80             :   uint8_t buff[] = { 
      81           0 :     slot, (uint8_t)((addr >> 16) & 0xFF),
      82           0 :     (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF),
      83           0 :   };
      84             : 
      85           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_ADDITIONAL_REG_TO_RETAIN, true, buff, sizeof(buff)));
      86             : }
      87             : 
      88           1 : int16_t LR2021::setRx(uint32_t timeout) {
      89             :   uint8_t buff[] = {
      90           1 :     (uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF),
      91           1 :   };
      92           2 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_RX, true, buff, sizeof(buff)));
      93             : }
      94             : 
      95           0 : int16_t LR2021::setTx(uint32_t timeout) {
      96             :   uint8_t buff[] = {
      97           0 :     (uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF),
      98           0 :   };
      99           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_TX, true, buff, sizeof(buff)));
     100             : }
     101             : 
     102           0 : int16_t LR2021::setRxTxFallbackMode(uint8_t mode) {
     103           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_RX_TX_FALLBACK_MODE, true, &mode, sizeof(mode)));
     104             : }
     105             : 
     106           0 : int16_t LR2021::setRxDutyCycle(uint32_t rxMaxTime, uint32_t cycleTime, uint8_t cfg) {
     107             :   uint8_t buff[] = {
     108           0 :     (uint8_t)((rxMaxTime >> 16) & 0xFF), (uint8_t)((rxMaxTime >> 8) & 0xFF), (uint8_t)(rxMaxTime & 0xFF),
     109           0 :     (uint8_t)((cycleTime >> 16) & 0xFF), (uint8_t)((cycleTime >> 8) & 0xFF), (uint8_t)(cycleTime & 0xFF),
     110             :     cfg
     111           0 :   };
     112           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_RX_DUTY_CYCLE, true, buff, sizeof(buff)));
     113             : }
     114             : 
     115           0 : int16_t LR2021::autoTxRx(uint32_t delay, uint8_t mode, uint32_t timeout) {
     116             :   uint8_t buff[] = {
     117           0 :     (uint8_t)((delay >> 16) & 0xFF), (uint8_t)((delay >> 8) & 0xFF), (uint8_t)(delay & 0xFF), mode,
     118           0 :     (uint8_t)((timeout >> 16) & 0xFF), (uint8_t)((timeout >> 8) & 0xFF), (uint8_t)(timeout & 0xFF),
     119           0 :   };
     120           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_AUTO_RX_TX, true, buff, sizeof(buff)));
     121             : }
     122             : 
     123           1 : int16_t LR2021::getRxPktLength(uint16_t* len) {
     124           1 :   uint8_t buff[2] = { 0 };
     125           1 :   int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_RX_PKT_LENGTH, false, buff, sizeof(buff));
     126           1 :   if(len) { *len = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1]; }
     127           1 :   return(state);
     128             : }
     129             : 
     130           0 : int16_t LR2021::resetRxStats(void) {
     131           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_RESET_RX_STATS, true, NULL, 0));
     132             : }
     133             : 
     134           0 : int16_t LR2021::setDefaultRxTxTimeout(uint32_t rxTimeout, uint32_t txTimeout) {
     135             :   uint8_t buff[] = {
     136           0 :     (uint8_t)((rxTimeout >> 16) & 0xFF), (uint8_t)((rxTimeout >> 8) & 0xFF), (uint8_t)(rxTimeout & 0xFF),
     137           0 :     (uint8_t)((txTimeout >> 16) & 0xFF), (uint8_t)((txTimeout >> 8) & 0xFF), (uint8_t)(txTimeout & 0xFF),
     138           0 :   };
     139           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_DEFAULT_RX_TX_TIMEOUT, true, buff, sizeof(buff)));
     140             : }
     141             : 
     142           0 : int16_t LR2021::setRegMode(uint8_t simoUsage, const uint8_t rampTimes[4]) {
     143             :   uint8_t buff[] = { simoUsage, 
     144           0 :     rampTimes[RADIOLIB_LR2021_REG_MODE_RAMP_INDEX_RC2RU], rampTimes[RADIOLIB_LR2021_REG_MODE_RAMP_INDEX_TX2RU], 
     145           0 :     rampTimes[RADIOLIB_LR2021_REG_MODE_RAMP_INDEX_RU2RC], rampTimes[RADIOLIB_LR2021_REG_MODE_RAMP_INDEX_RAMP_DOWN],
     146           0 :   };
     147           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_REG_MODE, true, buff, sizeof(buff)));
     148             : }
     149             : 
     150           0 : int16_t LR2021::calibrate(uint8_t blocks) {
     151           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_CALIBRATE, true, &blocks, sizeof(blocks)));
     152             : }
     153             : 
     154           0 : int16_t LR2021::calibrateFrontEnd(const uint16_t freq[3]) {
     155             :   uint8_t buff[] = {
     156           0 :     (uint8_t)((freq[0] >> 8) & 0xFF), (uint8_t)(freq[0] & 0xFF),
     157           0 :     (uint8_t)((freq[1] >> 8) & 0xFF), (uint8_t)(freq[1] & 0xFF),
     158           0 :     (uint8_t)((freq[2] >> 8) & 0xFF), (uint8_t)(freq[2] & 0xFF),
     159           0 :   };
     160           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_CALIB_FRONT_END, true, buff, sizeof(buff)));
     161             : }
     162             : 
     163           0 : int16_t LR2021::getVbat(uint8_t resolution, uint16_t* vbat) {
     164           0 :   uint8_t reqBuff[] = { (uint8_t)(RADIOLIB_LR2021_VBAT_FORMAT_MV | ((RADIOLIB_LR2021_MEAS_RESOLUTION_OFFSET + resolution) & 0x07)) };
     165           0 :   uint8_t rplBuff[2] = { 0 };
     166           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_V_BAT, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff));
     167           0 :   if(vbat) { *vbat = ((uint16_t)(rplBuff[0]) << 8) | (uint16_t)rplBuff[1]; }
     168           0 :   return(state);
     169             : }
     170             : 
     171           0 : int16_t LR2021::getTemp(uint8_t source, uint8_t resolution, float* temp) {
     172           0 :   uint8_t reqBuff[] = { (uint8_t)((source & 0x30) | RADIOLIB_LR2021_TEMP_FORMAT_DEG_C | ((RADIOLIB_LR2021_MEAS_RESOLUTION_OFFSET + resolution) & 0x07)) };
     173           0 :   uint8_t rplBuff[2] = { 0 };
     174           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_TEMP, false, rplBuff, sizeof(rplBuff), reqBuff, sizeof(reqBuff));
     175           0 :   if(temp) { 
     176           0 :     uint16_t raw = ((uint16_t)(rplBuff[0]) << 8) | (uint16_t)rplBuff[1];
     177           0 :     *temp = (float)raw/320.0f;
     178             :   }
     179           0 :   return(state);
     180             : }
     181             : 
     182           0 : int16_t LR2021::setEolConfig(bool enable, uint8_t trim) {
     183           0 :   uint8_t buff[] = { (uint8_t)((trim & 0x06) | (uint8_t)enable) };
     184           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_EOL_CONFIG, true, buff, sizeof(buff)));
     185             : }
     186             : 
     187           1 : int16_t LR2021::getRandomNumber(uint32_t* rnd) {
     188           1 :   uint8_t buff[4] = { 0 };
     189           1 :   int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_RANDOM_NUMBER, false, buff, sizeof(buff));
     190           1 :   if(rnd) { *rnd = ((uint32_t)(buff[0]) << 24) | ((uint32_t)(buff[1]) << 16) | ((uint32_t)(buff[2]) << 8) | (uint32_t)buff[3];  }
     191           1 :   return(state);
     192             : }
     193             : 
     194           0 : int16_t LR2021::getVersion(uint8_t* major, uint8_t* minor) {
     195           0 :   uint8_t buff[2] = { 0 };
     196           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_VERSION, false, buff, sizeof(buff));
     197           0 :   if(major)   { *major = buff[0]; }
     198           0 :   if(minor)   { *minor = buff[1]; }
     199           0 :   return(state);
     200             : }
     201             : 
     202           0 : int16_t LR2021::clearErrors(void) {
     203           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_CLEAR_ERRORS, true, NULL, 0));
     204             : }
     205             : 
     206           0 : int16_t LR2021::getErrors(uint16_t* err) {
     207           0 :   uint8_t buff[2] = { 0 };
     208           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_ERRORS, false, buff, sizeof(buff));
     209           0 :   if(err) { *err = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1];  }
     210           0 :   return(state);
     211             : }
     212             : 
     213           0 : int16_t LR2021::setDioFunction(uint8_t dio, uint8_t func, uint8_t pullDrive) {
     214           0 :   uint8_t buff[] = { dio, (uint8_t)((func & 0xF0) | (pullDrive & 0x0F)) };
     215           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_DIO_FUNCTION, true, buff, sizeof(buff)));
     216             : }
     217             : 
     218           0 : int16_t LR2021::setDioRfSwitchConfig(uint8_t dio, uint8_t func) {
     219           0 :   uint8_t buff[] = { dio, func };
     220           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_DIO_RF_SWITCH_CONFIG, true, buff, sizeof(buff)));
     221             : }
     222             : 
     223           1 : int16_t LR2021::setDioIrqConfig(uint8_t dio, uint32_t irq) {
     224             :   uint8_t buff[] = { dio, 
     225           1 :     (uint8_t)((irq >> 24) & 0xFF), (uint8_t)((irq >> 16) & 0xFF),
     226           1 :     (uint8_t)((irq >> 8) & 0xFF), (uint8_t)(irq & 0xFF),
     227           1 :   };
     228           2 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_DIO_IRQ_CONFIG, true, buff, sizeof(buff)));
     229             : }
     230             : 
     231           2 : int16_t LR2021::clearIrqState(uint32_t irq) {
     232           2 :   return(this->setU32(RADIOLIB_LR2021_CMD_CLEAR_IRQ, irq));
     233             : }
     234             : 
     235           0 : int16_t LR2021::getAndClearIrqStatus(uint32_t* irq) {
     236           0 :   uint8_t buff[4] = { 0 };
     237           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_AND_CLEAR_IRQ_STATUS, false, buff, sizeof(buff));
     238           0 :   if(irq) { *irq = ((uint32_t)(buff[0]) << 24) | ((uint32_t)(buff[1]) << 16) | ((uint32_t)(buff[2]) << 8) |(uint32_t)buff[3]; }
     239           0 :   return(state);
     240             : }
     241             : 
     242           0 : int16_t LR2021::configFifoIrq(uint8_t rxFifoIrq, uint8_t txFifoIrq, uint8_t rxHighThreshold, uint8_t txHighThreshold) {
     243           0 :   uint8_t buff[] = { rxFifoIrq, txFifoIrq, rxHighThreshold, txHighThreshold };
     244           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_CONFIG_FIFO_IRQ, true, buff, sizeof(buff)));
     245             : }
     246             : 
     247           0 : int16_t LR2021::getFifoIrqFlags(uint8_t* rxFifoFlags, uint8_t* txFifoFlags) {
     248           0 :   uint8_t buff[2] = { 0 };
     249           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_FIFO_IRQ_FLAGS, false, buff, sizeof(buff));
     250           0 :   if(rxFifoFlags) { *rxFifoFlags = buff[0]; }
     251           0 :   if(txFifoFlags) { *txFifoFlags = buff[1]; }
     252           0 :   return(state);
     253             : }
     254             : 
     255           0 : int16_t LR2021::clearFifoIrqFlags(uint8_t rxFifoFlags, uint8_t txFifoFlags) {
     256           0 :   uint8_t buff[] = { rxFifoFlags, txFifoFlags };
     257           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_CLEAR_FIFO_IRQ_FLAGS, true, buff, sizeof(buff)));
     258             : }
     259             : 
     260           0 : int16_t LR2021::getAndClearFifoIrqFlags(uint8_t* rxFifoFlags, uint8_t* txFifoFlags) {
     261           0 :   uint8_t buff[2] = { 0 };
     262           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_AND_CLEAR_FIFO_IRQ_FLAGS, false, buff, sizeof(buff));
     263           0 :   if(rxFifoFlags) { *rxFifoFlags = buff[0]; }
     264           0 :   if(txFifoFlags) { *txFifoFlags = buff[1]; }
     265           0 :   return(state);
     266             : }
     267             : 
     268           0 : int16_t LR2021::getRxFifoLevel(uint16_t* level) {
     269           0 :   uint8_t buff[2] = { 0 };
     270           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_RX_FIFO_LEVEL, false, buff, sizeof(buff));
     271           0 :   if(level) { *level = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1];  }
     272           0 :   return(state);
     273             : }
     274             : 
     275           0 : int16_t LR2021::getTxFifoLevel(uint16_t* level) {
     276           0 :   uint8_t buff[2] = { 0 };
     277           0 :   int16_t state = this->SPIcommand(RADIOLIB_LR2021_CMD_GET_TX_FIFO_LEVEL, false, buff, sizeof(buff));
     278           0 :   if(level) { *level = ((uint16_t)(buff[0]) << 8) | (uint16_t)buff[1];  }
     279           0 :   return(state);
     280             : }
     281             : 
     282           0 : int16_t LR2021::clearRxFifo(void) {
     283           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_CLEAR_RX_FIFO, true, NULL, 0));
     284             : }
     285             : 
     286           0 : int16_t LR2021::clearTxFifo(void) {
     287           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_CLEAR_TX_FIFO, true, NULL, 0));
     288             : }
     289             : 
     290           0 : int16_t LR2021::configLfClock(uint8_t cfg) {
     291           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_CONFIG_LF_CLOCK, true, &cfg, sizeof(cfg)));
     292             : }
     293             : 
     294           0 : int16_t LR2021::configClkOutputs(uint8_t scaling) {
     295           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_CONFIG_CLK_OUTPUTS, true, &scaling, sizeof(scaling)));
     296             : }
     297             : 
     298           0 : int16_t LR2021::setTcxoMode(uint8_t tune, uint32_t startTime) {
     299           0 :   uint8_t buff[] = { (uint8_t)(tune & 0x07),
     300           0 :     (uint8_t)((startTime >> 24) & 0xFF), (uint8_t)((startTime >> 16) & 0xFF),
     301           0 :     (uint8_t)((startTime >> 8) & 0xFF), (uint8_t)(startTime & 0xFF),
     302           0 :   };
     303           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_TCXO_MODE, true, buff, sizeof(buff)));
     304             : }
     305             : 
     306           0 : int16_t LR2021::setXoscCpTrim(uint8_t xta, uint8_t xtb, uint8_t startTime) {
     307           0 :   uint8_t buff[] = { (uint8_t)(xta & 0x3F), (uint8_t)(xtb & 0x3F), startTime };
     308           0 :   return(this->SPIcommand(RADIOLIB_LR2021_CMD_SET_XOSC_CP_TRIM, true, buff, sizeof(buff)));
     309             : }
     310             : 
     311             : #endif

Generated by: LCOV version 1.14