111 lines
3.5 KiB
C++
111 lines
3.5 KiB
C++
#include <cstdio>
|
|
#include <csignal>
|
|
#include <cstring>
|
|
|
|
#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;
|
|
}
|