Line data Source code
1 1 : /*
2 : * Copyright (c) 2023 Trackunit Corporation
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @ingroup gnss_interface
10 : * @brief Main header file for GNSS driver API.
11 : */
12 :
13 : #ifndef ZEPHYR_INCLUDE_DRIVERS_GNSS_H_
14 : #define ZEPHYR_INCLUDE_DRIVERS_GNSS_H_
15 :
16 : /**
17 : * @brief Interfaces for Global Navigation Satellite System (GNSS) receivers.
18 : * @defgroup gnss_interface GNSS
19 : * @since 3.6
20 : * @version 0.1.0
21 : * @ingroup io_interfaces
22 : * @{
23 : */
24 :
25 : #include <zephyr/kernel.h>
26 : #include <zephyr/types.h>
27 : #include <zephyr/device.h>
28 : #include <zephyr/data/navigation.h>
29 : #include <errno.h>
30 :
31 : #ifdef __cplusplus
32 : extern "C" {
33 : #endif
34 :
35 : /** GNSS PPS modes */
36 1 : enum gnss_pps_mode {
37 : /** PPS output disabled */
38 : GNSS_PPS_MODE_DISABLED = 0,
39 : /** PPS output always enabled */
40 : GNSS_PPS_MODE_ENABLED = 1,
41 : /** PPS output enabled from first lock */
42 : GNSS_PPS_MODE_ENABLED_AFTER_LOCK = 2,
43 : /** PPS output enabled while locked */
44 : GNSS_PPS_MODE_ENABLED_WHILE_LOCKED = 3
45 : };
46 :
47 : /** API for setting fix rate */
48 1 : typedef int (*gnss_set_fix_rate_t)(const struct device *dev, uint32_t fix_interval_ms);
49 :
50 : /** API for getting fix rate */
51 1 : typedef int (*gnss_get_fix_rate_t)(const struct device *dev, uint32_t *fix_interval_ms);
52 :
53 : /** GNSS navigation modes */
54 1 : enum gnss_navigation_mode {
55 : /** Dynamics have no impact on tracking */
56 : GNSS_NAVIGATION_MODE_ZERO_DYNAMICS = 0,
57 : /** Low dynamics have higher impact on tracking */
58 : GNSS_NAVIGATION_MODE_LOW_DYNAMICS = 1,
59 : /** Low and high dynamics have equal impact on tracking */
60 : GNSS_NAVIGATION_MODE_BALANCED_DYNAMICS = 2,
61 : /** High dynamics have higher impact on tracking */
62 : GNSS_NAVIGATION_MODE_HIGH_DYNAMICS = 3
63 : };
64 :
65 : /** API for setting navigation mode */
66 1 : typedef int (*gnss_set_navigation_mode_t)(const struct device *dev,
67 : enum gnss_navigation_mode mode);
68 :
69 : /** API for getting navigation mode */
70 1 : typedef int (*gnss_get_navigation_mode_t)(const struct device *dev,
71 : enum gnss_navigation_mode *mode);
72 :
73 : /** Systems contained in gnss_systems_t */
74 1 : enum gnss_system {
75 : /** Global Positioning System (GPS) */
76 : GNSS_SYSTEM_GPS = BIT(0),
77 : /** GLObal NAvigation Satellite System (GLONASS) */
78 : GNSS_SYSTEM_GLONASS = BIT(1),
79 : /** Galileo */
80 : GNSS_SYSTEM_GALILEO = BIT(2),
81 : /** BeiDou Navigation Satellite System */
82 : GNSS_SYSTEM_BEIDOU = BIT(3),
83 : /** Quasi-Zenith Satellite System (QZSS) */
84 : GNSS_SYSTEM_QZSS = BIT(4),
85 : /** Indian Regional Navigation Satellite System (IRNSS) */
86 : GNSS_SYSTEM_IRNSS = BIT(5),
87 : /** Satellite-Based Augmentation System (SBAS) */
88 : GNSS_SYSTEM_SBAS = BIT(6),
89 : /** Indoor Messaging System (IMES) */
90 : GNSS_SYSTEM_IMES = BIT(7),
91 : };
92 :
93 : /** Type storing bitmask of GNSS systems */
94 1 : typedef uint32_t gnss_systems_t;
95 :
96 : /** API for enabling systems */
97 1 : typedef int (*gnss_set_enabled_systems_t)(const struct device *dev, gnss_systems_t systems);
98 :
99 : /** API for getting enabled systems */
100 1 : typedef int (*gnss_get_enabled_systems_t)(const struct device *dev, gnss_systems_t *systems);
101 :
102 : /** API for getting enabled systems */
103 1 : typedef int (*gnss_get_supported_systems_t)(const struct device *dev, gnss_systems_t *systems);
104 :
105 : /** API for getting timestamp of last PPS pulse */
106 1 : typedef int (*gnss_get_latest_timepulse_t)(const struct device *dev, k_ticks_t *timestamp);
107 :
108 : /** GNSS fix status */
109 1 : enum gnss_fix_status {
110 : /** No GNSS fix acquired */
111 : GNSS_FIX_STATUS_NO_FIX = 0,
112 : /** GNSS fix acquired */
113 : GNSS_FIX_STATUS_GNSS_FIX = 1,
114 : /** Differential GNSS fix acquired */
115 : GNSS_FIX_STATUS_DGNSS_FIX = 2,
116 : /** Estimated fix acquired */
117 : GNSS_FIX_STATUS_ESTIMATED_FIX = 3,
118 : };
119 :
120 : /** GNSS fix quality */
121 1 : enum gnss_fix_quality {
122 : /** Invalid fix */
123 : GNSS_FIX_QUALITY_INVALID = 0,
124 : /** Standard positioning service */
125 : GNSS_FIX_QUALITY_GNSS_SPS = 1,
126 : /** Differential GNSS */
127 : GNSS_FIX_QUALITY_DGNSS = 2,
128 : /** Precise positioning service */
129 : GNSS_FIX_QUALITY_GNSS_PPS = 3,
130 : /** Real-time kinematic */
131 : GNSS_FIX_QUALITY_RTK = 4,
132 : /** Floating real-time kinematic */
133 : GNSS_FIX_QUALITY_FLOAT_RTK = 5,
134 : /** Estimated fix */
135 : GNSS_FIX_QUALITY_ESTIMATED = 6,
136 : };
137 :
138 : /** GNSS info data structure */
139 1 : struct gnss_info {
140 : /** Number of satellites being tracked */
141 1 : uint16_t satellites_cnt;
142 : /** Horizontal dilution of precision in 1/1000 */
143 1 : uint32_t hdop;
144 : /** Geoid separation in millimeters */
145 1 : int32_t geoid_separation;
146 : /** The fix status */
147 1 : enum gnss_fix_status fix_status;
148 : /** The fix quality */
149 1 : enum gnss_fix_quality fix_quality;
150 : };
151 :
152 : /** GNSS time data structure */
153 1 : struct gnss_time {
154 : /** Hour [0, 23] */
155 1 : uint8_t hour;
156 : /** Minute [0, 59] */
157 1 : uint8_t minute;
158 : /** Millisecond [0, 60999] */
159 1 : uint16_t millisecond;
160 : /** Day of month [1, 31] */
161 1 : uint8_t month_day;
162 : /** Month [1, 12] */
163 1 : uint8_t month;
164 : /** Year [0, 99] */
165 1 : uint8_t century_year;
166 : };
167 :
168 : /** GNSS API structure */
169 1 : __subsystem struct gnss_driver_api {
170 0 : gnss_set_fix_rate_t set_fix_rate;
171 0 : gnss_get_fix_rate_t get_fix_rate;
172 0 : gnss_set_navigation_mode_t set_navigation_mode;
173 0 : gnss_get_navigation_mode_t get_navigation_mode;
174 0 : gnss_set_enabled_systems_t set_enabled_systems;
175 0 : gnss_get_enabled_systems_t get_enabled_systems;
176 0 : gnss_get_supported_systems_t get_supported_systems;
177 0 : gnss_get_latest_timepulse_t get_latest_timepulse;
178 : };
179 :
180 : /** GNSS data structure */
181 1 : struct gnss_data {
182 : /** Navigation data acquired */
183 1 : struct navigation_data nav_data;
184 : /** GNSS info when navigation data was acquired */
185 1 : struct gnss_info info;
186 : /** UTC time when data was acquired */
187 1 : struct gnss_time utc;
188 : };
189 :
190 : /** Template for GNSS data callback */
191 1 : typedef void (*gnss_data_callback_t)(const struct device *dev, const struct gnss_data *data);
192 :
193 : /** GNSS callback structure */
194 1 : struct gnss_data_callback {
195 : /** Filter callback to GNSS data from this device if not NULL */
196 1 : const struct device *dev;
197 : /** Callback called when GNSS data is published */
198 1 : gnss_data_callback_t callback;
199 : };
200 :
201 : /** GNSS satellite structure */
202 1 : struct gnss_satellite {
203 : /** Pseudo-random noise sequence */
204 1 : uint8_t prn;
205 : /** Signal-to-noise ratio in dB */
206 1 : uint8_t snr;
207 : /** Elevation in degrees [0, 90] */
208 1 : uint8_t elevation;
209 : /** Azimuth relative to True North in degrees [0, 359] */
210 1 : uint16_t azimuth;
211 : /** System of satellite */
212 1 : enum gnss_system system;
213 : /** True if satellite is being tracked */
214 1 : uint8_t is_tracked : 1;
215 : /** True if satellite tracking has RTK corrections */
216 1 : uint8_t is_corrected : 1;
217 : };
218 :
219 : /** Template for GNSS satellites callback */
220 1 : typedef void (*gnss_satellites_callback_t)(const struct device *dev,
221 : const struct gnss_satellite *satellites,
222 : uint16_t size);
223 :
224 : /** GNSS callback structure */
225 1 : struct gnss_satellites_callback {
226 : /** Filter callback to GNSS data from this device if not NULL */
227 1 : const struct device *dev;
228 : /** Callback called when GNSS satellites is published */
229 1 : gnss_satellites_callback_t callback;
230 : };
231 :
232 : /**
233 : * @brief Set the GNSS fix rate
234 : *
235 : * @param dev Device instance
236 : * @param fix_interval_ms Fix interval to set in milliseconds
237 : *
238 : * @return 0 if successful
239 : * @return -errno negative errno code on failure
240 : */
241 1 : __syscall int gnss_set_fix_rate(const struct device *dev, uint32_t fix_interval_ms);
242 :
243 : static inline int z_impl_gnss_set_fix_rate(const struct device *dev, uint32_t fix_interval_ms)
244 : {
245 : const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api;
246 :
247 : if (api->set_fix_rate == NULL) {
248 : return -ENOSYS;
249 : }
250 :
251 : return api->set_fix_rate(dev, fix_interval_ms);
252 : }
253 :
254 : /**
255 : * @brief Get the GNSS fix rate
256 : *
257 : * @param dev Device instance
258 : * @param fix_interval_ms Destination for fix interval in milliseconds
259 : *
260 : * @return 0 if successful
261 : * @return -errno negative errno code on failure
262 : */
263 1 : __syscall int gnss_get_fix_rate(const struct device *dev, uint32_t *fix_interval_ms);
264 :
265 : static inline int z_impl_gnss_get_fix_rate(const struct device *dev, uint32_t *fix_interval_ms)
266 : {
267 : const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api;
268 :
269 : if (api->get_fix_rate == NULL) {
270 : return -ENOSYS;
271 : }
272 :
273 : return api->get_fix_rate(dev, fix_interval_ms);
274 : }
275 :
276 : /**
277 : * @brief Set the GNSS navigation mode
278 : *
279 : * @param dev Device instance
280 : * @param mode Navigation mode to set
281 : *
282 : * @return 0 if successful
283 : * @return -errno negative errno code on failure
284 : */
285 1 : __syscall int gnss_set_navigation_mode(const struct device *dev,
286 : enum gnss_navigation_mode mode);
287 :
288 : static inline int z_impl_gnss_set_navigation_mode(const struct device *dev,
289 : enum gnss_navigation_mode mode)
290 : {
291 : const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api;
292 :
293 : if (api->set_navigation_mode == NULL) {
294 : return -ENOSYS;
295 : }
296 :
297 : return api->set_navigation_mode(dev, mode);
298 : }
299 :
300 : /**
301 : * @brief Get the GNSS navigation mode
302 : *
303 : * @param dev Device instance
304 : * @param mode Destination for navigation mode
305 : *
306 : * @return 0 if successful
307 : * @return -errno negative errno code on failure
308 : */
309 1 : __syscall int gnss_get_navigation_mode(const struct device *dev,
310 : enum gnss_navigation_mode *mode);
311 :
312 : static inline int z_impl_gnss_get_navigation_mode(const struct device *dev,
313 : enum gnss_navigation_mode *mode)
314 : {
315 : const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api;
316 :
317 : if (api->get_navigation_mode == NULL) {
318 : return -ENOSYS;
319 : }
320 :
321 : return api->get_navigation_mode(dev, mode);
322 : }
323 :
324 : /**
325 : * @brief Set enabled GNSS systems
326 : *
327 : * @param dev Device instance
328 : * @param systems Systems to enable
329 : *
330 : * @return 0 if successful
331 : * @return -errno negative errno code on failure
332 : */
333 1 : __syscall int gnss_set_enabled_systems(const struct device *dev, gnss_systems_t systems);
334 :
335 : static inline int z_impl_gnss_set_enabled_systems(const struct device *dev,
336 : gnss_systems_t systems)
337 : {
338 : const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api;
339 :
340 : if (api->set_enabled_systems == NULL) {
341 : return -ENOSYS;
342 : }
343 :
344 : return api->set_enabled_systems(dev, systems);
345 : }
346 :
347 : /**
348 : * @brief Get enabled GNSS systems
349 : *
350 : * @param dev Device instance
351 : * @param systems Destination for enabled systems
352 : *
353 : * @return 0 if successful
354 : * @return -errno negative errno code on failure
355 : */
356 1 : __syscall int gnss_get_enabled_systems(const struct device *dev, gnss_systems_t *systems);
357 :
358 : static inline int z_impl_gnss_get_enabled_systems(const struct device *dev,
359 : gnss_systems_t *systems)
360 : {
361 : const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api;
362 :
363 : if (api->get_enabled_systems == NULL) {
364 : return -ENOSYS;
365 : }
366 :
367 : return api->get_enabled_systems(dev, systems);
368 : }
369 :
370 : /**
371 : * @brief Get supported GNSS systems
372 : *
373 : * @param dev Device instance
374 : * @param systems Destination for supported systems
375 : *
376 : * @return 0 if successful
377 : * @return -errno negative errno code on failure
378 : */
379 1 : __syscall int gnss_get_supported_systems(const struct device *dev, gnss_systems_t *systems);
380 :
381 : static inline int z_impl_gnss_get_supported_systems(const struct device *dev,
382 : gnss_systems_t *systems)
383 : {
384 : const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api;
385 :
386 : if (api->get_supported_systems == NULL) {
387 : return -ENOSYS;
388 : }
389 :
390 : return api->get_supported_systems(dev, systems);
391 : }
392 :
393 : /**
394 : * @brief Get the timestamp of the latest PPS timepulse
395 : *
396 : * @note The timestamp is considered valid when the timepulse pin is actively toggling.
397 : *
398 : * @param dev Device instance
399 : * @param timestamp Kernel tick count at the time of the PPS pulse
400 : *
401 : * @retval 0 if successful
402 : * @retval -ENOSYS if driver does not support API
403 : * @retval -ENOTSUP if driver does not have PPS pin connected
404 : * @retval -EAGAIN if PPS pulse is not considered valid
405 : */
406 1 : __syscall int gnss_get_latest_timepulse(const struct device *dev, k_ticks_t *timestamp);
407 :
408 : static inline int z_impl_gnss_get_latest_timepulse(const struct device *dev,
409 : k_ticks_t *timestamp)
410 : {
411 : const struct gnss_driver_api *api = (const struct gnss_driver_api *)dev->api;
412 :
413 : if (api->get_latest_timepulse == NULL) {
414 : return -ENOSYS;
415 : }
416 :
417 : return api->get_latest_timepulse(dev, timestamp);
418 : }
419 :
420 : /**
421 : * @brief Register a callback structure for GNSS data published
422 : *
423 : * @param _dev Device pointer
424 : * @param _callback The callback function
425 : */
426 : #if CONFIG_GNSS
427 : #define GNSS_DATA_CALLBACK_DEFINE(_dev, _callback) \
428 : static const STRUCT_SECTION_ITERABLE(gnss_data_callback, \
429 : _gnss_data_callback__##_callback) = { \
430 : .dev = _dev, \
431 : .callback = _callback, \
432 : }
433 : #else
434 1 : #define GNSS_DATA_CALLBACK_DEFINE(_dev, _callback)
435 : #endif
436 :
437 : /**
438 : * @brief Register a callback structure for GNSS satellites published
439 : *
440 : * @param _dev Device pointer
441 : * @param _callback The callback function
442 : */
443 : #if CONFIG_GNSS_SATELLITES
444 : #define GNSS_SATELLITES_CALLBACK_DEFINE(_dev, _callback) \
445 : static const STRUCT_SECTION_ITERABLE(gnss_satellites_callback, \
446 : _gnss_satellites_callback__##_callback) = { \
447 : .dev = _dev, \
448 : .callback = _callback, \
449 : }
450 : #else
451 1 : #define GNSS_SATELLITES_CALLBACK_DEFINE(_dev, _callback)
452 : #endif
453 :
454 : /**
455 : * @}
456 : */
457 :
458 : #ifdef __cplusplus
459 : }
460 : #endif
461 :
462 : #include <zephyr/syscalls/gnss.h>
463 :
464 : #endif /* ZEPHYR_INCLUDE_DRIVERS_GNSS_H_ */
|