// lora_tx.cpp — LR1121 transmit test // Usage: sudo ./lora_tx [-v] [--433|--868|--24|freq_hz] [--lp|--hp] [--dbm=N] // [--busy-gpio=N] [--reset-gpio=N] [--dio9-gpio=N] // -v verbose step labels (shows exactly where init hangs) // --433 433.05 MHz (default) // --868 868 MHz // --24 2403 MHz // freq_hz any raw frequency in Hz // // Requires SPI: sudo raspi-config → Interfaces → SPI → Yes → reboot #include #include #include #include #include #include "lr1121_malnus.hpp" int main(int argc, char **argv) { lr1121::Config cfg; cfg.verbose = false; cfg.pa_sel = 0x00; // LP default: avoids LBD on weak VBAT rails cfg.tx_dbm = 10; cfg.sf = 0x07; // SF7 cfg.bw = 0x04; // 125 kHz cfg.cr = 0x01; // CR 4/5 for (int i = 1; i < argc; ++i) { if (std::strcmp(argv[i], "-v") == 0) cfg.verbose = true; else if (std::strcmp(argv[i], "--433") == 0) cfg.freq_hz = lr1121::FREQ_433; else if (std::strcmp(argv[i], "--868") == 0) cfg.freq_hz = lr1121::FREQ_868; else if (std::strcmp(argv[i], "--24") == 0 || std::strcmp(argv[i], "--2g4") == 0) cfg.freq_hz = lr1121::FREQ_2400; else if (std::strcmp(argv[i], "--hp") == 0) cfg.pa_sel = 0x01; else if (std::strcmp(argv[i], "--lp") == 0) cfg.pa_sel = 0x00; else if (std::strncmp(argv[i], "--dbm=", 6) == 0) cfg.tx_dbm = (int8_t)std::atoi(argv[i] + 6); else if (std::strncmp(argv[i], "--busy-gpio=", 12) == 0) cfg.busy_gpio = (unsigned)std::strtoul(argv[i] + 12, nullptr, 10); else if (std::strncmp(argv[i], "--reset-gpio=", 13) == 0) cfg.reset_gpio = (unsigned)std::strtoul(argv[i] + 13, nullptr, 10); else if (std::strncmp(argv[i], "--dio9-gpio=", 12) == 0) cfg.dio9_gpio = (unsigned)std::strtoul(argv[i] + 12, nullptr, 10); else cfg.freq_hz = (uint32_t)std::strtoul(argv[i], nullptr, 10); } std::printf("lora_tx: %u Hz SF%u BW=0x%02X PA=%s PWR=%d dBm gpio(busy=%u reset=%u dio9=%u)%s\n", cfg.freq_hz, cfg.sf, cfg.bw, cfg.pa_sel ? "HP" : "LP", (int)cfg.tx_dbm, cfg.busy_gpio, cfg.reset_gpio, cfg.dio9_gpio, cfg.verbose ? " [verbose]" : ""); lr1121::Radio radio; if (!radio.begin(cfg)) { std::fprintf(stderr, "ERROR: radio init failed\n" " Check: SPI enabled? wiring? DIO5/DIO6 connected?\n" " If fw looks like bootloader: sudo ./lora_rx --reset\n" " Run with -v for step-by-step output\n"); return 1; } auto ver = radio.getVersion(); if (ver.fw_hi < 0x02) std::fprintf(stderr, "hint: fw=0x%02X%02X — try: sudo ./lora_rx --reset\n", ver.fw_hi, ver.fw_lo); std::printf("Radio OK — sending every second\n"); for (int n = 0; ; ++n) { char msg[32]; int len = std::snprintf(msg, sizeof(msg), "hello %d", n); bool ok = radio.send((const uint8_t *)msg, (uint8_t)len); std::printf("[%4d] tx '%s' → %s\n", n, msg, ok ? "OK" : "TIMEOUT"); std::this_thread::sleep_for(std::chrono::seconds(1)); } radio.end(); return 0; }