ai debloat

This commit is contained in:
shinya 2026-05-29 09:29:57 +02:00
parent aaea30e762
commit d9b666e0f4
3 changed files with 88 additions and 28 deletions

View File

@ -1,12 +1,20 @@
#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 : 10;
cfg.tx_dbm = hp_mode ? 14 : 8;
}
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)
{
std::signal(SIGINT, onSignal);
std::signal(SIGTERM, onSignal);
lr1121::Config cfg;
constexpr uint32_t rx_timeout_ms = 1000;
bool verbose = false;
@ -60,17 +71,21 @@ int main(int argc, char **argv)
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];
int pkt = 0;
uint32_t timeout_total = 0;
uint32_t crc_total = 0;
for (;;) {
while (!g_stop) {
lr1121::RxInfo info{};
const int r = radio.receive(buf, uint8_t(sizeof(buf) - 1),
rx_timeout_ms, &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",
@ -86,4 +101,10 @@ int main(int argc, char **argv)
lr1121::Radio::errorString(radio.lastError()));
}
}
std::puts("\nStopping listener...");
radio.stopListening();
radio.end();
std::puts("Radio OK - stopped listening...");
return 0;
}

View File

@ -8,7 +8,7 @@
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 : 10;
cfg.tx_dbm = hp_mode ? 14 : 8;
}
static bool parseArgs(int argc, char **argv, bool &verbose, bool &do_reset, bool &hp_mode)

View File

@ -112,10 +112,17 @@ public:
// Returns true on TX_DONE, false otherwise; check lastError() for reason.
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.
int receive(uint8_t *buf, uint8_t cap, uint32_t timeout_ms,
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
// standby_xosc after begin()/send()/receive()).
bool setFrequency(uint32_t hz);
@ -126,7 +133,7 @@ public:
ChipVersion chipVersion();
uint16_t chipErrors();
uint8_t vbatRaw();
float vbatVolts() { return vbatRaw() / 34.0f; }
float vbatVolts() { return vbatRaw() / 56.4f; }
const Config &config() const { return cfg_; }
Error lastError() const { return last_err_; }
static const char *errorString(Error e);
@ -135,7 +142,8 @@ public:
private:
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;
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;
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; }
else if (mhz < 740) { lo = 470; hi = 510; }
else if (mhz < 890) { lo = 860; hi = 876; }
else if (mhz < 2000) { lo = 902; hi = 928; }
else { lo = 2400; hi = 2500; }
else { lo = 902; hi = 928; }
f1 = uint8_t(lo / 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);
}
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,
RxInfo *rx_info)
{
if (!setStandbyXosc()) return -1;
if (!clearIrq()) return -1;
const uint32_t mask = IRQ_RX_DONE | IRQ_CRC_ERR | IRQ_TIMEOUT;
if (!setIrqMask(mask, mask)) return -1;
const uint32_t steps = timeoutMsToRtcSteps(timeout_ms);
if (!wcmd(OC_SET_RX, {
uint8_t(steps >> 16),
uint8_t(steps >> 8),
uint8_t(steps),
})) return -1;
if (!listening_) {
// one-shot: arm the chip, it will time out on its own
if (!setStandbyXosc()) return -1;
if (!clearIrq()) return -1;
const uint32_t mask = IRQ_RX_DONE | IRQ_CRC_ERR | IRQ_TIMEOUT;
if (!setIrqMask(mask, mask)) return -1;
const uint32_t steps = timeoutMsToRtcSteps(timeout_ms);
if (!wcmd(OC_SET_RX, {
uint8_t(steps >> 16),
uint8_t(steps >> 8),
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() +
std::chrono::milliseconds(timeout_ms == 0 ? 60000 : timeout_ms + 500);
std::chrono::milliseconds(poll_ms);
for (;;) {
if (std::chrono::steady_clock::now() >= deadline) {
(void)clearIrq();
(void)setIrqMask(0, 0);
if (has_deadline && std::chrono::steady_clock::now() >= deadline) {
if (!listening_) { (void)clearIrq(); (void)setIrqMask(0, 0); }
last_err_ = Error::RxTimeout;
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();
if (irq & IRQ_TIMEOUT) {
(void)clearIrq();
(void)setIrqMask(0, 0);
if (!listening_) { (void)clearIrq(); (void)setIrqMask(0, 0); }
last_err_ = Error::RxTimeout;
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)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; }
last_err_ = Error::Ok;
return int(len);