Line data Source code
1 : /* 2 : implement generic UARTDriver code, including port locking 3 : */ 4 : #include "AP_HAL.h" 5 : #include <AP_Logger/AP_Logger.h> 6 : 7 542808 : void AP_HAL::UARTDriver::begin(uint32_t baud, uint16_t rxSpace, uint16_t txSpace) 8 : { 9 542808 : if (lock_write_key != 0) { 10 : // silently fail 11 0 : return; 12 : } 13 542808 : return _begin(baud, rxSpace, txSpace); 14 : } 15 : 16 521764 : void AP_HAL::UARTDriver::begin(uint32_t baud) 17 : { 18 521764 : return begin(baud, 0, 0); 19 : } 20 : 21 : /* 22 : lock the uart for exclusive use by write_locked() and read_locked() with the right key 23 : */ 24 0 : bool AP_HAL::UARTDriver::lock_port(uint32_t write_key, uint32_t read_key) 25 : { 26 0 : if (lock_write_key != 0 && write_key != lock_write_key && write_key != 0) { 27 : // someone else is using it 28 0 : return false; 29 : } 30 0 : if (lock_read_key != 0 && read_key != lock_read_key && read_key != 0) { 31 : // someone else is using it 32 0 : return false; 33 : } 34 0 : lock_write_key = write_key; 35 0 : lock_read_key = read_key; 36 0 : return true; 37 : } 38 : 39 0 : void AP_HAL::UARTDriver::begin_locked(uint32_t baud, uint16_t rxSpace, uint16_t txSpace, uint32_t key) 40 : { 41 0 : if (lock_write_key != 0 && key != lock_write_key) { 42 : // silently fail 43 0 : return; 44 : } 45 0 : return _begin(baud, rxSpace, txSpace); 46 : } 47 : 48 : /* 49 : write to a locked port. If port is locked and key is not correct then 0 is returned 50 : and write is discarded. All writes are non-blocking 51 : */ 52 0 : size_t AP_HAL::UARTDriver::write_locked(const uint8_t *buffer, size_t size, uint32_t key) 53 : { 54 0 : if (lock_write_key != 0 && key != lock_write_key) { 55 0 : return 0; 56 : } 57 0 : return _write(buffer, size); 58 : } 59 : 60 : /* 61 : read from a locked port. If port is locked and key is not correct then -1 is returned 62 : */ 63 444374012 : ssize_t AP_HAL::UARTDriver::read_locked(uint8_t *buf, size_t count, uint32_t key) 64 : { 65 444374012 : if (lock_read_key != 0 && key != lock_read_key) { 66 0 : return 0; 67 : } 68 444374012 : ssize_t ret = _read(buf, count); 69 : #if AP_UART_MONITOR_ENABLED 70 444372662 : auto monitor = _monitor_read_buffer; 71 444372662 : if (monitor != nullptr && ret > 0) { 72 0 : monitor->write(buf, ret); 73 : } 74 : #endif 75 444372735 : return ret; 76 : } 77 : 78 0 : uint32_t AP_HAL::UARTDriver::available_locked(uint32_t key) 79 : { 80 0 : if (lock_read_key != 0 && lock_read_key != key) { 81 0 : return 0; 82 : } 83 0 : return _available(); 84 : } 85 : 86 117474477 : size_t AP_HAL::UARTDriver::write(const uint8_t *buffer, size_t size) 87 : { 88 117474477 : if (lock_write_key != 0) { 89 0 : return 0; 90 : } 91 117474477 : return _write(buffer, size); 92 : } 93 : 94 303159 : size_t AP_HAL::UARTDriver::write(uint8_t c) 95 : { 96 303159 : return write(&c, 1); 97 : } 98 : 99 155 : size_t AP_HAL::UARTDriver::write(const char *str) 100 : { 101 155 : return write((const uint8_t *)str, strlen(str)); 102 : } 103 : 104 444374096 : ssize_t AP_HAL::UARTDriver::read(uint8_t *buffer, uint16_t count) 105 : { 106 444374096 : return read_locked(buffer, count, 0); 107 : } 108 : 109 443774815 : bool AP_HAL::UARTDriver::read(uint8_t &b) 110 : { 111 443774815 : ssize_t n = read(&b, 1); 112 443773613 : return n > 0; 113 : } 114 : 115 142781192 : int16_t AP_HAL::UARTDriver::read(void) 116 : { 117 : uint8_t b; 118 142781192 : if (!read(b)) { 119 0 : return -1; 120 : } 121 142781192 : return b; 122 : } 123 : 124 : 125 136305479 : uint32_t AP_HAL::UARTDriver::available() 126 : { 127 136305479 : if (lock_read_key != 0) { 128 0 : return 0; 129 : } 130 136305479 : return _available(); 131 : } 132 : 133 0 : void AP_HAL::UARTDriver::end() 134 : { 135 0 : if (lock_read_key != 0 || lock_write_key != 0) { 136 0 : return; 137 : } 138 0 : _end(); 139 : } 140 : 141 1639 : void AP_HAL::UARTDriver::flush() 142 : { 143 1639 : if (lock_read_key != 0 || lock_write_key != 0) { 144 0 : return; 145 : } 146 1639 : _flush(); 147 : } 148 : 149 191581 : bool AP_HAL::UARTDriver::discard_input() 150 : { 151 191581 : if (lock_read_key != 0) { 152 0 : return false; 153 : } 154 191581 : return _discard_input(); 155 : } 156 : 157 : /* 158 : default implementation of receive_time_constraint_us() will be used 159 : for subclasses that don't implement the call (eg. network 160 : sockets). Best we can do is to use the current timestamp as we don't 161 : know the transport delay 162 : */ 163 0 : uint64_t AP_HAL::UARTDriver::receive_time_constraint_us(uint16_t nbytes) 164 : { 165 0 : return AP_HAL::micros64(); 166 : } 167 : 168 : // Helper to check if flow control is enabled given the passed setting 169 7704 : bool AP_HAL::UARTDriver::flow_control_enabled(enum flow_control flow_control_setting) const 170 : { 171 7704 : switch(flow_control_setting) { 172 7012 : case FLOW_CONTROL_ENABLE: 173 : case FLOW_CONTROL_AUTO: 174 7012 : return true; 175 692 : case FLOW_CONTROL_DISABLE: 176 : case FLOW_CONTROL_RTS_DE: 177 692 : break; 178 : } 179 692 : return false; 180 : } 181 : 182 0 : uint8_t AP_HAL::UARTDriver::get_parity(void) 183 : { 184 0 : return AP_HAL::UARTDriver::parity; 185 : } 186 : 187 : #if HAL_UART_STATS_ENABLED 188 : // Take cumulative bytes and return the change since last call 189 967590 : uint32_t AP_HAL::UARTDriver::StatsTracker::ByteTracker::update(uint32_t bytes) 190 : { 191 967590 : const uint32_t change = bytes - last_bytes; 192 967590 : last_bytes = bytes; 193 967590 : return change; 194 : } 195 : 196 : #if HAL_LOGGING_ENABLED 197 : // Write UART log message 198 1492499 : void AP_HAL::UARTDriver::log_stats(const uint8_t inst, StatsTracker &stats, const uint32_t dt_ms) 199 : { 200 : // get totals 201 1492499 : const uint32_t total_tx_bytes = get_total_tx_bytes(); 202 1492499 : const uint32_t total_rx_bytes = get_total_rx_bytes(); 203 : 204 : // Don't log if we have never seen data 205 1492499 : if ((total_tx_bytes == 0) && (total_rx_bytes == 0)) { 206 : // This could be wrong if we happen to wrap both tx and rx to zero at exactly the same time 207 : // In that very unlikely case one log will be missed 208 1177625 : return; 209 : } 210 : 211 : // Update tracking 212 314874 : const uint32_t tx_bytes = stats.tx.update(total_tx_bytes); 213 314874 : const uint32_t rx_bytes = stats.rx.update(total_rx_bytes); 214 314874 : const uint32_t rx_dropped_bytes = stats.rx_dropped.update(get_total_dropped_rx_bytes()); 215 : 216 : // Assemble struct and log 217 314874 : struct log_UART pkt { 218 : LOG_PACKET_HEADER_INIT(LOG_UART_MSG), 219 314874 : time_us : AP_HAL::micros64(), 220 : instance : inst, 221 314874 : tx_rate : float((tx_bytes * 1000) / dt_ms), 222 314874 : rx_rate : float((rx_bytes * 1000) / dt_ms), 223 314874 : rx_drop_rate : float((rx_dropped_bytes * 1000) / dt_ms), 224 314874 : }; 225 314874 : AP::logger().WriteBlock(&pkt, sizeof(pkt)); 226 : } 227 : #endif // HAL_LOGGING_ENABLED 228 : #endif // HAL_UART_STATS_ENABLED