forked from Archive/PX4-Autopilot
drivers: Sagetech MXS transponder support
Co-authored-by: Megan McCormick <megan.mccormick@sagetech.com> Co-authored-by: Chuck Faber <chuck.faber@sagetech.com>
This commit is contained in:
parent
9d486b1ccd
commit
32544452f0
|
@ -16,7 +16,7 @@ class ModuleDocumentation(object):
|
||||||
valid_categories = ['driver', 'estimator', 'controller', 'system',
|
valid_categories = ['driver', 'estimator', 'controller', 'system',
|
||||||
'communication', 'command', 'template', 'simulation', 'autotune']
|
'communication', 'command', 'template', 'simulation', 'autotune']
|
||||||
valid_subcategories = ['', 'distance_sensor', 'imu', 'airspeed_sensor',
|
valid_subcategories = ['', 'distance_sensor', 'imu', 'airspeed_sensor',
|
||||||
'magnetometer', 'baro', 'optical_flow', 'rpm_sensor']
|
'magnetometer', 'baro', 'optical_flow', 'rpm_sensor', 'transponder']
|
||||||
|
|
||||||
max_line_length = 80 # wrap lines that are longer than this
|
max_line_length = 80 # wrap lines that are longer than this
|
||||||
|
|
||||||
|
|
|
@ -106,3 +106,4 @@ CONFIG_SYSTEMCMDS_USB_CONNECTED=y
|
||||||
CONFIG_SYSTEMCMDS_VER=y
|
CONFIG_SYSTEMCMDS_VER=y
|
||||||
CONFIG_SYSTEMCMDS_WORK_QUEUE=y
|
CONFIG_SYSTEMCMDS_WORK_QUEUE=y
|
||||||
CONFIG_EXAMPLES_FAKE_GPS=y
|
CONFIG_EXAMPLES_FAKE_GPS=y
|
||||||
|
#CONFIG_DRIVERS_TRANSPONDER_SAGETECH_MXS=y
|
||||||
|
|
|
@ -24,14 +24,13 @@ CONFIG_COMMON_LIGHT=y
|
||||||
CONFIG_COMMON_MAGNETOMETER=y
|
CONFIG_COMMON_MAGNETOMETER=y
|
||||||
CONFIG_COMMON_OPTICAL_FLOW=y
|
CONFIG_COMMON_OPTICAL_FLOW=y
|
||||||
CONFIG_DRIVERS_OSD=y
|
CONFIG_DRIVERS_OSD=y
|
||||||
CONFIG_DRIVERS_PCA9685=y
|
|
||||||
CONFIG_DRIVERS_PCA9685_PWM_OUT=y
|
CONFIG_DRIVERS_PCA9685_PWM_OUT=y
|
||||||
CONFIG_DRIVERS_POWER_MONITOR_INA226=y
|
CONFIG_DRIVERS_POWER_MONITOR_INA226=y
|
||||||
CONFIG_DRIVERS_PWM_INPUT=y
|
CONFIG_DRIVERS_PWM_INPUT=y
|
||||||
CONFIG_DRIVERS_PWM_OUT=y
|
CONFIG_DRIVERS_PWM_OUT=y
|
||||||
CONFIG_DRIVERS_PWM_OUT_SIM=y
|
CONFIG_DRIVERS_PWM_OUT_SIM=y
|
||||||
CONFIG_DRIVERS_PX4IO=y
|
CONFIG_DRIVERS_PX4IO=y
|
||||||
CONFIG_DRIVERS_ROBOCLAW=y
|
#CONFIG_DRIVERS_ROBOCLAW=y
|
||||||
CONFIG_DRIVERS_RPM=y
|
CONFIG_DRIVERS_RPM=y
|
||||||
CONFIG_DRIVERS_SMART_BATTERY_BATMON=y
|
CONFIG_DRIVERS_SMART_BATTERY_BATMON=y
|
||||||
CONFIG_COMMON_TELEMETRY=y
|
CONFIG_COMMON_TELEMETRY=y
|
||||||
|
@ -101,3 +100,4 @@ CONFIG_SYSTEMCMDS_UORB=y
|
||||||
CONFIG_SYSTEMCMDS_USB_CONNECTED=y
|
CONFIG_SYSTEMCMDS_USB_CONNECTED=y
|
||||||
CONFIG_SYSTEMCMDS_VER=y
|
CONFIG_SYSTEMCMDS_VER=y
|
||||||
CONFIG_SYSTEMCMDS_WORK_QUEUE=y
|
CONFIG_SYSTEMCMDS_WORK_QUEUE=y
|
||||||
|
CONFIG_DRIVERS_TRANSPONDER_SAGETECH_MXS=y
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
module_name: Sagtech MXS
|
||||||
|
serial_config:
|
||||||
|
- command: mxs start -d ${SERIAL_DEV} -b p:${BAUD_PARAM}
|
||||||
|
port_config_param:
|
||||||
|
name: TRANS_MXS_CFG
|
||||||
|
group: Transponders
|
|
@ -208,6 +208,8 @@
|
||||||
|
|
||||||
#define DRV_HYGRO_DEVTYPE_SHT3X 0xB1
|
#define DRV_HYGRO_DEVTYPE_SHT3X 0xB1
|
||||||
|
|
||||||
|
#define DRV_TRNS_DEVTYPE_MXS 0xB2
|
||||||
|
|
||||||
#define DRV_DEVTYPE_UNUSED 0xff
|
#define DRV_DEVTYPE_UNUSED 0xff
|
||||||
|
|
||||||
#endif /* _DRV_SENSOR_H */
|
#endif /* _DRV_SENSOR_H */
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022 PX4 Development Team. All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
# used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
add_subdirectory(sagetech_mxs)
|
|
@ -0,0 +1,10 @@
|
||||||
|
menu "Transponder"
|
||||||
|
menuconfig TRANSPONDER
|
||||||
|
bool "Transponder"
|
||||||
|
default n
|
||||||
|
select DRIVERS_TRANSPONDER_SAGETECH_MXS
|
||||||
|
---help---
|
||||||
|
Enable default set of transponder drivers
|
||||||
|
|
||||||
|
rsource "*/Kconfig"
|
||||||
|
endmenu #transponder
|
|
@ -0,0 +1,82 @@
|
||||||
|
############################################################################
|
||||||
|
#
|
||||||
|
# Copyright (c) 2022 PX4 Development Team. All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
#
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in
|
||||||
|
# the documentation and/or other materials provided with the
|
||||||
|
# distribution.
|
||||||
|
# 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
# used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
############################################################################
|
||||||
|
|
||||||
|
px4_add_module(
|
||||||
|
MODULE drivers__transponder__sagetech_mxs
|
||||||
|
MAIN sagetech_mxs
|
||||||
|
COMPILE_FLAGS
|
||||||
|
#-DDEBUG_BUILD # uncomment for PX4_DEBUG output
|
||||||
|
#-O0 # uncomment when debugging
|
||||||
|
SRCS
|
||||||
|
sg_sdk/appendChecksum.c
|
||||||
|
sg_sdk/float2Buf.c
|
||||||
|
sg_sdk/sgDecodeFlightId.c
|
||||||
|
sg_sdk/sgDecodeSVR.c
|
||||||
|
sg_sdk/sgEncodeGPS.c
|
||||||
|
sg_sdk/sgEncodeTargetReq.c
|
||||||
|
sg_sdk/target.c
|
||||||
|
sg_sdk/toGS.c
|
||||||
|
sg_sdk/toIcao.c
|
||||||
|
sg_sdk/toLatLon.c
|
||||||
|
sg_sdk/toUint32.c
|
||||||
|
sg_sdk/uint322Buf.c
|
||||||
|
sg_sdk/calcChecksum.c
|
||||||
|
sg_sdk/icao2Buf.c
|
||||||
|
sg_sdk/sgDecodeInstall.c
|
||||||
|
sg_sdk/sgEncodeDataReq.c
|
||||||
|
sg_sdk/sgEncodeInstall.c
|
||||||
|
sg_sdk/toHeading2.c
|
||||||
|
sg_sdk/toInt16.c
|
||||||
|
sg_sdk/toTOA.c
|
||||||
|
sg_sdk/toVel.c
|
||||||
|
sg_sdk/charArray2Buf.c
|
||||||
|
sg_sdk/sgDecodeAck.c
|
||||||
|
sg_sdk/sgDecodeMSR.c
|
||||||
|
sg_sdk/sgEncodeFlightId.c
|
||||||
|
sg_sdk/sgEncodeOperating.c
|
||||||
|
sg_sdk/toAlt.c
|
||||||
|
sg_sdk/toHeading.c
|
||||||
|
sg_sdk/toInt32.c
|
||||||
|
sg_sdk/toUint16.c
|
||||||
|
sg_sdk/uint162Buf.c
|
||||||
|
sg_sdk/sagetech_mxs.h
|
||||||
|
sg_sdk/sg.h
|
||||||
|
sg_sdk/target.h
|
||||||
|
sg_sdk/sgUtil.h
|
||||||
|
SagetechMXS.cpp
|
||||||
|
SagetechMXS.hpp
|
||||||
|
DEPENDS
|
||||||
|
px4_work_queue
|
||||||
|
MODULE_CONFIG
|
||||||
|
module.yaml
|
||||||
|
)
|
|
@ -0,0 +1,5 @@
|
||||||
|
menuconfig DRIVERS_TRANSPONDER_SAGETECH_MXS
|
||||||
|
bool "sagetech_mxs"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Enable support for my_work_item
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,279 @@
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 PX4 Development Team. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <px4_platform_common/defines.h>
|
||||||
|
#include <px4_platform_common/module.h>
|
||||||
|
#include <px4_platform_common/module_params.h>
|
||||||
|
#include <px4_platform_common/cli.h>
|
||||||
|
#include <px4_platform_common/getopt.h>
|
||||||
|
#include <px4_platform_common/posix.h>
|
||||||
|
#include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
|
||||||
|
#include <px4_platform_common/events.h>
|
||||||
|
#include <systemlib/mavlink_log.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <drivers/drv_hrt.h>
|
||||||
|
#include <lib/perf/perf_counter.h>
|
||||||
|
#include <drivers/device/device.h>
|
||||||
|
#include <lib/geo/geo.h>
|
||||||
|
#include <termios.h>
|
||||||
|
|
||||||
|
#include <uORB/Publication.hpp>
|
||||||
|
#include <uORB/Subscription.hpp>
|
||||||
|
#include <uORB/SubscriptionCallback.hpp>
|
||||||
|
#include <uORB/topics/sensor_gps.h>
|
||||||
|
#include <uORB/topics/transponder_report.h>
|
||||||
|
#include <uORB/topics/vehicle_land_detected.h>
|
||||||
|
|
||||||
|
#include <uORB/topics/parameter_update.h>
|
||||||
|
#include <uORB/topics/sensor_accel.h>
|
||||||
|
#include <uORB/topics/vehicle_status.h>
|
||||||
|
|
||||||
|
#include "sg_sdk/sagetech_mxs.h"
|
||||||
|
|
||||||
|
using namespace time_literals;
|
||||||
|
|
||||||
|
class SagetechMXS : public ModuleBase<SagetechMXS>, public ModuleParams, public px4::ScheduledWorkItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SagetechMXS(const char *port);
|
||||||
|
~SagetechMXS() override;
|
||||||
|
|
||||||
|
/** @see ModuleBase */
|
||||||
|
static int task_spawn(int argc, char *argv[]);
|
||||||
|
|
||||||
|
/** @see ModuleBase */
|
||||||
|
static int custom_command(int argc, char *argv[]);
|
||||||
|
|
||||||
|
/** @see ModuleBase */
|
||||||
|
static int print_usage(const char *reason = nullptr);
|
||||||
|
|
||||||
|
void print_info();
|
||||||
|
|
||||||
|
bool init();
|
||||||
|
|
||||||
|
int print_status() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Parameters
|
||||||
|
DEFINE_PARAMETERS(
|
||||||
|
(ParamInt<px4::params::ADSB_SQUAWK>) _adsb_squawk,
|
||||||
|
(ParamInt<px4::params::ADSB_IDENT>) _adsb_ident,
|
||||||
|
(ParamInt<px4::params::ADSB_LIST_MAX>) _adsb_list_max,
|
||||||
|
(ParamInt<px4::params::ADSB_ICAO_ID>) _adsb_icao,
|
||||||
|
(ParamInt<px4::params::ADSB_LEN_WIDTH>) _adsb_len_width,
|
||||||
|
(ParamInt<px4::params::ADSB_EMIT_TYPE>) _adsb_emit_type,
|
||||||
|
(ParamInt<px4::params::ADSB_MAX_SPEED>) _adsb_max_speed,
|
||||||
|
(ParamInt<px4::params::ADSB_ICAO_SPECL>) _adsb_icao_specl,
|
||||||
|
(ParamInt<px4::params::ADSB_EMERGC>) _adsb_emergc,
|
||||||
|
(ParamInt<px4::params::MXS_OP_MODE>) _mxs_op_mode,
|
||||||
|
(ParamInt<px4::params::MXS_TARG_PORT>) _mxs_targ_port,
|
||||||
|
// (ParamInt<px4::params::MXS_COM0_BAUD>) _mxs_com0_baud,
|
||||||
|
// (ParamInt<px4::params::MXS_COM1_BAUD>) _mxs_com1_baud,
|
||||||
|
(ParamInt<px4::params::MXS_EXT_CFG>) _mxs_ext_cfg,
|
||||||
|
(ParamInt<px4::params::SER_MXS_BAUD>) _ser_mxs_baud
|
||||||
|
);
|
||||||
|
|
||||||
|
// Serial Port Variables
|
||||||
|
char _port[20] {};
|
||||||
|
int _fd{-1};
|
||||||
|
|
||||||
|
// Publications
|
||||||
|
uORB::Publication<transponder_report_s> _transponder_report_pub{ORB_ID(transponder_report)};
|
||||||
|
orb_advert_t _mavlink_log_pub{nullptr};
|
||||||
|
|
||||||
|
|
||||||
|
// Subscriptions
|
||||||
|
uORB::Subscription _sensor_gps_sub{ORB_ID(sensor_gps)};
|
||||||
|
uORB::SubscriptionInterval _parameter_update_sub{ORB_ID(parameter_update), 1_s}; // subscription limited to 1 Hz updates
|
||||||
|
uORB::Subscription _vehicle_status_sub{ORB_ID(vehicle_status)}; // regular subscription for additional data
|
||||||
|
uORB::Subscription _transponder_report_sub{ORB_ID(transponder_report)};
|
||||||
|
uORB::Subscription _vehicle_land_detected_sub{ORB_ID(vehicle_land_detected)};
|
||||||
|
|
||||||
|
|
||||||
|
// Performance (perf) counters
|
||||||
|
perf_counter_t _loop_count_perf{perf_alloc(PC_COUNT, MODULE_NAME": run_loop")};
|
||||||
|
perf_counter_t _loop_elapsed_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": cycle")};
|
||||||
|
perf_counter_t _loop_interval_perf{perf_alloc(PC_INTERVAL, MODULE_NAME": interval")};
|
||||||
|
perf_counter_t _sample_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": read")};
|
||||||
|
perf_counter_t _comms_errors{perf_alloc(PC_COUNT, MODULE_NAME": com_err")};
|
||||||
|
|
||||||
|
// Constants
|
||||||
|
static constexpr uint32_t UPDATE_INTERVAL_US{1000000 / 50}; // 20ms = 50 Hz
|
||||||
|
static constexpr uint8_t FIVE_HZ_MOD{10}; // 0.2s = 5 Hz
|
||||||
|
static constexpr uint8_t TWO_HZ_MOD{25}; // 0.5s = 2 Hz
|
||||||
|
static constexpr uint8_t ONE_HZ_MOD{50}; // 1 Hz
|
||||||
|
static constexpr uint16_t EIGHT_TWO_SEC_MOD{410}; // 8.2 seconds
|
||||||
|
// static constexpr uint8_t SG_MSG_START_BYTE{0xAA};
|
||||||
|
static constexpr uint32_t PAYLOAD_MXS_MAX_SIZE{255};
|
||||||
|
static constexpr float SAGETECH_SCALE_FEET_TO_M{0.3048F};
|
||||||
|
static constexpr float SAGETECH_SCALE_KNOTS_TO_M_PER_SEC{0.514444F};
|
||||||
|
static constexpr float SAGETECH_SCALE_M_PER_SEC_TO_KNOTS{1.94384F};
|
||||||
|
static constexpr float SAGETECH_SCALE_FT_PER_MIN_TO_M_PER_SEC{0.00508F};
|
||||||
|
static constexpr float SAGETECH_SCALE_MM_TO_FT{0.00328084F};
|
||||||
|
static constexpr float SAGETECH_SCALE_M_PER_SEC_TO_FT_PER_MIN{196.85F};
|
||||||
|
static constexpr uint8_t ADSB_ALTITUDE_TYPE_PRESSURE_QNH{0};
|
||||||
|
static constexpr uint8_t ADSB_ALTITUDE_TYPE_GEOMETRIC{1};
|
||||||
|
static constexpr uint16_t MAX_VEHICLES_LIMIT{50};
|
||||||
|
static constexpr float SAGETECH_HPL_UNKNOWN{38000.0F};
|
||||||
|
static constexpr float CLIMB_RATE_LIMIT{16448};
|
||||||
|
static constexpr uint16_t MXS_INIT_TIMEOUT_COUNT{1000}; // 1000 loop cycles = 20 seconds
|
||||||
|
static constexpr uint8_t BASE_OCTAL{8};
|
||||||
|
static constexpr uint8_t BASE_HEX{16};
|
||||||
|
static constexpr uint8_t BASE_DEC{10};
|
||||||
|
static constexpr uint16_t INVALID_SQUAWK{7777};
|
||||||
|
static constexpr unsigned BAUD_460800{0010004}; // B460800 not defined in MacOS termios
|
||||||
|
static constexpr unsigned BAUD_921600{0010007}; // B921600 not defined in MacOS termios
|
||||||
|
|
||||||
|
// Stored variables
|
||||||
|
uint64_t _loop_count;
|
||||||
|
|
||||||
|
// Cached Subscription Data
|
||||||
|
sensor_gps_s _gps;
|
||||||
|
vehicle_land_detected_s _landed;
|
||||||
|
|
||||||
|
enum class MsgType : uint8_t {
|
||||||
|
Installation = SG_MSG_TYPE_HOST_INSTALL,
|
||||||
|
FlightID = SG_MSG_TYPE_HOST_FLIGHT,
|
||||||
|
Operating = SG_MSG_TYPE_HOST_OPMSG,
|
||||||
|
GPS_Data = SG_MSG_TYPE_HOST_GPS,
|
||||||
|
Data_Request = SG_MSG_TYPE_HOST_DATAREQ,
|
||||||
|
// RESERVED 0x06 - 0x0A
|
||||||
|
Target_Request = SG_MSG_TYPE_HOST_TARGETREQ,
|
||||||
|
Mode = SG_MSG_TYPE_HOST_MODE,
|
||||||
|
// RESERVED 0x0D - 0xC1
|
||||||
|
ACK = SG_MSG_TYPE_XPNDR_ACK,
|
||||||
|
Installation_Response = SG_MSG_TYPE_XPNDR_INSTALL,
|
||||||
|
FlightID_Response = SG_MSG_TYPE_XPNDR_FLIGHT,
|
||||||
|
Status_Response = SG_MSG_TYPE_XPNDR_STATUS,
|
||||||
|
RESERVED_0x84 = 0x84,
|
||||||
|
RESERVED_0x85 = 0x85,
|
||||||
|
Mode_Settings = SG_MSG_TYPE_XPNDR_MODE,
|
||||||
|
RESERVED_0x8D = 0x8D,
|
||||||
|
Version_Response = SG_MSG_TYPE_XPNDR_VERSION,
|
||||||
|
Serial_Number_Response = SG_MSG_TYPE_XPNDR_SERIALNUM,
|
||||||
|
Target_Summary_Report = SG_MSG_TYPE_ADSB_TSUMMARY,
|
||||||
|
|
||||||
|
ADSB_StateVector_Report = SG_MSG_TYPE_ADSB_SVR,
|
||||||
|
ADSB_ModeStatus_Report = SG_MSG_TYPE_ADSB_MSR,
|
||||||
|
ADSB_Target_State_Report = SG_MSG_TYPE_ADSB_TSTATE,
|
||||||
|
ADSB_Air_Ref_Vel_Report = SG_MSG_TYPE_ADSB_ARVR,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ParseState {
|
||||||
|
WaitingFor_Start,
|
||||||
|
WaitingFor_MsgType,
|
||||||
|
WaitingFor_MsgId,
|
||||||
|
WaitingFor_PayloadLen,
|
||||||
|
WaitingFor_PayloadContents,
|
||||||
|
WaitingFor_Checksum,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed)) Packet {
|
||||||
|
const uint8_t start = SG_MSG_START_BYTE;
|
||||||
|
MsgType type;
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t payload_length;
|
||||||
|
uint8_t payload[PAYLOAD_MXS_MAX_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
ParseState state;
|
||||||
|
uint8_t index;
|
||||||
|
Packet packet;
|
||||||
|
uint8_t checksum;
|
||||||
|
} _message_in;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
bool initialized;
|
||||||
|
bool init_failed;
|
||||||
|
sg_operating_t op;
|
||||||
|
sg_install_t inst;
|
||||||
|
// sg_gps_t gps;
|
||||||
|
sg_targetreq_t treq;
|
||||||
|
sg_flightid_t fid;
|
||||||
|
sg_ack_t ack;
|
||||||
|
} mxs_state;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
// cached variables to compare against params so we can send msg on param change.
|
||||||
|
bool failXpdr;
|
||||||
|
bool failSystem;
|
||||||
|
struct {
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t type;
|
||||||
|
} msg;
|
||||||
|
} last;
|
||||||
|
|
||||||
|
// External Vehicle List
|
||||||
|
transponder_report_s *vehicle_list;
|
||||||
|
uint16_t list_size_allocated;
|
||||||
|
uint16_t vehicle_count = 0;
|
||||||
|
uint16_t furthest_vehicle_index = 0;
|
||||||
|
float furthest_vehicle_distance = 0;
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
void Run() override;
|
||||||
|
void handle_packet(const Packet &msg);
|
||||||
|
int msg_write(const uint8_t *data, const uint16_t len) const;
|
||||||
|
bool parse_byte(const uint8_t data);
|
||||||
|
void handle_ack(const sg_ack_t ack);
|
||||||
|
void handle_svr(const sg_svr_t svr);
|
||||||
|
void handle_msr(sg_msr_t msr);
|
||||||
|
bool get_vehicle_by_ICAO(const uint32_t icao, transponder_report_s &vehicle) const;
|
||||||
|
bool find_index(const transponder_report_s &vehicle, uint16_t *index) const;
|
||||||
|
void set_vehicle(const uint16_t index, const transponder_report_s &vehicle);
|
||||||
|
void delete_vehicle(const uint16_t index);
|
||||||
|
bool is_special_vehicle(uint32_t icao) const {return _adsb_icao_specl.get() != 0 && (_adsb_icao_specl.get() == (int32_t) icao);}
|
||||||
|
void handle_vehicle(const transponder_report_s &vehicle);
|
||||||
|
void determine_furthest_aircraft();
|
||||||
|
void send_data_req(const sg_datatype_t dataReqType);
|
||||||
|
void send_install_msg();
|
||||||
|
void send_flight_id_msg();
|
||||||
|
void send_operating_msg();
|
||||||
|
void send_gps_msg();
|
||||||
|
void send_targetreq_msg();
|
||||||
|
uint32_t convert_base_to_decimal(const uint8_t baseIn, uint32_t inputNumber);
|
||||||
|
int open_serial_port();
|
||||||
|
sg_emitter_t convert_emitter_type_to_sg(int emitType);
|
||||||
|
int convert_sg_to_emitter_type(sg_emitter_t sg_emit);
|
||||||
|
int handle_fid(const char *fid);
|
||||||
|
int store_inst_resp();
|
||||||
|
void auto_config_operating();
|
||||||
|
void auto_config_installation();
|
||||||
|
void auto_config_flightid();
|
||||||
|
unsigned convert_to_px4_baud(int baudType);
|
||||||
|
bool check_valid_squawk(int squawk);
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
module_name: Sagetech MXS
|
||||||
|
serial_config:
|
||||||
|
- command: sagetech_mxs start -d ${SERIAL_DEV}
|
||||||
|
port_config_param:
|
||||||
|
name: MXS_SER_CFG
|
||||||
|
group: Transponder
|
||||||
|
default: TEL2
|
||||||
|
label: Sagetech MXS Serial Port
|
|
@ -0,0 +1,269 @@
|
||||||
|
/****************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2022 PX4 Development Team. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in
|
||||||
|
* the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* 3. Neither the name PX4 nor the names of its contributors may be
|
||||||
|
* used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||||
|
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||||
|
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* parameters.c
|
||||||
|
*
|
||||||
|
* Sagetech MXS transponder custom parameters
|
||||||
|
* @author Megan McCormick megan.mccormick@sagetech.com
|
||||||
|
* @author Check Faber chuck.faber@sagetech.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ADSB-Out squawk code configuration
|
||||||
|
*
|
||||||
|
* This parameter defines the squawk code. Value should be between 0000 and 7777.
|
||||||
|
*
|
||||||
|
* @reboot_required false
|
||||||
|
* @min 0
|
||||||
|
* @max 7777
|
||||||
|
* @group Transponder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(ADSB_SQUAWK, 1200);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ADSB-Out Ident Configuration
|
||||||
|
*
|
||||||
|
* Enable Identification of Position feature
|
||||||
|
*
|
||||||
|
* @boolean
|
||||||
|
* @reboot_required false
|
||||||
|
* @group Transponder
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(ADSB_IDENT, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ADSB-In Vehicle List Size
|
||||||
|
*
|
||||||
|
* Change number of targets to track
|
||||||
|
*
|
||||||
|
* @min 0
|
||||||
|
* @max 50
|
||||||
|
* @reboot_required true
|
||||||
|
* @group Transponder
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(ADSB_LIST_MAX, 25);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ADSB-Out ICAO configuration
|
||||||
|
*
|
||||||
|
* Defines the ICAO ID of the vehicle
|
||||||
|
*
|
||||||
|
* @reboot_required true
|
||||||
|
* @min -1
|
||||||
|
* @max 16777215
|
||||||
|
* @group Transponder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(ADSB_ICAO_ID, 1194684);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ADSB-Out Vehicle Size Configuration
|
||||||
|
*
|
||||||
|
* Report the length and width of the vehicle in meters. In most cases, use '1' for the smallest vehicle size.
|
||||||
|
*
|
||||||
|
* @reboot_required true
|
||||||
|
* @min 0
|
||||||
|
* @max 15
|
||||||
|
* @group Transponder
|
||||||
|
*
|
||||||
|
* @value 0 SizeUnknown
|
||||||
|
* @value 1 Len15_Wid23
|
||||||
|
* @value 2 Len25_Wid28
|
||||||
|
* @value 3 Len25_Wid34
|
||||||
|
* @value 4 Len35_Wid33
|
||||||
|
* @value 5 Len35_Wid38
|
||||||
|
* @value 6 Len45_Wid39
|
||||||
|
* @value 7 Len45_Wid45
|
||||||
|
* @value 8 Len55_Wid45
|
||||||
|
* @value 9 Len55_Wid52
|
||||||
|
* @value 10 Len65_Wid59
|
||||||
|
* @value 11 Len65_Wid67
|
||||||
|
* @value 12 Len75_Wid72
|
||||||
|
* @value 13 Len75_Wid80
|
||||||
|
* @value 14 Len85_Wid80
|
||||||
|
* @value 15 Len85_Wid90
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(ADSB_LEN_WIDTH, 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ADSB-Out Vehicle Emitter Type
|
||||||
|
*
|
||||||
|
* Configure the emitter type of the vehicle.
|
||||||
|
*
|
||||||
|
* @reboot_required true
|
||||||
|
* @min 0
|
||||||
|
* @max 15
|
||||||
|
* @group Transponder
|
||||||
|
*
|
||||||
|
* @value 0 Unknown
|
||||||
|
* @value 1 Light
|
||||||
|
* @value 2 Small
|
||||||
|
* @value 3 Large
|
||||||
|
* @value 4 HighVortex
|
||||||
|
* @value 5 Heavy
|
||||||
|
* @value 6 Performance
|
||||||
|
* @value 7 Rotorcraft
|
||||||
|
* @value 8 RESERVED
|
||||||
|
* @value 9 Glider
|
||||||
|
* @value 10 LightAir
|
||||||
|
* @value 11 Parachute
|
||||||
|
* @value 12 UltraLight
|
||||||
|
* @value 13 RESERVED
|
||||||
|
* @value 14 UAV
|
||||||
|
* @value 15 Space
|
||||||
|
* @value 16 RESERVED
|
||||||
|
* @value 17 EmergencySurf
|
||||||
|
* @value 18 ServiceSurf
|
||||||
|
* @value 19 PointObstacle
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(ADSB_EMIT_TYPE, 14);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ADSB-Out Vehicle Max Speed
|
||||||
|
*
|
||||||
|
* Informs ADSB vehicles of this vehicle's max speed capability
|
||||||
|
*
|
||||||
|
* @reboot_required true
|
||||||
|
* @min 0
|
||||||
|
* @max 6
|
||||||
|
* @value 0 UnknownMaxSpeed
|
||||||
|
* @value 1 75Kts
|
||||||
|
* @value 2 150Kts
|
||||||
|
* @value 3 300Kts
|
||||||
|
* @value 4 600Kts
|
||||||
|
* @value 5 1200Kts
|
||||||
|
* @value 6 Over1200Kts
|
||||||
|
* @group Transponder
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(ADSB_MAX_SPEED, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ADSB-In Special ICAO configuration
|
||||||
|
*
|
||||||
|
* This vehicle is always tracked. Use 0 to disable.
|
||||||
|
*
|
||||||
|
* @reboot_required false
|
||||||
|
* @min 0
|
||||||
|
* @max 16777215
|
||||||
|
* @group Transponder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(ADSB_ICAO_SPECL, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ADSB-Out Emergency State
|
||||||
|
*
|
||||||
|
* Sets the vehicle emergency state
|
||||||
|
*
|
||||||
|
* @reboot_required false
|
||||||
|
* @min 0
|
||||||
|
* @max 6
|
||||||
|
* @value 0 NoEmergency
|
||||||
|
* @value 1 General
|
||||||
|
* @value 2 Medical
|
||||||
|
* @value 3 LowFuel
|
||||||
|
* @value 4 NoCommunications
|
||||||
|
* @value 5 Interference
|
||||||
|
* @value 6 Downed
|
||||||
|
* @group Transponder
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(ADSB_EMERGC, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sagetech MXS mode configuration
|
||||||
|
*
|
||||||
|
* This parameter defines the operating mode of the MXS
|
||||||
|
*
|
||||||
|
* @reboot_required false
|
||||||
|
* @min 0
|
||||||
|
* @max 3
|
||||||
|
* @group Transponder
|
||||||
|
*
|
||||||
|
* @value 0 Off
|
||||||
|
* @value 1 On
|
||||||
|
* @value 2 Standby
|
||||||
|
* @value 3 Alt
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(MXS_OP_MODE, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sagetech MXS Participant Configuration
|
||||||
|
*
|
||||||
|
* The MXS communication port to receive Target data from
|
||||||
|
*
|
||||||
|
* @min 0
|
||||||
|
* @max 2
|
||||||
|
* @reboot_required false
|
||||||
|
* @group Transponder
|
||||||
|
*
|
||||||
|
* @value 0 Auto
|
||||||
|
* @value 1 COM0
|
||||||
|
* @value 2 COM1
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(MXS_TARG_PORT, 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sagetech External Configuration Mode
|
||||||
|
*
|
||||||
|
* Disables auto-configuration mode enabling MXS config through external software.
|
||||||
|
*
|
||||||
|
* @reboot_required true
|
||||||
|
* @boolean
|
||||||
|
* @group Transponder
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(MXS_EXT_CFG, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MXS Serial Communication Baud rate
|
||||||
|
*
|
||||||
|
* Baudrate for the Serial Port connected to the MXS Transponder
|
||||||
|
*
|
||||||
|
* @reboot_required true
|
||||||
|
* @min 0
|
||||||
|
* @max 10
|
||||||
|
* @value 0 38400
|
||||||
|
* @value 1 600
|
||||||
|
* @value 2 4800
|
||||||
|
* @value 3 9600
|
||||||
|
* @value 4 RESERVED
|
||||||
|
* @value 5 57600
|
||||||
|
* @value 6 115200
|
||||||
|
* @value 7 230400
|
||||||
|
* @value 8 19200
|
||||||
|
* @value 9 460800
|
||||||
|
* @value 10 921600
|
||||||
|
* @group Serial
|
||||||
|
*/
|
||||||
|
PARAM_DEFINE_INT32(SER_MXS_BAUD, 5);
|
|
@ -0,0 +1,201 @@
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
|
@ -0,0 +1,6 @@
|
||||||
|
# Sagetech SDK
|
||||||
|
The contents of this folder includes selected functions from the full Sagetech SDK which can be found here:
|
||||||
|
https://github.com/Sagetech-Avionics/sagetech-mxs-sdk
|
||||||
|
|
||||||
|
## Links
|
||||||
|
[Host Interface Control Document for MXS](https://github.com/Sagetech-Avionics/sagetech-mxs-sdk/blob/main/doc/pdf/ICD02373_MXS_Host_ICD.pdf)
|
|
@ -0,0 +1,19 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file appendChecksum.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file
|
||||||
|
*/
|
||||||
|
void appendChecksum(uint8_t *buffer, uint8_t len)
|
||||||
|
{
|
||||||
|
buffer[len - 1] = calcChecksum(buffer, len);
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file calcChecksum.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file
|
||||||
|
*/
|
||||||
|
uint8_t calcChecksum(uint8_t *buffer, uint8_t len)
|
||||||
|
{
|
||||||
|
uint8_t sum = 0x00;
|
||||||
|
|
||||||
|
// Add all bytes excluding checksum
|
||||||
|
for (uint8_t i = 0; i < len - 1; ++i) {
|
||||||
|
sum += buffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file charArray2Buf.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
void charArray2Buf(uint8_t *bufferPos, char arr[], uint8_t len)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < len; ++i) {
|
||||||
|
bufferPos[i] = toupper(arr[i]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file float2Buf.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
void float2Buf(uint8_t *bufferPos, float value)
|
||||||
|
{
|
||||||
|
const uint16_t FLOAT_SIZE = 4;
|
||||||
|
|
||||||
|
union {
|
||||||
|
float val;
|
||||||
|
unsigned char bytes[FLOAT_SIZE];
|
||||||
|
} conversion;
|
||||||
|
|
||||||
|
conversion.val = value;
|
||||||
|
|
||||||
|
for (int i = 0; i < FLOAT_SIZE; ++i) {
|
||||||
|
bufferPos[i] = conversion.bytes[i];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file icao2Buf.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
void icao2Buf(uint8_t *bufferPos, uint32_t icao)
|
||||||
|
{
|
||||||
|
bufferPos[0] = (icao & 0x00FF0000) >> 16;
|
||||||
|
bufferPos[1] = (icao & 0x0000FF00) >> 8;
|
||||||
|
bufferPos[2] = (icao & 0x000000FF);
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "sg.h"
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,899 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file sg.h
|
||||||
|
* @author jimb
|
||||||
|
*
|
||||||
|
* @date Feb 10, 2021
|
||||||
|
*
|
||||||
|
* Sagetech protocol for host message building and parsing.
|
||||||
|
*
|
||||||
|
* This module performs both the following:
|
||||||
|
* 1. Parses raw Sagetech host messages defined in the SDIM and
|
||||||
|
* returns a populated struct dataset of the message type.
|
||||||
|
* 2. Receives a populated struct dataset of the desired host message
|
||||||
|
* and returns the corresponding raw message data buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SG_H
|
||||||
|
#define SG_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/// Host Message Lengths (bytes)
|
||||||
|
#define SG_MSG_LEN_INSTALL 41
|
||||||
|
#define SG_MSG_LEN_FLIGHT 17
|
||||||
|
#define SG_MSG_LEN_OPMSG 17
|
||||||
|
#define SG_MSG_LEN_GPS 68
|
||||||
|
#define SG_MSG_LEN_DATAREQ 9
|
||||||
|
#define SG_MSG_LEN_TARGETREQ 12
|
||||||
|
#define SG_MSG_LEN_MODE 10
|
||||||
|
|
||||||
|
/// Host Message Types
|
||||||
|
#define SG_MSG_TYPE_HOST_INSTALL 0x01
|
||||||
|
#define SG_MSG_TYPE_HOST_FLIGHT 0x02
|
||||||
|
#define SG_MSG_TYPE_HOST_OPMSG 0x03
|
||||||
|
#define SG_MSG_TYPE_HOST_GPS 0x04
|
||||||
|
#define SG_MSG_TYPE_HOST_DATAREQ 0x05
|
||||||
|
#define SG_MSG_TYPE_HOST_TARGETREQ 0x0B
|
||||||
|
#define SG_MSG_TYPE_HOST_MODE 0x0C
|
||||||
|
|
||||||
|
/// XPNDR Message Types
|
||||||
|
#define SG_MSG_TYPE_XPNDR_ACK 0x80
|
||||||
|
#define SG_MSG_TYPE_XPNDR_INSTALL 0x81
|
||||||
|
#define SG_MSG_TYPE_XPNDR_FLIGHT 0x82
|
||||||
|
#define SG_MSG_TYPE_XPNDR_STATUS 0x83
|
||||||
|
#define SG_MSG_TYPE_XPNDR_COMMA 0x85
|
||||||
|
#define SG_MSG_TYPE_XPNDR_MODE 0x8C
|
||||||
|
#define SG_MSG_TYPE_XPNDR_VERSION 0x8E
|
||||||
|
#define SG_MSG_TYPE_XPNDR_SERIALNUM 0x8F
|
||||||
|
|
||||||
|
/// ADS-B Message Types
|
||||||
|
#define SG_MSG_TYPE_ADSB_TSUMMARY 0x90
|
||||||
|
#define SG_MSG_TYPE_ADSB_SVR 0x91
|
||||||
|
#define SG_MSG_TYPE_ADSB_MSR 0x92
|
||||||
|
#define SG_MSG_TYPE_ADSB_TSTATE 0x97
|
||||||
|
#define SG_MSG_TYPE_ADSB_ARVR 0x98
|
||||||
|
|
||||||
|
/// Start byte for all host messages
|
||||||
|
#define SG_MSG_START_BYTE 0xAA
|
||||||
|
|
||||||
|
/// Emitter category set byte values
|
||||||
|
#define SG_EMIT_GROUP_A 0x00
|
||||||
|
#define SG_EMIT_GROUP_B 0x01
|
||||||
|
#define SG_EMIT_GROUP_C 0x02
|
||||||
|
#define SG_EMIT_GROUP_D 0x03
|
||||||
|
|
||||||
|
/// Emitter category enumeration offsets
|
||||||
|
#define SG_EMIT_OFFSET_A 0x00
|
||||||
|
#define SG_EMIT_OFFSET_B 0x10
|
||||||
|
#define SG_EMIT_OFFSET_C 0x20
|
||||||
|
#define SG_EMIT_OFFSET_D 0x30
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available COM port baud rates.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
baud38400 = 0,
|
||||||
|
baud600,
|
||||||
|
baud4800,
|
||||||
|
baud9600,
|
||||||
|
baud28800,
|
||||||
|
baud57600,
|
||||||
|
baud115200,
|
||||||
|
baud230400,
|
||||||
|
baud19200,
|
||||||
|
baud460800,
|
||||||
|
baud921600
|
||||||
|
} sg_baud_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transponder ethernet configuration
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t ipAddress; /// The transponder ip address
|
||||||
|
uint32_t subnetMask; /// The transponder subnet mask
|
||||||
|
uint16_t portNumber; /// The transponder port number
|
||||||
|
} sg_ethernet_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available GPS integrity SIL values
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
silUnknown = 0,
|
||||||
|
silLow,
|
||||||
|
silMedium,
|
||||||
|
silHigh
|
||||||
|
} sg_sil_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available GPS integrity SDA values
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
sdaUnknown = 0,
|
||||||
|
sdaMinor,
|
||||||
|
sdaMajor,
|
||||||
|
sdaHazardous
|
||||||
|
} sg_sda_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available emitter types
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
aUnknown = SG_EMIT_OFFSET_A,
|
||||||
|
aLight,
|
||||||
|
aSmall,
|
||||||
|
aLarge,
|
||||||
|
aHighVortex,
|
||||||
|
aHeavy,
|
||||||
|
aPerformance,
|
||||||
|
aRotorCraft,
|
||||||
|
bUnknown = SG_EMIT_OFFSET_B,
|
||||||
|
bGlider,
|
||||||
|
bAir,
|
||||||
|
bParachutist,
|
||||||
|
bUltralight,
|
||||||
|
bUAV = SG_EMIT_OFFSET_B + 6,
|
||||||
|
bSpace,
|
||||||
|
cUnknown = SG_EMIT_OFFSET_C,
|
||||||
|
cEmergency,
|
||||||
|
cService,
|
||||||
|
cPoint,
|
||||||
|
cCluster,
|
||||||
|
cLine,
|
||||||
|
dUnknown = SG_EMIT_OFFSET_D
|
||||||
|
} sg_emitter_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available aircraft sizes in meters
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
sizeUnknown = 0, /// Dimensions unknown
|
||||||
|
sizeL15W23, /// Length <= 15m & Width <= 23m
|
||||||
|
sizeL25W28, /// Length <= 25m & Width <= 28.5m
|
||||||
|
sizeL25W34, /// Length <= 25m & Width <= 34m
|
||||||
|
sizeL35W33, /// Length <= 35m & Width <= 33m
|
||||||
|
sizeL35W38, /// Length <= 35m & Width <= 38m
|
||||||
|
sizeL45W39, /// Length <= 45m & Width <= 39.5m
|
||||||
|
sizeL45W45, /// Length <= 45m & Width <= 45m
|
||||||
|
sizeL55W45, /// Length <= 55m & Width <= 45m
|
||||||
|
sizeL55W52, /// Length <= 55m & Width <= 52m
|
||||||
|
sizeL65W59, /// Length <= 65m & Width <= 59.5m
|
||||||
|
sizeL65W67, /// Length <= 65m & Width <= 67m
|
||||||
|
sizeL75W72, /// Length <= 75m & Width <= 72.5m
|
||||||
|
sizeL75W80, /// Length <= 75m & Width <= 80m
|
||||||
|
sizeL85W80, /// Length <= 85m & Width <= 80m
|
||||||
|
sizeL85W90 /// Length <= 85m & Width <= 90m
|
||||||
|
} sg_size_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available aircraft maximum airspeeds
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
speedUnknown = 0, /// Max speed unknown
|
||||||
|
speed75kt, /// 0 knots < Max speed < 75 knots
|
||||||
|
speed150kt, /// 75 knots < Max speed < 150 knots
|
||||||
|
speed300kt, /// 150 knots < Max speed < 300 knots
|
||||||
|
speed600kt, /// 300 knots < Max speed < 600 knots
|
||||||
|
speed1200kt, /// 600 knots < Max speed < 1200 knots
|
||||||
|
speedGreater /// 1200 knots < Max speed
|
||||||
|
} sg_airspeed_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available antenna configurations
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
antBottom = 1, /// bottom antenna only
|
||||||
|
antBoth = 3 /// both top and bottom antennae
|
||||||
|
} sg_antenna_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XPNDR Installation Message.
|
||||||
|
* Host --> XPNDR.
|
||||||
|
* XPNDR --> Host.
|
||||||
|
* Use 'strcpy(install.reg, "REGVAL1")' to assign the registration.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t icao; /// The aircraft's ICAO address
|
||||||
|
char reg[8]; /// The aircraft's registration (left-justified alphanumeric characters padded with spaces)
|
||||||
|
sg_baud_t com0; /// The baud rate for COM Port 0
|
||||||
|
sg_baud_t com1; /// The baud rate for COM Port 1
|
||||||
|
sg_ethernet_t eth; /// The ethernet configuration
|
||||||
|
sg_sil_t sil; /// The gps integrity SIL parameter
|
||||||
|
sg_sda_t sda; /// The gps integrity SDA parameter
|
||||||
|
sg_emitter_t emitter; /// The platform's emitter type
|
||||||
|
sg_size_t size; /// The platform's dimensions
|
||||||
|
sg_airspeed_t maxSpeed; /// The platform's maximum airspeed
|
||||||
|
int16_t altOffset; /// The altitude encoder offset is a legacy field that should always = 0
|
||||||
|
sg_antenna_t antenna; /// The antenna configuration
|
||||||
|
bool altRes100; /// Altitude resolution. true = 100 foot, false = 25 foot
|
||||||
|
bool hdgTrueNorth; /// Heading type. true = true north, false = magnetic north
|
||||||
|
bool airspeedTrue; /// Airspeed type. true = true speed, false = indicated speed
|
||||||
|
bool heater; /// true = heater enabled, false = heater disabled
|
||||||
|
bool wowConnected; /// Weight on Wheels sensor. true = connected, false = not connected
|
||||||
|
} sg_install_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XPNDR Flight ID Message.
|
||||||
|
* Host --> XPNDR.
|
||||||
|
* XPNDR --> Host.
|
||||||
|
* * Use 'strcpy(id.flightID, "FLIGHTNO")' to assign the flight identification.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
char flightId[9]; /// The flight identification (left-justified alphanumeric characters padded with spaces)
|
||||||
|
} sg_flightid_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available transponder operating modes. The enumerated values are
|
||||||
|
* offset from the host message protocol values.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
modeOff = 0, /// 'Off' Mode: Xpdr will not transmit
|
||||||
|
modeOn, /// 'On' Mode: Full functionality with Altitude = Invalid
|
||||||
|
modeStby, /// 'Standby' Mode: Reply to lethal interrogations, only
|
||||||
|
modeAlt /// 'Alt' Mode: Full functionality
|
||||||
|
} sg_op_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available emergency status codes.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
emergcNone = 0, /// No Emergency
|
||||||
|
emergcGeneral, /// General Emergency
|
||||||
|
emergcMed, /// Lifeguard/Medical Emergency
|
||||||
|
emergcFuel, /// Minimum Fuel
|
||||||
|
emergcComm, /// No Communications
|
||||||
|
emergcIntrfrc, /// Unlawful Interference
|
||||||
|
emergcDowned /// Downed Aircraft
|
||||||
|
} sg_emergc_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XPNDR Operating Message.
|
||||||
|
* Host --> XPNDR.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint16_t squawk; /// 4-digit octal Mode A code
|
||||||
|
sg_op_mode_t opMode; /// Operational mode
|
||||||
|
bool savePowerUp; /// Save power-up state in non-volatile
|
||||||
|
bool enableSqt; /// Enable extended squitters
|
||||||
|
bool enableXBit; /// Enable the x-bit
|
||||||
|
bool milEmergency; /// Broadcast a military emergency
|
||||||
|
sg_emergc_t emergcType; /// Enumerated civilian emergency type
|
||||||
|
bool identOn; /// Set the identification switch = On
|
||||||
|
bool altUseIntrnl; /// True = Report altitude from internal pressure sensor (will ignore other bits in the field)
|
||||||
|
bool altHostAvlbl; /// True = Host Altitude is being provided
|
||||||
|
bool altRes25; /// Host Altitude Resolution from install message, True = 25 ft, False = 100 ft
|
||||||
|
int32_t altitude; /// Sea-level altitude in feet. Field is ignored when internal altitude is selected.
|
||||||
|
bool climbValid; /// Climb rate is provided;
|
||||||
|
int16_t climbRate; /// Climb rate in ft/min. Limits are +/- 16,448 ft/min.
|
||||||
|
bool headingValid; /// Heading is valid.
|
||||||
|
double heading; /// Heading in degrees
|
||||||
|
bool airspdValid; /// Airspeed is valid.
|
||||||
|
uint16_t airspd; /// Airspeed in knots.
|
||||||
|
} sg_operating_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Avaiable NACp values.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
nacpUnknown, /// >= 18.52 km ( 10 nmile)
|
||||||
|
nacp10dot0, /// < 18.52 km ( 10 nmile)
|
||||||
|
nacp4dot0, /// < 7.408 km ( 4 nmile)
|
||||||
|
nacp2dot0, /// < 3.704 km ( 2 nmile)
|
||||||
|
nacp1dot0, /// < 1.852 km ( 1 nmile)
|
||||||
|
nacp0dot5, /// < 0.926 km (0.5 nmile)
|
||||||
|
nacp0dot3, /// < 0.556 km (0.3 nmile)
|
||||||
|
nacp0dot1, /// < 0.185 km (0.1 nmile)
|
||||||
|
nacp0dot05, /// < 92.6 m (0.05 nmile)
|
||||||
|
nacp30, /// < 30.0 m
|
||||||
|
nacp10, /// < 10.0 m
|
||||||
|
nacp3 /// < 3.0 m
|
||||||
|
} sg_nacp_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available NACv values (m/s)
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
nacvUnknown = 0, /// 10 <= NACv (or NACv is unknown)
|
||||||
|
nacv10dot0, /// 3 <= NACv < 10
|
||||||
|
nacv3dot0, /// 1 <= NACv < 3
|
||||||
|
nacv1dot0, /// 0.3 <= NACv < 1
|
||||||
|
nacv0dot3 /// 0.0 <= NACv < 0.3
|
||||||
|
} sg_nacv_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XPNDR Simulated GPS Message.
|
||||||
|
* Host --> XPNDR.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
char longitude[12]; /// The absolute value of longitude (degree and decimal minute)
|
||||||
|
char latitude[11]; /// The absolute value of latitude (degree and decimal minute)
|
||||||
|
char grdSpeed[7]; /// The GPS over-ground speed (knots)
|
||||||
|
char grdTrack[9]; /// The GPS track referenced from True North (degrees, clockwise)
|
||||||
|
bool latNorth; /// The aircraft is in the northern hemisphere
|
||||||
|
bool lngEast; /// The aircraft is in the eastern hemisphere
|
||||||
|
bool fdeFail; /// True = A satellite error has occurred
|
||||||
|
bool gpsValid; /// True = GPS data is valid
|
||||||
|
char timeOfFix[11]; /// Time, relative to midnight UTC (can optionally be filled spaces)
|
||||||
|
float height; /// The height above the WGS-84 ellipsoid (meters)
|
||||||
|
float hpl; /// The Horizontal Protection Limit (meters)
|
||||||
|
float hfom; /// The Horizontal Figure of Merit (meters)
|
||||||
|
float vfom; /// The Vertical Figure of Merit (meters)
|
||||||
|
sg_nacv_t nacv; /// Navigation Accuracy for Velocity (meters/second)
|
||||||
|
} sg_gps_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available data request types
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
dataInstall = 0x81, /// Installation data
|
||||||
|
dataFlightID = 0x82, /// Flight Identification data
|
||||||
|
dataStatus = 0x83, /// Status Response data
|
||||||
|
dataMode = 0x8C, /// Mode Settings data
|
||||||
|
dataHealth = 0x8D, /// Health Monitor data
|
||||||
|
dataVersion = 0x8E, /// Version data
|
||||||
|
dataSerialNum = 0x8F, /// Serial Number data
|
||||||
|
dataTOD = 0xD2, /// Time of Day data
|
||||||
|
dataMode5 = 0xD3, /// Mode 5 Indication data
|
||||||
|
dataCrypto = 0xD4, /// Crypto Status data
|
||||||
|
dataMilSettings = 0xD7 /// Military Settings data
|
||||||
|
} sg_datatype_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Data Request message.
|
||||||
|
* Host --> XPDR.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
sg_datatype_t reqType; /// The desired data response
|
||||||
|
uint8_t resv[3];
|
||||||
|
} sg_datareq_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available target request types
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
reportAuto = 0, /// Enable auto output of all target reports
|
||||||
|
reportSummary, /// Report list of all tracked targets (disables auto-output)
|
||||||
|
reportIcao, /// Generate reports for specific target, only (disables auto-output)
|
||||||
|
reportNone /// Disable all target reports
|
||||||
|
} sg_reporttype_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Available target report transmission ports
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
transmitSource = 0, /// Transmit reports on channel where target request was received
|
||||||
|
transmitCom0, /// Transmit reports on Com0
|
||||||
|
transmitCom1, /// Transmit reports on Com1
|
||||||
|
transmitEth /// Transmit reports on Ethernet
|
||||||
|
} sg_transmitport_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Target Request message for ADS-B 'in' data.
|
||||||
|
* Host --> XPDR.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
sg_reporttype_t reqType; /// The desired report mode
|
||||||
|
sg_transmitport_t transmitPort; /// The communication port used for report transmission
|
||||||
|
uint16_t maxTargets; /// The maximum number of targets to track (max value: 404)
|
||||||
|
uint32_t icao; /// The desired target's ID, if applicable
|
||||||
|
bool stateVector; /// Transmit state vector reports
|
||||||
|
bool modeStatus; /// Transmit mode status reports
|
||||||
|
bool targetState; /// Transmit target state reports
|
||||||
|
bool airRefVel; /// Transmit air referenced velocity reports
|
||||||
|
bool tisb; /// Transmit raw TIS-B message reports (requires auto-output)
|
||||||
|
bool military; /// Enable tracking of military aircraft
|
||||||
|
bool commA; /// Transmit Comm-A Reports (requires auto-output)
|
||||||
|
bool ownship; /// Transmit reports about own aircraft
|
||||||
|
} sg_targetreq_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Mode message.
|
||||||
|
* Host --> XPDR.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
bool reboot; /// Reboot the MX
|
||||||
|
} sg_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XPNDR Acknowledge Message following all host messages.
|
||||||
|
* XPNDR --> Host.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint8_t ackType; /// Message type being acknowledged
|
||||||
|
uint8_t ackId; /// Message ID being acknowledged
|
||||||
|
bool failXpdr; /// Built-in-test failure
|
||||||
|
bool failSystem; /// Required system input missing
|
||||||
|
bool failCrypto; /// Crypto status failure
|
||||||
|
bool wow; /// Weight-on-wheels indicates aircraft is on-ground
|
||||||
|
bool maint; /// Maintenance mode enabled
|
||||||
|
bool isHostAlt; /// False = Pressure sensor altitude, True = Host provided value
|
||||||
|
sg_op_mode_t opMode; /// Operational mode
|
||||||
|
int32_t alt; /// Altitude (feet)
|
||||||
|
bool altValid; /// Altitude is valid
|
||||||
|
} sg_ack_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XPNDR Status Response Message following a Data Request for Status.
|
||||||
|
* XPNDR --> Host.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint8_t versionSW; /// SW Version # installed on the XPNDR
|
||||||
|
uint8_t versionFW; /// FW Version # installed on the XPNDR
|
||||||
|
uint32_t crc; /// CRC Checksum for the installed XPNDR SW/FW versions
|
||||||
|
|
||||||
|
bool powerUp : 1; /// Integrity of CPU and Non-Volatile data at power-up
|
||||||
|
bool continuous : 1; /// Set by any other B.I.T. failures during operation
|
||||||
|
bool processor : 1; /// One-time processor instruction set test at power-up
|
||||||
|
bool crcValid : 1; /// Calculate then verifies the CRC against the stored value
|
||||||
|
bool memory : 1; /// Processor RAM is functional
|
||||||
|
bool calibrated : 1; /// Transponder is calibrated
|
||||||
|
bool receiver : 1; /// RF signals travel through hardware correctly
|
||||||
|
bool power53v : 1; /// Voltage at the 53V power supply is correct
|
||||||
|
bool adc : 1; /// Analog-to-Digital Converter is functional
|
||||||
|
bool pressure : 1; /// Internal pressure transducer is functional
|
||||||
|
bool fpga : 1; /// FPGA I/O operations are functional
|
||||||
|
bool rxLock : 1; /// Rx oscillator reporting PLL Lock at reference frequency
|
||||||
|
bool txLock : 1; /// Tx oscillator reporting PLL Lock at reference frequency
|
||||||
|
bool mtSuppress : 1; /// Mutual suppression is operating correctly
|
||||||
|
bool temp : 1; /// Internal temperature is within range (< 110 C)
|
||||||
|
bool sqMonitor : 1; /// Squitters are transmitting at their nominal rates
|
||||||
|
bool txRate : 1; /// Transmission duty cycle is in the safe range
|
||||||
|
bool sysLatency : 1; /// Systems events occurred within expected time limits
|
||||||
|
bool txPower : 1; /// Transmission power is in-range
|
||||||
|
bool voltageIn : 1; /// Input voltage is in-range (10V-32V)
|
||||||
|
bool icao : 1; /// ICAO Address is valid (fail at '000000' or 'FFFFFF')
|
||||||
|
bool gps : 1; /// Valid GPS data is received at 1Hz, minimum
|
||||||
|
} sg_status_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XPNDR Health Monitor Response Message.
|
||||||
|
* XPNDR --> Host.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
int8_t socTemp; /// System on a Chip temperature
|
||||||
|
int8_t rfTemp; /// RF Board temperature
|
||||||
|
int8_t ptTemp; /// Pressure Transducer temperature
|
||||||
|
} sg_healthmonitor_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XPNDR Version Response Message.
|
||||||
|
* XPNDR --> Host.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint8_t swVersion; /// The SW Version major revision number
|
||||||
|
uint8_t fwVersion; /// The FW Version major revision number
|
||||||
|
uint16_t swSvnRevision; /// The SW Repository version number
|
||||||
|
uint16_t fwSvnRevision; /// The FW Repository version number
|
||||||
|
} sg_version_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XPNDR Serial Number Response Message.
|
||||||
|
* XPNDR --> Host.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
char ifSN[33]; /// The Interface Board serial number
|
||||||
|
char rfSN[33]; /// The RF Board serial number
|
||||||
|
char xpndrSN[33]; /// The Transponder serial number
|
||||||
|
} sg_serialnumber_t;
|
||||||
|
|
||||||
|
/// The state vector report type.
|
||||||
|
typedef enum {
|
||||||
|
svrAirborne = 1, /// Airborne state vector report type.
|
||||||
|
svrSurface /// Surface state vector report type.
|
||||||
|
} sg_svr_type_t;
|
||||||
|
|
||||||
|
/// The state vector report participant address type.
|
||||||
|
typedef enum {
|
||||||
|
svrAdrIcaoUnknown, /// ICAO address unknown emitter category.
|
||||||
|
svrAdrNonIcaoUnknown, /// Non-ICAO address unknown emitter category.
|
||||||
|
svrAdrIcao, /// ICAO address aircraft.
|
||||||
|
svrAdrNonIcao, /// Non-ICAO address aircraft.
|
||||||
|
svrAdrIcaoSurface, /// ICAO address surface vehicle, fixed ground, tethered obstruction.
|
||||||
|
svrAdrNonIcaoSurface, /// Non-ICAO address surface vehicle, fixed ground, tethered obstruction.
|
||||||
|
svrAdrDup, /// Duplicate target of another ICAO address.
|
||||||
|
svrAdrAdsr /// ADS-R target.
|
||||||
|
} sg_addr_type_t;
|
||||||
|
|
||||||
|
/// The surface part of a state vector report.
|
||||||
|
typedef struct {
|
||||||
|
int16_t speed; /// Surface speed.
|
||||||
|
int16_t heading; /// Surface heading.
|
||||||
|
} sg_svr_surface_t;
|
||||||
|
|
||||||
|
/// The airborne part of a state vector report.
|
||||||
|
typedef struct {
|
||||||
|
int16_t velNS; /// The NS speed vector component. [knots]
|
||||||
|
int16_t velEW; /// The EW speed vector component. [knots]
|
||||||
|
int16_t speed; /// Speed from N/S and E/W velocity. [knots]
|
||||||
|
int16_t heading; /// Heading from N/S and E/W velocity. [deg from N]
|
||||||
|
int32_t geoAlt; /// Geometric altitude. [ft]
|
||||||
|
int32_t baroAlt; /// Barometric altitude. [ft]
|
||||||
|
int16_t vrate; /// Vertical rate. [ft/min]
|
||||||
|
float estLat; /// Estimated latitude. [deg N]
|
||||||
|
float estLon; /// Estimated longitude. [deg E]
|
||||||
|
} sg_svr_airborne_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool baroVRate : 1; /// Barometric vertical rate valid.
|
||||||
|
bool geoVRate : 1; /// Geometric vertical rate valid.
|
||||||
|
bool baroAlt : 1; /// Barometric altitude valid.
|
||||||
|
bool surfHeading : 1; /// Surface heading valid.
|
||||||
|
bool surfSpeed : 1; /// Surface speed valid.
|
||||||
|
bool airSpeed : 1; /// Airborne speed and heading valid.
|
||||||
|
bool geoAlt : 1; /// Geometric altitude valid.
|
||||||
|
bool position : 1; /// Lat and lon data valid.
|
||||||
|
} sg_svr_validity_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t reserved : 6; /// Reserved.
|
||||||
|
bool estSpeed : 1; /// Estimated N/S and E/W velocity.
|
||||||
|
bool estPosition : 1; /// Estimated lat/lon position.
|
||||||
|
} sg_svr_est_validity_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XPDR ADS-B state vector report Message.
|
||||||
|
* Host --> XPDR.
|
||||||
|
*
|
||||||
|
* @note The time of applicability values are based on the MX system clock that starts
|
||||||
|
* at 0 on power up. The time is the floating point number that is the seconds since
|
||||||
|
* power up. The time number rolls over at 512.0.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
sg_svr_type_t type; /// Report type.
|
||||||
|
union {
|
||||||
|
uint8_t flags;
|
||||||
|
sg_svr_validity_t validity; /// Field validity flags.
|
||||||
|
};
|
||||||
|
union {
|
||||||
|
uint8_t eflags;
|
||||||
|
sg_svr_est_validity_t evalidity; /// Estimated field validity flags.
|
||||||
|
};
|
||||||
|
uint32_t addr; /// Participant address.
|
||||||
|
sg_addr_type_t addrType; /// Participant address type.
|
||||||
|
float toaEst; /// Report estimated position and speed time of applicability.
|
||||||
|
float toaPosition; /// Report position time of applicability.
|
||||||
|
float toaSpeed; /// Report speed time of applicability.
|
||||||
|
uint8_t survStatus; /// Surveillance status.
|
||||||
|
uint8_t mode; /// Report mode.
|
||||||
|
uint8_t nic; /// Navigation integrity category.
|
||||||
|
float lat; /// Latitude.
|
||||||
|
float lon; /// Longitude.
|
||||||
|
union {
|
||||||
|
sg_svr_surface_t surface; /// Surface SVR data.
|
||||||
|
sg_svr_airborne_t airborne; /// Airborne SVR data.
|
||||||
|
};
|
||||||
|
} sg_svr_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
msrTypeV0,
|
||||||
|
msrTypeV1Airborne,
|
||||||
|
msrTypeV1Surface,
|
||||||
|
msrTypeV2Airborne,
|
||||||
|
msrTypeV2Surface
|
||||||
|
} sg_msr_type_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t reserved : 2;
|
||||||
|
bool priority : 1;
|
||||||
|
bool sil : 1;
|
||||||
|
bool nacv : 1;
|
||||||
|
bool nacp : 1;
|
||||||
|
bool opmode : 1;
|
||||||
|
bool capcodes : 1;
|
||||||
|
} sg_msr_validity_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
adsbVerDO260,
|
||||||
|
adsbVerDO260A,
|
||||||
|
adsbVerDO260B
|
||||||
|
} sg_adsb_version_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
adsbUnknown,
|
||||||
|
adsbLight,
|
||||||
|
adsbSmall = 0x3,
|
||||||
|
adsbLarge = 0x5,
|
||||||
|
adsbHighVortex,
|
||||||
|
adsbHeavy,
|
||||||
|
adsbPerformance,
|
||||||
|
adsbRotorcraft = 0x0A,
|
||||||
|
adsbGlider,
|
||||||
|
adsbAir,
|
||||||
|
adsbUnmaned,
|
||||||
|
adsbSpace,
|
||||||
|
adsbUltralight,
|
||||||
|
adsbParachutist,
|
||||||
|
adsbVehicle_emg = 0x14,
|
||||||
|
adsbVehicle_serv,
|
||||||
|
adsbObsticlePoint,
|
||||||
|
adsbObsticleCluster,
|
||||||
|
adsbObsticleLinear
|
||||||
|
} sg_adsb_emitter_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
priNone,
|
||||||
|
priGeneral,
|
||||||
|
priMedical,
|
||||||
|
priFuel,
|
||||||
|
priComm,
|
||||||
|
priUnlawful,
|
||||||
|
priDowned
|
||||||
|
} sg_priority_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
tcrNone,
|
||||||
|
tcrSingle,
|
||||||
|
tcrMultiple
|
||||||
|
} sg_tcr_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool b2low : 1;
|
||||||
|
bool uat : 1;
|
||||||
|
bool arv : 1;
|
||||||
|
bool tsr : 1;
|
||||||
|
bool adsb : 1;
|
||||||
|
bool tcas : 1;
|
||||||
|
sg_tcr_t tcr;
|
||||||
|
} sg_capability_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
gpsLonNodata,
|
||||||
|
gpsLonSensorSupplied,
|
||||||
|
gpsLon2m,
|
||||||
|
gpsLon4m,
|
||||||
|
gpsLon6m,
|
||||||
|
gpsLon8m,
|
||||||
|
gpsLon10m,
|
||||||
|
gpsLon12m,
|
||||||
|
gpsLon14m,
|
||||||
|
gpsLon16m,
|
||||||
|
gpsLon18m,
|
||||||
|
gpsLon20m,
|
||||||
|
gpsLon22m,
|
||||||
|
gpsLon24m,
|
||||||
|
gpsLon26m,
|
||||||
|
gpsLon28m,
|
||||||
|
gpsLon30m,
|
||||||
|
gpsLon32m,
|
||||||
|
gpsLon34m,
|
||||||
|
gpsLon36m,
|
||||||
|
gpsLon38m,
|
||||||
|
gpsLon40m,
|
||||||
|
gpsLon42m,
|
||||||
|
gpsLon44m,
|
||||||
|
gpsLon46m,
|
||||||
|
gpsLon48m,
|
||||||
|
gpsLon50m,
|
||||||
|
gpsLon52m,
|
||||||
|
gpsLon54m,
|
||||||
|
gpsLon56m,
|
||||||
|
gpsLon58m,
|
||||||
|
gpsLon60m
|
||||||
|
} sg_gps_lonofs_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
gpslatNodata,
|
||||||
|
gpslatLeft2m,
|
||||||
|
gpslatLeft4m,
|
||||||
|
gpslatLeft6m,
|
||||||
|
gpslatRight0m,
|
||||||
|
gpslatRight2m,
|
||||||
|
gpslatRight4m,
|
||||||
|
gpslatRight6m,
|
||||||
|
} sg_gps_latofs_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool gpsLatFmt;
|
||||||
|
sg_gps_latofs_t gpsLatOfs;
|
||||||
|
bool gpsLonFmt;
|
||||||
|
sg_gps_lonofs_t gpsLonOfs;
|
||||||
|
bool tcasRA : 1;
|
||||||
|
bool ident : 1;
|
||||||
|
bool singleAnt : 1;
|
||||||
|
} sg_adsb_opmode_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
gvaUnknown,
|
||||||
|
gvaLT150m,
|
||||||
|
gvaLT45m
|
||||||
|
} sg_gva_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
nicGolham,
|
||||||
|
nicNonGilham
|
||||||
|
} sg_nicbaro_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
svsilUnknown,
|
||||||
|
svsilPow3,
|
||||||
|
svsilPow5,
|
||||||
|
svsilPow7
|
||||||
|
} sg_svsil_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
sg_nacp_t nacp;
|
||||||
|
sg_nacv_t nacv;
|
||||||
|
sg_sda_t sda;
|
||||||
|
bool silSupp;
|
||||||
|
sg_svsil_t sil;
|
||||||
|
sg_gva_t gva;
|
||||||
|
sg_nicbaro_t nicBaro;
|
||||||
|
} sg_sv_qual_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
trackTrueNorth,
|
||||||
|
trackMagNorth,
|
||||||
|
headingTrueNorth,
|
||||||
|
headingMagNorth
|
||||||
|
} sg_trackheading_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
vrateBaroAlt,
|
||||||
|
vrateGeoAlt
|
||||||
|
} sg_vratetype_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XPDR ADS-B mode status report Message.
|
||||||
|
* Host --> XPDR.
|
||||||
|
*
|
||||||
|
* @note The time of applicability values are based on the MX system clock that starts
|
||||||
|
* at 0 on power up. The time is the floating point number that is the seconds since
|
||||||
|
* power up. The time number rolls over at 512.0.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
sg_msr_type_t type; /// Report type.
|
||||||
|
|
||||||
|
union {
|
||||||
|
uint8_t flags;
|
||||||
|
sg_msr_validity_t validity; /// Field validity flags.
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t addr; /// Participant address.
|
||||||
|
sg_addr_type_t addrType; /// Participant address type.
|
||||||
|
|
||||||
|
float toa;
|
||||||
|
sg_adsb_version_t version;
|
||||||
|
char callsign[9];
|
||||||
|
sg_adsb_emitter_t emitter;
|
||||||
|
sg_size_t size;
|
||||||
|
sg_priority_t priority;
|
||||||
|
sg_capability_t capability;
|
||||||
|
sg_adsb_opmode_t opMode;
|
||||||
|
sg_sv_qual_t svQuality;
|
||||||
|
sg_trackheading_t trackHeading;
|
||||||
|
sg_vratetype_t vrateType;
|
||||||
|
} sg_msr_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert install message struct to the raw buffer format.
|
||||||
|
*
|
||||||
|
* @param[out] buffer An empty buffer to contain the raw install message.
|
||||||
|
* @param[in] stl The install message struct with fields populated.
|
||||||
|
* @param[in] msgId The sequence number for the message.
|
||||||
|
*
|
||||||
|
* @return true if successful or false on failure.
|
||||||
|
*
|
||||||
|
* @warning data in stl parameter must be pre-validated.
|
||||||
|
*/
|
||||||
|
bool sgEncodeInstall(uint8_t *buffer, sg_install_t *stl, uint8_t msgId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert flight identification struct to the raw buffer format.
|
||||||
|
*
|
||||||
|
* @param[out] buffer An empty buffer to contain the raw flight identification message.
|
||||||
|
* @param[in] id The flight id struct with fields populated.
|
||||||
|
* @param[in] msgId The sequence number for the message.
|
||||||
|
*
|
||||||
|
* @return true if successful or false on failure.
|
||||||
|
*
|
||||||
|
* @warning data in id parameter must be pre-validated.
|
||||||
|
*/
|
||||||
|
bool sgEncodeFlightId(uint8_t *buffer, sg_flightid_t *id, uint8_t msgId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert operating message struct to the raw buffer format.
|
||||||
|
*
|
||||||
|
* @param[out] buffer An empty buffer to contain the raw operating message.
|
||||||
|
* @param[in] op The operating message struct with fields populated.
|
||||||
|
* @param[in] msgId The sequence number for the message.
|
||||||
|
*
|
||||||
|
* @return true if successful or false on failure.
|
||||||
|
*
|
||||||
|
* @warning data in op parameter must be pre-validated.
|
||||||
|
*/
|
||||||
|
bool sgEncodeOperating(uint8_t *buffer, sg_operating_t *op, uint8_t msgId);
|
||||||
|
|
||||||
|
/* TODO: Create GPS helper functions to convert other data types --> char buffers */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert GPS message struct to the raw buffer format.
|
||||||
|
*
|
||||||
|
* @param[out] buffer An empty buffer to contain the raw GPS message.
|
||||||
|
* @param[in] gps The GPS message struct with fields populated.
|
||||||
|
* @param[in] msgId The sequence number for the message.
|
||||||
|
*
|
||||||
|
* @return true if successful or false on failure.
|
||||||
|
*
|
||||||
|
* @warning data in gps parameter must be pre-validated.
|
||||||
|
*/
|
||||||
|
bool sgEncodeGPS(uint8_t *buffer, sg_gps_t *gps, uint8_t msgId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert data request message struct to the raw buffer format.
|
||||||
|
*
|
||||||
|
* @param[out] buffer An empty buffer to contain the raw target request message.
|
||||||
|
* @param[in] data The data request message struct with fields populated.
|
||||||
|
* @param[in] msgId The sequence number for the message.
|
||||||
|
*
|
||||||
|
* @return true if successful or false on failure.
|
||||||
|
*
|
||||||
|
* @warning data in data parameter must be pre-validated.
|
||||||
|
*/
|
||||||
|
bool sgEncodeDataReq(uint8_t *buffer, sg_datareq_t *data, uint8_t msgId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert target request message struct to the raw buffer format.
|
||||||
|
*
|
||||||
|
* @param[out] buffer An empty buffer to contain the raw target request message.
|
||||||
|
* @param[in] tgt The target request message struct with fields populated.
|
||||||
|
* @param[in] msgId The sequence number for the message.
|
||||||
|
*
|
||||||
|
* @return true if successful or false on failure.
|
||||||
|
*
|
||||||
|
* @warning data in tgt parameter must be pre-validated.
|
||||||
|
*/
|
||||||
|
bool sgEncodeTargetReq(uint8_t *buffer, sg_targetreq_t *tgt, uint8_t msgId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the ACK message response from the transponder.
|
||||||
|
*
|
||||||
|
* @param[in] buffer The raw ACK message buffer.
|
||||||
|
* @param[out] ack The parsed message results.
|
||||||
|
*
|
||||||
|
* @return true if successful or false on failure.
|
||||||
|
*/
|
||||||
|
bool sgDecodeAck(uint8_t *buffer, sg_ack_t *ack);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the Install message response from the transponder.
|
||||||
|
*
|
||||||
|
* @param[in] buffer The raw Install message buffer.
|
||||||
|
* @param[out] stl The parsed message results.
|
||||||
|
*
|
||||||
|
* @return true if successful or false on failure.
|
||||||
|
*/
|
||||||
|
bool sgDecodeInstall(uint8_t *buffer, sg_install_t *stl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the Flight ID message response from the transponder.
|
||||||
|
*
|
||||||
|
* @param[in] buffer The raw Flight ID message buffer.
|
||||||
|
* @param[out] id The parsed message results.
|
||||||
|
*
|
||||||
|
* @return true if successful or false on failure.
|
||||||
|
*/
|
||||||
|
bool sgDecodeFlightId(uint8_t *buffer, sg_flightid_t *id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the state vector report message.
|
||||||
|
*
|
||||||
|
* @param[in] buffer The raw SVR message buffer.
|
||||||
|
* @param[out] svr The parsed SVR message.
|
||||||
|
*
|
||||||
|
* @return true if successful or false on failure.
|
||||||
|
*/
|
||||||
|
bool sgDecodeSVR(uint8_t *buffer, sg_svr_t *svr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the mode status report message.
|
||||||
|
*
|
||||||
|
* @param buffer The raw MSR message buffer.
|
||||||
|
* @param msr The parsed MSR message.
|
||||||
|
*
|
||||||
|
* @return true if successful or false on failure.
|
||||||
|
*/
|
||||||
|
bool sgDecodeMSR(uint8_t *buffer, sg_msr_t *msr);
|
||||||
|
|
||||||
|
#endif /* SG_H */
|
|
@ -0,0 +1,72 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file sgDecodeAck.c
|
||||||
|
* @author jimb
|
||||||
|
*
|
||||||
|
* @date Feb 10, 2021
|
||||||
|
*
|
||||||
|
* This file receives a raw Acknowledge message buffer and
|
||||||
|
* parses the payload into a data struct.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "sg.h"
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define SG_ACK_XPNDR_FAIL 0x01
|
||||||
|
#define SG_ACK_SYSTEM_FAIL 0x02
|
||||||
|
#define SG_ACK_CRYPTO_FAIL 0x04
|
||||||
|
#define SG_ACK_WOW 0x08
|
||||||
|
#define SG_ACK_MAINT 0x10
|
||||||
|
#define SG_ACK_ALT_SOURCE 0x20
|
||||||
|
#define SG_ACK_OP_MODE 0xC0
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed))
|
||||||
|
{
|
||||||
|
uint8_t start;
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t payloadLen;
|
||||||
|
uint8_t ackType;
|
||||||
|
uint8_t ackId;
|
||||||
|
uint8_t state;
|
||||||
|
uint8_t alt[3];
|
||||||
|
uint8_t checksum;
|
||||||
|
} ack_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
bool sgDecodeAck(uint8_t *buffer, sg_ack_t *ack)
|
||||||
|
{
|
||||||
|
ack_t sgAck;
|
||||||
|
memcpy(&sgAck, buffer, sizeof(ack_t));
|
||||||
|
|
||||||
|
ack->ackType = sgAck.ackType;
|
||||||
|
ack->ackId = sgAck.ackId;
|
||||||
|
ack->failXpdr = (sgAck.state & SG_ACK_XPNDR_FAIL) > 0;
|
||||||
|
ack->failSystem = (sgAck.state & SG_ACK_SYSTEM_FAIL) > 0;
|
||||||
|
ack->failCrypto = (sgAck.state & SG_ACK_CRYPTO_FAIL) > 0;
|
||||||
|
ack->wow = (sgAck.state & SG_ACK_WOW) > 0;
|
||||||
|
ack->maint = (sgAck.state & SG_ACK_MAINT) > 0;
|
||||||
|
ack->isHostAlt = (sgAck.state & SG_ACK_ALT_SOURCE) > 0;
|
||||||
|
ack->opMode = (sgAck.state & SG_ACK_OP_MODE) >> 6;
|
||||||
|
|
||||||
|
int32_t int24 = toInt32(sgAck.alt);
|
||||||
|
|
||||||
|
// Bitmask altitude field to determine if alt = invalid
|
||||||
|
if ((int24 & 0x00FFFFFF) == 0x00800000) {
|
||||||
|
ack->alt = 0;
|
||||||
|
ack->altValid = false;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ack->alt = int24;
|
||||||
|
ack->altValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file sgDecodeFlightId.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 10, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "sg.h"
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define SG_ID_LEN 8 // The number of bytes in the flight id field
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed))
|
||||||
|
{
|
||||||
|
uint8_t start;
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t payloadLen;
|
||||||
|
char flightId[SG_ID_LEN];
|
||||||
|
uint8_t rsvd[4];
|
||||||
|
uint8_t checksum;
|
||||||
|
} flightid_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
bool sgDecodeFlightId(uint8_t *buffer, sg_flightid_t *id)
|
||||||
|
{
|
||||||
|
flightid_t sgId;
|
||||||
|
memcpy(&sgId, buffer, sizeof(flightid_t));
|
||||||
|
|
||||||
|
strcpy(id->flightId, sgId.flightId);
|
||||||
|
memset(&id->flightId[SG_ID_LEN], '\0', 1); // Ensure flight id is null-terminated
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file sgDecodeInstall.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 9, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "sg.h"
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define SG_REG_LEN 7 // The number of bytes in the registration field
|
||||||
|
|
||||||
|
#define SG_STL_ANTENNA 0x03
|
||||||
|
#define SG_STL_ALT_RES 0x08
|
||||||
|
#define SG_STL_HDG_TYPE 0x10
|
||||||
|
#define SG_STL_SPD_TYPE 0x20
|
||||||
|
#define SG_STL_HEATER 0x40
|
||||||
|
#define SG_STL_WOW 0x80
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed))
|
||||||
|
{
|
||||||
|
uint8_t start;
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t payloadLen;
|
||||||
|
uint8_t icao[3];
|
||||||
|
char registration[SG_REG_LEN];
|
||||||
|
uint8_t rsvd1[2];
|
||||||
|
uint8_t com0;
|
||||||
|
uint8_t com1;
|
||||||
|
uint8_t ipAddress[4];
|
||||||
|
uint8_t subnetMask[4];
|
||||||
|
uint8_t port[2];
|
||||||
|
uint8_t gpsIntegrity;
|
||||||
|
uint8_t emitterSet;
|
||||||
|
uint8_t emitterType;
|
||||||
|
uint8_t size;
|
||||||
|
uint8_t maxSpeed;
|
||||||
|
uint8_t altOffset[2];
|
||||||
|
uint8_t rsvd2[2];
|
||||||
|
uint8_t config;
|
||||||
|
uint8_t rsvd3[2];
|
||||||
|
uint8_t checksum;
|
||||||
|
} stl_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
bool sgDecodeInstall(uint8_t *buffer, sg_install_t *stl)
|
||||||
|
{
|
||||||
|
memset(&stl->reg[0], '\0', sizeof(stl->reg)); // Ensure registration is null-terminated
|
||||||
|
|
||||||
|
stl_t sgStl;
|
||||||
|
memcpy(&sgStl, buffer, sizeof(stl_t));
|
||||||
|
|
||||||
|
stl->icao = toIcao(sgStl.icao);
|
||||||
|
strcpy(stl->reg, sgStl.registration);
|
||||||
|
memset(&stl->reg[SG_REG_LEN], 0, 1); // Ensure registration is null-terminated
|
||||||
|
stl->com0 = (sg_baud_t)(sgStl.com0);
|
||||||
|
stl->com1 = (sg_baud_t)(sgStl.com1);
|
||||||
|
stl->eth.ipAddress = toUint32(sgStl.ipAddress);
|
||||||
|
stl->eth.subnetMask = toUint32(sgStl.subnetMask);
|
||||||
|
stl->eth.portNumber = toUint16(sgStl.port);
|
||||||
|
stl->sil = (sg_sil_t)(sgStl.gpsIntegrity >> 4);
|
||||||
|
stl->sda = (sg_sda_t)(sgStl.gpsIntegrity & 0x0F);
|
||||||
|
stl->emitter = (sg_emitter_t)(0x10 * sgStl.emitterSet + sgStl.emitterType);
|
||||||
|
stl->size = (sg_size_t)sgStl.size;
|
||||||
|
stl->maxSpeed = (sg_airspeed_t)sgStl.maxSpeed;
|
||||||
|
stl->altOffset = toUint16(sgStl.altOffset);
|
||||||
|
stl->antenna = (sg_antenna_t)sgStl.config & SG_STL_ANTENNA;
|
||||||
|
stl->altRes100 = sgStl.config & SG_STL_ALT_RES;
|
||||||
|
stl->hdgTrueNorth = sgStl.config & SG_STL_HDG_TYPE;
|
||||||
|
stl->airspeedTrue = sgStl.config & SG_STL_SPD_TYPE;
|
||||||
|
stl->heater = sgStl.config & SG_STL_HEATER;
|
||||||
|
stl->wowConnected = sgStl.config & SG_STL_WOW;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,183 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2020 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file sgDecodeMSR.c
|
||||||
|
* @author jim.billmeyer
|
||||||
|
*
|
||||||
|
* @date Mar 17, 2021
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sg.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define MS_PARAM_TOA (1 << 3)
|
||||||
|
#define MS_PARAM_ADSBVER (1 << 2)
|
||||||
|
#define MS_PARAM_CALLSIGN (1 << 1)
|
||||||
|
#define MS_PARAM_CATEMITTER (1 << 0)
|
||||||
|
|
||||||
|
#define MS_PARAM_AVLEN (1 << 7)
|
||||||
|
#define MS_PARAM_PRIORITY (1 << 6)
|
||||||
|
#define MS_PARAM_CAPCODES (1 << 5)
|
||||||
|
#define MS_PARAM_OPMODE (1 << 4)
|
||||||
|
#define MS_PARAM_NACP (1 << 3)
|
||||||
|
#define MS_PARAM_NACV (1 << 2)
|
||||||
|
#define MS_PARAM_SDA (1 << 1)
|
||||||
|
#define MS_PARAM_GVA (1 << 0)
|
||||||
|
|
||||||
|
#define MS_PARAM_NIC (1 << 7)
|
||||||
|
#define MS_PARAM_HEADING (1 << 6)
|
||||||
|
#define MS_PARAM_VRATE (1 << 5)
|
||||||
|
|
||||||
|
#define MS_CAP_B2LOW (1 << 3)
|
||||||
|
#define MS_CAP_UAT (1 << 1)
|
||||||
|
#define MS_CAP_TCR ((1 << 2) | (1 << 3))
|
||||||
|
#define MS_CAP_TSR (1 << 4)
|
||||||
|
#define MS_CAP_ARV (1 << 5)
|
||||||
|
#define MS_CAP_ADSB (1 << 6)
|
||||||
|
#define MS_CAP_TCAS (1 << 7)
|
||||||
|
|
||||||
|
#define MS_OP_GPS_LATFMT (1 << 7)
|
||||||
|
#define MS_OP_GPS_LONFMT (1 << 6)
|
||||||
|
#define MS_OP_TCAS_RA (1 << 5)
|
||||||
|
#define MS_OP_IDENT (1 << 4)
|
||||||
|
#define MS_OP_SINGLE_ANT (1 << 2)
|
||||||
|
|
||||||
|
/// the payload offset.
|
||||||
|
#define PBASE 4
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
bool sgDecodeMSR(uint8_t *buffer, sg_msr_t *msr)
|
||||||
|
{
|
||||||
|
memset(msr, 0, sizeof(sg_msr_t));
|
||||||
|
|
||||||
|
uint8_t fields[3];
|
||||||
|
memcpy(fields, &buffer[PBASE + 0], 3);
|
||||||
|
|
||||||
|
if (buffer[PBASE + 1] == 0x6E && buffer[PBASE + 2] == 0x60) {
|
||||||
|
msr->type = msrTypeV0;
|
||||||
|
|
||||||
|
} else if (buffer[PBASE + 1] == 0x7E && buffer[PBASE + 2] == 0xE0) {
|
||||||
|
msr->type = msrTypeV1Airborne;
|
||||||
|
|
||||||
|
} else if (buffer[PBASE + 1] == 0xFE && buffer[PBASE + 2] == 0xE0) {
|
||||||
|
msr->type = msrTypeV1Surface;
|
||||||
|
|
||||||
|
} else if (buffer[PBASE + 1] == 0x7F && buffer[PBASE + 2] == 0xE0) {
|
||||||
|
msr->type = msrTypeV2Airborne;
|
||||||
|
|
||||||
|
} else if (buffer[PBASE + 1] == 0xFF && buffer[PBASE + 2] == 0xE0) {
|
||||||
|
msr->type = msrTypeV2Surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
msr->flags = buffer[PBASE + 3];
|
||||||
|
msr->addr = toInt32(&buffer[PBASE + 4]) & 0xFFFFFF;
|
||||||
|
msr->addrType = buffer[PBASE + 7] & 0xFF;
|
||||||
|
|
||||||
|
uint8_t ofs = 8;
|
||||||
|
|
||||||
|
if (fields[0] & MS_PARAM_TOA) {
|
||||||
|
msr->toa = toTOA(&buffer[PBASE + ofs]);
|
||||||
|
ofs += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[0] & MS_PARAM_ADSBVER) {
|
||||||
|
msr->version = buffer[PBASE + ofs];
|
||||||
|
ofs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[0] & MS_PARAM_CALLSIGN) {
|
||||||
|
memset(msr->callsign, 0, 9);
|
||||||
|
memcpy(msr->callsign, &buffer[PBASE + ofs], 8);
|
||||||
|
ofs += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[0] & MS_PARAM_CATEMITTER) {
|
||||||
|
msr->emitter = buffer[PBASE + ofs];
|
||||||
|
ofs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & MS_PARAM_AVLEN) {
|
||||||
|
msr->size = buffer[PBASE + ofs];
|
||||||
|
ofs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & MS_PARAM_PRIORITY) {
|
||||||
|
msr->priority = buffer[PBASE + ofs];
|
||||||
|
ofs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & MS_PARAM_CAPCODES) {
|
||||||
|
uint8_t cap = buffer[PBASE + ofs + 0];
|
||||||
|
msr->capability.b2low = cap & MS_CAP_B2LOW;
|
||||||
|
|
||||||
|
cap = buffer[PBASE + ofs + 1];
|
||||||
|
msr->capability.uat = cap & MS_CAP_UAT;
|
||||||
|
msr->capability.tcr = (cap & MS_CAP_TCR) >> 2;
|
||||||
|
msr->capability.tsr = cap & MS_CAP_TSR;
|
||||||
|
msr->capability.arv = cap & MS_CAP_ARV;
|
||||||
|
msr->capability.adsb = cap & MS_CAP_ADSB;
|
||||||
|
msr->capability.tcas = cap & MS_CAP_TCAS;
|
||||||
|
|
||||||
|
ofs += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & MS_PARAM_OPMODE) {
|
||||||
|
uint8_t op = buffer[PBASE + ofs + 0];
|
||||||
|
msr->opMode.gpsLatFmt = (op & MS_OP_GPS_LATFMT) == 0;
|
||||||
|
msr->opMode.gpsLonFmt = (op & MS_OP_GPS_LONFMT) == 0;
|
||||||
|
msr->opMode.tcasRA = op & MS_OP_TCAS_RA;
|
||||||
|
msr->opMode.ident = op & MS_OP_IDENT;
|
||||||
|
msr->opMode.singleAnt = op & MS_OP_SINGLE_ANT;
|
||||||
|
|
||||||
|
op = buffer[PBASE + ofs + 1];
|
||||||
|
msr->opMode.gpsLatOfs = op >> 5;
|
||||||
|
msr->opMode.gpsLonOfs = op & 0x17;
|
||||||
|
|
||||||
|
ofs += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & MS_PARAM_NACP) {
|
||||||
|
msr->svQuality.nacp = buffer[PBASE + ofs];
|
||||||
|
ofs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & MS_PARAM_NACV) {
|
||||||
|
msr->svQuality.nacv = buffer[PBASE + ofs];
|
||||||
|
ofs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & MS_PARAM_SDA) {
|
||||||
|
uint8_t sda = buffer[PBASE + ofs];
|
||||||
|
msr->svQuality.sda = (sda & 0x18) >> 3;
|
||||||
|
msr->svQuality.silSupp = (sda & 0x04);
|
||||||
|
msr->svQuality.sil = (sda & 0x03);
|
||||||
|
ofs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & MS_PARAM_GVA) {
|
||||||
|
msr->svQuality.gva = buffer[PBASE + ofs];
|
||||||
|
ofs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[2] & MS_PARAM_NIC) {
|
||||||
|
msr->svQuality.nicBaro = buffer[PBASE + ofs];
|
||||||
|
ofs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[2] & MS_PARAM_HEADING) {
|
||||||
|
msr->trackHeading = buffer[PBASE + ofs];
|
||||||
|
ofs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[2] & MS_PARAM_VRATE) {
|
||||||
|
msr->vrateType = buffer[PBASE + ofs];
|
||||||
|
ofs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,209 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file sgDecodeSVR.c
|
||||||
|
* @author jimb
|
||||||
|
*
|
||||||
|
* @date Feb 10, 2021
|
||||||
|
*
|
||||||
|
* This file receives a raw ADS-B target state vector report message buffer and
|
||||||
|
* parses the payload into a data struct.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "sg.h"
|
||||||
|
#include "sgUtil.h"
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
|
// airborne surface
|
||||||
|
// -------- --------
|
||||||
|
#define SV_PARAM_TOA_EPOS (1 << 3) // x
|
||||||
|
#define SV_PARAM_TOA_POS (1 << 2) // x x
|
||||||
|
#define SV_PARAM_TOA_VEL (1 << 1) // x x
|
||||||
|
#define SV_PARAM_LATLON (1 << 0) // x x
|
||||||
|
|
||||||
|
#define SV_PARAM_GEOALT (1 << 7) // x
|
||||||
|
#define SV_PARAM_VEL (1 << 6) // x
|
||||||
|
#define SV_PARAM_SURF_GS (1 << 5) // x
|
||||||
|
#define SV_PARAM_SURF_HEAD (1 << 4) // x
|
||||||
|
#define SV_PARAM_BAROALT (1 << 3) // x
|
||||||
|
#define SV_PARAM_VRATE (1 << 2) // x
|
||||||
|
#define SV_PARAM_NIC (1 << 1) // x x
|
||||||
|
#define SV_PARAM_ESTLAT (1 << 0) // x
|
||||||
|
|
||||||
|
#define SV_PARAM_ESTLON (1 << 7) // x
|
||||||
|
#define SV_PARAM_ESTNVEL (1 << 6)
|
||||||
|
#define SV_PARAM_ESTEVAL (1 << 5)
|
||||||
|
#define SV_PARAM_SURV (1 << 4) // x x
|
||||||
|
#define SV_PARAM_REPORT (1 << 3) // x x
|
||||||
|
|
||||||
|
/// the payload offset.
|
||||||
|
#define PBASE 4
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
bool sgDecodeSVR(uint8_t *buffer, sg_svr_t *svr)
|
||||||
|
{
|
||||||
|
// memset(svr, 0, sizeof(sg_svr_t));
|
||||||
|
|
||||||
|
uint8_t fields[3];
|
||||||
|
memcpy(&fields, &buffer[PBASE + 0], 3);
|
||||||
|
|
||||||
|
svr->type = buffer[PBASE + 0] == 0x1F ? svrAirborne : svrSurface;
|
||||||
|
svr->flags = buffer[PBASE + 3];
|
||||||
|
svr->eflags = buffer[PBASE + 4];
|
||||||
|
svr->addr = toInt32(&buffer[PBASE + 5]) & 0xFFFFFF;
|
||||||
|
svr->addrType = buffer[PBASE + 8] & 0xFF;
|
||||||
|
|
||||||
|
uint8_t ofs = 9;
|
||||||
|
|
||||||
|
if (fields[0] & SV_PARAM_TOA_EPOS) {
|
||||||
|
svr->toaEst = toTOA(&buffer[PBASE + ofs]);
|
||||||
|
ofs += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[0] & SV_PARAM_TOA_POS) {
|
||||||
|
svr->toaPosition = toTOA(&buffer[PBASE + ofs]);
|
||||||
|
ofs += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[0] & SV_PARAM_TOA_VEL) {
|
||||||
|
svr->toaSpeed = toTOA(&buffer[PBASE + ofs]);
|
||||||
|
ofs += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[0] & SV_PARAM_LATLON) {
|
||||||
|
if (svr->validity.position) {
|
||||||
|
svr->lat = toLatLon(&buffer[PBASE + ofs + 0]);
|
||||||
|
svr->lon = toLatLon(&buffer[PBASE + ofs + 3]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
svr->lat = 0.0;
|
||||||
|
svr->lon = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ofs += 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (svr->type == svrAirborne) {
|
||||||
|
if (fields[1] & SV_PARAM_GEOALT) {
|
||||||
|
if (svr->validity.geoAlt) {
|
||||||
|
svr->airborne.geoAlt = toAlt(&buffer[PBASE + ofs]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
svr->airborne.geoAlt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ofs += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & SV_PARAM_VEL) {
|
||||||
|
if (svr->validity.airSpeed) {
|
||||||
|
int16_t nvel = toVel(&buffer[PBASE + ofs + 0]);
|
||||||
|
int16_t evel = toVel(&buffer[PBASE + ofs + 2]);
|
||||||
|
|
||||||
|
svr->airborne.heading = toHeading2((double)nvel, (double)evel);
|
||||||
|
svr->airborne.speed = sqrt(nvel * nvel + evel * evel);
|
||||||
|
svr->airborne.velEW = evel;
|
||||||
|
svr->airborne.velNS = nvel;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
svr->airborne.heading = 0;
|
||||||
|
svr->airborne.speed = 0;
|
||||||
|
svr->airborne.velEW = 0;
|
||||||
|
svr->airborne.velNS = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ofs += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & SV_PARAM_BAROALT) {
|
||||||
|
if (svr->validity.baroAlt) {
|
||||||
|
svr->airborne.baroAlt = toAlt(&buffer[PBASE + ofs]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
svr->airborne.baroAlt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ofs += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & SV_PARAM_VRATE) {
|
||||||
|
if (svr->validity.baroVRate || svr->validity.geoVRate) {
|
||||||
|
svr->airborne.vrate = toInt16(&buffer[PBASE + ofs]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
svr->airborne.vrate = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ofs += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (fields[1] & SV_PARAM_SURF_GS) {
|
||||||
|
if (svr->validity.surfSpeed) {
|
||||||
|
svr->surface.speed = toGS(&buffer[PBASE + ofs]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
svr->surface.speed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ofs += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & SV_PARAM_SURF_HEAD) {
|
||||||
|
if (svr->validity.surfHeading) {
|
||||||
|
svr->surface.heading = toHeading(&buffer[PBASE + ofs]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
svr->surface.heading = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ofs += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & SV_PARAM_NIC) {
|
||||||
|
svr->nic = buffer[PBASE + ofs];
|
||||||
|
|
||||||
|
ofs += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[1] & SV_PARAM_ESTLAT) {
|
||||||
|
if (svr->evalidity.estPosition) {
|
||||||
|
svr->airborne.estLat = toLatLon(&buffer[PBASE + ofs]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
svr->airborne.estLat = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ofs += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[2] & SV_PARAM_ESTLON) {
|
||||||
|
if (svr->evalidity.estPosition) {
|
||||||
|
svr->airborne.estLon = toLatLon(&buffer[PBASE + ofs]);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
svr->airborne.estLon = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ofs += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[2] & SV_PARAM_SURV) {
|
||||||
|
svr->survStatus = buffer[PBASE + ofs];
|
||||||
|
ofs += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fields[2] & SV_PARAM_REPORT) {
|
||||||
|
svr->mode = buffer[PBASE + ofs];
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file sgEncodeDataReq.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Feb 23, 2021
|
||||||
|
*
|
||||||
|
* This file receives a populated data request struct and
|
||||||
|
* converts it into a data request message buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "sg.h"
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define SG_PAYLOAD_LEN_DATAREQ SG_MSG_LEN_DATAREQ - 5 /// the payload length.
|
||||||
|
|
||||||
|
#define PBASE 4 /// the payload offset.
|
||||||
|
|
||||||
|
#define OFFSET_REQ_TYPE 0 /// the requested response message type
|
||||||
|
#define OFFSET_RSVD_1 1 /// a reserved field
|
||||||
|
#define OFFSET_RSVD_2 2 /// a reserved field
|
||||||
|
#define OFFSET_RSVD_3 3 /// a reserved field
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
bool sgEncodeDataReq(uint8_t *buffer, sg_datareq_t *data, uint8_t msgId)
|
||||||
|
{
|
||||||
|
// populate header
|
||||||
|
buffer[0] = SG_MSG_START_BYTE;
|
||||||
|
buffer[1] = SG_MSG_TYPE_HOST_DATAREQ;
|
||||||
|
buffer[2] = msgId;
|
||||||
|
buffer[3] = SG_PAYLOAD_LEN_DATAREQ;
|
||||||
|
|
||||||
|
// populate Request Type
|
||||||
|
buffer[PBASE + OFFSET_REQ_TYPE] = data->reqType;
|
||||||
|
|
||||||
|
// populate Reserved fields
|
||||||
|
buffer[PBASE + OFFSET_RSVD_1] = 0;
|
||||||
|
buffer[PBASE + OFFSET_RSVD_2] = 0;
|
||||||
|
buffer[PBASE + OFFSET_RSVD_3] = 0;
|
||||||
|
|
||||||
|
// populate checksum
|
||||||
|
appendChecksum(buffer, SG_MSG_LEN_DATAREQ);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file sgEncodeFlightId.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Feb 25, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "sg.h"
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define SG_PAYLOAD_LEN_FLIGHT SG_MSG_LEN_FLIGHT - 5 /// the payload length.
|
||||||
|
|
||||||
|
#define PBASE 4 /// the payload offset.
|
||||||
|
#define OFFSET_ID 0 /// the flight id offset in the payload.
|
||||||
|
#define OFFSET_RSVD 8 /// the reserved field offset in the payload.
|
||||||
|
|
||||||
|
#define ID_LEN 8 /// the length of the flight identification field.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
bool sgEncodeFlightId(uint8_t *buffer, sg_flightid_t *id, uint8_t msgId)
|
||||||
|
{
|
||||||
|
// populate header
|
||||||
|
buffer[0] = SG_MSG_START_BYTE;
|
||||||
|
buffer[1] = SG_MSG_TYPE_HOST_FLIGHT;
|
||||||
|
buffer[2] = msgId;
|
||||||
|
buffer[3] = SG_PAYLOAD_LEN_FLIGHT;
|
||||||
|
|
||||||
|
// populate flight identification
|
||||||
|
charArray2Buf(&buffer[PBASE + OFFSET_ID], id->flightId, ID_LEN);
|
||||||
|
|
||||||
|
// populate reserved field
|
||||||
|
uint322Buf(&buffer[PBASE + OFFSET_RSVD], 0);
|
||||||
|
|
||||||
|
// populate checksum
|
||||||
|
appendChecksum(buffer, SG_MSG_LEN_FLIGHT);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file sgEncodeGPS.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 1, 2021
|
||||||
|
*
|
||||||
|
* This file receives a populated GPS message struct and
|
||||||
|
* converts it into a GPS message buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "sg.h"
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define SG_PAYLOAD_LEN_GPS SG_MSG_LEN_GPS - 5 /// the payload length.
|
||||||
|
#define _UNUSED(x) ((void)(x))
|
||||||
|
|
||||||
|
#define PBASE 4 /// the payload offset.
|
||||||
|
#define OFFSET_LONGITUDE 0 /// the longitude offset in the payload.
|
||||||
|
#define OFFSET_LATITUDE 11 /// the latitude offset in the payload.
|
||||||
|
#define OFFSET_SPEED 21 /// the ground speed offset in the payload.
|
||||||
|
#define OFFSET_TRACK 27 /// the ground track offset in the payload.
|
||||||
|
#define OFFSET_STATUS 35 /// the hemisphere/data status offset in the payload.
|
||||||
|
#define OFFSET_TIME 36 /// the time of fix offset in the payload.
|
||||||
|
#define OFFSET_HEIGHT 46 /// the GNSS height offset in the payload.
|
||||||
|
#define OFFSET_HPL 50 /// the horizontal protection limit offset in the payload.
|
||||||
|
#define OFFSET_HFOM 54 /// the horizontal figure of merit offset in the payload.
|
||||||
|
#define OFFSET_VFOM 58 /// the vertical figure of merit offset in the payload.
|
||||||
|
#define OFFSET_NACV 62 /// the navigation accuracy for velocity offset in the payload.
|
||||||
|
|
||||||
|
#define LEN_LNG 11 /// bytes in the longitude field
|
||||||
|
#define LEN_LAT 10 /// bytes in the latitude field
|
||||||
|
#define LEN_SPD 6 /// bytes in the speed over ground field
|
||||||
|
#define LEN_TRK 8 /// bytes in the ground track field
|
||||||
|
#define LEN_TIME 10 /// bytes in the time of fix field
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
bool sgEncodeGPS(uint8_t *buffer, sg_gps_t *gps, uint8_t msgId)
|
||||||
|
{
|
||||||
|
// populate header
|
||||||
|
buffer[0] = SG_MSG_START_BYTE;
|
||||||
|
buffer[1] = SG_MSG_TYPE_HOST_GPS;
|
||||||
|
buffer[2] = msgId;
|
||||||
|
buffer[3] = SG_PAYLOAD_LEN_GPS;
|
||||||
|
|
||||||
|
// populate longitude
|
||||||
|
charArray2Buf(&buffer[PBASE + OFFSET_LONGITUDE], gps->longitude, LEN_LNG);
|
||||||
|
|
||||||
|
// populate latitude
|
||||||
|
charArray2Buf(&buffer[PBASE + OFFSET_LATITUDE], gps->latitude, LEN_LAT);
|
||||||
|
|
||||||
|
// populate ground speed
|
||||||
|
charArray2Buf(&buffer[PBASE + OFFSET_SPEED], gps->grdSpeed, LEN_SPD);
|
||||||
|
|
||||||
|
// populate ground track
|
||||||
|
charArray2Buf(&buffer[PBASE + OFFSET_TRACK], gps->grdTrack, LEN_TRK);
|
||||||
|
|
||||||
|
// populate hemisphere/data status
|
||||||
|
buffer[PBASE + OFFSET_STATUS] = !gps->gpsValid << 7 |
|
||||||
|
gps->fdeFail << 6 |
|
||||||
|
gps->lngEast << 1 |
|
||||||
|
gps->latNorth;
|
||||||
|
|
||||||
|
// populate time of fix
|
||||||
|
charArray2Buf(&buffer[PBASE + OFFSET_TIME], gps->timeOfFix, LEN_TIME);
|
||||||
|
|
||||||
|
// populate gnss height
|
||||||
|
float2Buf(&buffer[PBASE + OFFSET_HEIGHT], gps->height);
|
||||||
|
|
||||||
|
// populate HPL
|
||||||
|
float2Buf(&buffer[PBASE + OFFSET_HPL], gps->hpl);
|
||||||
|
|
||||||
|
// populate HFOM
|
||||||
|
float2Buf(&buffer[PBASE + OFFSET_HFOM], gps->hfom);
|
||||||
|
|
||||||
|
// populate VFOM
|
||||||
|
float2Buf(&buffer[PBASE + OFFSET_VFOM], gps->vfom);
|
||||||
|
|
||||||
|
// populate NACv
|
||||||
|
buffer[PBASE + OFFSET_NACV] = gps->nacv << 4;
|
||||||
|
|
||||||
|
// populate checksum
|
||||||
|
appendChecksum(buffer, SG_MSG_LEN_GPS);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,132 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file sgEncodeInstall.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Feb 23, 2021
|
||||||
|
*
|
||||||
|
* This file receives a populated installation message struct and
|
||||||
|
* converts it into a installation message buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "sg.h"
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define SG_PAYLOAD_LEN_INSTALL SG_MSG_LEN_INSTALL - 5 /// the payload length.
|
||||||
|
|
||||||
|
#define PBASE 4 /// the payload offset.
|
||||||
|
#define OFFSET_ICAO 0 /// the icao address offset in the payload.
|
||||||
|
#define OFFSET_REG 3 /// the registration offset in the payload.
|
||||||
|
#define OFFSET_RSVD1 10 /// the first reserved field offset in the payload.
|
||||||
|
#define OFFSET_COM0 12 /// the COM port 0 offset in the payload.
|
||||||
|
#define OFFSET_COM1 13 /// the COM port 1 offset in the payload.
|
||||||
|
#define OFFSET_IP 14 /// the IP address offset in the payload.
|
||||||
|
#define OFFSET_MASK 18 /// the net mask offset in the payload.
|
||||||
|
#define OFFSET_PORT 22 /// the port number offset in the payload.
|
||||||
|
#define OFFSET_GPS 24 /// the GPS integrity offset in the payload.
|
||||||
|
#define OFFSET_EMIT_SET 25 /// the emitter category offset in the payload.
|
||||||
|
#define OFFSET_EMIT_TYPE 26 /// the emitter type offset in the payload.
|
||||||
|
#define OFFSET_SIZE 27 /// the aircraft size offset in the payload.
|
||||||
|
#define OFFSET_SPEED 28 /// the maximum airspeed offset in the payload.
|
||||||
|
#define OFFSET_ENCODER 29 /// the altitude-encoder-offset offset in the payload.
|
||||||
|
#define OFFSET_RSVD2 31 /// the second reserved field offset in the payload.
|
||||||
|
#define OFFSET_CONFIG 33 /// the configuration offset in the payload.
|
||||||
|
#define OFFSET_RSVD3 34 /// the third reserved field offset in the payload.
|
||||||
|
|
||||||
|
#define REG_LEN 7 /// the registration field length.
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
bool sgEncodeInstall(uint8_t *buffer, sg_install_t *stl, uint8_t msgId)
|
||||||
|
{
|
||||||
|
// populate header
|
||||||
|
buffer[0] = SG_MSG_START_BYTE;
|
||||||
|
buffer[1] = SG_MSG_TYPE_HOST_INSTALL;
|
||||||
|
buffer[2] = msgId;
|
||||||
|
buffer[3] = SG_PAYLOAD_LEN_INSTALL;
|
||||||
|
|
||||||
|
// populate icao address
|
||||||
|
icao2Buf(&buffer[PBASE + OFFSET_ICAO], stl->icao);
|
||||||
|
|
||||||
|
// populate aircraft registration
|
||||||
|
charArray2Buf(&buffer[PBASE + OFFSET_REG], stl->reg, REG_LEN);
|
||||||
|
|
||||||
|
// populate reserved fields
|
||||||
|
uint162Buf(&buffer[PBASE + OFFSET_RSVD1], 0);
|
||||||
|
|
||||||
|
// populate COM port 0, correct enum offset
|
||||||
|
buffer[PBASE + OFFSET_COM0] = stl->com0;
|
||||||
|
|
||||||
|
// populate COM port 1, correct enum offset
|
||||||
|
buffer[PBASE + OFFSET_COM1] = stl->com1;
|
||||||
|
|
||||||
|
// populate IP address
|
||||||
|
uint322Buf(&buffer[PBASE + OFFSET_IP], stl->eth.ipAddress);
|
||||||
|
|
||||||
|
// populate net mask
|
||||||
|
uint322Buf(&buffer[PBASE + OFFSET_MASK], stl->eth.subnetMask);
|
||||||
|
|
||||||
|
// populate port number
|
||||||
|
uint162Buf(&buffer[PBASE + OFFSET_PORT], stl->eth.portNumber);
|
||||||
|
|
||||||
|
// populate gps integrity
|
||||||
|
buffer[PBASE + OFFSET_GPS] = stl->sil << 4 |
|
||||||
|
stl->sda;
|
||||||
|
|
||||||
|
// populate emitter category set and type
|
||||||
|
uint8_t emitSet;
|
||||||
|
uint8_t emitType;
|
||||||
|
|
||||||
|
if (stl->emitter < SG_EMIT_OFFSET_B) { // group A
|
||||||
|
emitSet = SG_EMIT_GROUP_A;
|
||||||
|
emitType = stl->emitter - SG_EMIT_OFFSET_A;
|
||||||
|
|
||||||
|
} else if (stl->emitter < SG_EMIT_OFFSET_C) { // group B
|
||||||
|
emitSet = SG_EMIT_GROUP_B;
|
||||||
|
emitType = stl->emitter - SG_EMIT_OFFSET_B;
|
||||||
|
|
||||||
|
} else if (stl->emitter < SG_EMIT_OFFSET_D) { // group C
|
||||||
|
emitSet = SG_EMIT_GROUP_C;
|
||||||
|
emitType = stl->emitter - SG_EMIT_OFFSET_C;
|
||||||
|
|
||||||
|
} else { // group D
|
||||||
|
emitSet = SG_EMIT_GROUP_D;
|
||||||
|
emitType = stl->emitter - SG_EMIT_OFFSET_D;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer[PBASE + OFFSET_EMIT_SET] = emitSet;
|
||||||
|
buffer[PBASE + OFFSET_EMIT_TYPE] = emitType;
|
||||||
|
|
||||||
|
// populate aircraft size
|
||||||
|
buffer[PBASE + OFFSET_SIZE] = stl->size;
|
||||||
|
|
||||||
|
// populate max airspeed
|
||||||
|
buffer[PBASE + OFFSET_SPEED] = stl->maxSpeed;
|
||||||
|
|
||||||
|
// populate altitude encoder offset
|
||||||
|
uint162Buf(&buffer[PBASE + OFFSET_ENCODER], stl->altOffset);
|
||||||
|
|
||||||
|
// populate reserved fields
|
||||||
|
uint162Buf(&buffer[PBASE + OFFSET_RSVD2], 0);
|
||||||
|
|
||||||
|
// populate install configuration
|
||||||
|
buffer[PBASE + OFFSET_CONFIG] = stl->wowConnected << 7 |
|
||||||
|
stl->heater << 6 |
|
||||||
|
stl->airspeedTrue << 5 |
|
||||||
|
stl->hdgTrueNorth << 4 |
|
||||||
|
stl->altRes100 << 3 |
|
||||||
|
stl->antenna;
|
||||||
|
|
||||||
|
// populate reserved fields
|
||||||
|
uint162Buf(&buffer[PBASE + OFFSET_RSVD3], 0);
|
||||||
|
|
||||||
|
// populate checksum
|
||||||
|
appendChecksum(buffer, SG_MSG_LEN_INSTALL);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,107 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file sgEncodeOperating.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Feb 15, 2021
|
||||||
|
*
|
||||||
|
* This file receives a populated operating message struct and
|
||||||
|
* converts it into a operating message buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "sg.h"
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define SG_PAYLOAD_LEN_OPMSG SG_MSG_LEN_OPMSG - 5 /// the payload length.
|
||||||
|
|
||||||
|
#define PBASE 4 /// the payload offset.
|
||||||
|
#define OFFSET_SQUAWK 0 /// the squawk code offset in the payload.
|
||||||
|
#define OFFSET_CONFIG 2 /// the mode/config offset in the payload.
|
||||||
|
#define OFFSET_EMRG_ID 3 /// the emergency flag offset in the payload.
|
||||||
|
#define OFFSET_ALT 4 /// the altitude offset in the payload.
|
||||||
|
#define OFFSET_RATE 6 /// the climb rate offset in the payload.
|
||||||
|
#define OFFSET_HEADING 8 /// the heading offset in the payload.
|
||||||
|
#define OFFSET_AIRSPEED 10 /// the airspeed offset in the payload.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
bool sgEncodeOperating(uint8_t *buffer, sg_operating_t *op, uint8_t msgId)
|
||||||
|
{
|
||||||
|
// populate header
|
||||||
|
buffer[0] = SG_MSG_START_BYTE;
|
||||||
|
buffer[1] = SG_MSG_TYPE_HOST_OPMSG;
|
||||||
|
buffer[2] = msgId;
|
||||||
|
buffer[3] = SG_PAYLOAD_LEN_OPMSG;
|
||||||
|
|
||||||
|
// populate Squawk code
|
||||||
|
uint162Buf(&buffer[PBASE + OFFSET_SQUAWK], op->squawk);
|
||||||
|
|
||||||
|
// populate Mode/Config
|
||||||
|
buffer[PBASE + OFFSET_CONFIG] = op->milEmergency << 5 |
|
||||||
|
op->enableXBit << 4 |
|
||||||
|
op->enableSqt << 3 |
|
||||||
|
op->savePowerUp << 2 |
|
||||||
|
op->opMode;
|
||||||
|
|
||||||
|
// populate Emergency/Ident
|
||||||
|
buffer[PBASE + OFFSET_EMRG_ID] = op->identOn << 3 |
|
||||||
|
op->emergcType;
|
||||||
|
|
||||||
|
// populate Altitude
|
||||||
|
uint16_t altCode = 0;
|
||||||
|
|
||||||
|
if (op->altUseIntrnl) {
|
||||||
|
altCode = 0x8000;
|
||||||
|
|
||||||
|
} else if (op->altHostAvlbl) {
|
||||||
|
// 100 foot encoding conversion
|
||||||
|
altCode = (op->altitude + 1200) / 100;
|
||||||
|
|
||||||
|
if (op->altRes25) {
|
||||||
|
altCode *= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'Host altitude available' flag
|
||||||
|
altCode += 0x4000;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint162Buf(&buffer[PBASE + OFFSET_ALT], altCode);
|
||||||
|
|
||||||
|
// populate Altitude Rate
|
||||||
|
int16_t rate = op->climbRate / 64;
|
||||||
|
|
||||||
|
if (!op->climbValid) {
|
||||||
|
rate = 0x8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint162Buf(&buffer[PBASE + OFFSET_RATE], rate);
|
||||||
|
|
||||||
|
// populate Heading
|
||||||
|
// conversion: heading * ( pow(2, 15) / 360 )
|
||||||
|
uint16_t heading = op->heading * 32768 / 360;
|
||||||
|
|
||||||
|
if (op->headingValid) {
|
||||||
|
heading += 0x8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint162Buf(&buffer[PBASE + OFFSET_HEADING], heading);
|
||||||
|
|
||||||
|
// populate Airspeed
|
||||||
|
uint16_t airspeed = op->airspd;
|
||||||
|
|
||||||
|
if (op->airspdValid) {
|
||||||
|
airspeed += 0x8000;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint162Buf(&buffer[PBASE + OFFSET_AIRSPEED], airspeed);
|
||||||
|
|
||||||
|
// populate checksum
|
||||||
|
appendChecksum(buffer, SG_MSG_LEN_OPMSG);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file sgEncodeTargetReq.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Feb 19, 2021
|
||||||
|
*
|
||||||
|
* This file receives a populated target request struct and
|
||||||
|
* converts it into a target request message buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "sg.h"
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define SG_PAYLOAD_LEN_TARGETREQ SG_MSG_LEN_TARGETREQ - 5 /// the payload length.
|
||||||
|
|
||||||
|
#define PBASE 4 /// the payload offset.
|
||||||
|
|
||||||
|
#define OFFSET_REQ_TYPE 0 /// the adsb reporting type and transmit port offset
|
||||||
|
#define OFFSET_MAX_TARGETS 1 /// the maximum number of targets offset
|
||||||
|
#define OFFSET_ICAO 3 /// the requested target icao offset
|
||||||
|
#define OFFSET_REPORTS 6 /// the requested report type offset
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
bool sgEncodeTargetReq(uint8_t *buffer, sg_targetreq_t *tgt, uint8_t msgId)
|
||||||
|
{
|
||||||
|
|
||||||
|
// populate header
|
||||||
|
buffer[0] = SG_MSG_START_BYTE;
|
||||||
|
buffer[1] = SG_MSG_TYPE_HOST_TARGETREQ;
|
||||||
|
buffer[2] = msgId;
|
||||||
|
buffer[3] = SG_PAYLOAD_LEN_TARGETREQ;
|
||||||
|
|
||||||
|
// populate Request Type
|
||||||
|
buffer[PBASE + OFFSET_REQ_TYPE] = tgt->transmitPort << 6 |
|
||||||
|
tgt->reqType;
|
||||||
|
|
||||||
|
// populate Max Targets
|
||||||
|
uint162Buf(&buffer[PBASE + OFFSET_MAX_TARGETS], tgt->maxTargets);
|
||||||
|
|
||||||
|
// populate Requested ICAO
|
||||||
|
icao2Buf(&buffer[PBASE + OFFSET_ICAO], tgt->icao);
|
||||||
|
|
||||||
|
// populated Requested Reports
|
||||||
|
buffer[PBASE + OFFSET_REPORTS] = tgt->ownship << 7 |
|
||||||
|
tgt->commA << 6 |
|
||||||
|
tgt->military << 5 |
|
||||||
|
tgt->tisb << 4 |
|
||||||
|
tgt->airRefVel << 3 |
|
||||||
|
tgt->targetState << 2 |
|
||||||
|
tgt->modeStatus << 1 |
|
||||||
|
tgt->stateVector;
|
||||||
|
|
||||||
|
// populate checksum
|
||||||
|
appendChecksum(buffer, SG_MSG_LEN_TARGETREQ);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,325 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file sgUtil.h
|
||||||
|
* @author jimb
|
||||||
|
*
|
||||||
|
* @date Feb 2, 2021
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UTIL_H
|
||||||
|
#define UTIL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef swap16
|
||||||
|
#define swap16(data) \
|
||||||
|
((((data) >> 8) & 0x00FF) | (((data) << 8) & 0xFF00))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef swap24
|
||||||
|
#define swap24(data) \
|
||||||
|
(((data) >> 16) | ((data)&0x00FF00) | (((data) << 16) & 0xFF0000))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef swap32
|
||||||
|
#define swap32(data) \
|
||||||
|
(((data) >> 24) | (((data)&0x00FF0000) >> 8) | (((data)&0x0000FF00) << 8) | ((data) << 24))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef swap64
|
||||||
|
#define swap64(data) \
|
||||||
|
(swap32((data & 0x00000000ffffffffULL))) << 32 | swap32(data >> 32))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PI
|
||||||
|
#define PI 3.14159265359
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef toRad
|
||||||
|
#define toRad(deg) \
|
||||||
|
((deg)*PI / 180.0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef toDeg
|
||||||
|
#define toDeg(rad) \
|
||||||
|
((rad)*180 / PI)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef toMeter
|
||||||
|
#define toMeter(feet) \
|
||||||
|
((feet)*0.3048)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef toFeet
|
||||||
|
#define toFeet(meter) \
|
||||||
|
((meter)*3.2808)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array of bytes to a 16 bit integer.
|
||||||
|
*
|
||||||
|
* @param bytes The array of bytes to convert.
|
||||||
|
*
|
||||||
|
* @return The 16 bit integer.
|
||||||
|
*/
|
||||||
|
int16_t toInt16(const uint8_t bytes[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array of bytes to a 32 bit integer.
|
||||||
|
*
|
||||||
|
* @param bytes The array of bytes to convert.
|
||||||
|
*
|
||||||
|
* @return The 32 bit integer.
|
||||||
|
*/
|
||||||
|
int32_t toInt32(const uint8_t bytes[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array of bytes to a 16 unsigned bit integer.
|
||||||
|
*
|
||||||
|
* @param bytes The array of bytes to convert.
|
||||||
|
*
|
||||||
|
* @return The 16 bit integer.
|
||||||
|
*/
|
||||||
|
uint16_t toUint16(const uint8_t bytes[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array of bytes to a 24 bit unsigned integer with leading 0s.
|
||||||
|
*
|
||||||
|
* @param bytes The array of bytes to convert.
|
||||||
|
*
|
||||||
|
* @return The 24 bit unsigned integer with leading 0s.
|
||||||
|
*/
|
||||||
|
uint32_t toUint24(const uint8_t bytes[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array of bytes to a 32 bit unsigned integer.
|
||||||
|
*
|
||||||
|
* @param bytes The array of bytes to convert.
|
||||||
|
*
|
||||||
|
* @return The 32 bit unsigned integer.
|
||||||
|
*/
|
||||||
|
uint32_t toUint32(const uint8_t bytes[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array of bytes to a distance.
|
||||||
|
*
|
||||||
|
* @param bytes The array of bytes to convert.
|
||||||
|
*
|
||||||
|
* @return The distance value.
|
||||||
|
*/
|
||||||
|
double toDist(const uint8_t *bytes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array of bytes to a 24 bit unsigned integer with leading 0's.
|
||||||
|
*
|
||||||
|
* @param bytes The array of bytes to convert.
|
||||||
|
*
|
||||||
|
* @return The 32 bit unsigned integer.
|
||||||
|
*/
|
||||||
|
uint32_t toIcao(const uint8_t bytes[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array of bytes to a lat/lon floating point number.
|
||||||
|
*
|
||||||
|
* @param bytes The array of bytes to convert.
|
||||||
|
*
|
||||||
|
* @return The lat/lon value.
|
||||||
|
*/
|
||||||
|
double toLatLon(const uint8_t bytes[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an array to an altitude.
|
||||||
|
*
|
||||||
|
* @param bytes The bytes to get the altitude from.
|
||||||
|
*
|
||||||
|
* @return The converted altitude.
|
||||||
|
*/
|
||||||
|
double toAlt(const uint8_t bytes[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array of bytes to an airborne velocity.
|
||||||
|
*
|
||||||
|
* @param bytes The bytes to extract the velocity.
|
||||||
|
*
|
||||||
|
* @return The converted velocity.
|
||||||
|
*/
|
||||||
|
double toVel(const uint8_t bytes[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the array of bytes to the surface ground speed.
|
||||||
|
*
|
||||||
|
* @param bytes The bytes to extract the ground speed.
|
||||||
|
*
|
||||||
|
* @return The converted ground speed.
|
||||||
|
*/
|
||||||
|
uint8_t toGS(const uint8_t bytes[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the bytes into the heading value.
|
||||||
|
*
|
||||||
|
* @param bytes The bytes holding the heading value.
|
||||||
|
*
|
||||||
|
* @return The heading.
|
||||||
|
*/
|
||||||
|
double toHeading(const uint8_t bytes[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine heading from y and x speed vectors.
|
||||||
|
*
|
||||||
|
* @param y The y speed vector.
|
||||||
|
* @param x The x speed vector.
|
||||||
|
*
|
||||||
|
* @return The resulting heading.
|
||||||
|
*/
|
||||||
|
int16_t toHeading2(double y, double x);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the array of bytes to a time of applicability (TOA).
|
||||||
|
*
|
||||||
|
* @param bytes The bytes to convert to a TOA.
|
||||||
|
*
|
||||||
|
* @return The converted TOA.
|
||||||
|
*/
|
||||||
|
float toTOA(const uint8_t bytes[]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an array of bytes to a float
|
||||||
|
*
|
||||||
|
* @param bufferPos the address of the field's first corresponding buffer byte.
|
||||||
|
*
|
||||||
|
* @return The converted float value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
float toFloat(const uint8_t *bufferPos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an array of bytes to a double
|
||||||
|
*
|
||||||
|
* @param bufferPos the address of the field's first corresponding buffer byte.
|
||||||
|
*
|
||||||
|
* @return The converted double value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
double toDouble(const uint8_t *bufferPos);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a uint16_t into its host message buffer format
|
||||||
|
*
|
||||||
|
* @param bufferPos The address of the field's first corresponding buffer byte.
|
||||||
|
* @param value The uint16_t to be converted.
|
||||||
|
*
|
||||||
|
* no return value, two buffer bytes are filled by reference
|
||||||
|
*/
|
||||||
|
void uint162Buf(uint8_t *bufferPos, uint16_t value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a int16_t into its host message buffer format
|
||||||
|
*
|
||||||
|
* @param bufferPos The address of the field's first corresponding buffer byte.
|
||||||
|
* @param value The int32_t to be converted.
|
||||||
|
*
|
||||||
|
* no return value, two buffer bytes are filled by reference
|
||||||
|
*/
|
||||||
|
void int242Buf(uint8_t *bufferPos, int32_t value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a uint32_t into a 24 bit host message buffer format
|
||||||
|
*
|
||||||
|
* @param bufferPos The address of the field's first corresponding buffer byte.
|
||||||
|
* @param value The int32_t to be converted.
|
||||||
|
*
|
||||||
|
* no return value, three buffer bytes are filled by reference
|
||||||
|
*/
|
||||||
|
void uint242Buf(uint8_t *bufferPos, uint32_t value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a uint32_t into its host message buffer format
|
||||||
|
*
|
||||||
|
* @param bufferPos The address of the field's first corresponding buffer byte.
|
||||||
|
* @param value The uint32_t to be converted.
|
||||||
|
*
|
||||||
|
* no return value, two buffer bytes are filled by reference
|
||||||
|
*/
|
||||||
|
void uint322Buf(uint8_t *bufferPos, uint32_t value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a uint32_t containing an ICAO into its 24-bit host message buffer format
|
||||||
|
*
|
||||||
|
* @param bufferPos The address of the field's first corresponding buffer byte.
|
||||||
|
* @param icao The uint32_t ICAO to be converted.
|
||||||
|
*
|
||||||
|
* no return value, three buffer bytes are filled by reference
|
||||||
|
*
|
||||||
|
* @warning icao parameter must be between 0x000000 and 0xFFFFFF
|
||||||
|
*/
|
||||||
|
void icao2Buf(uint8_t *bufferPos, uint32_t icao);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an array of characters into its host message buffer format
|
||||||
|
*
|
||||||
|
* @param bufferPos The address of the field's first corresponding buffer byte.
|
||||||
|
* @param arr[] The array of characters.
|
||||||
|
* @param len The number of characters in the array.
|
||||||
|
*
|
||||||
|
* no return value, the specified quantity of buffer bytes are filled by reference
|
||||||
|
*/
|
||||||
|
void charArray2Buf(uint8_t *bufferPos, char arr[], uint8_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a float into its host message buffer format
|
||||||
|
*
|
||||||
|
* @param bufferPos The address of the field's first corresponding buffer byte.
|
||||||
|
* @param value The float to be converted.
|
||||||
|
*
|
||||||
|
* no return value, four buffer bytes are filled by reference
|
||||||
|
*
|
||||||
|
* @warning The output of this function depends on the machine's endianness. It is designed
|
||||||
|
* for Little-Endian machines, only.
|
||||||
|
*/
|
||||||
|
void float2Buf(uint8_t *bufferPos, float value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a double into its host message buffer format
|
||||||
|
*
|
||||||
|
* @param bufferPos The address of the field's first corresponding buffer byte
|
||||||
|
* @param value The double to be converted
|
||||||
|
*
|
||||||
|
* no return value, eight buffer bytes are filled by reference
|
||||||
|
*
|
||||||
|
* @warning The output of this function depends on the machine's endianness. It is designed
|
||||||
|
* for Little-Endian machines, only
|
||||||
|
*/
|
||||||
|
void double2Buf(uint8_t *bufferPos, double value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a double into an encoded lat/lon buffer format.
|
||||||
|
*
|
||||||
|
* @param bytes address of the field's first corresponding buffer byte
|
||||||
|
* @param value the double to be converted.
|
||||||
|
*
|
||||||
|
* no return value, 3 buffer bytes are filled by reference.
|
||||||
|
*/
|
||||||
|
void latLon2Buf(uint8_t bytes[], double value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate checksum for a host message.
|
||||||
|
*
|
||||||
|
* @param buffer The raw message buffer.
|
||||||
|
* @param len The total quantity of bytes in the buffer
|
||||||
|
*
|
||||||
|
* @return The resulting checksum.
|
||||||
|
*/
|
||||||
|
uint8_t calcChecksum(uint8_t *buffer, uint8_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the checksum to a host message.
|
||||||
|
*
|
||||||
|
* @param buffer The raw message buffer.
|
||||||
|
* @param len The total quantity of bytes in the buffer
|
||||||
|
*
|
||||||
|
* no return value, final buffer byte is set to the checksum value.
|
||||||
|
*/
|
||||||
|
void appendChecksum(uint8_t *buffer, uint8_t len);
|
||||||
|
|
||||||
|
#endif /* UTIL_H */
|
|
@ -0,0 +1,127 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2020 SoftSolutions, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @File: target.c
|
||||||
|
* @Author: jim billmeyer
|
||||||
|
*
|
||||||
|
* @date December 11, 2020, 12:50 AM
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
|
static ownship_t ownship;
|
||||||
|
static target_t targets[XPNDR_ADSB_TARGETS] = {
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
target_t *targetList(void)
|
||||||
|
{
|
||||||
|
return targets;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
ownship_t *targetOwnship(void)
|
||||||
|
{
|
||||||
|
return &ownship;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
target_t *targetFind(uint32_t icao)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0; i < XPNDR_ADSB_TARGETS; i++) {
|
||||||
|
if (icao == targets[i].icao) {
|
||||||
|
// clear strike counter and set find flag while preserving the used bit.
|
||||||
|
targets[i].flag = TARGET_FLAG_FOUND | TARGET_FLAG_USED;
|
||||||
|
return &targets[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
void targetPurge(void)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0; i < XPNDR_ADSB_TARGETS; i++) {
|
||||||
|
// the the found flag was not set increment the strike counter.
|
||||||
|
if ((targets[i].flag & TARGET_FLAG_USED) && ((targets[i].flag & TARGET_FLAG_FOUND) == 0)) {
|
||||||
|
uint8_t strikes = (targets[i].flag & 0xFE) >> 2;
|
||||||
|
strikes++;
|
||||||
|
|
||||||
|
if (strikes > 5) {
|
||||||
|
memset(&targets[i], 0, sizeof(target_t));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// set the strike counter and clear the found flag.
|
||||||
|
targets[i].flag = strikes << 2 | TARGET_FLAG_USED;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// clear the found flag so the target find function can set it
|
||||||
|
// to signal that the icao address is still in range.
|
||||||
|
targets[i].flag = targets[i].flag & (TARGET_FLAG_STRIKE_MASK | TARGET_FLAG_USED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
void targetAdd(target_t *target)
|
||||||
|
{
|
||||||
|
for (uint16_t i = 0; i < XPNDR_ADSB_TARGETS; i++) {
|
||||||
|
if ((targets[i].flag & TARGET_FLAG_USED) == 0x0) {
|
||||||
|
memcpy(&targets[i], target, sizeof(target_t));
|
||||||
|
targets[i].flag = TARGET_FLAG_USED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
targetclimb_t targetClimb(int16_t vrate)
|
||||||
|
{
|
||||||
|
if (abs(vrate) < 500) {
|
||||||
|
return trafLevel;
|
||||||
|
|
||||||
|
} else if (vrate > 0) {
|
||||||
|
return trafClimb;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return trafDescend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
targetalert_t targetAlert(double dist,
|
||||||
|
uint16_t alt,
|
||||||
|
int16_t nvel,
|
||||||
|
int16_t evel)
|
||||||
|
{
|
||||||
|
if (alt <= 3000) {
|
||||||
|
if (dist <= 3.0) {
|
||||||
|
return trafResolution;
|
||||||
|
|
||||||
|
} else if (dist <= 6.0) {
|
||||||
|
return trafAdvisory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return trafTraffic;
|
||||||
|
}
|
|
@ -0,0 +1,128 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2020 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @File: target.h
|
||||||
|
* @Author: jim billmeyer
|
||||||
|
*
|
||||||
|
* @date December 11, 2020, 12:49 AM
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TARGET_H
|
||||||
|
#define TARGET_H
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define XPNDR_ADSB_TARGETS 400 // change this to the max number of
|
||||||
|
// target supported in the system.
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
trafLevel,
|
||||||
|
trafClimb,
|
||||||
|
trafDescend
|
||||||
|
} targetclimb_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
trafTraffic,
|
||||||
|
trafAdvisory,
|
||||||
|
trafResolution
|
||||||
|
} targetalert_t;
|
||||||
|
|
||||||
|
// bit 0 - target found flag.
|
||||||
|
// bit 1 - target slot in use.
|
||||||
|
// bits 2-7 - the strike counter.
|
||||||
|
#define TARGET_FLAG_FOUND 0x01
|
||||||
|
#define TARGET_FLAG_USED 0x02
|
||||||
|
#define TARGET_FLAG_STRIKE_MASK 0xFC
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed))
|
||||||
|
{
|
||||||
|
uint32_t icao;
|
||||||
|
bool airborne;
|
||||||
|
float bearing;
|
||||||
|
uint8_t distance;
|
||||||
|
int8_t altDiff;
|
||||||
|
int16_t nvel;
|
||||||
|
int16_t evel;
|
||||||
|
targetclimb_t climb;
|
||||||
|
targetalert_t alert;
|
||||||
|
#ifdef TARGET_SVR
|
||||||
|
msg_svr_t svr;
|
||||||
|
#endif
|
||||||
|
uint8_t flag; // used internally to purge stale targets.
|
||||||
|
} target_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t icao;
|
||||||
|
bool airborne;
|
||||||
|
float lat;
|
||||||
|
float lon;
|
||||||
|
int32_t alt;
|
||||||
|
int16_t heading;
|
||||||
|
uint16_t speed;
|
||||||
|
} ownship_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the target list.
|
||||||
|
*
|
||||||
|
* @return The array of traffic targets.
|
||||||
|
*/
|
||||||
|
target_t *targetList(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ownship target information.
|
||||||
|
*
|
||||||
|
* @return The ownship target info.
|
||||||
|
*/
|
||||||
|
ownship_t *targetOwnship(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a target based on its icao number.
|
||||||
|
*
|
||||||
|
* @param icao The target's icao number
|
||||||
|
*
|
||||||
|
* @return A pointer to the target element or null if not found.
|
||||||
|
*/
|
||||||
|
target_t *targetFind(uint32_t icao);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Purge the traffic target list of stale traffic.
|
||||||
|
*
|
||||||
|
* The traffic gets purged if a find has not been done based
|
||||||
|
* on a strike counter.
|
||||||
|
*/
|
||||||
|
void targetPurge(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a target to the traffic target list.
|
||||||
|
*
|
||||||
|
* @param target The target to add.
|
||||||
|
*/
|
||||||
|
void targetAdd(target_t *target);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the target climb flag based on the vertical rate.
|
||||||
|
*
|
||||||
|
* @param vrate The current vertical rate of climb for the target.
|
||||||
|
*
|
||||||
|
* @return The level, climb or descend flag.
|
||||||
|
*/
|
||||||
|
targetclimb_t targetClimb(int16_t vrate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the traffic alert flag.
|
||||||
|
*
|
||||||
|
* @param dist The distance of the target to the ownship.
|
||||||
|
* @param alt The altitude difference between the target and ownship.
|
||||||
|
* @param nvel The NS speed vector of the target.
|
||||||
|
* @param evel The EW speed vector of the target.
|
||||||
|
*
|
||||||
|
* @return The traffic flag based on the parameters.
|
||||||
|
*/
|
||||||
|
targetalert_t targetAlert(double dist,
|
||||||
|
uint16_t alt,
|
||||||
|
int16_t nvel,
|
||||||
|
int16_t evel);
|
||||||
|
|
||||||
|
#endif /* TARGET_H */
|
|
@ -0,0 +1,24 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file toAlt.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define SV_RES_ALT 0.015625
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
double toAlt(const uint8_t bytes[])
|
||||||
|
{
|
||||||
|
double value = toInt32(bytes);
|
||||||
|
value *= SV_RES_ALT;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file toGS.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
uint8_t toGS(const uint8_t bytes[])
|
||||||
|
{
|
||||||
|
uint8_t code = bytes[0];
|
||||||
|
float gs = 0.0f;
|
||||||
|
|
||||||
|
if (code <= 0x01) {
|
||||||
|
gs = 0.0f;
|
||||||
|
|
||||||
|
} else if (code <= 0x08) {
|
||||||
|
gs = 1.0f;
|
||||||
|
|
||||||
|
} else if (code <= 0x0C) {
|
||||||
|
gs = 1.0f + (code - 0x09) * 0.25f;
|
||||||
|
|
||||||
|
} else if (code <= 0x26) {
|
||||||
|
gs = 2.0f + (code - 0x0D) * 0.5f;
|
||||||
|
|
||||||
|
} else if (code <= 0x5D) {
|
||||||
|
gs = 15.0f + (code - 0x27) * 1.0f;
|
||||||
|
|
||||||
|
} else if (code <= 0x6C) {
|
||||||
|
gs = 70.0f + (code - 0x5E) * 2.0f;
|
||||||
|
|
||||||
|
} else if (code <= 0x7B) {
|
||||||
|
gs = 100.0f + (code - 0x6D) * 5.0f;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
gs = 176.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first converting to an 16 bit integer is necessary
|
||||||
|
// to keep the floating point conversion from
|
||||||
|
// truncating to 0.
|
||||||
|
return (uint8_t)((int16_t)gs & 0xFF);
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file toHeading.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define SV_RES_HEAD 1.40625
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
double toHeading(const uint8_t bytes[])
|
||||||
|
{
|
||||||
|
double value = bytes[0];
|
||||||
|
value *= SV_RES_HEAD;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file toHeading2.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
int16_t toHeading2(double y, double x)
|
||||||
|
{
|
||||||
|
int16_t heading = (toDeg(atan2(y, x)) + 0.5);
|
||||||
|
heading = 360 - heading + 90; // atan is ccw 0 degrees at x = 1 and y = 0.
|
||||||
|
|
||||||
|
if (heading > 360) {
|
||||||
|
heading -= 360;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
while (heading < 0) {
|
||||||
|
heading += 360;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return heading;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file toIcao.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 9, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
uint32_t toIcao(const uint8_t bytes[])
|
||||||
|
{
|
||||||
|
uint32_t icao = (0 << 24) | ((uint32_t)bytes[0] << 16) | ((uint32_t)bytes[1] << 8) | ((uint32_t)bytes[2]);
|
||||||
|
|
||||||
|
return icao;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file toInt16.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
int16_t toInt16(const uint8_t bytes[])
|
||||||
|
{
|
||||||
|
int16_t int16 = ((int16_t)bytes[0] << 8) | bytes[1];
|
||||||
|
|
||||||
|
return int16;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file toInt32.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
int32_t toInt32(const uint8_t bytes[])
|
||||||
|
{
|
||||||
|
int32_t int32 = ((int32_t)bytes[0] << 24) | ((int32_t)bytes[1] << 16) | ((int32_t)bytes[2] << 8);
|
||||||
|
int32 = int32 >> 8;
|
||||||
|
|
||||||
|
return int32;
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file toLatLon.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define SV_RES_LATLON 180.0 / 8388608.0 // 180 degrees / 2^23
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
double toLatLon(const uint8_t bytes[])
|
||||||
|
{
|
||||||
|
double value = toInt32(bytes);
|
||||||
|
value *= SV_RES_LATLON;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file toTOA.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
float toTOA(const uint8_t bytes[])
|
||||||
|
{
|
||||||
|
float toa = toInt16(bytes) & 0xFFFF;
|
||||||
|
return toa / (float) 128.0;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file toUint16.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 9, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
uint16_t toUint16(const uint8_t bytes[])
|
||||||
|
{
|
||||||
|
uint16_t uint16 = ((uint16_t) bytes[0] << 8 | (uint16_t) bytes[1]);
|
||||||
|
|
||||||
|
return uint16;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file toUint32.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
uint32_t toUint32(const uint8_t bytes[])
|
||||||
|
{
|
||||||
|
uint32_t uint32 = ((uint32_t) bytes[0] << 24) | ((uint32_t) bytes[1] << 16) | ((uint32_t) bytes[2] << 8) | ((
|
||||||
|
uint32_t) bytes[3]);
|
||||||
|
|
||||||
|
return uint32;
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file toVel.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
#define SV_RES_VEL 0.125
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
double toVel(const uint8_t bytes[])
|
||||||
|
{
|
||||||
|
double value = toInt16(bytes);
|
||||||
|
value *= SV_RES_VEL;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file uint162Buf.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
void uint162Buf(uint8_t *bufferPos, uint16_t value)
|
||||||
|
{
|
||||||
|
bufferPos[0] = value >> 8;
|
||||||
|
bufferPos[1] = value & 0xFF;
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* @copyright Copyright (c) 2021 Sagetech, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* @file uint322Buf.c
|
||||||
|
* @author Jacob.Garrison
|
||||||
|
*
|
||||||
|
* @date Mar 2, 2021
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "sgUtil.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Documented in the header file.
|
||||||
|
*/
|
||||||
|
void uint322Buf(uint8_t *bufferPos, uint32_t value)
|
||||||
|
{
|
||||||
|
bufferPos[0] = (value & 0xFF000000) >> 24;
|
||||||
|
bufferPos[1] = (value & 0x00FF0000) >> 16;
|
||||||
|
bufferPos[2] = (value & 0x0000FF00) >> 8;
|
||||||
|
bufferPos[3] = (value & 0x000000FF);
|
||||||
|
}
|
Loading…
Reference in New Issue