/* * SPDX-License-Identifier: MIT * * The GPS manager's internals, shared by its three files and nothing else: * ZephyrGPSManager.cpp state machine, fix validation, init, public API * gps_power.cpp module power: GPIO/regulator, UART sleep, UART PM * gps_module_cfg.cpp module configuration (GNSS API or PMTK/PCAS/UBX), * its diagnostics report * Main thread only, except where a function says otherwise. */ #pragma once #include #include #include #if defined(CONFIG_SOC_NRF52840) #include #endif /* ========== GNSS Support ========== */ #if DT_HAS_COMPAT_STATUS_OKAY(gnss_nmea_generic) || \ DT_HAS_COMPAT_STATUS_OKAY(quectel_lc76g) || \ DT_HAS_COMPAT_STATUS_OKAY(luatos_air530z) #define HAS_GNSS 1 #include #else #define HAS_GNSS 0 #endif /* ========== GPS Feature Detection ========== * Every HAS_GPS_* predicate is defined here, before first use: an undefined * identifier in #if is silently 0. Add new ones to this block. */ /* GNSS module hangs off a UART we can write to (any compatible). */ #if HAS_GNSS && DT_NODE_HAS_STATUS(DT_NODELABEL(gnss), okay) && \ DT_NODE_HAS_STATUS(DT_BUS(DT_NODELABEL(gnss)), okay) #define HAS_GPS_UART 1 #else #define HAS_GPS_UART 0 #endif /* The nRF register diagnostics read the GNSS module's own UARTE, which is not * always UARTE0 (the RAK4631's GNSS is on uart1). */ #if HAS_GPS_UART && defined(CONFIG_SOC_NRF52840) && \ DT_NODE_HAS_COMPAT(DT_BUS(DT_NODELABEL(gnss)), nordic_nrf_uarte) #define GPS_NRF_UARTE ((NRF_UARTE_Type *)DT_REG_ADDR(DT_BUS(DT_NODELABEL(gnss)))) #endif /* Discrete GPS power-enable GPIO (gps-enable alias). */ #if DT_NODE_EXISTS(DT_ALIAS(gps_enable)) #define HAS_GPS_POWER_CONTROL 1 #else #define HAS_GPS_POWER_CONTROL 0 #endif /* Module standby pin beside a supply switch (gps-wakeup alias, see gps_power.cpp). */ #if DT_NODE_EXISTS(DT_ALIAS(gps_wakeup)) #define HAS_GPS_WAKEUP 1 #else #define HAS_GPS_WAKEUP 0 #endif /* GPS powered from a PMU regulator rail (chosen zephcore,gps-power). */ #if DT_NODE_EXISTS(DT_CHOSEN(zephcore_gps_power)) #define HAS_GPS_POWER_REGULATOR 1 #else #define HAS_GPS_POWER_REGULATOR 0 #endif #if HAS_GNSS /* ---- ZephyrGPSManager.cpp ---- */ extern const struct device *gnss_dev; #ifdef CONFIG_ZEPHCORE_GPS_SAT_DIAG /* Satellites tracked per constellation (GPS, GLONASS, Galileo, BeiDou, * other), 0 for one that has stopped reporting. Any thread. */ void gps_sat_tally(uint8_t out[5]); #endif /* ---- gps_power.cpp ---- */ /* keep_vrtc (off only): the board's state-keeping off, if it has one. */ void gps_power_control(bool on, bool keep_vrtc = false); /* The power line or rail if the board has one, else the UART sleep commands. */ void gps_module_power(bool on, bool keep_vrtc = true); /* gps_module_power() calls, for `gps diag` (upstream's bc/sc). */ extern uint32_t gps_power_on_count; extern uint32_t gps_power_off_count; /* Suspend/resume the GNSS UART (nRF UARTE: releases HFCLK). */ void gps_uart_set_power(bool on); #if HAS_GPS_POWER_CONTROL void gps_dump_gpio_states(void); #endif /* ---- gps_module_cfg.cpp ---- */ /* Boot only: configure the module (see the file). */ void gps_module_configure(void); /* Re-run the UART configuration when `set gps diag 1` asked for it. */ void gps_diag_maybe_reconfigure(void); #if HAS_GPS_UART && defined(CONFIG_ZEPHCORE_GPS_REAPPLY) /* CONFIG_ZEPHCORE_GPS_REAPPLY: write the step-th re-sent setting blind * (see the list in gps_module_cfg.cpp). Returns the ms to wait before the * next step, 0 when that was the last. */ uint32_t gps_module_reapply_step(uint8_t step); #endif void gps_uart_dump_hw_state(void); #if HAS_GPS_UART extern const struct device *const gps_uart_dev; /* Bytes to the module, blind (counted while configuring). */ void gps_uart_send(const uint8_t *data, size_t len); #endif #endif /* HAS_GNSS */