dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
GPS.c
Go to the documentation of this file.
1 
17 /*
18  * This program is free software; you can redistribute it and/or modify
19  * it under the terms of the GNU General Public License as published by
20  * the Free Software Foundation; either version 3 of the License, or
21  * (at your option) any later version.
22  *
23  * This program is distributed in the hope that it will be useful, but
24  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26  * for more details.
27  *
28  * You should have received a copy of the GNU General Public License along
29  * with this program; if not, see <http://www.gnu.org/licenses/>
30  *
31  * Additional note on redistribution: The copyright and license notices above
32  * must be maintained in each individual source file that is a derivative work
33  * of this source file; otherwise redistribution is prohibited.
34  */
35 
36 // ****************
37 
38 #include "openpilot.h"
39 #include "GPS.h"
40 
41 #include "gpsposition.h"
42 #include "airspeedactual.h"
43 #include "homelocation.h"
44 #include "gpstime.h"
45 #include "gpssatellites.h"
46 #include "gpsvelocity.h"
47 #include "modulesettings.h"
48 #include "pios_thread.h"
49 #include "pios_modules.h"
50 
51 #include "NMEA.h"
52 #include "UBX.h"
53 #include "ubx_cfg.h"
54 
55 #include <pios_hal.h>
56 
57 #if defined(PIOS_GPS_PROVIDES_AIRSPEED)
58 #include "gps_airspeed.h"
59 #endif
60 
61 // ****************
62 // Private functions
63 
64 static void gpsTask(void *parameters);
65 static void updateSettings();
66 
67 // ****************
68 // Private constants
69 
70 #define GPS_TIMEOUT_MS 750
71 #define GPS_COM_TIMEOUT_MS 100
72 #define STACK_SIZE_BYTES 850
73 
74 #define TASK_PRIORITY PIOS_THREAD_PRIO_LOW
75 
76 // ****************
77 // Private variables
78 
79 static uintptr_t gpsPort;
80 static bool module_enabled = false;
81 
82 static struct pios_thread *gpsTaskHandle;
83 
84 static char* gps_rx_buffer;
85 
86 static struct GPS_RX_STATS gpsRxStats;
87 
88 // ****************
95 int32_t GPSStart(void)
96 {
97  if (module_enabled) {
98  if (gpsPort) {
99  // Start gps task
101  TaskMonitorAdd(TASKINFO_RUNNING_GPS, gpsTaskHandle);
102  return 0;
103  }
104 
105  AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_ERROR);
106  }
107  return -1;
108 }
109 
115 int32_t GPSInitialize(void)
116 {
118  uint8_t gpsProtocol;
119 
120 #ifdef MODULE_GPS_BUILTIN
121  module_enabled = true;
122 #else
124 #endif
125 
126  // These things are only conditional on small F1 targets.
127  // Expected to be always present otherwise.
128  if (GPSPositionInitialize() == -1 \
129  || GPSVelocityInitialize() == -1) {
130  module_enabled = false;
131  return -1;
132  }
133  if (GPSTimeInitialize() == -1 \
134  || GPSSatellitesInitialize() == -1 \
135  || HomeLocationInitialize() == -1 \
136  || UBloxInfoInitialize() == -1) {
137  module_enabled = false;
138  return -1;
139  }
140 #if defined(PIOS_GPS_PROVIDES_AIRSPEED)
141  if (AirspeedActualInitialize() == -1) {
142  module_enabled = false;
143  return -1;
144  }
145 #endif
146  updateSettings();
147 
148  if (gpsPort && module_enabled) {
149  ModuleSettingsGPSDataProtocolGet(&gpsProtocol);
150  switch (gpsProtocol) {
151  case MODULESETTINGS_GPSDATAPROTOCOL_NMEA:
153  if (gps_rx_buffer == NULL) {
154  AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_ERROR);
155  return -1;
156  }
157  break;
158  case MODULESETTINGS_GPSDATAPROTOCOL_UBX:
159  gps_rx_buffer = PIOS_malloc(sizeof(struct UBXPacket));
160  if (gps_rx_buffer == NULL) {
161  AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_ERROR);
162  return -1;
163  }
164  break;
165  default:
166  gps_rx_buffer = NULL;
167  }
169 
170  return 0;
171  }
172 
173  return -1;
174 }
175 
177 
178 // ****************
179 
180 static void gpsConfigure(uint8_t gpsProtocol)
181 {
182  ModuleSettingsGPSAutoConfigureOptions gpsAutoConfigure;
183  ModuleSettingsGPSAutoConfigureGet(&gpsAutoConfigure);
184 
185  if (gpsAutoConfigure != MODULESETTINGS_GPSAUTOCONFIGURE_TRUE) {
186  return;
187  }
188 
189  switch (gpsProtocol) {
190 #if defined(PIOS_INCLUDE_GPS_UBX_PARSER)
191  case MODULESETTINGS_GPSDATAPROTOCOL_UBX:
192  {
193  // Runs through a number of possible GPS baud rates to
194  // configure the ublox baud rate. This uses a NMEA string
195  // so could work for either UBX or NMEA actually. This is
196  // somewhat redundant with updateSettings below, but that
197  // is only called on startup and is not an issue.
198 
199  ModuleSettingsGPSSpeedOptions baud_rate;
200  ModuleSettingsGPSConstellationOptions constellation;
201  ModuleSettingsGPSSBASConstellationOptions sbas_const;
202  ModuleSettingsGPSDynamicsModeOptions dyn_mode;
203 
204  ModuleSettingsGPSSpeedGet(&baud_rate);
205  ModuleSettingsGPSConstellationGet(&constellation);
206  ModuleSettingsGPSSBASConstellationGet(&sbas_const);
207  ModuleSettingsGPSDynamicsModeGet(&dyn_mode);
208 
209  ubx_cfg_set_baudrate(gpsPort, baud_rate);
210 
211  PIOS_Thread_Sleep(1000);
212 
214  constellation, sbas_const, dyn_mode);
215  }
216  break;
217 #endif
218  default:
219  break;
220  }
221 }
222 
227 static void gpsTask(void *parameters)
228 {
229  GPSPositionData gpsposition;
230 
231  uint32_t timeOfLastUpdateMs = 0;
232  uint32_t timeOfConfigAttemptMs = 0;
233 
234  uint8_t gpsProtocol;
235 
236 #ifdef PIOS_GPS_PROVIDES_AIRSPEED
237  gps_airspeed_initialize();
238 #endif
239 
240  GPSPositionGet(&gpsposition);
241 
242  // Wait for power to stabilize before talking to external devices
243  PIOS_Thread_Sleep(1000);
244 
245  // Loop forever
246  while (1) {
247  uint32_t xDelay = GPS_COM_TIMEOUT_MS;
248 
249  uint32_t loopTimeMs = PIOS_Thread_Systime();
250 
251  // XXX TODO: also on modulesettings change..
252  if (!timeOfConfigAttemptMs) {
253  ModuleSettingsGPSDataProtocolGet(&gpsProtocol);
254 
255  gpsConfigure(gpsProtocol);
256  timeOfConfigAttemptMs = PIOS_Thread_Systime();
257 
258  continue;
259  }
260 
261  uint8_t c;
262 
263  // This blocks the task until there is something on the buffer
264  while (PIOS_COM_ReceiveBuffer(gpsPort, &c, 1, xDelay) > 0)
265  {
266  int res;
267  switch (gpsProtocol) {
268 #if defined(PIOS_INCLUDE_GPS_NMEA_PARSER)
269  case MODULESETTINGS_GPSDATAPROTOCOL_NMEA:
270  res = parse_nmea_stream (c,gps_rx_buffer, &gpsposition, &gpsRxStats);
271  break;
272 #endif
273 #if defined(PIOS_INCLUDE_GPS_UBX_PARSER)
274  case MODULESETTINGS_GPSDATAPROTOCOL_UBX:
275  res = parse_ubx_stream (c,gps_rx_buffer, &gpsposition, &gpsRxStats);
276  break;
277 #endif
278  default:
279  res = NO_PARSER; // this should not happen
280  break;
281  }
282 
283  if (res == PARSER_COMPLETE) {
284  timeOfLastUpdateMs = loopTimeMs;
285  }
286 
287  xDelay = 0; // For now on, don't block / wait,
288  // but consume what we can from the fifo
289  }
290 
291  // Check for GPS timeout
292  if ((loopTimeMs - timeOfLastUpdateMs) >= GPS_TIMEOUT_MS) {
293  // we have not received any valid GPS sentences for a while.
294  // either the GPS is not plugged in or a hardware problem or the GPS has locked up.
295  uint8_t status = GPSPOSITION_STATUS_NOGPS;
296  GPSPositionStatusSet(&status);
297  AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_ERROR);
298  /* Don't reinitialize too often. */
299  if ((loopTimeMs - timeOfConfigAttemptMs) >= GPS_TIMEOUT_MS) {
300  timeOfConfigAttemptMs = 0; // reinit next loop
301  }
302  } else {
303  // we appear to be receiving GPS sentences OK, we've had an update
304  //criteria for GPS-OK taken from this post
305  if (gpsposition.PDOP < 3.5f &&
306  gpsposition.Satellites >= 7 &&
307  (gpsposition.Status == GPSPOSITION_STATUS_FIX3D ||
308  gpsposition.Status == GPSPOSITION_STATUS_DIFF3D)) {
309  AlarmsClear(SYSTEMALARMS_ALARM_GPS);
310  } else if (gpsposition.Status == GPSPOSITION_STATUS_FIX3D ||
311  gpsposition.Status == GPSPOSITION_STATUS_DIFF3D)
312  AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_WARNING);
313  else
314  AlarmsSet(SYSTEMALARMS_ALARM_GPS, SYSTEMALARMS_ALARM_CRITICAL);
315  }
316 
317  }
318 }
319 
320 
324 static void updateSettings()
325 {
326  if (gpsPort) {
327 
328  // Retrieve settings
329  uint8_t speed;
330  ModuleSettingsGPSSpeedGet(&speed);
331 
332  // Set port speed
334  }
335 }
336 
uint16_t speed
Definition: msp_messages.h:101
uint32_t PIOS_Thread_Systime(void)
Definition: pios_thread.c:212
static char * gps_rx_buffer
Definition: GPS.c:84
static bool module_enabled
Definition: GPS.c:80
#define GPS_COM_TIMEOUT_MS
Definition: GPS.c:71
static uintptr_t gpsPort
Definition: GPS.c:79
void ubx_cfg_send_configuration(uintptr_t gps_port, char *buffer, ModuleSettingsGPSConstellationOptions constellation, ModuleSettingsGPSSBASConstellationOptions sbas_const, ModuleSettingsGPSDynamicsModeOptions dyn_mode)
Definition: ubx_cfg.c:479
#define GPS_TIMEOUT_MS
Definition: GPS.c:70
bool PIOS_Modules_IsEnabled(enum pios_modules module)
Definition: pios_modules.c:41
static void updateSettings()
Definition: GPS.c:324
void * PIOS_malloc(size_t size)
Definition: pios_heap.c:125
int32_t AlarmsSet(SystemAlarmsAlarmElem alarm, SystemAlarmsAlarmOptions severity)
Definition: alarms.c:97
MODULE_INITCALL(GPSInitialize, GPSStart)
void PIOS_HAL_ConfigureSerialSpeed(uintptr_t com_id, HwSharedSpeedBpsOptions speed)
Definition: pios_hal.c:1115
int16_t status
Definition: main.c:61
int32_t GPSStart(void)
Definition: GPS.c:95
#define STACK_SIZE_BYTES
Definition: GPS.c:72
Airspeed module, reads temperature and pressure from BMP085.
uint16_t PIOS_COM_ReceiveBuffer(uintptr_t com_id, uint8_t *buf, uint16_t buf_len, uint32_t timeout_ms)
struct pios_thread * PIOS_Thread_Create(void(*fp)(void *), const char *namep, size_t stack_bytes, void *argp, enum pios_thread_prio_e prio)
Definition: pios_thread.c:89
static struct pios_thread * gpsTaskHandle
Definition: GPS.c:82
Include file of the GPS module.
void ubx_cfg_set_baudrate(uintptr_t gps_port, ModuleSettingsGPSSpeedOptions baud_rate)
Make sure the GPS is set to the same baud.
Definition: ubx_cfg.c:523
#define TASK_PRIORITY
Definition: GPS.c:74
#define PARSER_COMPLETE
Definition: GPS.h:42
int32_t TaskMonitorAdd(TaskInfoRunningElem task, struct pios_thread *threadp)
Definition: taskmonitor.c:67
int parse_ubx_stream(uint8_t, char *, GPSPositionData *, struct GPS_RX_STATS *)
void PIOS_Thread_Sleep(uint32_t time_ms)
Definition: pios_thread.c:229
static void gpsTask(void *parameters)
Definition: GPS.c:227
Include file to process NMEA data.
Include file for UBX configuration.
int parse_nmea_stream(uint8_t, char *, GPSPositionData *, struct GPS_RX_STATS *)
Includes PiOS and core architecture components.
#define NO_PARSER
Definition: GPS.h:38
int32_t AlarmsClear(SystemAlarmsAlarmElem alarm)
Definition: alarms.c:171
Include file for UBX processing.
static struct GPS_RX_STATS gpsRxStats
Definition: GPS.c:86
static void gpsConfigure(uint8_t gpsProtocol)
Definition: GPS.c:180
int32_t GPSInitialize(void)
Definition: GPS.c:115
#define NMEA_MAX_PACKET_LENGTH
Definition: NMEA.h:37
#define PIOS_Assert(test)
Definition: pios_debug.h:52
#define PIOS_COM_GPS
Definition: pios_board.h:113
Definition: UBX.h:222