Skip to content

Commit 7411c5d

Browse files
committed
Add SBF
1 parent 3df60dc commit 7411c5d

File tree

7 files changed

+631
-4
lines changed

7 files changed

+631
-4
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
SparkFun Extensible Message Parser
22
========================================
33

4-
The SparkFun Extensible Message Parser provides a base set of routines to construct serial stream parsers. On top of this are several GNSS protocol parsers for NMEA, RTCM, u-blox, SPARTN and Unicore. Some of SparkFun's RTK products use these parsers. Users may add protocol parse routines to enable the base routines to parse other protocols. Examples are provided for various parse configurations.
4+
The SparkFun Extensible Message Parser provides a base set of routines to construct serial stream parsers. On top of this are several GNSS protocol parsers for NMEA, RTCM, u-blox UBX, SPARTN, Septentrio SBF and Unicore. Some of SparkFun's RTK products use these parsers. Users may add protocol parse routines to enable the base routines to parse other protocols. Examples are provided for various parse configurations.
55

66
License Information
77
-------------------

examples/SBF_Test/SBF_TEST.ino

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
/*
2+
SparkFun SBF test example sketch
3+
4+
License: MIT. Please see LICENSE.md for more details
5+
*/
6+
7+
#include <SparkFun_Extensible_Message_Parser.h> //http://librarymanager/All#SparkFun_Extensible_Message_Parser
8+
9+
//----------------------------------------
10+
// Constants
11+
//----------------------------------------
12+
13+
// Build the table listing all of the parsers
14+
SEMP_PARSE_ROUTINE const parserTable[] =
15+
{
16+
sempSbfPreamble
17+
};
18+
const int parserCount = sizeof(parserTable) / sizeof(parserTable[0]);
19+
20+
const char * const parserNames[] =
21+
{
22+
"SBF parser"
23+
};
24+
const int parserNameCount = sizeof(parserNames) / sizeof(parserNames[0]);
25+
26+
// Provide some valid SBF messages
27+
//
28+
29+
// Provide some valid and invalid SBF messages
30+
const uint8_t rawDataStream[] =
31+
{
32+
// Invalid data - must skip over
33+
0, 1, 2, 3, 4, 5, 6, 7, // 0
34+
35+
// SBF Block 5914 (ReceiverTime)
36+
0x24, 0x40, 0x06, 0xFE, 0x1A, 0x17, 0x18, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x80,
37+
0x80, 0x80, 0x80, 0x80, 0x12, 0x00, 0x00, 0x00,
38+
39+
// SBF Block 5914 (ReceiverTime) - invalid length
40+
0x24, 0x40, 0x06, 0xFE, 0x1A, 0x17, 0x17, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x80,
41+
0x80, 0x80, 0x80, 0x80, 0x12, 0x00, 0x00, 0x00,
42+
43+
// SBF Block 5914 (ReceiverTime) - invalid CRC
44+
0x24, 0x40, 0x06, 0xFE, 0x1A, 0x17, 0x18, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x80,
45+
0xFF, 0x80, 0x80, 0x80, 0x12, 0x00, 0x00, 0x00,
46+
47+
// Invalid data - must skip over
48+
0, 1, 2, 3, 4, 5, 6, 7, // 0
49+
50+
// SBF Block 4007 (PVTGeodetic)
51+
0x24, 0x40, 0xC4, 0x86, 0xA7, 0x4F, 0x60, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
52+
0x00, 0x00, 0x00, 0x20, 0x5F, 0xA0, 0x12, 0xC2, 0x00, 0x00, 0x00, 0x20, 0x5F, 0xA0, 0x12, 0xC2,
53+
0x00, 0x00, 0x00, 0x20, 0x5F, 0xA0, 0x12, 0xC2, 0xF9, 0x02, 0x95, 0xD0, 0xF9, 0x02, 0x95, 0xD0,
54+
0xF9, 0x02, 0x95, 0xD0, 0xF9, 0x02, 0x95, 0xD0, 0xF9, 0x02, 0x95, 0xD0, 0x00, 0x00, 0x00, 0x20,
55+
0x5F, 0xA0, 0x12, 0xC2, 0xF9, 0x02, 0x95, 0xD0, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
56+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
57+
58+
};
59+
60+
// Number of bytes in the rawDataStream
61+
#define RAW_DATA_BYTES (sizeof(rawDataStream) / sizeof(rawDataStream[0]))
62+
63+
// Account for the largest SBF messages
64+
#define BUFFER_LENGTH 2048
65+
66+
//----------------------------------------
67+
// Locals
68+
//----------------------------------------
69+
70+
uint32_t dataOffset;
71+
SEMP_PARSE_STATE *parse;
72+
73+
//----------------------------------------
74+
// Test routine
75+
//----------------------------------------
76+
77+
// Initialize the system
78+
void setup()
79+
{
80+
delay(1000);
81+
82+
Serial.begin(115200);
83+
Serial.println();
84+
Serial.println("SBF_Test example sketch");
85+
Serial.println();
86+
87+
// Initialize the parser
88+
parse = sempBeginParser(parserTable, parserCount,
89+
parserNames, parserNameCount,
90+
0, BUFFER_LENGTH, processMessage, "SBF_Test");
91+
if (!parse)
92+
reportFatalError("Failed to initialize the parser");
93+
94+
// Obtain a raw data stream from somewhere
95+
Serial.printf("Raw data stream: %d bytes\r\n", RAW_DATA_BYTES);
96+
97+
// The raw data stream is passed to the parser one byte at a time
98+
sempEnableDebugOutput(parse);
99+
for (dataOffset = 0; dataOffset < RAW_DATA_BYTES; dataOffset++)
100+
// Update the parser state based on the incoming byte
101+
sempParseNextByte(parse, rawDataStream[dataOffset]);
102+
103+
// Done parsing the data
104+
sempStopParser(&parse);
105+
}
106+
107+
// Main loop processing after system is initialized
108+
void loop()
109+
{
110+
// Nothing to do here...
111+
}
112+
113+
// Call back from within parser, for end of message
114+
// Process a complete message incoming from parser
115+
void processMessage(SEMP_PARSE_STATE *parse, uint16_t type)
116+
{
117+
SEMP_SCRATCH_PAD *scratchPad = (SEMP_SCRATCH_PAD *)parse->scratchPad;
118+
119+
uint32_t offset;
120+
121+
// Display the raw message
122+
Serial.println();
123+
offset = dataOffset + 1 - parse->length;
124+
Serial.printf("Valid SBF message block %d : %d bytes at 0x%08lx (%ld)\r\n",
125+
scratchPad->sbf.sbfID,
126+
parse->length, offset, offset);
127+
dumpBuffer(parse->buffer, parse->length);
128+
129+
// Display Block Number
130+
Serial.print("SBF Block Number: ");
131+
Serial.println(sempSbfGetBlockNumber(parse));
132+
133+
// If this is PVTGeodetic, extract some data
134+
if (sempSbfGetBlockNumber(parse) == 4007)
135+
{
136+
Serial.printf("TOW: %ld\r\n", sempSbfGetU4(parse, 8));
137+
Serial.printf("Mode: %d\r\n", sempSbfGetU1(parse, 14));
138+
Serial.printf("Error: %d\r\n", sempSbfGetU1(parse, 15));
139+
Serial.printf("Latitude: %.7g\r\n", sempSbfGetF8(parse, 16) * 180.0 / PI);
140+
Serial.printf("Longitude: %.7g\r\n", sempSbfGetF8(parse, 24) * 180.0 / PI);
141+
}
142+
143+
// Display the parser state
144+
static bool displayOnce = true;
145+
if (displayOnce)
146+
{
147+
displayOnce = false;
148+
Serial.println();
149+
sempPrintParserConfiguration(parse, &Serial);
150+
}
151+
}
152+
153+
// Display the contents of a buffer
154+
void dumpBuffer(const uint8_t *buffer, uint16_t length)
155+
{
156+
int bytes;
157+
const uint8_t *end;
158+
int index;
159+
uint32_t offset;
160+
161+
end = &buffer[length];
162+
offset = 0;
163+
while (buffer < end)
164+
{
165+
// Determine the number of bytes to display on the line
166+
bytes = end - buffer;
167+
if (bytes > (16 - (offset & 0xf)))
168+
bytes = 16 - (offset & 0xf);
169+
170+
// Display the offset
171+
Serial.printf("0x%08lx: ", offset);
172+
173+
// Skip leading bytes
174+
for (index = 0; index < (offset & 0xf); index++)
175+
Serial.printf(" ");
176+
177+
// Display the data bytes
178+
for (index = 0; index < bytes; index++)
179+
Serial.printf("%02x ", buffer[index]);
180+
181+
// Separate the data bytes from the ASCII
182+
for (; index < (16 - (offset & 0xf)); index++)
183+
Serial.printf(" ");
184+
Serial.printf(" ");
185+
186+
// Skip leading bytes
187+
for (index = 0; index < (offset & 0xf); index++)
188+
Serial.printf(" ");
189+
190+
// Display the ASCII values
191+
for (index = 0; index < bytes; index++)
192+
Serial.printf("%c", ((buffer[index] < ' ') || (buffer[index] >= 0x7f)) ? '.' : buffer[index]);
193+
Serial.printf("\r\n");
194+
195+
// Set the next line of data
196+
buffer += bytes;
197+
offset += bytes;
198+
}
199+
}
200+
201+
// Print the error message every 15 seconds
202+
void reportFatalError(const char *errorMsg)
203+
{
204+
while (1)
205+
{
206+
Serial.print("HALTED: ");
207+
Serial.print(errorMsg);
208+
Serial.println();
209+
sleep(15);
210+
}
211+
}

examples/SPARTN_Test/SPARTN_TEST.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const int parserNameCount = sizeof(parserNames) / sizeof(parserNames[0]);
2626
// Provide some valid SPARTN messages
2727
//
2828

29-
// Provide some valid and invalid u-blox messages
29+
// Provide some valid and invalid SPARTN messages
3030
const uint8_t rawDataStream[] =
3131
{
3232
// Invalid data - must skip over

0 commit comments

Comments
 (0)