LCOV - code coverage report
Current view: top level - src/modules/SX128x - SX1280.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 3 112 2.7 %
Date: 2026-02-22 10:42:45 Functions: 1 7 14.3 %

          Line data    Source code
       1             : #include "SX1280.h"
       2             : #include <string.h>
       3             : #if !RADIOLIB_EXCLUDE_SX128X
       4             : 
       5           2 : SX1280::SX1280(Module* mod) : SX1281(mod) {
       6           2 :   chipType = RADIOLIB_SX1280_CHIP_TYPE;
       7           2 : }
       8             : 
       9           0 : int16_t SX1280::range(bool master, uint32_t addr, uint16_t calTable[3][6]) {
      10             :   // start ranging
      11           0 :   int16_t state = startRanging(master, addr, calTable);
      12           0 :   RADIOLIB_ASSERT(state);
      13             : 
      14             :   // wait until ranging is finished
      15           0 :   Module* mod = this->getMod();
      16           0 :   RadioLibTime_t start = mod->hal->millis();
      17           0 :   while(!mod->hal->digitalRead(mod->getIrq())) {
      18           0 :     mod->hal->yield();
      19           0 :     if(mod->hal->millis() - start > 10000) {
      20           0 :       (void)finishRanging();
      21           0 :       return(RADIOLIB_ERR_RANGING_TIMEOUT);
      22             :     }
      23             :   }
      24             : 
      25           0 :   return(finishRanging());
      26             : }
      27             : 
      28           0 : int16_t SX1280::startRanging(bool master, uint32_t addr, const uint16_t calTable[3][6]) {
      29             :   // check active modem
      30           0 :   uint8_t modem = getPacketType();
      31           0 :   if(!((modem == RADIOLIB_SX128X_PACKET_TYPE_LORA) || (modem == RADIOLIB_SX128X_PACKET_TYPE_RANGING))) {
      32           0 :     return(RADIOLIB_ERR_WRONG_MODEM);
      33             :   }
      34             : 
      35             :   // set mode to standby
      36           0 :   int16_t state = standby();
      37           0 :   RADIOLIB_ASSERT(state);
      38             : 
      39             :   // ensure modem is set to ranging
      40           0 :   if(modem == RADIOLIB_SX128X_PACKET_TYPE_LORA) {
      41           0 :     state = setPacketType(RADIOLIB_SX128X_PACKET_TYPE_RANGING);
      42           0 :     RADIOLIB_ASSERT(state);
      43             :   }
      44             : 
      45             :   // set modulation parameters
      46           0 :   state = setModulationParams(this->spreadingFactor, this->bandwidth, this->codingRateLoRa);
      47           0 :   RADIOLIB_ASSERT(state);
      48             : 
      49             :   // set packet parameters
      50           0 :   state = setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, this->payloadLen, this->crcLoRa);
      51           0 :   RADIOLIB_ASSERT(state);
      52             : 
      53             :   // check all address bits
      54           0 :   if(!master) {
      55             :     uint8_t regValue;
      56           0 :     state = readRegister(RADIOLIB_SX128X_REG_SLAVE_RANGING_ADDRESS_WIDTH, &regValue, 1);
      57           0 :     RADIOLIB_ASSERT(state);
      58           0 :     regValue &= 0b00111111;
      59           0 :     regValue |= 0b11000000;
      60           0 :     state = writeRegister(RADIOLIB_SX128X_REG_SLAVE_RANGING_ADDRESS_WIDTH, &regValue, 1);
      61           0 :     RADIOLIB_ASSERT(state);
      62             :   }
      63             : 
      64             :   // set remaining parameter values
      65           0 :   uint32_t addrReg = RADIOLIB_SX128X_REG_SLAVE_RANGING_ADDRESS_BYTE_3;
      66           0 :   uint32_t irqMask = RADIOLIB_SX128X_IRQ_RANGING_SLAVE_RESP_DONE | RADIOLIB_SX128X_IRQ_RANGING_SLAVE_REQ_DISCARD;
      67           0 :   uint32_t irqDio1 = RADIOLIB_SX128X_IRQ_RANGING_SLAVE_RESP_DONE;
      68           0 :   if(master) {
      69           0 :     addrReg = RADIOLIB_SX128X_REG_MASTER_RANGING_ADDRESS_BYTE_3;
      70           0 :     irqMask = RADIOLIB_SX128X_IRQ_RANGING_MASTER_RES_VALID | RADIOLIB_SX128X_IRQ_RANGING_MASTER_TIMEOUT;
      71           0 :     irqDio1 = RADIOLIB_SX128X_IRQ_RANGING_MASTER_RES_VALID;
      72             :   }
      73             : 
      74             :   // set ranging address
      75           0 :   const uint8_t addrBuff[] = { (uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF) };
      76           0 :   state = writeRegister(addrReg, addrBuff, 4);
      77           0 :   RADIOLIB_ASSERT(state);
      78             : 
      79             :   // set DIO mapping
      80           0 :   state = setDioIrqParams(irqMask, irqDio1);
      81           0 :   RADIOLIB_ASSERT(state);
      82             : 
      83             :   // this is the default calibration from AN1200.29
      84           0 :   uint16_t calTbl[3][6] = {
      85             :     { 10299, 10271, 10244, 10242, 10230, 10246 },
      86             :     { 11486, 11474, 11453, 11426, 11417, 11401 },
      87             :     { 13308, 13493, 13528, 13515, 13430, 13376 }
      88             :   };
      89             : 
      90             :   // check if user provided some custom calibration
      91           0 :   if(calTable != NULL) {
      92           0 :     memcpy(calTbl, calTable, sizeof(calTbl));
      93             :   }
      94             : 
      95             :   // set calibration values
      96           0 :   uint8_t index = (this->spreadingFactor >> 4) - 5;
      97           0 :   uint16_t val = 0;
      98           0 :   switch(this->bandwidth) {
      99           0 :     case(RADIOLIB_SX128X_LORA_BW_406_25):
     100           0 :       val = calTbl[0][index];
     101           0 :       break;
     102           0 :     case(RADIOLIB_SX128X_LORA_BW_812_50):
     103           0 :       val = calTbl[1][index];
     104           0 :       break;
     105           0 :     case(RADIOLIB_SX128X_LORA_BW_1625_00):
     106           0 :       val = calTbl[2][index];
     107           0 :       break;
     108           0 :     default:
     109           0 :       return(RADIOLIB_ERR_INVALID_BANDWIDTH);
     110             :   }
     111           0 :   const uint8_t calBuff[] = { (uint8_t)((val >> 8) & 0xFF), (uint8_t)(val & 0xFF) };
     112           0 :   state = writeRegister(RADIOLIB_SX128X_REG_RANGING_CALIBRATION_MSB, calBuff, 2);
     113           0 :   RADIOLIB_ASSERT(state);
     114             : 
     115             :   // set role and start ranging
     116           0 :   if(master) {
     117           0 :     state = setRangingRole(RADIOLIB_SX128X_RANGING_ROLE_MASTER);
     118           0 :     RADIOLIB_ASSERT(state);
     119             : 
     120           0 :     state = setTx(RADIOLIB_SX128X_TX_TIMEOUT_NONE);
     121           0 :     RADIOLIB_ASSERT(state);
     122             : 
     123             :   } else {
     124           0 :     state = setRangingRole(RADIOLIB_SX128X_RANGING_ROLE_SLAVE);
     125           0 :     RADIOLIB_ASSERT(state);
     126             : 
     127           0 :     state = setRx(RADIOLIB_SX128X_RX_TIMEOUT_INF);
     128           0 :     RADIOLIB_ASSERT(state);
     129             : 
     130             :   }
     131             : 
     132           0 :   return(state);
     133             : }
     134             : 
     135           0 : int16_t SX1280::finishRanging() {
     136             :   // start by clearing interrupt flags
     137           0 :   int16_t state = clearIrqStatus();
     138           0 :   RADIOLIB_ASSERT(state);
     139             : 
     140             :   // set mode to standby
     141           0 :   state = standby();
     142           0 :   RADIOLIB_ASSERT(state);
     143             : 
     144             :   // restore back to LoRa communication
     145             :   // config sets up the bare minimum
     146           0 :   state = config(RADIOLIB_SX128X_PACKET_TYPE_LORA);
     147           0 :   RADIOLIB_ASSERT(state);
     148             : 
     149             :   // restore modulation and packet parameters and we're done
     150           0 :   state = setModulationParams(this->spreadingFactor, this->bandwidth, this->codingRateLoRa);
     151           0 :   RADIOLIB_ASSERT(state);
     152           0 :   return(setPacketParamsLoRa(this->preambleLengthLoRa, this->headerType, this->payloadLen, this->crcLoRa));
     153             : }
     154             : 
     155           0 : int32_t SX1280::getRangingResultRaw() {
     156           0 :   return(getRangingResultCommon(false));
     157             : }
     158             : 
     159           0 : float SX1280::getRangingResult() {
     160           0 :   int32_t raw = getRangingResultCommon(false);
     161           0 :   return((float)raw * 150.0f / (4.096f * this->bandwidthKhz));
     162             : }
     163             : 
     164           0 : int32_t SX1280::getRangingResultCommon(bool filtered) {
     165             :   // set mode to standby XOSC
     166           0 :   int16_t state = standby(RADIOLIB_SX128X_STANDBY_XOSC);
     167           0 :   RADIOLIB_ASSERT(state);
     168             : 
     169             :   // enable clock
     170           0 :   uint8_t data[3] = { 0 };
     171           0 :   state = readRegister(RADIOLIB_SX128X_REG_RANGING_LORA_CLOCK_ENABLE, data, 1);
     172           0 :   RADIOLIB_ASSERT(state);
     173             : 
     174           0 :   data[0] |= (1 << 1);
     175           0 :   state = writeRegister(RADIOLIB_SX128X_REG_RANGING_LORA_CLOCK_ENABLE, data, 1);
     176           0 :   RADIOLIB_ASSERT(state);
     177             : 
     178             :   // set result type filtered/raw
     179             :   // TODO: at the moment, filtered values do not work and just return huge numbers
     180             :   // the datasheet also isn't exactly clear on how to use the filtering
     181             :   // (when to reset, when are samples added etc.)
     182           0 :   state = readRegister(RADIOLIB_SX128X_REG_RANGING_TYPE, data, 1);
     183           0 :   RADIOLIB_ASSERT(state);
     184             : 
     185           0 :   data[0] &= 0xCF;
     186           0 :   data[0] |= ((uint8_t)filtered << 4);
     187           0 :   state = writeRegister(RADIOLIB_SX128X_REG_RANGING_TYPE, data, 1);
     188           0 :   RADIOLIB_ASSERT(state);
     189             : 
     190             :   // read the register values
     191           0 :   state = readRegister(RADIOLIB_SX128X_REG_RANGING_RESULT_MSB, data, 3);
     192           0 :   RADIOLIB_ASSERT(state);
     193             : 
     194             :   // set mode to standby RC
     195           0 :   state = standby();
     196           0 :   RADIOLIB_ASSERT(state);
     197             : 
     198             :   // shifting everything by 8 bits more to the left will convert the result to signed number
     199           0 :   int32_t raw = ((((int32_t)data[0]) << 24) | (((int32_t)data[1]) << 16) | (((int32_t)data[2]) << 8)) >> 8;
     200           0 :   return(raw);
     201             : }
     202             : 
     203             : #endif

Generated by: LCOV version 1.14