2 ******************************************************************************
3 * @addtogroup OpenPilotModules OpenPilot Modules
5 * @addtogroup GPSModule GPS Module
6 * @brief Support code for UBX AutoConfig
9 * @file ubx_autoconfig.c
10 * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016.
11 * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2014.
12 * @brief Support code for UBX AutoConfig
13 * @see The GNU Public License (GPL) Version 3
15 *****************************************************************************/
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 3 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful, but
23 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
24 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #include <openpilot.h>
32 #include "hwsettings.h"
33 #include "gpssettings.h"
35 #include "inc/ubx_autoconfig.h"
38 // private type definitions
41 INIT_STEP_DISABLED
= 0,
43 INIT_STEP_SEND_MON_VER
,
44 INIT_STEP_WAIT_MON_VER_ACK
,
46 INIT_STEP_REVO_9600_BAUD
,
49 INIT_STEP_ENABLE_SENTENCES
,
50 INIT_STEP_ENABLE_SENTENCES_WAIT_ACK
,
52 INIT_STEP_CONFIGURE_WAIT_ACK
,
54 INIT_STEP_SAVE_WAIT_ACK
,
62 initSteps_t currentStep
; // Current configuration "fsm" status
63 initSteps_t currentStepSave
; // Current configuration "fsm" status
64 uint32_t lastStepTimestampRaw
; // timestamp of last operation
65 uint32_t lastConnectedRaw
; // timestamp of last time gps was connected
69 UBXSentPacket_t working_packet
; // outbound "buffer"
70 // bufferPaddingForPiosBugAt2400Baud must exist for baud rate change to work at 2400 or 4800
71 // failure mode otherwise:
72 // - send message with baud rate change
73 // - wait 1 second (even at 2400, the baud rate change command
74 // - should clear even an initially full 31 byte PIOS buffer much more quickly)
75 // - change Revo port baud rate
76 // sometimes fails (much worse for lowest baud rates)
77 // FIXME: remove this and retest when someone has time
78 uint8_t bufferPaddingForPiosBugAt2400Baud
[2]; // must be at least 2 for 2400 to work, probably 1 for 4800 and 0 for 9600+
79 } __attribute__((packed
));
80 GPSSettingsData gpsSettings
;
81 } __attribute__((packed
));
82 } __attribute__((packed
));
83 volatile ubx_autoconfig_settings_t currentSettings
;
84 int8_t lastConfigSent
; // index of last configuration string sent
85 struct UBX_ACK_ACK requiredAck
; // Class and id of the message we are waiting for an ACK from GPS
89 ubx_cfg_msg_t msg_config_ubx6
[] = {
90 // messages to disable
91 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_CLOCK
, .rate
= 0 },
92 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_POSECEF
, .rate
= 0 },
93 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_SBAS
, .rate
= 0 },
94 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_TIMEGPS
, .rate
= 0 },
95 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_VELECEF
, .rate
= 0 },
97 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_HW
, .rate
= 0 },
98 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_HW2
, .rate
= 0 },
99 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_IO
, .rate
= 0 },
100 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_MSGPP
, .rate
= 0 },
101 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_RXBUFF
, .rate
= 0 },
102 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_RXR
, .rate
= 0 },
103 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_TXBUF
, .rate
= 0 },
105 { .msgClass
= UBX_CLASS_RXM
, .msgID
= UBX_ID_RXM_SVSI
, .rate
= 0 },
108 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_POSLLH
, .rate
= 1 },
109 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_DOP
, .rate
= 1 },
110 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_SOL
, .rate
= 1 },
111 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_STATUS
, .rate
= 1 },
112 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_VELNED
, .rate
= 1 },
113 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_TIMEUTC
, .rate
= 1 },
114 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_SVINFO
, .rate
= 10 },
117 ubx_cfg_msg_t msg_config_ubx7
[] = {
118 // messages to disable
119 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_AOPSTATUS
, .rate
= 0 },
120 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_CLOCK
, .rate
= 0 },
121 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_DGPS
, .rate
= 0 },
122 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_POSECEF
, .rate
= 0 },
123 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_SBAS
, .rate
= 0 },
124 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_TIMEGPS
, .rate
= 0 },
125 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_VELECEF
, .rate
= 0 },
126 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_SOL
, .rate
= 0 },
127 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_STATUS
, .rate
= 0 },
128 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_VELNED
, .rate
= 0 },
129 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_TIMEUTC
, .rate
= 0 },
130 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_POSLLH
, .rate
= 0 },
132 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_HW
, .rate
= 0 },
133 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_HW2
, .rate
= 0 },
134 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_IO
, .rate
= 0 },
135 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_MSGPP
, .rate
= 0 },
136 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_RXBUFF
, .rate
= 0 },
137 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_RXR
, .rate
= 0 },
138 { .msgClass
= UBX_CLASS_MON
, .msgID
= UBX_ID_MON_TXBUF
, .rate
= 0 },
140 { .msgClass
= UBX_CLASS_RXM
, .msgID
= UBX_ID_RXM_SVSI
, .rate
= 0 },
143 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_PVT
, .rate
= 1 },
144 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_DOP
, .rate
= 1 },
145 { .msgClass
= UBX_CLASS_NAV
, .msgID
= UBX_ID_NAV_SVINFO
, .rate
= 10 },
150 #define LAST_CONFIG_SENT_START (-1)
151 #define LAST_CONFIG_SENT_COMPLETED (-2)
152 // always reset the stored GPS configuration, even when doing autoconfig.nostore
153 // that is required to do a 100% correct configuration
154 // but is unexpected because it changes the stored configuration when doing autoconfig.nostore
155 // note that a reset is always done with autoconfig.store
156 // #define ALWAYS_RESET
158 // we can enable this when we know how to make the Flight Controller save an object to permanent storage
159 // also see comment about simple edit in gpssettings.xml
160 #define AUTOBAUD_CONFIGURE_STORE_AND_DISABLE
161 // Alessio Morale May 20 3:16 AM
162 // @Cliff you should update the ObjectPersistence uavo passing the object id and the desired operation.
166 // enable the autoconfiguration system
167 static volatile bool enabled
= false;
168 static volatile bool current_step_touched
= false;
169 // both the pointer and what it points to are volatile. Yuk.
170 static volatile status_t
*volatile status
= 0;
171 static uint8_t hwsettings_baud
;
172 static uint8_t baud_to_try_index
= 255;
176 static void append_checksum(UBXSentPacket_t
*packet
)
181 uint16_t len
= packet
->message
.header
.len
+ sizeof(UBXSentHeader_t
);
183 for (i
= 2; i
< len
; i
++) {
184 ck_a
+= packet
->buffer
[i
];
188 packet
->buffer
[len
] = ck_a
;
189 packet
->buffer
[len
+ 1] = ck_b
;
194 * prepare a packet to be sent, fill the header and appends the checksum.
195 * return the total packet lenght comprising header and checksum
197 static uint16_t prepare_packet(UBXSentPacket_t
*packet
, uint8_t classID
, uint8_t messageID
, uint16_t len
)
199 memset((uint8_t *)status
->working_packet
.buffer
+ len
+ sizeof(UBXSentHeader_t
) + 2, 0, sizeof(status
->bufferPaddingForPiosBugAt2400Baud
));
200 packet
->message
.header
.prolog
[0] = UBX_SYNC1
;
201 packet
->message
.header
.prolog
[1] = UBX_SYNC2
;
202 packet
->message
.header
.class = classID
;
203 packet
->message
.header
.id
= messageID
;
204 packet
->message
.header
.len
= len
;
205 append_checksum(packet
);
207 status
->requiredAck
.clsID
= classID
;
208 status
->requiredAck
.msgID
= messageID
;
210 return len
+ sizeof(UBXSentHeader_t
) + 2 + sizeof(status
->bufferPaddingForPiosBugAt2400Baud
); // payload + header + checksum + extra bytes
214 static void build_request(UBXSentPacket_t
*packet
, uint8_t classID
, uint8_t messageID
, uint16_t *bytes_to_send
)
216 *bytes_to_send
= prepare_packet(packet
, classID
, messageID
, 0);
220 static void set_current_step_if_untouched(initSteps_t new_steps
)
222 // assume this one byte initSteps_t is atomic
223 // take care of some concurrency issues
225 if (!current_step_touched
) {
226 status
->currentStep
= new_steps
;
228 if (current_step_touched
) {
229 status
->currentStep
= status
->currentStepSave
;
234 void gps_ubx_reset_sensor_type()
236 static uint8_t mutex
; // = 0
239 // what happens if two tasks / threads try to do an XyzSet() at the same time?
240 if (__sync_fetch_and_add(&mutex
, 1) == 0) {
242 baud_to_try_index
-= 1; // undo postincrement and start with the one that was most recently successful
243 ubxSensorType
= GPSPOSITIONSENSOR_SENSORTYPE_UNKNOWN
;
244 GPSPositionSensorSensorTypeSet(&ubxSensorType
);
245 // make the sensor type / autobaud code time out immediately to send the request immediately
247 status
->lastStepTimestampRaw
+= 0x8000000UL
;
254 static void config_reset(uint16_t *bytes_to_send
)
256 memset((uint8_t *)status
->working_packet
.buffer
, 0, sizeof(UBXSentHeader_t
) + sizeof(ubx_cfg_cfg_t
));
257 // mask LSB=ioPort|msgConf|infMsg|navConf|rxmConf|||||rinvConf|antConf|....|= MSB
258 // ioPort=1, msgConf=2, infMsg=4, navConf=8, tpConf=0x10, sfdrConf=0x100, rinvConf=0x200, antConf=0x400
259 // first: reset (permanent settings to default) all but rinv = e.g. owner name
260 status
->working_packet
.message
.payload
.cfg_cfg
.clearMask
= UBX_CFG_CFG_OP_RESET_SETTINGS
;
261 // then: don't store any current settings to permanent
262 status
->working_packet
.message
.payload
.cfg_cfg
.saveMask
= UBX_CFG_CFG_SETTINGS_NONE
;
263 // lastly: load (immediately start to use) all but rinv = e.g. owner name
264 status
->working_packet
.message
.payload
.cfg_cfg
.loadMask
= UBX_CFG_CFG_OP_RESET_SETTINGS
;
266 status
->working_packet
.message
.payload
.cfg_cfg
.deviceMask
= UBX_CFG_CFG_DEVICE_ALL
;
268 *bytes_to_send
= prepare_packet((UBXSentPacket_t
*)&status
->working_packet
, UBX_CLASS_CFG
, UBX_ID_CFG_CFG
, sizeof(ubx_cfg_cfg_t
));
272 // set the GPS baud rate to the user specified baud rate
273 // because we may have started up with 9600 baud (for a GPS with no permanent settings)
274 static void config_gps_baud(uint16_t *bytes_to_send
)
276 memset((uint8_t *)status
->working_packet
.buffer
, 0, sizeof(UBXSentHeader_t
) + sizeof(ubx_cfg_prt_t
));
277 status
->working_packet
.message
.payload
.cfg_prt
.mode
= UBX_CFG_PRT_MODE_DEFAULT
; // 8databits, 1stopbit, noparity, and non-zero reserved
278 status
->working_packet
.message
.payload
.cfg_prt
.portID
= 1; // 1 = UART1, 2 = UART2
279 // for protocol masks, bit 0 is UBX enable, bit 1 is NMEA enable
280 status
->working_packet
.message
.payload
.cfg_prt
.inProtoMask
= 1; // 1 = UBX only (bit 0)
281 // disable current UBX messages for low baud rates
282 status
->working_packet
.message
.payload
.cfg_prt
.outProtoMask
= 1;
283 // Ask GPS to change it's speed
284 status
->working_packet
.message
.payload
.cfg_prt
.baudRate
= hwsettings_gpsspeed_enum_to_baud(hwsettings_baud
);
285 *bytes_to_send
= prepare_packet((UBXSentPacket_t
*)&status
->working_packet
, UBX_CLASS_CFG
, UBX_ID_CFG_PRT
, sizeof(ubx_cfg_prt_t
));
289 static void config_rate(uint16_t *bytes_to_send
)
291 memset((uint8_t *)status
->working_packet
.buffer
, 0, sizeof(UBXSentHeader_t
) + sizeof(ubx_cfg_rate_t
));
292 // if rate is less than 1 uses the highest rate for current hardware
293 uint16_t rate
= status
->currentSettings
.navRate
> 0 ? status
->currentSettings
.navRate
: 99;
294 if (ubxHwVersion
< UBX_HW_VERSION_7
&& rate
> UBX_MAX_RATE
) {
296 } else if (ubxHwVersion
< UBX_HW_VERSION_8
&& rate
> UBX_MAX_RATE_VER7
) {
297 rate
= UBX_MAX_RATE_VER7
;
298 } else if (ubxHwVersion
>= UBX_HW_VERSION_8
&& rate
> UBX_MAX_RATE_VER8
) {
299 rate
= UBX_MAX_RATE_VER8
;
301 uint16_t period
= 1000 / rate
;
302 status
->working_packet
.message
.payload
.cfg_rate
.measRate
= period
;
303 status
->working_packet
.message
.payload
.cfg_rate
.navRate
= 1; // must be set to 1
304 status
->working_packet
.message
.payload
.cfg_rate
.timeRef
= 1; // 0 = UTC Time, 1 = GPS Time
306 *bytes_to_send
= prepare_packet((UBXSentPacket_t
*)&status
->working_packet
, UBX_CLASS_CFG
, UBX_ID_CFG_RATE
, sizeof(ubx_cfg_rate_t
));
310 static void config_nav(uint16_t *bytes_to_send
)
312 memset((uint8_t *)status
->working_packet
.buffer
, 0, sizeof(UBXSentHeader_t
) + sizeof(ubx_cfg_nav5_t
));
313 status
->working_packet
.message
.payload
.cfg_nav5
.dynModel
= status
->currentSettings
.dynamicModel
;
314 status
->working_packet
.message
.payload
.cfg_nav5
.fixMode
= UBX_CFG_NAV5_FIXMODE_3D_ONLY
;
315 // mask LSB=dyn|minEl|posFixMode|drLim|posMask|statisticHoldMask|dgpsMask|......|reservedBit0 = MSB
316 status
->working_packet
.message
.payload
.cfg_nav5
.mask
= UBX_CFG_NAV5_DYNMODEL
+ UBX_CFG_NAV5_FIXMODE
;
318 *bytes_to_send
= prepare_packet((UBXSentPacket_t
*)&status
->working_packet
, UBX_CLASS_CFG
, UBX_ID_CFG_NAV5
, sizeof(ubx_cfg_nav5_t
));
321 static void config_navx(uint16_t *bytes_to_send
)
323 memset((uint8_t *)status
->working_packet
.buffer
, 0, sizeof(UBXSentHeader_t
) + sizeof(ubx_cfg_navx5_t
));
324 status
->working_packet
.message
.payload
.cfg_navx5
.useAOP
= status
->currentSettings
.AssistNowAutonomous
;
325 status
->working_packet
.message
.payload
.cfg_navx5
.mask1
= UBX_CFG_NAVX5_AOP
;
327 *bytes_to_send
= prepare_packet((UBXSentPacket_t
*)&status
->working_packet
, UBX_CLASS_CFG
, UBX_ID_CFG_NAVX5
, sizeof(ubx_cfg_navx5_t
));
331 static void config_sbas(uint16_t *bytes_to_send
)
333 memset((uint8_t *)status
->working_packet
.buffer
, 0, sizeof(UBXSentHeader_t
) + sizeof(ubx_cfg_sbas_t
));
334 status
->working_packet
.message
.payload
.cfg_sbas
.maxSBAS
=
335 status
->currentSettings
.SBASChannelsUsed
< 4 ? status
->currentSettings
.SBASChannelsUsed
: 3;
336 status
->working_packet
.message
.payload
.cfg_sbas
.usage
=
337 (status
->currentSettings
.SBASCorrection
? UBX_CFG_SBAS_USAGE_DIFFCORR
: 0) |
338 (status
->currentSettings
.SBASIntegrity
? UBX_CFG_SBAS_USAGE_INTEGRITY
: 0) |
339 (status
->currentSettings
.SBASRanging
? UBX_CFG_SBAS_USAGE_RANGE
: 0);
340 // If sbas is used for anything then set mode as enabled
341 status
->working_packet
.message
.payload
.cfg_sbas
.mode
=
342 status
->working_packet
.message
.payload
.cfg_sbas
.usage
!= 0 ? UBX_CFG_SBAS_MODE_ENABLED
: 0;
343 status
->working_packet
.message
.payload
.cfg_sbas
.scanmode1
=
344 status
->currentSettings
.SBASSats
== UBX_SBAS_SATS_WAAS
? UBX_CFG_SBAS_SCANMODE1_WAAS
:
345 status
->currentSettings
.SBASSats
== UBX_SBAS_SATS_EGNOS
? UBX_CFG_SBAS_SCANMODE1_EGNOS
:
346 status
->currentSettings
.SBASSats
== UBX_SBAS_SATS_MSAS
? UBX_CFG_SBAS_SCANMODE1_MSAS
:
347 status
->currentSettings
.SBASSats
== UBX_SBAS_SATS_GAGAN
? UBX_CFG_SBAS_SCANMODE1_GAGAN
:
348 status
->currentSettings
.SBASSats
== UBX_SBAS_SATS_SDCM
? UBX_CFG_SBAS_SCANMODE1_SDCM
: UBX_SBAS_SATS_AUTOSCAN
;
349 status
->working_packet
.message
.payload
.cfg_sbas
.scanmode2
=
350 UBX_CFG_SBAS_SCANMODE2
;
352 *bytes_to_send
= prepare_packet((UBXSentPacket_t
*)&status
->working_packet
, UBX_CLASS_CFG
, UBX_ID_CFG_SBAS
, sizeof(ubx_cfg_sbas_t
));
356 static void config_gnss(uint16_t *bytes_to_send
)
358 memset((uint8_t *)status
->working_packet
.buffer
, 0, sizeof(UBXSentHeader_t
) + sizeof(ubx_cfg_gnss_t
));
359 status
->working_packet
.message
.payload
.cfg_gnss
.numConfigBlocks
= UBX_GNSS_ID_MAX
;
360 status
->working_packet
.message
.payload
.cfg_gnss
.numTrkChHw
= (ubxHwVersion
> UBX_HW_VERSION_7
) ? UBX_CFG_GNSS_NUMCH_VER8
: UBX_CFG_GNSS_NUMCH_VER7
;
361 status
->working_packet
.message
.payload
.cfg_gnss
.numTrkChUse
= status
->working_packet
.message
.payload
.cfg_gnss
.numTrkChHw
;
363 for (int32_t i
= 0; i
< UBX_GNSS_ID_MAX
; i
++) {
364 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].gnssId
= i
;
366 case UBX_GNSS_ID_GPS
:
367 if (status
->currentSettings
.enableGPS
) {
368 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].flags
= UBX_CFG_GNSS_FLAGS_ENABLED
| UBX_CFG_GNSS_FLAGS_GPS_L1CA
;
369 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].maxTrkCh
= 16;
370 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].resTrkCh
= 8;
373 case UBX_GNSS_ID_QZSS
:
374 if (status
->currentSettings
.enableGPS
) {
375 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].flags
= UBX_CFG_GNSS_FLAGS_ENABLED
| UBX_CFG_GNSS_FLAGS_QZSS_L1CA
;
376 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].maxTrkCh
= 3;
377 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].resTrkCh
= 0;
380 case UBX_GNSS_ID_SBAS
:
381 if (status
->currentSettings
.SBASCorrection
|| status
->currentSettings
.SBASIntegrity
|| status
->currentSettings
.SBASRanging
) {
382 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].flags
= UBX_CFG_GNSS_FLAGS_ENABLED
| UBX_CFG_GNSS_FLAGS_SBAS_L1CA
;
383 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].maxTrkCh
= status
->currentSettings
.SBASChannelsUsed
< 4 ? status
->currentSettings
.SBASChannelsUsed
: 3;
384 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].resTrkCh
= 1;
387 case UBX_GNSS_ID_GLONASS
:
388 if (status
->currentSettings
.enableGLONASS
) {
389 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].flags
= UBX_CFG_GNSS_FLAGS_ENABLED
| UBX_CFG_GNSS_FLAGS_GLONASS_L1OF
;
390 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].maxTrkCh
= 14;
391 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].resTrkCh
= 8;
394 case UBX_GNSS_ID_BEIDOU
:
395 if (status
->currentSettings
.enableBeiDou
) {
396 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].flags
= UBX_CFG_GNSS_FLAGS_ENABLED
| UBX_CFG_GNSS_FLAGS_BEIDOU_B1I
;
397 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].maxTrkCh
= 14;
398 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].resTrkCh
= 8;
401 case UBX_GNSS_ID_GALILEO
:
402 if (status
->currentSettings
.enableGalileo
) {
403 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].flags
= UBX_CFG_GNSS_FLAGS_ENABLED
| UBX_CFG_GNSS_FLAGS_GALILEO_E1
;
404 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].maxTrkCh
= 10;
405 status
->working_packet
.message
.payload
.cfg_gnss
.cfgBlocks
[i
].resTrkCh
= 8;
413 *bytes_to_send
= prepare_packet((UBXSentPacket_t
*)&status
->working_packet
, UBX_CLASS_CFG
, UBX_ID_CFG_GNSS
, sizeof(ubx_cfg_gnss_t
));
417 static void config_save(uint16_t *bytes_to_send
)
419 memset((uint8_t *)status
->working_packet
.buffer
, 0, sizeof(UBXSentHeader_t
) + sizeof(ubx_cfg_cfg_t
));
420 // mask LSB=ioPort|msgConf|infMsg|navConf|rxmConf|||||rinvConf|antConf|....|= MSB
421 // ioPort=1, msgConf=2, infMsg=4, navConf=8, tpConf=0x10, sfdrConf=0x100, rinvConf=0x200, antConf=0x400
422 status
->working_packet
.message
.payload
.cfg_cfg
.saveMask
= UBX_CFG_CFG_OP_STORE_SETTINGS
; // a list of settings we just set
423 status
->working_packet
.message
.payload
.cfg_cfg
.clearMask
= UBX_CFG_CFG_OP_CLEAR_SETTINGS
; // everything else gets factory default
424 status
->working_packet
.message
.payload
.cfg_cfg
.deviceMask
= UBX_CFG_CFG_DEVICE_ALL
;
426 *bytes_to_send
= prepare_packet((UBXSentPacket_t
*)&status
->working_packet
, UBX_CLASS_CFG
, UBX_ID_CFG_CFG
, sizeof(ubx_cfg_cfg_t
));
429 static void configure(uint16_t *bytes_to_send
)
431 switch (status
->lastConfigSent
) {
432 case LAST_CONFIG_SENT_START
:
433 // increase message rates to 5 fixes per second
434 config_rate(bytes_to_send
);
437 case LAST_CONFIG_SENT_START
+ 1:
438 config_nav(bytes_to_send
);
441 case LAST_CONFIG_SENT_START
+ 2:
442 if (ubxHwVersion
> UBX_HW_VERSION_5
) {
443 config_navx(bytes_to_send
);
446 // Skip and fall through to next step
447 status
->lastConfigSent
++;
450 case LAST_CONFIG_SENT_START
+ 3:
451 if (status
->currentSettings
.enableGLONASS
|| status
->currentSettings
.enableGPS
) {
452 config_gnss(bytes_to_send
);
455 // Skip and fall through to next step
456 status
->lastConfigSent
++;
458 // in the else case we must fall through because we must send something each time because successful send is tested externally
460 case LAST_CONFIG_SENT_START
+ 4:
461 config_sbas(bytes_to_send
);
465 status
->lastConfigSent
= LAST_CONFIG_SENT_COMPLETED
;
471 static void enable_sentences(__attribute__((unused
)) uint16_t *bytes_to_send
)
473 int8_t msg
= status
->lastConfigSent
+ 1;
474 uint8_t msg_count
= (ubxHwVersion
>= UBX_HW_VERSION_7
) ?
475 NELEMENTS(msg_config_ubx7
) : NELEMENTS(msg_config_ubx6
);
476 ubx_cfg_msg_t
*msg_config
= (ubxHwVersion
>= UBX_HW_VERSION_7
) ?
477 &msg_config_ubx7
[0] : &msg_config_ubx6
[0];
479 if (msg
>= 0 && msg
< msg_count
) {
480 status
->working_packet
.message
.payload
.cfg_msg
= msg_config
[msg
];
481 *bytes_to_send
= prepare_packet((UBXSentPacket_t
*)&status
->working_packet
, UBX_CLASS_CFG
, UBX_ID_CFG_MSG
, sizeof(ubx_cfg_msg_t
));
483 status
->lastConfigSent
= LAST_CONFIG_SENT_COMPLETED
;
488 #if defined(AUTOBAUD_CONFIGURE_STORE_AND_DISABLE)
489 // permanently store our version of GPSSettings.UbxAutoConfig
490 // we use this to disable after AbConfigStoreAndDisable is complete
491 static void setGpsSettings()
493 // trying to do this as perfectly as possible we must realize that they may have pressed Send on some fields
494 // and so those fields are not stored permanently
495 // if we write the memory copy to flash, we will have made those permanent
497 // we could save off the uavo memory copy to a local buffer with a standard GPSSettingsGet()
498 // load from flash to uavo memory with a UAVObjLoad()
499 // update our one setting in uavo memory with a standard GPSSettingsUbxAutoConfigSet()
500 // save from uavo memory to flash with a UAVObjSave()
501 // modify our saved off copy to have our new setting in it too
502 // and finally copy the local buffer back out to uavo memory
504 // that would do it as correctly as possible, but it doesn't work
505 // so we do it the way autotune.c does it
508 // get the "in memory" version to a local buffer
509 GPSSettingsGet((void *)&status
->gpsSettings
);
510 // load the permanent version into memory
511 UAVObjLoad(GPSSettingsHandle(), 0);
513 // change the in memory version of the field we want to change
514 GPSSettingsUbxAutoConfigSet((GPSSettingsUbxAutoConfigOptions
*)&status
->currentSettings
.UbxAutoConfig
);
515 // save the in memory version to permanent
516 UAVObjSave(GPSSettingsHandle(), 0);
518 // copy the setting into the struct we will use to Set()
519 status
->gpsSettings
.UbxAutoConfig
= status
->currentSettings
.UbxAutoConfig
;
520 // try casting it correctly and it says:
521 // expected 'struct GPSSettingsData *' but argument is of type 'struct GPSSettingsData *'
522 // probably a volatile or align issue
523 GPSSettingsSet((void *)&status
->gpsSettings
); // set the "in memory" version back into use
526 #endif /* if defined(AUTOBAUD_CONFIGURE_STORE_AND_DISABLE) */
529 // 9600 baud and lower are not usable, and are best left at factory default
530 // if the user selects 9600
531 void gps_ubx_autoconfig_run(char * *buffer
, uint16_t *bytes_to_send
)
534 *buffer
= (char *)status
->working_packet
.buffer
;
535 current_step_touched
= false;
537 // autoconfig struct not yet allocated
542 // get UBX version whether autobaud / autoconfig is enabled or not
543 // this allows the user to manually try some baud rates and visibly see when it works
544 // it also is how the autobaud code determines when the baud rate is correct
545 // ubxHwVersion is a global set externally by the caller of this function
546 // it is set when the GPS responds to a MON_VER message
547 if (ubxHwVersion
<= 0) {
548 // at low baud rates and high data rates the ubx gps simply must drop some outgoing data
549 // this isn't really an error
550 // and when a lot of data is being dropped, the MON VER reply often gets dropped
551 // on the other hand, uBlox documents that some versions discard data that is over 1 second old
552 // implying a 1 second send buffer and that it could be over 1 second before a reply is received
553 // later uBlox versions dropped this 1 second constraint and drop data when the send buffer is full
554 // and that could be even longer than 1 second
555 // send this more quickly and it will get a reply more quickly if a fixed percentage of replies are being dropped
557 // wait for the normal reply timeout before sending it over and over
558 if (PIOS_DELAY_DiffuS(status
->lastStepTimestampRaw
) < UBX_PARSER_TIMEOUT
) {
562 // at this point we have already waited for the MON_VER reply to time out (except the first time where it times out without being sent)
563 // and the fact we are here says that ubxHwVersion has not been set (it is set externally)
564 // so this try at this baud rate has failed
566 // select the next baud rate, skipping ahead if new baud rate is HwSettings.GPSSpeed
567 // set Revo baud rate to current++ value (immediate change so we can send right after that) and send the MON_VER request
568 // baud rate search order are most likely matches first
570 // if AutoBaud or higher, do AutoBaud
571 if (status
->currentSettings
.UbxAutoConfig
>= GPSSETTINGS_UBXAUTOCONFIG_AUTOBAUD
) {
573 static uint8_t baud_array
[] = {
574 HWSETTINGS_GPSSPEED_57600
,
575 HWSETTINGS_GPSSPEED_9600
,
576 HWSETTINGS_GPSSPEED_115200
,
577 HWSETTINGS_GPSSPEED_38400
,
578 HWSETTINGS_GPSSPEED_19200
,
579 HWSETTINGS_GPSSPEED_230400
,
580 HWSETTINGS_GPSSPEED_4800
,
581 HWSETTINGS_GPSSPEED_2400
584 // first try HwSettings.GPSSpeed and then
585 // get the next baud rate to try from the table, but skip over the value of HwSettings.GPSSpeed
587 // index is inited to be out of bounds, which is interpreted as "currently defined baud rate" (= HwSettings.GPSSpeed)
588 if (baud_to_try_index
>= sizeof(baud_array
) / sizeof(baud_array
[0])) {
589 HwSettingsGPSSpeedGet(&hwsettings_baud
);
590 baud_to_try
= hwsettings_baud
;
591 baud_to_try_index
= 0;
594 baud_to_try
= baud_array
[baud_to_try_index
++];
596 // skip HwSettings.GPSSpeed when you run across it in the list
597 } while (baud_to_try
== hwsettings_baud
);
598 // set the FC (Revo) baud rate
599 gps_set_fc_baud_from_arg(baud_to_try
);
602 // this code is executed even if ubxautoconfig is disabled
603 // it detects the "sensor type" = type of GPS
604 // the user can use this to manually determine if the baud rate is correct
605 build_request((UBXSentPacket_t
*)&status
->working_packet
, UBX_CLASS_MON
, UBX_ID_MON_VER
, bytes_to_send
);
606 // keep timeouts running properly, we (will have) just sent a packet that generates a reply
607 status
->lastStepTimestampRaw
= PIOS_DELAY_GetRaw();
612 // keep resetting the timeouts here if we are not actually going to run the configure code
613 // not really necessary, but it keeps the timer from wrapping every 50 seconds
614 status
->lastStepTimestampRaw
= PIOS_DELAY_GetRaw();
615 return; // autoconfig not enabled
621 switch (status
->currentStep
) {
622 // if here, we have verified that the baud rates are in sync sometime in the past
623 case INIT_STEP_START
:
624 // we should look for the GPS version again (user may plug in a different GPS and then do autoconfig again)
625 // zero retries for the next state that needs it (INIT_STEP_SAVE)
626 set_current_step_if_untouched(INIT_STEP_SEND_MON_VER
);
627 // fall through to next state
628 // we can do that if we choose because we haven't sent any data in this state
631 case INIT_STEP_SEND_MON_VER
:
632 build_request((UBXSentPacket_t
*)&status
->working_packet
, UBX_CLASS_MON
, UBX_ID_MON_VER
, bytes_to_send
);
633 // keep timeouts running properly, we (will have) just sent a packet that generates a reply
634 set_current_step_if_untouched(INIT_STEP_WAIT_MON_VER_ACK
);
635 status
->lastStepTimestampRaw
= PIOS_DELAY_GetRaw();
638 case INIT_STEP_WAIT_MON_VER_ACK
:
639 // wait for previous step
640 // extra wait time might well be unnecessary but we want to make sure
641 // that we don't stop waiting too soon
642 if (PIOS_DELAY_DiffuS(status
->lastStepTimestampRaw
) < UBX_UNVERIFIED_STEP_WAIT_TIME
) {
645 // Continue with next configuration option
646 set_current_step_if_untouched(INIT_STEP_RESET_GPS
);
647 // fall through to next state
648 // we can do that if we choose because we haven't sent any data in this state
651 // if here, we have just verified that the baud rates are in sync (again)
652 case INIT_STEP_RESET_GPS
:
653 // make sure we don't change the baud rate too soon and garble the packet being sent
654 // even after pios says the buffer is empty, the serial port buffer still has data in it
655 // and changing the baud will screw it up
656 // when the GPS is configured to send a lot of data, but has a low baud rate
657 // it has way too many messages to send and has to drop most of them
659 // Retrieve desired GPS baud rate once for use throughout this module
660 HwSettingsGPSSpeedGet(&hwsettings_baud
);
661 #if !defined(ALWAYS_RESET)
662 // ALWAYS_RESET is undefined because it causes stored settings to change even with autoconfig.nostore
663 // but with it off, some settings may be enabled that should really be disabled (but aren't) after autoconfig.nostore
664 // if user requests a low baud rate then we just reset and avoid adding navigation sentences
665 // because low GPS baud and high OP data rate doesn't play nice
666 // if user requests that settings be saved, we will reset here too
667 // that makes sure that all strange settings are reset to factory default
668 // else these strange settings may persist because we don't reset all settings by table
669 if (status
->currentSettings
.UbxAutoConfig
== GPSSETTINGS_UBXAUTOCONFIG_AUTOBAUDCONFIGUREANDSTORE
670 #if defined(AUTOBAUD_CONFIGURE_STORE_AND_DISABLE)
671 || status
->currentSettings
.UbxAutoConfig
== GPSSETTINGS_UBXAUTOCONFIG_AUTOBAUDCONFIGURESTOREANDDISABLE
676 // reset all GPS parameters to factory default (configure low rate NMEA for low baud rates)
677 // this is not usable by OP code for either baud rate or types of messages sent
678 // but it starts up very quickly for use with autoconfig-nostore (which sets a high baud and enables all the necessary messages)
679 config_reset(bytes_to_send
);
680 status
->lastStepTimestampRaw
= PIOS_DELAY_GetRaw();
682 // else allow it enter the next state immmediately by not setting status->lastStepTimestampRaw = PIOS_DELAY_GetRaw();
683 set_current_step_if_untouched(INIT_STEP_REVO_9600_BAUD
);
686 // GPS was just reset, so GPS is running 9600 baud, and Revo is running whatever baud it was before
687 case INIT_STEP_REVO_9600_BAUD
:
688 #if !defined(ALWAYS_RESET)
689 // if user requests a low baud rate then we just reset and leave it set to NMEA
690 // because low baud and high OP data rate doesn't play nice
691 // if user requests that settings be saved, we will reset here too
692 // that makes sure that all strange settings are reset to factory default
693 // else these strange settings may persist because we don't reset all settings by hand
694 if (status
->currentSettings
.UbxAutoConfig
== GPSSETTINGS_UBXAUTOCONFIG_AUTOBAUDCONFIGUREANDSTORE
695 #if defined(AUTOBAUD_CONFIGURE_STORE_AND_DISABLE)
696 || status
->currentSettings
.UbxAutoConfig
== GPSSETTINGS_UBXAUTOCONFIG_AUTOBAUDCONFIGURESTOREANDDISABLE
701 // wait for previous step
702 // extra wait time might well be unnecessary but we want to make very sure
703 // that we don't stop waiting too soon as that could leave us at an unknown baud rate
704 // (i.e. set or not set) if the the transmit buffer was full and we were running at a low baud rate
705 if (PIOS_DELAY_DiffuS(status
->lastStepTimestampRaw
) < UBX_UNVERIFIED_STEP_WAIT_TIME
) {
708 // set the Revo GPS port to 9600 baud to match the reset to factory default that has already been done
709 gps_set_fc_baud_from_arg(HWSETTINGS_GPSSPEED_9600
);
711 // at most, we just set Revo baud and that doesn't send any data
712 // fall through to next state
713 // we can do that if we choose because we haven't sent any data in this state
714 // set_current_step_if_untouched(INIT_STEP_GPS_BAUD);
715 // allow it enter the next state immmediately by not setting status->lastStepTimestampRaw = PIOS_DELAY_GetRaw();
718 // Revo and GPS are both at 9600 baud
719 case INIT_STEP_GPS_BAUD
:
720 // https://www.u-blox.com/images/downloads/Product_Docs/u-bloxM8_ReceiverDescriptionProtocolSpec_%28UBX-13003221%29_Public.pdf
721 // It is possible to change the current communications port settings using a UBX-CFG-CFG message. This could
722 // affect baud rate and other transmission parameters. Because there may be messages queued for transmission
723 // there may be uncertainty about which protocol applies to such messages. In addition a message currently in
724 // transmission may be corrupted by a protocol change. Host data reception parameters may have to be changed to
725 // be able to receive future messages, including the acknowledge message associated with the UBX-CFG-CFG message.
727 // so the message that changes the baud rate will send it's acknowledgement back at the new baud rate; this is not good.
728 // if your message was corrupted, you didn't change the baud rate and you have to guess; try pinging at both baud rates.
729 // also, you would have to change the baud rate instantly after the last byte of the sentence was sent,
730 // and you would have to poll the port in real time for that, and there may be messages ahead of the baud rate change.
732 // so we ignore the ack from this. it has proven to be reliable (with the addition of two dummy bytes after the packet)
734 // set the GPS internal baud rate to the user configured value
735 config_gps_baud(bytes_to_send
);
736 set_current_step_if_untouched(INIT_STEP_REVO_BAUD
);
737 status
->lastStepTimestampRaw
= PIOS_DELAY_GetRaw();
740 // GPS is at final baud and Revo is at old baud (old is 9600 or initial detected baud)
741 case INIT_STEP_REVO_BAUD
:
742 // wait for previous step
743 if (PIOS_DELAY_DiffuS(status
->lastStepTimestampRaw
) < UBX_UNVERIFIED_STEP_WAIT_TIME
) {
746 // set the Revo GPS port baud rate to the (same) user configured value
747 gps_set_fc_baud_from_arg(hwsettings_baud
);
748 status
->lastConfigSent
= LAST_CONFIG_SENT_START
;
749 // zero the retries for the first "enable sentence"
750 status
->retryCount
= 0;
751 // skip enabling UBX sentences for low baud rates
752 // low baud rates are not usable, and higher data rates just makes it harder for this code to change the configuration
753 if (hwsettings_baud
<= HWSETTINGS_GPSSPEED_9600
) {
754 set_current_step_if_untouched(INIT_STEP_SAVE
);
756 set_current_step_if_untouched(INIT_STEP_ENABLE_SENTENCES
);
758 // allow it enter the next state immmediately by not setting status->lastStepTimestampRaw = PIOS_DELAY_GetRaw();
761 case INIT_STEP_ENABLE_SENTENCES
:
762 case INIT_STEP_CONFIGURE
:
764 bool step_configure
= (status
->currentStep
== INIT_STEP_CONFIGURE
);
765 if (step_configure
) {
766 configure(bytes_to_send
);
768 enable_sentences(bytes_to_send
);
771 // for some branches, allow it enter the next state immmediately by not setting status->lastStepTimestampRaw = PIOS_DELAY_GetRaw();
772 if (status
->lastConfigSent
== LAST_CONFIG_SENT_COMPLETED
) {
773 if (step_configure
) {
774 // zero retries for the next state that needs it (INIT_STEP_SAVE)
775 status
->retryCount
= 0;
776 set_current_step_if_untouched(INIT_STEP_SAVE
);
778 // finished enabling sentences, now configure() needs to start at the beginning
779 status
->lastConfigSent
= LAST_CONFIG_SENT_START
;
780 set_current_step_if_untouched(INIT_STEP_CONFIGURE
);
783 set_current_step_if_untouched(step_configure
? INIT_STEP_CONFIGURE_WAIT_ACK
: INIT_STEP_ENABLE_SENTENCES_WAIT_ACK
);
784 status
->lastStepTimestampRaw
= PIOS_DELAY_GetRaw();
789 case INIT_STEP_ENABLE_SENTENCES_WAIT_ACK
:
790 case INIT_STEP_CONFIGURE_WAIT_ACK
: // Wait for an ack from GPS
792 bool step_configure
= (status
->currentStep
== INIT_STEP_CONFIGURE_WAIT_ACK
);
793 if (ubxLastAck
.clsID
== status
->requiredAck
.clsID
&& ubxLastAck
.msgID
== status
->requiredAck
.msgID
) {
794 // Continue with next configuration option
795 // start retries over for the next setting to be sent
796 status
->retryCount
= 0;
797 status
->lastConfigSent
++;
798 } else if (PIOS_DELAY_DiffuS(status
->lastStepTimestampRaw
) < UBX_REPLY_TIMEOUT
&&
799 (ubxLastNak
.clsID
!= status
->requiredAck
.clsID
|| ubxLastNak
.msgID
!= status
->requiredAck
.msgID
)) {
800 // allow timeouts to count up by not setting status->lastStepTimestampRaw = PIOS_DELAY_GetRaw();
803 // timeout or NAK, resend the message or abort
804 status
->retryCount
++;
805 if (status
->retryCount
> UBX_MAX_RETRIES
) {
806 set_current_step_if_untouched(INIT_STEP_PRE_ERROR
);
807 status
->lastStepTimestampRaw
= PIOS_DELAY_GetRaw();
811 // success or failure here, retries are handled elsewhere
812 if (step_configure
) {
813 set_current_step_if_untouched(INIT_STEP_CONFIGURE
);
815 set_current_step_if_untouched(INIT_STEP_ENABLE_SENTENCES
);
820 // all configurations have been made
822 // now decide whether to save them permanently into the GPS
823 if (status
->currentSettings
.UbxAutoConfig
== GPSSETTINGS_UBXAUTOCONFIG_AUTOBAUDCONFIGUREANDSTORE
824 #if defined(AUTOBAUD_CONFIGURE_STORE_AND_DISABLE)
825 || status
->currentSettings
.UbxAutoConfig
== GPSSETTINGS_UBXAUTOCONFIG_AUTOBAUDCONFIGURESTOREANDDISABLE
828 config_save(bytes_to_send
);
829 set_current_step_if_untouched(INIT_STEP_SAVE_WAIT_ACK
);
830 status
->lastStepTimestampRaw
= PIOS_DELAY_GetRaw();
832 set_current_step_if_untouched(INIT_STEP_PRE_DONE
);
833 // allow it enter INIT_STEP_PRE_DONE immmediately by not setting status->lastStepTimestampRaw = PIOS_DELAY_GetRaw();
837 // command to save configuration has already been issued
838 case INIT_STEP_SAVE_WAIT_ACK
:
839 // save doesn't appear to respond, even in 24 seconds
840 // just delay a while, in case there it is busy with a flash write, etc.
841 if (PIOS_DELAY_DiffuS(status
->lastStepTimestampRaw
) < UBX_SAVE_WAIT_TIME
) {
844 // fall through to next state
845 // we can do that if we choose because we haven't sent any data in this state
846 set_current_step_if_untouched(INIT_STEP_PRE_DONE
);
849 // the autoconfig has completed normally
850 case INIT_STEP_PRE_DONE
:
851 #if defined(AUTOBAUD_CONFIGURE_STORE_AND_DISABLE)
852 // determine if we need to disable autoconfig via the autoconfig==AUTOBAUDCONFIGSTOREANDDISABLE setting
853 if (status
->currentSettings
.UbxAutoConfig
== GPSSETTINGS_UBXAUTOCONFIG_AUTOBAUDCONFIGURESTOREANDDISABLE
) {
855 status
->currentSettings
.UbxAutoConfig
= GPSSETTINGS_UBXAUTOCONFIG_DISABLED
;
860 set_current_step_if_untouched(INIT_STEP_DONE
);
863 // an error, such as retries exhausted, has occurred
864 case INIT_STEP_PRE_ERROR
:
865 // on error we should get the GPS version immediately
866 gps_ubx_reset_sensor_type();
867 set_current_step_if_untouched(INIT_STEP_ERROR
);
871 case INIT_STEP_ERROR
:
872 case INIT_STEP_DISABLED
:
878 // (re)init the autoconfig stuff so that it will run if called
880 // this can be called from a different thread
881 // so everything it touches must be declared volatile
882 void gps_ubx_autoconfig_set(ubx_autoconfig_settings_t
*config
)
884 initSteps_t new_step
;
889 status
= (status_t
*)pios_malloc(sizeof(status_t
));
891 memset((status_t
*)status
, 0, sizeof(status_t
));
894 // if caller used NULL, just use current settings to restart autoconfig process
895 if (config
!= NULL
) {
896 status
->currentSettings
= *config
;
898 if (status
->currentSettings
.UbxAutoConfig
>= GPSSETTINGS_UBXAUTOCONFIG_AUTOBAUDANDCONFIGURE
) {
899 new_step
= INIT_STEP_START
;
901 new_step
= INIT_STEP_DISABLED
;
903 status
->lastStepTimestampRaw
= PIOS_DELAY_GetRaw();
905 // assume this one byte initSteps_t is atomic
906 // take care of some but not all concurrency issues
908 status
->currentStep
= new_step
;
909 status
->currentStepSave
= new_step
;
910 current_step_touched
= true;
911 status
->currentStep
= new_step
;
912 status
->currentStepSave
= new_step
;
914 // this forces the sensor type detection to occur outside the FSM
915 // and _can_ also engage the autobaud detection that is outside the FSM
916 // don't do it if FSM is enabled as FSM can change the baud itself
917 // (don't do it because the baud rates are already in sync)
918 gps_ubx_reset_sensor_type();
920 if (status
->currentSettings
.UbxAutoConfig
>= GPSSETTINGS_UBXAUTOCONFIG_AUTOBAUDANDCONFIGURE
) {
921 // enabled refers to autoconfigure
922 // note that sensor type (gps type) detection happens even if completely disabled
923 // also note that AutoBaud is less than AutoBaudAndConfigure
929 int32_t ubx_autoconfig_get_status()
931 if (!status
|| !enabled
) {
932 return UBX_AUTOCONFIG_STATUS_DISABLED
;
934 switch (status
->currentStep
) {
935 case INIT_STEP_ERROR
:
936 return UBX_AUTOCONFIG_STATUS_ERROR
;
938 case INIT_STEP_DISABLED
:
939 return UBX_AUTOCONFIG_STATUS_DISABLED
;
942 return UBX_AUTOCONFIG_STATUS_DONE
;
947 return UBX_AUTOCONFIG_STATUS_RUNNING
;