Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/libraries/AP_ADSB/AP_ADSB_Sagetech_MXS.h
Views: 1798
/*1* Copyright (C) 2022 Sagetech Avionics Inc. All rights reserved.2*3* This file is free software: you can redistribute it and/or modify it4* under the terms of the GNU General Public License as published by the5* Free Software Foundation, either version 3 of the License, or6* (at your option) any later version.7*8* This file is distributed in the hope that it will be useful, but9* WITHOUT ANY WARRANTY; without even the implied warranty of10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.11* See the GNU General Public License for more details.12*13* You should have received a copy of the GNU General Public License along14* with this program. If not, see <http://www.gnu.org/licenses/>.15*16* SDK specification17* https://github.com/Sagetech-Avionics/sagetech-mxs-sdk/blob/main/doc/pdf/ICD02373_MXS_Host_ICD.pdf18*19* Authors: Chuck Faber, Tom Pittenger20*/2122#pragma once2324#include "AP_ADSB_Backend.h"2526#if HAL_ADSB_SAGETECH_MXS_ENABLED2728#include "sagetech-sdk/sagetech_mxs.h"2930class AP_ADSB_Sagetech_MXS : public AP_ADSB_Backend {31public:32using AP_ADSB_Backend::AP_ADSB_Backend;3334/**35* @brief Performs required initialization for this instance36*37* @return true if initialization successful38*/39bool init() override;4041/**42* @brief The main callback function (Called with freq of 10Hz) that sends43* appropriate message types at specific times.44*45* Read Byte from Serial Port Buffer (10Hz)46* Send installation message (every 5 seconds)47* Send Flight ID (every 8.2 s)48* Send Operating Message (every second)49* Send GPS data (flying: 5Hz, not flying: 1Hz)50*51*/52void update() override;5354/**55* @brief Detect if a port is configured as Sagetech56*57* @return true58* @return false59*/60static bool detect();6162private:6364static const uint32_t PAYLOAD_MXS_MAX_SIZE = 255;65static const uint8_t START_BYTE = 0xAA;66static const uint8_t rf_capable_flags_default =67ADSB_BITBASK_RF_CAPABILITIES_1090ES_IN |68ADSB_BITBASK_RF_CAPABILITIES_1090ES_OUT;697071enum class MsgType : uint8_t {72Installation = SG_MSG_TYPE_HOST_INSTALL,73FlightID = SG_MSG_TYPE_HOST_FLIGHT,74Operating = SG_MSG_TYPE_HOST_OPMSG,75GPS_Data = SG_MSG_TYPE_HOST_GPS,76Data_Request = SG_MSG_TYPE_HOST_DATAREQ,77// RESERVED 0x06 - 0x0A78Target_Request = SG_MSG_TYPE_HOST_TARGETREQ,79Mode = SG_MSG_TYPE_HOST_MODE,80// RESERVED 0x0D - 0xC181ACK = SG_MSG_TYPE_XPNDR_ACK,82Installation_Response = SG_MSG_TYPE_XPNDR_INSTALL,83FlightID_Response = SG_MSG_TYPE_XPNDR_FLIGHT,84Status_Response = SG_MSG_TYPE_XPNDR_STATUS,85RESERVED_0x84 = 0x84,86RESERVED_0x85 = 0x85,87Mode_Settings = SG_MSG_TYPE_XPNDR_MODE,88RESERVED_0x8D = 0x8D,89Version_Response = SG_MSG_TYPE_XPNDR_VERSION,90Serial_Number_Response = SG_MSG_TYPE_XPNDR_SERIALNUM,91Target_Summary_Report = SG_MSG_TYPE_ADSB_TSUMMARY,9293ADSB_StateVector_Report = SG_MSG_TYPE_ADSB_SVR,94ADSB_ModeStatus_Report = SG_MSG_TYPE_ADSB_MSR,95ADSB_Target_State_Report= SG_MSG_TYPE_ADSB_TSTATE,96ADSB_Air_Ref_Vel_Report = SG_MSG_TYPE_ADSB_ARVR,97};9899enum class ParseState {100WaitingFor_Start,101WaitingFor_MsgType,102WaitingFor_MsgId,103WaitingFor_PayloadLen,104WaitingFor_PayloadContents,105WaitingFor_Checksum,106};107108struct __attribute__((packed)) Packet {109const uint8_t start = SG_MSG_START_BYTE;110MsgType type;111uint8_t id;112uint8_t payload_length;113uint8_t payload[PAYLOAD_MXS_MAX_SIZE];114};115116struct {117ParseState state;118uint8_t index;119Packet packet;120uint8_t checksum;121} message_in;122123/**124* @brief Given the dataReqType, send the appropriate data request message125*126* @param dataReqType127*/128void send_data_req(const sg_datatype_t dataReqType);129130/**131* @brief Takes incoming packets, gets their message type, and132* appropriately handles them with the correct callbacks.133*134* @param msg Message packet received, cast into Packet type.135*/136void handle_packet(const Packet &msg);137138/**139* @brief Sends data received from ADSB State Vector Report to AutoPilot140*141* @param svr142*/143void handle_svr(const sg_svr_t svr);144145/**146* @brief Handle a received ADSB mode status report and updates the vehicle list147*148* @param msr Sagetech SDK Mode Status Report type149*/150void handle_msr(const sg_msr_t msr);151152153/**154* @brief Handles an incoming byte and processes it through the state155* machine to determine if end of message is reached.156*157* @param data : incoming byte158* @return false : if not yet reached packet termination159*/160bool parse_byte(const uint8_t data);161162/**163* @brief Takes a raw buffer and writes it out to the device port.164*165* @param data : pointer to data buffer166* @param len : number of bytes to write167*/168void msg_write(const uint8_t *data, const uint16_t len) const;169170171/**172* @brief Callback for sending an installation message.173*174*/175void send_install_msg();176177/**178* @brief Callback for sending a FlightID message179*180*/181void send_flight_id_msg();182183/**184* @brief Callback for sending an operating message.185*186*/187void send_operating_msg();188189/**190* @brief Callback for sending a GPS data message191*192*/193void send_gps_msg();194195/**196* @brief Callback for sending a Target Request message197*198*/199void send_targetreq_msg();200201/**202* @brief Convert the AP_ADSB uint8_t Emitter Type to the Sagetech Emitter Type definition203*204* @param emitterType205* @return sg_emitter_t206*/207sg_emitter_t convert_emitter_type_to_sg(const uint8_t emitterType) const;208209/**210* @brief Convert the float maxAirSpeed value to the Sagetech Max Airspeed Type211*212* @param maxAirSpeed213* @return sg_airspeed_t214*/215sg_airspeed_t convert_airspeed_knots_to_sg(const float maxAirSpeed) const;216217/**218* @brief Converts a Sagetech Emitter type value to the values used by ADSB.219*220* @return uint8_t221*/222uint8_t convert_sg_emitter_type_to_adsb(const sg_emitter_t sgEmitterType) const;223224void auto_config_operating();225void auto_config_installation();226void auto_config_flightid();227void handle_ack(const sg_ack_t ack);228229struct {230// timers for each out-bound packet231uint32_t packet_initialize_ms;232uint32_t packet_PreFlight_ms;233uint32_t packet_GPS_ms;234uint32_t packet_Operating_ms;235uint32_t packet_targetReq;236237// cached variables to compare against params so we can send msg on param change.238uint16_t operating_squawk;239int32_t operating_alt;240uint8_t operating_rf_select;241bool modeAEnabled;242bool modeCEnabled;243bool modeSEnabled;244bool failXpdr;245bool failSystem;246uint8_t callsign[8];247struct {248uint8_t id;249uint8_t type;250} msg;251} last;252253struct {254bool init;255bool init_failed;256sg_operating_t op;257sg_install_t inst;258sg_targetreq_t treq;259sg_flightid_t fid;260sg_ack_t ack;261} mxs_state;262263// helper functions for populating the operating message:264void populate_op_altitude(const struct AP_ADSB::Loc &loc);265void populate_op_climbrate(const struct AP_ADSB::Loc &loc);266void populate_op_airspeed_and_heading(const struct AP_ADSB::Loc &loc);267268// last course-over-ground calculated from groundspeed vector.269// This is cached so we don't flip to a COG of 90-degrees when270// we stop moving.271float cog;272};273#endif // HAL_ADSB_SAGETECH_MXS_ENABLED274275276277