Initial commit of Arduino libraries

This commit is contained in:
Sam
2025-05-23 10:47:41 +10:00
commit 5bfce5fc3e
2476 changed files with 1108481 additions and 0 deletions

View File

@@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.18)
# create the project
project(rpi-sx1261)
# when using debuggers such as gdb, the following line can be used
#set(CMAKE_BUILD_TYPE Debug)
# if you did not build RadioLib as shared library (see README),
# you will have to add it as source directory
# the following is just an example, yours will likely be different
#add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CURRENT_BINARY_DIR}/RadioLib")
# add the executable
add_executable(${PROJECT_NAME} main.cpp)
# link both libraries
target_link_libraries(${PROJECT_NAME} RadioLib pigpio)
# you can also specify RadioLib compile-time flags here
#target_compile_definitions(${PROJECT_NAME} PUBLIC RADIOLIB_DEBUG RADIOLIB_VERBOSE)

View File

@@ -0,0 +1,151 @@
#ifndef PI_HAL_H
#define PI_HAL_H
// include RadioLib
#include <RadioLib/RadioLib.h>
// include the library for Raspberry GPIO pins
#include "pigpio.h"
// create a new Raspberry Pi hardware abstraction layer
// using the pigpio library
// the HAL must inherit from the base RadioLibHal class
// and implement all of its virtual methods
class PiHal : public RadioLibHal {
public:
// default constructor - initializes the base HAL and any needed private members
PiHal(uint8_t spiChannel, uint32_t spiSpeed = 2000000)
: RadioLibHal(PI_INPUT, PI_OUTPUT, PI_LOW, PI_HIGH, RISING_EDGE, FALLING_EDGE),
_spiChannel(spiChannel),
_spiSpeed(spiSpeed) {
}
void init() override {
// first initialise pigpio library
gpioInitialise();
// now the SPI
spiBegin();
// Waveshare LoRaWAN Hat also needs pin 18 to be pulled high to enable the radio
gpioSetMode(18, PI_OUTPUT);
gpioWrite(18, PI_HIGH);
}
void term() override {
// stop the SPI
spiEnd();
// pull the enable pin low
gpioSetMode(18, PI_OUTPUT);
gpioWrite(18, PI_LOW);
// finally, stop the pigpio library
gpioTerminate();
}
// GPIO-related methods (pinMode, digitalWrite etc.) should check
// RADIOLIB_NC as an alias for non-connected pins
void pinMode(uint32_t pin, uint32_t mode) override {
if(pin == RADIOLIB_NC) {
return;
}
gpioSetMode(pin, mode);
}
void digitalWrite(uint32_t pin, uint32_t value) override {
if(pin == RADIOLIB_NC) {
return;
}
gpioWrite(pin, value);
}
uint32_t digitalRead(uint32_t pin) override {
if(pin == RADIOLIB_NC) {
return(0);
}
return(gpioRead(pin));
}
void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override {
if(interruptNum == RADIOLIB_NC) {
return;
}
gpioSetISRFunc(interruptNum, mode, 0, (gpioISRFunc_t)interruptCb);
}
void detachInterrupt(uint32_t interruptNum) override {
if(interruptNum == RADIOLIB_NC) {
return;
}
gpioSetISRFunc(interruptNum, 0, 0, NULL);
}
void delay(RadioLibTime_t ms) override {
gpioDelay(ms * 1000);
}
void delayMicroseconds(RadioLibTime_t us) override {
gpioDelay(us);
}
RadioLibTime_t millis() override {
return(gpioTick() / 1000);
}
RadioLibTime_t micros() override {
return(gpioTick());
}
long pulseIn(uint32_t pin, uint32_t state, RadioLibTime_t timeout) override {
if(pin == RADIOLIB_NC) {
return(0);
}
this->pinMode(pin, PI_INPUT);
RadioLibTime_t start = this->micros();
RadioLibTime_t curtick = this->micros();
while(this->digitalRead(pin) == state) {
if((this->micros() - curtick) > timeout) {
return(0);
}
}
return(this->micros() - start);
}
void spiBegin() {
if(_spiHandle < 0) {
_spiHandle = spiOpen(_spiChannel, _spiSpeed, 0);
}
}
void spiBeginTransaction() {}
void spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
spiXfer(_spiHandle, (char*)out, (char*)in, len);
}
void spiEndTransaction() {}
void spiEnd() {
if(_spiHandle >= 0) {
spiClose(_spiHandle);
_spiHandle = -1;
}
}
private:
// the HAL can contain any additional private members
const unsigned int _spiSpeed;
const uint8_t _spiChannel;
int _spiHandle = -1;
};
#endif

View File

@@ -0,0 +1,8 @@
#!/bin/bash
set -e
mkdir -p build
cd build
cmake -G "CodeBlocks - Unix Makefiles" ..
make -j4
cd ..

View File

@@ -0,0 +1,3 @@
#!/bin/bash
rm -rf ./build

View File

@@ -0,0 +1,26 @@
// this is an autotest file for the SX126x
// runs on Raspberry Pi with Waveshare LoRaWAN hat
#include <RadioLib/RadioLib.h>
#include "PiHal.h"
#define RADIOLIB_TEST_ASSERT(STATEVAR) { if((STATEVAR) != RADIOLIB_ERR_NONE) { return(-1*(STATEVAR)); } }
PiHal* hal = new PiHal(1);
SX1261 radio = new Module(hal, 7, 17, 22, RADIOLIB_NC);
// the entry point for the program
int main(int argc, char** argv) {
int state = RADIOLIB_ERR_UNKNOWN;
state = radio.begin();
printf("[SX1261] Test:begin() = %d\n", state);
RADIOLIB_TEST_ASSERT(state);
state = radio.transmit("Hello World!");
printf("[SX1261] Test:transmit() = %d\n", state);
RADIOLIB_TEST_ASSERT(state);
hal->term();
return(0);
}

View File

@@ -0,0 +1,13 @@
#!/bin/bash
board=$1
sketch=$2
flags=$3
warnings="all"
arduino-cli compile \
--libraries ../../../../ \
--fqbn $board \
--build-property compiler.cpp.extra_flags="$flags" \
--warnings=$warnings \
$sketch --export-binaries

View File

@@ -0,0 +1,41 @@
#!/bin/bash
#board=arduino:avr:mega
board="$1"
#skip="(STM32WL|LR11x0_Firmware_Update|NonArduino)"
skip="$2"
#options=""
options="$3"
# file for saving the compiled binary size reports
size_file="size_$board.txt"
rm -f $size_file
path="../../../examples"
for example in $(find $path -name '*.ino' | sort); do
# check whether to skip this sketch
if [ ! -z '$skip' ] && [[ ${example} =~ ${skip} ]]; then
# skip sketch
echo -e "\n\033[1;33mSkipped ${example##*/} (matched with $skip)\033[0m";
else
# apply special flags for LoRaWAN
if [[ ${example} =~ "LoRaWAN" ]]; then
flags="-DRADIOLIB_LORAWAN_DEV_ADDR=0 -DRADIOLIB_LORAWAN_FNWKSINT_KEY=0 -DRADIOLIB_LORAWAN_SNWKSINT_KEY=0 -DRADIOLIB_LORAWAN_NWKSENC_KEY=0 -DRADIOLIB_LORAWAN_APPS_KEY=0 -DRADIOLIB_LORAWAN_APP_KEY=0 -DRADIOLIB_LORAWAN_NWK_KEY=0 -DRADIOLIB_LORAWAN_DEV_EUI=0 -DARDUINO_TTGO_LORA32_V1"
fi
# build sketch
echo -e "\n\033[1;33mBuilding ${example##*/} ... \033[0m";
board_opts=$board$options
./build_arduino.sh $board_opts $example "$flags"
if [ $? -ne 0 ]; then
echo -e "\033[1;31m${example##*/} build FAILED\033[0m\n";
exit 1;
else
echo -e "\033[1;32m${example##*/} build PASSED\033[0m\n";
dir="$(dirname -- "$example")"
file="$(basename -- "$example")"
size="$(size $dir/build/*/$file.elf)"
echo $size >> $size_file
fi
fi
done

View File

@@ -0,0 +1,24 @@
#!/bin/bash
board=$1
hash=$(git rev-parse --short HEAD)
in_file="size_$board.txt"
out_file="size_${hash}_${board//:/-}.csv"
rm -f $out_file
# write the header
echo "text,data,bss,dec,hex,filename" > "$out_file"
# convert to CSV
awk 'NR > 1 {
split($12, path_parts, "/");
filename_with_ext = path_parts[length(path_parts)];
split(filename_with_ext, filename_parts, ".");
filename = filename_parts[1];
print $7 "," $8 "," $9 "," $10 "," $11 "," filename
}' "$in_file" >> "$out_file"
# remove input file
rm -f $in_file

View File

@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.13)
project(radiolib-unittest)
# add RadioLib sources
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../../../../RadioLib" "${CMAKE_CURRENT_BINARY_DIR}/RadioLib")
# add test sources
file(GLOB_RECURSE TEST_SOURCES
"tests/main.cpp"
"tests/TestModule.cpp"
)
# create the executable
add_executable(${PROJECT_NAME} ${TEST_SOURCES})
# include directories
target_include_directories(${PROJECT_NAME} PUBLIC include)
# link RadioLib
target_link_libraries(${PROJECT_NAME} RadioLib fmt)
# set target properties and options
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra)
# set RadioLib debug
#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_BASIC RADIOLIB_DEBUG_SPI)
#target_compile_definitions(RadioLib PUBLIC RADIOLIB_DEBUG_PORT=stdout)

View File

@@ -0,0 +1,71 @@
#ifndef HARDWARE_EMULATION_HPP
#define HARDWARE_EMULATION_HPP
#include <stdint.h>
// value that is returned by the emualted radio class when performing SPI transfer to it
#define EMULATED_RADIO_SPI_RETURN (0xFF)
// pin indexes
#define EMULATED_RADIO_NSS_PIN (1)
#define EMULATED_RADIO_IRQ_PIN (2)
#define EMULATED_RADIO_RST_PIN (3)
#define EMULATED_RADIO_GPIO_PIN (4)
enum PinFunction_t {
PIN_UNASSIGNED = 0,
PIN_CS,
PIN_IRQ,
PIN_RST,
PIN_GPIO,
};
// structure for emulating GPIO pins
struct EmulatedPin_t {
uint32_t mode;
uint32_t value;
bool event;
PinFunction_t func;
};
// structure for emulating SPI registers
struct EmulatedRegister_t {
uint8_t value;
uint8_t readOnlyBitFlags;
bool bufferAccess;
};
// base class for emulated radio modules (SX126x etc.)
class EmulatedRadio {
public:
void connect(EmulatedPin_t* csPin, EmulatedPin_t* irqPin, EmulatedPin_t* rstPin, EmulatedPin_t* gpioPin) {
this->cs = csPin;
this->cs->func = PIN_CS;
this->irq = irqPin;
this->irq->func = PIN_IRQ;
this->rst = rstPin;
this->rst->func = PIN_RST;
this->gpio = gpioPin;
this->gpio->func = PIN_GPIO;
}
virtual uint8_t HandleSPI(uint8_t b) {
(void)b;
// handle the SPI input and generate output here
return(EMULATED_RADIO_SPI_RETURN);
}
virtual void HandleGPIO() {
// handle discrete GPIO signals here (e.g. reset state machine on NSS falling edge)
}
protected:
// pointers to emulated GPIO pins
// this is done via pointers so that the same GPIO entity is shared, like with a real hardware
EmulatedPin_t* cs;
EmulatedPin_t* irq;
EmulatedPin_t* rst;
EmulatedPin_t* gpio;
};
#endif

View File

@@ -0,0 +1,237 @@
#ifndef TEST_HAL_HPP
#define TEST_HAL_HPP
#include <chrono>
#include <thread>
#include <fmt/format.h>
#include <RadioLib.h>
#include <boost/log/trivial.hpp>
#include <boost/format.hpp>
#if defined(TEST_HAL_LOG)
#define HAL_LOG(...) BOOST_TEST_MESSAGE(__VA_ARGS__)
#else
#define HAL_LOG(...) {}
#endif
#include "HardwareEmulation.hpp"
#define TEST_HAL_INPUT (0)
#define TEST_HAL_OUTPUT (1)
#define TEST_HAL_LOW (0)
#define TEST_HAL_HIGH (1)
#define TEST_HAL_RISING (0)
#define TEST_HAL_FALLING (1)
// number of emulated GPIO pins
#define TEST_HAL_NUM_GPIO_PINS (32)
#define TEST_HAL_SPI_LOG_LENGTH (512)
class TestHal : public RadioLibHal {
public:
TestHal() : RadioLibHal(TEST_HAL_INPUT, TEST_HAL_OUTPUT, TEST_HAL_LOW, TEST_HAL_HIGH, TEST_HAL_RISING, TEST_HAL_FALLING) { }
void init() override {
HAL_LOG("TestHal::init()");
// save program start timestamp
start = std::chrono::high_resolution_clock::now();
// init emulated GPIO
for(int i = 0; i < TEST_HAL_NUM_GPIO_PINS; i++) {
this->gpio[i].mode = 0;
this->gpio[i].value = 0;
this->gpio[i].event = false;
this->gpio[i].func = PIN_UNASSIGNED;
}
}
void term() override {
HAL_LOG("TestHal::term()");
}
void pinMode(uint32_t pin, uint32_t mode) override {
HAL_LOG("TestHal::pinMode(pin=" << pin << ", mode=" << mode << " [" << ((mode == TEST_HAL_INPUT) ? "INPUT" : "OUTPUT") << "])");
// check the range
BOOST_ASSERT_MSG(pin < TEST_HAL_NUM_GPIO_PINS, "Pin number out of range");
// check known modes
BOOST_ASSERT_MSG(((mode == TEST_HAL_INPUT) || (mode == TEST_HAL_OUTPUT)), "Invalid pin mode");
// set mode
this->gpio[pin].mode = mode;
}
void digitalWrite(uint32_t pin, uint32_t value) override {
HAL_LOG("TestHal::digitalWrite(pin=" << pin << ", value=" << value << " [" << ((value == TEST_HAL_LOW) ? "LOW" : "HIGH") << "])");
// check the range
BOOST_ASSERT_MSG(pin < TEST_HAL_NUM_GPIO_PINS, "Pin number out of range");
// check it is output
BOOST_ASSERT_MSG(this->gpio[pin].mode == TEST_HAL_OUTPUT, "GPIO is not output!");
// check known values
BOOST_ASSERT_MSG(((value == TEST_HAL_LOW) || (value == TEST_HAL_HIGH)), "Invalid output value");
// set value
this->gpio[pin].value = value;
this->gpio[pin].event = true;
if(radio) {
this->radio->HandleGPIO();
}
this->gpio[pin].event = false;
}
uint32_t digitalRead(uint32_t pin) override {
HAL_LOG("TestHal::digitalRead(pin=" << pin << ")");
// check the range
BOOST_ASSERT_MSG(pin < TEST_HAL_NUM_GPIO_PINS, "Pin number out of range");
// check it is input
BOOST_ASSERT_MSG(this->gpio[pin].mode == TEST_HAL_INPUT, "GPIO is not input");
// read the value
uint32_t value = this->gpio[pin].value;
HAL_LOG("TestHal::digitalRead(pin=" << pin << ")=" << value << " [" << ((value == TEST_HAL_LOW) ? "LOW" : "HIGH") << "]");
return(value);
}
void attachInterrupt(uint32_t interruptNum, void (*interruptCb)(void), uint32_t mode) override {
HAL_LOG("TestHal::attachInterrupt(interruptNum=" << interruptNum << ", interruptCb=" << interruptCb << ", mode=" << mode << ")");
}
void detachInterrupt(uint32_t interruptNum) override {
HAL_LOG("TestHal::detachInterrupt(interruptNum=" << interruptNum << ")");
}
void delay(unsigned long ms) override {
HAL_LOG("TestHal::delay(ms=" << ms << ")");
const auto start = std::chrono::high_resolution_clock::now();
// sleep_for is sufficient for ms-precision sleep
std::this_thread::sleep_for(std::chrono::duration<unsigned long, std::milli>(ms));
// measure and print
const auto end = std::chrono::high_resolution_clock::now();
const std::chrono::duration<double, std::milli> elapsed = end - start;
HAL_LOG("TestHal::delay(ms=" << ms << ")=" << elapsed.count() << "ms");
}
void delayMicroseconds(unsigned long us) override {
HAL_LOG("TestHal::delayMicroseconds(us=" << us << ")");
const auto start = std::chrono::high_resolution_clock::now();
// busy wait is needed for microseconds precision
const auto len = std::chrono::microseconds(us);
while(std::chrono::high_resolution_clock::now() - start < len);
// measure and print
const auto end = std::chrono::high_resolution_clock::now();
const std::chrono::duration<double, std::micro> elapsed = end - start;
HAL_LOG("TestHal::delayMicroseconds(us=" << us << ")=" << elapsed.count() << "us");
}
void yield() override {
HAL_LOG("TestHal::yield()");
}
unsigned long millis() override {
HAL_LOG("TestHal::millis()");
std::chrono::time_point now = std::chrono::high_resolution_clock::now();
auto res = std::chrono::duration_cast<std::chrono::milliseconds>(now - this->start);
HAL_LOG("TestHal::millis()=" << res.count());
return(res.count());
}
unsigned long micros() override {
HAL_LOG("TestHal::micros()");
std::chrono::time_point now = std::chrono::high_resolution_clock::now();
auto res = std::chrono::duration_cast<std::chrono::microseconds>(now - this->start);
HAL_LOG("TestHal::micros()=" << res.count());
return(res.count());
}
long pulseIn(uint32_t pin, uint32_t state, unsigned long timeout) override {
HAL_LOG("TestHal::pulseIn(pin=" << pin << ", state=" << state << ", timeout=" << timeout << ")");
return(0);
}
void spiBegin() {
HAL_LOG("TestHal::spiBegin()");
}
void spiBeginTransaction() {
HAL_LOG("TestHal::spiBeginTransaction()");
// wipe history log
memset(this->spiLog, 0x00, TEST_HAL_SPI_LOG_LENGTH);
this->spiLogPtr = this->spiLog;
}
void spiTransfer(uint8_t* out, size_t len, uint8_t* in) {
HAL_LOG("TestHal::spiTransfer(len=" << len << ")");
for(size_t i = 0; i < len; i++) {
// append to log
(*this->spiLogPtr++) = out[i];
// process the SPI byte
in[i] = this->radio->HandleSPI(out[i]);
// outpu debug
HAL_LOG(fmt::format("out={:#02x}, in={:#02x}", out[i], in[i]));
}
}
void spiEndTransaction() {
HAL_LOG("TestHal::spiEndTransaction()");
}
void spiEnd() {
HAL_LOG("TestHal::spiEnd()");
}
void tone(uint32_t pin, unsigned int frequency, unsigned long duration = 0) {
HAL_LOG("TestHal::tone(pin=" << pin << ", frequency=" << frequency << ", duration=" << duration << ")");
}
void noTone(uint32_t pin) {
HAL_LOG("TestHal::noTone(pin=" << pin << ")");
}
// method to compare buffer to the internal SPI log, for verifying SPI transactions
int spiLogMemcmp(const void* in, size_t n) {
return(memcmp(this->spiLog, in, n));
}
// method that "connects" the emualted radio hardware to this HAL
void connectRadio(EmulatedRadio* r) {
this->radio = r;
this->radio->connect(&this->gpio[EMULATED_RADIO_NSS_PIN],
&this->gpio[EMULATED_RADIO_IRQ_PIN],
&this->gpio[EMULATED_RADIO_RST_PIN],
&this->gpio[EMULATED_RADIO_GPIO_PIN]);
}
private:
// array of emulated GPIO pins
EmulatedPin_t gpio[TEST_HAL_NUM_GPIO_PINS];
// start time point
std::chrono::time_point<std::chrono::high_resolution_clock> start;
// emulated radio hardware
EmulatedRadio* radio;
// SPI history log
uint8_t spiLog[TEST_HAL_SPI_LOG_LENGTH];
uint8_t* spiLogPtr;
};
#endif

View File

@@ -0,0 +1,13 @@
#!/bin/bash
set -e
# build the test binary
mkdir -p build
cd build
cmake -G "CodeBlocks - Unix Makefiles" ..
make -j4
# run it
cd ..
./build/radiolib-unittest --log_level=message

View File

@@ -0,0 +1,103 @@
// boost test header
#include <boost/test/unit_test.hpp>
// mock HAL
#include "TestHal.hpp"
// testing fixture
struct ModuleFixture {
TestHal* hal = nullptr;
Module* mod = nullptr;
EmulatedRadio* radioHardware = nullptr;
ModuleFixture() {
BOOST_TEST_MESSAGE("--- Module fixture setup ---");
hal = new TestHal();
radioHardware = new EmulatedRadio();
hal->connectRadio(radioHardware);
mod = new Module(hal, EMULATED_RADIO_NSS_PIN, EMULATED_RADIO_IRQ_PIN, EMULATED_RADIO_RST_PIN, EMULATED_RADIO_GPIO_PIN);
mod->init();
}
~ModuleFixture() {
BOOST_TEST_MESSAGE("--- Module fixture teardown ---");
mod->term();
delete[] mod;
delete[] hal;
}
};
BOOST_FIXTURE_TEST_SUITE(suite_Module, ModuleFixture)
BOOST_FIXTURE_TEST_CASE(Module_SPIgetRegValue_reg, ModuleFixture)
{
BOOST_TEST_MESSAGE("--- Test Module::SPIgetRegValue register access ---");
int16_t ret;
// basic register read with default config
const uint8_t address = 0x12;
const uint8_t spiTxn[] = { address, 0x00 };
ret = mod->SPIgetRegValue(address);
// check return code, value and history log
BOOST_TEST(ret >= RADIOLIB_ERR_NONE);
BOOST_TEST(ret == EMULATED_RADIO_SPI_RETURN);
BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
// register read masking test
const uint8_t msb = 5;
const uint8_t lsb = 1;
ret = mod->SPIgetRegValue(address, msb, lsb);
BOOST_TEST(ret == 0x3E);
// invalid mask tests (swapped MSB and LSB, out of range bit masks)
ret = mod->SPIgetRegValue(address, lsb, msb);
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
ret = mod->SPIgetRegValue(address, 10, lsb);
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
ret = mod->SPIgetRegValue(address, msb, 10);
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
}
BOOST_FIXTURE_TEST_CASE(Module_SPIgetRegValue_stream, ModuleFixture)
{
BOOST_TEST_MESSAGE("--- Test Module::SPIgetRegValue stream access ---");
int16_t ret;
// change settings to stream type
mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_ADDR] = Module::BITS_16;
mod->spiConfig.widths[RADIOLIB_MODULE_SPI_WIDTH_CMD] = Module::BITS_8;
mod->spiConfig.statusPos = 1;
mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_READ] = RADIOLIB_SX126X_CMD_READ_REGISTER;
mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_WRITE] = RADIOLIB_SX126X_CMD_WRITE_REGISTER;
mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_NOP] = RADIOLIB_SX126X_CMD_NOP;
mod->spiConfig.cmds[RADIOLIB_MODULE_SPI_COMMAND_STATUS] = RADIOLIB_SX126X_CMD_GET_STATUS;
mod->spiConfig.stream = true;
// basic register read
const uint8_t address = 0x12;
const uint8_t spiTxn[] = { RADIOLIB_SX126X_CMD_READ_REGISTER, 0x00, address, 0x00, 0x00 };
ret = mod->SPIgetRegValue(address);
// check return code, value and history log
BOOST_TEST(ret >= RADIOLIB_ERR_NONE);
BOOST_TEST(ret == EMULATED_RADIO_SPI_RETURN);
BOOST_TEST(hal->spiLogMemcmp(spiTxn, sizeof(spiTxn)) == 0);
// register read masking test
const uint8_t msb = 5;
const uint8_t lsb = 1;
ret = mod->SPIgetRegValue(address, msb, lsb);
BOOST_TEST(ret == 0x3E);
// invalid mask tests (swapped MSB and LSB, out of range bit masks)
ret = mod->SPIgetRegValue(address, lsb, msb);
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
ret = mod->SPIgetRegValue(address, 10, lsb);
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
ret = mod->SPIgetRegValue(address, msb, 10);
BOOST_TEST(ret == RADIOLIB_ERR_INVALID_BIT_RANGE);
}
BOOST_AUTO_TEST_SUITE_END()

View File

@@ -0,0 +1,5 @@
#define BOOST_TEST_MODULE "RadioLib Unit test"
#include <boost/test/included/unit_test.hpp>
// intentionally left blank, boost.test creates its own entrypoint