LCOV - code coverage report
Current view: top level - AP_RCProtocol - AP_RCProtocol_GHST.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 2 11 18.2 %
Date: 2026-09-09 11:02:08 Functions: 1 6 16.7 %

          Line data    Source code
       1             : /*
       2             :  * This file is free software: you can redistribute it and/or modify it
       3             :  * under the terms of the GNU General Public License as published by the
       4             :  * Free Software Foundation, either version 3 of the License, or
       5             :  * (at your option) any later version.
       6             :  *
       7             :  * This file is distributed in the hope that it will be useful, but
       8             :  * WITHOUT ANY WARRANTY; without even the implied warranty of
       9             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
      10             :  * See the GNU General Public License for more details.
      11             :  *
      12             :  * You should have received a copy of the GNU General Public License along
      13             :  * with this program.  If not, see <http://www.gnu.org/licenses/>.
      14             :  */
      15             : #pragma once
      16             : 
      17             : #include "AP_RCProtocol_config.h"
      18             : 
      19             : #if AP_RCPROTOCOL_GHST_ENABLED
      20             : 
      21             : #include "AP_RCProtocol.h"
      22             : #include <AP_Math/AP_Math.h>
      23             : #include <RC_Channel/RC_Channel.h>
      24             : #include "SoftSerial.h"
      25             : 
      26             : #define GHST_MAX_CHANNELS   16U      // Maximum number of channels from GHST datastream
      27             : #define GHST_FRAMELEN_MAX   14U      // maximum possible framelength
      28             : #define GHST_HEADER_LEN     2U       // header length
      29             : #define GHST_FRAME_PAYLOAD_MAX (GHST_FRAMELEN_MAX - GHST_HEADER_LEN)     // maximum size of the frame length field in a packet
      30             : #define GHST_BAUDRATE      420000U
      31             : #define GHST_TX_TIMEOUT    500000U   // the period after which the transmitter is considered disconnected (matches copters failsafe)
      32             : #define GHST_RX_TIMEOUT    150000U   // the period after which the receiver is considered disconnected (>ping frequency)
      33             : 
      34             : class AP_RCProtocol_GHST : public AP_RCProtocol_Backend {
      35             : public:
      36             :     AP_RCProtocol_GHST(AP_RCProtocol &_frontend);
      37             :     virtual ~AP_RCProtocol_GHST();
      38             :     void process_byte(uint8_t byte, uint32_t baudrate) override;
      39             :     void process_handshake(uint32_t baudrate) override;
      40             :     void update(void) override;
      41             : 
      42             :     // is the receiver active, used to detect power loss and baudrate changes
      43           0 :     bool is_rx_active() const override {
      44           0 :         return AP_HAL::micros() < _last_rx_frame_time_us + GHST_RX_TIMEOUT;
      45             :     }
      46             : 
      47             :     // is the transmitter active, used to adjust telemetry data
      48           0 :     bool is_tx_active() const {
      49             :         // this is the same as the Copter failsafe timeout
      50           0 :         return AP_HAL::micros() < _last_tx_frame_time_us + GHST_TX_TIMEOUT;
      51             :     }
      52             : 
      53             :     // get singleton instance
      54           0 :     static AP_RCProtocol_GHST* get_singleton() {
      55           0 :         return _singleton;
      56             :     }
      57             : 
      58             :     enum FrameType {
      59             :         GHST_UL_RC_CHANS_HS4_5TO8 = 0x10, // Control packet with 4 primary channels + CH5-8
      60             :         GHST_UL_RC_CHANS_HS4_9TO12 = 0x11, // Control packet with 4 primary channels + CH9-12
      61             :         GHST_UL_RC_CHANS_HS4_13TO16 = 0x12, // Control packet with 4 primary channels + CH13-16
      62             :         GHST_UL_RC_CHANS_RSSI = 0x13, // Control packet with RSSI and LQ data
      63             :         GHST_UL_RC_VTX_CTRL = 0x14, // Goggle/FC channel changing
      64             :         // -> 0x1F reserved
      65             :         GHST_UL_VTX_SETUP = 0x20, // vTx Setup w/o 4 primary channels (GECO Only)
      66             :         GHST_UL_MSP_REQ = 0x21, // MSP frame, Request
      67             :         GHST_UL_MSP_WRITE = 0x22, // MSP frame, Write
      68             : 
      69             :         GHST_DL_PACK_STAT = 0x23, // Battery Status
      70             :         GHST_DL_GPS_PRIMARY = 0x25, // Primary GPS Data
      71             :         GHST_DL_GPS_SECONDARY = 0x26, // Secondary GPS Data
      72             :         GHST_DL_MAGBARO = 0x27, // Magnetometer, Barometer (and Vario) Data
      73             :         GHST_DL_MSP_RESP = 0x28, // MSP Response
      74             : 
      75             :         GHST_UL_RC_CHANS_HS4_12_5TO8 = 0x30, // Control packet with 4 primary channels + CH5-8
      76             :         GHST_UL_RC_CHANS_HS4_12_9TO12 = 0x31, // Control packet with 4 primary channels + CH9-12
      77             :         GHST_UL_RC_CHANS_HS4_12_13TO16 = 0x32, // Control packet with 4 primary channels + CH13-16
      78             :         GHST_UL_RC_CHANS_12_RSSI = 0x33, // Control packet with RSSI and LQ data
      79             :         // 0x30 -> 0x3f - raw 12 bit packets
      80             :     };
      81             : 
      82             :     enum DeviceAddress {
      83             :         GHST_ADDRESS_FLIGHT_CONTROLLER = 0x82,
      84             :         GHST_ADDRESS_GOGGLES = 0x83,
      85             :         GHST_ADDRESS_GHST_RECEIVER = 0x89,
      86             :     };
      87             : 
      88             :     struct Frame {
      89             :         uint8_t device_address;
      90             :         uint8_t length;
      91             :         uint8_t type;
      92             :         uint8_t payload[GHST_FRAME_PAYLOAD_MAX - 1]; // type is already accounted for
      93             :     } PACKED;
      94             : 
      95             :     struct Channels12Bit_4Chan {
      96             : #if __BYTE_ORDER != __LITTLE_ENDIAN
      97             : #error "Only supported on little-endian architectures"
      98             : #endif
      99             :         uint32_t ch0 : 12;
     100             :         uint32_t ch1 : 12;
     101             :         uint32_t ch2 : 12;
     102             :         uint32_t ch3 : 12;
     103             :     } PACKED;
     104             : 
     105             :     struct RadioFrame {
     106             : #if __BYTE_ORDER != __LITTLE_ENDIAN
     107             : #error "Only supported on little-endian architectures"
     108             : #endif
     109             :         Channels12Bit_4Chan channels;   // high-res channels
     110             :         uint8_t lowres_channels[4];     // low-res channels
     111             :     } PACKED;
     112             : 
     113             :     struct LinkStatisticsFrame {
     114             : #if __BYTE_ORDER != __LITTLE_ENDIAN
     115             : #error "Only supported on little-endian architectures"
     116             : #endif
     117             :         Channels12Bit_4Chan channels;
     118             :         uint8_t link_quality; // ( 0 - 100)
     119             :         uint8_t rssi_dbm; // ( dBm * -1 )
     120             :         uint8_t protocol : 5;
     121             :         uint8_t telemetry : 1;
     122             :         uint8_t alt_scale : 1;
     123             :         uint8_t reserved : 1;
     124             :         int8_t tx_power;
     125             :     } PACKED;
     126             : 
     127             :     enum RFMode {
     128             :         GHST_RF_MODE_NORMAL = 5,    // 55Hz
     129             :         GHST_RF_MODE_RACE = 6,      // 160Hz
     130             :         GHST_RF_MODE_PURERACE = 7,  // 250Hz
     131             :         GHST_RF_MODE_LR = 8,        // 19Hz
     132             :         GHST_RF_MODE_RACE250 = 10,  // 250Hz
     133             :         GHST_RF_MODE_RACE500 = 11,  // 500Hz
     134             :         GHTS_RF_MODE_SOLID150 = 12, // 150Hz
     135             :         GHST_RF_MODE_SOLID250 = 13, // 250Hz
     136             :         RF_MODE_MAX_MODES,
     137             :         RF_MODE_UNKNOWN,
     138             :     };
     139             : 
     140             :     struct LinkStatus {
     141             :         int16_t rssi = -1;
     142             :         int16_t link_quality = -1;
     143             :         uint8_t rf_mode;
     144             :     };
     145             : 
     146             :     bool is_telemetry_supported() const;
     147             : 
     148             :     // this will be used by AP_GHST_Telem to access link status data
     149             :     // from within AP_RCProtocol_GHST thread so no need for cross-thread synch
     150           0 :     const volatile LinkStatus& get_link_status() const {
     151           0 :         return _link_status;
     152             :     }
     153             : 
     154             :     // return the link rate as defined by the LinkStatistics
     155             :     uint16_t get_link_rate()  const;
     156             : 
     157             :     // return the protocol string
     158             :     const char* get_protocol_string() const;
     159             : 
     160             : private:
     161             :     struct Frame _frame;
     162             :     struct Frame _telemetry_frame;
     163             :     uint8_t _frame_ofs;
     164             :     uint8_t _frame_crc;
     165             : 
     166        2094 :     const uint8_t MAX_CHANNELS = MIN((uint8_t)GHST_MAX_CHANNELS, (uint8_t)MAX_RCIN_CHANNELS);
     167             : 
     168             :     static AP_RCProtocol_GHST* _singleton;
     169             : 
     170             :     void _process_byte(uint32_t timestamp_us, uint8_t byte);
     171             :     bool decode_ghost_packet();
     172             :     bool process_telemetry(bool check_constraint = true);
     173             :     void process_link_stats_frame(const void* data);
     174             :     bool write_frame(Frame* frame);
     175           4 :     AP_HAL::UARTDriver* get_current_UART() { return get_available_UART(); }
     176             : 
     177             :     uint16_t _channels[GHST_MAX_CHANNELS];    /* buffer for extracted RC channel data as pulsewidth in microseconds */
     178             : 
     179           0 :     void add_to_buffer(uint8_t index, uint8_t b) { ((uint8_t*)&_frame)[index] = b; }
     180             : 
     181             :     uint32_t _last_frame_time_us;
     182             :     uint32_t _last_tx_frame_time_us;
     183             :     uint32_t _last_rx_frame_time_us;
     184             :     uint32_t _start_frame_time_us;
     185             :     bool telem_available;
     186             :     bool _use_lq_for_rssi;
     187             :     int16_t derive_scaled_lq_value(uint8_t uplink_lq);
     188             : 
     189             :     volatile struct LinkStatus _link_status;
     190             : 
     191             :     static const uint16_t RF_MODE_RATES[RFMode::RF_MODE_MAX_MODES];
     192             : };
     193             : 
     194             : namespace AP {
     195             :     AP_RCProtocol_GHST* ghost();
     196             : };
     197             : 
     198             : #endif  // AP_RCPROTOCOL_GHST_ENABLED

Generated by: LCOV version 1.14