Skip to content

Commit 6414616

Browse files
authored
Merge pull request #277 from LeeLeahy2/usb-serial
Switch USB serial output to GNSS data with system/operation menu and back to status and debug messages using +++
2 parents 05db063 + 4130719 commit 6414616

File tree

6 files changed

+175
-13
lines changed

6 files changed

+175
-13
lines changed

Firmware/RTK_Everywhere/RTK_Everywhere.ino

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,29 @@ float batteryChargingPercentPerHour;
445445
#include "bluetoothSelect.h"
446446
#endif // COMPILE_BT
447447

448+
// This value controls the data that is output from the USB serial port
449+
// to the host PC. By default (false) status and debug messages are output
450+
// to the USB serial port. When this value is set to true then the status
451+
// and debug messages are discarded and only GNSS data is output to USB
452+
// serial.
453+
//
454+
// Switching from status and debug messages to GNSS output is done in two
455+
// places, at the end of setup and at the end of maenuMain. In both of
456+
// these places the new value comes from settings.enableGnssToUsbSerial.
457+
// Upon boot status and debug messages are output at least until the end
458+
// of setup. Upon entry into menuMain, this value is set false to again
459+
// output menu output, status and debug messages to be output. At the end
460+
// of setup the value is updated and if enabled GNSS data is sent to the
461+
// USB serial port and PC.
462+
volatile bool forwardGnssDataToUsbSerial;
463+
464+
// Timeout between + characters to enter the +++ sequence while
465+
// forwardGnssDataToUsbSerial is true. When sequence is properly entered
466+
// forwardGnssDataToUsbSerial is set to false and menuMain is displayed.
467+
// If the timeout between characters occurs or an invalid character is
468+
// entered then no changes are made and the +++ sequence must be re-entered.
469+
#define PLUS_PLUS_PLUS_TIMEOUT (2 * 1000) // Milliseconds
470+
448471
#define platformPrefix platformPrefixTable[productVariant] // Sets the prefix for broadcast names
449472

450473
#include <driver/uart.h> //Required for uart_set_rx_full_threshold() on cores <v2.0.5
@@ -1113,6 +1136,10 @@ void setup()
11131136
systemPrintf("%8d mSec: Total boot time\r\n", bootTime[bootTimeIndex]);
11141137
systemPrintln();
11151138
}
1139+
1140+
// If necessary, switch to sending GNSS data out the USB serial port
1141+
// to the PC
1142+
forwardGnssDataToUsbSerial = settings.enableGnssToUsbSerial;
11161143
}
11171144

11181145
void loop()

Firmware/RTK_Everywhere/Tasks.ino

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,13 @@ enum RingBufferConsumers
5656
RBC_TCP_SERVER,
5757
RBC_SD_CARD,
5858
RBC_UDP_SERVER,
59+
RBC_USB_SERIAL,
5960
// Insert new consumers here
6061
RBC_MAX
6162
};
6263

6364
const char *const ringBufferConsumer[] = {
64-
"Bluetooth", "TCP Client", "TCP Server", "SD Card", "UDP Server",
65+
"Bluetooth", "TCP Client", "TCP Server", "SD Card", "UDP Server", "USB Serial",
6566
};
6667

6768
const int ringBufferConsumerEntries = sizeof(ringBufferConsumer) / sizeof(ringBufferConsumer[0]);
@@ -101,6 +102,7 @@ unsigned long lastGnssSend; // Timestamp of the last time we sent RTCM to GNSS
101102
// Ring buffer tails
102103
static RING_BUFFER_OFFSET btRingBufferTail; // BT Tail advances as it is sent over BT
103104
static RING_BUFFER_OFFSET sdRingBufferTail; // SD Tail advances as it is recorded to SD
105+
static RING_BUFFER_OFFSET usbRingBufferTail; // USB Tail advances as it is sent over USB serial
104106

105107
// Ring buffer offsets
106108
static uint16_t rbOffsetHead;
@@ -898,6 +900,58 @@ void handleGnssDataTask(void *e)
898900
}
899901
}
900902

903+
//----------------------------------------------------------------------
904+
// Send data over USB serial
905+
//----------------------------------------------------------------------
906+
907+
startMillis = millis();
908+
909+
// Determine USB serial connection state
910+
if (!forwardGnssDataToUsbSerial)
911+
// Discard the data
912+
usbRingBufferTail = dataHead;
913+
else
914+
{
915+
// Determine the amount of USB serial data in the buffer
916+
bytesToSend = dataHead - usbRingBufferTail;
917+
if (bytesToSend < 0)
918+
bytesToSend += settings.gnssHandlerBufferSize;
919+
if (bytesToSend > 0)
920+
{
921+
// Reduce bytes to send if we have more to send then the end of
922+
// the buffer, we'll wrap next loop
923+
if ((usbRingBufferTail + bytesToSend) > settings.gnssHandlerBufferSize)
924+
bytesToSend = settings.gnssHandlerBufferSize - usbRingBufferTail;
925+
926+
// Send data over USB serial to the PC
927+
bytesToSend = systemWriteGnssDataToUsbSerial(&ringBuffer[usbRingBufferTail], bytesToSend);
928+
929+
// Account for the data that was sent
930+
if (bytesToSend > 0)
931+
{
932+
// Account for the sent or dropped data
933+
usbRingBufferTail += bytesToSend;
934+
if (usbRingBufferTail >= settings.gnssHandlerBufferSize)
935+
usbRingBufferTail -= settings.gnssHandlerBufferSize;
936+
937+
// Remember the maximum transfer time
938+
deltaMillis = millis() - startMillis;
939+
if (maxMillis[RBC_USB_SERIAL] < deltaMillis)
940+
maxMillis[RBC_USB_SERIAL] = deltaMillis;
941+
}
942+
943+
// Determine the amount of data that remains in the buffer
944+
bytesToSend = dataHead - usbRingBufferTail;
945+
if (bytesToSend < 0)
946+
bytesToSend += settings.gnssHandlerBufferSize;
947+
if (usedSpace < bytesToSend)
948+
{
949+
usedSpace = bytesToSend;
950+
slowConsumer = "USB Serial";
951+
}
952+
}
953+
}
954+
901955
//----------------------------------------------------------------------
902956
// Send data to the network clients
903957
//----------------------------------------------------------------------

Firmware/RTK_Everywhere/menuMain.ino

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ void terminalUpdate()
1111
periodicDisplay = settings.periodicDisplay;
1212
}
1313

14+
// Check for USB serial input
1415
if (systemAvailable())
1516
{
1617
byte incoming = systemRead();
@@ -21,13 +22,49 @@ void terminalUpdate()
2122
printCurrentConditionsNMEA();
2223
}
2324
else
25+
{
26+
// When outputting GNSS data to USB serial, check for +++
27+
if (forwardGnssDataToUsbSerial)
28+
{
29+
static uint32_t plusTimeout;
30+
static uint8_t plusCount;
31+
32+
// Reset plusCount on timeout
33+
if ((millis() - plusTimeout) > PLUS_PLUS_PLUS_TIMEOUT)
34+
plusCount = 0;
35+
36+
// Check for + input
37+
if (incoming != '+')
38+
{
39+
// Must start over looking for +++
40+
plusCount = 0;
41+
return;
42+
}
43+
else
44+
{
45+
// + entered, check for the +++ sequence
46+
plusCount++;
47+
if (plusCount < 3)
48+
{
49+
// Restart the timeout
50+
plusTimeout = millis();
51+
return;
52+
}
53+
54+
// +++ was entered, display the main menu
55+
}
56+
}
2457
menuMain(); // Present user menu
58+
}
2559
}
2660
}
2761

2862
// Display the main menu configuration options
2963
void menuMain()
3064
{
65+
// Redirect menu output, status and debug messages to the USB serial port
66+
forwardGnssDataToUsbSerial = false;
67+
3168
inMainMenu = true;
3269
displaySerialConfig(); // Display 'Serial Config' while user is configuring
3370

@@ -259,6 +296,9 @@ void menuMain()
259296
clearBuffer(); // Empty buffer of any newline chars
260297
btPrintEchoExit = false; // We are out of the menu system
261298
inMainMenu = false;
299+
300+
// Change the USB serial output behavior if necessary
301+
forwardGnssDataToUsbSerial = settings.enableGnssToUsbSerial;
262302
}
263303

264304
// Change system wide settings based on current user profile

Firmware/RTK_Everywhere/menuSystem.ino

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ void menuSystem()
156156
systemPrintf("Filtered by parser: %d NMEA / %d RTCM / %d UBX\r\n", failedParserMessages_NMEA,
157157
failedParserMessages_RTCM, failedParserMessages_UBX);
158158

159+
// Display the USB serial output status
160+
menuSystemDisplayUsbSerialOutput(settings.enableGnssToUsbSerial);
161+
162+
//---------------------------
163+
// Start of menu
164+
//---------------------------
165+
159166
systemPrintln();
160167
systemPrintln("Menu: System");
161168
// Separate the menu from the status
@@ -211,7 +218,7 @@ void menuSystem()
211218

212219
systemPrintln("n) Debug network");
213220

214-
systemPrintln("o) Configure RTK operation");
221+
systemPrintln("o) Configure operation");
215222

216223
systemPrintln("p) Configure periodic print messages");
217224

@@ -429,7 +436,7 @@ void menuDebugHardware()
429436
systemPrintf("%s\r\n", settings.enableImuCompensationDebug ? "Enabled" : "Disabled");
430437

431438
if (present.gnss_um980)
432-
systemPrintln("13) UM980 Direct connect");
439+
systemPrintln("13) UM980 direct connect");
433440

434441
systemPrint("14) PSRAM (");
435442
if (ESP.getPsramSize() == 0)
@@ -939,7 +946,11 @@ void menuOperation()
939946
systemPrintln(settings.uartReceiveBufferSize);
940947

941948
// ZED
942-
systemPrintln("10) Mirror ZED-F9x's UART1 settings to USB");
949+
if(present.gnss_zedf9p)
950+
systemPrintln("10) Mirror ZED-F9x's UART1 settings to USB");
951+
952+
// USB Serial
953+
systemPrintln("11) Output GNSS data to USB serial");
943954

944955
systemPrintln("---- Interrupts ----");
945956
systemPrint("30) Bluetooth Interrupts Core: ");
@@ -1032,7 +1043,7 @@ void menuOperation()
10321043
ESP.restart();
10331044
}
10341045
}
1035-
else if (incoming == 10)
1046+
else if (incoming == 10 && present.gnss_zedf9p)
10361047
{
10371048
bool response = gnssSetMessagesUsb(MAX_SET_MESSAGES_RETRIES);
10381049

@@ -1042,6 +1053,12 @@ void menuOperation()
10421053
systemPrintln(F("USB messages successfully enabled"));
10431054
}
10441055

1056+
else if (incoming == 11)
1057+
{
1058+
settings.enableGnssToUsbSerial ^= 1;
1059+
menuSystemDisplayUsbSerialOutput(settings.enableGnssToUsbSerial);
1060+
}
1061+
10451062
else if (incoming == 30)
10461063
{
10471064
getNewSetting("Not yet implemented! - Enter Core used for Bluetooth Interrupts", 0, 1,
@@ -1094,6 +1111,15 @@ void menuOperation()
10941111
clearBuffer(); // Empty buffer of any newline chars
10951112
}
10961113

1114+
// Display the USB serial output
1115+
void menuSystemDisplayUsbSerialOutput(bool gnssData)
1116+
{
1117+
if (gnssData)
1118+
systemPrintln("USB Serial output is GNSS data");
1119+
else
1120+
systemPrintln("USB Serial output is status and debug messages");
1121+
}
1122+
10971123
// Toggle periodic print message enables
10981124
void menuPeriodicPrint()
10991125
{

Firmware/RTK_Everywhere/settings.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -976,7 +976,7 @@ typedef struct
976976
const uint32_t frequency; // L-Band frequency, Hz, if supported. 0 if not supported
977977
} Regional_Information;
978978

979-
const Regional_Information Regional_Information_Table[] =
979+
const Regional_Information Regional_Information_Table[] =
980980
{
981981
{ "US", "us", { 50.0, 25.0, -60.0, -125.0}, 1556290000 },
982982
{ "EU", "eu", { 72.0, 36.0, 32.0, -11.0}, 1545260000 },
@@ -1324,6 +1324,8 @@ struct Settings
13241324
uint8_t wifiChannel = 1; //Valid channels are 1 to 14
13251325
bool enableGalileoHas = true; // Allow E6 corrections if possible
13261326

1327+
bool enableGnssToUsbSerial = false;
1328+
13271329
// Add new settings above <------------------------------------------------------------>
13281330
// Then also add to rtkSettingsEntries below
13291331

@@ -1627,6 +1629,8 @@ const RTK_Settings_Entry rtkSettingsEntries[] = {
16271629
{ & settings.wifiChannel, "wifiChannel", _uint8_t, 0, false, true, true },
16281630
{ & settings.enableGalileoHas, "enableGalileoHas", _bool, 0, false, true, true },
16291631

1632+
{ & settings.enableGnssToUsbSerial, "enableGnssToUsbSerial", _bool, 0, false, true, true },
1633+
16301634
// Add new settings above <------------------------------------------------------------>
16311635
/*
16321636
{ & settings., "", , 0, false, true },

Firmware/RTK_Everywhere/support.ino

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,28 @@ int systemRead()
1919
// Output a buffer of the specified length to the serial port
2020
void systemWrite(const uint8_t *buffer, uint16_t length)
2121
{
22-
if (printEndpoint == PRINT_ENDPOINT_ALL)
23-
{
24-
Serial.write(buffer, length);
25-
bluetoothWrite(buffer, length);
26-
}
27-
else if (printEndpoint == PRINT_ENDPOINT_BLUETOOTH)
22+
// Output data to bluetooth if necessary
23+
if ((printEndpoint == PRINT_ENDPOINT_ALL)
24+
|| (printEndpoint == PRINT_ENDPOINT_BLUETOOTH))
2825
bluetoothWrite(buffer, length);
29-
else
26+
27+
// Output data to USB serial if necessary
28+
if ((printEndpoint != PRINT_ENDPOINT_BLUETOOTH)
29+
&& (!forwardGnssDataToUsbSerial))
3030
Serial.write(buffer, length);
3131
}
3232

33+
// Forward GNSS data to the USB serial port
34+
size_t systemWriteGnssDataToUsbSerial(const uint8_t *buffer, uint16_t length)
35+
{
36+
// Determine if status and debug messages are being output to USB serial
37+
if (!forwardGnssDataToUsbSerial)
38+
return length;
39+
40+
// Output GNSS data to USB serial
41+
return Serial.write(buffer, length);
42+
}
43+
3344
// Ensure all serial output has been transmitted, FIFOs are empty
3445
void systemFlush()
3546
{

0 commit comments

Comments
 (0)