@@ -420,7 +420,8 @@ void um980ProcessMessage(SEMP_PARSE_STATE *parse, uint16_t type)
420420 // Does this response contain the command we are looking for?
421421 if (strcasecmp ((char *)scratchPad->unicoreHash .sentenceName , ptrUM980->commandName ) == 0 ) // Found
422422 {
423- ptrUM980->debugPrintf (" Unicore Lib: Query response: %s" , parse->buffer );
423+ ptrUM980->debugPrintf (" Hash response: %s" , parse->buffer );
424+ ptrUM980->modeHandler (parse->buffer , parse->length );
424425 ptrUM980->commandResponse = UM980_RESULT_RESPONSE_COMMAND_OK;
425426 }
426427 break ;
@@ -502,6 +503,67 @@ bool UM980::setMode(const char *modeType)
502503 return (sendCommand (command));
503504}
504505
506+ // getMode returns int representing its current mode
507+ // #MODE,97,GPS,FINE,2389,337235000,0,0,18,969;MODE ROVER SURVEY,*18
508+ // #MODE,97,GPS,FINE,2389,338172000,0,0,18,968;MODE BASE TIME 60,*72
509+ // #MODE,97,GPS,FINE,2283,499142000,0,0,18,22;MODE BASE -1280206.5680 -4716804.4030 4086665.4840,*60
510+ // Unknown = 0
511+ // SURVEY = 1
512+ // UAV = 2
513+ // AUTOMOTIVE = 3
514+ // BASE with survey time (survey-in) = 4
515+ // BASE with fixed coordinates = 5
516+ int8_t UM980::getMode (uint16_t maxWaitMs)
517+ {
518+ Um980Result result;
519+
520+ clearBuffer ();
521+
522+ // Send command and check for OK response
523+ result = sendString (" MODE" , maxWaitMs);
524+ if (result != UM980_RESULT_OK)
525+ return (-2 );
526+
527+ commandResponse = UM980_RESULT_RESPONSE_COMMAND_WAITING; // Reset
528+
529+ modeType = UM980_MODE_UNKNOWN; // Reset
530+
531+ unicoreLibrarySemaphoreBlock = true ; // Prevent external tasks from harvesting serial data
532+
533+ // Feed the parser until we see a response to the command
534+ int wait = 0 ;
535+ while (1 )
536+ {
537+ if (wait++ == maxWaitMs)
538+ {
539+ debugPrintf (" Unicore Lib: Response timeout" );
540+ unicoreLibrarySemaphoreBlock = false ; // Allow external tasks to control serial hardware
541+ return (-1 );
542+ }
543+
544+ updateOnce (); // Will call um980ProcessMessage() and modeHandler()
545+
546+ if (modeType != UM980_MODE_UNKNOWN)
547+ {
548+ unicoreLibrarySemaphoreBlock = false ; // Allow external tasks to control serial hardware
549+ return ((int8_t )modeType);
550+ }
551+
552+ if (commandResponse == UM980_RESULT_RESPONSE_COMMAND_ERROR)
553+ {
554+ debugPrintf (" Unicore Lib: Query failure" );
555+ unicoreLibrarySemaphoreBlock = false ; // Allow external tasks to control serial hardware
556+ return (-2 );
557+ }
558+
559+ delay (1 );
560+ }
561+
562+ unicoreLibrarySemaphoreBlock = false ; // Allow external tasks to control serial hardware
563+
564+ return (-3 ); // Uncaught error
565+ }
566+
505567// Directly set a base mode: setModeBase("40.09029479 -105.18505761 1560.089")
506568bool UM980::setModeBase (const char *baseType)
507569{
@@ -1044,6 +1106,8 @@ bool UM980::sendCommand(const char *command, uint16_t maxWaitMs)
10441106// Looks for a query response ('#')
10451107// Some commands like MASK or CONFIG have responses that begin with $
10461108// '#' begins the responses to queries, ie 'MODE', ends with the result (ie MODE ROVER)
1109+ // #MODE,97,GPS,FINE,2389,337235000,0,0,18,969;MODE ROVER SURVEY,*18
1110+ // #MODE,97,GPS,FINE,2389,338172000,0,0,18,968;MODE BASE TIME 60,*72
10471111// #MODE,97,GPS,FINE,2283,499142000,0,0,18,22;MODE BASE -1280206.5680 -4716804.4030 4086665.4840,*60
10481112
10491113// '$' begins the responses to commands, ie 'MODE ROVER', ends with OK
@@ -1769,6 +1833,76 @@ char *UM980::getVersionFull(uint16_t maxWaitMs)
17691833 return ((char *)" Error2" );
17701834}
17711835
1836+ // Cracks a given MODE response into settings
1837+ void UM980::modeHandler (uint8_t *response, uint16_t length)
1838+ {
1839+ // We've received a response such as #MODE,97,GPS,FINE,2389,338172000,0,0,18,968;MODE BASE TIME 60,*72
1840+ modeType = UM980_MODE_UNKNOWN;
1841+
1842+ // Extract the mode type
1843+ char *responsePointer = strcasestr ((char *)response, " ;MODE" );
1844+ if (responsePointer != nullptr ) // Found
1845+ {
1846+ // Obtain the value following the search string
1847+ responsePointer += strlen (" ;MODE" ); // Move the position to the end of the word
1848+
1849+ // Skip any whitespace
1850+ while (*responsePointer && isspace (*responsePointer))
1851+ responsePointer++;
1852+
1853+ // Now 'responsePointer' should point at the start of the next term
1854+
1855+ char *typePointer = nullptr ;
1856+
1857+ typePointer = strcasestr (responsePointer, " BASE" );
1858+ if (typePointer != nullptr ) // Found
1859+ {
1860+ char *baseTypePointer = nullptr ;
1861+ baseTypePointer = strcasestr (typePointer, " TIME" );
1862+ if (baseTypePointer != nullptr ) // Found
1863+ {
1864+ modeType = UM980_MODE_BASE_SURVEY_IN;
1865+ }
1866+ else
1867+ {
1868+ // Response contains non-text such as:
1869+ // #MODE,97,GPS,FINE,2283,499142000,0,0,18,22;MODE BASE -1280206.5680 -4716804.4030 4086665.4840,*60
1870+ modeType = UM980_MODE_BASE_FIXED;
1871+ }
1872+ }
1873+ else
1874+ {
1875+ // Response contains ROVER
1876+ // #MODE,97,GPS,FINE,2389,337235000,0,0,18,969;MODE ROVER SURVEY,*18
1877+
1878+ typePointer = strcasestr (responsePointer, " SURVEY" );
1879+ if (typePointer != nullptr ) // Found
1880+ {
1881+ modeType = UM980_MODE_ROVER_SURVEY;
1882+ return ;
1883+ }
1884+
1885+ typePointer = strcasestr (responsePointer, " UAV" );
1886+ if (typePointer != nullptr ) // Found
1887+ {
1888+ modeType = UM980_MODE_ROVER_UAV;
1889+ return ;
1890+ }
1891+
1892+ typePointer = strcasestr (responsePointer, " AUTOMOTIVE" );
1893+ if (typePointer != nullptr ) // Found
1894+ {
1895+ modeType = UM980_MODE_ROVER_AUTOMOTIVE;
1896+ return ;
1897+ }
1898+ }
1899+ }
1900+ else
1901+ {
1902+ // This mode response did not contain ;MODE
1903+ }
1904+ }
1905+
17721906// Cracks a given CONFIG response into settings
17731907void UM980::configHandler (uint8_t *response, uint16_t length)
17741908{
0 commit comments