Paparazzi UAS v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
Loading...
Searching...
No Matches
rtcm3.h
Go to the documentation of this file.
1/*
2 * Copyright (C) 2016 Wilco Vlenterie, Anand Sundaresan.
3 * Contact: Anand Sundaresan <nomail@donotmailme.com>
4 *
5 * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
6 * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
7 * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
8 */
9
10#ifndef LIBRTCM3_RTCM3_H
11#define LIBRTCM3_RTCM3_H
12
13/* Macros for RTCM message processing */
14#define READ_RESERVED 1
15#define READ_LENGTH 2
16#define READ_MESSAGE 3
17#define READ_CHECKSUM 4
18
19#define RTCM3_PREAMBLE 0xD3
20#define RTCM3_MSG_1005 0x69
21#define RTCM3_MSG_4072 0x72
22#define RTCM3_MSG_1077 0xB1
23#define RTCM3_MSG_1087 0xBB
24#define RTCM3_MSG_1097 0xC5
25#define RTCM3_MSG_1230 0xE6
26
27/* Macros for UBX message processing */
28
29#define UNINIT 0
30#define GOT_SYNC1 1
31#define GOT_SYNC2 2
32#define GOT_CLASS 3
33#define GOT_ID 4
34#define GOT_LEN1 5
35#define GOT_LEN2 6
36#define GOT_PAYLOAD 7
37#define GOT_CHECKSUM1 8
38
39#define UBX_PREAMBLE1 0xB5 // Sync 1
40#define UBX_PREAMBLE2 0x62 // Sync 2
41#define UBX_NAV_SVIN 0x3B
42#define GPS_UBX_MAX_PAYLOAD 255
43
44#define GPS_UBX_ERR_NONE 0
45#define GPS_UBX_ERR_OVERRUN 1
46#define GPS_UBX_ERR_MSG_TOO_LONG 2
47#define GPS_UBX_ERR_CHECKSUM 3
48#define GPS_UBX_ERR_UNEXPECTED 4
49#define GPS_UBX_ERR_OUT_OF_SYNC 5
50
51#define NO_CLASS 0
52#define RTCM_CLASS 1
53#define UBX_CLASS 2
54
55
56#define UBX_NAV_SVIN_VERSION(_ubx_payload) (uint8_t)(*((uint8_t*)_ubx_payload+0))
57#define UBX_NAV_SVIN_RES1(_ubx_payload) (uint8_t)(*((uint8_t*)_ubx_payload+1))
58#define UBX_NAV_SVIN_RES2(_ubx_payload) (uint16_t)(*((uint8_t*)_ubx_payload+2)|*((uint8_t*)_ubx_payload+1+2)<<8)
59#define UBX_NAV_SVIN_ITOW(_ubx_payload) (uint32_t)(*((uint8_t*)_ubx_payload+4)|*((uint8_t*)_ubx_payload+1+4)<<8|((uint32_t)*((uint8_t*)_ubx_payload+2+4))<<16|((uint32_t)*((uint8_t*)_ubx_payload+3+4))<<24)
60#define UBX_NAV_SVIN_dur(_ubx_payload) (uint32_t)(*((uint8_t*)_ubx_payload+8)|*((uint8_t*)_ubx_payload+1+8)<<8|((uint32_t)*((uint8_t*)_ubx_payload+2+8))<<16|((uint32_t)*((uint8_t*)_ubx_payload+3+8))<<24)
61#define UBX_NAV_SVIN_meanX(_ubx_payload) (int32_t)(*((uint8_t*)_ubx_payload+12)|*((uint8_t*)_ubx_payload+1+12)<<8|((int32_t)*((uint8_t*)_ubx_payload+2+12))<<16|((int32_t)*((uint8_t*)_ubx_payload+3+12))<<24)
62#define UBX_NAV_SVIN_meanY(_ubx_payload) (int32_t)(*((uint8_t*)_ubx_payload+16)|*((uint8_t*)_ubx_payload+1+16)<<8|((int32_t)*((uint8_t*)_ubx_payload+2+16))<<16|((int32_t)*((uint8_t*)_ubx_payload+3+16))<<24)
63#define UBX_NAV_SVIN_meanZ(_ubx_payload) (int32_t)(*((uint8_t*)_ubx_payload+20)|*((uint8_t*)_ubx_payload+1+20)<<8|((int32_t)*((uint8_t*)_ubx_payload+2+20))<<16|((int32_t)*((uint8_t*)_ubx_payload+3+20))<<24)
64#define UBX_NAV_SVIN_meanXHP(_ubx_payload) (int8_t)(*((uint8_t*)_ubx_payload+24))
65#define UBX_NAV_SVIN_meanYHP(_ubx_payload) (int8_t)(*((uint8_t*)_ubx_payload+25))
66#define UBX_NAV_SVIN_meanZHP(_ubx_payload) (int8_t)(*((uint8_t*)_ubx_payload+26))
67#define UBX_NAV_SVIN_RES3(_ubx_payload) (uint8_t)(*((uint8_t*)_ubx_payload+27))
68#define UBX_NAV_SVIN_meanACC(_ubx_payload) (uint32_t)(*((uint8_t*)_ubx_payload+28)|*((uint8_t*)_ubx_payload+1+28)<<8|((uint32_t)*((uint8_t*)_ubx_payload+2+28))<<16|((uint32_t)*((uint8_t*)_ubx_payload+3+28))<<24)
69#define UBX_NAV_SVIN_OBS(_ubx_payload) (uint32_t)(*((uint8_t*)_ubx_payload+32)|*((uint8_t*)_ubx_payload+1+32)<<8|((uint32_t)*((uint8_t*)_ubx_payload+2+32))<<16|((uint32_t)*((uint8_t*)_ubx_payload+3+32))<<24)
70#define UBX_NAV_SVIN_Valid(_ubx_payload) (uint8_t)(*((uint8_t*)_ubx_payload+36))
71#define UBX_NAV_SVIN_Active(_ubx_payload) (uint8_t)(*((uint8_t*)_ubx_payload+37))
72#define UBX_NAV_SVIN_RES4(_ubx_payload) (uint16_t)(*((uint8_t*)_ubx_payload+38)|*((uint8_t*)_ubx_payload+1+38)<<8)
73
74
75#include <errno.h>
76#include "common.h"
77//#include "ubx_protocol.h"
78
80#define RTCM_OK 0
82#define RTCM_OK_CALLBACK_EXECUTED 1
84#define RTCM_OK_CALLBACK_UNDEFINED 2
86#define RTCM_CALLBACK_ERROR -1
88#define RTCM_CRC_ERROR -2
90#define RTCM_SEND_ERROR -3
92#define RTCM_NULL_ERROR -4
93
96typedef void (*rtcm3_msg_callback_t)(u8 len, u8 msg[]);
97
105 //void *context; /**< Pointer to a context */
108
109/* structure for processing RTCM and UBX messages */
125
126
127/* Function prototypes */
128
134
135s8 rtcm3_process(msg_state_t *s, unsigned char buff);
136s8 ubx_process(msg_state_t *s, unsigned char buff);
137unsigned int RTCMgetbitu(unsigned char *, int, int);
138int RTCMgetbits(unsigned char *, int , int);
139static double RTCMgetbits_38(unsigned char *, int);
140
141
142/* Global variables used for RTCM processing */
145int byteIndex = 0;
147int rawIndex = 0;
148
162{
163 /* Check our callback function pointer isn't NULL. */
164 if (cb == 0) {
165 return RTCM_NULL_ERROR;
166 }
167
168 /* Check our callback node pointer isn't NULL. */
169 if (node == 0) {
170 return RTCM_NULL_ERROR;
171 }
172
173 /* Check if callback was already registered for this type. */
174 if (rtcm3_find_callback(s, msg_type) != 0) {
175 return RTCM_CALLBACK_ERROR;
176 }
177
178 /* Fill in our new rtcm3_msg_callback_node_t. */
179 node->msg_type = msg_type;
180 node->cb = cb;
181 //node->context = context;
182 /* The next pointer is set to NULL, i.e. this
183 * will be the new end of the linked list.
184 */
185 node->next = 0;
186
187 /* If our linked list is empty then just
188 * add the new node to the start.
189 */
190 if (s->rtcm3_msg_callbacks_head == 0) {
191 s->rtcm3_msg_callbacks_head = node;
192 return RTCM_OK;
193 }
194
195 /* Find the tail of our linked list and
196 * add our new node to the end.
197 */
198 rtcm3_msg_callbacks_node_t *p = s->rtcm3_msg_callbacks_head;
199 while (p->next) {
200 p = p->next;
201 }
202
203 p->next = node;
204
205 return RTCM_OK;
206}
207
212{
213 /* Reset the head of the callbacks list to NULL. */
214 s->rtcm3_msg_callbacks_head = 0;
215}
216
226{
227 /* If our list is empty, return NULL. */
228 if (!s->rtcm3_msg_callbacks_head) {
229 return 0;
230 }
231
232 /* Traverse the linked list and return the callback
233 * function pointer if we find a node with a matching
234 * message id.
235 */
236 rtcm3_msg_callbacks_node_t *p = s->rtcm3_msg_callbacks_head;
237 do
238 if (p->msg_type == msg_type) {
239 return p;
240 }
241
242 while ((p = p->next));
243
244 /* Didn't find a matching callback, return NULL. */
245 return 0;
246}
247
256{
257 s->state = UNINIT;
258 s->msg_class = NO_CLASS;
259
260 /* Set the IO context pointer, passed to read and write functions, to NULL. */
261 // s->io_context = 0;
262
263 /* Clear the callbacks, if any, currently in s */
265}
266
267
268
269
310{
311 /* FAKE MESSAGE
312 buff[s->n_read] = s->n_read;
313 s->n_read++;
314 int fakeMsgLen = 200;
315 if(s->n_read == fakeMsgLen)
316 {
317 s->n_read = 0;
318 rtcm3_msg_callbacks_node_t* node = rtcm3_find_callback(s, RTCM3_MSG_1077);
319 (*node->cb)(s->sender_id, fakeMsgLen, buff, node->context);
320 return RTCM_OK_CALLBACK_EXECUTED;
321 }else{
322 return RTCM_OK;
323 }
324 */
325 if (s->n_read == (1024 + 6) && s->state != UNINIT) {
326 // We have exceeded the maximum message length (10bit) + 3 opening and 3 closing bytes. And we are not at UNINIT, this is not a proper message, reset!
327 s->state = UNINIT;
328 s->msg_class = NO_CLASS;
329 }
330 // Suppose we get more bytes than requested, lets still process them all
331#ifdef DEBUG_PRINT_PACKAGE
332 printf("0x%x ", buff);
333#endif
334 if (s->state != UNINIT && s->msg_class == RTCM_CLASS) { s->msg_buff[s->n_read] = buff; }
335 switch (s->state) {
336 case UNINIT:
337 s->n_read = 0;
338 if (((int) buff) == RTCM3_PREAMBLE) {
339 s->msg_class = RTCM_CLASS;
340 s->state = READ_RESERVED;
341 rawIndex = 0;
342 checksumCounter = 0;
343 byteIndex = 0;
344 s->msg_buff[s->n_read] = buff;
345 }
346 break;
347 case READ_RESERVED:
348 rd_msg_len1 = ((int) buff) & 0b00000011;
349 s->state = READ_LENGTH;
350 break;
351 case READ_LENGTH:
352 rd_msg_len = (rd_msg_len1 << 8) + ((int) buff) ;
353 s->state = READ_MESSAGE;
354 break;
355 case READ_MESSAGE:
356 if (byteIndex >= (rd_msg_len - 1)) { s->state = READ_CHECKSUM; }
357 byteIndex++;
358 break;
359 case READ_CHECKSUM:
361 if (checksumCounter == 3) {
362#ifdef DEBUG_PRINT_PACKAGE
363 printf("\n\n");
364#endif
365 s->state = UNINIT;
366 // Check what message type it is
367 switch (RTCMgetbitu(s->msg_buff, 24 + 0, 12)) {
368 case 1005: s->msg_type = RTCM3_MSG_1005; break;
369 case 4072: s->msg_type = RTCM3_MSG_4072; break;
370 case 1077: s->msg_type = RTCM3_MSG_1077; break;
371 case 1087: s->msg_type = RTCM3_MSG_1087; break;
372 case 1097: s->msg_type = RTCM3_MSG_1097; break;
373 case 1230: s->msg_type = RTCM3_MSG_1230; break;
374 default:
375#ifdef DEBUG_PRINT_PACKAGE
376 printf("Unknown message type %u\n", RTCMgetbitu(s->msg_buff, 24 + 0, 12));
377#endif
379 }
380 s->n_read++;
381 s->msg_len = s->n_read;
382 s->msg_class = NO_CLASS;
383#ifdef NO_CALLBACK
385#else
386 /* Message complete, process its callback. */
388 if (node) {
389 (*node->cb)(s->msg_len, s->msg_buff);
391 } else {
393 }
394#endif
395 }
396 break;
397 }
398 s->n_read++;
399 return RTCM_OK;
400}
401
402
403// UBX message decoding
404
406{
407 if (s->state < GOT_PAYLOAD && s->msg_class == UBX_CLASS) {
408 s->ck_a += buff;
409 s->ck_b += s->ck_a;
410 }
411 switch (s->state) {
412 case UNINIT:
413 if (buff == UBX_PREAMBLE1) {
414 s->state++;
415 s->msg_class = UBX_CLASS;
416 } else {
417 s->n_read = 0;
418 }
419 break;
420 case GOT_SYNC1:
421 if (buff != UBX_PREAMBLE2 && s->msg_class == UBX_CLASS) {
422 s->error_last = GPS_UBX_ERR_OUT_OF_SYNC;
423 goto error;
424 }
425 s->ck_a = 0;
426 s->ck_b = 0;
427 s->state ++;
428 break;
429 case GOT_SYNC2:
430 //s->msg_class = buff;
431 s->state++;
432 break;
433 case GOT_CLASS:
434 s->msg_type = buff;
435 s->state++;
436 break;
437 case GOT_ID:
438 s->msg_len = buff;
439 s->state++;
440 break;
441 case GOT_LEN1:
442 s->msg_len |= (buff << 8);
443 if (s->msg_len > GPS_UBX_MAX_PAYLOAD) {
444 s->error_last = GPS_UBX_ERR_MSG_TOO_LONG;
445 goto error;
446 }
447 s->n_read = 0;
448 s->state++;
449 break;
450 case GOT_LEN2:
451 s->msg_buff[s->n_read] = buff;
452 s->n_read++;
453 if (s->n_read >= s->msg_len) {
454 s->state++;
455 }
456 break;
457 case GOT_PAYLOAD:
458 if (buff != s->ck_a) {
459 s->error_last = GPS_UBX_ERR_CHECKSUM;
460 goto error;
461 }
462 s->state++;
463 break;
464 case GOT_CHECKSUM1:
465 if (buff != s->ck_b) {
466 s->error_last = GPS_UBX_ERR_CHECKSUM;
467 goto error;
468 }
469 s->msg_class = NO_CLASS;
470 s->n_read = 0;
471 s->state = UNINIT;
472#ifdef NO_CALLBACK
474#else
475 /* Message complete, process its callback. */
477 if (node) {
478 (*node->cb)(s->msg_len, s->msg_buff);
480 } else {
482 }
483#endif
484 break;
485 default:
486 s->error_last = GPS_UBX_ERR_UNEXPECTED;
487 goto error;
488 }
489 return RTCM_OK;
490error:
491 s->error_cnt++;
492 s->state = UNINIT;
493 s->msg_class = NO_CLASS;
494 return s->error_last;
495}
496
497unsigned int RTCMgetbitu(unsigned char *buff, int pos, int lenb)
498{
499 unsigned int bits = 0;
500 int i;
501 for (i = pos; i < pos + lenb; i++) { bits = (bits << 1) + ((buff[i / 8] >> (7 - i % 8)) & 1u); }
502 return bits;
503}
504
505int RTCMgetbits(unsigned char *buff, int pos, int lenb)
506{
507 unsigned int bits = RTCMgetbitu(buff, pos, lenb);
508 if (lenb <= 0 || 32 <= lenb || !(bits & (1u << (lenb - 1)))) { return (int)bits; }
509 return (int)(bits | (~0u << lenb)); /* extend sign */
510}
511
512static double RTCMgetbits_38(unsigned char *buff, int pos)
513{
514 return (double)RTCMgetbits(buff, pos, 32) * 64.0 + RTCMgetbitu(buff, pos + 32, 6);
515}
516
517#endif /* LIBRTCM3_RTCM3_H */
uint8_t u8
Unsigned 8-bit integer.
Definition common.h:41
int8_t s8
Signed 8-bit integer.
Definition common.h:33
uint16_t u16
Unsigned 16-bit integer.
Definition common.h:43
uint8_t msg[10]
Buffer used for general comunication over SPI (out buffer)
uint8_t buff[25]
Buffer used for general comunication over SPI (in buffer)
static float p[2][2]
static uint32_t s
uint16_t foo
Definition main_demo5.c:58
#define GOT_CLASS
Definition rtcm3.h:32
#define RTCM3_MSG_1005
Definition rtcm3.h:20
u16 msg_len
Definition rtcm3.h:116
#define GPS_UBX_ERR_UNEXPECTED
Definition rtcm3.h:48
struct rtcm3_msg_callbacks_node rtcm3_msg_callbacks_node_t
RTCM3 callback node.
int checksumCounter
Definition rtcm3.h:146
void(* rtcm3_msg_callback_t)(u8 len, u8 msg[])
RTCM3 callback function prototype definition.
Definition rtcm3.h:96
#define READ_MESSAGE
Definition rtcm3.h:16
#define GOT_SYNC2
Definition rtcm3.h:31
#define UBX_PREAMBLE1
Definition rtcm3.h:39
#define RTCM3_MSG_1077
Definition rtcm3.h:22
#define RTCM3_MSG_4072
Definition rtcm3.h:21
#define UBX_CLASS
Definition rtcm3.h:53
s8 ubx_process(msg_state_t *s, unsigned char buff)
Definition rtcm3.h:405
int rd_msg_len
Definition rtcm3.h:143
#define RTCM_OK
Return value indicating success.
Definition rtcm3.h:80
#define RTCM3_MSG_1230
Definition rtcm3.h:25
#define GOT_LEN1
Definition rtcm3.h:34
#define RTCM_OK_CALLBACK_UNDEFINED
Return value indicating message decoded with no associated callback in rtcm3_process.
Definition rtcm3.h:84
void msg_state_init(msg_state_t *s)
Initialize an msg_state_t struct before use.
Definition rtcm3.h:255
#define GPS_UBX_ERR_MSG_TOO_LONG
Definition rtcm3.h:46
#define NO_CLASS
Definition rtcm3.h:51
#define RTCM3_MSG_1087
Definition rtcm3.h:23
#define GOT_PAYLOAD
Definition rtcm3.h:36
#define GOT_SYNC1
Definition rtcm3.h:30
#define UNINIT
Definition rtcm3.h:29
#define GOT_CHECKSUM1
Definition rtcm3.h:37
rtcm3_msg_callbacks_node_t * rtcm3_find_callback(msg_state_t *s, u16 msg_type)
Find the callback function associated with a message type.
Definition rtcm3.h:225
s8 rtcm3_register_callback(msg_state_t *s, u16 msg_type, rtcm3_msg_callback_t cb, rtcm3_msg_callbacks_node_t *node)
Register a callback for a message type.
Definition rtcm3.h:160
#define RTCM_OK_CALLBACK_EXECUTED
Return value indicating message decoded and callback executed by rtcm3_process.
Definition rtcm3.h:82
u8 n_read
Definition rtcm3.h:117
#define READ_CHECKSUM
Definition rtcm3.h:17
#define GOT_ID
Definition rtcm3.h:33
#define GPS_UBX_ERR_CHECKSUM
Definition rtcm3.h:47
unsigned int RTCMgetbitu(unsigned char *, int, int)
Definition rtcm3.h:497
#define RTCM_NULL_ERROR
Return value indicating an error occured because an argument was NULL.
Definition rtcm3.h:92
#define READ_RESERVED
Definition rtcm3.h:14
#define RTCM_CALLBACK_ERROR
Return value indicating an error with the callback (function defined).
Definition rtcm3.h:86
struct rtcm3_msg_callbacks_node * next
Pointer to next node in list.
Definition rtcm3.h:106
u8 error_cnt
Definition rtcm3.h:122
u8 error_last
Definition rtcm3.h:123
#define READ_LENGTH
Definition rtcm3.h:15
s8 rtcm3_process(msg_state_t *s, unsigned char buff)
Read and process RTCM3 messages.
Definition rtcm3.h:309
#define RTCM_CLASS
Definition rtcm3.h:52
u8 status
Definition rtcm3.h:120
int rd_msg_len1
Definition rtcm3.h:144
u16 msg_type
Message ID associated with callback.
Definition rtcm3.h:103
#define RTCM3_PREAMBLE
Definition rtcm3.h:19
#define UBX_PREAMBLE2
Definition rtcm3.h:40
rtcm3_msg_callback_t cb
Pointer to callback function.
Definition rtcm3.h:104
int rawIndex
Definition rtcm3.h:147
int byteIndex
Definition rtcm3.h:145
#define GPS_UBX_MAX_PAYLOAD
Definition rtcm3.h:42
rtcm3_msg_callbacks_node_t * rtcm3_msg_callbacks_head
Definition rtcm3.h:119
#define RTCM3_MSG_1097
Definition rtcm3.h:24
void rtcm3_clear_callbacks(msg_state_t *s)
Clear all registered callbacks.
Definition rtcm3.h:211
u16 crc
Definition rtcm3.h:115
#define GOT_LEN2
Definition rtcm3.h:35
#define GPS_UBX_ERR_OUT_OF_SYNC
Definition rtcm3.h:49
static double RTCMgetbits_38(unsigned char *, int)
Definition rtcm3.h:512
u8 msg_class
Definition rtcm3.h:114
int RTCMgetbits(unsigned char *, int, int)
Definition rtcm3.h:505
u16 msg_type
Definition rtcm3.h:113
RTCM3 callback node.
Definition rtcm3.h:102
uint8_t ck_b
Definition w5100.c:91