Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow changing switch mode when connected #1792

Merged
merged 1 commit into from
Sep 3, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
45 changes: 36 additions & 9 deletions src/src/rx_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ MeanAccumulator<int32_t, int8_t, -16> SnrMean;

uint8_t scanIndex = RATE_DEFAULT;
uint8_t ExpressLRS_nextAirRateIndex;
uint8_t SwitchModePending;
int8_t SwitchModePending;

int32_t PfdPrevRawOffset;
RXtimerState_e RXtimerState;
Expand Down Expand Up @@ -773,6 +773,38 @@ static void ICACHE_RAM_ATTR ProcessRfPacket_MSP(OTA_Packet_s const * const otaPk
}
}

static void ICACHE_RAM_ATTR updateSwitchModePendingFromOta(uint8_t newSwitchMode)
{
if (OtaSwitchModeCurrent == newSwitchMode)
{
// Cancel any switch if pending
SwitchModePending = 0;
return;
}

// One is added to the mode because SwitchModePending==0 means no switch pending
// and that's also a valid switch mode. The 1 is removed when this is handled.
// A negative SwitchModePending means not to switch yet
int8_t newSwitchModePending = -(int8_t)newSwitchMode - 1;

// Switch mode can be changed while disconnected
// OR there are two sync packets with the same new switch mode,
// as a "confirm". No RC packets are processed until
if (connectionState == disconnected ||
SwitchModePending == newSwitchModePending)
{
// Add one to the mode because SwitchModePending==0 means no switch pending
// and that's also a valid switch mode. The 1 is removed when this is handled
SwitchModePending = newSwitchMode + 1;
}
else
{
// Save the negative version of the new switch mode to compare
// against on the next SYNC packet, but do not switch yet
SwitchModePending = newSwitchModePending;
}
}

static bool ICACHE_RAM_ATTR ProcessRfPacket_SYNC(uint32_t const now, OTA_Sync_s const * const otaSync)
{
// Verify the first two of three bytes of the binding ID, which should always match
Expand All @@ -792,13 +824,7 @@ static bool ICACHE_RAM_ATTR ProcessRfPacket_SYNC(uint32_t const now, OTA_Sync_s

// Will change the packet air rate in loop() if this changes
ExpressLRS_nextAirRateIndex = otaSync->rateIndex;
// Switch mode can only change when disconnected, and happens on the main thread
if (connectionState == disconnected)
{
// Add one to the mode because SwitchModePending==0 means no switch pending
// and that's also a valid switch mode. The 1 is removed when this is handled
SwitchModePending = otaSync->switchEncMode + 1;
}
updateSwitchModePendingFromOta(otaSync->switchEncMode);

// Update TLM ratio, should never be TLM_RATIO_STD/DISARMED, the TX calculates the correct value for the RX
expresslrs_tlm_ratio_e TLMrateIn = (expresslrs_tlm_ratio_e)(otaSync->newTlmRatio + (uint8_t)TLM_RATIO_NO_TLM);
Expand Down Expand Up @@ -1326,7 +1352,8 @@ static void debugRcvrLinkstats()

static void updateSwitchMode()
{
if (!SwitchModePending)
// Negative value means waiting for confirm of the new switch mode while connected
if (SwitchModePending <= 0)
return;

OtaUpdateSerializers((OtaSwitchMode_e)(SwitchModePending - 1), ExpressLRS_currAirRate_Modparams->PayloadLength);
Expand Down