123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- #pragma once
- #include <AP_HAL/utility/RingBuffer.h>
- #include "AP_HAL_ChibiOS.h"
- #include "shared_dma.h"
- #include "Semaphores.h"
- #define RX_BOUNCE_BUFSIZE 128U
- #define TX_BOUNCE_BUFSIZE 64U
- #define UART_MAX_DRIVERS 9
- class ChibiOS::UARTDriver : public AP_HAL::UARTDriver {
- public:
- UARTDriver(uint8_t serial_num);
- void begin(uint32_t b) override;
- void begin(uint32_t b, uint16_t rxS, uint16_t txS) override;
- void end() override;
- void flush() override;
- bool is_initialized() override;
- void set_blocking_writes(bool blocking) override;
- bool tx_pending() override;
- uint32_t available() override;
- uint32_t txspace() override;
- int16_t read() override;
- int16_t read_locked(uint32_t key) override;
- void _timer_tick(void) override;
- size_t write(uint8_t c) override;
- size_t write(const uint8_t *buffer, size_t size) override;
-
- bool lock_port(uint32_t write_key, uint32_t read_key) override;
-
- bool set_options(uint8_t options) override;
- uint8_t get_options(void) const override;
-
-
-
- size_t write_locked(const uint8_t *buffer, size_t size, uint32_t key) override;
-
- struct SerialDef {
- BaseSequentialStream* serial;
- bool is_usb;
- #ifndef HAL_UART_NODMA
- bool dma_rx;
- uint8_t dma_rx_stream_id;
- uint32_t dma_rx_channel_id;
- bool dma_tx;
- uint8_t dma_tx_stream_id;
- uint32_t dma_tx_channel_id;
- #endif
- ioline_t rts_line;
- int8_t rxinv_gpio;
- uint8_t rxinv_polarity;
- int8_t txinv_gpio;
- uint8_t txinv_polarity;
- uint8_t get_index(void) const {
- return uint8_t(this - &_serial_tab[0]);
- }
- };
- bool wait_timeout(uint16_t n, uint32_t timeout_ms) override;
- void set_flow_control(enum flow_control flow_control) override;
- enum flow_control get_flow_control(void) override { return _flow_control; }
-
- bool set_unbuffered_writes(bool on) override;
- void configure_parity(uint8_t v) override;
- void set_stop_bits(int n) override;
-
- uint64_t receive_time_constraint_us(uint16_t nbytes) override;
- uint32_t bw_in_kilobytes_per_second() const override {
- if (sdef.is_usb) {
- return 200;
- }
- return _baudrate/(9*1024);
- }
- private:
- const SerialDef &sdef;
-
- static thread_t *uart_thread_ctx;
-
- static UARTDriver *uart_drivers[UART_MAX_DRIVERS];
-
- uint8_t serial_num;
-
- uint32_t lock_write_key;
- uint32_t lock_read_key;
- uint32_t _baudrate;
- uint16_t tx_len;
- #if HAL_USE_SERIAL == TRUE
- SerialConfig sercfg;
- #endif
- const thread_t* _uart_owner_thd;
- struct {
-
- thread_t *thread_ctx;
-
- uint16_t n;
- } _wait;
-
-
- #ifndef HAL_UART_NODMA
- bool tx_bounce_buf_ready;
- uint8_t *rx_bounce_buf;
- uint8_t *tx_bounce_buf;
- #endif
- ByteBuffer _readbuf{0};
- ByteBuffer _writebuf{0};
- Semaphore _write_mutex;
- #ifndef HAL_UART_NODMA
- const stm32_dma_stream_t* rxdma;
- const stm32_dma_stream_t* txdma;
- #endif
- virtual_timer_t tx_timeout;
- bool _in_timer;
- bool _blocking_writes;
- bool _initialised;
- bool _device_initialised;
- bool _lock_rx_in_timer_tick = false;
- #ifndef HAL_UART_NODMA
- Shared_DMA *dma_handle;
- #endif
- static const SerialDef _serial_tab[];
-
- uint64_t _receive_timestamp[2];
- uint8_t _receive_timestamp_idx;
-
- enum flow_control _flow_control = FLOW_CONTROL_DISABLE;
- bool _rts_is_active;
- uint32_t _last_write_completed_us;
- uint32_t _first_write_started_us;
- uint32_t _total_written;
-
- uint32_t _cr3_options;
- uint32_t _cr2_options;
- uint8_t _last_options;
-
-
- bool half_duplex;
- uint32_t hd_read_delay_us;
- uint32_t hd_write_us;
- void half_duplex_setup_delay(uint16_t len);
-
- bool unbuffered_writes;
- #if CH_CFG_USE_EVENTS == TRUE
-
- event_listener_t ev_listener;
- bool parity_enabled;
- #endif
-
- #ifndef HAL_UART_NODMA
- static void rx_irq_cb(void* sd);
- #endif
- static void rxbuff_full_irq(void* self, uint32_t flags);
- static void tx_complete(void* self, uint32_t flags);
- static void handle_tx_timeout(void *arg);
- #ifndef HAL_UART_NODMA
- void dma_tx_allocate(Shared_DMA *ctx);
- void dma_tx_deallocate(Shared_DMA *ctx);
- #endif
- void update_rts_line(void);
- void check_dma_tx_completion(void);
- #ifndef HAL_UART_NODMA
- void write_pending_bytes_DMA(uint32_t n);
- #endif
- void write_pending_bytes_NODMA(uint32_t n);
- void write_pending_bytes(void);
- void receive_timestamp_update(void);
-
- void thread_init();
- static void uart_thread(void *);
- };
|