#include #include #include #include "lr1121_malnus.hpp" static volatile std::sig_atomic_t g_stop = 0; static void onSignal(int) { g_stop = 1; } static void applyPaPreset(lr1121::Config &cfg, bool hp_mode) { cfg.pa_sel = hp_mode ? lr1121::PA_HP : lr1121::PA_LP; cfg.tx_dbm = hp_mode ? 14 : 8; } static bool parseArgs(int argc, char **argv, bool &verbose, bool &do_reset, bool &hp_mode) { for (int i = 1; i < argc; ++i) { if (std::strcmp(argv[i], "-v") == 0) verbose = true; else if (std::strcmp(argv[i], "--reset") == 0) do_reset = true; else if (std::strcmp(argv[i], "--hp") == 0) hp_mode = true; else if (std::strcmp(argv[i], "--lp") == 0) hp_mode = false; else { std::fprintf(stderr, "Unknown option: %s\n" "Usage: sudo ./lora_rx [-v] [--reset] [--lp|--hp]\n", argv[i]); return false; } } return true; } int main(int argc, char **argv) { std::signal(SIGINT, onSignal); std::signal(SIGTERM, onSignal); lr1121::Config cfg; constexpr uint32_t rx_timeout_ms = 1000; bool verbose = false; bool do_reset = false; bool hp_mode = false; if (!parseArgs(argc, argv, verbose, do_reset, hp_mode)) return 2; applyPaPreset(cfg, hp_mode); std::printf("RX %u Hz, tmo=%ums, gpio(busy=%u reset=%u dio9=%u)%s\n", cfg.freq_hz, rx_timeout_ms, cfg.busy_gpio, cfg.reset_gpio, cfg.dio9_gpio, verbose ? " [v]" : ""); lr1121::Radio radio; if (!radio.begin(cfg)) { std::fprintf(stderr, "ERROR: radio init failed: %s\n", lr1121::Radio::errorString(radio.lastError())); return 1; } if (verbose) { const auto v = radio.chipVersion(); std::printf("[lr1121] hw=0x%02X type=0x%02X fw=0x%02X%02X vbat=%.2fV\n", v.hw, v.type, v.fw_hi, v.fw_lo, radio.vbatVolts()); } if (do_reset) { std::puts("Applying soft settings reset..."); if (!radio.softResetSettings()) { std::fprintf(stderr, "ERROR: soft settings reset failed: %s\n", lr1121::Radio::errorString(radio.lastError())); return 1; } } if (!radio.startListening()) { std::fprintf(stderr, "ERROR: start listening failed: %s\n", lr1121::Radio::errorString(radio.lastError())); return 1; } std::puts("Radio OK - listening (continuous RX). Press Ctrl+C to stop."); uint8_t buf[256]; int pkt = 0; uint32_t timeout_total = 0; uint32_t crc_total = 0; while (!g_stop) { lr1121::RxInfo info{}; const int r = radio.receive(buf, uint8_t(sizeof(buf) - 1), rx_timeout_ms, &info); if (r > 0) { buf[r] = '\0'; std::printf("[%04d] %3d B rssi=%4d snr=%3d '%s'\n", ++pkt, r, info.rssi_dbm, info.snr_db, buf); } else if (r == -2) { std::printf("crc error x%u\n", ++crc_total); } else if (radio.lastError() == lr1121::Error::RxTimeout) { ++timeout_total; if ((timeout_total % 10u) == 0u) std::printf("timeout x%u\n", timeout_total); } else { std::printf("rx error: %s\n", lr1121::Radio::errorString(radio.lastError())); } } std::puts("\nStopping listener..."); radio.stopListening(); radio.end(); std::puts("Radio OK - stopped listening..."); return 0; }