@@ -12,7 +12,8 @@ void beginBoard()
12
12
}
13
13
else if (isConnected (0x19 ) == true ) // Check for accelerometer
14
14
{
15
- productVariant = RTK_EXPRESS;
15
+ if (zedModuleType == PLATFORM_F9P) productVariant = RTK_EXPRESS;
16
+ else if (zedModuleType == PLATFORM_F9R) productVariant = RTK_EXPRESS_PLUS;
16
17
}
17
18
else
18
19
{
@@ -29,16 +30,20 @@ void beginBoard()
29
30
pin_positionAccuracyLED_100cm = 13 ;
30
31
pin_baseStatusLED = 4 ;
31
32
pin_bluetoothStatusLED = 12 ;
32
- pin_baseSwitch = 5 ;
33
+ pin_setupButton = 5 ;
33
34
pin_microSD_CS = 25 ;
34
35
pin_zed_tx_ready = 26 ;
35
36
pin_zed_reset = 27 ;
36
37
pin_batteryLevel_alert = 36 ;
37
38
39
+ // Bug in ZED-F9P v1.13 firmware causes RTK LED to not light when RTK Floating with SBAS on.
40
+ // The following changes the POR default but will be overwritten by settings in NVM or settings file
41
+ ubxConstellations[1 ].enabled = false ;
42
+
38
43
strcpy (platformFilePrefix, " SFE_Surveyor" );
39
44
strcpy (platformPrefix, " Surveyor" );
40
45
}
41
- else if (productVariant == RTK_EXPRESS)
46
+ else if (productVariant == RTK_EXPRESS || productVariant == RTK_EXPRESS_PLUS )
42
47
{
43
48
pin_muxA = 2 ;
44
49
pin_muxB = 4 ;
@@ -61,8 +66,16 @@ void beginBoard()
61
66
62
67
setMuxport (settings.dataPortChannel ); // Set mux to user's choice: NMEA, I2C, PPS, or DAC
63
68
64
- strcpy (platformFilePrefix, " SFE_Express" );
65
- strcpy (platformPrefix, " Express" );
69
+ if (productVariant == RTK_EXPRESS)
70
+ {
71
+ strcpy (platformFilePrefix, " SFE_Express" );
72
+ strcpy (platformPrefix, " Express" );
73
+ }
74
+ else if (productVariant == RTK_EXPRESS_PLUS)
75
+ {
76
+ strcpy (platformFilePrefix, " SFE_Express_Plus" );
77
+ strcpy (platformPrefix, " Express Plus" );
78
+ }
66
79
}
67
80
else if (productVariant == RTK_FACET)
68
81
{
@@ -89,8 +102,6 @@ void beginBoard()
89
102
90
103
setMuxport (settings.dataPortChannel ); // Set mux to user's choice: NMEA, I2C, PPS, or DAC
91
104
92
- delay (1000 );
93
-
94
105
strcpy (platformFilePrefix, " SFE_Facet" );
95
106
strcpy (platformPrefix, " Facet" );
96
107
}
@@ -101,10 +112,14 @@ void beginBoard()
101
112
if (esp_reset_reason () == ESP_RST_POWERON)
102
113
{
103
114
reuseLastLog = false ; // Start new log
115
+ settings.resetCount = 0 ;
116
+ recordSystemSettings (); // Record to NVM
104
117
}
105
118
else
106
119
{
107
120
reuseLastLog = true ; // Attempt to reuse previous log
121
+ settings.resetCount ++;
122
+ recordSystemSettings (); // Record to NVM
108
123
109
124
Serial.print (" Reset reason: " );
110
125
switch (esp_reset_reason ())
@@ -188,25 +203,76 @@ void beginSD()
188
203
}
189
204
}
190
205
206
+ // We want the UART2 interrupts to be pinned to core 0 to avoid competing with I2C interrupts
191
207
// We do not start the UART2 for GNSS->BT reception here because the interrupts would be pinned to core 1
192
- // competing with I2C interrupts
193
- // See issue: https://github.com/espressif/arduino-esp32/issues/3386
194
208
// We instead start a task that runs on core 0, that then begins serial
209
+ // See issue: https://github.com/espressif/arduino-esp32/issues/3386
195
210
void beginUART2 ()
196
211
{
197
- if (startUART2TaskHandle == NULL ) xTaskCreatePinnedToCore (
198
- startUART2Task ,
212
+ if (pinUART2TaskHandle == NULL ) xTaskCreatePinnedToCore (
213
+ pinUART2Task ,
199
214
" UARTStart" , // Just for humans
200
215
2000 , // Stack Size
201
216
NULL , // Task input parameter
202
217
0 , // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
203
- &startUART2TaskHandle , // Task handle
218
+ &pinUART2TaskHandle , // Task handle
204
219
0 ); // Core where task should run, 0=core, 1=Arduino
205
220
206
- while (uart2Started == false ) // Wait for task to run once
221
+ while (uart2pinned == false ) // Wait for task to run once
207
222
delay (1 );
208
223
}
209
224
225
+ // Assign UART2 interrupts to the core 0. See: https://github.com/espressif/arduino-esp32/issues/3386
226
+ void pinUART2Task ( void *pvParameters )
227
+ {
228
+ serialGNSS.begin (settings.dataPortBaud ); // UART2 on pins 16/17 for SPP. The ZED-F9P will be configured to output NMEA over its UART1 at the same rate.
229
+ serialGNSS.setRxBufferSize (SERIAL_SIZE_RX);
230
+ serialGNSS.setTimeout (50 );
231
+
232
+ uart2pinned = true ;
233
+
234
+ vTaskDelete ( NULL ); // Delete task once it has run once
235
+ }
236
+
237
+ // Serial Read/Write tasks for the F9P must be started after BT is up and running otherwise SerialBT.available will cause reboot
238
+ void startUART2Tasks ()
239
+ {
240
+ // Start the tasks for handling incoming and outgoing BT bytes to/from ZED-F9P
241
+ if (F9PSerialReadTaskHandle == NULL )
242
+ xTaskCreate (
243
+ F9PSerialReadTask,
244
+ " F9Read" , // Just for humans
245
+ readTaskStackSize, // Stack Size
246
+ NULL , // Task input parameter
247
+ F9PSerialReadTaskPriority, // Priority
248
+ &F9PSerialReadTaskHandle); // Task handle
249
+
250
+ if (F9PSerialWriteTaskHandle == NULL )
251
+ xTaskCreate (
252
+ F9PSerialWriteTask,
253
+ " F9Write" , // Just for humans
254
+ writeTaskStackSize, // Stack Size
255
+ NULL , // Task input parameter
256
+ F9PSerialWriteTaskPriority, // Priority
257
+ &F9PSerialWriteTaskHandle); // Task handle
258
+ }
259
+
260
+ // Stop tasks - useful when running firmware update or WiFi AP is running
261
+ void stopUART2Tasks ()
262
+ {
263
+ // Delete tasks if running
264
+ if (F9PSerialReadTaskHandle != NULL )
265
+ {
266
+ vTaskDelete (F9PSerialReadTaskHandle);
267
+ F9PSerialReadTaskHandle = NULL ;
268
+ }
269
+ if (F9PSerialWriteTaskHandle != NULL )
270
+ {
271
+ vTaskDelete (F9PSerialWriteTaskHandle);
272
+ F9PSerialWriteTaskHandle = NULL ;
273
+ }
274
+ }
275
+
210
276
// ESP32 requires the creation of an EEPROM space
211
277
void beginEEPROM ()
212
278
{
@@ -229,7 +295,7 @@ void beginDisplay()
229
295
}
230
296
}
231
297
232
- // Connect to and configure ZED-F9P
298
+ // Connect to ZED module and identify particulars
233
299
void beginGNSS ()
234
300
{
235
301
if (i2cGNSS.begin () == false )
@@ -250,32 +316,32 @@ void beginGNSS()
250
316
// Check the firmware version of the ZED-F9P. Based on Example21_ModuleInfo.
251
317
if (i2cGNSS.getModuleInfo (1100 ) == true ) // Try to get the module info
252
318
{
319
+ // i2cGNSS.minfo.extension[1] looks like 'FWVER=HPG 1.12'
253
320
strcpy (zedFirmwareVersion, i2cGNSS.minfo .extension [1 ]);
254
321
255
- // i2cGNSS.minfo.extension[1] looks like 'FWVER=HPG 1.12'
256
- // Replace = with - to avoid NVM parsing issues
257
- char *ptr = strchr (zedFirmwareVersion, ' =' );
322
+ // Remove 'FWVER='. It's extraneous and = causes settings file parsing issues
323
+ char *ptr = strstr (zedFirmwareVersion, " FWVER=" );
258
324
if (ptr != NULL )
259
- zedFirmwareVersion[ptr - zedFirmwareVersion] = ' :' ;
260
-
261
- Serial.print (F (" ZED-F9P firmware: " ));
262
- Serial.println (zedFirmwareVersion);
263
-
264
- // if (strcmp(i2cGNSS.minfo.extension[1], latestZEDFirmware) != 0)
265
- // {
266
- // Serial.print(F("The ZED-F9P appears to have outdated firmware. Found: "));
267
- // Serial.println(i2cGNSS.minfo.extension[1]);
268
- // Serial.print(F("The Surveyor works best with "));
269
- // Serial.println(latestZEDFirmware);
270
- // Serial.print(F("Please upgrade using u-center."));
271
- // Serial.println();
272
- // }
273
- // else
274
- // {
275
- // Serial.println(F("ZED-F9P firmware is current"));
276
- // }
325
+ strcpy (zedFirmwareVersion, ptr + strlen (" FWVER=" ));
326
+
327
+ // Determine if we have a ZED-F9P (Express/Facet) or an ZED-F9R (Express Plus/Facet Plus)
328
+ if (strstr (i2cGNSS.minfo .extension [3 ], " ZED-F9P" ) != NULL )
329
+ {
330
+ zedModuleType = PLATFORM_F9P;
331
+ }
332
+ else if (strstr (i2cGNSS.minfo .extension [3 ], " ZED-F9R" ) != NULL )
333
+ {
334
+ zedModuleType = PLATFORM_F9R;
335
+ }
336
+
337
+ printModuleInfo (); // Print module type and firmware version
277
338
}
339
+ online.gnss = true ;
340
+ }
278
341
342
+ // Configuration can take >1s so configure during splash
343
+ void configureGNSS ()
344
+ {
279
345
bool response = configureUbloxModule ();
280
346
if (response == false )
281
347
{
@@ -293,8 +359,6 @@ void beginGNSS()
293
359
}
294
360
295
361
Serial.println (F (" GNSS configuration complete" ));
296
-
297
- online.gnss = true ;
298
362
}
299
363
300
364
// Set LEDs for output and configure PWM
@@ -307,22 +371,25 @@ void beginLEDs()
307
371
pinMode (pin_positionAccuracyLED_100cm, OUTPUT);
308
372
pinMode (pin_baseStatusLED, OUTPUT);
309
373
pinMode (pin_bluetoothStatusLED, OUTPUT);
310
- pinMode (pin_baseSwitch , INPUT_PULLUP); // HIGH = rover, LOW = base
374
+ pinMode (pin_setupButton , INPUT_PULLUP); // HIGH = rover, LOW = base
311
375
312
376
digitalWrite (pin_positionAccuracyLED_1cm, LOW);
313
377
digitalWrite (pin_positionAccuracyLED_10cm, LOW);
314
378
digitalWrite (pin_positionAccuracyLED_100cm, LOW);
315
379
digitalWrite (pin_baseStatusLED, LOW);
316
380
digitalWrite (pin_bluetoothStatusLED, LOW);
317
381
318
- ledcSetup (ledRedChannel, freq, resolution);
319
- ledcSetup (ledGreenChannel, freq, resolution);
382
+ ledcSetup (ledRedChannel, pwmFreq, pwmResolution);
383
+ ledcSetup (ledGreenChannel, pwmFreq, pwmResolution);
384
+ ledcSetup (ledBTChannel, pwmFreq, pwmResolution);
320
385
321
386
ledcAttachPin (pin_batteryLevelLED_Red, ledRedChannel);
322
387
ledcAttachPin (pin_batteryLevelLED_Green, ledGreenChannel);
388
+ ledcAttachPin (pin_bluetoothStatusLED, ledBTChannel);
323
389
324
390
ledcWrite (ledRedChannel, 0 );
325
391
ledcWrite (ledGreenChannel, 0 );
392
+ ledcWrite (ledBTChannel, 0 );
326
393
}
327
394
}
328
395
@@ -368,19 +435,31 @@ void beginSystemState()
368
435
{
369
436
if (productVariant == RTK_SURVEYOR)
370
437
{
371
- // Assume Rover. checkButtons () will correct as needed.
372
- systemState = STATE_ROVER_NOT_STARTED;
373
- buttonPreviousState = BUTTON_BASE;
438
+ systemState = STATE_ROVER_NOT_STARTED; // Assume Rover. ButtonCheckTask_Switch () will correct as needed.
439
+
440
+ setupBtn = new Button (pin_setupButton); // Create the button in memory
374
441
}
375
- if (productVariant == RTK_EXPRESS || productVariant == RTK_EXPRESS )
442
+ else if (productVariant == RTK_EXPRESS || productVariant == RTK_EXPRESS_PLUS )
376
443
{
377
444
systemState = settings.lastState ; // Return to system state previous to power down.
378
445
379
- if (systemState == STATE_ROVER_NOT_STARTED)
380
- buttonPreviousState = BUTTON_ROVER;
381
- else if (systemState == STATE_BASE_NOT_STARTED)
382
- buttonPreviousState = BUTTON_BASE;
383
- else
384
- buttonPreviousState = BUTTON_ROVER;
446
+ setupBtn = new Button (pin_setupButton); // Create the button in memory
447
+ powerBtn = new Button (pin_powerSenseAndControl); // Create the button in memory
385
448
}
449
+ else if (productVariant == RTK_FACET)
450
+ {
451
+ systemState = settings.lastState ; // Return to system state previous to power down.
452
+
453
+ powerBtn = new Button (pin_powerSenseAndControl); // Create the button in memory
454
+ }
455
+
456
+ // Starts task for monitoring button presses
457
+ if (ButtonCheckTaskHandle == NULL )
458
+ xTaskCreate (
459
+ ButtonCheckTask,
460
+ " BtnCheck" , // Just for humans
461
+ buttonTaskStackSize, // Stack Size
462
+ NULL , // Task input parameter
463
+ ButtonCheckTaskPriority, // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
464
+ &ButtonCheckTaskHandle); // Task handle
386
465
}
0 commit comments