diff --git a/coverage/amber.png b/coverage/amber.png new file mode 100644 index 00000000..2cab170d Binary files /dev/null and b/coverage/amber.png differ diff --git a/coverage/emerald.png b/coverage/emerald.png new file mode 100644 index 00000000..38ad4f40 Binary files /dev/null and b/coverage/emerald.png differ diff --git a/coverage/extras/test/unit/include/HardwareEmulation.hpp.func-sort-c.html b/coverage/extras/test/unit/include/HardwareEmulation.hpp.func-sort-c.html new file mode 100644 index 00000000..8f44ded9 --- /dev/null +++ b/coverage/extras/test/unit/include/HardwareEmulation.hpp.func-sort-c.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/include/HardwareEmulation.hpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/include - HardwareEmulation.hpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:1414100.0 %
Date:2025-03-23 20:50:28Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN13EmulatedRadio7connectEP13EmulatedPin_tS1_S1_S1_4
_ZN13EmulatedRadio10HandleGPIOEv2932
_ZN13EmulatedRadio9HandleSPIEh4192
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/include/HardwareEmulation.hpp.func.html b/coverage/extras/test/unit/include/HardwareEmulation.hpp.func.html new file mode 100644 index 00000000..be41d11a --- /dev/null +++ b/coverage/extras/test/unit/include/HardwareEmulation.hpp.func.html @@ -0,0 +1,84 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/include/HardwareEmulation.hpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/include - HardwareEmulation.hpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:1414100.0 %
Date:2025-03-23 20:50:28Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN13EmulatedRadio10HandleGPIOEv2932
_ZN13EmulatedRadio7connectEP13EmulatedPin_tS1_S1_S1_4
_ZN13EmulatedRadio9HandleSPIEh4192
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/include/HardwareEmulation.hpp.gcov.html b/coverage/extras/test/unit/include/HardwareEmulation.hpp.gcov.html new file mode 100644 index 00000000..0ad46f9b --- /dev/null +++ b/coverage/extras/test/unit/include/HardwareEmulation.hpp.gcov.html @@ -0,0 +1,147 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/include/HardwareEmulation.hpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/include - HardwareEmulation.hpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:1414100.0 %
Date:2025-03-23 20:50:28Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : #ifndef HARDWARE_EMULATION_HPP
+       2             : #define HARDWARE_EMULATION_HPP
+       3             : 
+       4             : #include <stdint.h>
+       5             : 
+       6             : // value that is returned by the emualted radio class when performing SPI transfer to it
+       7             : #define EMULATED_RADIO_SPI_RETURN (0xFF)
+       8             : 
+       9             : // pin indexes
+      10             : #define EMULATED_RADIO_NSS_PIN    (1)
+      11             : #define EMULATED_RADIO_IRQ_PIN    (2)
+      12             : #define EMULATED_RADIO_RST_PIN    (3)
+      13             : #define EMULATED_RADIO_GPIO_PIN   (4)
+      14             : 
+      15             : enum PinFunction_t {
+      16             :   PIN_UNASSIGNED = 0,
+      17             :   PIN_CS,
+      18             :   PIN_IRQ,
+      19             :   PIN_RST,
+      20             :   PIN_GPIO,
+      21             : };
+      22             : 
+      23             : // structure for emulating GPIO pins
+      24             : struct EmulatedPin_t {
+      25             :   uint32_t mode;
+      26             :   uint32_t value;
+      27             :   bool event;
+      28             :   PinFunction_t func; 
+      29             : };
+      30             : 
+      31             : // structure for emulating SPI registers
+      32             : struct EmulatedRegister_t {
+      33             :   uint8_t value;
+      34             :   uint8_t readOnlyBitFlags;
+      35             :   bool bufferAccess;
+      36             : };
+      37             : 
+      38             : // base class for emulated radio modules (SX126x etc.)
+      39             : class EmulatedRadio {
+      40             :   public:
+      41           4 :     void connect(EmulatedPin_t* csPin, EmulatedPin_t* irqPin, EmulatedPin_t* rstPin, EmulatedPin_t* gpioPin) {
+      42           4 :       this->cs = csPin;
+      43           4 :       this->cs->func = PIN_CS;
+      44           4 :       this->irq = irqPin;
+      45           4 :       this->irq->func = PIN_IRQ;
+      46           4 :       this->rst = rstPin;
+      47           4 :       this->rst->func = PIN_RST;
+      48           4 :       this->gpio = gpioPin;
+      49           4 :       this->gpio->func = PIN_GPIO;
+      50           4 :     }
+      51             : 
+      52        4192 :     virtual uint8_t HandleSPI(uint8_t b) {
+      53             :       (void)b;
+      54             :       // handle the SPI input and generate output here
+      55        4192 :       return(EMULATED_RADIO_SPI_RETURN);
+      56             :     }
+      57             : 
+      58        2932 :     virtual void HandleGPIO() {
+      59             :       // handle discrete GPIO signals here (e.g. reset state machine on NSS falling edge)
+      60        2932 :     }
+      61             :   
+      62             :   protected:
+      63             :     // pointers to emulated GPIO pins
+      64             :     // this is done via pointers so that the same GPIO entity is shared, like with a real hardware
+      65             :     EmulatedPin_t* cs;
+      66             :     EmulatedPin_t* irq;
+      67             :     EmulatedPin_t* rst;
+      68             :     EmulatedPin_t* gpio;
+      69             : };
+      70             : 
+      71             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/include/TestHal.hpp.func-sort-c.html b/coverage/extras/test/unit/include/TestHal.hpp.func-sort-c.html new file mode 100644 index 00000000..94239ee4 --- /dev/null +++ b/coverage/extras/test/unit/include/TestHal.hpp.func-sort-c.html @@ -0,0 +1,168 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/include/TestHal.hpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/include - TestHal.hpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:699175.8 %
Date:2025-03-23 20:50:28Functions:152462.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN7TestHal15attachInterruptEjPFvvEj0
_ZN7TestHal15detachInterruptEj0
_ZN7TestHal4toneEjjm0
_ZN7TestHal5delayEm0
_ZN7TestHal5yieldEv0
_ZN7TestHal6noToneEj0
_ZN7TestHal6spiEndEv0
_ZN7TestHal7pulseInEjjm0
_ZN7TestHal8spiBeginEv0
_ZN7TestHal12connectRadioEP13EmulatedRadio4
_ZN7TestHal4initEv4
_ZN7TestHal4termEv4
_ZN7TestHal7pinModeEjj4
_ZN7TestHalC2Ev4
_ZN7TestHal12spiLogMemcmpEPKvm12
_ZN7TestHal10spiLogWipeEv16
_ZN7TestHal11digitalReadEj846
_ZN7TestHal6millisEv846
_ZN7TestHal6microsEv1462
_ZN7TestHal11spiTransferEPhmS0_1464
_ZN7TestHal17spiEndTransactionEv1464
_ZN7TestHal19spiBeginTransactionEv1464
_ZN7TestHal12digitalWriteEjj2932
_ZN7TestHal17delayMicrosecondsEm4615
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/include/TestHal.hpp.func.html b/coverage/extras/test/unit/include/TestHal.hpp.func.html new file mode 100644 index 00000000..3b04c674 --- /dev/null +++ b/coverage/extras/test/unit/include/TestHal.hpp.func.html @@ -0,0 +1,168 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/include/TestHal.hpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/include - TestHal.hpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:699175.8 %
Date:2025-03-23 20:50:28Functions:152462.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN7TestHal10spiLogWipeEv16
_ZN7TestHal11digitalReadEj846
_ZN7TestHal11spiTransferEPhmS0_1464
_ZN7TestHal12connectRadioEP13EmulatedRadio4
_ZN7TestHal12digitalWriteEjj2932
_ZN7TestHal12spiLogMemcmpEPKvm12
_ZN7TestHal15attachInterruptEjPFvvEj0
_ZN7TestHal15detachInterruptEj0
_ZN7TestHal17delayMicrosecondsEm4615
_ZN7TestHal17spiEndTransactionEv1464
_ZN7TestHal19spiBeginTransactionEv1464
_ZN7TestHal4initEv4
_ZN7TestHal4termEv4
_ZN7TestHal4toneEjjm0
_ZN7TestHal5delayEm0
_ZN7TestHal5yieldEv0
_ZN7TestHal6microsEv1462
_ZN7TestHal6millisEv846
_ZN7TestHal6noToneEj0
_ZN7TestHal6spiEndEv0
_ZN7TestHal7pinModeEjj4
_ZN7TestHal7pulseInEjjm0
_ZN7TestHal8spiBeginEv0
_ZN7TestHalC2Ev4
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/include/TestHal.hpp.gcov.html b/coverage/extras/test/unit/include/TestHal.hpp.gcov.html new file mode 100644 index 00000000..632fe2ca --- /dev/null +++ b/coverage/extras/test/unit/include/TestHal.hpp.gcov.html @@ -0,0 +1,345 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/include/TestHal.hpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/include - TestHal.hpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:699175.8 %
Date:2025-03-23 20:50:28Functions:152462.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : #ifndef TEST_HAL_HPP
+       2             : #define TEST_HAL_HPP
+       3             : 
+       4             : #include <chrono>
+       5             : #include <thread>
+       6             : #include <fmt/format.h>
+       7             : 
+       8             : #include <RadioLib.h>
+       9             : 
+      10             : #include <boost/log/trivial.hpp>
+      11             : #include <boost/format.hpp>
+      12             : 
+      13             : #if defined(TEST_HAL_LOG)
+      14             : #define HAL_LOG(...) BOOST_TEST_MESSAGE(__VA_ARGS__)
+      15             : #else
+      16             : #define HAL_LOG(...) {}
+      17             : #endif
+      18             : 
+      19             : #include "HardwareEmulation.hpp"
+      20             : 
+      21             : #define TEST_HAL_INPUT          (0)
+      22             : #define TEST_HAL_OUTPUT         (1)
+      23             : #define TEST_HAL_LOW            (0)
+      24             : #define TEST_HAL_HIGH           (1)
+      25             : #define TEST_HAL_RISING         (0)
+      26             : #define TEST_HAL_FALLING        (1)
+      27             : 
+      28             : // number of emulated GPIO pins
+      29             : #define TEST_HAL_NUM_GPIO_PINS  (32)
+      30             : 
+      31             : #define TEST_HAL_SPI_LOG_LENGTH (512)
+      32             : 
+      33             : class TestHal : public RadioLibHal {
+      34             :   public:
+      35           4 :     TestHal() : RadioLibHal(TEST_HAL_INPUT, TEST_HAL_OUTPUT, TEST_HAL_LOW, TEST_HAL_HIGH, TEST_HAL_RISING, TEST_HAL_FALLING) { }
+      36             : 
+      37           4 :     void init() override {
+      38             :       HAL_LOG("TestHal::init()");
+      39             : 
+      40             :       // save program start timestamp
+      41           4 :       start = std::chrono::high_resolution_clock::now();
+      42             : 
+      43             :       // init emulated GPIO
+      44         132 :       for(int i = 0; i < TEST_HAL_NUM_GPIO_PINS; i++) {
+      45         128 :         this->gpio[i].mode = 0;
+      46         128 :         this->gpio[i].value = 0;
+      47         128 :         this->gpio[i].event = false;
+      48         128 :         this->gpio[i].func = PIN_UNASSIGNED;
+      49             :       }
+      50             : 
+      51             :       // wipe history log
+      52           4 :       this->spiLogWipe();
+      53           4 :     }
+      54             : 
+      55           4 :     void term() override {
+      56             :       HAL_LOG("TestHal::term()");
+      57           4 :     }
+      58             : 
+      59           4 :     void pinMode(uint32_t pin, uint32_t mode) override {
+      60             :       HAL_LOG("TestHal::pinMode(pin=" << pin << ", mode=" << mode << " [" << ((mode == TEST_HAL_INPUT) ? "INPUT" : "OUTPUT") << "])");
+      61             :       
+      62             :       // check the range
+      63           4 :       BOOST_ASSERT_MSG(pin < TEST_HAL_NUM_GPIO_PINS, "Pin number out of range");
+      64             : 
+      65             :       // check known modes
+      66           4 :       BOOST_ASSERT_MSG(((mode == TEST_HAL_INPUT) || (mode == TEST_HAL_OUTPUT)), "Invalid pin mode");
+      67             : 
+      68             :       // set mode
+      69           4 :       this->gpio[pin].mode = mode;
+      70           4 :     }
+      71             : 
+      72        2932 :     void digitalWrite(uint32_t pin, uint32_t value) override {
+      73             :       HAL_LOG("TestHal::digitalWrite(pin=" << pin << ", value=" << value << " [" << ((value == TEST_HAL_LOW) ? "LOW" : "HIGH") << "])");
+      74             : 
+      75             :       // check the range
+      76        2932 :       BOOST_ASSERT_MSG(pin < TEST_HAL_NUM_GPIO_PINS, "Pin number out of range");
+      77             : 
+      78             :       // check it is output
+      79        2932 :       BOOST_ASSERT_MSG(this->gpio[pin].mode == TEST_HAL_OUTPUT, "GPIO is not output!");
+      80             : 
+      81             :       // check known values
+      82        2932 :       BOOST_ASSERT_MSG(((value == TEST_HAL_LOW) || (value == TEST_HAL_HIGH)), "Invalid output value");
+      83             : 
+      84             :       // set value
+      85        2932 :       this->gpio[pin].value = value;
+      86        2932 :       this->gpio[pin].event = true;
+      87        2932 :       if(radio) {
+      88        2932 :         this->radio->HandleGPIO();
+      89             :       }
+      90        2932 :       this->gpio[pin].event = false;
+      91        2932 :     }
+      92             : 
+      93         846 :     uint32_t digitalRead(uint32_t pin) override {
+      94             :       HAL_LOG("TestHal::digitalRead(pin=" << pin << ")");
+      95             : 
+      96             :       // check the range
+      97         846 :       BOOST_ASSERT_MSG(pin < TEST_HAL_NUM_GPIO_PINS, "Pin number out of range");
+      98             : 
+      99             :       // check it is input
+     100         846 :       BOOST_ASSERT_MSG(this->gpio[pin].mode == TEST_HAL_INPUT, "GPIO is not input");
+     101             : 
+     102             :       // read the value
+     103         846 :       uint32_t value = this->gpio[pin].value;
+     104             :       HAL_LOG("TestHal::digitalRead(pin=" << pin << ")=" << value << " [" << ((value == TEST_HAL_LOW) ? "LOW" : "HIGH") << "]");
+     105         846 :       return(value);
+     106             :     }
+     107             : 
+     108           0 :     void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override {
+     109             :       HAL_LOG("TestHal::attachInterrupt(interruptNum=" << interruptNum << ", interruptCb=" << interruptCb << ", mode=" << mode << ")");
+     110             : 
+     111             :       // TODO implement
+     112             :       (void)interruptNum;
+     113             :       (void)interruptCb;
+     114             :       (void)mode;
+     115           0 :     }
+     116             : 
+     117           0 :     void detachInterrupt(uint32_t interruptNum) override {
+     118             :       HAL_LOG("TestHal::detachInterrupt(interruptNum=" << interruptNum << ")");
+     119             : 
+     120             :       // TODO implement
+     121             :       (void)interruptNum;
+     122           0 :     }
+     123             : 
+     124           0 :     void delay(unsigned long ms) override {
+     125             :       HAL_LOG("TestHal::delay(ms=" << ms << ")");
+     126           0 :       const auto start = std::chrono::high_resolution_clock::now();
+     127             : 
+     128             :       // sleep_for is sufficient for ms-precision sleep
+     129           0 :       std::this_thread::sleep_for(std::chrono::duration<unsigned long, std::milli>(ms));
+     130             : 
+     131             :       // measure and print
+     132           0 :       const auto end = std::chrono::high_resolution_clock::now();
+     133           0 :       const std::chrono::duration<double, std::milli> elapsed = end - start;
+     134             :       HAL_LOG("TestHal::delay(ms=" << ms << ")=" << elapsed.count() << "ms");
+     135           0 :     }
+     136             : 
+     137        4615 :     void delayMicroseconds(unsigned long us) override {
+     138             :       HAL_LOG("TestHal::delayMicroseconds(us=" << us << ")");
+     139        4615 :       const auto start = std::chrono::high_resolution_clock::now();
+     140             : 
+     141             :       // busy wait is needed for microseconds precision
+     142        4615 :       const auto len = std::chrono::microseconds(us);
+     143     6568288 :       while(std::chrono::high_resolution_clock::now() - start < len);
+     144             : 
+     145             :       // measure and print
+     146        4615 :       const auto end = std::chrono::high_resolution_clock::now();
+     147        4615 :       const std::chrono::duration<double, std::micro> elapsed = end - start;
+     148             :       HAL_LOG("TestHal::delayMicroseconds(us=" << us << ")=" << elapsed.count() << "us");
+     149        4615 :     }
+     150             : 
+     151           0 :     void yield() override {
+     152             :       HAL_LOG("TestHal::yield()");
+     153           0 :     }
+     154             : 
+     155         846 :     unsigned long millis() override {
+     156             :       HAL_LOG("TestHal::millis()");
+     157         846 :       std::chrono::time_point now = std::chrono::high_resolution_clock::now();
+     158         846 :       auto res = std::chrono::duration_cast<std::chrono::milliseconds>(now - this->start);
+     159             :       HAL_LOG("TestHal::millis()=" << res.count());
+     160         846 :       return(res.count());
+     161             :     }
+     162             : 
+     163        1462 :     unsigned long micros() override {
+     164             :       HAL_LOG("TestHal::micros()");
+     165        1462 :       std::chrono::time_point now = std::chrono::high_resolution_clock::now();
+     166        1462 :       auto res = std::chrono::duration_cast<std::chrono::microseconds>(now - this->start);
+     167             :       HAL_LOG("TestHal::micros()=" << res.count());
+     168        1462 :       return(res.count());
+     169             :     }
+     170             : 
+     171           0 :     long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override {
+     172             :       HAL_LOG("TestHal::pulseIn(pin=" << pin << ", state=" << state << ", timeout=" << timeout << ")");
+     173             : 
+     174             :       // TODO implement
+     175             :       (void)pin;
+     176             :       (void)state;
+     177             :       (void)timeout;
+     178           0 :       return(0);
+     179             :     }
+     180             : 
+     181           0 :     void spiBegin() {
+     182             :       HAL_LOG("TestHal::spiBegin()");
+     183           0 :     }
+     184             : 
+     185        1464 :     void spiBeginTransaction() {
+     186             :       HAL_LOG("TestHal::spiBeginTransaction()");
+     187        1464 :     }
+     188             : 
+     189        1464 :     void spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
+     190             :       HAL_LOG("TestHal::spiTransfer(len=" << len << ")");
+     191             :       
+     192        5656 :       for(size_t i = 0; i < len; i++) {
+     193             :         // append to log
+     194        4192 :         (*this->spiLogPtr++) = out[i];
+     195             : 
+     196             :         // process the SPI byte
+     197        4192 :         in[i] = this->radio->HandleSPI(out[i]);
+     198             : 
+     199             :         // artificial delay to emulate SPI running at a finite speed
+     200             :         // this is added because timeouts are based on time duration,
+     201             :         // so we need to make sure some time actually elapses
+     202        4192 :         this->delayMicroseconds(100);
+     203             : 
+     204             :         // output debug
+     205             :         HAL_LOG(fmt::format("out={:#02x}, in={:#02x}", out[i], in[i]));
+     206             :       }
+     207        1464 :     }
+     208             : 
+     209        1464 :     void spiEndTransaction() {
+     210             :       HAL_LOG("TestHal::spiEndTransaction()");
+     211        1464 :     }
+     212             : 
+     213           0 :     void spiEnd() {
+     214             :       HAL_LOG("TestHal::spiEnd()");
+     215           0 :     }
+     216             : 
+     217           0 :     void tone(uint32_t pin, unsigned int frequency, unsigned long duration = 0) {
+     218             :       HAL_LOG("TestHal::tone(pin=" << pin << ", frequency=" << frequency << ", duration=" << duration << ")");
+     219             : 
+     220             :       // TODO implement
+     221             :       (void)pin;
+     222             :       (void)frequency;
+     223             :       (void)duration;
+     224           0 :     }
+     225             : 
+     226           0 :     void noTone(uint32_t pin) {
+     227             :       HAL_LOG("TestHal::noTone(pin=" << pin << ")");
+     228             : 
+     229             :       // TODO implement
+     230             :       (void)pin;
+     231           0 :     }
+     232             : 
+     233             :     // method to compare buffer to the internal SPI log, for verifying SPI transactions
+     234          12 :     int spiLogMemcmp(const void* in, size_t n) {
+     235          12 :       int ret = memcmp(this->spiLog, in, n);
+     236          12 :       this->spiLogWipe();
+     237          12 :       return(ret);
+     238             :     }
+     239             : 
+     240          16 :     void spiLogWipe() {
+     241          16 :       memset(this->spiLog, 0x00, TEST_HAL_SPI_LOG_LENGTH);
+     242          16 :       this->spiLogPtr = this->spiLog;
+     243          16 :     }
+     244             : 
+     245             :     // method that "connects" the emualted radio hardware to this HAL
+     246           4 :     void connectRadio(EmulatedRadio* r) {
+     247           4 :       this->radio = r;
+     248           4 :       this->radio->connect(&this->gpio[EMULATED_RADIO_NSS_PIN],
+     249             :                            &this->gpio[EMULATED_RADIO_IRQ_PIN],
+     250             :                            &this->gpio[EMULATED_RADIO_RST_PIN],
+     251             :                            &this->gpio[EMULATED_RADIO_GPIO_PIN]);
+     252           4 :     }
+     253             : 
+     254             :   private:
+     255             :     // array of emulated GPIO pins
+     256             :     EmulatedPin_t gpio[TEST_HAL_NUM_GPIO_PINS];
+     257             : 
+     258             :     // start time point
+     259             :     std::chrono::time_point<std::chrono::high_resolution_clock> start;
+     260             : 
+     261             :     // emulated radio hardware
+     262             :     EmulatedRadio* radio;
+     263             : 
+     264             :     // SPI history log
+     265             :     uint8_t spiLog[TEST_HAL_SPI_LOG_LENGTH];
+     266             :     uint8_t* spiLogPtr;
+     267             : };
+     268             : 
+     269             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/include/index-sort-f.html b/coverage/extras/test/unit/include/index-sort-f.html new file mode 100644 index 00000000..8484d7a8 --- /dev/null +++ b/coverage/extras/test/unit/include/index-sort-f.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/include + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/includeHitTotalCoverage
Test:lcov.infoLines:8310579.0 %
Date:2025-03-23 20:50:28Functions:182766.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
TestHal.hpp +
75.8%75.8%
+
75.8 %69 / 9162.5 %15 / 24
HardwareEmulation.hpp +
100.0%
+
100.0 %14 / 14100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/include/index-sort-l.html b/coverage/extras/test/unit/include/index-sort-l.html new file mode 100644 index 00000000..c376d321 --- /dev/null +++ b/coverage/extras/test/unit/include/index-sort-l.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/include + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/includeHitTotalCoverage
Test:lcov.infoLines:8310579.0 %
Date:2025-03-23 20:50:28Functions:182766.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
TestHal.hpp +
75.8%75.8%
+
75.8 %69 / 9162.5 %15 / 24
HardwareEmulation.hpp +
100.0%
+
100.0 %14 / 14100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/include/index.html b/coverage/extras/test/unit/include/index.html new file mode 100644 index 00000000..cfb10228 --- /dev/null +++ b/coverage/extras/test/unit/include/index.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/include + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/includeHitTotalCoverage
Test:lcov.infoLines:8310579.0 %
Date:2025-03-23 20:50:28Functions:182766.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
HardwareEmulation.hpp +
100.0%
+
100.0 %14 / 14100.0 %3 / 3
TestHal.hpp +
75.8%75.8%
+
75.8 %69 / 9162.5 %15 / 24
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/tests/TestModule.cpp.func-sort-c.html b/coverage/extras/test/unit/tests/TestModule.cpp.func-sort-c.html new file mode 100644 index 00000000..2d95fa85 --- /dev/null +++ b/coverage/extras/test/unit/tests/TestModule.cpp.func-sort-c.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/tests/TestModule.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/tests - TestModule.cpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:142142100.0 %
Date:2025-03-23 20:50:28Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN12suite_Module25Module_SPIgetRegValue_reg11test_methodEv1
_ZN12suite_Module25Module_SPIsetRegValue_reg11test_methodEv1
_ZN12suite_Module28Module_SPIgetRegValue_stream11test_methodEv1
_ZN12suite_Module28Module_SPIsetRegValue_stream11test_methodEv1
_ZN12suite_ModuleL33Module_SPIgetRegValue_reg_invokerEv1
_ZN12suite_ModuleL33Module_SPIsetRegValue_reg_invokerEv1
_ZN12suite_ModuleL36Module_SPIgetRegValue_stream_invokerEv1
_ZN12suite_ModuleL36Module_SPIsetRegValue_stream_invokerEv1
_ZN13ModuleFixtureC2Ev4
_ZN13ModuleFixtureD2Ev4
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/tests/TestModule.cpp.func.html b/coverage/extras/test/unit/tests/TestModule.cpp.func.html new file mode 100644 index 00000000..afd0d599 --- /dev/null +++ b/coverage/extras/test/unit/tests/TestModule.cpp.func.html @@ -0,0 +1,112 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/tests/TestModule.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/tests - TestModule.cpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:142142100.0 %
Date:2025-03-23 20:50:28Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN12suite_Module25Module_SPIgetRegValue_reg11test_methodEv1
_ZN12suite_Module25Module_SPIsetRegValue_reg11test_methodEv1
_ZN12suite_Module28Module_SPIgetRegValue_stream11test_methodEv1
_ZN12suite_Module28Module_SPIsetRegValue_stream11test_methodEv1
_ZN12suite_ModuleL33Module_SPIgetRegValue_reg_invokerEv1
_ZN12suite_ModuleL33Module_SPIsetRegValue_reg_invokerEv1
_ZN12suite_ModuleL36Module_SPIgetRegValue_stream_invokerEv1
_ZN12suite_ModuleL36Module_SPIsetRegValue_stream_invokerEv1
_ZN13ModuleFixtureC2Ev4
_ZN13ModuleFixtureD2Ev4
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/tests/TestModule.cpp.gcov.html b/coverage/extras/test/unit/tests/TestModule.cpp.gcov.html new file mode 100644 index 00000000..545c0cca --- /dev/null +++ b/coverage/extras/test/unit/tests/TestModule.cpp.gcov.html @@ -0,0 +1,305 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/tests/TestModule.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/tests - TestModule.cpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:142142100.0 %
Date:2025-03-23 20:50:28Functions:1010100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : // boost test header
+       2             : #include <boost/test/unit_test.hpp>
+       3             : 
+       4             : // mock HAL
+       5             : #include "TestHal.hpp"
+       6             : 
+       7             : // testing fixture
+       8             : struct ModuleFixture {
+       9             :   TestHal* hal = nullptr;
+      10             :   Module* mod = nullptr;
+      11             :   EmulatedRadio* radioHardware = nullptr;
+      12             : 
+      13           4 :   ModuleFixture()  { 
+      14           4 :     BOOST_TEST_MESSAGE("--- Module fixture setup ---"); 
+      15           4 :     hal = new TestHal();
+      16           4 :     radioHardware = new EmulatedRadio();
+      17           4 :     hal->connectRadio(radioHardware);
+      18             : 
+      19           4 :     mod = new Module(hal, EMULATED_RADIO_NSS_PIN, EMULATED_RADIO_IRQ_PIN, EMULATED_RADIO_RST_PIN, EMULATED_RADIO_GPIO_PIN);
+      20           4 :     mod->init();
+      21           4 :   }
+      22             : 
+      23           4 :   ~ModuleFixture() { 
+      24           4 :     BOOST_TEST_MESSAGE("--- Module fixture teardown ---");
+      25           4 :     mod->term();
+      26           4 :     delete[] mod;
+      27           4 :     delete[] hal;
+      28           4 :   }
+      29             : };
+      30             : 
+      31             : BOOST_FIXTURE_TEST_SUITE(suite_Module, ModuleFixture)
+      32             : 
+      33           2 :   BOOST_FIXTURE_TEST_CASE(Module_SPIgetRegValue_reg, ModuleFixture)
+      34             :   {
+      35           1 :     BOOST_TEST_MESSAGE("--- Test Module::SPIgetRegValue register access ---");
+      36             :     int16_t ret;
+      37             : 
+      38             :     // basic register read with default config
+      39           1 :     const uint8_t address = 0x12;
+      40           1 :     const uint8_t spiTxn[] = { address, 0x00 };
+      41           1 :     ret = mod->SPIgetRegValue(address);
+      42             : 
+      43             :     // check return code, value and history log
+      44           1 :     BOOST_TEST(ret >= RADIOLIB_ERR_NONE);
+      45           1 :     BOOST_TEST(ret == EMULATED_RADIO_SPI_RETURN);
+      46           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
+      47             : 
+      48             :     // register read masking test
+      49           1 :     const uint8_t msb = 5;
+      50           1 :     const uint8_t lsb = 1;
+      51           1 :     const uint8_t maskedValue = 0x3E;
+      52           1 :     ret = mod->SPIgetRegValue(address, msb, lsb);
+      53           1 :     BOOST_TEST(ret == maskedValue);
+      54             : 
+      55             :     // invalid mask tests (swapped MSB and LSB, out of range bit masks)
+      56           1 :     ret = mod->SPIgetRegValue(address, lsb, msb);
+      57           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
+      58           1 :     ret = mod->SPIgetRegValue(address, 10, lsb);
+      59           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
+      60           1 :     ret = mod->SPIgetRegValue(address, msb, 10);
+      61           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
+      62           1 :   }
+      63             : 
+      64           2 :   BOOST_FIXTURE_TEST_CASE(Module_SPIsetRegValue_reg, ModuleFixture)
+      65             :   {
+      66           1 :     BOOST_TEST_MESSAGE("--- Test Module::SPIsetRegValue register access ---");
+      67             :     int16_t ret;
+      68             : 
+      69             :     // basic register write with default config
+      70           1 :     const uint8_t address = 0x12;
+      71           1 :     const uint8_t value = 0xAB;
+      72           1 :     const uint8_t spiTxn[] = { address, 0x00, 0x80 | address, value };
+      73           1 :     ret = mod->SPIsetRegValue(address, value);
+      74             : 
+      75             :     // check return code and history log
+      76             :     // this will return write error because the bare emulated radio has no internal logic
+      77           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
+      78           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
+      79             : 
+      80             :     // register write masking test
+      81           1 :     const uint8_t msb = 5;
+      82           1 :     const uint8_t lsb = 1;
+      83           1 :     const uint8_t maskedValue = 0xEB;
+      84           1 :     const uint8_t spiTxn2[] = { address, 0x00, 0x80 | address, maskedValue };
+      85           1 :     ret = mod->SPIsetRegValue(address, value, msb, lsb);
+      86           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
+      87           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn2, sizeof(spiTxn2)) == 0);
+      88             : 
+      89             :     // invalid mask tests (swapped MSB and LSB, out of range bit masks)
+      90           1 :     ret = mod->SPIsetRegValue(address, value, lsb, msb);
+      91           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
+      92           1 :     ret = mod->SPIsetRegValue(address, value, 10, lsb);
+      93           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
+      94           1 :     ret = mod->SPIsetRegValue(address, value, msb, 10);
+      95           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
+      96             : 
+      97             :     // check interval test
+      98           1 :     const uint8_t interval = 200;
+      99           1 :     const unsigned long start = hal->micros();
+     100           1 :     ret = mod->SPIsetRegValue(address, value, 7, 0, interval);
+     101           1 :     const unsigned long stop = hal->micros();
+     102           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
+     103           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
+     104           1 :     const unsigned long elapsed = stop - start;
+     105           1 :     BOOST_TEST(elapsed >= (unsigned long)interval*1000UL);
+     106             : 
+     107             :     // disabled check mask test
+     108           1 :     ret = mod->SPIsetRegValue(address, value, 7, 0, 2, 0);
+     109           1 :     BOOST_TEST(ret == RADIOLIB_ERR_NONE);
+     110           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
+     111             : 
+     112             :     // forced write test
+     113           1 :     ret = mod->SPIsetRegValue(address, value, 7, 0, 2, 0xFF, true);
+     114           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
+     115           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
+     116           1 :   }
+     117             : 
+     118           2 :   BOOST_FIXTURE_TEST_CASE(Module_SPIgetRegValue_stream, ModuleFixture)
+     119             :   {
+     120           1 :     BOOST_TEST_MESSAGE("--- Test Module::SPIgetRegValue stream access ---");
+     121             :     int16_t ret;
+     122             : 
+     123             :     // change settings to stream type
+     124           1 :     mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR] = Module::BITS_16;
+     125           1 :     mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_8;
+     126           1 :     mod->spiConfig.statusPos = 1;
+     127           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] = RADIOLIB_SX126X_CMD_READ_REGISTER;
+     128           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] = RADIOLIB_SX126X_CMD_WRITE_REGISTER;
+     129           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_NOP] = RADIOLIB_SX126X_CMD_NOP;
+     130           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_STATUS] = RADIOLIB_SX126X_CMD_GET_STATUS;
+     131           1 :     mod->spiConfig.stream = true;
+     132             : 
+     133             :     // basic register read
+     134           1 :     const uint8_t address = 0x12;
+     135           1 :     const uint8_t spiTxn[] = { RADIOLIB_SX126X_CMD_READ_REGISTER, 0x00, address, 0x00, 0x00 };
+     136           1 :     ret = mod->SPIgetRegValue(address);
+     137             : 
+     138             :     // check return code, value and history log
+     139           1 :     BOOST_TEST(ret >= RADIOLIB_ERR_NONE);
+     140           1 :     BOOST_TEST(ret == EMULATED_RADIO_SPI_RETURN);
+     141           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
+     142             : 
+     143             :     // register read masking test
+     144           1 :     const uint8_t msb = 5;
+     145           1 :     const uint8_t lsb = 1;
+     146           1 :     const uint8_t maskedValue = 0x3E;
+     147           1 :     ret = mod->SPIgetRegValue(address, msb, lsb);
+     148           1 :     BOOST_TEST(ret == maskedValue);
+     149             : 
+     150             :     // invalid mask tests (swapped MSB and LSB, out of range bit masks)
+     151           1 :     ret = mod->SPIgetRegValue(address, lsb, msb);
+     152           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
+     153           1 :     ret = mod->SPIgetRegValue(address, 10, lsb);
+     154           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
+     155           1 :     ret = mod->SPIgetRegValue(address, msb, 10);
+     156           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
+     157           1 :   }
+     158             : 
+     159           2 :   BOOST_FIXTURE_TEST_CASE(Module_SPIsetRegValue_stream, ModuleFixture)
+     160             :   {
+     161           1 :     BOOST_TEST_MESSAGE("--- Test Module::SPIsetRegValue stream access ---");
+     162             :     int16_t ret;
+     163             : 
+     164             :     // change settings to stream type
+     165           1 :     mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR] = Module::BITS_16;
+     166           1 :     mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_8;
+     167           1 :     mod->spiConfig.statusPos = 1;
+     168           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] = RADIOLIB_SX126X_CMD_READ_REGISTER;
+     169           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] = RADIOLIB_SX126X_CMD_WRITE_REGISTER;
+     170           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_NOP] = RADIOLIB_SX126X_CMD_NOP;
+     171           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_STATUS] = RADIOLIB_SX126X_CMD_GET_STATUS;
+     172           1 :     mod->spiConfig.stream = true;
+     173             : 
+     174             :     // basic register write with default config
+     175           1 :     const uint8_t address = 0x12;
+     176           1 :     const uint8_t value = 0xAB;
+     177           1 :     const uint8_t spiTxn[] = { 
+     178             :       RADIOLIB_SX126X_CMD_READ_REGISTER,  0x00, address, 0x00, 0x00,
+     179             :       RADIOLIB_SX126X_CMD_WRITE_REGISTER, 0x00, address, value,
+     180             :     };
+     181           1 :     ret = mod->SPIsetRegValue(address, value);
+     182             : 
+     183             :     // check return code and history log
+     184             :     // this will return write error because the bare emulated radio has no internal logic
+     185           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
+     186           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
+     187             : 
+     188             :     // register write masking test
+     189           1 :     const uint8_t msb = 5;
+     190           1 :     const uint8_t lsb = 1;
+     191           1 :     const uint8_t maskedValue = 0xEB;
+     192           1 :     const uint8_t spiTxn2[] = { 
+     193             :       RADIOLIB_SX126X_CMD_READ_REGISTER,  0x00, address, 0x00, 0x00,
+     194             :       RADIOLIB_SX126X_CMD_WRITE_REGISTER, 0x00, address, maskedValue,
+     195             :     };
+     196           1 :     ret = mod->SPIsetRegValue(address, value, msb, lsb);
+     197           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
+     198           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn2, sizeof(spiTxn2)) == 0);
+     199             : 
+     200             :     // invalid mask tests (swapped MSB and LSB, out of range bit masks)
+     201           1 :     ret = mod->SPIsetRegValue(address, value, lsb, msb);
+     202           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
+     203           1 :     ret = mod->SPIsetRegValue(address, value, 10, lsb);
+     204           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
+     205           1 :     ret = mod->SPIsetRegValue(address, value, msb, 10);
+     206           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
+     207             : 
+     208             :     // check interval test
+     209           1 :     const uint8_t interval = 200;
+     210           1 :     const unsigned long start = hal->micros();
+     211           1 :     ret = mod->SPIsetRegValue(address, value, 7, 0, interval);
+     212           1 :     const unsigned long stop = hal->micros();
+     213           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
+     214           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
+     215           1 :     const unsigned long elapsed = stop - start;
+     216           1 :     BOOST_TEST(elapsed >= (unsigned long)interval*1000UL);
+     217             : 
+     218             :     // disabled check mask test
+     219           1 :     ret = mod->SPIsetRegValue(address, value, 7, 0, 2, 0);
+     220           1 :     BOOST_TEST(ret == RADIOLIB_ERR_NONE);
+     221           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
+     222             : 
+     223             :     // forced write test
+     224           1 :     ret = mod->SPIsetRegValue(address, value, 7, 0, 2, 0xFF, true);
+     225           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
+     226           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
+     227           1 :   }
+     228             : 
+     229             : BOOST_AUTO_TEST_SUITE_END()
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/tests/index-sort-f.html b/coverage/extras/test/unit/tests/index-sort-f.html new file mode 100644 index 00000000..0289bc1f --- /dev/null +++ b/coverage/extras/test/unit/tests/index-sort-f.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/tests + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/testsHitTotalCoverage
Test:lcov.infoLines:142142100.0 %
Date:2025-03-23 20:50:28Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
TestModule.cpp +
100.0%
+
100.0 %142 / 142100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/tests/index-sort-l.html b/coverage/extras/test/unit/tests/index-sort-l.html new file mode 100644 index 00000000..398b08bc --- /dev/null +++ b/coverage/extras/test/unit/tests/index-sort-l.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/tests + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/testsHitTotalCoverage
Test:lcov.infoLines:142142100.0 %
Date:2025-03-23 20:50:28Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
TestModule.cpp +
100.0%
+
100.0 %142 / 142100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/extras/test/unit/tests/index.html b/coverage/extras/test/unit/tests/index.html new file mode 100644 index 00000000..0883784f --- /dev/null +++ b/coverage/extras/test/unit/tests/index.html @@ -0,0 +1,93 @@ + + + + + + + LCOV - lcov.info - extras/test/unit/tests + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - extras/test/unit/testsHitTotalCoverage
Test:lcov.infoLines:142142100.0 %
Date:2025-03-23 20:50:28Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
TestModule.cpp +
100.0%
+
100.0 %142 / 142100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/gcov.css b/coverage/gcov.css new file mode 100644 index 00000000..bfd0a83e --- /dev/null +++ b/coverage/gcov.css @@ -0,0 +1,519 @@ +/* All views: initial background and text color */ +body +{ + color: #000000; + background-color: #FFFFFF; +} + +/* All views: standard link format*/ +a:link +{ + color: #284FA8; + text-decoration: underline; +} + +/* All views: standard link - visited format */ +a:visited +{ + color: #00CB40; + text-decoration: underline; +} + +/* All views: standard link - activated format */ +a:active +{ + color: #FF0040; + text-decoration: underline; +} + +/* All views: main title format */ +td.title +{ + text-align: center; + padding-bottom: 10px; + font-family: sans-serif; + font-size: 20pt; + font-style: italic; + font-weight: bold; +} + +/* All views: header item format */ +td.headerItem +{ + text-align: right; + padding-right: 6px; + font-family: sans-serif; + font-weight: bold; + vertical-align: top; + white-space: nowrap; +} + +/* All views: header item value format */ +td.headerValue +{ + text-align: left; + color: #284FA8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; +} + +/* All views: header item coverage table heading */ +td.headerCovTableHead +{ + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; +} + +/* All views: header item coverage table entry */ +td.headerCovTableEntry +{ + text-align: right; + color: #284FA8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #DAE7FE; +} + +/* All views: header item coverage table entry for high coverage rate */ +td.headerCovTableEntryHi +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #A7FC9D; +} + +/* All views: header item coverage table entry for medium coverage rate */ +td.headerCovTableEntryMed +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #FFEA20; +} + +/* All views: header item coverage table entry for ow coverage rate */ +td.headerCovTableEntryLo +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #FF0000; +} + +/* All views: header legend value for legend entry */ +td.headerValueLeg +{ + text-align: left; + color: #000000; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; + padding-top: 4px; +} + +/* All views: color of horizontal ruler */ +td.ruler +{ + background-color: #6688D4; +} + +/* All views: version string format */ +td.versionInfo +{ + text-align: center; + padding-top: 2px; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all)/Test case descriptions: + table headline format */ +td.tableHead +{ + text-align: center; + color: #FFFFFF; + background-color: #6688D4; + font-family: sans-serif; + font-size: 120%; + font-weight: bold; + white-space: nowrap; + padding-left: 4px; + padding-right: 4px; +} + +span.tableHeadSort +{ + padding-right: 4px; +} + +/* Directory view/File view (all): filename entry format */ +td.coverFile +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284FA8; + background-color: #DAE7FE; + font-family: monospace; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; +} + +/* Directory view/File view (all): bar-graph outline color */ +td.coverBarOutline +{ + background-color: #000000; +} + +/* Directory view/File view (all): percentage entry for files with + high coverage rate */ +td.coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #A7FC9D; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + high coverage rate */ +td.coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #A7FC9D; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + medium coverage rate */ +td.coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FFEA20; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + medium coverage rate */ +td.coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FFEA20; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + low coverage rate */ +td.coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FF0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + low coverage rate */ +td.coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FF0000; + white-space: nowrap; + font-family: sans-serif; +} + +/* File view (all): "show/hide details" link format */ +a.detail:link +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - visited format */ +a.detail:visited +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - activated format */ +a.detail:active +{ + color: #FFFFFF; + font-size:80%; +} + +/* File view (detail): test name entry */ +td.testName +{ + text-align: right; + padding-right: 10px; + background-color: #DAE7FE; + font-family: sans-serif; +} + +/* File view (detail): test percentage entry */ +td.testPer +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; + font-family: sans-serif; +} + +/* File view (detail): test lines count entry */ +td.testNum +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; + font-family: sans-serif; +} + +/* Test case descriptions: test name format*/ +dt +{ + font-family: sans-serif; + font-weight: bold; +} + +/* Test case descriptions: description table body */ +td.testDescription +{ + padding-top: 10px; + padding-left: 30px; + padding-bottom: 10px; + padding-right: 30px; + background-color: #DAE7FE; +} + +/* Source code view: function entry */ +td.coverFn +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284FA8; + background-color: #DAE7FE; + font-family: monospace; +} + +/* Source code view: function entry zero count*/ +td.coverFnLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #FF0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: function entry nonzero count*/ +td.coverFnHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #DAE7FE; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: source code format */ +pre.source +{ + font-family: monospace; + white-space: pre; + margin-top: 2px; +} + +/* Source code view: line number format */ +span.lineNum +{ + background-color: #EFE383; +} + +/* Source code view: format for lines which were executed */ +td.lineCov, +span.lineCov +{ + background-color: #CAD7FE; +} + +/* Source code view: format for Cov legend */ +span.coverLegendCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #CAD7FE; +} + +/* Source code view: format for lines which were not executed */ +td.lineNoCov, +span.lineNoCov +{ + background-color: #FF6230; +} + +/* Source code view: format for NoCov legend */ +span.coverLegendNoCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #FF6230; +} + +/* Source code view (function table): standard link - visited format */ +td.lineNoCov > a:visited, +td.lineCov > a:visited +{ + color: black; + text-decoration: underline; +} + +/* Source code view: format for lines which were executed only in a + previous version */ +span.lineDiffCov +{ + background-color: #B5F7AF; +} + +/* Source code view: format for branches which were executed + * and taken */ +span.branchCov +{ + background-color: #CAD7FE; +} + +/* Source code view: format for branches which were executed + * but not taken */ +span.branchNoCov +{ + background-color: #FF6230; +} + +/* Source code view: format for branches which were not executed */ +span.branchNoExec +{ + background-color: #FF6230; +} + +/* Source code view: format for the source code heading line */ +pre.sourceHeading +{ + white-space: pre; + font-family: monospace; + font-weight: bold; + margin: 0px; +} + +/* All views: header legend value for low rate */ +td.headerValueLegL +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 4px; + padding-right: 2px; + background-color: #FF0000; + font-size: 80%; +} + +/* All views: header legend value for med rate */ +td.headerValueLegM +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 2px; + background-color: #FFEA20; + font-size: 80%; +} + +/* All views: header legend value for hi rate */ +td.headerValueLegH +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 4px; + background-color: #A7FC9D; + font-size: 80%; +} + +/* All views except source code view: legend format for low coverage */ +span.coverLegendCovLo +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #FF0000; +} + +/* All views except source code view: legend format for med coverage */ +span.coverLegendCovMed +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #FFEA20; +} + +/* All views except source code view: legend format for hi coverage */ +span.coverLegendCovHi +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #A7FC9D; +} diff --git a/coverage/glass.png b/coverage/glass.png new file mode 100644 index 00000000..e1abc006 Binary files /dev/null and b/coverage/glass.png differ diff --git a/coverage/index-sort-f.html b/coverage/index-sort-f.html new file mode 100644 index 00000000..78d1726b --- /dev/null +++ b/coverage/index-sort-f.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - lcov.info + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:lcov.infoLines:34048969.5 %
Date:2025-03-23 20:50:28Functions:386855.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
src +
47.5%47.5%
+
47.5 %115 / 24232.3 %10 / 31
extras/test/unit/include +
79.0%79.0%
+
79.0 %83 / 10566.7 %18 / 27
extras/test/unit/tests +
100.0%
+
100.0 %142 / 142100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/index-sort-l.html b/coverage/index-sort-l.html new file mode 100644 index 00000000..82d5880e --- /dev/null +++ b/coverage/index-sort-l.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - lcov.info + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:lcov.infoLines:34048969.5 %
Date:2025-03-23 20:50:28Functions:386855.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
src +
47.5%47.5%
+
47.5 %115 / 24232.3 %10 / 31
extras/test/unit/include +
79.0%79.0%
+
79.0 %83 / 10566.7 %18 / 27
extras/test/unit/tests +
100.0%
+
100.0 %142 / 142100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/index.html b/coverage/index.html new file mode 100644 index 00000000..db431498 --- /dev/null +++ b/coverage/index.html @@ -0,0 +1,113 @@ + + + + + + + LCOV - lcov.info + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:lcov.infoLines:34048969.5 %
Date:2025-03-23 20:50:28Functions:386855.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
extras/test/unit/include +
79.0%79.0%
+
79.0 %83 / 10566.7 %18 / 27
extras/test/unit/tests +
100.0%
+
100.0 %142 / 142100.0 %10 / 10
src +
47.5%47.5%
+
47.5 %115 / 24232.3 %10 / 31
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/ruby.png b/coverage/ruby.png new file mode 100644 index 00000000..991b6d4e Binary files /dev/null and b/coverage/ruby.png differ diff --git a/coverage/snow.png b/coverage/snow.png new file mode 100644 index 00000000..2cdae107 Binary files /dev/null and b/coverage/snow.png differ diff --git a/coverage/src/Hal.cpp.func-sort-c.html b/coverage/src/Hal.cpp.func-sort-c.html new file mode 100644 index 00000000..5b3b2caf --- /dev/null +++ b/coverage/src/Hal.cpp.func-sort-c.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - lcov.info - src/Hal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - Hal.cpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:102441.7 %
Date:2025-03-23 20:50:28Functions:1812.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_Z11rlb_time_usv0
_ZN11RadioLibHal14pinToInterruptEj0
_ZN11RadioLibHal4initEv0
_ZN11RadioLibHal4termEv0
_ZN11RadioLibHal4toneEjjm0
_ZN11RadioLibHal5yieldEv0
_ZN11RadioLibHal6noToneEj0
_ZN11RadioLibHalC2Ejjjjjj4
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/Hal.cpp.func.html b/coverage/src/Hal.cpp.func.html new file mode 100644 index 00000000..3948e221 --- /dev/null +++ b/coverage/src/Hal.cpp.func.html @@ -0,0 +1,104 @@ + + + + + + + LCOV - lcov.info - src/Hal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - Hal.cpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:102441.7 %
Date:2025-03-23 20:50:28Functions:1812.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_Z11rlb_time_usv0
_ZN11RadioLibHal14pinToInterruptEj0
_ZN11RadioLibHal4initEv0
_ZN11RadioLibHal4termEv0
_ZN11RadioLibHal4toneEjjm0
_ZN11RadioLibHal5yieldEv0
_ZN11RadioLibHal6noToneEj0
_ZN11RadioLibHalC2Ejjjjjj4
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/Hal.cpp.gcov.html b/coverage/src/Hal.cpp.gcov.html new file mode 100644 index 00000000..809f2dda --- /dev/null +++ b/coverage/src/Hal.cpp.gcov.html @@ -0,0 +1,121 @@ + + + + + + + LCOV - lcov.info - src/Hal.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - Hal.cpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:102441.7 %
Date:2025-03-23 20:50:28Functions:1812.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : #include "Hal.h"
+       2             : 
+       3             : static RadioLibHal* rlb_timestamp_hal = nullptr;
+       4             : 
+       5           4 : RadioLibHal::RadioLibHal(const uint32_t input, const uint32_t output, const uint32_t low, const uint32_t high, const uint32_t rising, const uint32_t falling)
+       6           4 :     : GpioModeInput(input),
+       7           4 :       GpioModeOutput(output),
+       8           4 :       GpioLevelLow(low),
+       9           4 :       GpioLevelHigh(high),
+      10           4 :       GpioInterruptRising(rising),
+      11           4 :       GpioInterruptFalling(falling) {
+      12           4 :         if(!rlb_timestamp_hal) {
+      13           1 :           rlb_timestamp_hal = this;
+      14             :         }
+      15           4 :       }
+      16             : 
+      17           0 : void RadioLibHal::init() {
+      18             : 
+      19           0 : }
+      20             : 
+      21           0 : void RadioLibHal::term() {
+      22             : 
+      23           0 : }
+      24             : 
+      25           0 : void RadioLibHal::tone(uint32_t pin, unsigned int frequency, RadioLibTime_t duration) {
+      26             :   (void)pin;
+      27             :   (void)frequency;
+      28             :   (void)duration;
+      29           0 : }
+      30             : 
+      31           0 : void RadioLibHal::noTone(uint32_t pin) {
+      32             :   (void)pin;
+      33           0 : }
+      34             : 
+      35           0 : void RadioLibHal::yield() {
+      36             : 
+      37           0 : }
+      38             : 
+      39           0 : uint32_t RadioLibHal::pinToInterrupt(uint32_t pin) {
+      40           0 :   return(pin);
+      41             : }
+      42             : 
+      43           0 : RadioLibTime_t rlb_time_us() {
+      44           0 :   return(rlb_timestamp_hal == nullptr ? 0 : rlb_timestamp_hal->micros());
+      45             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/Module.cpp.func-sort-c.html b/coverage/src/Module.cpp.func-sort-c.html new file mode 100644 index 00000000..697253fa --- /dev/null +++ b/coverage/src/Module.cpp.func-sort-c.html @@ -0,0 +1,164 @@ + + + + + + + LCOV - lcov.info - src/Module.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - Module.cpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:10521848.2 %
Date:2025-03-23 20:50:28Functions:92339.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN6Module13SPIreadStreamEPKhhPhmbb0
_ZN6Module13SPIreadStreamEtPhmbb0
_ZN6Module14SPIcheckStreamEv0
_ZN6Module14SPIwriteStreamEPKhhS1_mbb0
_ZN6Module14SPIwriteStreamEtPKhmbb0
_ZN6Module15setRfSwitchPinsEjj0
_ZN6Module16setRfSwitchStateEh0
_ZN6Module16setRfSwitchTableERA5_KjPKNS_14RfSwitchMode_tE0
_ZN6Module19waitForMicrosecondsEmm0
_ZN6Module20SPIreadRegisterBurstEjmPh0
_ZN6Module21SPIwriteRegisterBurstEjPKhm0
_ZN6ModuleC2ERKS_0
_ZN6ModuleaSERKS_0
_ZNK6Module16findRfSwitchModeEh0
_ZN6Module4initEv4
_ZN6Module4termEv4
_ZN6ModuleC2EP11RadioLibHaljjjj4
_ZN6Module14SPIgetRegValueEjhh10
_ZN6Module16SPIwriteRegisterEjh10
_ZN6Module14SPIsetRegValueEjhhhhhb16
_ZN6Module17SPItransferStreamEPKhhbS1_Phmb423
_ZN6Module11SPItransferEtjPKhPhm1041
_ZN6Module15SPIreadRegisterEj1454
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/Module.cpp.func.html b/coverage/src/Module.cpp.func.html new file mode 100644 index 00000000..45a4c7de --- /dev/null +++ b/coverage/src/Module.cpp.func.html @@ -0,0 +1,164 @@ + + + + + + + LCOV - lcov.info - src/Module.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - Module.cpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:10521848.2 %
Date:2025-03-23 20:50:28Functions:92339.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN6Module11SPItransferEtjPKhPhm1041
_ZN6Module13SPIreadStreamEPKhhPhmbb0
_ZN6Module13SPIreadStreamEtPhmbb0
_ZN6Module14SPIcheckStreamEv0
_ZN6Module14SPIgetRegValueEjhh10
_ZN6Module14SPIsetRegValueEjhhhhhb16
_ZN6Module14SPIwriteStreamEPKhhS1_mbb0
_ZN6Module14SPIwriteStreamEtPKhmbb0
_ZN6Module15SPIreadRegisterEj1454
_ZN6Module15setRfSwitchPinsEjj0
_ZN6Module16SPIwriteRegisterEjh10
_ZN6Module16setRfSwitchStateEh0
_ZN6Module16setRfSwitchTableERA5_KjPKNS_14RfSwitchMode_tE0
_ZN6Module17SPItransferStreamEPKhhbS1_Phmb423
_ZN6Module19waitForMicrosecondsEmm0
_ZN6Module20SPIreadRegisterBurstEjmPh0
_ZN6Module21SPIwriteRegisterBurstEjPKhm0
_ZN6Module4initEv4
_ZN6Module4termEv4
_ZN6ModuleC2EP11RadioLibHaljjjj4
_ZN6ModuleC2ERKS_0
_ZN6ModuleaSERKS_0
_ZNK6Module16findRfSwitchModeEh0
+
+
+ + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/Module.cpp.gcov.html b/coverage/src/Module.cpp.gcov.html new file mode 100644 index 00000000..bf8aabeb --- /dev/null +++ b/coverage/src/Module.cpp.gcov.html @@ -0,0 +1,615 @@ + + + + + + + LCOV - lcov.info - src/Module.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src - Module.cpp (source / functions)HitTotalCoverage
Test:lcov.infoLines:10521848.2 %
Date:2025-03-23 20:50:28Functions:92339.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : #include "Module.h"
+       2             : 
+       3             : // the following is probably only needed on non-Arduino builds
+       4             : #include <stdio.h>
+       5             : #include <string.h>
+       6             : 
+       7             : #if defined(RADIOLIB_BUILD_ARDUINO)
+       8             : #include "hal/Arduino/ArduinoHal.h"
+       9             : 
+      10             : Module::Module(uint32_t cs, uint32_t irq, uint32_t rst, uint32_t gpio) : csPin(cs), irqPin(irq), rstPin(rst), gpioPin(gpio) {
+      11             :   this->hal = new ArduinoHal();
+      12             : }
+      13             : 
+      14             : Module::Module(uint32_t cs, uint32_t irq, uint32_t rst, uint32_t gpio, SPIClass& spi, SPISettings spiSettings) : csPin(cs), irqPin(irq), rstPin(rst), gpioPin(gpio) {
+      15             :   this->hal = new ArduinoHal(spi, spiSettings);
+      16             : }
+      17             : #endif
+      18             : 
+      19           4 : Module::Module(RadioLibHal *hal, uint32_t cs, uint32_t irq, uint32_t rst, uint32_t gpio) : csPin(cs), irqPin(irq), rstPin(rst), gpioPin(gpio) {
+      20           4 :   this->hal = hal;
+      21           4 : }
+      22             : 
+      23           0 : Module::Module(const Module& mod) {
+      24           0 :   *this = mod;
+      25           0 : }
+      26             : 
+      27           0 : Module& Module::operator=(const Module& mod) {
+      28           0 :   memcpy(reinterpret_cast<void*>(&(const_cast<Module&>(mod)).spiConfig), &this->spiConfig, sizeof(SPIConfig_t));
+      29           0 :   this->csPin = mod.csPin;
+      30           0 :   this->irqPin = mod.irqPin;
+      31           0 :   this->rstPin = mod.rstPin;
+      32           0 :   this->gpioPin = mod.gpioPin;
+      33           0 :   return(*this);
+      34             : }
+      35             : 
+      36             : static volatile const char info[] = RADIOLIB_INFO;
+      37           4 : void Module::init() {
+      38           4 :   this->hal->init();
+      39           4 :   this->hal->pinMode(csPin, this->hal->GpioModeOutput);
+      40           4 :   this->hal->digitalWrite(csPin, this->hal->GpioLevelHigh);
+      41             :   RADIOLIB_DEBUG_BASIC_PRINTLN(RADIOLIB_INFO);
+      42           4 : }
+      43             : 
+      44           4 : void Module::term() {
+      45             :   // stop hardware interfaces (if they were initialized by the library)
+      46           4 :   this->hal->term();
+      47           4 : }
+      48             : 
+      49          10 : int16_t Module::SPIgetRegValue(uint32_t reg, uint8_t msb, uint8_t lsb) {
+      50          10 :   if((msb > 7) || (lsb > 7) || (lsb > msb)) {
+      51           6 :     return(RADIOLIB_ERR_INVALID_BIT_RANGE);
+      52             :   }
+      53             : 
+      54           4 :   uint8_t rawValue = SPIreadRegister(reg);
+      55           4 :   uint8_t maskedValue = rawValue & ((0b11111111 << lsb) & (0b11111111 >> (7 - msb)));
+      56           4 :   return(maskedValue);
+      57             : }
+      58             : 
+      59          16 : int16_t Module::SPIsetRegValue(uint32_t reg, uint8_t value, uint8_t msb, uint8_t lsb, uint8_t checkInterval, uint8_t checkMask, bool force) {
+      60          16 :   if((msb > 7) || (lsb > 7) || (lsb > msb)) {
+      61           6 :     return(RADIOLIB_ERR_INVALID_BIT_RANGE);
+      62             :   }
+      63             : 
+      64             :   // read the current value
+      65          10 :   uint8_t currentValue = SPIreadRegister(reg);
+      66          10 :   uint8_t mask = ~((0b11111111 << (msb + 1)) | (0b11111111 >> (8 - lsb)));
+      67             : 
+      68             :   // check if we actually need to update the register
+      69          10 :   if((currentValue & mask) == (value & mask) && !force) {
+      70           0 :     return(RADIOLIB_ERR_NONE);
+      71             :   }
+      72             : 
+      73             :   // update the register
+      74          10 :   uint8_t newValue = (currentValue & ~mask) | (value & mask);
+      75          10 :   SPIwriteRegister(reg, newValue);
+      76             : 
+      77             :   #if RADIOLIB_SPI_PARANOID
+      78             :     // check register value each millisecond until check interval is reached
+      79             :     // some registers need a bit of time to process the change (e.g. SX127X_REG_OP_MODE)
+      80          10 :     RadioLibTime_t start = this->hal->micros();
+      81             :     #if RADIOLIB_DEBUG_SPI
+      82             :     uint8_t readValue = 0x00;
+      83             :     #endif
+      84        1448 :     while(this->hal->micros() - start < (checkInterval * 1000)) {
+      85        1440 :       uint8_t val = SPIreadRegister(reg);
+      86        1440 :       if((val & checkMask) == (newValue & checkMask)) {
+      87             :         // check passed, we can stop the loop
+      88           2 :         return(RADIOLIB_ERR_NONE);
+      89             :       }
+      90             :       #if RADIOLIB_DEBUG_SPI
+      91             :       readValue = val;
+      92             :       #endif
+      93             :     }
+      94             : 
+      95             :     // check failed, print debug info
+      96             :     RADIOLIB_DEBUG_SPI_PRINTLN();
+      97             :     RADIOLIB_DEBUG_SPI_PRINTLN("address:\t0x%X", reg);
+      98             :     RADIOLIB_DEBUG_SPI_PRINTLN("bits:\t\t%d %d", msb, lsb);
+      99             :     RADIOLIB_DEBUG_SPI_PRINTLN("value:\t\t0x%X", value);
+     100             :     RADIOLIB_DEBUG_SPI_PRINTLN("current:\t0x%X", currentValue);
+     101             :     RADIOLIB_DEBUG_SPI_PRINTLN("mask:\t\t0x%X", mask);
+     102             :     RADIOLIB_DEBUG_SPI_PRINTLN("new:\t\t0x%X", newValue);
+     103             :     RADIOLIB_DEBUG_SPI_PRINTLN("read:\t\t0x%X", readValue);
+     104             : 
+     105           8 :     return(RADIOLIB_ERR_SPI_WRITE_FAILED);
+     106             :   #else
+     107             :     return(RADIOLIB_ERR_NONE);
+     108             :   #endif
+     109             : }
+     110             : 
+     111           0 : void Module::SPIreadRegisterBurst(uint32_t reg, size_t numBytes, uint8_t* inBytes) {
+     112           0 :   if(!this->spiConfig.stream) {
+     113           0 :     SPItransfer(this->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ], reg, NULL, inBytes, numBytes);
+     114             :   } else {
+     115             :     uint8_t cmd[6];
+     116           0 :     uint8_t* cmdPtr = cmd;
+     117           0 :     for(int8_t i = (int8_t)this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 - 1; i >= 0; i--) {
+     118           0 :       *(cmdPtr++) = (this->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] >> 8*i) & 0xFF;
+     119             :     }
+     120           0 :     for(int8_t i = (int8_t)((this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8) - 1); i >= 0; i--) {
+     121           0 :       *(cmdPtr++) = (reg >> 8*i) & 0xFF;
+     122             :     }
+     123           0 :     SPItransferStream(cmd, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8, false, NULL, inBytes, numBytes, true);
+     124             :   }
+     125           0 : }
+     126             : 
+     127        1454 : uint8_t Module::SPIreadRegister(uint32_t reg) {
+     128        1454 :   uint8_t resp = 0;
+     129        1454 :   if(!spiConfig.stream) {
+     130        1036 :     SPItransfer(this->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ], reg, NULL, &resp, 1);
+     131             :   } else {
+     132             :     uint8_t cmd[6];
+     133         418 :     uint8_t* cmdPtr = cmd;
+     134         836 :     for(int8_t i = (int8_t)this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 - 1; i >= 0; i--) {
+     135         418 :       *(cmdPtr++) = (this->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] >> 8*i) & 0xFF;
+     136             :     }
+     137        1254 :     for(int8_t i = (int8_t)((this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8) - 1); i >= 0; i--) {
+     138         836 :       *(cmdPtr++) = (reg >> 8*i) & 0xFF;
+     139             :     }
+     140         418 :     SPItransferStream(cmd, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8, false, NULL, &resp, 1, true);
+     141             :   }
+     142        1454 :   return(resp);
+     143             : }
+     144             : 
+     145           0 : void Module::SPIwriteRegisterBurst(uint32_t reg, const uint8_t* data, size_t numBytes) {
+     146           0 :   if(!spiConfig.stream) {
+     147           0 :     SPItransfer(spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE], reg, data, NULL, numBytes);
+     148             :   } else {
+     149             :     uint8_t cmd[6];
+     150           0 :     uint8_t* cmdPtr = cmd;
+     151           0 :     for(int8_t i = (int8_t)this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 - 1; i >= 0; i--) {
+     152           0 :       *(cmdPtr++) = (this->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] >> 8*i) & 0xFF;
+     153             :     }
+     154           0 :     for(int8_t i = (int8_t)((this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8) - 1); i >= 0; i--) {
+     155           0 :       *(cmdPtr++) = (reg >> 8*i) & 0xFF;
+     156             :     }
+     157           0 :     SPItransferStream(cmd, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8, true, data, NULL, numBytes, true);
+     158             :   }
+     159           0 : }
+     160             : 
+     161          10 : void Module::SPIwriteRegister(uint32_t reg, uint8_t data) {
+     162          10 :   if(!spiConfig.stream) {
+     163           5 :     SPItransfer(spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE], reg, &data, NULL, 1);
+     164             :   } else {
+     165             :     uint8_t cmd[6];
+     166           5 :     uint8_t* cmdPtr = cmd;
+     167          10 :     for(int8_t i = (int8_t)this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 - 1; i >= 0; i--) {
+     168           5 :       *(cmdPtr++) = (this->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] >> 8*i) & 0xFF;
+     169             :     }
+     170          15 :     for(int8_t i = (int8_t)((this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8) - 1); i >= 0; i--) {
+     171          10 :       *(cmdPtr++) = (reg >> 8*i) & 0xFF;
+     172             :     }
+     173           5 :     SPItransferStream(cmd, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8, true, &data, NULL, 1, true);
+     174             :   }
+     175          10 : }
+     176             : 
+     177        1041 : void Module::SPItransfer(uint16_t cmd, uint32_t reg, const uint8_t* dataOut, uint8_t* dataIn, size_t numBytes) {
+     178             :   // prepare the buffers
+     179        1041 :   size_t buffLen = this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 + this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8 + numBytes;
+     180             :   #if RADIOLIB_STATIC_ONLY
+     181             :     uint8_t buffOut[RADIOLIB_STATIC_ARRAY_SIZE];
+     182             :     uint8_t buffIn[RADIOLIB_STATIC_ARRAY_SIZE];
+     183             :   #else
+     184        1041 :     uint8_t* buffOut = new uint8_t[buffLen];
+     185        1041 :     uint8_t* buffIn = new uint8_t[buffLen];
+     186             :   #endif
+     187        1041 :   uint8_t* buffOutPtr = buffOut;
+     188             : 
+     189             :   // copy the command
+     190             :   // TODO properly handle variable commands and addresses
+     191        1041 :   if(this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR] <= 8) {
+     192        1041 :     *(buffOutPtr++) = reg | cmd;
+     193             :   } else {
+     194           0 :     *(buffOutPtr++) = (reg >> 8) | cmd;
+     195           0 :     *(buffOutPtr++) = reg & 0xFF;
+     196             :   }
+     197             : 
+     198             :   // copy the data
+     199        1041 :   if(cmd == spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE]) {
+     200           5 :     memcpy(buffOutPtr, dataOut, numBytes);
+     201             :   } else {
+     202        1036 :     memset(buffOutPtr, this->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_NOP], numBytes);
+     203             :   }
+     204             : 
+     205             :   // do the transfer
+     206        1041 :   this->hal->spiBeginTransaction();
+     207        1041 :   this->hal->digitalWrite(this->csPin, this->hal->GpioLevelLow);
+     208        1041 :   this->hal->spiTransfer(buffOut, buffLen, buffIn);
+     209        1041 :   this->hal->digitalWrite(this->csPin, this->hal->GpioLevelHigh);
+     210        1041 :   this->hal->spiEndTransaction();
+     211             :   
+     212             :   // copy the data
+     213        1041 :   if(cmd == spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ]) {
+     214        1036 :     memcpy(dataIn, &buffIn[this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8], numBytes);
+     215             :   }
+     216             : 
+     217             :   // print debug information
+     218             :   #if RADIOLIB_DEBUG_SPI
+     219             :     const uint8_t* debugBuffPtr = NULL;
+     220             :     if(cmd == spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE]) {
+     221             :       RADIOLIB_DEBUG_SPI_PRINT("W\t%X\t", reg);
+     222             :       debugBuffPtr = &buffOut[this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8];
+     223             :     } else if(cmd == spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ]) {
+     224             :       RADIOLIB_DEBUG_SPI_PRINT("R\t%X\t", reg);
+     225             :       debugBuffPtr = &buffIn[this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR]/8];
+     226             :     }
+     227             :     for(size_t n = 0; n < numBytes; n++) {
+     228             :       RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", debugBuffPtr[n]);
+     229             :     }
+     230             :     RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG("");
+     231             :   #endif
+     232             : 
+     233             :   #if !RADIOLIB_STATIC_ONLY
+     234        1041 :     delete[] buffOut;
+     235        1041 :     delete[] buffIn;
+     236             :   #endif
+     237        1041 : }
+     238             : 
+     239           0 : int16_t Module::SPIreadStream(uint16_t cmd, uint8_t* data, size_t numBytes, bool waitForGpio, bool verify) {
+     240             :   uint8_t cmdBuf[2];
+     241           0 :   uint8_t* cmdPtr = cmdBuf;
+     242           0 :   for(int8_t i = (int8_t)this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 - 1; i >= 0; i--) {
+     243           0 :     *(cmdPtr++) = (cmd >> 8*i) & 0xFF;
+     244             :   }
+     245           0 :   return(this->SPIreadStream(cmdBuf, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8, data, numBytes, waitForGpio, verify));
+     246             : }
+     247             : 
+     248           0 : int16_t Module::SPIreadStream(const uint8_t* cmd, uint8_t cmdLen, uint8_t* data, size_t numBytes, bool waitForGpio, bool verify) {
+     249             :   // send the command
+     250           0 :   int16_t state = this->SPItransferStream(cmd, cmdLen, false, NULL, data, numBytes, waitForGpio);
+     251           0 :   RADIOLIB_ASSERT(state);
+     252             : 
+     253             :   #if !RADIOLIB_SPI_PARANOID
+     254             :   (void)verify;
+     255             :   return(RADIOLIB_ERR_NONE);
+     256             :   #else
+     257             : 
+     258             :   // check the status
+     259           0 :   if(verify && (this->spiConfig.checkStatusCb != nullptr)) {
+     260           0 :     state = this->spiConfig.checkStatusCb(this);
+     261             :   }
+     262             : 
+     263           0 :   return(state);
+     264             :   #endif
+     265             : }
+     266             : 
+     267           0 : int16_t Module::SPIwriteStream(uint16_t cmd, const uint8_t* data, size_t numBytes, bool waitForGpio, bool verify) {
+     268             :   uint8_t cmdBuf[2];
+     269           0 :   uint8_t* cmdPtr = cmdBuf;
+     270           0 :   for(int8_t i = (int8_t)this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 - 1; i >= 0; i--) {
+     271           0 :     *(cmdPtr++) = (cmd >> 8*i) & 0xFF;
+     272             :   }
+     273           0 :   return(this->SPIwriteStream(cmdBuf, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8, data, numBytes, waitForGpio, verify));
+     274             : }
+     275             : 
+     276           0 : int16_t Module::SPIwriteStream(const uint8_t* cmd, uint8_t cmdLen, const uint8_t* data, size_t numBytes, bool waitForGpio, bool verify) {
+     277             :   // send the command
+     278           0 :   int16_t state = this->SPItransferStream(cmd, cmdLen, true, data, NULL, numBytes, waitForGpio);
+     279           0 :   RADIOLIB_ASSERT(state);
+     280             : 
+     281             :   #if !RADIOLIB_SPI_PARANOID
+     282             :   (void)verify;
+     283             :   return(RADIOLIB_ERR_NONE);
+     284             :   #else
+     285             : 
+     286             :   // check the status
+     287           0 :   if(verify && (this->spiConfig.checkStatusCb != nullptr)) {
+     288           0 :     state = this->spiConfig.checkStatusCb(this);
+     289             :   }
+     290             : 
+     291           0 :   return(state);
+     292             :   #endif
+     293             : }
+     294             : 
+     295           0 : int16_t Module::SPIcheckStream() {
+     296           0 :   int16_t state = RADIOLIB_ERR_NONE;
+     297             : 
+     298             :   #if RADIOLIB_SPI_PARANOID
+     299             :   // get the status
+     300           0 :   uint8_t spiStatus = 0;
+     301             :   uint8_t cmdBuf[2];
+     302           0 :   uint8_t* cmdPtr = cmdBuf;
+     303           0 :   for(int8_t i = (int8_t)this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8 - 1; i >= 0; i--) {
+     304           0 :     *(cmdPtr++) = ( this->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_STATUS] >> 8*i) & 0xFF;
+     305             :   }
+     306           0 :   state = this->SPItransferStream(cmdBuf, this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD]/8, false, NULL, &spiStatus, 1, true);
+     307           0 :   RADIOLIB_ASSERT(state);
+     308             : 
+     309             :   // translate to RadioLib status code
+     310           0 :   if(this->spiConfig.parseStatusCb != nullptr) {
+     311           0 :     this->spiConfig.err = this->spiConfig.parseStatusCb(spiStatus);
+     312             :   }
+     313             :   #endif
+     314             : 
+     315           0 :   return(state);
+     316             : }
+     317             : 
+     318         423 : int16_t Module::SPItransferStream(const uint8_t* cmd, uint8_t cmdLen, bool write, const uint8_t* dataOut, uint8_t* dataIn, size_t numBytes, bool waitForGpio) {
+     319             :   // prepare the output buffer
+     320         423 :   int16_t state = RADIOLIB_ERR_NONE;
+     321         423 :   size_t buffLen = cmdLen + numBytes;
+     322         423 :   if(!write) {
+     323         418 :     buffLen += (this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] / 8);
+     324             :   }
+     325             :   #if RADIOLIB_STATIC_ONLY
+     326             :     uint8_t buffOut[RADIOLIB_STATIC_ARRAY_SIZE];
+     327             :   #else
+     328         423 :     uint8_t* buffOut = new uint8_t[buffLen];
+     329             :   #endif
+     330         423 :   uint8_t* buffOutPtr = buffOut;
+     331             : 
+     332             :   // copy the command
+     333        1692 :   for(uint8_t n = 0; n < cmdLen; n++) {
+     334        1269 :     *(buffOutPtr++) = cmd[n];
+     335             :   }
+     336             : 
+     337             :   // copy the data
+     338         423 :   if(write) {
+     339           5 :     memcpy(buffOutPtr, dataOut, numBytes);
+     340             :   } else {
+     341         418 :     memset(buffOutPtr, this->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_NOP], numBytes + (this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] / 8));
+     342             :   }
+     343             : 
+     344             :   // ensure GPIO is low
+     345         423 :   if(waitForGpio) {
+     346         423 :     if(this->gpioPin == RADIOLIB_NC) {
+     347           0 :       this->hal->delay(50);
+     348             :     } else {
+     349         423 :       RadioLibTime_t start = this->hal->millis();
+     350         423 :       while(this->hal->digitalRead(this->gpioPin)) {
+     351           0 :         this->hal->yield();
+     352             : 
+     353             :         // this timeout check triggers a false positive from cppcheck
+     354             :         // cppcheck-suppress unsignedLessThanZero
+     355           0 :         if(this->hal->millis() - start >= this->spiConfig.timeout) {
+     356             :           RADIOLIB_DEBUG_BASIC_PRINTLN("GPIO pre-transfer timeout, is it connected?");
+     357             :           #if !RADIOLIB_STATIC_ONLY
+     358           0 :             delete[] buffOut;
+     359             :           #endif
+     360           0 :           return(RADIOLIB_ERR_SPI_CMD_TIMEOUT);
+     361             :         }
+     362             :       
+     363             :       }
+     364             :     }
+     365             :   }
+     366             : 
+     367             :   // prepare the input buffer
+     368             :   #if RADIOLIB_STATIC_ONLY
+     369             :     uint8_t buffIn[RADIOLIB_STATIC_ARRAY_SIZE];
+     370             :   #else
+     371         423 :     uint8_t* buffIn = new uint8_t[buffLen];
+     372             :   #endif
+     373             : 
+     374             :   // do the transfer
+     375         423 :   this->hal->spiBeginTransaction();
+     376         423 :   this->hal->digitalWrite(this->csPin, this->hal->GpioLevelLow);
+     377         423 :   this->hal->spiTransfer(buffOut, buffLen, buffIn);
+     378         423 :   this->hal->digitalWrite(this->csPin, this->hal->GpioLevelHigh);
+     379         423 :   this->hal->spiEndTransaction();
+     380             : 
+     381             :   // wait for GPIO to go high and then low
+     382         423 :   if(waitForGpio) {
+     383         423 :     if(this->gpioPin == RADIOLIB_NC) {
+     384           0 :       this->hal->delay(1);
+     385             :     } else {
+     386         423 :       this->hal->delayMicroseconds(1);
+     387         423 :       RadioLibTime_t start = this->hal->millis();
+     388         423 :       while(this->hal->digitalRead(this->gpioPin)) {
+     389           0 :         this->hal->yield();
+     390             :         
+     391             :         // this timeout check triggers a false positive from cppcheck
+     392             :         // cppcheck-suppress unsignedLessThanZero
+     393           0 :         if(this->hal->millis() - start >= this->spiConfig.timeout) {
+     394             :           RADIOLIB_DEBUG_BASIC_PRINTLN("GPIO post-transfer timeout, is it connected?");
+     395             : 
+     396             :           // do not return yet to display the debug output
+     397           0 :           state = RADIOLIB_ERR_SPI_CMD_TIMEOUT;
+     398           0 :           break;
+     399             :         }
+     400             :       
+     401             :       }
+     402             :     }
+     403             :   }
+     404             : 
+     405             :   // parse status (only if GPIO did not timeout)
+     406         423 :   if((state == RADIOLIB_ERR_NONE) && (this->spiConfig.parseStatusCb != nullptr) && (numBytes > 0)) {
+     407           0 :     state = this->spiConfig.parseStatusCb(buffIn[this->spiConfig.statusPos]);
+     408             :   }
+     409             :   
+     410             :   // copy the data
+     411         423 :   if(!write) {
+     412             :     // skip the status bytes if present
+     413         418 :     memcpy(dataIn, &buffIn[cmdLen + (this->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_STATUS] / 8)], numBytes);
+     414             :   }
+     415             : 
+     416             :   // print debug information
+     417             :   #if RADIOLIB_DEBUG_SPI
+     418             :     // print command byte(s)
+     419             :     RADIOLIB_DEBUG_SPI_PRINT("CMD");
+     420             :     if(write) {
+     421             :       RADIOLIB_DEBUG_SPI_PRINT_NOTAG("W\t");
+     422             :     } else {
+     423             :       RADIOLIB_DEBUG_SPI_PRINT_NOTAG("R\t");
+     424             :     }
+     425             :     size_t n = 0;
+     426             :     for(; n < cmdLen; n++) {
+     427             :       RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", cmd[n]);
+     428             :     }
+     429             :     RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG("");
+     430             : 
+     431             :     // print data bytes
+     432             :     RADIOLIB_DEBUG_SPI_PRINT("SI\t");
+     433             :     for(n = 0; n < cmdLen; n++) {
+     434             :       RADIOLIB_DEBUG_SPI_PRINT_NOTAG("\t");
+     435             :     }
+     436             :     for(; n < buffLen; n++) {
+     437             :       RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", buffOut[n]);
+     438             :     }
+     439             :     RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG("");
+     440             :     RADIOLIB_DEBUG_SPI_PRINT("SO\t");
+     441             :     for(n = 0; n < buffLen; n++) {
+     442             :       RADIOLIB_DEBUG_SPI_PRINT_NOTAG("%X\t", buffIn[n]);
+     443             :     }
+     444             :     RADIOLIB_DEBUG_SPI_PRINTLN_NOTAG("");
+     445             :   #endif
+     446             : 
+     447             :   #if !RADIOLIB_STATIC_ONLY
+     448         423 :     delete[] buffOut;
+     449         423 :     delete[] buffIn;
+     450             :   #endif
+     451             : 
+     452         423 :   return(state);
+     453             : }
+     454             : 
+     455           0 : void Module::waitForMicroseconds(RadioLibTime_t start, RadioLibTime_t len) {
+     456             :   #if RADIOLIB_INTERRUPT_TIMING
+     457             :   (void)start;
+     458             :   if((this->TimerSetupCb != nullptr) && (len != this->prevTimingLen)) {
+     459             :     prevTimingLen = len;
+     460             :     this->TimerSetupCb(len);
+     461             :   }
+     462             :   this->TimerFlag = false;
+     463             :   while(!this->TimerFlag) {
+     464             :     this->hal->yield();
+     465             :   }
+     466             :   #else
+     467           0 :    while(this->hal->micros() - start < len) {
+     468           0 :     this->hal->yield();
+     469             :   }
+     470             :   #endif
+     471           0 : }
+     472             : 
+     473             : #if RADIOLIB_DEBUG
+     474             : void Module::regdump(const char* level, uint16_t start, size_t len) {
+     475             :   #if RADIOLIB_STATIC_ONLY
+     476             :     uint8_t buff[RADIOLIB_STATIC_ARRAY_SIZE];
+     477             :   #else
+     478             :     uint8_t* buff = new uint8_t[len];
+     479             :   #endif
+     480             :   SPIreadRegisterBurst(start, len, buff);
+     481             :   rlb_hexdump(level, buff, len, start);
+     482             :   #if !RADIOLIB_STATIC_ONLY
+     483             :     delete[] buff;
+     484             :   #endif
+     485             : }
+     486             : #endif
+     487             : 
+     488           0 : void Module::setRfSwitchPins(uint32_t rxEn, uint32_t txEn) {
+     489             :   // This can be on the stack, setRfSwitchTable copies the contents
+     490           0 :   const uint32_t pins[] = {
+     491             :     rxEn, txEn, RADIOLIB_NC, RADIOLIB_NC, RADIOLIB_NC,
+     492           0 :   };
+     493             :   
+     494             :   // This must be static, since setRfSwitchTable stores a reference.
+     495             :   static const RfSwitchMode_t table[] = {
+     496           0 :     { MODE_IDLE,  {this->hal->GpioLevelLow,  this->hal->GpioLevelLow} },
+     497           0 :     { MODE_RX,    {this->hal->GpioLevelHigh, this->hal->GpioLevelLow} },
+     498           0 :     { MODE_TX,    {this->hal->GpioLevelLow,  this->hal->GpioLevelHigh} },
+     499             :     END_OF_MODE_TABLE,
+     500           0 :   };
+     501           0 :   setRfSwitchTable(pins, table);
+     502           0 : }
+     503             : 
+     504           0 : void Module::setRfSwitchTable(const uint32_t (&pins)[RFSWITCH_MAX_PINS], const RfSwitchMode_t table[]) {
+     505           0 :   memcpy(this->rfSwitchPins, pins, sizeof(this->rfSwitchPins));
+     506           0 :   this->rfSwitchTable = table;
+     507           0 :   for(size_t i = 0; i < RFSWITCH_MAX_PINS; i++) {
+     508           0 :     this->hal->pinMode(pins[i], this->hal->GpioModeOutput);
+     509             :   }
+     510           0 : }
+     511             : 
+     512           0 : const Module::RfSwitchMode_t *Module::findRfSwitchMode(uint8_t mode) const {
+     513           0 :   const RfSwitchMode_t *row = this->rfSwitchTable;
+     514           0 :   while(row && row->mode != MODE_END_OF_TABLE) {
+     515           0 :     if(row->mode == mode) {
+     516           0 :       return row;
+     517             :     }
+     518           0 :     ++row;
+     519             :   }
+     520           0 :   return nullptr;
+     521             : }
+     522             : 
+     523           0 : void Module::setRfSwitchState(uint8_t mode) {
+     524           0 :   const RfSwitchMode_t *row = findRfSwitchMode(mode);
+     525           0 :   if(!row) {
+     526             :     // RF switch control is disabled or does not have this mode
+     527           0 :     return;
+     528             :   }
+     529             : 
+     530             :   // set pins
+     531           0 :   const uint32_t *value = &row->values[0];
+     532           0 :   for(size_t i = 0; i < RFSWITCH_MAX_PINS; i++) {
+     533           0 :     uint32_t pin = this->rfSwitchPins[i];
+     534           0 :     if(!(pin & RFSWITCH_PIN_FLAG)) {
+     535           0 :       this->hal->digitalWrite(pin, *value);
+     536             :     }
+     537           0 :     ++value;
+     538             :   }
+     539             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/index-sort-f.html b/coverage/src/index-sort-f.html new file mode 100644 index 00000000..22b3638d --- /dev/null +++ b/coverage/src/index-sort-f.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - lcov.info - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcov.infoLines:11524247.5 %
Date:2025-03-23 20:50:28Functions:103132.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Hal.cpp +
41.7%41.7%
+
41.7 %10 / 2412.5 %1 / 8
Module.cpp +
48.2%48.2%
+
48.2 %105 / 21839.1 %9 / 23
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/index-sort-l.html b/coverage/src/index-sort-l.html new file mode 100644 index 00000000..2279d11a --- /dev/null +++ b/coverage/src/index-sort-l.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - lcov.info - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcov.infoLines:11524247.5 %
Date:2025-03-23 20:50:28Functions:103132.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Hal.cpp +
41.7%41.7%
+
41.7 %10 / 2412.5 %1 / 8
Module.cpp +
48.2%48.2%
+
48.2 %105 / 21839.1 %9 / 23
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/src/index.html b/coverage/src/index.html new file mode 100644 index 00000000..11df2c62 --- /dev/null +++ b/coverage/src/index.html @@ -0,0 +1,103 @@ + + + + + + + LCOV - lcov.info - src + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - srcHitTotalCoverage
Test:lcov.infoLines:11524247.5 %
Date:2025-03-23 20:50:28Functions:103132.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Hal.cpp +
41.7%41.7%
+
41.7 %10 / 2412.5 %1 / 8
Module.cpp +
48.2%48.2%
+
48.2 %105 / 21839.1 %9 / 23
+
+
+ + + + +
Generated by: LCOV version 1.14
+
+ + + diff --git a/coverage/updown.png b/coverage/updown.png new file mode 100644 index 00000000..aa56a238 Binary files /dev/null and b/coverage/updown.png differ