C++17 drivers for HopeRF RFM69 (SX1231/H) and RFM95/96/97/98 (SX127x) transceiver modules, designed for embedded systems and MCUs.
- Hardware abstraction layer: Portable interface for SPI, GPIO, and timing
- Zero dependencies: Standard library only (C++17)
- MCU-friendly: Works on ARM Cortex-M0/M4/M7 and Unix-like systems
- Comprehensive drivers: Full support for RFM69 (FSK/GFSK/OOK) and RFM95 (LoRa)
- Test suite: Unit tests and hardware integration tests
- RFM69HCW (SX1231/H): FSK, GFSK, and OOK modulation
- RFM95/96/97/98 (SX1276/77/78/79): LoRa modulation
- Implement the HAL interfaces (
SpiDevice,DigitalOutPin,Timing) for your platform - Include the driver headers and link against the library:
#include "radio/rfm95.hpp"
// Your platform-specific HAL implementations
MySpiDevice spi;
MyDigitalOutPin csPin;
MyTiming timing;
MyDigitalOutPin resetPin;
// Configure the radio
radio::Rfm95::RadioConfig cfg{};
cfg.frequencyHz = 915000000;
cfg.modem.bandwidth = radio::Rfm95::Bandwidth::Bw125k;
cfg.modem.spreadingFactor = 7;
cfg.modem.codingRate = radio::Rfm95::CodingRate::Cr4_5;
cfg.power.powerDbm = 17;
// Initialize and use
radio::Rfm95 radio(spi, csPin, timing, &resetPin);
radio.initialize(cfg);
// Send/receive packets
std::uint8_t payload[] = {0x01, 0x02, 0x03};
radio.send(payload, sizeof(payload), std::chrono::milliseconds(1000));
std::uint8_t buffer[255];
std::size_t length;
std::int16_t rssi;
if (radio.receive(buffer, sizeof(buffer), length,
std::chrono::milliseconds(5000), &rssi)) {
// Process received packet
}The drivers use a minimal HAL interface defined in radio/hal.hpp:
SpiDevice: Full-duplex SPI transfersDigitalOutPin: Digital output pins (chip-select, reset)DigitalInPin: Optional digital input pins (for DIO interrupts)Timing: Monotonic delays and timestamps (milliseconds)
Implement these interfaces using your platform SDK (CMSIS, Zephyr, Arduino, Linux spidev/sysfs, etc.).
The radio::Rfm69 class provides:
- Modulation modes: FSK, GFSK (BT 1.0/0.5/0.3), OOK
- Configurable parameters: Frequency, bitrate, deviation, RX/AFC bandwidth, sync word, packet settings, PA configuration
- Packet engine: Variable or fixed-length packets, CRC, AES encryption, address filtering
- Power control: Configurable output power up to +20 dBm (with PA boost)
See docs/radio_drivers.md for detailed API documentation.
The radio::Rfm95 class provides:
- LoRa modulation: Bandwidth (7.8 kHz - 500 kHz), spreading factor (SF6-SF12), coding rate
- Modem configuration: CRC, IQ inversion, symbol timeout, preamble length, sync word
- Power control: Configurable output power up to +20 dBm
- RSSI and SNR: Automatic signal quality reporting
See docs/radio_drivers.md for detailed API documentation.
cmake -S . -B build
cmake --build build -j$(nproc)make buildRun the test suite:
cd build
ctest --output-on-failureOr run individual tests:
./build/rfm69_modulation_tests
./build/radio_hardware_tests # Requires physical hardwareThe radio_hardware_tests require physical RFM69/RFM95 modules connected via SPI and GPIO. Set environment variables to configure the test:
export RADIO_HW_RFM69_A_SPI=/dev/spidev0.0
export RADIO_HW_RFM69_A_CS=/sys/class/gpio/gpio25
export RADIO_HW_RFM69_A_RESET=/sys/class/gpio/gpio24
export RADIO_HW_RFM69_B_SPI=/dev/spidev0.1
export RADIO_HW_RFM69_B_CS=/sys/class/gpio/gpio27
export RADIO_HW_RFM69_B_RESET=/sys/class/gpio/gpio23
./build/radio_hardware_testsdocs/radio_drivers.md: Detailed driver documentation and API referenceRF_docs/: Datasheets for RFM69 and RFM95 modules
MIT License - see LICENSE file for details.