Skip to content

Commit 025ac73

Browse files
committed
Add SBF-in-SPARTN test example
1 parent 7411c5d commit 025ac73

File tree

3 files changed

+294
-6
lines changed

3 files changed

+294
-6
lines changed

examples/SBF_Test/SBF_TEST.ino

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ const char * const parserNames[] =
2323
};
2424
const int parserNameCount = sizeof(parserNames) / sizeof(parserNames[0]);
2525

26-
// Provide some valid SBF messages
27-
//
28-
2926
// Provide some valid and invalid SBF messages
3027
const uint8_t rawDataStream[] =
3128
{
Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
/*
2+
SparkFun SBF in SPARTN test example sketch
3+
4+
The mosaic-X5 can output raw L-Band (LBandBeam1) data, interspersed with SBF messages
5+
6+
This example demonstrates how to use two parsers to extract the SBF from the L-Band stream
7+
8+
License: MIT. Please see LICENSE.md for more details
9+
*/
10+
11+
#include <SparkFun_Extensible_Message_Parser.h> //http://librarymanager/All#SparkFun_Extensible_Message_Parser
12+
13+
//----------------------------------------
14+
// Constants
15+
//----------------------------------------
16+
17+
// Build the table listing all of the parsers
18+
SEMP_PARSE_ROUTINE const parserTable1[] =
19+
{
20+
sempSbfPreamble
21+
};
22+
const int parserCount1 = sizeof(parserTable1) / sizeof(parserTable1[0]);
23+
24+
const char * const parser1Names[] =
25+
{
26+
"SBF parser"
27+
};
28+
const int parser1NameCount = sizeof(parser1Names) / sizeof(parser1Names[0]);
29+
30+
SEMP_PARSE_ROUTINE const parserTable2[] =
31+
{
32+
sempSpartnPreamble
33+
};
34+
const int parserCount2 = sizeof(parserTable2) / sizeof(parserTable2[0]);
35+
36+
const char * const parser2Names[] =
37+
{
38+
"SPARTN parser"
39+
};
40+
const int parser2NameCount = sizeof(parser2Names) / sizeof(parser2Names[0]);
41+
42+
// Provide some valid L-Band SPARTN data, interspersed with valid SBF messages
43+
const uint8_t rawDataStream[] =
44+
{
45+
// Invalid data - must skip over
46+
0, 1, 2, 3, 4, 5, 6, 7, // 0
47+
48+
// SPARTN HPAC 0 - first ~half
49+
0x73, 0x03, 0x12, 0x6C, 0x08, 0xBF, 0x33, 0xD0, 0xF0, 0x6C, 0x2E, 0x88, 0xFA, 0xE5, 0x9B, 0x61,
50+
0x1B, 0x55, 0x79, 0x31, 0x7C, 0x12, 0x89, 0xE6, 0xE6, 0x91, 0x39, 0xA4, 0x65, 0x70, 0xC4, 0xB7,
51+
0xDD, 0x01, 0xE0, 0x64, 0xFE, 0x15, 0xED, 0x9C, 0x0C, 0x3B, 0xC0, 0xBE, 0xA9, 0x1A, 0xF6, 0xB6,
52+
0x72, 0xC5, 0x01, 0xDF, 0x17, 0xC2, 0xF6, 0x1B, 0xDD, 0x7B, 0x65, 0x8D, 0xD6, 0xB0, 0xCF, 0x03,
53+
0x04, 0xB3, 0x14, 0x46, 0xC0, 0x0B, 0x71, 0x93, 0xDC, 0x22, 0xCF, 0x3D, 0x6B, 0x98, 0xB9, 0xD0,
54+
0x26, 0x9C, 0xA4, 0xEC, 0xE7, 0xBD, 0x54, 0x47, 0x85, 0x46, 0x78, 0x0F, 0xDA, 0x73, 0x8B, 0xBB,
55+
0xD5, 0xEA, 0x7F, 0xE4, 0x55, 0xEE, 0x4C, 0x71, 0xA7, 0x77, 0x93, 0x89, 0x31, 0xE1, 0x64, 0x44,
56+
0xA6, 0xBB, 0xB3, 0xF9, 0x1E, 0x5A, 0xF0, 0xE9, 0xEC, 0xD5, 0x08, 0x6C, 0x59, 0x0D, 0x8C, 0xF6,
57+
0x95, 0x8B, 0x1B, 0x12, 0x3D, 0x52, 0x88, 0xA8, 0xD0, 0x4E, 0x20, 0x5F, 0x88, 0x31, 0x64, 0xD2,
58+
0xDE, 0xDE, 0x97, 0x15, 0xFD, 0x5A, 0x35, 0xF0, 0xC0, 0xBC, 0x28, 0x14, 0xE2, 0x90, 0x40, 0x27,
59+
0x17, 0xFC, 0x3C, 0x5E, 0xFD, 0x52, 0xA8, 0xF2, 0xBB, 0x9E, 0x0B, 0x9E, 0x96, 0x63, 0xB9, 0x75,
60+
0x47, 0xC7, 0xDC, 0x95, 0xF0, 0xEB, 0x5B, 0x91, 0x66, 0xAA, 0xCB, 0x67, 0xAF, 0x86, 0xCC, 0x29,
61+
0xC4, 0x8A, 0xB3, 0xE2, 0x2F, 0xF9, 0xAA, 0xC8, 0x35, 0x21, 0xD3, 0x9E, 0x93, 0x5B, 0x6D, 0xB6,
62+
0x41, 0xD9, 0xDD, 0x12, 0x38, 0x5C, 0xA7, 0x8B, 0xDE, 0x9A, 0xCC, 0x56, 0x0F, 0xBE, 0x7D, 0x5D,
63+
0x22, 0xA1, 0x11, 0x52, 0x83, 0x1A, 0xD8, 0xFD, 0xEF, 0x92, 0xFB, 0x04, 0x2F, 0xF1, 0x28, 0x59,
64+
0xE5, 0x66, 0x40, 0x51, 0xF1, 0x7F, 0xE6, 0x21, 0x38, 0x21, 0x2D, 0x51, 0x80, 0xF6, 0x53, 0x99,
65+
0x46, 0x76, 0xAD, 0x69, 0xC1, 0xE1, 0xF7, 0x7B, 0xF0, 0x0F, 0xDD, 0xAC, 0xC4, 0x22, 0x15, 0x1D,
66+
67+
68+
// SBF Block 4007 (PVTGeodetic)
69+
0x24, 0x40, 0xC4, 0x86, 0xA7, 0x4F, 0x60, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
70+
0x00, 0x00, 0x00, 0x20, 0x5F, 0xA0, 0x12, 0xC2, 0x00, 0x00, 0x00, 0x20, 0x5F, 0xA0, 0x12, 0xC2,
71+
0x00, 0x00, 0x00, 0x20, 0x5F, 0xA0, 0x12, 0xC2, 0xF9, 0x02, 0x95, 0xD0, 0xF9, 0x02, 0x95, 0xD0,
72+
0xF9, 0x02, 0x95, 0xD0, 0xF9, 0x02, 0x95, 0xD0, 0xF9, 0x02, 0x95, 0xD0, 0x00, 0x00, 0x00, 0x20,
73+
0x5F, 0xA0, 0x12, 0xC2, 0xF9, 0x02, 0x95, 0xD0, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
74+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
75+
76+
77+
// SPARTN HPAC 0 - second ~half
78+
0x2A, 0x4D, 0x6C, 0xA3, 0x17, 0xE3, 0x7B, 0x99, 0xF1, 0xC8, 0xCB, 0xC0, 0x4B, 0x75, 0x1E, 0xE4,
79+
0x5B, 0x14, 0x90, 0x13, 0xC7, 0x19, 0x11, 0xFA, 0xDD, 0x57, 0x1A, 0xCF, 0x63, 0x02, 0x13, 0x45,
80+
0x83, 0x72, 0xA4, 0x56, 0x40, 0xD8, 0xD7, 0xAC, 0x7A, 0xA4, 0x83, 0xD9, 0xA9, 0x2B, 0x42, 0x77,
81+
0x12, 0xCF, 0xFB, 0xFA, 0xBD, 0x3E, 0x4D, 0xFA, 0x3C, 0x79, 0xC1, 0xD5, 0xE8, 0x73, 0x09, 0x9C,
82+
0xB4, 0x36, 0x7C, 0xCC, 0x46, 0x5B, 0x4D, 0x8D, 0xC5, 0xF1, 0xAA, 0xEB, 0x2B, 0x1E, 0xCF, 0xB1,
83+
0xE5, 0x74, 0xE3, 0x75, 0xD4, 0x77, 0x8F, 0x6A, 0x1B, 0xE8, 0x5D, 0x56, 0xEB, 0xB6, 0xE9, 0x95,
84+
0x88, 0x13, 0x97, 0xA2, 0x19, 0x7B, 0xE3, 0x2B, 0xEA, 0x17, 0x01, 0x7E, 0xCB, 0x81, 0x81, 0x21,
85+
0x95, 0xD1, 0x0E, 0x55, 0x3D, 0xA2, 0xC1, 0x75, 0xAF, 0x03, 0x4B, 0x28, 0x10, 0x47, 0x20, 0x58,
86+
0xA4, 0x9F, 0x95, 0x05, 0x5F, 0x51, 0x3A, 0x39, 0x94, 0xAA, 0xD7, 0xBF, 0x88, 0x61, 0xCF, 0x7B,
87+
0x99, 0x38, 0x6A, 0xBD, 0xA8, 0xEA, 0xE0, 0x2A, 0xBC, 0x04, 0x84, 0xF2, 0xC1, 0xD2, 0xB8, 0x86,
88+
0xC3, 0x07, 0x1C, 0x3B, 0x42, 0x49, 0xDC, 0xC3, 0x65, 0x29, 0x81, 0x8C, 0x17, 0x7A, 0xD0, 0x92,
89+
0x47, 0x16, 0xB7, 0x53, 0xB9, 0x67, 0x98, 0x57, 0x9A, 0xCD, 0x15, 0x98, 0x27, 0x52, 0x0D, 0x4F,
90+
0x4B, 0x49, 0xBA, 0x74, 0xE0, 0x4D, 0x37, 0x8B, 0x23, 0xB3, 0x69, 0x2B, 0xA4, 0x73, 0x68, 0x9B,
91+
0xA9, 0xEC, 0x71, 0xCF, 0x13, 0x17, 0x63, 0xC9, 0x49, 0xD9, 0x5A, 0xAC, 0x22, 0xDC, 0x5F, 0xD2,
92+
0x43, 0xC0, 0x0A, 0x4F, 0xF8, 0xD6, 0x18, 0x34, 0x4F, 0x3D, 0xF4, 0xC1, 0x84, 0x97, 0xE5, 0x68,
93+
0xBB, 0x44, 0x00, 0xEF, 0xB0, 0x10, 0x75, 0xA0, 0xFF, 0xE6, 0x3E, 0x83, 0x53, 0x58, 0x56, 0x5E,
94+
0x56, 0x60, 0xB0, 0xFE, 0x18, 0x94, 0x40, 0xB3, 0xC1, 0x6E, 0x5D, 0x5D, 0x90, 0xD7, 0x72, 0x46,
95+
0x58, 0x95, 0x5C, 0x69, 0x1C, 0x64, 0x1A, 0xA6, 0x5C, 0xF3, 0xCD, 0x32, 0xFA, 0x00, 0xCE, 0xD7,
96+
0x71, 0x5E, 0x8D,
97+
98+
};
99+
100+
// Number of bytes in the rawDataStream
101+
#define RAW_DATA_BYTES (sizeof(rawDataStream) / sizeof(rawDataStream[0]))
102+
103+
// Account for the largest SBF messages
104+
#define BUFFER_LENGTH 2048
105+
106+
//----------------------------------------
107+
// Locals
108+
//----------------------------------------
109+
110+
uint32_t dataOffset1;
111+
SEMP_PARSE_STATE *parse1;
112+
uint32_t dataOffset2;
113+
SEMP_PARSE_STATE *parse2;
114+
115+
//----------------------------------------
116+
// Test routine
117+
//----------------------------------------
118+
119+
// Initialize the system
120+
void setup()
121+
{
122+
delay(1000);
123+
124+
Serial.begin(115200);
125+
Serial.println();
126+
Serial.println("SBF_in_SPARTN_Test example sketch");
127+
Serial.println();
128+
129+
// Initialize the parsers
130+
parse1 = sempBeginParser(parserTable1, parserCount1,
131+
parser1Names, parser1NameCount,
132+
0, BUFFER_LENGTH, processSbfMessage, "SBF_Test");
133+
if (!parse1)
134+
reportFatalError("Failed to initialize parser 1");
135+
136+
parse2 = sempBeginParser(parserTable2, parserCount2,
137+
parser2Names, parser2NameCount,
138+
0, BUFFER_LENGTH, processSpartnMessage, "SPARTN_Test");
139+
if (!parse2)
140+
reportFatalError("Failed to initialize parser 2");
141+
142+
// Obtain a raw data stream from somewhere
143+
Serial.printf("Raw data stream: %d bytes\r\n", RAW_DATA_BYTES);
144+
145+
// The raw data stream is passed to the SBF parser one byte at a time
146+
sempEnableDebugOutput(parse1);
147+
148+
// Any data which is not SBF is passed to the SPARTN parser
149+
sempEnableDebugOutput(parse2);
150+
151+
for (dataOffset1 = 0; dataOffset1 < RAW_DATA_BYTES; dataOffset1++)
152+
{
153+
// Update the SBF parser state based on the incoming byte
154+
sempParseNextByte(parse1, rawDataStream[dataOffset1]);
155+
156+
// If the data is not SBF, the state will return to sempFirstByte
157+
if (parse1->state == sempFirstByte)
158+
{
159+
// Data is not SBF, so pass it to the SPARTN parser
160+
for (dataOffset2 = 0; dataOffset2 < parse1->length; dataOffset2++)
161+
{
162+
// Update the SPARTN parser state based on the non-SBF byte
163+
sempParseNextByte(parse2, parse1->buffer[dataOffset2]);
164+
}
165+
}
166+
}
167+
168+
// Done parsing the data
169+
sempStopParser(&parse1);
170+
sempStopParser(&parse2);
171+
}
172+
173+
// Main loop processing after system is initialized
174+
void loop()
175+
{
176+
// Nothing to do here...
177+
}
178+
179+
// Call back from within parser, for end of message
180+
// Process a complete message incoming from parser
181+
void processSbfMessage(SEMP_PARSE_STATE *parse, uint16_t type)
182+
{
183+
SEMP_SCRATCH_PAD *scratchPad = (SEMP_SCRATCH_PAD *)parse->scratchPad;
184+
185+
uint32_t offset;
186+
187+
// Display the raw message
188+
Serial.println();
189+
offset = dataOffset1 + 1 - parse->length;
190+
Serial.printf("Valid SBF message block %d : %d bytes at 0x%08lx (%ld)\r\n",
191+
scratchPad->sbf.sbfID,
192+
parse->length, offset, offset);
193+
dumpBuffer(parse->buffer, parse->length);
194+
195+
// Display Block Number
196+
Serial.print("SBF Block Number: ");
197+
Serial.println(sempSbfGetBlockNumber(parse));
198+
199+
// Display the parser state
200+
static bool displayOnce = true;
201+
if (displayOnce)
202+
{
203+
displayOnce = false;
204+
Serial.println();
205+
sempPrintParserConfiguration(parse, &Serial);
206+
}
207+
}
208+
209+
// Call back from within parser, for end of message
210+
// Process a complete message incoming from parser
211+
void processSpartnMessage(SEMP_PARSE_STATE *parse, uint16_t type)
212+
{
213+
SEMP_SCRATCH_PAD *scratchPad = (SEMP_SCRATCH_PAD *)parse->scratchPad;
214+
215+
static bool displayOnce = true;
216+
uint32_t offset;
217+
218+
// Display the raw message
219+
Serial.println();
220+
offset = dataOffset2 + 1 - parse->length;
221+
Serial.printf("Valid SPARTN message, type %d, subtype %d : %d bytes at 0x%08lx (%ld)\r\n",
222+
scratchPad->spartn.messageType,
223+
scratchPad->spartn.messageSubtype,
224+
parse->length, offset, offset);
225+
dumpBuffer(parse->buffer, parse->length);
226+
227+
// Display the parser state
228+
if (displayOnce)
229+
{
230+
displayOnce = false;
231+
Serial.println();
232+
sempPrintParserConfiguration(parse, &Serial);
233+
}
234+
}
235+
236+
// Display the contents of a buffer
237+
void dumpBuffer(const uint8_t *buffer, uint16_t length)
238+
{
239+
int bytes;
240+
const uint8_t *end;
241+
int index;
242+
uint32_t offset;
243+
244+
end = &buffer[length];
245+
offset = 0;
246+
while (buffer < end)
247+
{
248+
// Determine the number of bytes to display on the line
249+
bytes = end - buffer;
250+
if (bytes > (16 - (offset & 0xf)))
251+
bytes = 16 - (offset & 0xf);
252+
253+
// Display the offset
254+
Serial.printf("0x%08lx: ", offset);
255+
256+
// Skip leading bytes
257+
for (index = 0; index < (offset & 0xf); index++)
258+
Serial.printf(" ");
259+
260+
// Display the data bytes
261+
for (index = 0; index < bytes; index++)
262+
Serial.printf("%02x ", buffer[index]);
263+
264+
// Separate the data bytes from the ASCII
265+
for (; index < (16 - (offset & 0xf)); index++)
266+
Serial.printf(" ");
267+
Serial.printf(" ");
268+
269+
// Skip leading bytes
270+
for (index = 0; index < (offset & 0xf); index++)
271+
Serial.printf(" ");
272+
273+
// Display the ASCII values
274+
for (index = 0; index < bytes; index++)
275+
Serial.printf("%c", ((buffer[index] < ' ') || (buffer[index] >= 0x7f)) ? '.' : buffer[index]);
276+
Serial.printf("\r\n");
277+
278+
// Set the next line of data
279+
buffer += bytes;
280+
offset += bytes;
281+
}
282+
}
283+
284+
// Print the error message every 15 seconds
285+
void reportFatalError(const char *errorMsg)
286+
{
287+
while (1)
288+
{
289+
Serial.print("HALTED: ");
290+
Serial.print(errorMsg);
291+
Serial.println();
292+
sleep(15);
293+
}
294+
}

examples/SPARTN_Test/SPARTN_TEST.ino

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,6 @@ const char * const parserNames[] =
2323
};
2424
const int parserNameCount = sizeof(parserNames) / sizeof(parserNames[0]);
2525

26-
// Provide some valid SPARTN messages
27-
//
28-
2926
// Provide some valid and invalid SPARTN messages
3027
const uint8_t rawDataStream[] =
3128
{

0 commit comments

Comments
 (0)