Merge pull request #176 from ladyada-eagleclaw/main

Store GPS source and sentence tables in flash
This commit is contained in:
Limor "Ladyada" Fried authored and GitHub committed 2026-09-15 11:36:50 -04:00
commit 976908d647
2 files changed
+32 -30

No files matched your search

+5 -18
View File
@@ -244,7 +244,7 @@ private:
// NMEA_data.cpp
void data_init();
// NMEA_parse.cpp
const char *tokenOnList(char *token, const char **list);
const char *tokenOnList(char *token, const char list[][4]);
bool parseCoord(char *p, nmea_float_t *angleDegrees = NULL,
nmea_float_t *angle = NULL, int32_t *angle_fixed = NULL,
char *dir = NULL);
@@ -254,23 +254,10 @@ private:
bool parseAntenna(char *);
bool isEmpty(char *pStart);
// used by check() for validity tests, room for future expansion
const char *sources[9] = {"II", "WI", "GP", "PG", "GL",
"GA", "GN", "P", "ZZZ"}; ///< valid source ids
#ifdef NMEA_EXTENSIONS
const char *sentences_parsed[21] = {"GGA", "GLL", "GSA", "RMC", "DBT", "HDM",
"HDT", "MDA", "MTW", "MWV", "RMB", "TOP",
"TXT", "VHW", "VLW", "VPW", "VWR", "WCV",
"XTE", "ZZZ"}; ///< parseable sentence ids
const char *sentences_known[15] = {
"APB", "DPT", "GSV", "HDG", "MWD", "ROT",
"RPM", "RSA", "VDR", "VTG", "ZDA", "ZZZ"}; ///< known, but not parseable
#else // make the lists short to save memory
const char *sentences_parsed[6] = {"GGA", "GLL", "GSA", "RMC",
"TOP", "ZZZ"}; ///< parseable sentence ids
const char *sentences_known[4] = {"DBT", "HDM", "HDT",
"ZZZ"}; ///< known, but not parseable
#endif
// Shared flash tables avoid RAM copies of both the IDs and their pointers.
static const char PROGMEM sources[][4]; ///< valid source ids
static const char PROGMEM sentences_parsed[][4]; ///< parseable sentence ids
static const char PROGMEM sentences_known[][4]; ///< known, but not parseable
// Make all of these times far in the past by setting them near the middle of
// the millis() range. Timing assumes that sentences are parsed promptly.
+27 -12
View File
@@ -21,6 +21,22 @@
/**************************************************************************/
#include <Adafruit_GPS.h>
const char PROGMEM Adafruit_GPS::sources[][4] = {"II", "WI", "GP", "PG", "GL",
"GA", "GN", "P", "ZZZ"};
#ifdef NMEA_EXTENSIONS
const char PROGMEM Adafruit_GPS::sentences_parsed[][4] = {
"GGA", "GLL", "GSA", "RMC", "DBT", "HDM", "HDT", "MDA", "MTW", "MWV",
"RMB", "TOP", "TXT", "VHW", "VLW", "VPW", "VWR", "WCV", "XTE", "ZZZ"};
const char PROGMEM Adafruit_GPS::sentences_known[][4] = {
"APB", "DPT", "GSV", "HDG", "MWD", "ROT",
"RPM", "RSA", "VDR", "VTG", "ZDA", "ZZZ"};
#else // make the lists short to save flash on small boards
const char PROGMEM Adafruit_GPS::sentences_parsed[][4] = {"GGA", "GLL", "GSA",
"RMC", "TOP", "ZZZ"};
const char PROGMEM Adafruit_GPS::sentences_known[][4] = {"DBT", "HDM", "HDT",
"ZZZ"};
#endif
#include <ctype.h>
/**************************************************************************/
@@ -648,20 +664,20 @@ bool Adafruit_GPS::check(char *nmea) {
char *p = nmea + 1;
const char *src = tokenOnList(p, sources);
if (src) {
strcpy(thisSource, src);
strcpy_P(thisSource, src);
thisCheck += NMEA_HAS_SOURCE;
} else
return false;
p += strlen(src);
p += strlen_P(src);
// extract sentence id and check if parsed
const char *snc = tokenOnList(p, sentences_parsed);
if (snc) {
strcpy(thisSentence, snc);
strcpy_P(thisSentence, snc);
thisCheck += NMEA_HAS_SENTENCE_P + NMEA_HAS_SENTENCE;
} else { // check if known
snc = tokenOnList(p, sentences_known);
if (snc) {
strcpy(thisSentence, snc);
strcpy_P(thisSentence, snc);
thisCheck += NMEA_HAS_SENTENCE;
return false; // known but not parsed
} else {
@@ -676,18 +692,17 @@ bool Adafruit_GPS::check(char *nmea) {
/*!
@brief Check if a token at the start of a string is on a list.
@param token Pointer to the string
@param list A list of strings, with the final entry starting "ZZ"
@return Pointer to the found token, or NULL if it fails
@param list A table in program memory, with the final entry starting "ZZ"
@return Program-memory pointer to the found token, or NULL if it fails
*/
/**************************************************************************/
const char *Adafruit_GPS::tokenOnList(char *token, const char **list) {
int i = 0; // index in the list
while (strncmp(list[i], "ZZ", 2) &&
i < 1000) { // stop at terminator and don't crash without it
const char *Adafruit_GPS::tokenOnList(char *token, const char list[][4]) {
for (int i = 0; i < 1000; i++) {
if (pgm_read_byte(list[i]) == 'Z' && pgm_read_byte(list[i] + 1) == 'Z')
break; // stop at terminator
// test for a match on the sentence name
if (!strncmp((const char *)list[i], (const char *)token, strlen(list[i])))
if (!strncmp_P(token, list[i], strlen_P(list[i])))
return list[i];
i++;
}
return NULL; // couldn't find a match
}