@@ -142,7 +142,10 @@ void gnssDetectReceiverType()
142142
143143 // TODO remove after testing, force retest on each boot
144144 // Note: with this in place, the X5 detection will take a lot longer due to the baud rate change
145- settings.detectedGnssReceiver = GNSS_RECEIVER_UNKNOWN;
145+ #ifndef NOT_FACET_FLEX
146+ systemPrintln (" <<<<<<<<<< !!!!!!!!!! FLEX FORCED !!!!!!!!!! >>>>>>>>>>" );
147+ // settings.detectedGnssReceiver = GNSS_RECEIVER_UNKNOWN; // This may be causing weirdness on the LG290P. Commenting for now
148+ #endif
146149
147150 // Start auto-detect if NVM is not yet set
148151 if (settings.detectedGnssReceiver == GNSS_RECEIVER_UNKNOWN)
@@ -243,4 +246,174 @@ void gnssReset()
243246 {
244247 digitalWrite (pin_GNSS_Reset, LOW); // Tell LG290P to reset
245248 }
246- }
249+ }
250+
251+ // ----------------------------------------
252+ // Force UART connection to GNSS for firmware update on the next boot by special file in
253+ // LittleFS
254+ // ----------------------------------------
255+ bool createGNSSPassthrough ()
256+ {
257+ return createPassthrough (" /updateGnssFirmware.txt" );
258+ }
259+ bool createPassthrough (const char *filename)
260+ {
261+ if (online.fs == false )
262+ return false ;
263+
264+ if (LittleFS.exists (filename))
265+ {
266+ if (settings.debugGnss )
267+ systemPrintf (" LittleFS %s already exists\r\n " , filename);
268+ return true ;
269+ }
270+
271+ File updateUm980Firmware = LittleFS.open (filename, FILE_WRITE);
272+ updateUm980Firmware.close ();
273+
274+ if (LittleFS.exists (filename))
275+ return true ;
276+
277+ if (settings.debugGnss )
278+ systemPrintf (" Unable to create %s on LittleFS\r\n " , filename);
279+ return false ;
280+ }
281+
282+ // ----------------------------------------
283+ void gnssFirmwareBeginUpdate ()
284+ {
285+ // Note: UM980 needs its own dedicated update function, due to the T@ and bootloader trigger
286+
287+ // Note: gnssFirmwareBeginUpdate is called during setup, after identify board. I2C, gpio expanders, buttons
288+ // and display have all been initialized. But, importantly, the UARTs have not yet been started.
289+ // This makes our job much easier...
290+
291+ // NOTE: QGNSS firmware update fails on LG290P due, I think, to QGNSS doing some kind of autobaud
292+ // detection at the start of the update. I think the delays introduced by serialGNSS->write(Serial.read())
293+ // and Serial.write(serialGNSS->read()) cause the failure, but I'm not sure.
294+ // It seems that LG290P needs a dedicated hardware link from USB to GNSS UART for a successful update.
295+ // This will be added in the next rev of the Flex motherboard.
296+
297+ // NOTE: X20P will expect a baud rate change during the update, unless we force 9600 baud.
298+ // The dedicated hardware link will make X20P firmware updates easy.
299+
300+ // Flag that we are in direct connect mode. Button task will gnssFirmwareRemoveUpdate and exit
301+ inDirectConnectMode = true ;
302+
303+ // Note: we can't call gnssFirmwareRemoveUpdate() here as closing Tera Term will reset the ESP32,
304+ // returning the firmware to normal operation...
305+
306+ // Paint GNSS Update
307+ paintGnssUpdate ();
308+
309+ // Stop all UART tasks. Redundant
310+ tasksStopGnssUart ();
311+
312+ uint32_t serialBaud = 115200 ;
313+
314+ forceGnssCommunicationRate (serialBaud); // On Flex, must be called after gnssDetectReceiverType
315+
316+ systemPrintln ();
317+ systemPrintf (" Entering GNSS direct connect for firmware update and configuration. Disconnect this terminal "
318+ " connection. Use the GNSS manufacturer software "
319+ " to update the firmware. Baudrate: %dbps. Press the %s button to return "
320+ " to normal operation.\r\n " , serialBaud, present.button_mode ? " mode" : " power" );
321+ systemFlush ();
322+
323+ Serial.end (); // We must end before we begin otherwise the UART settings are corrupted
324+ Serial.begin (serialBaud);
325+
326+ if (serialGNSS == nullptr )
327+ serialGNSS = new HardwareSerial (2 ); // Use UART2 on the ESP32 for communication with the GNSS module
328+
329+ serialGNSS->setRxBufferSize (settings.uartReceiveBufferSize );
330+ serialGNSS->setTimeout (settings.serialTimeoutGNSS ); // Requires serial traffic on the UART pins for detection
331+
332+ // This is OK for Flex too. We're using the main GNSS pins.
333+ serialGNSS->begin (serialBaud, SERIAL_8N1, pin_GnssUart_RX, pin_GnssUart_TX);
334+
335+ // Echo everything to/from GNSS
336+ while (1 )
337+ {
338+ static unsigned long lastSerial = millis (); // Temporary fix for buttonless Flex
339+
340+ if (Serial.available ()) // Note: use if, not while
341+ {
342+ serialGNSS->write (Serial.read ());
343+ lastSerial = millis ();
344+ }
345+
346+ if (serialGNSS->available ()) // Note: use if, not while
347+ Serial.write (serialGNSS->read ());
348+
349+ // Button task will gnssFirmwareRemoveUpdate and restart
350+
351+ // Temporary fix for buttonless Flex. TODO - remove
352+ if ((productVariant == RTK_FLEX) && (millis () > (lastSerial + 30000 )))
353+ {
354+ // Beep to indicate exit
355+ beepOn ();
356+ delay (300 );
357+ beepOff ();
358+ delay (100 );
359+ beepOn ();
360+ delay (300 );
361+ beepOff ();
362+
363+ gnssFirmwareRemoveUpdate ();
364+
365+ systemPrintln (" Exiting direct connection (passthrough) mode" );
366+ systemFlush (); // Complete prints
367+
368+ ESP.restart ();
369+ }
370+ }
371+ }
372+
373+ // ----------------------------------------
374+ // Check if direct connection file exists
375+ // ----------------------------------------
376+ bool gnssFirmwareCheckUpdate ()
377+ {
378+ return gnssFirmwareCheckUpdateFile (" /updateGnssFirmware.txt" );
379+ }
380+ bool gnssFirmwareCheckUpdateFile (const char *filename)
381+ {
382+ if (online.fs == false )
383+ return false ;
384+
385+ if (LittleFS.exists (filename))
386+ {
387+ if (settings.debugGnss )
388+ systemPrintf (" LittleFS %s exists\r\n " , filename);
389+
390+ // We do not remove the file here. See removeupdateUm980Firmware().
391+
392+ return true ;
393+ }
394+
395+ return false ;
396+ }
397+
398+ // ----------------------------------------
399+ // Remove direct connection file
400+ // ----------------------------------------
401+ void gnssFirmwareRemoveUpdate ()
402+ {
403+ return gnssFirmwareRemoveUpdateFile (" /updateGnssFirmware.txt" );
404+ }
405+ void gnssFirmwareRemoveUpdateFile (const char *filename)
406+ {
407+ if (online.fs == false )
408+ return ;
409+
410+ if (LittleFS.exists (filename))
411+ {
412+ if (settings.debugGnss )
413+ systemPrintf (" Removing %s\r\n " , filename);
414+
415+ LittleFS.remove (filename);
416+ }
417+ }
418+
419+ // ----------------------------------------
0 commit comments