Skip to content

Commit dc1e7a4

Browse files
authored
Merge pull request #52 from sparkfun/release_candidate
v1.0.6
2 parents 9260600 + f08494a commit dc1e7a4

12 files changed

+293
-30
lines changed

examples/UBLOX_Test/UBLOX_Test.ino

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,22 @@ const uint8_t rawDataStream[] =
9595
0xa3, 0x2a, 0x00, 0x00, 0x00, 0xf6, 0x8e, 0xaa,
9696
0xaa, 0x00, 0x40, 0x3f, 0x50, 0x69, 0x70,
9797

98-
// Message too long
99-
0xb5, // 0x160
100-
0x62, 0x02, 0x13, 0x29, 0x00, 0x02, 0x09, 0x05,
101-
0x00, 0x08, 0x40, 0x02, 0x43, 0x55, 0x55, 0x95,
102-
0x00, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
103-
0x55, 0x00, 0x40, 0xbd, 0x52, 0x00, 0x00, 0xe5,
104-
0xa3, 0x2a, 0x00, 0x00, 0x00, 0xf6, 0x8e, 0xaa,
105-
0xaa, 0x00, 0x40, 0x3f, 0x50, 0x00, 0x6a, 0x05,
98+
// Message too long - needs BUFFER_LENGTH of at least 100 bytes
99+
// Valid u-blox NAV-PVT message // 0x160
100+
0xB5,0x62,0x01,0x07,0x5C,0x00, // Header
101+
0x50,0x32,0x20,0x17,0xE3,0x07,0x0A,0x11, // Payload
102+
0x0B,0x2E,0x08,0x37,0x0F,0x00,0x00,0x00,
103+
0x2E,0x3A,0x01,0x00,0x03,0x01,0xEA,0x0F,
104+
0x46,0x4E,0x44,0x04,0xFE,0x81,0x90,0x1E,
105+
0x03,0x9A,0x03,0x00,0x46,0xE4,0x02,0x00,
106+
0xD3,0x10,0x00,0x00,0xB9,0x1B,0x00,0x00,
107+
0x89,0xFF,0xFF,0xFF,0xE5,0xFF,0xFF,0xFF,
108+
0x7C,0xFF,0xFF,0xFF,0x7A,0x00,0x00,0x00,
109+
0x63,0xFD,0xC9,0x00,0xFF,0x01,0x00,0x00,
110+
0x1C,0x0D,0x4B,0x00,0x8D,0x00,0x00,0x00,
111+
0xB8,0x41,0x47,0x3D,0x00,0x00,0x00,0x00,
112+
0x00,0x00,0x00,0x00,
113+
0x9D,0x7C // Checksum
106114
};
107115

108116
// Number of bytes in the rawDataStream
@@ -178,6 +186,20 @@ void processMessage(SEMP_PARSE_STATE *parse, uint16_t type)
178186
Serial.println();
179187
sempPrintParserConfiguration(parse, &Serial);
180188
}
189+
190+
// Test UBX data parse routines
191+
if (sempUbloxGetMessageClass(parse) == 0x01) // Class: NAV
192+
if (sempUbloxGetMessageId(parse) == 0x07) // ID: PVT
193+
{
194+
Serial.println("UBX-NAV-PVT:");
195+
Serial.printf("Payload Length: %d\r\n", sempUbloxGetPayloadLength(parse));
196+
Serial.printf("iTOW: %ld\r\n", sempUbloxGetU4(parse, 0));
197+
Serial.printf("Year: %d\r\n", sempUbloxGetU2(parse, 4));
198+
Serial.printf("Month: %d\r\n", sempUbloxGetU1(parse, 6));
199+
Serial.printf("Day: %d\r\n", sempUbloxGetU1(parse, 7));
200+
Serial.printf("Latitude: %ld\r\n", sempUbloxGetI4(parse, 28));
201+
Serial.printf("Longitude: %ld\r\n", sempUbloxGetI4(parse, 24));
202+
}
181203
}
182204

183205
// Display the contents of a buffer

keywords.txt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,27 @@ sempFirstByte KEYWORD2
2929
sempParseNextByte KEYWORD2
3030
sempParseNextBytes KEYWORD2
3131
sempStopParser KEYWORD2
32+
sempAbortNmeaOnNonPrintable KEYWORD2
33+
sempAbortHashOnNonPrintable KEYWORD2
3234
sempNmeaGetSentenceName KEYWORD2
3335
sempRtcmGetMessageNumber KEYWORD2
3436
sempRtcmGetUnsignedBits KEYWORD2
3537
sempRtcmGetSignedBits KEYWORD2
3638
sempUbloxGetMessageNumber KEYWORD2
39+
sempUbloxGetMessageClass KEYWORD2
40+
sempUbloxGetMessageId KEYWORD2
41+
sempUbloxGetPayloadLength KEYWORD2
42+
sempUbloxGetU1 KEYWORD2
43+
sempUbloxGetU2 KEYWORD2
44+
sempUbloxGetU4 KEYWORD2
45+
sempUbloxGetU8 KEYWORD2
46+
sempUbloxGetI1 KEYWORD2
47+
sempUbloxGetI2 KEYWORD2
48+
sempUbloxGetI4 KEYWORD2
49+
sempUbloxGetI8 KEYWORD2
50+
sempUbloxGetR4 KEYWORD2
51+
sempUbloxGetR8 KEYWORD2
52+
sempUbloxGetString KEYWORD2
3753
sempUnicoreHashGetSentenceName KEYWORD2
3854
sempSpartnGetMessageType KEYWORD2
3955
sempSbfSetInvalidDataCallback KEYWORD2

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=SparkFun Extensible Message Parser
2-
version=1.0.5
2+
version=1.0.6
33
author=SparkFun Electronics
44
maintainer=SparkFun Electronics <sparkfun.com>
55
sentence=Library to parse structured serial streams

src/Parse_NMEA.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ void sempNmeaValidateChecksum(SEMP_PARSE_STATE *parse)
6565
else
6666
// Display the checksum error
6767
sempPrintf(parse->printDebug,
68-
"SEMP: %s NMEA %s, 0x%04x (%d) bytes, bad checksum, "
68+
"SEMP %s: NMEA %s, 0x%04x (%d) bytes, bad checksum, "
6969
"received 0x%c%c, computed: 0x%02x",
7070
parse->parserName,
7171
scratchPad->nmea.sentenceName,
@@ -189,13 +189,30 @@ bool sempNmeaChecksumByte1(SEMP_PARSE_STATE *parse, uint8_t data)
189189
// Read the sentence data
190190
bool sempNmeaFindAsterisk(SEMP_PARSE_STATE *parse, uint8_t data)
191191
{
192+
SEMP_SCRATCH_PAD *scratchPad = (SEMP_SCRATCH_PAD *)parse->scratchPad;
193+
192194
if (data == '*')
193195
parse->state = sempNmeaChecksumByte1;
194196
else
195197
{
196198
// Include this byte in the checksum
197199
parse->crc ^= data;
198200

201+
// Abort on a non-printable char - if enabled
202+
if (parse->abortNmeaOnNonPrintable)
203+
{
204+
if ((data < ' ') || (data > '~'))
205+
{
206+
sempPrintf(parse->printDebug,
207+
"SEMP %s: NMEA %s abort on non-printable char",
208+
parse->parserName,
209+
scratchPad->nmea.sentenceName);
210+
211+
// Start searching for a preamble byte
212+
return sempFirstByte(parse, data);
213+
}
214+
}
215+
199216
// Verify that enough space exists in the buffer
200217
if ((uint32_t)(parse->length + NMEA_BUFFER_OVERHEAD) > parse->bufferLength)
201218
{

src/Parse_RTCM.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ bool sempRtcmReadCrc(SEMP_PARSE_STATE *parse, uint8_t data)
6363
{
6464
if (parse->length == 6)
6565
sempPrintf(parse->printDebug,
66-
"SEMP: %s RTCM 0x%04x (%d) bytes, \"filler\" message",
66+
"SEMP %s: RTCM 0x%04x (%d) bytes, \"filler\" message",
6767
parse->parserName,
6868
parse->length, parse->length);
6969
parse->eomCallback(parse, parse->type); // Pass parser array index
@@ -72,7 +72,7 @@ bool sempRtcmReadCrc(SEMP_PARSE_STATE *parse, uint8_t data)
7272
// Display the RTCM messages with bad CRC
7373
else
7474
sempPrintf(parse->printDebug,
75-
"SEMP: %s RTCM %d, 0x%04x (%d) bytes, bad CRC, "
75+
"SEMP %s: RTCM %d, 0x%04x (%d) bytes, bad CRC, "
7676
"received %02x %02x %02x, computed: %02x %02x %02x",
7777
parse->parserName,
7878
scratchPad->rtcm.message,
@@ -135,6 +135,12 @@ bool sempRtcmReadLength2(SEMP_PARSE_STATE *parse, uint8_t data)
135135
SEMP_SCRATCH_PAD *scratchPad = (SEMP_SCRATCH_PAD *)parse->scratchPad;
136136

137137
scratchPad->rtcm.bytesRemaining |= data;
138+
if (parse->verboseDebug)
139+
sempPrintf(parse->printDebug,
140+
"SEMP %s: Incoming RTCM %d, 0x%04x (%d) bytes",
141+
parse->parserName,
142+
scratchPad->rtcm.message,
143+
scratchPad->rtcm.bytesRemaining, scratchPad->rtcm.bytesRemaining);
138144
if (scratchPad->rtcm.bytesRemaining == 0) // Handle zero length messages - 10403 "filler" messages
139145
{
140146
scratchPad->rtcm.message = 0; // Clear the previous message number
@@ -143,7 +149,9 @@ bool sempRtcmReadLength2(SEMP_PARSE_STATE *parse, uint8_t data)
143149
parse->state = sempRtcmReadCrc; // Jump to the CRC
144150
}
145151
else
152+
{
146153
parse->state = sempRtcmReadMessage1;
154+
}
147155
return true;
148156
}
149157

src/Parse_SBF.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ bool sempSbfReadBytes(SEMP_PARSE_STATE *parse, uint8_t data)
4141
else
4242
{
4343
sempPrintf(parse->printDebug,
44-
"SEMP: %s SBF %d, 0x%04x (%d) bytes, bad CRC",
44+
"SEMP %s: SBF %d, 0x%04x (%d) bytes, bad CRC",
4545
parse->parserName,
4646
scratchPad->sbf.sbfID,
4747
parse->length, parse->length);
@@ -69,11 +69,17 @@ bool sempSbfLengthMSB(SEMP_PARSE_STATE *parse, uint8_t data)
6969
{
7070
scratchPad->sbf.bytesRemaining = scratchPad->sbf.length - 8; // Subtract 8 header bytes
7171
parse->state = sempSbfReadBytes;
72+
if (parse->verboseDebug)
73+
sempPrintf(parse->printDebug,
74+
"SEMP %s: Incoming SBF %d, 0x%04x (%d) bytes",
75+
parse->parserName,
76+
scratchPad->sbf.sbfID,
77+
scratchPad->sbf.bytesRemaining, scratchPad->sbf.bytesRemaining);
7278
return true;
7379
}
7480
// else
7581
sempPrintf(parse->printDebug,
76-
"SEMP: %s SBF, 0x%04x (%d) bytes, length not modulo 4",
82+
"SEMP %s: SBF, 0x%04x (%d) bytes, length not modulo 4",
7783
parse->parserName,
7884
parse->length, parse->length);
7985

@@ -158,7 +164,7 @@ bool sempSbfPreamble2(SEMP_PARSE_STATE *parse, uint8_t data)
158164
}
159165
// else
160166
sempPrintf(parse->printDebug,
161-
"SEMP: %s SBF, 0x%04x (%d) bytes, invalid preamble2",
167+
"SEMP %s: SBF, 0x%04x (%d) bytes, invalid preamble2",
162168
parse->parserName,
163169
parse->length, parse->length);
164170

src/Parse_SPARTN.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ bool sempSpartnReadTF018(SEMP_PARSE_STATE *parse, uint8_t data)
8282
parse->eomCallback(parse, parse->type); // Pass parser array index
8383
else
8484
sempPrintf(parse->printDebug,
85-
"SEMP: %s SPARTN %d %d, 0x%04x (%d) bytes, bad CRC",
85+
"SEMP %s: SPARTN %d %d, 0x%04x (%d) bytes, bad CRC",
8686
parse->parserName,
8787
scratchPad->spartn.messageType,
8888
scratchPad->spartn.messageSubtype,
@@ -235,6 +235,13 @@ bool sempSpartnReadTF002TF006(SEMP_PARSE_STATE *parse, uint8_t data)
235235
if (semp_uSpartnCrc4(&parse->buffer[1], 3) == scratchPad->spartn.frameCRC)
236236
{
237237
parse->buffer[3] = data; // Restore TF005 and TF006 now we know the data is valid
238+
if (parse->verboseDebug)
239+
sempPrintf(parse->printDebug,
240+
"SEMP %s: Incoming SPARTN %d %d, 0x%04x (%d) bytes",
241+
parse->parserName,
242+
scratchPad->spartn.messageType,
243+
scratchPad->spartn.messageSubtype,
244+
scratchPad->spartn.payloadLength, scratchPad->spartn.payloadLength);
238245
parse->state = sempSpartnReadTF007;
239246
}
240247
else
@@ -244,7 +251,7 @@ bool sempSpartnReadTF002TF006(SEMP_PARSE_STATE *parse, uint8_t data)
244251
parse->state = sempFirstByte;
245252

246253
sempPrintf(parse->printDebug,
247-
"SEMP: %s SPARTN %d, 0x%04x (%d) bytes, bad header CRC",
254+
"SEMP %s: SPARTN %d, 0x%04x (%d) bytes, bad header CRC",
248255
parse->parserName,
249256
scratchPad->spartn.messageType,
250257
parse->length, parse->length);

src/Parse_UBLOX.cpp

Lines changed: 120 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,19 @@ bool sempUbloxLength2(SEMP_PARSE_STATE *parse, uint8_t data)
101101

102102
// Save the second length byte
103103
scratchPad->ublox.bytesRemaining |= ((uint16_t)data) << 8;
104+
scratchPad->ublox.payloadLength = scratchPad->ublox.bytesRemaining;
104105
if (scratchPad->ublox.bytesRemaining == 0) // Handle zero length messages - e.g. UBX-UPD
105106
parse->state = sempUbloxCkA; // Jump to CRC
106107
else
108+
{
109+
if (parse->verboseDebug)
110+
sempPrintf(parse->printDebug,
111+
"SEMP %s: Incoming UBLOX 0x%02X:0x%02X, 0x%04x (%d) bytes",
112+
parse->parserName,
113+
scratchPad->ublox.messageClass, scratchPad->ublox.messageId,
114+
scratchPad->ublox.payloadLength, scratchPad->ublox.payloadLength);
107115
parse->state = sempUbloxPayload;
116+
}
108117
return true;
109118
}
110119

@@ -132,8 +141,7 @@ bool sempUbloxId(SEMP_PARSE_STATE *parse, uint8_t data)
132141
scratchPad->ublox.ck_a += data;
133142
scratchPad->ublox.ck_b += scratchPad->ublox.ck_a;
134143

135-
// Save the ID as the lower 8-bits of the message
136-
scratchPad->ublox.message |= data;
144+
scratchPad->ublox.messageId = data; // Save the ID
137145
parse->state = sempUbloxLength1;
138146
return true;
139147
}
@@ -147,8 +155,7 @@ bool sempUbloxClass(SEMP_PARSE_STATE *parse, uint8_t data)
147155
scratchPad->ublox.ck_a = data;
148156
scratchPad->ublox.ck_b = data;
149157

150-
// Save the class as the upper 8-bits of the message
151-
scratchPad->ublox.message = ((uint16_t)data) << 8;
158+
scratchPad->ublox.messageClass = data; // Save the Class
152159
parse->state = sempUbloxId;
153160
return true;
154161
}
@@ -205,9 +212,116 @@ const char * sempUbloxGetStateName(const SEMP_PARSE_STATE *parse)
205212
return nullptr;
206213
}
207214

208-
// Get the message number
215+
// Get the message number: |- Class (8 bits) -||- ID (8 bits) -|
209216
uint16_t sempUbloxGetMessageNumber(const SEMP_PARSE_STATE *parse)
210217
{
211218
SEMP_SCRATCH_PAD *scratchPad = (SEMP_SCRATCH_PAD *)parse->scratchPad;
212-
return scratchPad->ublox.message;
219+
uint16_t message = ((uint16_t)scratchPad->ublox.messageClass) << 8;
220+
message |= (uint16_t)scratchPad->ublox.messageId;
221+
return message;
222+
}
223+
224+
// Get the message Class
225+
uint8_t sempUbloxGetMessageClass(const SEMP_PARSE_STATE *parse)
226+
{
227+
SEMP_SCRATCH_PAD *scratchPad = (SEMP_SCRATCH_PAD *)parse->scratchPad;
228+
return scratchPad->ublox.messageClass;
229+
}
230+
231+
// Get the message ID
232+
uint8_t sempUbloxGetMessageId(const SEMP_PARSE_STATE *parse)
233+
{
234+
SEMP_SCRATCH_PAD *scratchPad = (SEMP_SCRATCH_PAD *)parse->scratchPad;
235+
return scratchPad->ublox.messageId;
236+
}
237+
238+
// Get the Payload Length
239+
uint16_t sempUbloxGetPayloadLength(const SEMP_PARSE_STATE *parse)
240+
{
241+
SEMP_SCRATCH_PAD *scratchPad = (SEMP_SCRATCH_PAD *)parse->scratchPad;
242+
return scratchPad->ublox.payloadLength;
243+
}
244+
245+
// Get data
246+
uint8_t sempUbloxGetU1(const SEMP_PARSE_STATE *parse, uint16_t offset)
247+
{
248+
return parse->buffer[offset + SEMP_UBLOX_PAYLOAD_OFFSET];
249+
}
250+
uint16_t sempUbloxGetU2(const SEMP_PARSE_STATE *parse, uint16_t offset)
251+
{
252+
uint16_t data = parse->buffer[offset + SEMP_UBLOX_PAYLOAD_OFFSET];
253+
data |= ((uint16_t)parse->buffer[offset + SEMP_UBLOX_PAYLOAD_OFFSET + 1]) << 8;
254+
return data;
255+
}
256+
uint32_t sempUbloxGetU4(const SEMP_PARSE_STATE *parse, uint16_t offset)
257+
{
258+
uint32_t data = 0;
259+
for (uint16_t i = 0; i < sizeof(data); i++)
260+
data |= ((uint32_t)parse->buffer[offset + SEMP_UBLOX_PAYLOAD_OFFSET + i]) << (8 * i);
261+
return data;
262+
}
263+
uint64_t sempUbloxGetU8(const SEMP_PARSE_STATE *parse, uint16_t offset)
264+
{
265+
uint64_t data = 0;
266+
for (uint16_t i = 0; i < sizeof(data); i++)
267+
data |= ((uint64_t)parse->buffer[offset + SEMP_UBLOX_PAYLOAD_OFFSET + i]) << (8 * i);
268+
return data;
269+
}
270+
int8_t sempUbloxGetI1(const SEMP_PARSE_STATE *parse, uint16_t offset)
271+
{
272+
union {
273+
uint8_t unsignedN;
274+
int8_t signedN;
275+
} unsignedSignedN;
276+
unsignedSignedN.unsignedN = sempUbloxGetU1(parse, offset);
277+
return unsignedSignedN.signedN;
278+
}
279+
int16_t sempUbloxGetI2(const SEMP_PARSE_STATE *parse, uint16_t offset)
280+
{
281+
union {
282+
uint16_t unsignedN;
283+
int16_t signedN;
284+
} unsignedSignedN;
285+
unsignedSignedN.unsignedN = sempUbloxGetU2(parse, offset);
286+
return unsignedSignedN.signedN;
287+
}
288+
int32_t sempUbloxGetI4(const SEMP_PARSE_STATE *parse, uint16_t offset)
289+
{
290+
union {
291+
uint32_t unsignedN;
292+
int32_t signedN;
293+
} unsignedSignedN;
294+
unsignedSignedN.unsignedN = sempUbloxGetU4(parse, offset);
295+
return unsignedSignedN.signedN;
296+
}
297+
int64_t sempUbloxGetI8(const SEMP_PARSE_STATE *parse, uint16_t offset)
298+
{
299+
union {
300+
uint64_t unsignedN;
301+
int64_t signedN;
302+
} unsignedSignedN;
303+
unsignedSignedN.unsignedN = sempUbloxGetU8(parse, offset);
304+
return unsignedSignedN.signedN;
305+
}
306+
float sempUbloxGetR4(const SEMP_PARSE_STATE *parse, uint16_t offset)
307+
{
308+
union {
309+
uint32_t unsignedN;
310+
float flt;
311+
} unsignedFloat;
312+
unsignedFloat.unsignedN = sempUbloxGetU4(parse, offset);
313+
return unsignedFloat.flt;
314+
}
315+
double sempUbloxGetR8(const SEMP_PARSE_STATE *parse, uint16_t offset)
316+
{
317+
union {
318+
uint64_t unsignedN;
319+
double flt;
320+
} unsignedFloat;
321+
unsignedFloat.unsignedN = sempUbloxGetU8(parse, offset);
322+
return unsignedFloat.flt;
323+
}
324+
const char *sempUbloxGetString(const SEMP_PARSE_STATE *parse, uint16_t offset)
325+
{
326+
return (const char *)(&parse->buffer[offset]);
213327
}

0 commit comments

Comments
 (0)