// SPDX-License-Identifier: Apache-2.0 #pragma once #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include /** * @brief Supported GPS/GNSS receiver chipsets. */ enum GpsModel { GPS_MODEL_UNKNOWN = 0, GPS_MODEL_AG3335, GPS_MODEL_AG3352, // CASIC, might work with AT6558, Neoway N58 LTE Cat.1, Neoway G2 and Neoway G7A GPS_MODEL_ATGM336H, GPS_MODEL_LS20031, GPS_MODEL_MTK, GPS_MODEL_MTK_L76B, GPS_MODEL_MTK_PA1616S, GPS_MODEL_UBLOX6, GPS_MODEL_UBLOX7, GPS_MODEL_UBLOX8, GPS_MODEL_UBLOX9, GPS_MODEL_UBLOX10, GPS_MODEL_UC6580, }; /** @return a human-readable name for the model, e.g. "UBLOX8" or "Unknown" */ const char* gps_model_to_string(enum GpsModel model); /** * @brief Lifecycle state of a GPS_TYPE device. */ enum GpsState { GPS_STATE_OFF, GPS_STATE_PENDING_ON, GPS_STATE_ON, GPS_STATE_ERROR, GPS_STATE_PENDING_OFF, }; enum GpsEventType { GPS_EVENT_UNSUBSCRIBED, // Last event, device wants to destroy itself and unsubscribed the subscriber. GPS_EVENT_MESSAGE_RMC, GPS_EVENT_MESSAGE_GGA, }; struct GpsEvent { enum GpsEventType type; union { struct minmea_sentence_rmc rmc; struct minmea_sentence_gga gga; } data; }; struct GpsSubscription { TaskHandle_t task; struct GpsEvent event; uint32_t sequence; uint32_t consumed_sequence; struct GpsSubscription* next; }; /** * @brief API for GPS/GNSS receiver drivers. */ struct GpsApi { /** * @brief Registers a subscriber for GPS events (e.g. RMC/GGA sentences). * @param[in] device the GPS device * @param[in,out] sub subscription to register; caller owns the storage and must keep it alive until unsubscribed */ error_t (*event_subscribe)(struct Device* device, struct GpsSubscription* sub); /** * @brief Removes a previously registered subscription. * @param[in] device the GPS device * @param[in] sub subscription to remove, as passed to event_subscribe */ error_t (*event_unsubscribe)(struct Device* device, struct GpsSubscription* sub); /** * @brief Blocks the calling task until a new event arrives for the subscription, or timeout elapses. * @param[in] device the GPS device * @param[in,out] sub subscription to wait on * @param[in] timeout max ticks to wait * @return ERROR_NONE if an event arrived, ERROR_TIMEOUT if the timeout elapsed */ error_t (*event_await)(struct Device* device, struct GpsSubscription* sub, TickType_t timeout); /** * @brief Gets the current lifecycle state. * @param[in] device the GPS device */ enum GpsState (*get_state)(struct Device* device); /** * @brief Gets a human-readable model name for the device, e.g. "UBLOX8". * @param[in] device the GPS device * @param[out] model_name buffer to receive the NUL-terminated name * @param[in] buffer_size size of model_name in bytes * @return ERROR_NONE on success */ error_t (*get_model_name)(struct Device* device, char* model_name, size_t buffer_size); }; /** @copydoc GpsApi::event_subscribe */ error_t gps_event_subscribe(struct Device* device, struct GpsSubscription* sub); /** @copydoc GpsApi::event_unsubscribe */ error_t gps_event_unsubscribe(struct Device* device, struct GpsSubscription* sub); /** @copydoc GpsApi::event_await */ error_t gps_event_await(struct Device* device, struct GpsSubscription* sub, TickType_t timeout); /** @copydoc GpsApi::get_state */ enum GpsState gps_get_state(struct Device* device); /** @copydoc GpsApi::get_model_name */ error_t gps_get_model_name(struct Device* device, char* model_name, size_t buffer_size); extern const struct DeviceType GPS_TYPE; #ifdef __cplusplus } #endif