@@ -76,7 +76,7 @@ extern bool webserverPreventAutoStart;
7676#endif
7777
7878#if defined(GPIO_PIN_PWM_OUTPUTS)
79- #include < Servo.h>
79+ #include < Servo.h>
8080static constexpr uint8_t SERVO_PINS[] = GPIO_PIN_PWM_OUTPUTS;
8181static constexpr uint8_t SERVO_COUNT = ARRAY_SIZE(SERVO_PINS);
8282static Servo *Servos[SERVO_COUNT];
@@ -670,6 +670,14 @@ static void ICACHE_RAM_ATTR MspReceiveComplete()
670670
671671static void ICACHE_RAM_ATTR ProcessRfPacket_MSP ()
672672{
673+ // Always examine MSP packets for bind information if in bind mode
674+ // [1] is the package index, first packet of the MSP
675+ if (InBindingMode && Radio.RXdataBuffer [1 ] == 1 && Radio.RXdataBuffer [2 ] == MSP_ELRS_BIND)
676+ {
677+ OnELRSBindMSP ((uint8_t *)&Radio.RXdataBuffer [2 ]);
678+ return ;
679+ }
680+
673681 // Must be fully connected to process MSP, prevents processing MSP
674682 // during sync, where packets can be received before connection
675683 if (connectionState != connected)
@@ -681,13 +689,7 @@ static void ICACHE_RAM_ATTR ProcessRfPacket_MSP()
681689 {
682690 NextTelemetryType = ELRS_TELEMETRY_TYPE_LINK;
683691 }
684-
685- if (Radio.RXdataBuffer [1 ] == 1 && MspData[0 ] == MSP_ELRS_BIND)
686- {
687- OnELRSBindMSP (MspData);
688- MspReceiver.ResetState ();
689- }
690- else if (MspReceiver.HasFinishedData ())
692+ if (MspReceiver.HasFinishedData ())
691693 {
692694 MspReceiveComplete ();
693695 }
@@ -753,8 +755,8 @@ void ICACHE_RAM_ATTR ProcessRFPacket()
753755 uint16_t inCRC = (((uint16_t )(Radio.RXdataBuffer [0 ] & 0b11111100 )) << 6 ) | Radio.RXdataBuffer [7 ];
754756
755757 // For smHybrid the CRC only has the packet type in byte 0
756- // For smHybridWide the FHSS slot is added to the CRC in byte 0 except on SYNC packets
757- if (type == SYNC_PACKET || OtaSwitchModeCurrent != smHybridWide)
758+ // For smHybridWide the FHSS slot is added to the CRC in byte 0 on RC_DATA_PACKETs
759+ if (type != RC_DATA_PACKET || OtaSwitchModeCurrent != smHybridWide)
758760 {
759761 Radio.RXdataBuffer [0 ] = type;
760762 }
@@ -797,7 +799,7 @@ void ICACHE_RAM_ATTR ProcessRFPacket()
797799 // not implimented yet
798800 break ;
799801 case SYNC_PACKET: // sync packet from master
800- doStartTimer = ProcessRfPacket_SYNC (now);
802+ doStartTimer = ProcessRfPacket_SYNC (now) && !InBindingMode ;
801803 break ;
802804 default : // code to be executed if n doesn't match any cases
803805 break ;
@@ -1072,7 +1074,7 @@ static void servosUpdate(unsigned long now)
10721074
10731075 if (Servos[ch])
10741076 Servos[ch]->writeMicroseconds (us);
1075- else if (us >= 988U && us <= 2012U )
1077+ else if (us >= 988U && us <= 2012U )
10761078 {
10771079 // us might be out of bounds if this is a switch channel and it has not been
10781080 // received yet. Delay initializing the servo until the channel is valid
@@ -1104,6 +1106,34 @@ static void servosUpdate(unsigned long now)
11041106#endif
11051107}
11061108
1109+ static void updateBindingMode ()
1110+ {
1111+ // If the eeprom is indicating that we're not bound
1112+ // and we're not already in binding mode, enter binding
1113+ if (!config.GetIsBound () && !InBindingMode)
1114+ {
1115+ INFOLN (" RX has not been bound, enter binding mode..." );
1116+ EnterBindingMode ();
1117+ }
1118+ // If in binding mode and the bind packet has come in, leave binding mode
1119+ else if (config.GetIsBound () && InBindingMode)
1120+ {
1121+ ExitBindingMode ();
1122+ }
1123+
1124+ #ifndef MY_UID
1125+ // If the power on counter is >=3, enter binding and clear counter
1126+ if (config.GetPowerOnCounter () >= 3 )
1127+ {
1128+ config.SetPowerOnCounter (0 );
1129+ config.Commit ();
1130+
1131+ INFOLN (" Power on counter >=3, enter binding mode..." );
1132+ EnterBindingMode ();
1133+ }
1134+ #endif
1135+ }
1136+
11071137#if defined(PLATFORM_ESP8266)
11081138// Called from core's user_rf_pre_init() function (which is called by SDK) before setup()
11091139RF_PRE_INIT ()
@@ -1166,7 +1196,6 @@ void loop()
11661196 }
11671197
11681198 devicesUpdate (now);
1169- servosUpdate (now);
11701199
11711200 #if defined(PLATFORM_ESP8266) && defined(AUTO_WIFI_ON_INTERVAL)
11721201 // If the reboot time is set and the current time is past the reboot time then reboot.
@@ -1175,7 +1204,7 @@ void loop()
11751204 }
11761205 #endif
11771206
1178- if (connectionState > FAILURE_STATES )
1207+ if (connectionState > MODE_STATES )
11791208 {
11801209 return ;
11811210 }
@@ -1198,6 +1227,7 @@ void loop()
11981227 }
11991228
12001229 cycleRfMode (now);
1230+ servosUpdate (now);
12011231
12021232 uint32_t localLastValidPacket = LastValidPacket; // Required to prevent race condition due to LastValidPacket getting updated from ISR
12031233 if ((connectionState == disconnectPending) ||
@@ -1230,33 +1260,14 @@ void loop()
12301260 DBGLN (" Timer locked" );
12311261 }
12321262
1233- // If the eeprom is indicating that we're not bound
1234- // and we're not already in binding mode, enter binding
1235- if (!config.GetIsBound () && !InBindingMode)
1236- {
1237- INFOLN (" RX has not been bound, enter binding mode..." );
1238- EnterBindingMode ();
1239- }
1240-
1241- // If the power on counter is >=3, enter binding and clear counter
1242- #ifndef MY_UID
1243- if (config.GetPowerOnCounter () >= 3 )
1244- {
1245- config.SetPowerOnCounter (0 );
1246- config.Commit ();
1247-
1248- INFOLN (" Power on counter >=3, enter binding mode..." );
1249- EnterBindingMode ();
1250- }
1251- #endif
1252-
12531263 uint8_t *nextPayload = 0 ;
12541264 uint8_t nextPlayloadSize = 0 ;
12551265 if (!TelemetrySender.IsActive () && telemetry.GetNextPayload (&nextPlayloadSize, &nextPayload))
12561266 {
12571267 TelemetrySender.SetDataToTransmit (nextPlayloadSize, nextPayload, ELRS_TELEMETRY_BYTES_PER_CALL);
12581268 }
12591269 updateTelemetryBurst ();
1270+ updateBindingMode ();
12601271}
12611272
12621273struct bootloader {
@@ -1310,11 +1321,12 @@ void EnterBindingMode()
13101321 UID[5 ] = BindingUID[5 ];
13111322
13121323 CRCInitializer = 0 ;
1324+ config.SetIsBound (false );
13131325 InBindingMode = true ;
13141326
13151327 // Start attempting to bind
13161328 // Lock the RF rate and freq while binding
1317- SetRFLinkRate (RATE_DEFAULT );
1329+ SetRFLinkRate (RATE_BINDING );
13181330 Radio.SetFrequencyReg (GetInitialFreq ());
13191331 // If the Radio Params (including InvertIQ) parameter changed, need to restart RX to take effect
13201332 Radio.RXnb ();
@@ -1325,13 +1337,25 @@ void EnterBindingMode()
13251337
13261338void ExitBindingMode ()
13271339{
1328- if (!InBindingMode) {
1340+ if (!InBindingMode)
1341+ {
13291342 // Not in binding mode
13301343 DBGLN (" Cannot exit binding mode, not in binding mode!" );
13311344 return ;
13321345 }
13331346
1347+ // Prevent any new packets from coming in
1348+ Radio.SetTxIdleMode ();
13341349 LostConnection ();
1350+ // Write the values to eeprom
1351+ config.Commit ();
1352+
1353+ CRCInitializer = (UID[4 ] << 8 ) | UID[5 ];
1354+ FHSSrandomiseFHSSsequence (uidMacSeedGet ());
1355+
1356+ #if defined(PLATFORM_ESP32) || defined(PLATFORM_ESP8266)
1357+ webserverPreventAutoStart = true ;
1358+ #endif
13351359
13361360 // Force RF cycling to start at the beginning immediately
13371361 scanIndex = RATE_MAX;
@@ -1340,18 +1364,17 @@ void ExitBindingMode()
13401364 // Do this last as LostConnection() will wait for a tock that never comes
13411365 // if we're in binding mode
13421366 InBindingMode = false ;
1367+ DBGLN (" Exiting binding mode" );
13431368 devicesTriggerEvent ();
13441369}
13451370
1346- void OnELRSBindMSP (uint8_t * packet)
1371+ void ICACHE_RAM_ATTR OnELRSBindMSP (uint8_t * packet)
13471372{
13481373 for (int i = 1 ; i <=4 ; i++)
13491374 {
13501375 UID[i + 1 ] = packet[i];
13511376 }
13521377
1353- CRCInitializer = (UID[4 ] << 8 ) | UID[5 ];
1354-
13551378 DBGLN (" New UID = %d, %d, %d, %d, %d, %d" , UID[0 ], UID[1 ], UID[2 ], UID[3 ], UID[4 ], UID[5 ]);
13561379
13571380 // Set new UID in eeprom
@@ -1360,15 +1383,7 @@ void OnELRSBindMSP(uint8_t* packet)
13601383 // Set eeprom byte to indicate RX is bound
13611384 config.SetIsBound (true );
13621385
1363- // Write the values to eeprom
1364- config.Commit ();
1365-
1366- FHSSrandomiseFHSSsequence (uidMacSeedGet ());
1367-
1368- #if defined(PLATFORM_ESP32) || defined(PLATFORM_ESP8266)
1369- webserverPreventAutoStart = true ;
1370- #endif
1371- ExitBindingMode ();
1386+ // EEPROM commit will happen on the main thread in ExitBindingMode()
13721387}
13731388
13741389void UpdateModelMatch (uint8_t model)
0 commit comments