#pragma once #include "main.h" #include "stm32h5xx_hal_uart.h" #include #include #include #include #include class SerialPort { private: UART_HandleTypeDef* handle; uint32_t timeout; std::unique_ptr buffer; uint8_t ReadByteForce() { return handle->Instance->RDR; } public: SerialPort(UART_HandleTypeDef* uart, uint32_t baudRate, uint32_t length, uint32_t timeout) : handle(uart), timeout(timeout), buffer(std::make_unique(length)) { SetBaudRate(baudRate); } ~SerialPort() = default; void SetBaudRate(uint32_t baudRate) { HAL_UART_DeInit(handle); handle->Init.BaudRate = baudRate; HAL_UART_Init(handle); } std::string ReadLine() { std::string result; result.reserve(128); char c; ReadByteForce(); while (true) { auto r = HAL_UART_Receive(handle, reinterpret_cast(&c), sizeof(c), timeout); if (r != HAL_OK) { throw std::runtime_error("UART receive error"); } if (c == '\n') { if (!result.empty() && result.back() == '\r') { result.pop_back(); } break; } result.push_back(c); } return result; } void ReadBytesBlocking(uint8_t* data, size_t size) { auto r = HAL_UART_Receive(handle, data, size, timeout); if (r != HAL_OK) { throw std::runtime_error("UART receive error"); } } void WriteBytesBlocking(const uint8_t* data, size_t size) { HAL_UART_Transmit(handle, const_cast(data), size, timeout); } void WriteBlocking(const char* format, ...) { va_list args; va_start(args, format); auto len = vsnprintf(buffer.get(), sizeof(buffer), format, args); va_end(args); if (len < 0 || len > static_cast(sizeof(buffer))) { return; } HAL_UART_Transmit(handle, reinterpret_cast(buffer.get()), strlen(buffer.get()), timeout); } void WriteLineBlocking(const char* format, ...) { va_list args; va_start(args, format); int len = vsnprintf(buffer.get(), sizeof(buffer) - 1, format, args); va_end(args); if (len < 0 || len > static_cast(sizeof(buffer) - 1)) { return; } buffer[len] = '\n'; len++; HAL_UART_Transmit(handle, reinterpret_cast(buffer.get()), len, timeout); } };