LCOV - code coverage report
Current view: top level - extras/test/unit/tests - TestModule.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 185 189 97.9 %
Date: 2026-04-20 19:58:46 Functions: 10 14 71.4 %

          Line data    Source code
       1             : // boost test header
       2             : #include <boost/test/unit_test.hpp>
       3             : 
       4             : // mock HAL
       5             : #include "ModuleFixture.hpp"
       6             : 
       7           0 : static int16_t srcParseStatusCb(uint8_t in) { (void)in; return(RADIOLIB_ERR_UNKNOWN); }
       8           0 : static int16_t dstParseStatusCb(uint8_t in) { (void)in; return(RADIOLIB_ERR_UNKNOWN); }
       9           0 : static int16_t srcCheckStatusCb(Module* mod) { (void)mod; return(RADIOLIB_ERR_UNKNOWN); }
      10           0 : static int16_t dstCheckStatusCb(Module* mod) { (void)mod; return(RADIOLIB_ERR_UNKNOWN); }
      11             : 
      12             : BOOST_FIXTURE_TEST_SUITE(suite_Module, ModuleFixture)
      13             : 
      14           2 :   BOOST_FIXTURE_TEST_CASE(Module_CopyConstructor, ModuleFixture)
      15             :   {
      16           1 :     BOOST_TEST_MESSAGE("--- Test Module::CopyConstructor ---");
      17             : 
      18             :     // intentionally not using the Module fixture, since we will be modifying members arbitrarily
      19           1 :     Module src(hal, EMULATED_RADIO_NSS_PIN, EMULATED_RADIO_IRQ_PIN, EMULATED_RADIO_RST_PIN, EMULATED_RADIO_GPIO_PIN);
      20           1 :     Module dst(hal, -1*EMULATED_RADIO_NSS_PIN, -1*EMULATED_RADIO_IRQ_PIN, -1*EMULATED_RADIO_RST_PIN, -1*EMULATED_RADIO_GPIO_PIN);
      21             : 
      22             :     // set the source
      23           1 :     src.spiConfig.stream = true;
      24           1 :     src.spiConfig.err = 0xAA;
      25           5 :     for(unsigned int i = 0; i < sizeof(src.spiConfig.cmds)/sizeof(src.spiConfig.cmds[0]); i++) { src.spiConfig.cmds[i] = (2*i) + 1; }
      26           4 :     for(unsigned int i = 0; i < sizeof(src.spiConfig.widths)/sizeof(src.spiConfig.widths[0]); i++) { src.spiConfig.widths[i] = Module::BITS_8; }
      27           6 :     for(unsigned int i = 0; i < sizeof(src.rfSwitchPins)/sizeof(src.rfSwitchPins[0]); i++) { src.rfSwitchPins[i] = (2*i) + 1; }
      28           1 :     src.spiConfig.statusPos = 0x55;
      29           1 :     src.spiConfig.parseStatusCb = srcParseStatusCb;
      30           1 :     src.spiConfig.checkStatusCb = srcCheckStatusCb;
      31           1 :     src.spiConfig.timeout = 3000;
      32           1 :     const Module::RfSwitchMode_t srcRfMode[] = { { Module::MODE_IDLE, { 0, 0 } } };
      33           1 :     src.rfSwitchTable = srcRfMode;
      34             :     
      35             :     // set up the "modules" so that they are unequal
      36           1 :     dst.spiConfig.stream = !src.spiConfig.stream;
      37           1 :     dst.spiConfig.err = ~src.spiConfig.err;
      38           5 :     for(unsigned int i = 0; i < sizeof(dst.spiConfig.cmds)/sizeof(dst.spiConfig.cmds[0]); i++) { dst.spiConfig.cmds[i] = -1*src.spiConfig.cmds[i]; }
      39           4 :     for(unsigned int i = 0; i < sizeof(dst.spiConfig.widths)/sizeof(dst.spiConfig.widths[0]); i++) { dst.spiConfig.widths[i] = Module::BITS_24; }
      40           6 :     for(unsigned int i = 0; i < sizeof(dst.rfSwitchPins)/sizeof(dst.rfSwitchPins[0]); i++) { dst.rfSwitchPins[i] = -1*src.rfSwitchPins[i]; }
      41           1 :     dst.spiConfig.statusPos = ~src.spiConfig.statusPos;
      42           1 :     dst.spiConfig.parseStatusCb = dstParseStatusCb;
      43           1 :     dst.spiConfig.checkStatusCb = dstCheckStatusCb;
      44           1 :     dst.spiConfig.timeout = -1*src.spiConfig.timeout;
      45           1 :     const Module::RfSwitchMode_t dstRfMode[] = { { Module::MODE_RX, { 1, 1 } } };
      46           1 :     dst.rfSwitchTable = dstRfMode;
      47             : 
      48             :     // check unequality before copy
      49           1 :     BOOST_TEST(src.csPin != dst.csPin);
      50           1 :     BOOST_TEST(src.irqPin != dst.irqPin);
      51           1 :     BOOST_TEST(src.rstPin != dst.rstPin);
      52           1 :     BOOST_TEST(src.gpioPin != dst.gpioPin);
      53           1 :     BOOST_TEST(src.spiConfig.stream != dst.spiConfig.stream);
      54           1 :     BOOST_TEST(src.spiConfig.err != dst.spiConfig.err);
      55           5 :     for(unsigned int i = 0; i < sizeof(src.spiConfig.cmds)/sizeof(src.spiConfig.cmds[0]); i++) { BOOST_TEST(dst.spiConfig.cmds[i] != src.spiConfig.cmds[i]); }
      56           4 :     for(unsigned int i = 0; i < sizeof(src.spiConfig.widths)/sizeof(src.spiConfig.widths[0]); i++) { BOOST_TEST(dst.spiConfig.widths[i] != src.spiConfig.widths[i]); }
      57           1 :     BOOST_TEST(src.spiConfig.statusPos != dst.spiConfig.statusPos);
      58           1 :     BOOST_TEST(src.spiConfig.parseStatusCb != dst.spiConfig.parseStatusCb);
      59           1 :     BOOST_TEST(src.spiConfig.checkStatusCb != dst.spiConfig.checkStatusCb);
      60           1 :     BOOST_TEST(src.spiConfig.timeout != dst.spiConfig.timeout);
      61           6 :     for(unsigned int i = 0; i < sizeof(src.rfSwitchPins)/sizeof(src.rfSwitchPins[0]); i++) { BOOST_TEST(dst.rfSwitchPins[i] != src.rfSwitchPins[i]); }
      62           1 :     BOOST_TEST(src.rfSwitchTable != dst.rfSwitchTable);
      63             : 
      64             :     // make the copy
      65           1 :     dst = src;
      66             : 
      67             :     // check that source remained unchanged
      68           1 :     BOOST_TEST(src.spiConfig.parseStatusCb == srcParseStatusCb);
      69             : 
      70             :     // check equality after copy
      71           1 :     BOOST_TEST(src.csPin == dst.csPin);
      72           1 :     BOOST_TEST(src.irqPin == dst.irqPin);
      73           1 :     BOOST_TEST(src.rstPin == dst.rstPin);
      74           1 :     BOOST_TEST(src.gpioPin == dst.gpioPin);
      75           1 :     BOOST_TEST(src.spiConfig.stream == dst.spiConfig.stream);
      76           1 :     BOOST_TEST(src.spiConfig.err == dst.spiConfig.err);
      77           5 :     for(unsigned int i = 0; i < sizeof(src.spiConfig.cmds)/sizeof(src.spiConfig.cmds[0]); i++) { BOOST_TEST(dst.spiConfig.cmds[i] == src.spiConfig.cmds[i]); }
      78           4 :     for(unsigned int i = 0; i < sizeof(src.spiConfig.widths)/sizeof(src.spiConfig.widths[0]); i++) { BOOST_TEST(dst.spiConfig.widths[i] == src.spiConfig.widths[i]); }
      79           1 :     BOOST_TEST(src.spiConfig.statusPos == dst.spiConfig.statusPos);
      80           1 :     BOOST_TEST(src.spiConfig.parseStatusCb == dst.spiConfig.parseStatusCb);
      81           1 :     BOOST_TEST(src.spiConfig.checkStatusCb == dst.spiConfig.checkStatusCb);
      82           1 :     BOOST_TEST(src.spiConfig.timeout == dst.spiConfig.timeout);
      83           6 :     for(unsigned int i = 0; i < sizeof(src.rfSwitchPins)/sizeof(src.rfSwitchPins[0]); i++) { BOOST_TEST(dst.rfSwitchPins[i] == src.rfSwitchPins[i]); }
      84           1 :     BOOST_TEST(src.rfSwitchTable == dst.rfSwitchTable);
      85           1 :   }
      86             : 
      87           2 :   BOOST_FIXTURE_TEST_CASE(Module_SPIgetRegValue_reg, ModuleFixture)
      88             :   {
      89           1 :     BOOST_TEST_MESSAGE("--- Test Module::SPIgetRegValue register access ---");
      90             :     int16_t ret;
      91             : 
      92             :     // basic register read with default config
      93           1 :     const uint8_t address = 0x12;
      94           1 :     const uint8_t spiTxn[] = { address, 0x00 };
      95           1 :     ret = mod->SPIgetRegValue(address);
      96             : 
      97             :     // check return code, value and history log
      98           1 :     BOOST_TEST(ret >= RADIOLIB_ERR_NONE);
      99           1 :     BOOST_TEST(ret == EMULATED_RADIO_SPI_RETURN);
     100           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
     101             : 
     102             :     // register read masking test
     103           1 :     const uint8_t msb = 5;
     104           1 :     const uint8_t lsb = 1;
     105           1 :     const uint8_t maskedValue = 0x3E;
     106           1 :     ret = mod->SPIgetRegValue(address, msb, lsb);
     107           1 :     BOOST_TEST(ret == maskedValue);
     108             : 
     109             :     // invalid mask tests (swapped MSB and LSB, out of range bit masks)
     110           1 :     ret = mod->SPIgetRegValue(address, lsb, msb);
     111           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
     112           1 :     ret = mod->SPIgetRegValue(address, 10, lsb);
     113           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
     114           1 :     ret = mod->SPIgetRegValue(address, msb, 10);
     115           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
     116           1 :   }
     117             : 
     118           2 :   BOOST_FIXTURE_TEST_CASE(Module_SPIsetRegValue_reg, ModuleFixture)
     119             :   {
     120           1 :     BOOST_TEST_MESSAGE("--- Test Module::SPIsetRegValue register access ---");
     121             :     int16_t ret;
     122             : 
     123             :     // basic register write with default config
     124           1 :     const uint8_t address = 0x12;
     125           1 :     const uint8_t value = 0xAB;
     126           1 :     const uint8_t spiTxn[] = { address, 0x00, 0x80 | address, value };
     127           1 :     ret = mod->SPIsetRegValue(address, value);
     128             : 
     129             :     // check return code and history log
     130             :     // this will return write error because the bare emulated radio has no internal logic
     131           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
     132           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
     133             : 
     134             :     // register write masking test
     135           1 :     const uint8_t msb = 5;
     136           1 :     const uint8_t lsb = 1;
     137           1 :     const uint8_t maskedValue = 0xEB;
     138           1 :     const uint8_t spiTxn2[] = { address, 0x00, 0x80 | address, maskedValue };
     139           1 :     ret = mod->SPIsetRegValue(address, value, msb, lsb);
     140           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
     141           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn2, sizeof(spiTxn2)) == 0);
     142             : 
     143             :     // invalid mask tests (swapped MSB and LSB, out of range bit masks)
     144           1 :     ret = mod->SPIsetRegValue(address, value, lsb, msb);
     145           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
     146           1 :     ret = mod->SPIsetRegValue(address, value, 10, lsb);
     147           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
     148           1 :     ret = mod->SPIsetRegValue(address, value, msb, 10);
     149           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
     150             : 
     151             :     // check interval test
     152           1 :     const uint8_t interval = 200;
     153           1 :     const unsigned long start = hal->micros();
     154           1 :     ret = mod->SPIsetRegValue(address, value, 7, 0, interval);
     155           1 :     const unsigned long stop = hal->micros();
     156           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
     157           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
     158           1 :     const unsigned long elapsed = stop - start;
     159           1 :     BOOST_TEST(elapsed >= (unsigned long)interval*1000UL);
     160             : 
     161             :     // disabled check mask test
     162           1 :     ret = mod->SPIsetRegValue(address, value, 7, 0, 2, 0);
     163           1 :     BOOST_TEST(ret == RADIOLIB_ERR_NONE);
     164           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
     165             : 
     166             :     // forced write test
     167           1 :     ret = mod->SPIsetRegValue(address, value, 7, 0, 2, 0xFF, true);
     168           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
     169           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
     170           1 :   }
     171             : 
     172           2 :   BOOST_FIXTURE_TEST_CASE(Module_SPIgetRegValue_stream, ModuleFixture)
     173             :   {
     174           1 :     BOOST_TEST_MESSAGE("--- Test Module::SPIgetRegValue stream access ---");
     175             :     int16_t ret;
     176             : 
     177             :     // change settings to stream type
     178           1 :     mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR] = Module::BITS_16;
     179           1 :     mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_8;
     180           1 :     mod->spiConfig.statusPos = 1;
     181           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] = RADIOLIB_SX126X_CMD_READ_REGISTER;
     182           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] = RADIOLIB_SX126X_CMD_WRITE_REGISTER;
     183           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_NOP] = RADIOLIB_SX126X_CMD_NOP;
     184           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_STATUS] = RADIOLIB_SX126X_CMD_GET_STATUS;
     185           1 :     mod->spiConfig.stream = true;
     186             : 
     187             :     // basic register read
     188           1 :     const uint8_t address = 0x12;
     189           1 :     const uint8_t spiTxn[] = { RADIOLIB_SX126X_CMD_READ_REGISTER, 0x00, address, 0x00, 0x00 };
     190           1 :     ret = mod->SPIgetRegValue(address);
     191             : 
     192             :     // check return code, value and history log
     193           1 :     BOOST_TEST(ret >= RADIOLIB_ERR_NONE);
     194           1 :     BOOST_TEST(ret == EMULATED_RADIO_SPI_RETURN);
     195           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
     196             : 
     197             :     // register read masking test
     198           1 :     const uint8_t msb = 5;
     199           1 :     const uint8_t lsb = 1;
     200           1 :     const uint8_t maskedValue = 0x3E;
     201           1 :     ret = mod->SPIgetRegValue(address, msb, lsb);
     202           1 :     BOOST_TEST(ret == maskedValue);
     203             : 
     204             :     // invalid mask tests (swapped MSB and LSB, out of range bit masks)
     205           1 :     ret = mod->SPIgetRegValue(address, lsb, msb);
     206           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
     207           1 :     ret = mod->SPIgetRegValue(address, 10, lsb);
     208           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
     209           1 :     ret = mod->SPIgetRegValue(address, msb, 10);
     210           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
     211           1 :   }
     212             : 
     213           2 :   BOOST_FIXTURE_TEST_CASE(Module_SPIsetRegValue_stream, ModuleFixture)
     214             :   {
     215           1 :     BOOST_TEST_MESSAGE("--- Test Module::SPIsetRegValue stream access ---");
     216             :     int16_t ret;
     217             : 
     218             :     // change settings to stream type
     219           1 :     mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR] = Module::BITS_16;
     220           1 :     mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_8;
     221           1 :     mod->spiConfig.statusPos = 1;
     222           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] = RADIOLIB_SX126X_CMD_READ_REGISTER;
     223           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] = RADIOLIB_SX126X_CMD_WRITE_REGISTER;
     224           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_NOP] = RADIOLIB_SX126X_CMD_NOP;
     225           1 :     mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_STATUS] = RADIOLIB_SX126X_CMD_GET_STATUS;
     226           1 :     mod->spiConfig.stream = true;
     227             : 
     228             :     // basic register write with default config
     229           1 :     const uint8_t address = 0x12;
     230           1 :     const uint8_t value = 0xAB;
     231           1 :     const uint8_t spiTxn[] = { 
     232             :       RADIOLIB_SX126X_CMD_READ_REGISTER,  0x00, address, 0x00, 0x00,
     233             :       RADIOLIB_SX126X_CMD_WRITE_REGISTER, 0x00, address, value,
     234             :     };
     235           1 :     ret = mod->SPIsetRegValue(address, value);
     236             : 
     237             :     // check return code and history log
     238             :     // this will return write error because the bare emulated radio has no internal logic
     239           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
     240           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
     241             : 
     242             :     // register write masking test
     243           1 :     const uint8_t msb = 5;
     244           1 :     const uint8_t lsb = 1;
     245           1 :     const uint8_t maskedValue = 0xEB;
     246           1 :     const uint8_t spiTxn2[] = { 
     247             :       RADIOLIB_SX126X_CMD_READ_REGISTER,  0x00, address, 0x00, 0x00,
     248             :       RADIOLIB_SX126X_CMD_WRITE_REGISTER, 0x00, address, maskedValue,
     249             :     };
     250           1 :     ret = mod->SPIsetRegValue(address, value, msb, lsb);
     251           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
     252           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn2, sizeof(spiTxn2)) == 0);
     253             : 
     254             :     // invalid mask tests (swapped MSB and LSB, out of range bit masks)
     255           1 :     ret = mod->SPIsetRegValue(address, value, lsb, msb);
     256           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
     257           1 :     ret = mod->SPIsetRegValue(address, value, 10, lsb);
     258           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
     259           1 :     ret = mod->SPIsetRegValue(address, value, msb, 10);
     260           1 :     BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
     261             : 
     262             :     // check interval test
     263           1 :     const uint8_t interval = 200;
     264           1 :     const unsigned long start = hal->micros();
     265           1 :     ret = mod->SPIsetRegValue(address, value, 7, 0, interval);
     266           1 :     const unsigned long stop = hal->micros();
     267           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
     268           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
     269           1 :     const unsigned long elapsed = stop - start;
     270           1 :     BOOST_TEST(elapsed >= (unsigned long)interval*1000UL);
     271             : 
     272             :     // disabled check mask test
     273           1 :     ret = mod->SPIsetRegValue(address, value, 7, 0, 2, 0);
     274           1 :     BOOST_TEST(ret == RADIOLIB_ERR_NONE);
     275           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
     276             : 
     277             :     // forced write test
     278           1 :     ret = mod->SPIsetRegValue(address, value, 7, 0, 2, 0xFF, true);
     279           1 :     BOOST_TEST(ret == RADIOLIB_ERR_SPI_WRITE_FAILED);
     280           1 :     BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
     281           1 :   }
     282             : 
     283             : BOOST_AUTO_TEST_SUITE_END()

Generated by: LCOV version 1.14