halx_driver
読み取り中…
検索中…
一致する文字列を見つけられません
scs_manager.hpp
[詳解]
1#pragma once
2
3#include <array>
4#include <cstdint>
5#include <optional>
6#include <utility>
7
8#include <halx/peripheral/uart.hpp>
9
10namespace halx::driver {
11
13public:
14 ScsManager(peripheral::UartBase &uart) : uart_{uart} {}
15
16 std::optional<uint8_t> ping(uint8_t id) {
17 if (!send_message(id, Instruction::PING, 0, nullptr, 0)) {
18 return std::nullopt;
19 }
20 return check_error(id);
21 }
22
23 std::optional<uint8_t> read_data(uint8_t id, uint8_t address, uint8_t *data,
24 uint8_t size) {
25 if (!send_message(id, Instruction::READ_DATA, address, &size, 1)) {
26 return std::nullopt;
27 }
28 std::array<uint8_t, 6> buf;
29 if (!uart_.receive(buf.data(), buf.size() - 1, 5)) {
30 return std::nullopt;
31 }
32 if (buf[0] != 0xFF || buf[1] != 0xFF) {
33 return std::nullopt;
34 }
35 if (buf[2] != id) {
36 return std::nullopt;
37 }
38 if (buf[3] != size + 2) {
39 return std::nullopt;
40 }
41 if (!uart_.receive(data, size, 5)) {
42 return std::nullopt;
43 }
44 if (!uart_.receive(&buf[5], 1, 5)) {
45 return std::nullopt;
46 }
47 uint8_t checksum = sum(&buf[2], buf.size() - 3) + sum(data, size);
48 checksum = ~checksum;
49 if (buf[5] != checksum) {
50 return std::nullopt;
51 }
52 return buf[4];
53 }
54
55 std::optional<uint8_t> write_data(uint8_t id, uint8_t address,
56 const uint8_t *data, uint8_t size) {
57 if (!send_message(id, Instruction::WRITE_DATA, address, data, size)) {
58 return false;
59 }
60 return check_error(id);
61 }
62
63 std::optional<uint8_t> reg_write(uint8_t id, uint8_t address,
64 const uint8_t *data, uint8_t size) {
65 if (!send_message(id, Instruction::REG_WRITE, address, data, size)) {
66 return false;
67 }
68 return check_error(id);
69 }
70
71 std::optional<uint8_t> action(uint8_t id) {
72 if (!send_message(id, Instruction::ACTION, 0, nullptr, 0)) {
73 return false;
74 }
75 return check_error(id);
76 }
77
78 std::optional<uint8_t> recovery(uint8_t id) {
79 if (!send_message(id, Instruction::RECOVERY, 0, nullptr, 0)) {
80 return false;
81 }
82 return check_error(id);
83 }
84
85 std::optional<uint8_t> reset(uint8_t id) {
86 if (!send_message(id, Instruction::RESET, 0, nullptr, 0)) {
87 return false;
88 }
89 return check_error(id);
90 }
91
92private:
93 enum class Instruction : uint8_t {
94 PING = 0x01,
95 READ_DATA = 0x02,
96 WRITE_DATA = 0x03,
97 REG_WRITE = 0x04,
98 ACTION = 0x05,
99 SYNC_READ = 0x82,
100 SYNC_WRITE = 0x83,
101 RECOVERY = 0x06,
102 RESET = 0x0A,
103 };
104
105 peripheral::UartBase &uart_;
106
107 bool send_message(uint8_t id, Instruction instruction, uint8_t address,
108 const uint8_t *data, uint8_t size) {
109 std::array<uint8_t, 5> buf{0xFF, 0xFF, id, static_cast<uint8_t>(size + 3),
110 std::to_underlying(instruction)};
111 uart_.flush();
112 if (!uart_.transmit(buf.data(), buf.size(), 5)) {
113 return false;
114 }
115 if (!uart_.transmit(&address, 1, 5)) {
116 return false;
117 }
118 uint8_t checksum = sum(&buf[2], buf.size() - 2) + address;
119 if (data) {
120 if (!uart_.transmit(data, size, 5)) {
121 return false;
122 }
123 for (uint8_t i = 0; i < size; i++) {
124 checksum += data[i];
125 }
126 }
127 checksum = ~checksum;
128 return uart_.transmit(&checksum, 1, 5);
129 }
130
131 std::optional<uint8_t> check_error(uint8_t id) {
132 if (id == 0xFE) {
133 return 0;
134 }
135 std::array<uint8_t, 6> buf;
136 if (!uart_.receive(buf.data(), buf.size(), 5)) {
137 return std::nullopt;
138 }
139 if (buf[0] != 0xFF || buf[1] != 0xFF) {
140 return std::nullopt;
141 }
142 if (buf[2] != id) {
143 return std::nullopt;
144 }
145 if (buf[3] != 2) {
146 return std::nullopt;
147 }
148 uint8_t checksum = sum(&buf[2], buf.size() - 3);
149 checksum = ~checksum;
150 if (buf[5] != checksum) {
151 return std::nullopt;
152 }
153 return buf[4];
154 }
155
156 static inline uint8_t sum(const uint8_t *data, uint8_t size) {
157 uint8_t sum = 0;
158 for (uint8_t i = 0; i < size; ++i) {
159 sum += data[i];
160 }
161 return sum;
162 }
163};
164
165} // namespace halx::driver
std::optional< uint8_t > ping(uint8_t id)
Definition scs_manager.hpp:16
ScsManager(peripheral::UartBase &uart)
Definition scs_manager.hpp:14
std::optional< uint8_t > recovery(uint8_t id)
Definition scs_manager.hpp:78
std::optional< uint8_t > action(uint8_t id)
Definition scs_manager.hpp:71
std::optional< uint8_t > reg_write(uint8_t id, uint8_t address, const uint8_t *data, uint8_t size)
Definition scs_manager.hpp:63
std::optional< uint8_t > reset(uint8_t id)
Definition scs_manager.hpp:85
std::optional< uint8_t > read_data(uint8_t id, uint8_t address, uint8_t *data, uint8_t size)
Definition scs_manager.hpp:23
std::optional< uint8_t > write_data(uint8_t id, uint8_t address, const uint8_t *data, uint8_t size)
Definition scs_manager.hpp:55
Definition amt21.hpp:10