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};
9796const 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[] =
106104const 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.
282286void 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