fix(crsf): send modelID after module reset (#5506)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user