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