tutrcos
読み取り中…
検索中…
一致する文字列を見つけられません
uart.hpp
[詳解]
1#pragma once
2
3#include "main.h"
4
5#include <array>
6#include <cstddef>
7#include <cstdint>
8#include <mutex>
9
10#include "tutrcos/core.hpp"
11#include "tutrcos/utility.hpp"
12
13extern "C" int _write(int file, char *ptr, int len);
14
15namespace tutrcos {
16namespace peripheral {
17
51class UART {
52public:
53 UART(UART_HandleTypeDef *huart, size_t rx_queue_size = 64)
54 : huart_{huart}, rx_queue_{rx_queue_size} {
55 auto uart =
56 std::find(get_instances().begin(), get_instances().end(), nullptr);
57 TUTRCOS_VERIFY(uart != get_instances().end());
58 *uart = this;
59 TUTRCOS_VERIFY(HAL_UART_Receive_IT(huart_, &rx_buf_, 1) == HAL_OK);
60 }
61
63 TUTRCOS_VERIFY(HAL_UART_Abort(huart_) == HAL_OK);
64 auto uart = std::find(get_instances().begin(), get_instances().end(), this);
65 TUTRCOS_VERIFY(uart != get_instances().end());
66 *uart = nullptr;
67 }
68
69 bool transmit(const uint8_t *data, size_t size, uint32_t timeout) {
70 std::lock_guard lock{mtx_};
71 if (HAL_UART_Transmit_IT(huart_, data, size) != HAL_OK) {
72 return false;
73 }
74 uint32_t start = core::Kernel::get_ticks();
75 while (huart_->gState != HAL_UART_STATE_READY) {
76 uint32_t elapsed = core::Kernel::get_ticks() - start;
77 if (elapsed >= timeout) {
78 return false;
79 }
81 }
82 return true;
83 }
84
85 bool receive(uint8_t *data, size_t size, uint32_t timeout) {
86 std::lock_guard lock{mtx_};
87 uint32_t start = core::Kernel::get_ticks();
88 while (rx_queue_.size() < size) {
89 uint32_t elapsed = core::Kernel::get_ticks() - start;
90 if (elapsed >= timeout) {
91 return false;
92 }
94 }
95 for (size_t i = 0; i < size; ++i) {
96 rx_queue_.pop(data[i], 0);
97 }
98 return true;
99 }
100
101 void flush() {
102 std::lock_guard lock{mtx_};
103 rx_queue_.clear();
104 }
105
106 void enable_stdout() { get_uart_stdout() = this; }
107
108 UART_HandleTypeDef *get_hal_handle() { return huart_; }
109
110private:
111 UART_HandleTypeDef *huart_;
112 core::Mutex mtx_;
113 core::Queue<uint8_t> rx_queue_;
114
115 static inline uint8_t rx_buf_;
116
117 static inline std::array<UART *, 20> &get_instances() {
118 static std::array<UART *, 20> instances{};
119 return instances;
120 }
121
122 static inline UART *&get_uart_stdout() {
123 static UART *uart = nullptr;
124 return uart;
125 }
126
127 friend void ::HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);
128 friend void ::HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart);
129 friend int ::_write(int file, char *ptr, int len);
130};
131
132} // namespace peripheral
133} // namespace tutrcos
static uint32_t get_ticks()
Definition kernel.hpp:14
Definition mutex.hpp:12
Definition queue.hpp:13
bool pop(T &value, uint32_t timeout)
Definition queue.hpp:33
void clear()
Definition queue.hpp:37
size_t size()
Definition queue.hpp:39
static void delay(uint32_t ticks)
Definition thread.hpp:32
Definition uart.hpp:51
void enable_stdout()
Definition uart.hpp:106
~UART()
Definition uart.hpp:62
UART_HandleTypeDef * get_hal_handle()
Definition uart.hpp:108
UART(UART_HandleTypeDef *huart, size_t rx_queue_size=64)
Definition uart.hpp:53
bool receive(uint8_t *data, size_t size, uint32_t timeout)
Definition uart.hpp:85
bool transmit(const uint8_t *data, size_t size, uint32_t timeout)
Definition uart.hpp:69
void flush()
Definition uart.hpp:101
Definition kernel.hpp:7
int _write(int file, char *ptr, int len)
#define TUTRCOS_VERIFY(expr)
Definition utility.hpp:16