Skip to content

Commit 6d6b0e6

Browse files
committed
Add isBlocking
Allow check to see if Unicore library needs lone control of serial hardware.
1 parent 59e841f commit 6d6b0e6

File tree

2 files changed

+159
-148
lines changed

2 files changed

+159
-148
lines changed

src/SparkFun_Unicore_GNSS_Arduino_Library.cpp

Lines changed: 91 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -81,23 +81,21 @@
8181
//----------------------------------------
8282

8383
// parserTable index values
84-
#define UM980_NMEA_PARSER_INDEX 0
85-
#define UM980_UNICORE_HASH_PARSER_INDEX 1
86-
#define UM980_RTCM_PARSER_INDEX 2
87-
#define UM980_UNICORE_BINARY_PARSER_INDEX 3
84+
#define UM980_NMEA_PARSER_INDEX 0
85+
#define UM980_UNICORE_HASH_PARSER_INDEX 1
86+
#define UM980_RTCM_PARSER_INDEX 2
87+
#define UM980_UNICORE_BINARY_PARSER_INDEX 3
8888

8989
// Build the table listing all of the parsers
90-
SEMP_PARSE_ROUTINE const parserTable[] =
91-
{
90+
SEMP_PARSE_ROUTINE const parserTable[] = {
9291
sempNmeaPreamble,
9392
sempUnicoreHashPreamble,
9493
sempRtcmPreamble,
9594
sempUnicoreBinaryPreamble,
9695
};
9796
const int parserCount = sizeof(parserTable) / sizeof(parserTable[0]);
9897

99-
const char * const parserNames[] =
100-
{
98+
const char *const parserNames[] = {
10199
"UN980 NMEA Parser",
102100
"UM980 Unicore Hash (#) Parser",
103101
"UM980 RTCM Parser",
@@ -106,7 +104,7 @@ const char * const parserNames[] =
106104
const int parserNameCount = sizeof(parserNames) / sizeof(parserNames[0]);
107105

108106
// Account for the largest message
109-
#define BUFFER_LENGTH 3000
107+
#define BUFFER_LENGTH 3000
110108

111109
//----------------------------------------
112110
// Globals
@@ -161,7 +159,7 @@ bool badNmeaChecksum(SEMP_PARSE_STATE *parse)
161159
}
162160

163161
// Translate the state value into an ASCII state name
164-
const char * um980GetStateName(SEMP_PARSE_STATE *parse)
162+
const char *um980GetStateName(SEMP_PARSE_STATE *parse)
165163
{
166164
const char *name;
167165

@@ -224,11 +222,9 @@ bool UM980::begin(HardwareSerial &serialPort, Print *parserDebug, Print *parserE
224222
_hwSerialPort = &serialPort;
225223

226224
// Initialize the parser
227-
_sempParse = sempBeginParser(parserTable, parserCount,
228-
parserNames, parserNameCount,
229-
0, BUFFER_LENGTH, um980ProcessMessage,
230-
"SFE_Unicore_GNSS_Library", parserError,
231-
parserDebug, badNmeaChecksum);
225+
_sempParse =
226+
sempBeginParser(parserTable, parserCount, parserNames, parserNameCount, 0, BUFFER_LENGTH, um980ProcessMessage,
227+
"SFE_Unicore_GNSS_Library", parserError, parserDebug, badNmeaChecksum);
232228
if (!_sempParse)
233229
{
234230
debugPrintf("UM980: Failed to initialize the parser!");
@@ -277,6 +273,14 @@ bool UM980::isConnected()
277273
return (false);
278274
}
279275

276+
// If another task outside of this library is accessing the same Serial hardware, it can
277+
// check to see if this library currently needs exclusive read/write access for a short period.
278+
// If isBlocking is true, external consumers should not read/write to the Serial hardware
279+
bool UM980::isBlocking()
280+
{
281+
return(unicoreLibrarySemaphoreBlock);
282+
}
283+
280284
// Calling this function with nothing sets the debug port to Serial
281285
// You can also call it with other streams like Serial1, SerialUSB, etc.
282286
void UM980::enableDebugging(Print &debugPort)
@@ -331,9 +335,8 @@ bool UM980::updateOnce()
331335
endName = um980GetStateName(_sempParse);
332336

333337
// Display the parser state transition
334-
debugPrintf("UM980: 0x%02x (%c), crc: 0x%08x, state: %s --> %s",
335-
incoming, ((incoming >= ' ') && (incoming < 0x7f)) ? incoming : '.',
336-
_sempParse->crc, startName, endName);
338+
debugPrintf("UM980: 0x%02x (%c), crc: 0x%08x, state: %s --> %s", incoming,
339+
((incoming >= ' ') && (incoming < 0x7f)) ? incoming : '.', _sempParse->crc, startName, endName);
337340
}
338341
return (true);
339342
}
@@ -380,7 +383,8 @@ void UM980::dumpBuffer(const uint8_t *buffer, uint16_t length)
380383

381384
// Display the ASCII values
382385
for (index = 0; index < bytes; index++)
383-
sprintf(&line[strlen(line)], "%c", ((buffer[index] < ' ') || (buffer[index] >= 0x7f)) ? '.' : buffer[index]);
386+
sprintf(&line[strlen(line)], "%c",
387+
((buffer[index] < ' ') || (buffer[index] >= 0x7f)) ? '.' : buffer[index]);
384388
debugPrintf("%s", line);
385389

386390
// Set the next line of data
@@ -425,27 +429,23 @@ void um980ProcessMessage(SEMP_PARSE_STATE *parse, uint16_t type)
425429
ptrUM980->debugPrintf("");
426430
switch (type)
427431
{
428-
case UM980_NMEA_PARSER_INDEX:
429-
ptrUM980->debugPrintf("Valid NMEA Sentence: %s, 0x%04x (%d) bytes",
430-
sempNmeaGetSentenceName(parse),
431-
parse->length, parse->length);
432-
break;
432+
case UM980_NMEA_PARSER_INDEX:
433+
ptrUM980->debugPrintf("Valid NMEA Sentence: %s, 0x%04x (%d) bytes", sempNmeaGetSentenceName(parse),
434+
parse->length, parse->length);
435+
break;
433436

434-
case UM980_UNICORE_HASH_PARSER_INDEX:
435-
ptrUM980->debugPrintf("Valid Unicore Hash (#) Sentence: %s, 0x%04x (%d) bytes",
436-
sempUnicoreHashGetSentenceName(parse),
437-
parse->length, parse->length);
438-
break;
437+
case UM980_UNICORE_HASH_PARSER_INDEX:
438+
ptrUM980->debugPrintf("Valid Unicore Hash (#) Sentence: %s, 0x%04x (%d) bytes",
439+
sempUnicoreHashGetSentenceName(parse), parse->length, parse->length);
440+
break;
439441

440-
case UM980_RTCM_PARSER_INDEX:
441-
ptrUM980->debugPrintf("Valid RTCM message: 0x%04x (%d) bytes",
442-
parse->length, parse->length);
443-
break;
442+
case UM980_RTCM_PARSER_INDEX:
443+
ptrUM980->debugPrintf("Valid RTCM message: 0x%04x (%d) bytes", parse->length, parse->length);
444+
break;
444445

445-
case UM980_UNICORE_BINARY_PARSER_INDEX:
446-
ptrUM980->debugPrintf("Valid Unicore message: 0x%04x (%d) bytes",
447-
parse->length, parse->length);
448-
break;
446+
case UM980_UNICORE_BINARY_PARSER_INDEX:
447+
ptrUM980->debugPrintf("Valid Unicore message: 0x%04x (%d) bytes", parse->length, parse->length);
448+
break;
449449
}
450450
}
451451

@@ -456,62 +456,59 @@ void um980ProcessMessage(SEMP_PARSE_STATE *parse, uint16_t type)
456456
// Process the message
457457
switch (type)
458458
{
459-
case UM980_UNICORE_BINARY_PARSER_INDEX:
460-
ptrUM980->unicoreHandler(parse->buffer, parse->length);
461-
break;
459+
case UM980_UNICORE_BINARY_PARSER_INDEX:
460+
ptrUM980->unicoreHandler(parse->buffer, parse->length);
461+
break;
462462

463-
case UM980_RTCM_PARSER_INDEX:
464-
break;
463+
case UM980_RTCM_PARSER_INDEX:
464+
break;
465465

466-
case UM980_UNICORE_HASH_PARSER_INDEX:
466+
case UM980_UNICORE_HASH_PARSER_INDEX:
467+
// Does this response contain the command we are looking for?
468+
if (strcasecmp((char *)scratchPad->unicoreHash.sentenceName, ptrUM980->commandName) == 0) // Found
469+
{
470+
ptrUM980->debugPrintf("UM980: Query response: %s", parse->buffer);
471+
ptrUM980->commandResponse = UM980_RESULT_RESPONSE_COMMAND_OK;
472+
}
473+
break;
474+
475+
case UM980_NMEA_PARSER_INDEX:
476+
//$command,MODE,response: OK*5D
477+
if (strcasecmp((char *)scratchPad->nmea.sentenceName, "command") != 0 &&
478+
strcasecmp((char *)scratchPad->nmea.sentenceName, "MASK") != 0 &&
479+
strcasecmp((char *)scratchPad->nmea.sentenceName, "CONFIG") != 0) // Found
480+
481+
// Unknown response, ignore this message
482+
ptrUM980->debugPrintf("UM980: Message ignored: %s", parse->buffer);
483+
else
484+
{
467485
// Does this response contain the command we are looking for?
468-
if (strcasecmp((char *)scratchPad->unicoreHash.sentenceName, ptrUM980->commandName) == 0) // Found
486+
// It may be anywhere in the response:
487+
// $command,MODE,response: OK*5D
488+
char *responsePointer = strcasestr((char *)parse->buffer, ptrUM980->commandName);
489+
if (responsePointer != nullptr) // Found
469490
{
470-
ptrUM980->debugPrintf("UM980: Query response: %s",
471-
parse->buffer);
472-
ptrUM980->commandResponse = UM980_RESULT_RESPONSE_COMMAND_OK;
473-
}
474-
break;
491+
// Display the command response
492+
ptrUM980->debugPrintf("UM980: Command response: %s", parse->buffer);
475493

476-
case UM980_NMEA_PARSER_INDEX:
477-
//$command,MODE,response: OK*5D
478-
if (strcasecmp((char *)scratchPad->nmea.sentenceName, "command") != 0 &&
479-
strcasecmp((char *)scratchPad->nmea.sentenceName, "MASK") != 0 &&
480-
strcasecmp((char *)scratchPad->nmea.sentenceName, "CONFIG") != 0) // Found
481-
482-
// Unknown response, ignore this message
483-
ptrUM980->debugPrintf("UM980: Message ignored: %s", parse->buffer);
484-
else
485-
{
486-
// Does this response contain the command we are looking for?
487-
// It may be anywhere in the response:
488-
// $command,MODE,response: OK*5D
489-
char *responsePointer = strcasestr((char *)parse->buffer, ptrUM980->commandName);
494+
// Check to see if we got a command response
495+
responsePointer = strcasestr((char *)parse->buffer, "OK");
490496
if (responsePointer != nullptr) // Found
491497
{
492-
// Display the command response
493-
ptrUM980->debugPrintf("UM980: Command response: %s",
494-
parse->buffer);
495-
496-
// Check to see if we got a command response
497-
responsePointer = strcasestr((char *)parse->buffer, "OK");
498-
if (responsePointer != nullptr) // Found
499-
{
500-
ptrUM980->commandResponse = UM980_RESULT_RESPONSE_COMMAND_OK;
501-
return;
502-
}
503-
504-
responsePointer = strcasestr((char *)parse->buffer, "PARSING");
505-
if (responsePointer != nullptr) // Found
506-
{
507-
ptrUM980->debugPrintf("UM980: Error response: %s",
508-
parse->buffer);
509-
ptrUM980->commandResponse = UM980_RESULT_RESPONSE_COMMAND_ERROR;
510-
return;
511-
}
498+
ptrUM980->commandResponse = UM980_RESULT_RESPONSE_COMMAND_OK;
499+
return;
500+
}
501+
502+
responsePointer = strcasestr((char *)parse->buffer, "PARSING");
503+
if (responsePointer != nullptr) // Found
504+
{
505+
ptrUM980->debugPrintf("UM980: Error response: %s", parse->buffer);
506+
ptrUM980->commandResponse = UM980_RESULT_RESPONSE_COMMAND_ERROR;
507+
return;
512508
}
513509
}
514-
break;
510+
}
511+
break;
515512
}
516513
}
517514

@@ -966,13 +963,16 @@ Um980Result UM980::sendQuery(const char *command, uint16_t maxWaitMs)
966963
strncpy(commandName, command, sizeof(commandName));
967964
commandResponse = UM980_RESULT_RESPONSE_COMMAND_WAITING; // Reset
968965

966+
unicoreLibrarySemaphoreBlock = true; // Prevent external tasks from harvesting serial data
967+
969968
// Feed the parser until we see a response to the command
970969
int wait = 0;
971970
while (1)
972971
{
973972
if (wait++ == maxWaitMs)
974973
{
975974
debugPrintf("UM980: Response timeout");
975+
unicoreLibrarySemaphoreBlock = false; // Allow external tasks to control serial hardware
976976
return (UM980_RESULT_TIMEOUT_RESPONSE);
977977
}
978978

@@ -987,12 +987,15 @@ Um980Result UM980::sendQuery(const char *command, uint16_t maxWaitMs)
987987
if (commandResponse == UM980_RESULT_RESPONSE_COMMAND_ERROR)
988988
{
989989
debugPrintf("UM980: Query failure");
990+
unicoreLibrarySemaphoreBlock = false; // Allow external tasks to control serial hardware
990991
return (UM980_RESULT_RESPONSE_COMMAND_ERROR);
991992
}
992993

993994
delay(1);
994995
}
995996

997+
unicoreLibrarySemaphoreBlock = false; // Allow external tasks to control serial hardware
998+
996999
return (UM980_RESULT_OK);
9971000
}
9981001

@@ -1010,6 +1013,8 @@ Um980Result UM980::sendString(const char *command, uint16_t maxWaitMs)
10101013
strncpy(commandName, command, sizeof(commandName)); // Copy to class so that parsers can see it
10111014
commandResponse = UM980_RESULT_RESPONSE_COMMAND_WAITING; // Reset
10121015

1016+
unicoreLibrarySemaphoreBlock = true; // Prevent external tasks from harvesting serial data
1017+
10131018
serialPrintln(command);
10141019

10151020
// Feed the parser until we see a response to the command
@@ -1039,6 +1044,8 @@ Um980Result UM980::sendString(const char *command, uint16_t maxWaitMs)
10391044
delay(1);
10401045
}
10411046

1047+
unicoreLibrarySemaphoreBlock = false; // Allow external tasks to control serial hardware
1048+
10421049
return (UM980_RESULT_OK);
10431050
}
10441051

0 commit comments

Comments
 (0)