#pragma once #include "stm32h5xx_nucleo.h" #include #include #include #include class SerialPort { private: static constexpr uint32_t kTransmitTimeout = 1000; static constexpr auto* kHandle = &hcom_uart[COM1]; static inline char buffer[256] = {0}; friend void HAL_UART_TxCpltCallback(UART_HandleTypeDef* huart); static inline volatile bool isTransmitting = false; static void WaitTransmit() { const auto tick = HAL_GetTick(); while (isTransmitting) { if (HAL_GetTick() - tick > kTransmitTimeout) { HAL_UART_AbortTransmit(kHandle); isTransmitting = false; } } } public: static uint8_t ReadByte() { return kHandle->Instance->RDR; } static std::string ReadLine() { std::string result; result.reserve(128); char c; ReadByte(); while (true) { HAL_UART_Receive(kHandle, reinterpret_cast(&c), 1, HAL_MAX_DELAY); if (c == '\n') { if (!result.empty() && result.back() == '\r') { result.pop_back(); } break; } result.push_back(c); } return result; } static void WriteLineDMA(const char* format, ...) { WaitTransmit(); isTransmitting = true; va_list args; va_start(args, format); int len = vsnprintf(buffer, sizeof(buffer) - 1, format, args); va_end(args); if (len < 0 || len > static_cast(sizeof(buffer) - 1)) { isTransmitting = false; return; } buffer[len] = '\n'; len++; HAL_UART_Transmit_DMA(kHandle, reinterpret_cast(buffer), len); } static void WriteLineBlocking(const char* format, ...) { WaitTransmit(); va_list args; va_start(args, format); int len = vsnprintf(buffer, 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(kHandle, reinterpret_cast(buffer), len, kTransmitTimeout); } static void WriteDMA(const char* format, ...) { WaitTransmit(); isTransmitting = true; va_list args; va_start(args, format); auto len = vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); if (len < 0 || len > static_cast(sizeof(buffer))) { isTransmitting = false; return; } HAL_UART_Transmit_DMA(kHandle, reinterpret_cast(buffer), len); } static void WriteBlocking(const char* format, ...) { WaitTransmit(); va_list args; va_start(args, format); auto len = vsnprintf(buffer, sizeof(buffer), format, args); va_end(args); if (len < 0 || len > static_cast(sizeof(buffer))) { return; } HAL_UART_Transmit(kHandle, reinterpret_cast(buffer), strlen(buffer), kTransmitTimeout); } static void WriteBytesDMA(const uint8_t* data, size_t size) { WaitTransmit(); isTransmitting = true; HAL_UART_Transmit_DMA(kHandle, const_cast(data), size); } static void WriteBytesBlocking(const uint8_t* data, size_t size) { WaitTransmit(); HAL_UART_Transmit(kHandle, const_cast(data), size, kTransmitTimeout); } };