forked from cgwood/ArdustationMega
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AP_GPS_Auto.cpp
126 lines (103 loc) · 2.97 KB
/
AP_GPS_Auto.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: t -*-
/// @file AP_GPS_Auto.cpp
/// @brief Simple GPS auto-detection logic.
//#include <AP_Common.h>
#include "AP_GPS.h" // includes AP_GPS_Auto.h
static const uint32_t baudrates[] PROGMEM = {38400U, 57600U, 9600U, 4800U};
const prog_char AP_GPS_Auto::_mtk_set_binary[] PROGMEM = MTK_SET_BINARY;
const prog_char AP_GPS_Auto::_sirf_set_binary[] PROGMEM = SIRF_SET_BINARY;
AP_GPS_Auto::AP_GPS_Auto(Stream *s, GPS **gps) :
GPS(s),
_fs(s),
_gps(gps)
{
}
// Do nothing at init time - it may be too early to try detecting the GPS
//
void
AP_GPS_Auto::init(enum GPS_Engine_Setting nav_setting)
{
idleTimeout = 1200;
_nav_setting = nav_setting;
}
// Called the first time that a client tries to kick the GPS to update.
//
// We detect the real GPS, then update the pointer we have been called through
// and return.
//
bool
AP_GPS_Auto::read(void)
{
static uint32_t last_baud_change_ms;
static uint8_t last_baud;
GPS *gps;
uint32_t now = millis();
if (now - last_baud_change_ms > 1200) {
// its been more than 1.2 seconds without detection on this
// GPS - switch to another baud rate
// _fs->begin(pgm_read_dword(&baudrates[last_baud]), 256, 16);
// last_baud++;
// last_baud_change_ms = now;
// if (last_baud == sizeof(baudrates) / sizeof(baudrates[0])) {
// last_baud = 0;
// }
// Above doesn't work, disable for now
last_baud = 0;
// write config strings for the types of GPS we support
_send_progstr(_fs, _mtk_set_binary, sizeof(_mtk_set_binary));
_send_progstr(_fs, AP_GPS_UBLOX::_ublox_set_binary, AP_GPS_UBLOX::_ublox_set_binary_size);
_send_progstr(_fs, _sirf_set_binary, sizeof(_sirf_set_binary));
}
_update_progstr();
if (NULL != (gps = _detect())) {
// configure the detected GPS
gps->init(_nav_setting);
// Serial.println_P(PSTR("OK"));
Serial.println("OK");
*_gps = gps;
return true;
}
return false;
}
//
// Perform one iteration of the auto-detection process.
//
GPS *
AP_GPS_Auto::_detect(void)
{
static uint32_t detect_started_ms;
if (detect_started_ms == 0 && _port->available() > 0) {
detect_started_ms = millis();
}
while (_port->available() > 0) {
uint8_t data = _port->read();
if (AP_GPS_UBLOX::_detect(data)) {
Serial.print((" ublox "));
return new AP_GPS_UBLOX(_port);
}
if (AP_GPS_MTK19::_detect(data)) {
Serial.print((" MTK19 "));
return new AP_GPS_MTK19(_port);
}
if (AP_GPS_MTK::_detect(data)) {
Serial.print((" MTK "));
return new AP_GPS_MTK(_port);
}
#if !defined( __AVR_ATmega1280__ )
// save a bit of code space on a 1280
if (AP_GPS_SIRF::_detect(data)) {
Serial.print((" SIRF "));
return new AP_GPS_SIRF(_port);
}
if (millis() - detect_started_ms > 5000) {
// prevent false detection of NMEA mode in
// a MTK or UBLOX which has booted in NMEA mode
if (AP_GPS_NMEA::_detect(data)) {
Serial.print((" NMEA "));
return new AP_GPS_NMEA(_port);
}
}
#endif
}
return NULL;
}