@@ -168,9 +168,7 @@ bool doStartTimer = false;
168168
169169// /////////////////////////////////////////////
170170
171- bool didFHSS = false ;
172- bool alreadyFHSS = false ;
173- bool alreadyTLMresp = false ;
171+ static bool alreadyTLMresp = false ;
174172
175173// ////////////////////////////////////////////////////////////
176174
@@ -369,20 +367,19 @@ void SetRFLinkRate(uint8_t index, bool bindMode) // Set speed of RF link
369367 EnableLBT ();
370368}
371369
372- bool ICACHE_RAM_ATTR HandleFHSS ()
370+ static void ICACHE_RAM_ATTR HandleFHSS ()
373371{
374- uint8_t modresultFHSS = ( OtaNonce + 1 ) % ExpressLRS_currAirRate_Modparams->FHSShopInterval ;
372+ uint8_t modresultFHSS = OtaNonce % ExpressLRS_currAirRate_Modparams->FHSShopInterval ;
375373
376- if ((ExpressLRS_currAirRate_Modparams->FHSShopInterval == 0 ) || alreadyFHSS == true || InBindingMode || (modresultFHSS != 0 ) || (connectionState == disconnected))
374+ if ((ExpressLRS_currAirRate_Modparams->FHSShopInterval == 0 ) || InBindingMode || (modresultFHSS != 0 ) || (connectionState == disconnected))
377375 {
378- return false ;
376+ return ;
379377 }
380378
381- alreadyFHSS = true ;
382-
383379 if (geminiMode)
384380 {
385- if ((((OtaNonce + 1 )/ExpressLRS_currAirRate_Modparams->FHSShopInterval ) % 2 == 0 ) || FHSSuseDualBand) // When in DualBand do not switch between radios. The OTA modulation parameters and HighFreq/LowFreq Tx amps are set during Config.
381+ if (((OtaNonce / ExpressLRS_currAirRate_Modparams->FHSShopInterval ) % 2 == 0 ) || FHSSuseDualBand) // When in DualBand do not switch between radios. The OTA modulation paramters and HighFreq/LowFreq Tx amps are set during Config.
382+
386383 {
387384 Radio.SetFrequencyReg (FHSSgetNextFreq (), SX12XX_Radio_1);
388385 Radio.SetFrequencyReg (FHSSgetGeminiFreq (), SX12XX_Radio_2);
@@ -402,7 +399,7 @@ bool ICACHE_RAM_ATTR HandleFHSS()
402399
403400#if defined(RADIO_SX127X)
404401 // SX127x radio has to reset receive mode after hopping
405- uint8_t modresultTLM = ( OtaNonce + 1 ) % ExpressLRS_currTlmDenom;
402+ uint8_t modresultTLM = OtaNonce % ExpressLRS_currTlmDenom;
406403 if (modresultTLM != 0 || ExpressLRS_currTlmDenom == 1 ) // if we are about to send a tlm response don't bother going back to rx
407404 {
408405 Radio.RXnb ();
@@ -411,7 +408,6 @@ bool ICACHE_RAM_ATTR HandleFHSS()
411408#if defined(Regulatory_Domain_EU_CE_2400)
412409 SetClearChannelAssessmentTime ();
413410#endif
414- return true ;
415411}
416412
417413void ICACHE_RAM_ATTR LinkStatsToOta (OTA_LinkStats_s * const ls)
@@ -441,7 +437,7 @@ void ICACHE_RAM_ATTR LinkStatsToOta(OTA_LinkStats_s * const ls)
441437
442438bool ICACHE_RAM_ATTR HandleSendTelemetryResponse ()
443439{
444- uint8_t modresult = ( OtaNonce + 1 ) % ExpressLRS_currTlmDenom;
440+ uint8_t modresult = OtaNonce % ExpressLRS_currTlmDenom;
445441
446442 if ((connectionState == disconnected) || (ExpressLRS_currTlmDenom == 1 ) || (alreadyTLMresp == true ) || (modresult != 0 ) || !teamraceHasModelMatch)
447443 {
@@ -605,7 +601,7 @@ bool ICACHE_RAM_ATTR HandleSendTelemetryResponse()
605601 // Gemini flips frequencies between radios on the rx side only. This is to help minimise antenna cross polarization.
606602 // The payloads need to be switch when this happens.
607603 // GemX does not switch due to the time required to reconfigure the LR1121 params.
608- if ((( OtaNonce + 1 ) /ExpressLRS_currAirRate_Modparams->FHSShopInterval ) % 2 == 0 || !sendGeminiBuffer || FHSSuseDualBand)
604+ if ((OtaNonce/ExpressLRS_currAirRate_Modparams->FHSShopInterval ) % 2 == 0 || !sendGeminiBuffer || FHSSuseDualBand)
609605 {
610606 Radio.TXnb ((uint8_t *)&otaPkt, ExpressLRS_currAirRate_Modparams->PayloadLength , sendGeminiBuffer, (uint8_t *)&otaPktGemini, transmittingRadio);
611607 }
@@ -678,10 +674,8 @@ void ICACHE_RAM_ATTR updatePhaseLock()
678674
679675 if (RXtimerState == tim_locked)
680676 {
681- // limit rate of freq offset adjustment, use slot 1
682- // because telemetry can fall on slot 1 and will
683- // never get here
684- if (OtaNonce % 8 == 1 )
677+ // limit rate of freq offset adjustment
678+ if (OtaNonce % 8 == 0 )
685679 {
686680 if (Offset > 0 )
687681 {
@@ -712,15 +706,6 @@ void ICACHE_RAM_ATTR updatePhaseLock()
712706
713707void ICACHE_RAM_ATTR HWtimerCallbackTick () // this is 180 out of phase with the other callback, occurs mid-packet reception
714708{
715- updatePhaseLock ();
716- OtaNonce++;
717-
718- // if (!alreadyTLMresp && !alreadyFHSS && !LQCalc.currentIsSet()) // packet timeout AND didn't DIDN'T just hop or send TLM
719- // {
720- // Radio.RXnb(); // put the radio cleanly back into RX in case of garbage data
721- // }
722-
723-
724709 if (ExpressLRS_currAirRate_Modparams->numOfSends == 1 )
725710 {
726711 // Save the LQ value before the inc() reduces it by 1
@@ -738,7 +723,6 @@ void ICACHE_RAM_ATTR HWtimerCallbackTick() // this is 180 out of phase with the
738723 LQCalc.inc ();
739724
740725 alreadyTLMresp = false ;
741- alreadyFHSS = false ;
742726}
743727
744728// ////////////////////////////////////////////////////////////
@@ -857,14 +841,11 @@ void ICACHE_RAM_ATTR HWtimerCallbackTock()
857841 // For any serial drivers that need to send on a regular cadence (i.e. CRSF to betaflight)
858842 sendImmediateRC ();
859843
860- if (!didFHSS)
861- {
862- HandleFHSS ();
863- }
864- didFHSS = false ;
865-
844+ OtaNonce++;
845+ HandleFHSS ();
866846 updateDiversity ();
867847 tlmSent = HandleSendTelemetryResponse ();
848+ updatePhaseLock ();
868849
869850 #if defined(DEBUG_RX_SCOREBOARD)
870851 static bool lastPacketWasTelemetry = false ;
@@ -890,7 +871,6 @@ void LostConnection(bool resumeRx)
890871 LPF_Offset.init (0 );
891872 LPF_OffsetDx.init (0 );
892873 alreadyTLMresp = false ;
893- alreadyFHSS = false ;
894874
895875 if (!InBindingMode)
896876 {
@@ -1148,7 +1128,7 @@ static bool ICACHE_RAM_ATTR ProcessRfPacket_SYNC(uint32_t const now, OTA_Sync_s
11481128 || FHSSgetCurrIndex () != otaSync->fhssIndex
11491129 || connectionHasModelMatch != modelMatched)
11501130 {
1151- // DBGLN("\r\n%ux%ux%u", OtaNonce, otaPktPtr->sync. nonce, otaPktPtr->sync. fhssIndex);
1131+ // DBGLN("\r\n%ux%ux%u", OtaNonce, otaSync-> nonce, otaSync-> fhssIndex);
11521132 FHSSsetCurrIndex (otaSync->fhssIndex );
11531133 OtaNonce = otaSync->nonce ;
11541134 TentativeConnection (now);
@@ -1184,7 +1164,12 @@ bool ICACHE_RAM_ATTR ProcessRFPacket(SX12xxDriverCommon::rx_status const status)
11841164 return false ;
11851165 }
11861166
1187- PFDloop.extEvent (beginProcessing + PACKET_TO_TOCK_SLACK);
1167+ // The extEvent defines where TOCK timer ISR is to be synced to, i.e. where the packet period begins.
1168+ // For rates where the TOA is longer than half the packet period schedule the TOCK for rougly 1x TOA before
1169+ // the TX's end of the period so telemetry is received by the TX in the correct period. For all others,
1170+ // schedule TOCK to be PACKET_TO_TOCK_SLACK (us) after RX packet reception.
1171+ int32_t slack = std::max (ExpressLRS_currAirRate_Modparams->interval - 2 * ExpressLRS_currAirRate_RFperfParams->TOA , (int32_t )PACKET_TO_TOCK_SLACK);
1172+ PFDloop.extEvent (beginProcessing + slack);
11881173
11891174 doStartTimer = false ;
11901175 unsigned long now = millis ();
@@ -1275,8 +1260,6 @@ bool ICACHE_RAM_ATTR RXdoneISR(SX12xxDriverCommon::rx_status const status)
12751260
12761261 if (ProcessRFPacket (status))
12771262 {
1278- didFHSS = HandleFHSS ();
1279-
12801263 if (doStartTimer)
12811264 {
12821265 doStartTimer = false ;
0 commit comments