@@ -142,7 +142,10 @@ void gnssDetectReceiverType()
142
142
143
143
// TODO remove after testing, force retest on each boot
144
144
// 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
146
149
147
150
// Start auto-detect if NVM is not yet set
148
151
if (settings.detectedGnssReceiver == GNSS_RECEIVER_UNKNOWN)
@@ -243,4 +246,174 @@ void gnssReset()
243
246
{
244
247
digitalWrite (pin_GNSS_Reset, LOW); // Tell LG290P to reset
245
248
}
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