mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-03-30 14:55:46 +00:00
- Trigger noise floor calibration every 2s and AGC reset every 30s in main loop. - Reorder loop to match Dispatcher: calibrate + radio.loop() before AGC reset and recvRaw() so RSSI is never sampled right after startReceive(). - Update protocol doc with calibration intervals and typical noise floor range. - Variant platformio.ini updates (heltec_v3, rak4631).
133 lines
3.6 KiB
C++
133 lines
3.6 KiB
C++
#include <Arduino.h>
|
|
#include <target.h>
|
|
#include <helpers/ArduinoHelpers.h>
|
|
#include <helpers/IdentityStore.h>
|
|
#include "KissModem.h"
|
|
|
|
#if defined(NRF52_PLATFORM)
|
|
#include <InternalFileSystem.h>
|
|
#elif defined(RP2040_PLATFORM)
|
|
#include <LittleFS.h>
|
|
#elif defined(ESP32)
|
|
#include <SPIFFS.h>
|
|
#endif
|
|
|
|
#define NOISE_FLOOR_CALIB_INTERVAL_MS 2000 // match Dispatcher default
|
|
#define AGC_RESET_INTERVAL_MS 30000 // periodic RX restart so AGC doesn't drift (repeater uses same via prefs)
|
|
|
|
StdRNG rng;
|
|
mesh::LocalIdentity identity;
|
|
KissModem* modem;
|
|
static uint32_t next_noise_floor_calib_ms = 0;
|
|
static uint32_t next_agc_reset_ms = 0;
|
|
|
|
void halt() {
|
|
while (1) ;
|
|
}
|
|
|
|
void loadOrCreateIdentity() {
|
|
#if defined(NRF52_PLATFORM)
|
|
InternalFS.begin();
|
|
IdentityStore store(InternalFS, "");
|
|
#elif defined(ESP32)
|
|
SPIFFS.begin(true);
|
|
IdentityStore store(SPIFFS, "/identity");
|
|
#elif defined(RP2040_PLATFORM)
|
|
LittleFS.begin();
|
|
IdentityStore store(LittleFS, "/identity");
|
|
store.begin();
|
|
#else
|
|
#error "Filesystem not defined"
|
|
#endif
|
|
|
|
if (!store.load("_main", identity)) {
|
|
identity = radio_new_identity();
|
|
while (identity.pub_key[0] == 0x00 || identity.pub_key[0] == 0xFF) {
|
|
identity = radio_new_identity();
|
|
}
|
|
store.save("_main", identity);
|
|
}
|
|
}
|
|
|
|
void onSetRadio(float freq, float bw, uint8_t sf, uint8_t cr) {
|
|
radio_set_params(freq, bw, sf, cr);
|
|
}
|
|
|
|
void onSetTxPower(uint8_t power) {
|
|
radio_set_tx_power(power);
|
|
}
|
|
|
|
float onGetCurrentRssi() {
|
|
return radio_driver.getCurrentRSSI();
|
|
}
|
|
|
|
void onGetStats(uint32_t* rx, uint32_t* tx, uint32_t* errors) {
|
|
*rx = radio_driver.getPacketsRecv();
|
|
*tx = radio_driver.getPacketsSent();
|
|
*errors = radio_driver.getPacketsRecvErrors();
|
|
}
|
|
|
|
void setup() {
|
|
board.begin();
|
|
|
|
if (!radio_init()) {
|
|
halt();
|
|
}
|
|
|
|
radio_driver.begin();
|
|
|
|
rng.begin(radio_get_rng_seed());
|
|
loadOrCreateIdentity();
|
|
|
|
Serial.begin(115200);
|
|
uint32_t start = millis();
|
|
while (!Serial && millis() - start < 3000) delay(10);
|
|
delay(100);
|
|
|
|
sensors.begin();
|
|
|
|
modem = new KissModem(Serial, identity, rng, radio_driver, board, sensors);
|
|
modem->setRadioCallback(onSetRadio);
|
|
modem->setTxPowerCallback(onSetTxPower);
|
|
modem->setGetCurrentRssiCallback(onGetCurrentRssi);
|
|
modem->setGetStatsCallback(onGetStats);
|
|
modem->begin();
|
|
}
|
|
|
|
void loop() {
|
|
modem->loop();
|
|
|
|
uint8_t packet[KISS_MAX_PACKET_SIZE];
|
|
uint16_t len;
|
|
|
|
// Match Dispatcher order: noise floor calib + loop() first, so we never sample RSSI in the same
|
|
// iteration as startReceive() (AGC reset -> recvRaw below). Sampling right after startReceive()
|
|
// can yield settling/cold RSSI and drive the floor toward -120.
|
|
if ((uint32_t)(millis() - next_noise_floor_calib_ms) >= NOISE_FLOOR_CALIB_INTERVAL_MS) {
|
|
radio_driver.triggerNoiseFloorCalibrate(0); // 0 = no interference threshold (KISS has no prefs)
|
|
next_noise_floor_calib_ms = millis();
|
|
}
|
|
radio_driver.loop();
|
|
|
|
if (modem->getPacketToSend(packet, &len)) {
|
|
radio_driver.startSendRaw(packet, len);
|
|
while (!radio_driver.isSendComplete()) {
|
|
delay(1);
|
|
}
|
|
radio_driver.onSendFinished();
|
|
modem->onTxComplete(true);
|
|
}
|
|
|
|
if ((uint32_t)(millis() - next_agc_reset_ms) >= AGC_RESET_INTERVAL_MS) {
|
|
radio_driver.resetAGC(); // next recvRaw() will startReceive() and reset AGC so RSSI/noise floor don't stick at -120
|
|
next_agc_reset_ms = millis();
|
|
}
|
|
uint8_t rx_buf[256];
|
|
int rx_len = radio_driver.recvRaw(rx_buf, sizeof(rx_buf));
|
|
if (rx_len > 0) {
|
|
int8_t snr = (int8_t)(radio_driver.getLastSNR() * 4);
|
|
int8_t rssi = (int8_t)radio_driver.getLastRSSI();
|
|
modem->onPacketReceived(snr, rssi, rx_buf, rx_len);
|
|
}
|
|
}
|