// SPDX-License-Identifier: BSD-3-Clause #ifndef INVERTER_TOOLS_VOLTRONIC_DEVICE_H #define INVERTER_TOOLS_VOLTRONIC_DEVICE_H #include #include #include #include #include "../numeric_types.h" namespace voltronic { enum { FLAG_WRITE_CRC = 1, FLAG_READ_CRC = 2, FLAG_VERIFY_CRC = 4, }; /** * Common device */ class Device { protected: int flags_; u64 timeout_; u64 timeStarted_; bool verbose_; void send(const u8* buf, size_t bufSize); size_t recv(u8* buf, size_t bufSize); void writeLoop(const u8* data, size_t dataSize); size_t readLoop(u8* buf, size_t bufSize); u64 getElapsedTime() const; u64 getTimeLeft() const; public: static const u64 TIMEOUT = 1000; Device(); virtual size_t read(u8* buf, size_t bufSize) = 0; virtual size_t write(const u8* data, size_t dataSize) = 0; void setTimeout(u64 timeout); size_t run(const u8* inbuf, size_t inbufSize, u8* outbuf, size_t outbufSize); void setFlags(int flags); int getFlags() const; void setVerbose(bool verbose); }; /** * USB device */ class USBDevice : public Device { private: hid_device* device_; public: static const u16 VENDOR_ID = 0x0665; static const u16 PRODUCT_ID = 0x5161; static const u16 HID_REPORT_SIZE = 8; static u16 GET_HID_REPORT_SIZE(size_t size); USBDevice(u16 vendorId, u16 productId); ~USBDevice(); size_t read(u8* buf, size_t bufSize) override; size_t write(const u8* data, size_t dataSize) override; }; /** * Serial device */ typedef unsigned SerialBaudRate; enum class SerialDataBits { Five = 5, Six = 6, Seven = 7, Eight = 8, }; enum class SerialStopBits { One = 1, OneAndHalf = 3, Two = 2 }; enum class SerialParity { Invalid = SP_PARITY_INVALID, None = SP_PARITY_NONE, Odd = SP_PARITY_ODD, Even = SP_PARITY_EVEN, Mark = SP_PARITY_MARK, Space = SP_PARITY_SPACE, }; class SerialDevice : public Device { private: struct sp_port* port_; SerialBaudRate baudRate_; SerialDataBits dataBits_; SerialStopBits stopBits_; SerialParity parity_; std::string name_; unsigned getTimeout(); public: static const char* DEVICE_NAME; static const SerialBaudRate BAUD_RATE = 2400; static const SerialDataBits DATA_BITS = SerialDataBits::Eight; static const SerialStopBits STOP_BITS = SerialStopBits::One; static const SerialParity PARITY = SerialParity::None; explicit SerialDevice(std::string& name, SerialBaudRate baudRate, SerialDataBits dataBits, SerialStopBits stopBits, SerialParity parity); ~SerialDevice(); [[nodiscard]] inline struct sp_port* getPort() const { return port_; } size_t read(u8* buf, size_t bufSize) override; size_t write(const u8* data, size_t dataSize) override; }; class SerialPortConfiguration { private: struct sp_port_config* config_; SerialDevice& device_; public: explicit SerialPortConfiguration(SerialDevice& device); ~SerialPortConfiguration(); void setConfiguration(SerialBaudRate baudRate, SerialDataBits dataBits, SerialStopBits stopBits, SerialParity parity); }; bool is_serial_baud_rate_valid(SerialBaudRate baudRate); bool is_serial_data_bits_valid(SerialDataBits dataBits); bool is_serial_stop_bits_valid(SerialStopBits stopBits); bool is_serial_parity_valid(SerialParity parity); /** * Pseudo device */ class PseudoDevice : public Device { public: PseudoDevice() = default; ~PseudoDevice() = default; size_t read(u8* buf, size_t bufSize) override; size_t write(const u8* data, size_t dataSize) override; }; } #endif //INVERTER_TOOLS_VOLTRONIC_DEVICE_H