LCOV - code coverage report
Current view: top level - AP_HAL - UARTDriver.h (source / functions) Hit Total Coverage
Test: lcov.info Lines: 13 30 43.3 %
Date: 2026-09-09 11:02:08 Functions: 12 27 44.4 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <stdint.h>
       4             : 
       5             : #include "AP_HAL_Namespace.h"
       6             : #include "utility/BetterStream.h"
       7             : #include <AP_Logger/AP_Logger_config.h>
       8             : 
       9             : #ifndef HAL_UART_STATS_ENABLED
      10             : #define HAL_UART_STATS_ENABLED AP_HAL_UARTDRIVER_ENABLED
      11             : #endif
      12             : 
      13             : #ifndef AP_UART_MONITOR_ENABLED
      14             : #define AP_UART_MONITOR_ENABLED 0
      15             : #endif
      16             : 
      17             : class ExpandingString;
      18             : class ByteBuffer;
      19             : 
      20             : /* Pure virtual UARTDriver class */
      21             : class AP_HAL::UARTDriver : public AP_HAL::BetterStream {
      22             : public:
      23       36637 :     UARTDriver() {}
      24             :     /* Do not allow copies */
      25             :     CLASS_NO_COPY(UARTDriver);
      26             : 
      27             :     /*
      28             :       the individual HALs need to implement the protected versions of these calls, _begin(), _write(), _read()
      29             :       port locking is checked by the top level AP_HAL functions
      30             :      */
      31             :     void begin(uint32_t baud);
      32             : 
      33             :     /*
      34             :       begin with specified minimum tx and rx buffer sizes
      35             :      */
      36             :     void begin(uint32_t baud, uint16_t rxSpace, uint16_t txSpace);
      37             : 
      38             :     /*
      39             :       begin for use when the port is write locked. Note that this does
      40             :       not lock the port, an existing write_key from lock_port() must
      41             :       be used
      42             :      */
      43             :     void begin_locked(uint32_t baud, uint16_t rxSpace, uint16_t txSpace, uint32_t write_key);
      44             : 
      45             :     /*
      46             :       single and multi-byte write methods
      47             :      */
      48             :     size_t write(uint8_t c) override;
      49             :     size_t write(const uint8_t *buffer, size_t size) override;
      50             :     size_t write(const char *str) override;
      51             : 
      52             :     /*
      53             :       single and multi-byte read methods
      54             :      */
      55             :     int16_t read(void) override;
      56             :     bool read(uint8_t &b) override WARN_IF_UNUSED;
      57             :     ssize_t read(uint8_t *buffer, uint16_t count) override;
      58             :     
      59             :     void end();
      60             :     void flush();
      61             : 
      62             :     virtual bool is_initialized() = 0;
      63             :     virtual bool tx_pending() = 0;
      64             : 
      65             :     // lock a port for exclusive use. Use a key of 0 to unlock
      66             :     bool lock_port(uint32_t write_key, uint32_t read_key);
      67             : 
      68             :     // check data available for read, return 0 is not available
      69             :     uint32_t available() override;
      70             :     uint32_t available_locked(uint32_t key);
      71             : 
      72             :     // discard any pending input
      73             :     bool discard_input() override;
      74             : 
      75             :     // write to a locked port. If port is locked and key is not correct then 0 is returned
      76             :     // and write is discarded
      77             :     size_t write_locked(const uint8_t *buffer, size_t size, uint32_t key);
      78             : 
      79             :     // read buffer from a locked port. If port is locked and key is not correct then -1 is returned
      80             :     ssize_t read_locked(uint8_t *buf, size_t count, uint32_t key) WARN_IF_UNUSED;
      81             : 
      82             :     // get current parity for passthrough use
      83             :     uint8_t get_parity(void);
      84             :     
      85             :     // control optional features
      86       23185 :     virtual bool set_options(uint16_t options) { _last_options = options; return options==0; }
      87           1 :     virtual uint16_t get_options(void) const { return _last_options; }
      88             : 
      89             :     enum Option {
      90             :         OPTION_RXINV              = (1U<<0),  // invert RX line
      91             :         OPTION_TXINV              = (1U<<1),  // invert TX line
      92             :         OPTION_HDPLEX             = (1U<<2), // half-duplex (one-wire) mode
      93             :         OPTION_SWAP               = (1U<<3), // swap RX and TX pins
      94             :         OPTION_PULLDOWN_RX        = (1U<<4), // apply pulldown to RX
      95             :         OPTION_PULLUP_RX          = (1U<<5), // apply pullup to RX
      96             :         OPTION_PULLDOWN_TX        = (1U<<6), // apply pulldown to TX
      97             :         OPTION_PULLUP_TX          = (1U<<7), // apply pullup to TX
      98             :         OPTION_NODMA_RX           = (1U<<8), // don't use DMA for RX
      99             :         OPTION_NODMA_TX           = (1U<<9), // don't use DMA for TX
     100             :         OPTION_MAVLINK_NO_FORWARD_old = (1U<<10), // // moved to GCS_MAVLINK::Option
     101             :         OPTION_NOFIFO             = (1U<<11), // disable hardware FIFO
     102             :         OPTION_NOSTREAMOVERRIDE_old   = (1U<<12), // moved to GCS_MAVLINK::Option
     103             :     };
     104             : 
     105        1838 :     bool option_is_set(Option option) const {
     106        1838 :         return (_last_options & (uint16_t)option) != 0;
     107             :     }
     108             : 
     109             : 
     110             :     enum flow_control {
     111             :         FLOW_CONTROL_DISABLE=0,
     112             :         FLOW_CONTROL_ENABLE=1,
     113             :         FLOW_CONTROL_AUTO=2,
     114             :         FLOW_CONTROL_RTS_DE=3, // RTS pin is used as a driver enable (used in RS-485)
     115             :     };
     116          24 :     virtual void set_flow_control(enum flow_control flow_control_setting) {};
     117           2 :     virtual enum flow_control get_flow_control(void) { return FLOW_CONTROL_DISABLE; }
     118             : 
     119             :     // Return true if flow control is currently enabled
     120        7704 :     bool flow_control_enabled() { return flow_control_enabled(get_flow_control()); }
     121             : 
     122           0 :     virtual void configure_parity(uint8_t v){};
     123           0 :     virtual void set_stop_bits(int n){};
     124             : 
     125             :     /* unbuffered writes bypass the ringbuffer and go straight to the
     126             :      * file descriptor
     127             :      */
     128           0 :     virtual bool set_unbuffered_writes(bool on){ return false; };
     129             : 
     130             :     /*
     131             :       wait for at least n bytes of incoming data, with timeout in
     132             :       milliseconds. Return true if n bytes are available, false if
     133             :       timeout
     134             :      */
     135           0 :     virtual bool wait_timeout(uint16_t n, uint32_t timeout_ms) { return false; }
     136             : 
     137             :     /*
     138             :      * Optional method to control the update of the motors. Derived classes
     139             :      * can implement it if their HAL layer requires.
     140             :      */
     141           0 :     virtual void _timer_tick(void) { }
     142             : 
     143             :     /*
     144             :       return timestamp estimate in microseconds for when the start of
     145             :       a nbytes packet arrived on the uart. This should be treated as a
     146             :       time constraint, not an exact time. It is guaranteed that the
     147             :       packet did not start being received after this time, but it
     148             :       could have been in a system buffer before the returned time.
     149             : 
     150             :       This takes account of the baudrate of the link. For transports
     151             :       that have no baudrate (such as USB) the time estimate may be
     152             :       less accurate.
     153             :      */
     154             :     virtual uint64_t receive_time_constraint_us(uint16_t nbytes);
     155             : 
     156           0 :     virtual uint32_t bw_in_bytes_per_second() const {
     157           0 :         return 5760;
     158             :     }
     159             : 
     160           0 :     virtual uint32_t get_baud_rate() const { return 0; }
     161             : 
     162             :     /*
     163             :       return true if this UART has DMA enabled on both RX and TX
     164             :      */
     165           0 :     virtual bool is_dma_enabled() const { return false; }
     166             : 
     167             :     /*
     168             :       return true if this port carries its data over a network
     169             :       connection (e.g. a NET_Pn port) rather than over a physical
     170             :       serial port.
     171             : 
     172             :       If you are calling this you are probably doing something wrong;
     173             :       users of a port should be agnostic as to how the bytes reach the
     174             :       other end.  It exists only for the rare device whose protocol
     175             :       itself cares - e.g. a gimbal which is told which of its own
     176             :       interfaces to send its replies out of.
     177             :      */
     178       14642 :     virtual bool is_network_port() const { return false; }
     179             : 
     180             : #if HAL_UART_STATS_ENABLED
     181             :     // Helper to keep track of data usage since last call
     182             :     struct StatsTracker {
     183             :         class ByteTracker {
     184             :         public:
     185             :             // Take cumulative bytes and return the change since last call
     186             :             uint32_t update(uint32_t bytes);
     187             :         private:
     188             :             uint32_t last_bytes;
     189             :         };
     190             :         ByteTracker tx;
     191             :         ByteTracker rx;
     192             :         ByteTracker rx_dropped;
     193             :     };
     194             : 
     195             :     // request information on uart I/O for this uart, for @SYS/uarts.txt
     196           0 :     virtual void uart_info(ExpandingString &str, StatsTracker &stats, const uint32_t dt_ms) {}
     197             : 
     198             : #if HAL_LOGGING_ENABLED
     199             :     // Log stats for this instance
     200             :     void log_stats(const uint8_t inst, StatsTracker &stats, const uint32_t dt_ms);
     201             : #endif
     202             : #endif // HAL_UART_STATS_ENABLED
     203             : 
     204             :     /*
     205             :       software control of the CTS/RTS pins if available. Return false if
     206             :       not available
     207             :      */
     208           0 :     virtual bool set_RTS_pin(bool high) { return false; };
     209           0 :     virtual bool set_CTS_pin(bool high) { return false; };
     210             : 
     211             :     // return true requested baud on USB port
     212           0 :     virtual uint32_t get_usb_baud(void) const { return 0; }
     213             : 
     214             :     // return requested parity on USB port
     215           0 :     virtual uint8_t get_usb_parity(void) const { return parity; }
     216             : 
     217             :     // disable TX/RX pins for unusued uart
     218        6164 :     virtual void disable_rxtx(void) const {}
     219             : 
     220             : #if AP_UART_MONITOR_ENABLED
     221             :     // a way to monitor all reads from the UART, putting them in a
     222             :     // buffer. Used by AP_Periph for GPS debug
     223             :     bool set_monitor_read_buffer(ByteBuffer *buffer) {
     224             :         _monitor_read_buffer = buffer;
     225             :         return true;
     226             :     }
     227             : #endif
     228             : 
     229             :     /*
     230             :       return true if the port is currently locked for writing
     231             :      */
     232           0 :     bool is_write_locked(void) const {
     233           0 :         return lock_write_key != 0;
     234             :     }
     235             : 
     236             :     // check that the current thread owns the uart making certain operations possible
     237           0 :     virtual bool is_owned_by_current_thread() const { return true; }
     238             : 
     239             : protected:
     240             :     // key for a locked port
     241             :     uint32_t lock_write_key;
     242             :     uint32_t lock_read_key;
     243             : 
     244             :     uint8_t parity;
     245             : 
     246             :     /*
     247             :       backend begin method
     248             :      */
     249             :     virtual void _begin(uint32_t baud, uint16_t rxSpace, uint16_t txSpace) = 0;
     250             : 
     251             :     /*
     252             :       backend write method
     253             :      */
     254             :     virtual size_t _write(const uint8_t *buffer, size_t size) = 0;
     255             : 
     256             :     /*
     257             :       backend read method
     258             :      */
     259             :     virtual ssize_t _read(uint8_t *buffer, uint16_t count)  WARN_IF_UNUSED = 0;
     260             : 
     261             :     /*
     262             :       end control of the port, freeing buffers
     263             :      */
     264             :     virtual void _end() = 0;
     265             : 
     266             :     /*
     267             :       flush any pending data
     268             :      */
     269             :     virtual void _flush() = 0;
     270             : 
     271             :     // check available data on the port
     272             :     virtual uint32_t _available() = 0;
     273             : 
     274             :     // discard incoming data on the port
     275             :     virtual bool _discard_input(void) = 0;
     276             : 
     277             :     // Helper to check if flow control is enabled given the passed setting
     278             :     bool flow_control_enabled(enum flow_control flow_control_setting) const;
     279             : 
     280             : #if HAL_UART_STATS_ENABLED
     281             :     // Getters for cumulative tx and rx counts
     282           6 :     virtual uint32_t get_total_tx_bytes() const { return 0; }
     283           6 :     virtual uint32_t get_total_rx_bytes() const { return 0; }
     284      314808 :     virtual uint32_t get_total_dropped_rx_bytes() const { return 0; }
     285             : #endif
     286             : 
     287             :     // option bits for port
     288             :     uint16_t _last_options;
     289             : 
     290             : private:
     291             : 
     292             : #if AP_UART_MONITOR_ENABLED
     293             :     ByteBuffer *_monitor_read_buffer;
     294             : #endif
     295             : };

Generated by: LCOV version 1.14