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 : * Code by Andrew Tridgell and Siddharth Bharat Purohit 16 : */ 17 : 18 : #pragma once 19 : 20 : #include "AP_RCProtocol.h" 21 : 22 : #if AP_RCPROTOCOL_ENABLED 23 : 24 : #include <AP_HAL/utility/sparse-endian.h> 25 : #include <AP_VideoTX/AP_VideoTX_config.h> 26 : 27 : class AP_RCProtocol_Backend { 28 : friend class AP_RCProtcol; 29 : 30 : public: 31 : AP_RCProtocol_Backend(AP_RCProtocol &_frontend); 32 8172 : virtual ~AP_RCProtocol_Backend() {} 33 0 : virtual void process_pulse(uint32_t width_s0, uint32_t width_s1) {} 34 0 : virtual void process_byte(uint8_t byte, uint32_t baudrate) {} 35 60 : virtual void process_handshake(uint32_t baudrate) {} 36 : uint16_t read(uint8_t chan); 37 : void read(uint16_t *pwm, uint8_t n); 38 : bool new_input(); 39 : uint8_t num_channels() const; 40 : 41 : // support for receivers that have FC initiated bind support 42 0 : virtual void start_bind() {} 43 : 44 : // allow for backends that need regular polling 45 397952434 : virtual void update(void) {} 46 : 47 : // update from mavlink messages 48 : #if AP_RCPROTOCOL_MAVLINK_RADIO_ENABLED 49 0 : virtual void update_radio_rc_channels(const mavlink_radio_rc_channels_t* packet) {} 50 : #endif 51 : 52 : // get number of frames, ignoring failsafe 53 0 : uint32_t get_rc_frame_count(void) const { 54 0 : return rc_frame_count; 55 : } 56 : 57 : // reset valid rc frame count 58 0 : void reset_rc_frame_count(void) { 59 0 : rc_frame_count = 0; 60 0 : } 61 : 62 : // get number of frames, honoring failsafe 63 0 : uint32_t get_rc_input_count(void) const { 64 0 : return rc_input_count; 65 : } 66 : 67 4 : uint32_t get_rc_protocols_mask(void) const { 68 4 : return frontend.rc_protocols_mask; 69 : } 70 : 71 0 : bool protocol_enabled(enum AP_RCProtocol::rcprotocol_t protocol) const { 72 0 : return frontend.protocol_enabled(protocol); 73 : } 74 : 75 : // get RSSI 76 0 : int16_t get_RSSI(void) const { 77 0 : return rssi; 78 : } 79 0 : int16_t get_rx_link_quality(void) const { 80 0 : return rx_link_quality; 81 : } 82 : // get UART for RCIN, if available. This will return false if we 83 : // aren't getting the active RC input protocol via the uart 84 0 : AP_HAL::UARTDriver *get_UART(void) const { 85 0 : return frontend._detected_with_bytes?frontend.added.uart:nullptr; 86 : } 87 : 88 : // get an available uart regardless of whether we have detected a protocol via it 89 8 : AP_HAL::UARTDriver *get_available_UART(void) const { 90 8 : return frontend.added.uart; 91 : } 92 : 93 : // return true if we have a uart available for protocol handling. 94 0 : bool have_UART(void) const { 95 0 : return frontend.added.uart != nullptr; 96 : } 97 : 98 : // is the receiver active, used to detect power loss and baudrate changes 99 0 : virtual bool is_rx_active() const { 100 0 : return true; 101 : } 102 : 103 0 : bool is_detected() const { 104 0 : return frontend._detected_protocol != AP_RCProtocol::NONE && frontend.backend[frontend._detected_protocol] == this; 105 : } 106 : 107 : #if AP_VIDEOTX_ENABLED 108 : // called by static methods to confiig video transmitters: 109 : static void configure_vtx(uint8_t band, uint8_t channel, uint8_t power, uint8_t pitmode); 110 : #endif 111 : 112 : protected: 113 : 114 : struct Channels11Bit_8Chan { 115 : #if __BYTE_ORDER != __LITTLE_ENDIAN 116 : #error "Only supported on little-endian architectures" 117 : #endif 118 : uint32_t ch0 : 11; 119 : uint32_t ch1 : 11; 120 : uint32_t ch2 : 11; 121 : uint32_t ch3 : 11; 122 : uint32_t ch4 : 11; 123 : uint32_t ch5 : 11; 124 : uint32_t ch6 : 11; 125 : uint32_t ch7 : 11; 126 : } PACKED; 127 : 128 : void add_input(uint8_t num_channels, uint16_t *values, bool in_failsafe, int16_t rssi=-1, int16_t rx_link_quality=-1); 129 : AP_RCProtocol &frontend; 130 : 131 : void log_data(AP_RCProtocol::rcprotocol_t prot, uint32_t timestamp, const uint8_t *data, uint8_t len) const; 132 : 133 : // decode channels from the standard 11bit format (used by CRSF and SBUS) 134 : static void decode_11bit_channels(const uint8_t* data, uint8_t nchannels, uint16_t *values, uint16_t mult, uint16_t div, uint16_t offset); 135 : 136 : private: 137 : uint32_t rc_input_count; 138 : uint32_t last_rc_input_count; 139 : uint32_t rc_frame_count; 140 : 141 : uint16_t _pwm_values[MAX_RCIN_CHANNELS]; 142 : uint8_t _num_channels; 143 : int16_t rssi = -1; 144 : int16_t rx_link_quality = -1; 145 : }; 146 : 147 : #endif // AP_RCPROTOCOL_ENABLED