fix(crsf): send modelID after module reset (#5506)

This commit is contained in:
Michael
2024-09-06 12:00:54 +10:00
committed by GitHub
parent 3ac8da2575
commit cb249268aa
+33
View File
@@ -42,6 +42,10 @@
#define MIN_FRAME_LEN 3
#define MODULE_ALIVE_TIMEOUT 50 // if the module has sent a valid frame within 500ms it is declared alive
static tmr10ms_t lastAlive[NUM_MODULES]; // last time stamp module sent CRSF frames
static bool moduleAlive[NUM_MODULES]; // module alive status
uint8_t createCrossfireBindFrame(uint8_t moduleIdx, uint8_t * frame)
{
uint8_t * buf = frame;
@@ -125,6 +129,34 @@ static void setupPulsesCrossfire(uint8_t module, uint8_t*& p_buf,
} else
#endif
{
//
// An ELRS module stores the RF parameters in a model specific way using the
// modelID as index. If the module resets after it was initally initialized the modelID
// needs to be resent as otherwise the module assumes modelID 0 which leads to the
// module using the stored RF parameters for the model with modelID 0. This is not only
// annoying but also potentially dangerous as a receiver will no longer re-connect.
//
// Reasons for a module resetting might be:
// - power surge
// - internal non-recoverable error
// - after flashing in WiFi mode
// - putting the module in WiFi mode and exiting WiFi mode (LUA script)
//
// This logic takes care of sending the modelID again after a module comes back to
// live after a module reset
//
if(moduleState[module].counter != CRSF_FRAME_MODELID ) { // skip the reset check logic if first init
if((get_tmr10ms() - lastAlive[module]) > MODULE_ALIVE_TIMEOUT) { // check if module has recently sent CRSF frames
moduleAlive[module] = false; // no, declare it as dead
} else {
if(moduleAlive[module] == false) { // if the module was dead and came back to live, e.g. reset
moduleAlive[module] = true; // declare the module as alive
moduleState[module].counter = CRSF_FRAME_MODELID; // and send it the modelID again
TRACE("[XF] sending ModelID after module reset");
}
}
}
if (moduleState[module].counter == CRSF_FRAME_MODELID) {
p_buf += createCrossfireModelIDFrame(module, p_buf);
moduleState[module].counter = CRSF_FRAME_MODELID_SENT;
@@ -223,6 +255,7 @@ static uint8_t* _processFrames(void* ctx, uint8_t* buf, uint8_t& len)
#endif
auto mod_st = (etx_module_state_t*)ctx;
auto module = modulePortGetModule(mod_st);
lastAlive[module] = get_tmr10ms(); // valid frame received, note timestamp
processCrossfireTelemetryFrame(module, p_buf, pkt_len);
}