119 lines
3.5 KiB
C++
119 lines
3.5 KiB
C++
#pragma once
|
|
|
|
#include "stm32h5xx_nucleo.h"
|
|
#include <cstdarg>
|
|
#include <cstdint>
|
|
#include <cstring>
|
|
#include <string>
|
|
|
|
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<uint8_t*>(&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 WriteLine(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<int>(sizeof(buffer) - 1)) {
|
|
isTransmitting = false;
|
|
return;
|
|
}
|
|
buffer[len] = '\n';
|
|
len++;
|
|
HAL_UART_Transmit_DMA(kHandle, reinterpret_cast<uint8_t*>(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<int>(sizeof(buffer) - 1)) {
|
|
return;
|
|
}
|
|
buffer[len] = '\n';
|
|
len++;
|
|
HAL_UART_Transmit(kHandle, reinterpret_cast<uint8_t*>(buffer), len, kTransmitTimeout);
|
|
}
|
|
|
|
static void Write(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<int>(sizeof(buffer))) {
|
|
isTransmitting = false;
|
|
return;
|
|
}
|
|
HAL_UART_Transmit_DMA(kHandle, reinterpret_cast<uint8_t*>(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<int>(sizeof(buffer))) {
|
|
return;
|
|
}
|
|
HAL_UART_Transmit(kHandle, reinterpret_cast<uint8_t*>(buffer), strlen(buffer), kTransmitTimeout);
|
|
}
|
|
|
|
static void WriteBytes(const uint8_t* data, size_t size) {
|
|
WaitTransmit();
|
|
isTransmitting = true;
|
|
HAL_UART_Transmit_DMA(kHandle, const_cast<uint8_t*>(data), size);
|
|
}
|
|
|
|
static void WriteBytesBlocking(const uint8_t* data, size_t size) {
|
|
WaitTransmit();
|
|
HAL_UART_Transmit(kHandle, const_cast<uint8_t*>(data), size, kTransmitTimeout);
|
|
}
|
|
};
|