-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
x411: mpm: add support for GPSDO from USRP N2x0 (JacksonLabs Firefly)
The GPSDO has to be configured before use through RS232 with following commands: SYST:COMM:SER:ECHO OFF SYST:COMM:SER:PRO OFF GPS:GPGGA 1 GPS:GGAST 0 GPS:GPRMC 1 SERV:TRAC 1 SYSTem:COMMunicate:SERial:BAUD 38400 The code is totally not clean, but at this stage it works.
- Loading branch information
Showing
4 changed files
with
234 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
# | ||
# Copyright 2021 Ettus Research, a National Instruments Company | ||
# Copyright 2023 Piotr Krysik <[email protected]> | ||
# | ||
# SPDX-License-Identifier: GPL-3.0-or-later | ||
# | ||
""" | ||
X4XX GPS Manager | ||
Handles GPS-related tasks | ||
""" | ||
|
||
import re | ||
from usrp_mpm.gpsd_iface import GPSDIfaceExtension | ||
|
||
class ZCU111GPSMgr: | ||
""" | ||
Manager class for GPS-related actions for the X4XX. | ||
This also "disables" the sensors when the GPS is not enabled. | ||
""" | ||
def __init__(self, log): | ||
# assert clk_aux_board and clk_aux_board.is_gps_supported() | ||
# self._clocking_auxbrd = clk_aux_board | ||
self.log = log.getChild('GPS') | ||
self.log.trace("Initializing GPSd interface") | ||
self._gpsd = GPSDIfaceExtension() | ||
# To disable sensors, we simply return an empty value if GPS is disabled. | ||
# For TPV, SKY, and GPGGA, we can do this in the same fashion (they are | ||
# very similar). gps_time is different (it returns an int) so for sake | ||
# of simplicity it's defined separately below. | ||
for sensor_name in ('gps_tpv', 'gps_sky', 'gps_gpgga'): | ||
sensor_api = f'get_{sensor_name}_sensor' | ||
setattr( | ||
self, sensor_api, | ||
lambda sensor_name=sensor_name: { | ||
'name': sensor_name, 'type': 'STRING', | ||
'unit': '', 'value': 'n/a'} \ | ||
if not self.is_gps_enabled() \ | ||
else getattr(self._gpsd, f'get_{sensor_name}_sensor')() | ||
) | ||
|
||
def extend(self, context): | ||
""" | ||
Extend 'context' with the sensor methods of this class (get_gps_*_sensor). | ||
If 'context' already has such a method, it is skipped. | ||
Returns a dictionary compatible to mboard_sensor_callback_map. | ||
""" | ||
new_methods = { | ||
re.search(r"get_(.*)_sensor", method_name).group(1): method_name | ||
for method_name in dir(self) | ||
if not method_name.startswith('_') \ | ||
and callable(getattr(self, method_name)) \ | ||
and method_name.endswith("sensor")} | ||
for method_name in new_methods.values(): | ||
if hasattr(context, method_name): | ||
continue | ||
new_method = getattr(self, method_name) | ||
self.log.trace("%s: Adding %s method", context, method_name) | ||
setattr(context, method_name, new_method) | ||
return new_methods | ||
|
||
def is_gps_enabled(self): | ||
""" | ||
Return True if the GPS is enabled/active. | ||
""" | ||
# return self._clocking_auxbrd.is_gps_enabled() | ||
return self._gpsd.is_gps_enabled() | ||
|
||
def get_gps_enabled_sensor(self): | ||
""" | ||
Get enabled status of GPS as a sensor dict | ||
""" | ||
gps_enabled = self.is_gps_enabled() | ||
return { | ||
'name': 'gps_enabled', | ||
'type': 'BOOLEAN', | ||
'unit': 'enabled' if gps_enabled else 'disabled', | ||
'value': str(gps_enabled).lower(), | ||
} | ||
|
||
def get_gps_locked_sensor(self): | ||
""" | ||
Get lock status of GPS as a sensor dict | ||
""" | ||
gps_locked = self._gpsd.get_gps_lock() | ||
|
||
# self.is_gps_enabled() and \ | ||
# bool(self._clocking_auxbrd.get_gps_lock()) | ||
return { | ||
'name': 'gps_lock', | ||
'type': 'BOOLEAN', | ||
'unit': 'locked' if gps_locked else 'unlocked', | ||
'value': str(gps_locked).lower(), | ||
} | ||
# TODO PK: connect lock pin of GPSDO to a GPIO pin? | ||
|
||
# return { | ||
# 'name': 'gps_lock', | ||
# 'type': 'BOOLEAN', | ||
# 'unit': 'locked', | ||
# 'value': 'true', | ||
# } | ||
|
||
# def get_gps_alarm_sensor(self): | ||
# """ | ||
# Get alarm status of GPS as a sensor dict | ||
# """ | ||
# # gps_alarm = self.is_gps_enabled() and \ | ||
# # bool(self._clocking_auxbrd.get_gps_alarm()) | ||
# # return { | ||
# # 'name': 'gps_alarm', | ||
# # 'type': 'BOOLEAN', | ||
# # 'unit': 'active' if gps_alarm else 'not active', | ||
# # 'value': str(gps_alarm).lower(), | ||
# # } | ||
# return { | ||
# 'name': 'gps_alarm', | ||
# 'type': 'BOOLEAN', | ||
# 'unit': 'not active', | ||
# 'value': 'false', | ||
# } | ||
|
||
# def get_gps_warmup_sensor(self): | ||
# """ | ||
# Get warmup status of GPS as a sensor dict | ||
# """ | ||
# # gps_warmup = self.is_gps_enabled() and \ | ||
# # bool(self._clocking_auxbrd.get_gps_warmup()) | ||
# # return { | ||
# # 'name': 'gps_warmup', | ||
# # 'type': 'BOOLEAN', | ||
# # 'unit': 'warming up' if gps_warmup else 'warmup done', | ||
# # 'value': str(gps_warmup).lower(), | ||
# # } | ||
# return { | ||
# 'name': 'gps_warmup', | ||
# 'type': 'BOOLEAN', | ||
# 'unit': 'warmup done', | ||
# 'value': 'false', | ||
# } | ||
|
||
# def get_gps_survey_sensor(self): | ||
# """ | ||
# Get survey status of GPS as a sensor dict | ||
# """ | ||
# # gps_survey = self.is_gps_enabled() and \ | ||
# # bool(self._clocking_auxbrd.get_gps_survey()) | ||
# # return { | ||
# # 'name': 'gps_survey', | ||
# # 'type': 'BOOLEAN', | ||
# # 'unit': 'survey active' if gps_survey else 'survey not active', | ||
# # 'value': str(gps_survey).lower(), | ||
# # } | ||
# return { | ||
# 'name': 'gps_survey', | ||
# 'type': 'BOOLEAN', | ||
# 'unit': 'survey not active', | ||
# 'value': 'False', | ||
# } | ||
|
||
# def get_gps_phase_lock_sensor(self): | ||
# """ | ||
# Get phase_lock status of GPS as a sensor dict | ||
# """ | ||
# # gps_phase_lock = self.is_gps_enabled() and \ | ||
# # bool(self._clocking_auxbrd.get_gps_phase_lock()) | ||
# # return { | ||
# # 'name': 'gps_phase_lock', | ||
# # 'type': 'BOOLEAN', | ||
# # 'unit': 'phase locked' if gps_phase_lock else 'no phase lock', | ||
# # 'value': str(gps_phase_lock).lower(), | ||
# # } | ||
# return { | ||
# 'name': 'gps_phase_lock', | ||
# 'type': 'BOOLEAN', | ||
# 'unit': 'phase locked', | ||
# 'value': 'true' | ||
# } | ||
|
||
def get_gps_time_sensor(self): | ||
""" | ||
Get GPS time in integer seconds as a sensor dict | ||
""" | ||
if not self.is_gps_enabled(): | ||
return { | ||
'name': 'gps_time', | ||
'type': 'INTEGER', | ||
'unit': 'seconds', | ||
'value': str(-1), | ||
} | ||
return self._gpsd.get_gps_time_sensor() |