LCOV - code coverage report
Current view: top level - AP_Frsky_Telem - AP_Frsky_SPort_Passthrough.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 8 10 80.0 %
Date: 2026-09-09 11:02:08 Functions: 2 3 66.7 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include "AP_Frsky_SPort.h"
       4             : 
       5             : #if AP_FRSKY_SPORT_PASSTHROUGH_ENABLED
       6             : 
       7             : #include <AP_RCTelemetry/AP_RCTelemetry.h>
       8             : #include <AP_Mission/AP_Mission_config.h>
       9             : 
      10             : #include "AP_Frsky_SPortParser.h"
      11             : #include "AP_Frsky_MAVlite.h"
      12             : 
      13             : #include "AP_Frsky_Telem.h"
      14             : 
      15             : #if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
      16             : #include "AP_Frsky_MAVlite_SPortToMAVlite.h"
      17             : #include "AP_Frsky_MAVlite_MAVliteToSPort.h"
      18             : #include "AP_Frsky_MAVliteMsgHandler.h"
      19             : 
      20             : #define SPORT_TX_PACKET_DUPLICATES          1   // number of duplicates packets we send (fport only)
      21             : #endif
      22             : 
      23             : class AP_Frsky_SPort_Passthrough : public AP_Frsky_SPort, public AP_RCTelemetry
      24             : {
      25             : public:
      26             : 
      27           3 :     AP_Frsky_SPort_Passthrough(AP_HAL::UARTDriver *port, bool use_external_data, AP_Frsky_Parameters *&frsky_parameters) :
      28             :         AP_Frsky_SPort(port),
      29             :         AP_RCTelemetry(WFQ_LAST_ITEM),
      30           3 :         _frsky_parameters(frsky_parameters),
      31           3 :         _use_external_data(use_external_data)
      32             :     {
      33           3 :         singleton = this;
      34           3 :     }
      35             : 
      36           0 :     static AP_Frsky_SPort_Passthrough *get_singleton(void) {
      37           0 :         return singleton;
      38             :     }
      39             : 
      40             :     bool init() override;
      41             :     bool init_serial_port() override;
      42             : 
      43             :     // passthrough WFQ scheduler
      44             :     bool is_packet_ready(uint8_t idx, bool queue_empty) override;
      45             :     void process_packet(uint8_t idx) override;
      46             :     void adjust_packet_weight(bool queue_empty) override;
      47             :     // setup ready for passthrough operation
      48             :     void setup_wfq_scheduler(void) override;
      49             : 
      50             :     bool get_next_msg_chunk(void) override;
      51             : 
      52             :     bool get_telem_data(sport_packet_t* packet_array, uint8_t &packet_count, const uint8_t max_size) override;
      53             : #if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
      54             :     bool set_telem_data(const uint8_t frame, const uint16_t appid, const uint32_t data) override;
      55             : #endif //HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
      56             : 
      57         102 :     void queue_text_message(MAV_SEVERITY severity, const char *text) override
      58             :     {
      59         102 :         AP_RCTelemetry::queue_message(severity, text);
      60         102 :     }
      61             : 
      62             :     enum PassthroughPacketType : uint8_t {
      63             :         TEXT =          0,  // 0x5000 status text (dynamic)
      64             :         ATTITUDE =      1,  // 0x5006 Attitude and range (dynamic)
      65             :         GPS_LAT =       2,  // 0x800 GPS lat
      66             :         GPS_LON =       3,  // 0x800 GPS lon
      67             :         VEL_YAW =       4,  // 0x5005 Vel and Yaw
      68             :         AP_STATUS =     5,  // 0x5001 AP status
      69             :         GPS_STATUS =    6,  // 0x5002 GPS status
      70             :         HOME =          7,  // 0x5004 Home
      71             :         BATT_2 =        8,  // 0x5008 Battery 2 status
      72             :         BATT_1 =        9,  // 0x5008 Battery 1 status
      73             :         PARAM =         10, // 0x5007 parameters
      74             :         RPM =           11, // 0x500A rpm sensors 1 and 2
      75             :         UDATA =         12, // user data
      76             : #if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
      77             :         MAV =           13,  // mavlite
      78             : #endif //HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
      79             :         TERRAIN =       14, // 0x500B terrain data
      80             :         WIND =          15, // 0x500C wind data
      81             : #if AP_MISSION_ENABLED
      82             :         WAYPOINT =      16, // 0x500D waypoint data
      83             : #endif  // AP_MISSION_ENABLED
      84             :         WFQ_LAST_ITEM       // must be last
      85             :     };
      86             : 
      87             : protected:
      88             : 
      89             :     void send() override;
      90             : 
      91             : private:
      92             : 
      93             :     AP_Frsky_Parameters *&_frsky_parameters;
      94             : 
      95             :     enum PassthroughParam : uint8_t {
      96             :         NONE =                0,
      97             :         FRAME_TYPE =          1,
      98             :         BATT_FS_VOLTAGE =     2,
      99             :         BATT_FS_CAPACITY =    3,
     100             :         BATT_CAPACITY_1 =     4,
     101             :         BATT_CAPACITY_2 =     5,
     102             :         TELEMETRY_FEATURES =  6
     103             :     };
     104             : 
     105             :     enum PassthroughFeatures : uint8_t {
     106             :         BIDIR =                 0,
     107             :         SCRIPTING =             1,
     108             :     };
     109             : 
     110             :     // methods to convert flight controller data to FrSky SPort Passthrough (OpenTX) format
     111             :     uint32_t calc_param(void);
     112             :     uint32_t calc_batt(uint8_t instance);
     113             :     uint32_t calc_ap_status(void);
     114             :     uint32_t calc_home(void);
     115             :     uint32_t calc_velandyaw(void);
     116             :     uint32_t calc_attiandrng(void);
     117             :     uint32_t calc_rpm(void);
     118             :     uint32_t calc_terrain(void);
     119             :     uint32_t calc_wind(void);
     120             : #if AP_MISSION_ENABLED
     121             :     uint32_t calc_waypoint(void);
     122             : #endif  // AP_MISSION_ENABLED
     123             : 
     124             :     // use_external_data is set when this library will
     125             :     // be providing data to another transport, such as FPort
     126             :     bool _use_external_data;
     127             : 
     128             :     struct {
     129             :         sport_packet_t packet;
     130             :         bool pending;
     131             :     } external_data;
     132             : 
     133             :     struct {
     134             :         uint32_t chunk; // a "chunk" (four characters/bytes) at a time of the queued message to be sent
     135             :         uint8_t repeats; // send each message "chunk" 3 times to make sure the entire messsage gets through without getting cut
     136             :         uint8_t char_index; // index of which character to get in the message
     137             :     } _msg_chunk;
     138             : 
     139             :     // passthrough default sensor id
     140             :     uint8_t downlink_sensor_id = 0x1B;
     141             : 
     142             : #if HAL_WITH_FRSKY_TELEM_BIDIRECTIONAL
     143             :     // bidirectional sport telemetry
     144             :     struct {
     145             :         uint8_t uplink_sensor_id = 0x0D;
     146             :         uint8_t downlink1_sensor_id = 0x34;
     147             :         uint8_t downlink2_sensor_id = 0x67;
     148             :         uint8_t tx_packet_duplicates;
     149             :         ObjectBuffer_TS<AP_Frsky_SPort::sport_packet_t> rx_packet_queue{SPORT_PACKET_QUEUE_LENGTH};
     150             :         ObjectBuffer_TS<AP_Frsky_SPort::sport_packet_t> tx_packet_queue{SPORT_PACKET_QUEUE_LENGTH};
     151             :     } _SPort_bidir;
     152             : 
     153             :     AP_Frsky_SPortParser _sport_handler;
     154             :     AP_Frsky_MAVlite_SPortToMAVlite sport_to_mavlite;
     155             :     AP_Frsky_MAVlite_MAVliteToSPort mavlite_to_sport;
     156             : 
     157             :     // tx/rx sport packet processing
     158             :     void queue_rx_packet(const AP_Frsky_SPort::sport_packet_t sp);
     159             :     void process_rx_queue(void);
     160             :     void process_tx_queue(void);
     161             : 
     162             :     // create an object to handle incoming mavlite messages; a
     163             :     // callback method is provided to allow the handler to send responses
     164             :     bool send_message(const AP_Frsky_MAVlite_Message &txmsg);
     165             :     AP_Frsky_MAVliteMsgHandler mavlite{FUNCTOR_BIND_MEMBER(&AP_Frsky_SPort_Passthrough::send_message, bool, const AP_Frsky_MAVlite_Message &)};
     166             : #endif
     167             :     void set_sensor_id(AP_Int8 idx, uint8_t &sensor);
     168             :     void send_sport_frame(uint8_t frame, uint16_t appid, uint32_t data);
     169             : 
     170             :     // true if we need to respond to the last polling byte
     171             :     bool is_passthrough_byte(const uint8_t byte) const;
     172             : 
     173             :     uint8_t _paramID;
     174             : 
     175             :     uint32_t calc_gps_status(void);
     176             : 
     177             :     static AP_Frsky_SPort_Passthrough *singleton;
     178             : };
     179             : 
     180             : namespace AP {
     181             :     AP_Frsky_SPort_Passthrough *frsky_passthrough_telem();
     182             : };
     183             : 
     184             : 
     185             : #endif  // AP_FRSKY_SPORT_PASSTHROUGH_ENABLED

Generated by: LCOV version 1.14