Paparazzi UAS  v5.8.2_stable-0-g6260b7c
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
gps_ubx_ucenter.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2008-2011 The Paparazzi Team
3  *
4  * This file is part of paparazzi.
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, write to
18  * the Free Software Foundation, 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  * Initial author: C. De Wagter
22  */
23 
31 #include "subsystems/gps/gps_ubx.h"
32 #include "ubx_protocol.h"
34 #include <stdio.h>
35 
36 #if PRINT_DEBUG_GPS_UBX_UCENTER
37 #define DEBUG_PRINT(...) printf(__VA_ARGS__)
38 #else
39 #define DEBUG_PRINT(...) {}
40 #endif
41 
44 //
45 // UCENTER: init, periodic and event
46 
47 static bool_t gps_ubx_ucenter_autobaud(uint8_t nr);
48 static bool_t gps_ubx_ucenter_configure(uint8_t nr);
49 
50 #define GPS_UBX_UCENTER_STATUS_STOPPED 0
51 #define GPS_UBX_UCENTER_STATUS_AUTOBAUD 1
52 #define GPS_UBX_UCENTER_STATUS_CONFIG 2
53 
54 #define GPS_UBX_UCENTER_REPLY_NONE 0
55 #define GPS_UBX_UCENTER_REPLY_ACK 1
56 #define GPS_UBX_UCENTER_REPLY_NACK 2
57 #define GPS_UBX_UCENTER_REPLY_VERSION 3
58 #define GPS_UBX_UCENTER_REPLY_CFG_PRT 4
59 
60 // Target baudrate for the module
61 #define UBX_GPS_BAUD (GPS_LINK).baudrate
62 
63 // All U-Center data
65 
66 
68 // Init Function
69 
71 {
72  // Start UCenter
75  gps_ubx_ucenter.cnt = 0;
76 
80 
85 
86  for (int i = 0; i < GPS_UBX_UCENTER_CONFIG_STEPS; i++) {
87  gps_ubx_ucenter.replies[i] = 0;
88  }
89 
90  gps_ubx_ucenter.dev = &(GPS_LINK).device;
91 }
92 
93 
95 // Periodic Function
96 // -time-based configuration
97 
99 {
100  switch (gps_ubx_ucenter.status) {
101  // Save processing time inflight
103  return;
104  // Automatically Determine Current Baudrate
108  gps_ubx_ucenter.cnt = 0;
109 #if PRINT_DEBUG_GPS_UBX_UCENTER
110  if (gps_ubx_ucenter.baud_init > 0) {
111  DEBUG_PRINT("Initial ublox baudrate found: %u\n", gps_ubx_ucenter.baud_init);
112  } else {
113  DEBUG_PRINT("WARNING: Unable to determine the ublox baudrate. Autoconfiguration is unlikely to work.\n");
114  }
115 #endif
116  } else {
118  }
119  break;
120  // Send Configuration
124  gps_ubx_ucenter.cnt = 0;
125  } else {
127  }
128  break;
129  default:
130  // stop this module now...
131  // todo
132  break;
133  }
134 }
135 
137 // Event Function
138 // -fetch replies: ACK and VERSION info
139 
141 {
142  // Save processing time inflight
144  return;
145  }
146 
147  // Read Configuration Reply's
148  switch (gps_ubx.msg_class) {
149  case UBX_ACK_ID:
150  if (gps_ubx.msg_id == UBX_ACK_ACK_ID) {
152  DEBUG_PRINT("ACK\n");
153  } else {
155  DEBUG_PRINT("NACK\n");
156  }
157  break;
158  case UBX_MON_ID:
159  if (gps_ubx.msg_id == UBX_MON_VER_ID) {
161  gps_ubx_ucenter.sw_ver_h = UBX_MON_VER_c(gps_ubx.msg_buf, 0) - '0';
162  gps_ubx_ucenter.sw_ver_l = 10 * (UBX_MON_VER_c(gps_ubx.msg_buf, 2) - '0');
163  gps_ubx_ucenter.sw_ver_l += UBX_MON_VER_c(gps_ubx.msg_buf, 3) - '0';
164  gps_ubx_ucenter.hw_ver_h = UBX_MON_VER_c(gps_ubx.msg_buf, 33) - '0';
165  gps_ubx_ucenter.hw_ver_h += 10 * (UBX_MON_VER_c(gps_ubx.msg_buf, 32) - '0');
166  gps_ubx_ucenter.hw_ver_l = UBX_MON_VER_c(gps_ubx.msg_buf, 37) - '0';
167  gps_ubx_ucenter.hw_ver_l += 10 * (UBX_MON_VER_c(gps_ubx.msg_buf, 36) - '0');
168 
169  DEBUG_PRINT("ublox sw_ver: %u.%u\n", gps_ubx_ucenter.sw_ver_h, gps_ubx_ucenter.sw_ver_l);
170  DEBUG_PRINT("ublox hw_ver: %u.%u\n", gps_ubx_ucenter.hw_ver_h, gps_ubx_ucenter.hw_ver_l);
171  }
172  break;
173  case UBX_CFG_ID:
174  if (gps_ubx.msg_id == UBX_CFG_PRT_ID) {
176  gps_ubx_ucenter.port_id = UBX_CFG_PRT_PortId(gps_ubx.msg_buf, 0);
177  gps_ubx_ucenter.baud_run = UBX_CFG_PRT_Baudrate(gps_ubx.msg_buf, 0);
178 
179  DEBUG_PRINT("gps_ubx_ucenter.baud_run: %u\n", gps_ubx_ucenter.baud_run);
180  DEBUG_PRINT("gps_ubx_ucenter.port_id: %u\n", gps_ubx_ucenter.port_id);
181  }
182  break;
183  default:
184  break;
185  }
186 }
187 
190 //
191 // UCENTER Configuration Functions
192 
199 static inline void gps_ubx_ucenter_config_port_poll(void)
200 {
201  UbxSend_CFG_PRT_POLL(gps_ubx_ucenter.dev);
202 }
203 
216 static inline void gps_ubx_ucenter_enable_msg(uint8_t class, uint8_t id, uint8_t rate)
217 {
218  UbxSend_CFG_MSG(gps_ubx_ucenter.dev, class, id, rate);
219 }
220 
230 {
231  switch (nr) {
232  case 0:
233  case 1:
234  // Very important for some modules:
235  // Give the GPS some time to boot (up to 0.75 second)
236  break;
237  case 2:
239  uart_periph_set_baudrate(&(GPS_LINK), B38400); // Try the most common first?
241  break;
242  case 3:
245  return FALSE;
246  }
248  uart_periph_set_baudrate(&(GPS_LINK), B9600); // Maybe the factory default?
250  break;
251  case 4:
254  return FALSE;
255  }
257  uart_periph_set_baudrate(&(GPS_LINK), B57600); // The high-rate default?
259  break;
260  case 5:
263  return FALSE;
264  }
266  uart_periph_set_baudrate(&(GPS_LINK), B4800); // Default NMEA baudrate?
268  break;
269  case 6:
272  return FALSE;
273  }
275  uart_periph_set_baudrate(&(GPS_LINK), B115200); // Last possible option for ublox
277  break;
278  case 7:
281  return FALSE;
282  }
284  uart_periph_set_baudrate(&(GPS_LINK), B230400); // Last possible option for ublox
286  break;
287  case 8:
290  return FALSE;
291  }
292 
293  // Autoconfig Failed... let's setup the failsafe baudrate
294  // Should we try even a different baudrate?
295  gps_ubx_ucenter.baud_init = 0; // Set as zero to indicate that we couldn't verify the baudrate
296  uart_periph_set_baudrate(&(GPS_LINK), B9600);
297  return FALSE;
298  default:
299  break;
300  }
301  return TRUE;
302 }
303 
305 // UBlox internal Navigation Solution
306 
307 #define NAV_DYN_STATIONARY 1
308 #define NAV_DYN_PEDESTRIAN 2
309 #define NAV_DYN_AUTOMOTIVE 3
310 #define NAV_DYN_SEA 4
311 #define NAV_DYN_AIRBORNE_1G 5
312 #define NAV_DYN_AIRBORNE_2G 6 // paparazzi default
313 #define NAV_DYN_AIRBORNE_4G 7
314 
315 #define NAV5_DYN_PORTABLE 0 // ublox default
316 #define NAV5_DYN_FIXED 1
317 #define NAV5_DYN_STATIONARY 2
318 #define NAV5_DYN_PEDESTRIAN 3
319 #define NAV5_DYN_AUTOMOTIVE 4
320 #define NAV5_DYN_SEA 5
321 #define NAV5_DYN_AIRBORNE_1G 6
322 #define NAV5_DYN_AIRBORNE_2G 7 // paparazzi default
323 #define NAV5_DYN_AIRBORNE_4G 8
324 
325 #ifndef GPS_UBX_NAV5_DYNAMICS
326 #define GPS_UBX_NAV5_DYNAMICS NAV5_DYN_AIRBORNE_2G
327 #endif
328 
329 #define NAV5_MASK 0x05 // Apply dynamic model and position fix mode settings
330 
331 #define NAV5_2D_ONLY 1
332 #define NAV5_3D_ONLY 2 // paparazzi default
333 #define NAV5_AUTO 3 // ublox default
334 
335 #define NAV5_DEFAULT_MIN_ELEV 5 // deg
336 #define NAV5_DEFAULT_PDOP_MASK 25 // no units
337 #define NAV5_DEFAULT_TDOP_MASK 25 // no units
338 #define NAV5_DEFAULT_P_ACC 100 // m
339 #define NAV5_DEFAULT_T_ACC 300 // m
340 #define NAV5_DEFAULT_STATIC_HOLD_THRES 0 // cm/s
341 
342 #define IGNORED 0
343 #define RESERVED 0
344 
345 static inline void gps_ubx_ucenter_config_nav(void)
346 {
347  // New ublox firmware v5 or higher uses CFG_NAV5 message, CFG_NAV is no longer available
348  // If version message couldn't be fetched, default to NAV5
351  UbxSend_CFG_NAV(gps_ubx_ucenter.dev,
352  NAV_DYN_AIRBORNE_2G, 3, 16, 24, 20, 5, 0, 0x3C,
353  0x3C, 0x14, 0x03E8 , 0x0000, 0x0, 0x17, 0x00FA, 0x00FA,
354  0x0064, 0x012C, 0x000F, 0x00, 0x00);
355  } else {
356  UbxSend_CFG_NAV5(gps_ubx_ucenter.dev,
360  }
361 }
362 
363 
364 
366 // UBlox port and protocol GPS configuration
367 
368 #ifdef GPS_PORT_ID
369 #warning "GPS_PORT_ID is no longer needed by the ublox ucenter for automatically configuration. Please remove this defined variable and double check that autoconfig is working as expected."
370 #endif
371 
372 // UART mode: 8N1 with reserved1 set for compatability with A4
373 #define UBX_UART_MODE_MASK 0x000008D0
374 
375 #define UBX_PROTO_MASK 0x0001
376 #define NMEA_PROTO_MASK 0x0002
377 #define RTCM_PROTO_MASK 0x0004
378 
379 #define GPS_PORT_DDC 0x00
380 #define GPS_PORT_UART1 0x01
381 #define GPS_PORT_UART2 0x02
382 #define GPS_PORT_USB 0x03
383 #define GPS_PORT_SPI 0x04
384 #define GPS_PORT_RESERVED 0x05
385 
386 #ifndef GPS_UBX_UCENTER_RATE
387 #define GPS_UBX_UCENTER_RATE 0x00FA // In milliseconds. 0x00FA = 250ms = 4Hz
388 #endif
389 
390 static inline void gps_ubx_ucenter_config_port(void)
391 {
392  switch (gps_ubx_ucenter.port_id) {
393  // I2C Interface
394  case GPS_PORT_DDC:
395 #ifdef GPS_I2C
396  UbxSend_CFG_PRT(gps_ubx_ucenter.dev, gps_ubx_ucenter.port_id, 0x0, 0x0, GPS_I2C_SLAVE_ADDR, 0x0, UBX_PROTO_MASK, UBX_PROTO_MASK, 0x0, 0x0);
397 #else
398  DEBUG_PRINT("WARNING: Please include the gps_i2c module.\n");
399 #endif
400  break;
401  // UART Interface
402  case GPS_PORT_UART1:
403  case GPS_PORT_UART2:
404  UbxSend_CFG_PRT(gps_ubx_ucenter.dev,
405  gps_ubx_ucenter.port_id, 0x0, 0x0,
407  UBX_PROTO_MASK, 0x0, 0x0);
408  break;
409  // USB Interface
410  case GPS_PORT_USB:
411  UbxSend_CFG_PRT(gps_ubx_ucenter.dev,
412  gps_ubx_ucenter.port_id, 0x0, 0x0, 0x0, 0x0,
413  UBX_PROTO_MASK, UBX_PROTO_MASK, 0x0, 0x0);
414  break;
415  case GPS_PORT_SPI:
416  DEBUG_PRINT("WARNING: ublox SPI port is currently not supported.\n");
417  break;
418  default:
419  DEBUG_PRINT("WARNING: Unknown ublox port id: %u\n", gps_ubx_ucenter.port_id);
420  break;
421  }
422 }
423 
424 #define GPS_SBAS_ENABLED 0x01
425 
426 #define GPS_SBAS_RANGING 0x01
427 #define GPS_SBAS_CORRECTIONS 0x02
428 #define GPS_SBAS_INTEGRITY 0x04
429 
430 #define GPS_SBAS_MAX_SBAS 1 // Default ublox setting uses 3 SBAS channels(?)
431 
432 #define GPS_SBAS_AUTOSCAN 0x00
433 
434 static inline void gps_ubx_ucenter_config_sbas(void)
435 {
436  // Since March 2nd 2011 EGNOS is released for aviation purposes
439  //UbxSend_CFG_SBAS(0x00, 0x00, 0x00, 0x00, 0x00);
440 }
441 
442 // Text Telemetry for Debugging
443 #undef GOT_PAYLOAD
444 
446 {
447  DEBUG_PRINT("gps_ubx_ucenter_configure nr: %u\n", nr);
448 
449  // Store the reply of the last configuration step and reset
450  if (nr < GPS_UBX_UCENTER_CONFIG_STEPS) {
452  }
453 
454  switch (nr) {
455  case 0:
456  // Use old baudrate to issue a baudrate change command
458  break;
459  case 1:
460 #if PRINT_DEBUG_GPS_UBX_UCENTER
462  DEBUG_PRINT("ublox did not acknowledge port configuration.\n");
463  } else {
464  DEBUG_PRINT("Changed ublox baudrate to: %u\n", UART_SPEED(gps_ubx_ucenter.baud_target));
465  }
466 #endif
467  // Now the GPS baudrate should have changed
470  UbxSend_MON_GET_VER(gps_ubx_ucenter.dev);
471  break;
472  case 2:
473  case 3:
474  case 4:
475  case 5:
476  // UBX_G5010 takes 0.7 seconds to answer a firmware request
477  // Version info is important for proper configuration as different firmwares have different settings
478  break;
479  case 6:
480  // Send some debugging info: detected baudrate, software version etc...
487 #if DEBUG_GPS_UBX_UCENTER
488  DOWNLINK_SEND_DEBUG(DefaultChannel, DefaultDevice, 6, gps_ubx_ucenter.replies);
489 #endif
490  // Configure CFG-NAV(5) message
492  break;
493  case 7:
494  // Geodetic Position Solution
495  gps_ubx_ucenter_enable_msg(UBX_NAV_ID, UBX_NAV_POSLLH_ID, 1);
496  break;
497  case 8:
498  // Velocity Solution in NED
499  gps_ubx_ucenter_enable_msg(UBX_NAV_ID, UBX_NAV_VELNED_ID, 1);
500  break;
501  case 9:
502  // Receiver Navigation Status
503  gps_ubx_ucenter_enable_msg(UBX_NAV_ID, UBX_NAV_STATUS_ID, 1);
504  break;
505  case 10:
506  // Space Vehicle Information
507  gps_ubx_ucenter_enable_msg(UBX_NAV_ID, UBX_NAV_SVINFO_ID, 4);
508  break;
509  case 11:
510  // Navigation Solution Information
511 #if GPS_UBX_UCENTER_SLOW_NAV_SOL
512  gps_ubx_ucenter_enable_msg(UBX_NAV_ID, UBX_NAV_SOL_ID, 8);
513 #else
514  gps_ubx_ucenter_enable_msg(UBX_NAV_ID, UBX_NAV_SOL_ID, 1);
515 #endif
516  break;
517  case 12:
518  // Disable UTM on old Lea4P
519  gps_ubx_ucenter_enable_msg(UBX_NAV_ID, UBX_NAV_POSUTM_ID, 0);
520  break;
521  case 13:
522  // SBAS Configuration
524  break;
525  case 14:
526  // Poll Navigation/Measurement Rate Settings
527  UbxSend_CFG_RATE(gps_ubx_ucenter.dev, GPS_UBX_UCENTER_RATE, 0x0001, 0x0000);
528  break;
529  case 15:
530  // Raw Measurement Data
531 #if USE_GPS_UBX_RXM_RAW
532  gps_ubx_ucenter_enable_msg(UBX_RXM_ID, UBX_RXM_RAW_ID, 1);
533 #endif
534  break;
535  case 16:
536  // Subframe Buffer
537 #if USE_GPS_UBX_RXM_SFRB
538  gps_ubx_ucenter_enable_msg(UBX_RXM_ID, UBX_RXM_SFRB_ID, 1);
539 #endif
540  break;
541  case 17:
542  // Try to save on non-ROM devices...
543  UbxSend_CFG_CFG(gps_ubx_ucenter.dev, 0x00000000, 0xffffffff, 0x00000000);
544  break;
545  case 18:
546 #if DEBUG_GPS_UBX_UCENTER
547  // Debug Downlink the result of all configuration steps: see messages
548  // To view, enable DEBUG message in your telemetry configuration .xml
550  for (int i = 0; i < GPS_UBX_UCENTER_CONFIG_STEPS; i++) {
551  DEBUG_PRINT("%u\n", gps_ubx_ucenter.replies[i]);
552  }
553 #endif
554  return FALSE;
555  default:
556  break;
557  }
558 
560  return TRUE; // Continue, except for the last case
561 }
562 
#define NAV5_DEFAULT_MIN_ELEV
#define NAV5_DEFAULT_P_ACC
#define GPS_UBX_UCENTER_CONFIG_STEPS
U-Center Variables.
#define NAV5_DEFAULT_PDOP_MASK
#define GPS_UBX_UCENTER_STATUS_STOPPED
#define GPS_PORT_UART1
#define GPS_SBAS_RANGING
#define GPS_UBX_UCENTER_REPLY_NONE
#define GPS_SBAS_AUTOSCAN
#define GPS_PORT_DDC
#define GPS_SBAS_CORRECTIONS
#define NAV5_DEFAULT_STATIC_HOLD_THRES
UBX protocol specific code.
#define IGNORED
#define GPS_UBX_UCENTER_RATE
struct GpsUbx gps_ubx
Definition: gps_ubx.c:58
#define UBX_GPS_BAUD
char replies[GPS_UBX_UCENTER_CONFIG_STEPS]
uint8_t msg_buf[GPS_UBX_MAX_PAYLOAD]
Definition: gps_ubx.h:41
#define GPS_SBAS_ENABLED
#define B9600
Definition: uart_arch.h:40
uint8_t msg_id
Definition: gps_ubx.h:42
static void gps_ubx_ucenter_config_sbas(void)
#define FALSE
Definition: std.h:5
#define B115200
Definition: uart_arch.h:45
void uart_periph_set_baudrate(struct uart_periph *periph, uint32_t baud)
Definition: uart_arch.c:216
#define GPS_UBX_UCENTER_REPLY_NACK
static void gps_ubx_ucenter_config_port(void)
Configure Ublox GPS.
struct gps_ubx_ucenter_struct gps_ubx_ucenter
#define TRUE
Definition: std.h:4
#define GPS_PORT_SPI
void gps_ubx_ucenter_periodic(void)
#define NAV5_DEFAULT_T_ACC
#define GPS_UBX_NAV5_DYNAMICS
#define GPS_UBX_UCENTER_STATUS_AUTOBAUD
#define NAV5_DEFAULT_TDOP_MASK
#define GPS_UBX_UCENTER_REPLY_ACK
#define GPS_UBX_UCENTER_STATUS_CONFIG
#define GPS_SBAS_INTEGRITY
#define NAV_DYN_AIRBORNE_2G
#define B38400
Definition: uart_arch.h:42
#define GPS_UBX_UCENTER_REPLY_VERSION
#define GPS_UBX_UCENTER_REPLY_CFG_PRT
#define B57600
Definition: uart_arch.h:43
#define RESERVED
static void gps_ubx_ucenter_config_port_poll(void)
Polls the u-blox port configuration When the payload is omitted (zero length), the configuration for ...
#define NAV5_MASK
void gps_ubx_ucenter_init(void)
#define UART_SPEED(_def)
Definition: uart_arch.h:61
void gps_ubx_ucenter_event(void)
static bool_t gps_ubx_ucenter_configure(uint8_t nr)
unsigned char uint8_t
Definition: types.h:14
struct link_device * dev
#define GPS_PORT_USB
#define GPS_SBAS_MAX_SBAS
uint8_t port_id
Port identifier number.
#define DEBUG_PRINT(...)
static bool_t gps_ubx_ucenter_autobaud(uint8_t nr)
Automatically determine the baudrate of the u-blox module.
#define B230400
Definition: uart_arch.h:46
#define NAV5_3D_ONLY
#define UBX_PROTO_MASK
#define GPS_PORT_UART2
#define B4800
Definition: uart_arch.h:39
#define UBX_UART_MODE_MASK
uint8_t msg_class
Definition: gps_ubx.h:43
#define GPS_I2C_SLAVE_ADDR
Default address for u-blox (and others?)
Definition: gps_i2c.h:29
static void gps_ubx_ucenter_config_nav(void)
static void gps_ubx_ucenter_enable_msg(uint8_t class, uint8_t id, uint8_t rate)
Enable u-blox message at desired period.