mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-09-04 06:34:14 +00:00
separate main events from housekeeping ones
This commit is contained in:
+25
-23
@@ -22,7 +22,6 @@ LOG_MODULE_REGISTER(zephcore_dispatcher, CONFIG_ZEPHCORE_LORA_LOG_LEVEL);
|
||||
namespace mesh {
|
||||
|
||||
#define MAX_RX_DELAY_MILLIS 32000
|
||||
#define NOISE_FLOOR_CALIB_INTERVAL 2000
|
||||
|
||||
Dispatcher::Dispatcher(Radio &radio, MillisecondClock &ms, PacketManager &mgr)
|
||||
: _radio(&radio), _ms(&ms), _mgr(&mgr)
|
||||
@@ -31,7 +30,7 @@ Dispatcher::Dispatcher(Radio &radio, MillisecondClock &ms, PacketManager &mgr)
|
||||
total_air_time = rx_air_time = 0;
|
||||
next_tx_time = 0;
|
||||
cad_busy_start = 0;
|
||||
next_floor_calib_time = next_agc_reset_time = 0;
|
||||
next_agc_reset_time = 0;
|
||||
_err_flags = 0;
|
||||
_duty_cycle.init(0);
|
||||
radio_nonrx_start = 0;
|
||||
@@ -94,22 +93,6 @@ uint32_t Dispatcher::getCADFailMaxDuration() const
|
||||
|
||||
void Dispatcher::loop()
|
||||
{
|
||||
if (millisHasNowPassed(next_floor_calib_time)) {
|
||||
_radio->triggerNoiseFloorCalibrate(getInterferenceThreshold());
|
||||
next_floor_calib_time = futureMillis(NOISE_FLOOR_CALIB_INTERVAL);
|
||||
}
|
||||
|
||||
bool is_recv = _radio->isInRecvMode();
|
||||
if (is_recv != prev_isrecv_mode) {
|
||||
prev_isrecv_mode = is_recv;
|
||||
if (!is_recv) {
|
||||
radio_nonrx_start = (uint32_t)_ms->getMillis();
|
||||
}
|
||||
}
|
||||
if (!is_recv && (uint32_t)_ms->getMillis() - radio_nonrx_start > 8000) {
|
||||
_err_flags |= ERR_EVENT_STARTRX_TIMEOUT;
|
||||
}
|
||||
|
||||
if (outbound) {
|
||||
if (_radio->isSendComplete()) {
|
||||
uint32_t t = (uint32_t)_ms->getMillis() - outbound_start;
|
||||
@@ -135,11 +118,6 @@ void Dispatcher::loop()
|
||||
next_agc_reset_time = futureMillis(getAGCResetInterval());
|
||||
}
|
||||
|
||||
if (getAGCResetInterval() > 0 && millisHasNowPassed(next_agc_reset_time)) {
|
||||
_radio->resetAGC();
|
||||
next_agc_reset_time = futureMillis(getAGCResetInterval());
|
||||
}
|
||||
|
||||
{
|
||||
Packet *pkt = _mgr->getNextInbound((uint32_t)_ms->getMillis());
|
||||
if (pkt) {
|
||||
@@ -150,6 +128,30 @@ void Dispatcher::loop()
|
||||
checkSend();
|
||||
}
|
||||
|
||||
void Dispatcher::maintenanceLoop()
|
||||
{
|
||||
/* Noise floor calibration — one EMA tick per housekeeping cycle */
|
||||
_radio->triggerNoiseFloorCalibrate(getInterferenceThreshold());
|
||||
|
||||
/* RX mode watchdog — detect if radio is stuck outside RX */
|
||||
bool is_recv = _radio->isInRecvMode();
|
||||
if (is_recv != prev_isrecv_mode) {
|
||||
prev_isrecv_mode = is_recv;
|
||||
if (!is_recv) {
|
||||
radio_nonrx_start = (uint32_t)_ms->getMillis();
|
||||
}
|
||||
}
|
||||
if (!is_recv && (uint32_t)_ms->getMillis() - radio_nonrx_start > 8000) {
|
||||
_err_flags |= ERR_EVENT_STARTRX_TIMEOUT;
|
||||
}
|
||||
|
||||
/* AGC reset — periodic warm sleep + recalibration */
|
||||
if (getAGCResetInterval() > 0 && millisHasNowPassed(next_agc_reset_time)) {
|
||||
_radio->resetAGC();
|
||||
next_agc_reset_time = futureMillis(getAGCResetInterval());
|
||||
}
|
||||
}
|
||||
|
||||
bool Dispatcher::tryParsePacket(Packet *pkt, const uint8_t *raw, int len)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
@@ -288,18 +288,22 @@ static void mesh_event_loop(void)
|
||||
gps_process_event();
|
||||
}
|
||||
|
||||
/* Run mesh loop - handles all pending work:
|
||||
* - Process received LoRa packets
|
||||
* - Check TX completion
|
||||
* - Timeout handling
|
||||
* - Noise floor calibration (runs when loop is called)
|
||||
*/
|
||||
if (companion_mesh_ptr) {
|
||||
/* Packet processing — only on radio/BLE/TX events */
|
||||
if (companion_mesh_ptr &&
|
||||
(events & (MESH_EVENT_LORA_RX | MESH_EVENT_LORA_TX_DONE |
|
||||
MESH_EVENT_BLE_RX | MESH_EVENT_TX_DRAIN))) {
|
||||
companion_mesh_ptr->loop();
|
||||
}
|
||||
|
||||
/* Periodic UI refresh (every housekeeping cycle = 5s) */
|
||||
/* Periodic housekeeping — maintenance + UI refresh */
|
||||
if (events & MESH_EVENT_HOUSEKEEPING) {
|
||||
/* Radio maintenance: noise floor calibration, AGC reset,
|
||||
* RX watchdog. Separated from loop() so these never run
|
||||
* on packet-driven events. */
|
||||
if (companion_mesh_ptr) {
|
||||
companion_mesh_ptr->maintenanceLoop();
|
||||
}
|
||||
|
||||
mesh_housekeeping_ui_refresh();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -328,13 +328,25 @@ static void repeater_event_loop(void)
|
||||
}
|
||||
|
||||
#ifdef ZEPHCORE_LORA
|
||||
if (repeater_mesh_ptr) {
|
||||
/* Packet processing — only on radio/CLI/TX events */
|
||||
if (repeater_mesh_ptr &&
|
||||
(events & (MESH_EVENT_LORA_RX | MESH_EVENT_LORA_TX_DONE |
|
||||
MESH_EVENT_CLI_RX | MESH_EVENT_TX_DRAIN))) {
|
||||
repeater_mesh_ptr->loop();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Periodic housekeeping — update display with live data */
|
||||
/* Periodic housekeeping — maintenance + display refresh */
|
||||
if (events & MESH_EVENT_HOUSEKEEPING) {
|
||||
#ifdef ZEPHCORE_LORA
|
||||
/* Radio maintenance: noise floor calibration, AGC reset,
|
||||
* RX watchdog. Separated from loop() so these never run
|
||||
* on packet-driven events. */
|
||||
if (repeater_mesh_ptr) {
|
||||
repeater_mesh_ptr->maintenanceLoop();
|
||||
}
|
||||
#endif
|
||||
|
||||
ui_set_clock(rtc_clock.getCurrentTime());
|
||||
|
||||
#ifdef ZEPHCORE_LORA
|
||||
|
||||
Reference in New Issue
Block a user