#pragma once #include "common.h" #include #include #include #include #include void tty_init(); void tty_ping(); // // This is needed because there isn't a common serial device // class in Arduino, sigh... // struct tty_packet_hdr { uint8_t stx; uint8_t len; uint16_t resv; uint32_t offs; uint32_t crc; } __attribute__((packed)); class TTY { public: TTY(Stream &port); ~TTY(); void reset(); int rxdata(void *buf, size_t len); static int rxdata(token_t me, void *buf, size_t len); // Global events static void init(); static void ping(); private: Stream *_port; // Android stream void _onrx(); void _onerr(); void _onbreak(); void _onconnect(); void _ondisconnect(); void (*_flush)(); public: inline void flush() { _flush(); } inline Stream & port() { return *_port; } inline operator Stream & () { return port(); } private: // Event handler dispatchers static void usb_task_handler(void *); static void usb_onevent(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); static void uart_onrx(); static void uart_onerr(hardwareSerial_error_t); enum rx_state { normal, // Normal console mode stxwait, // Waiting for header STX hdr, // Getting header data // Getting data packet }; void _upload_begin(); void _update_window(bool rst = false); int _decode_data(int); // Packet receive state machine struct { enum rx_state state; uint8_t b64_buf; uint8_t b64_bits; union { struct tty_packet_hdr hdr; uint8_t hdr_raw[sizeof(struct tty_packet_hdr)]; }; size_t rlen; uint32_t last_ack; } rx; StreamBufferHandle_t rx_sbuf; uint32_t tx_credits; volatile bool tx_credits_reset; volatile uint32_t last_rx; uint8_t rx_data[256]; };