ai debloat
This commit is contained in:
parent
aaea30e762
commit
d9b666e0f4
@ -1,12 +1,20 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
#include <csignal>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "lr1121_malnus.hpp"
|
#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)
|
static void applyPaPreset(lr1121::Config &cfg, bool hp_mode)
|
||||||
{
|
{
|
||||||
cfg.pa_sel = hp_mode ? lr1121::PA_HP : lr1121::PA_LP;
|
cfg.pa_sel = hp_mode ? lr1121::PA_HP : lr1121::PA_LP;
|
||||||
cfg.tx_dbm = hp_mode ? 14 : 10;
|
cfg.tx_dbm = hp_mode ? 14 : 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parseArgs(int argc, char **argv, bool &verbose, bool &do_reset, bool &hp_mode)
|
static bool parseArgs(int argc, char **argv, bool &verbose, bool &do_reset, bool &hp_mode)
|
||||||
@ -27,6 +35,9 @@ static bool parseArgs(int argc, char **argv, bool &verbose, bool &do_reset, bool
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
std::signal(SIGINT, onSignal);
|
||||||
|
std::signal(SIGTERM, onSignal);
|
||||||
|
|
||||||
lr1121::Config cfg;
|
lr1121::Config cfg;
|
||||||
constexpr uint32_t rx_timeout_ms = 1000;
|
constexpr uint32_t rx_timeout_ms = 1000;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
@ -60,17 +71,21 @@ int main(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::puts("Radio OK - listening...");
|
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];
|
uint8_t buf[256];
|
||||||
int pkt = 0;
|
int pkt = 0;
|
||||||
uint32_t timeout_total = 0;
|
uint32_t timeout_total = 0;
|
||||||
uint32_t crc_total = 0;
|
uint32_t crc_total = 0;
|
||||||
|
|
||||||
for (;;) {
|
while (!g_stop) {
|
||||||
lr1121::RxInfo info{};
|
lr1121::RxInfo info{};
|
||||||
const int r = radio.receive(buf, uint8_t(sizeof(buf) - 1),
|
const int r = radio.receive(buf, uint8_t(sizeof(buf) - 1), rx_timeout_ms, &info);
|
||||||
rx_timeout_ms, &info);
|
|
||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
buf[r] = '\0';
|
buf[r] = '\0';
|
||||||
std::printf("[%04d] %3d B rssi=%4d snr=%3d '%s'\n",
|
std::printf("[%04d] %3d B rssi=%4d snr=%3d '%s'\n",
|
||||||
@ -86,4 +101,10 @@ int main(int argc, char **argv)
|
|||||||
lr1121::Radio::errorString(radio.lastError()));
|
lr1121::Radio::errorString(radio.lastError()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::puts("\nStopping listener...");
|
||||||
|
radio.stopListening();
|
||||||
|
radio.end();
|
||||||
|
std::puts("Radio OK - stopped listening...");
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
static void applyPaPreset(lr1121::Config &cfg, bool hp_mode)
|
static void applyPaPreset(lr1121::Config &cfg, bool hp_mode)
|
||||||
{
|
{
|
||||||
cfg.pa_sel = hp_mode ? lr1121::PA_HP : lr1121::PA_LP;
|
cfg.pa_sel = hp_mode ? lr1121::PA_HP : lr1121::PA_LP;
|
||||||
cfg.tx_dbm = hp_mode ? 14 : 10;
|
cfg.tx_dbm = hp_mode ? 14 : 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool parseArgs(int argc, char **argv, bool &verbose, bool &do_reset, bool &hp_mode)
|
static bool parseArgs(int argc, char **argv, bool &verbose, bool &do_reset, bool &hp_mode)
|
||||||
|
|||||||
@ -112,10 +112,17 @@ public:
|
|||||||
// Returns true on TX_DONE, false otherwise; check lastError() for reason.
|
// Returns true on TX_DONE, false otherwise; check lastError() for reason.
|
||||||
bool send(const uint8_t *data, uint8_t n);
|
bool send(const uint8_t *data, uint8_t n);
|
||||||
|
|
||||||
|
// One-shot RX: arm, wait timeout_ms, return to standby.
|
||||||
// Returns bytes received (>=0), -1 on timeout/error, -2 on CRC error.
|
// Returns bytes received (>=0), -1 on timeout/error, -2 on CRC error.
|
||||||
int receive(uint8_t *buf, uint8_t cap, uint32_t timeout_ms,
|
int receive(uint8_t *buf, uint8_t cap, uint32_t timeout_ms,
|
||||||
RxInfo *rx_info = nullptr);
|
RxInfo *rx_info = nullptr);
|
||||||
|
|
||||||
|
// Continuous RX: arm once, call receive() in a loop — chip stays in RX
|
||||||
|
// between packets. timeout_ms in receive() becomes a per-call poll window
|
||||||
|
// (0 = wait forever). Call stopListening() to return to standby.
|
||||||
|
bool startListening();
|
||||||
|
void stopListening();
|
||||||
|
|
||||||
// Runtime tuning. Call from standby (the driver leaves the chip in
|
// Runtime tuning. Call from standby (the driver leaves the chip in
|
||||||
// standby_xosc after begin()/send()/receive()).
|
// standby_xosc after begin()/send()/receive()).
|
||||||
bool setFrequency(uint32_t hz);
|
bool setFrequency(uint32_t hz);
|
||||||
@ -126,7 +133,7 @@ public:
|
|||||||
ChipVersion chipVersion();
|
ChipVersion chipVersion();
|
||||||
uint16_t chipErrors();
|
uint16_t chipErrors();
|
||||||
uint8_t vbatRaw();
|
uint8_t vbatRaw();
|
||||||
float vbatVolts() { return vbatRaw() / 34.0f; }
|
float vbatVolts() { return vbatRaw() / 56.4f; }
|
||||||
const Config &config() const { return cfg_; }
|
const Config &config() const { return cfg_; }
|
||||||
Error lastError() const { return last_err_; }
|
Error lastError() const { return last_err_; }
|
||||||
static const char *errorString(Error e);
|
static const char *errorString(Error e);
|
||||||
@ -135,7 +142,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Config cfg_{};
|
Config cfg_{};
|
||||||
int spi_fd_ = -1, busy_fd_ = -1, reset_fd_ = -1, dio9_fd_ = -1;
|
int spi_fd_ = -1, busy_fd_ = -1, reset_fd_ = -1, dio9_fd_ = -1;
|
||||||
|
bool listening_ = false;
|
||||||
Error last_err_ = Error::NotReady;
|
Error last_err_ = Error::NotReady;
|
||||||
|
|
||||||
bool fail(Error e) { last_err_ = e; return false; }
|
bool fail(Error e) { last_err_ = e; return false; }
|
||||||
@ -314,11 +322,12 @@ inline void Radio::imgCalFreqs(uint32_t hz, uint8_t &f1, uint8_t &f2)
|
|||||||
{
|
{
|
||||||
const uint32_t mhz = hz / 1'000'000u;
|
const uint32_t mhz = hz / 1'000'000u;
|
||||||
uint32_t lo, hi;
|
uint32_t lo, hi;
|
||||||
|
// 2.4 GHz values are hardcoded (lo/4 would overflow uint8_t).
|
||||||
|
if (mhz >= 2000) { f1 = 0xD7; f2 = 0xDB; return; }
|
||||||
if (mhz < 446) { lo = 430; hi = 440; }
|
if (mhz < 446) { lo = 430; hi = 440; }
|
||||||
else if (mhz < 740) { lo = 470; hi = 510; }
|
else if (mhz < 740) { lo = 470; hi = 510; }
|
||||||
else if (mhz < 890) { lo = 860; hi = 876; }
|
else if (mhz < 890) { lo = 860; hi = 876; }
|
||||||
else if (mhz < 2000) { lo = 902; hi = 928; }
|
else { lo = 902; hi = 928; }
|
||||||
else { lo = 2400; hi = 2500; }
|
|
||||||
f1 = uint8_t(lo / 4);
|
f1 = uint8_t(lo / 4);
|
||||||
f2 = uint8_t((hi + 3) / 4);
|
f2 = uint8_t((hi + 3) / 4);
|
||||||
}
|
}
|
||||||
@ -587,28 +596,53 @@ inline bool Radio::send(const uint8_t *data, uint8_t n)
|
|||||||
return fail(Error::TxLbd);
|
return fail(Error::TxLbd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool Radio::startListening()
|
||||||
|
{
|
||||||
|
if (!setStandbyXosc()) return false;
|
||||||
|
if (!clearIrq()) return false;
|
||||||
|
const uint32_t mask = IRQ_RX_DONE | IRQ_CRC_ERR;
|
||||||
|
if (!setIrqMask(mask, mask)) return false;
|
||||||
|
// 0xFFFFFF = continuous RX, no radio timeout
|
||||||
|
if (!wcmd(OC_SET_RX, {0xFF, 0xFF, 0xFF})) return false;
|
||||||
|
listening_ = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Radio::stopListening()
|
||||||
|
{
|
||||||
|
(void)setStandbyXosc();
|
||||||
|
(void)clearIrq();
|
||||||
|
(void)setIrqMask(0, 0);
|
||||||
|
listening_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
inline int Radio::receive(uint8_t *buf, uint8_t cap, uint32_t timeout_ms,
|
inline int Radio::receive(uint8_t *buf, uint8_t cap, uint32_t timeout_ms,
|
||||||
RxInfo *rx_info)
|
RxInfo *rx_info)
|
||||||
{
|
{
|
||||||
if (!setStandbyXosc()) return -1;
|
if (!listening_) {
|
||||||
if (!clearIrq()) return -1;
|
// one-shot: arm the chip, it will time out on its own
|
||||||
const uint32_t mask = IRQ_RX_DONE | IRQ_CRC_ERR | IRQ_TIMEOUT;
|
if (!setStandbyXosc()) return -1;
|
||||||
if (!setIrqMask(mask, mask)) return -1;
|
if (!clearIrq()) return -1;
|
||||||
|
const uint32_t mask = IRQ_RX_DONE | IRQ_CRC_ERR | IRQ_TIMEOUT;
|
||||||
const uint32_t steps = timeoutMsToRtcSteps(timeout_ms);
|
if (!setIrqMask(mask, mask)) return -1;
|
||||||
if (!wcmd(OC_SET_RX, {
|
const uint32_t steps = timeoutMsToRtcSteps(timeout_ms);
|
||||||
uint8_t(steps >> 16),
|
if (!wcmd(OC_SET_RX, {
|
||||||
uint8_t(steps >> 8),
|
uint8_t(steps >> 16),
|
||||||
uint8_t(steps),
|
uint8_t(steps >> 8),
|
||||||
})) return -1;
|
uint8_t(steps),
|
||||||
|
})) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// continuous: timeout_ms is a per-call poll window, 0 means wait forever
|
||||||
|
const uint32_t poll_ms = listening_ ? (timeout_ms == 0 ? 0 : timeout_ms)
|
||||||
|
: (timeout_ms == 0 ? 60000 : timeout_ms + 500);
|
||||||
|
const bool has_deadline = poll_ms > 0;
|
||||||
const auto deadline = std::chrono::steady_clock::now() +
|
const auto deadline = std::chrono::steady_clock::now() +
|
||||||
std::chrono::milliseconds(timeout_ms == 0 ? 60000 : timeout_ms + 500);
|
std::chrono::milliseconds(poll_ms);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (std::chrono::steady_clock::now() >= deadline) {
|
if (has_deadline && std::chrono::steady_clock::now() >= deadline) {
|
||||||
(void)clearIrq();
|
if (!listening_) { (void)clearIrq(); (void)setIrqMask(0, 0); }
|
||||||
(void)setIrqMask(0, 0);
|
|
||||||
last_err_ = Error::RxTimeout;
|
last_err_ = Error::RxTimeout;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -618,8 +652,7 @@ inline int Radio::receive(uint8_t *buf, uint8_t cap, uint32_t timeout_ms,
|
|||||||
}
|
}
|
||||||
const uint32_t irq = getIrq();
|
const uint32_t irq = getIrq();
|
||||||
if (irq & IRQ_TIMEOUT) {
|
if (irq & IRQ_TIMEOUT) {
|
||||||
(void)clearIrq();
|
if (!listening_) { (void)clearIrq(); (void)setIrqMask(0, 0); }
|
||||||
(void)setIrqMask(0, 0);
|
|
||||||
last_err_ = Error::RxTimeout;
|
last_err_ = Error::RxTimeout;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -645,7 +678,13 @@ inline int Radio::receive(uint8_t *buf, uint8_t cap, uint32_t timeout_ms,
|
|||||||
|
|
||||||
(void)wcmd(OC_CLEAR_RXBUF);
|
(void)wcmd(OC_CLEAR_RXBUF);
|
||||||
(void)clearIrq();
|
(void)clearIrq();
|
||||||
(void)setIrqMask(0, 0);
|
if (listening_) {
|
||||||
|
// re-arm IRQ mask but leave chip in RX
|
||||||
|
const uint32_t mask = IRQ_RX_DONE | IRQ_CRC_ERR;
|
||||||
|
(void)setIrqMask(mask, mask);
|
||||||
|
} else {
|
||||||
|
(void)setIrqMask(0, 0);
|
||||||
|
}
|
||||||
if (irq & IRQ_CRC_ERR) { last_err_ = Error::RxCrc; return -2; }
|
if (irq & IRQ_CRC_ERR) { last_err_ = Error::RxCrc; return -2; }
|
||||||
last_err_ = Error::Ok;
|
last_err_ = Error::Ok;
|
||||||
return int(len);
|
return int(len);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user