Subversion Repositories FlightCtrl

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
740 Nick666 1
#include "main.h"
2
 
3
// ubx protocol parser state machine
4
#define UBXSTATE_IDLE   0
5
#define UBXSTATE_SYNC1  1
6
#define UBXSTATE_SYNC2  2
7
#define UBXSTATE_CLASS  3
8
#define UBXSTATE_LEN1   4
9
#define UBXSTATE_LEN2   5
10
#define UBXSTATE_DATA   6
11
#define UBXSTATE_CKA    7
12
#define UBXSTATE_CKB    8
13
 
14
// ublox protocoll identifier
15
#define UBX_CLASS_NAV   0x01
16
#define UBX_ID_POSLLH   0x02
17
#define UBX_ID_POSUTM   0x08
18
#define UBX_ID_STATUS   0x03
19
#define UBX_ID_VELNED   0x12
20
#define UBX_SYNC1_CHAR  0xB5
21
#define UBX_SYNC2_CHAR  0x62
22
 
23
typedef struct {
24
        uint32_t                ITOW;           // ms GPS Millisecond Time of Week
25
        uint8_t                 GPSfix;         // GPSfix Type, range 0..6
26
        uint8_t                 Flags;          // Navigation Status Flags
27
        uint8_t                 DiffS;          // Differential Status
28
        uint8_t                 res;            // reserved
29
        uint32_t                TTFF;           // Time to first fix (millisecond time tag)
30
        uint32_t                MSSS;           // Milliseconds since Startup / Reset
31
        uint8_t                 Status;
32
} GPS_STATUS_t;
33
 
34
typedef struct {
35
        uint32_t                ITOW;           // ms GPS Millisecond Time of Week
36
        int32_t                 LON;            // 1e-07 deg Longitude
37
        int32_t                 LAT;            // 1e-07 deg Latitude
38
        int32_t                 HEIGHT;         // mm Height above Ellipsoid
39
        int32_t                 HMSL;           // mm Height above mean sea level
40
        uint32_t                Hacc;           // mm Horizontal Accuracy Estimate
41
        uint32_t                Vacc;           // mm Vertical Accuracy Estimate
42
        uint8_t                 Status;
43
} GPS_POSLLH_t;
44
 
45
typedef struct {
46
        uint32_t                ITOW;           // ms GPS Millisecond Time of Week
47
        int32_t                 EAST;           // cm  UTM Easting
48
        int32_t                 NORTH;          // cm  UTM Nording
49
        int32_t                 ALT;            // cm  altitude
50
        uint8_t                 ZONE;           // UTM zone number
51
        uint8_t                 HEM;            // Hemisphere Indicator (0=North, 1=South)
52
        uint8_t                 Status;
53
} GPS_POSUTM_t;
54
 
55
typedef struct {
56
        uint32_t                ITOW;           // ms  GPS Millisecond Time of Week
57
        int32_t                 VEL_N;          // cm/s  NED north velocity
58
        int32_t                 VEL_E;          // cm/s  NED east velocity
59
        int32_t                 VEL_D;          // cm/s  NED down velocity
60
        uint32_t                Speed;          // cm/s  Speed (3-D)
61
        uint32_t                GSpeed;         // cm/s  Ground Speed (2-D)
62
        int32_t                 Heading;        // 1e-05 deg  Heading 2-D
63
        uint32_t                SAcc;           // cm/s  Speed Accuracy Estimate
64
        uint32_t                CAcc;           // deg  Course / Heading Accuracy Estimate
65
        uint8_t                 Status;
66
} GPS_VELNED_t;
67
 
68
GPS_STATUS_t    GpsStatus = {0,0,0,0,0,0,0, INVALID};
69
GPS_POSLLH_t    GpsPosLlh = {0,0,0,0,0,0,0, INVALID};
70
GPS_POSUTM_t    GpsPosUtm = {0,0,0,0,0,0, INVALID};
71
GPS_VELNED_t    GpsVelNed = {0,0,0,0,0,0,0,0,0, INVALID};
72
GPS_INFO_t      GPSInfo   = {0,0,0,0,0,0,0,0,0,0, INVALID};
73
 
74
volatile uint8_t GPSTimeout = 0;
75
 
76
void UpdateGPSInfo (void)
77
{
78
        if (GpsStatus.Status == VALID)                  // valid packet
79
        {
80
                GPSInfo.satfix = GpsStatus.GPSfix;
81
                GpsStatus.Status = PROCESSED;           // never update old data
82
        }
83
        if (GpsPosLlh.Status == VALID)                  // valid packet
84
        {
85
                GPSInfo.longitude = GpsPosLlh.LON;
86
                GPSInfo.latitude = GpsPosLlh.LAT;
87
                GPSInfo.altitude = GpsPosLlh.HEIGHT;
88
                GpsPosLlh.Status = PROCESSED;           // never update old data
89
        }
90
        if (GpsPosUtm.Status == VALID)                  // valid packet
91
        {
92
                GPSInfo.utmeast = GpsPosUtm.EAST;
93
                GPSInfo.utmnorth = GpsPosUtm.NORTH;
94
                GPSInfo.utmalt = GpsPosUtm.ALT;
95
                GpsPosUtm.Status = PROCESSED;           // never update old data
96
        }
97
        if (GpsVelNed.Status == VALID)                  // valid packet
98
        {
99
                GPSInfo.veleast = GpsVelNed.VEL_E;
100
                GPSInfo.velnorth = GpsVelNed.VEL_N;
101
                GPSInfo.veltop = -GpsVelNed.VEL_D;
742 Nick666 102
                GPSInfo.velground = GpsVelNed.GSpeed;
740 Nick666 103
                GpsVelNed.Status = PROCESSED;           // never update old data
104
        }
105
        if (GpsStatus.Status != INVALID)
106
        {
107
                GPSInfo.status = VALID;             // set valid if data are updated
108
        }
109
}
110
 
111
 
112
// this function should be called within the UART RX ISR
113
void ubx_parser(uint8_t c)
114
{
115
        static uint8_t ubxstate = UBXSTATE_IDLE;
116
        static uint8_t cka, ckb;
117
        static uint16_t msglen;
118
        static int8_t *ubxP, *ubxEp, *ubxSp; // pointers to data currently transfered
119
 
120
        switch(ubxstate)
121
        {
122
                case UBXSTATE_IDLE: // check 1st sync byte
123
                        if (c == UBX_SYNC1_CHAR) ubxstate = UBXSTATE_SYNC1;
124
                        else ubxstate = UBXSTATE_IDLE; // out of synchronization
125
                        break;
126
 
127
                case UBXSTATE_SYNC1: // check 2nd sync byte
128
                        if (c == UBX_SYNC2_CHAR) ubxstate = UBXSTATE_SYNC2;
129
                        else ubxstate = UBXSTATE_IDLE; // out of synchronization
130
                        break;
131
 
132
                case UBXSTATE_SYNC2: // check msg class to be NAV
133
                        if (c == UBX_CLASS_NAV) ubxstate = UBXSTATE_CLASS;
134
                        else ubxstate = UBXSTATE_IDLE; // unsupported message class
135
                        break;
136
 
137
                case UBXSTATE_CLASS: // check message identifier
138
                        switch(c)
139
                        {
140
                                case UBX_ID_POSUTM: // utm position
141
                                        ubxP =  (int8_t *)&GpsPosUtm; // data start pointer
142
                                        ubxEp = (int8_t *)(&GpsPosUtm + sizeof(GPS_POSUTM_t)); // data end pointer
143
                                        ubxSp = (int8_t *)&GpsPosUtm.Status; // status pointer
144
                                        break;
145
 
146
                                case UBX_ID_POSLLH: // geodetic position
147
                                        ubxP =  (int8_t *)&GpsPosLlh; // data start pointer
148
                                        ubxEp = (int8_t *)(&GpsPosLlh + sizeof(GPS_POSLLH_t)); // data end pointer
149
                                        ubxSp = (int8_t *)&GpsPosLlh.Status; // status pointer
150
                                        break;
151
 
152
                                case UBX_ID_STATUS: // receiver status
153
                                        ubxP =  (int8_t *)&GpsStatus; // data start pointer
154
                                        ubxEp = (int8_t *)(&GpsStatus + sizeof(GPS_STATUS_t)); // data end pointer
155
                                        ubxSp = (int8_t *)&GpsStatus.Status; // status pointer
156
                                        break;
157
 
158
                                case UBX_ID_VELNED: // velocity vector in tangent plane
159
                                        ubxP =  (int8_t *)&GpsVelNed; // data start pointer
160
                                        ubxEp = (int8_t *)(&GpsVelNed + sizeof(GPS_VELNED_t)); // data end pointer
161
                                        ubxSp = (int8_t *)&GpsVelNed.Status; // status pointer
162
                                        break;
163
 
164
                                default:                        // unsupported identifier
165
                                        ubxstate = UBXSTATE_IDLE;
166
                                        break;
167
                        }
168
                        if (ubxstate != UBXSTATE_IDLE)
169
                        {
170
                                ubxstate = UBXSTATE_LEN1;
171
                                cka = UBX_CLASS_NAV + c;
172
                                ckb = UBX_CLASS_NAV + cka;
173
                        }
174
                        break;
175
 
176
                case UBXSTATE_LEN1: // 1st message length byte
177
                        msglen = c;
178
                        cka += c;
179
                        ckb += cka;
180
                        ubxstate = UBXSTATE_LEN2;
181
                        break;
182
 
183
                case UBXSTATE_LEN2: // 2nd message length byte
184
                        msglen += ((uint16_t)c)<<8;
185
                        cka += c;
186
                        ckb += cka;
187
                        // if the old data are not processed so far then break parsing now
188
                        // to avoid writing new data in ISR during reading by another function
189
                        if ( *ubxSp == VALID ) ubxstate = UBXSTATE_IDLE;
190
                        else // data invalid or allready processd
191
                        {
192
                                *ubxSp = INVALID;
193
                                ubxstate = UBXSTATE_DATA;
194
                        }
195
                        break;
196
 
197
                case UBXSTATE_DATA:
198
                        if (ubxP < ubxEp) *ubxP++ = c; // copy curent data byte if any space is left
199
                        cka += c;
200
                        ckb += cka;
201
                        if (--msglen == 0)      ubxstate = UBXSTATE_CKA; // switch to next state if all data was read
202
                        break;
203
 
204
                case UBXSTATE_CKA:
205
                        if (c == cka) ubxstate = UBXSTATE_CKB;
206
                        else
207
                        {
208
                                *ubxSp = INVALID;
209
                                ubxstate = UBXSTATE_IDLE;
210
                        }
211
                        break;
212
 
213
                case UBXSTATE_CKB:
214
                        if (c == ckb)
215
                        {
216
                                *ubxSp = VALID; // new data are valid
217
                                ROT_FLASH;
218
                                UpdateGPSInfo(); //update GPS info respectively
219
                                GPSTimeout = 255;
220
                        }
221
                        else
222
                        {       // if checksum not fit then set data invalid
223
                                *ubxSp = INVALID;
224
                        }
225
                        ubxstate = UBXSTATE_IDLE; // ready to parse new data
226
                        break;
227
 
228
                default: // unknown ubx state
229
                        ubxstate = UBXSTATE_IDLE;
230
                        break;
231
        }
232
 
233
}
234
 
235