Skip to content

Commit a221007

Browse files
authored
Merge pull request #724 from sparkfun/AddFlexLoRa
Add initial LoRa support on Flex
2 parents ce62276 + 2c5d9aa commit a221007

File tree

11 files changed

+658
-224
lines changed

11 files changed

+658
-224
lines changed

Firmware/RTK_Everywhere/Begin.ino

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ void identifyBoard()
161161
productVariant = RTK_POSTCARD;
162162

163163
#ifndef NOT_FACET_FLEX
164+
systemPrintln("<<<<<<<<<< !!!!!!!!!! FLEX FORCED !!!!!!!!!! >>>>>>>>>>");
164165
productVariant = RTK_FLEX; // TODO remove once v1.1 Flex has ID resistors
165166
#endif
166167
}
@@ -1129,27 +1130,8 @@ void beginGnssUart()
11291130
}
11301131
}
11311132

1132-
// Assign GNSS UART interrupts to the core that started the task. See:
1133-
// https://github.com/espressif/arduino-esp32/issues/3386
1134-
void pinGnssUartTask(void *pvParameters)
1133+
void forceGnssCommunicationRate(uint32_t &platformGnssCommunicationRate)
11351134
{
1136-
// Start notification
1137-
if (settings.printTaskStartStop)
1138-
systemPrintln("Task pinGnssUartTask started");
1139-
1140-
if (serialGNSS == nullptr)
1141-
serialGNSS = new HardwareSerial(2); // Use UART2 on the ESP32 for communication with the GNSS module
1142-
1143-
serialGNSS->setRxBufferSize(settings.uartReceiveBufferSize);
1144-
serialGNSS->setTimeout(settings.serialTimeoutGNSS); // Requires serial traffic on the UART pins for detection
1145-
1146-
if (pin_GnssUart_RX == -1 || pin_GnssUart_TX == -1)
1147-
reportFatalError("Illegal UART pin assignment.");
1148-
1149-
uint32_t platformGnssCommunicationRate =
1150-
settings.dataPortBaud; // Default to 230400bps for ZED. This limits GNSS fixes at 4Hz but allows SD buffer to be
1151-
// reduced to 6k.
1152-
11531135
if (productVariant == RTK_TORCH)
11541136
{
11551137
// Override user setting. Required because beginGnssUart() is called before beginBoard().
@@ -1178,6 +1160,29 @@ void pinGnssUartTask(void *pvParameters)
11781160
platformGnssCommunicationRate = 115200;
11791161
}
11801162
}
1163+
}
1164+
// Assign GNSS UART interrupts to the core that started the task. See:
1165+
// https://github.com/espressif/arduino-esp32/issues/3386
1166+
void pinGnssUartTask(void *pvParameters)
1167+
{
1168+
// Start notification
1169+
if (settings.printTaskStartStop)
1170+
systemPrintln("Task pinGnssUartTask started");
1171+
1172+
if (serialGNSS == nullptr)
1173+
serialGNSS = new HardwareSerial(2); // Use UART2 on the ESP32 for communication with the GNSS module
1174+
1175+
serialGNSS->setRxBufferSize(settings.uartReceiveBufferSize);
1176+
serialGNSS->setTimeout(settings.serialTimeoutGNSS); // Requires serial traffic on the UART pins for detection
1177+
1178+
if (pin_GnssUart_RX == -1 || pin_GnssUart_TX == -1)
1179+
reportFatalError("Illegal UART pin assignment.");
1180+
1181+
uint32_t platformGnssCommunicationRate =
1182+
settings.dataPortBaud; // Default to 230400bps for ZED. This limits GNSS fixes at 4Hz but allows SD buffer to be
1183+
// reduced to 6k.
1184+
1185+
forceGnssCommunicationRate(platformGnssCommunicationRate);
11811186

11821187
serialGNSS->begin(platformGnssCommunicationRate, SERIAL_8N1, pin_GnssUart_RX,
11831188
pin_GnssUart_TX); // Start UART on platform dependent pins for SPP. The GNSS will be

Firmware/RTK_Everywhere/Display.ino

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3288,3 +3288,30 @@ void displayWebConfig(std::vector<iconPropertyBlinking> &iconPropertyList)
32883288

32893289
printTextCenter(myIP, yPos, QW_FONT_5X7, 1, false);
32903290
}
3291+
3292+
// Show GNSS update - button exit
3293+
void paintGnssUpdate()
3294+
{
3295+
paintGenericUpdate("GNSS");
3296+
}
3297+
void paintLoRaUpdate()
3298+
{
3299+
paintGenericUpdate("LoRa");
3300+
}
3301+
void paintGenericUpdate(const char *device)
3302+
{
3303+
if (online.display)
3304+
{
3305+
oled->erase(); // Clear the display's internal buffer
3306+
int yPos = (oled->getHeight() - 38) / 2;
3307+
uint8_t fontHeight = 8;
3308+
printTextCenter(device, yPos, QW_FONT_5X7, 1, false); // text, y, font type, kerning, inverted
3309+
yPos = yPos + fontHeight + 1;
3310+
printTextCenter("Update", yPos, QW_FONT_5X7, 1, false);
3311+
yPos = yPos + fontHeight + 3;
3312+
printTextCenter("Button", yPos, QW_FONT_5X7, 1, true); // text, y, font type, kerning, inverted
3313+
yPos = yPos + fontHeight + 1;
3314+
printTextCenter("To Exit", yPos, QW_FONT_5X7, 1, true);
3315+
oled->display(); // Push internal buffer to display
3316+
}
3317+
}

Firmware/RTK_Everywhere/GNSS.ino

Lines changed: 175 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)