CodexPadFrameDecoder Arduino 库 1.0.3

载入中...
搜索中...
未找到
codex_pad_frame_decoder.h
浏览该文件的文档.
1#pragma once
2
3#ifndef _CODEX_PAD_FRAME_DECODER_H_
4#define _CODEX_PAD_FRAME_DECODER_H_
5
6#include <Stream.h>
7
8#include "robust_frame.h"
9
10/**
11 * @file codex_pad_frame_decoder.h
12 */
13
14/**
15 * @~Chinese
16 * @class CodexPadFrameDecoder
17 * @brief CodexPad 手柄数据帧解码主类。
18 * @details 通过外部传入的 Stream 对象获取原始字节流，内部使用 robust_frame 协议解析器完成帧同步、转义还原和 CRC
19 * 校验，成功接收完整的有效载荷后，输出按键状态和摇杆轴值。
20 */
21/**
22 * @~English
23 * @class CodexPadFrameDecoder
24 * @brief CodexPad controller data frame decoding main class.
25 * @details It takes a Stream object as input to read the raw byte stream, and internally uses the robust_frame protocol parser for frame
26 * synchronization, escape sequence restoration, and CRC validation. Upon successfully receiving a complete and valid payload, it outputs
27 * button states and joystick axis values.
28 */
29 class CodexPadFrameDecoder {
30 public:
31 /**
32 * @~Chinese
33 * @brief 摇杆轴值的数量。
34 */
35 /**
36 * @~English
37 * @brief Number of axis values.
38 */
39 static constexpr size_t kAxisValueNum = 4;
40
41 /**
42 * @~Chinese
43 * @brief 摇杆轴的中心值（静止时的典型值）。
44 */
45 /**
46 * @~English
47 * @brief Center value of joystick axes (typical value at rest).
48 */
49 static constexpr uint8_t kAxisCenter = 0x80;
50
51 /**
52 * @~Chinese
53 * @brief 手柄输入报告的类型标识（有效载荷的第一个字节）。
54 */
55 /**
56 * @~English
57 * @brief Input report type identifier for the gamepad (the first byte of the payload).
58 */
59 static constexpr uint8_t kPayloadType = 0x01;
60
61 /**
62 * @~Chinese
63 * @enum Button
64 * @brief 手柄按键掩码枚举。
65 */
66 /**
67 * @~English
68 * @enum Button
69 * @brief Gamepad button mask enumeration.
70 */
71 enum class Button : uint32_t {
72 /**
73 * @~Chinese
74 * @brief 上。
75 */
76 /**
77 * @~English
78 * @brief Up.
79 */
80 kUp = uint32_t{1} << 0,
81
82 /**
83 * @~Chinese
84 * @brief 下。
85 */
86 /**
87 * @~English
88 * @brief Down.
89 */
90 kDown = uint32_t{1} << 1,
91
92 /**
93 * @~Chinese
94 * @brief 左。
95 */
96 /**
97 * @~English
98 * @brief Left.
99 */
100 kLeft = uint32_t{1} << 2,
101
102 /**
103 * @~Chinese
104 * @brief 右。
105 */
106 /**
107 * @~English
108 * @brief Right.
109 */
110 kRight = uint32_t{1} << 3,
111
112 /**
113 * @~Chinese
114 * @brief 方形 或者 X。
115 */
116 /**
117 * @~English
118 * @brief Square or X.
119 */
120 kSquareX = uint32_t{1} << 4,
121
122 /**
123 * @~Chinese
124 * @brief 三角形 或者 Y。
125 */
126 /**
127 * @~English
128 * @brief Triangle or Y.
129 */
130 kTriangleY = uint32_t{1} << 5,
131
132 /**
133 * @~Chinese
134 * @brief 叉形 或者 A。
135 */
136 /**
137 * @~English
138 * @brief Cross or A.
139 */
140 kCrossA = uint32_t{1} << 6,
141
142 /**
143 * @~Chinese
144 * @brief 圆形 或者 B。
145 */
146 /**
147 * @~English
148 * @brief Circle or B.
149 */
150 kCircleB = uint32_t{1} << 7,
151
152 /**
153 * @~Chinese
154 * @brief L1。
155 */
156 /**
157 * @~English
158 * @brief L1.
159 */
160 kL1 = uint32_t{1} << 8,
161
162 /**
163 * @~Chinese
164 * @brief L2。
165 */
166 /**
167 * @~English
168 * @brief L2.
169 */
170 kL2 = uint32_t{1} << 9,
171
172 /**
173 * @~Chinese
174 * @brief L3。
175 */
176 /**
177 * @~English
178 * @brief L3.
179 */
180 kL3 = uint32_t{1} << 10,
181
182 /**
183 * @~Chinese
184 * @brief R1。
185 */
186 /**
187 * @~English
188 * @brief R1.
189 */
190 kR1 = uint32_t{1} << 11,
191
192 /**
193 * @~Chinese
194 * @brief R2。
195 */
196 /**
197 * @~English
198 * @brief R2.
199 */
200 kR2 = uint32_t{1} << 12,
201
202 /**
203 * @~Chinese
204 * @brief R3。
205 */
206 /**
207 * @~English
208 * @brief R3.
209 */
210 kR3 = uint32_t{1} << 13,
211
212 /**
213 * @~Chinese
214 * @brief 选择。
215 */
216 /**
217 * @~English
218 * @brief Select.
219 */
220 kSelect = uint32_t{1} << 14,
221
222 /**
223 * @~Chinese
224 * @brief 开始。
225 */
226 /**
227 * @~English
228 * @brief Start.
229 */
230 kStart = uint32_t{1} << 15,
231
232 /**
233 * @~Chinese
234 * @brief 首页。
235 */
236 /**
237 * @~English
238 * @brief Home.
239 */
240 kHome = uint32_t{1} << 16,
241 };
242
243 /**
244 * @~Chinese
245 * @enum Axis
246 * @brief 摇杆轴索引枚举。
247 */
248 /**
249 * @~English
250 * @enum Axis
251 * @brief Joystick axis index enumeration.
252 */
253 enum class Axis : size_t {
254 /**
255 * @~Chinese
256 * @brief 左摇杆X轴。
257 */
258 /**
259 * @~English
260 * @brief Left stick X axis.
261 */
262 kLeftStickX,
263
264 /**
265 * @~Chinese
266 * @brief 左摇杆Y轴。
267 */
268 /**
269 * @~English
270 * @brief Left stick Y axis.
271 */
272 kLeftStickY,
273
274 /**
275 * @~Chinese
276 * @brief 右摇杆X轴。
277 */
278 /**
279 * @~English
280 * @brief Right stick X axis.
281 */
282 kRightStickX,
283
284 /**
285 * @~Chinese
286 * @brief 右摇杆Y轴。
287 */
288 /**
289 * @~English
290 * @brief Right stick Y axis.
291 */
292 kRightStickY,
293 };
294
295 /**
296 * @~Chinese
297 * @brief 构造函数。
298 * @param[in] stream 用于读取数据字节流的 Stream 对象引用。
299 */
300 /**
301 * @~English
302 * @brief Constructor.
303 * @param[in] stream Reference to a Stream object for reading data byte stream.
304 */
305 CodexPadFrameDecoder(Stream &stream);
306
307 /**
308 * @~Chinese
309 * @brief 更新解码器状态。需要在主循环中不断调用此函数，以喂入并解析字节流。
310 */
311 /**
312 * @~English
313 * @brief Update the decoder state. This function must be called continuously in the main loop
314 * to feed and parse the byte stream.
315 */
316 void Update();
317
318 /**
319 * @~Chinese
320 * @brief 查询按键是否被按下。
321 * @retval true 按键被按下。
322 * @retval false 按键没有被按下。
323 */
324 /**
325 * @~English
326 * @brief check if a button is pressed.
327 * @retval true if the button is pressed.
328 * @retval false if the button is not pressed.
329 */
330 bool pressed(const Button button) const;
331
332 /**
333 * @~Chinese
334 * @brief 查询按键是否被释放。
335 * @retval true 按键被释放。
336 * @retval false 按键没有被释放。
337 */
338 /**
339 * @~English
340 * @brief check if a button is released.
341 * @retval true if the button is released.
342 * @retval false if the button is not released.
343 */
344 bool released(const Button button) const;
345
346 /**
347 * @~Chinese
348 * @brief 查询按键是否被持续按下。
349 * @retval true 按键被持续按下。
350 * @retval false 按键没有被持续按下。
351 */
352 /**
353 * @~English
354 * @brief check if a button is held.
355 * @retval true if the button is held.
356 * @retval false if the button is not held.
357 */
358 bool holding(const Button button) const;
359
360 /**
361 * @~Chinese
362 * @brief 查询按键是否被按下或持续按下。
363 * @retval true 按键被按下或持续按下。
364 * @retval false 按键没有被按下或持续按下。
365 */
366 /**
367 * @~English
368 * @brief check if a button is pressed or held.
369 * @retval true if the button is pressed or held.
370 * @retval false if the button is not pressed or held.
371 */
372 bool button_state(const Button button) const;
373
374 /**
375 * @~Chinese
376 * @brief 以位掩码形式获取所有按键的当前状态。
377 * @return 一个32位无符号整数，每一位（bit）表示 @ref Button 枚举中对应按键的状态（1为按下，0为未按下）。
378 * 位的分配从最低有效位（LSB，第0位）开始，依次对应 @ref Button 中的各个值。
379 * 可使用位与操作 (&) 配合具体的 @ref Button 枚举值来检查特定按键状态。
380 * 示例：
381 * @code
382 * const uint32_t button_states = g_codex_pad_frame_decoder.button_states();
383 * if ((button_states & CodexPadFrameDecoder::Button::kUp)) != 0) {
384 * // 方向上按键被按下
385 * }
386 * @endcode
387 */
388 /**
389 * @~English
390 * @brief Get all button states, return a 32-bit unsigned integer where each bit represents the state of a specific button.
391 * @return A 32-bit unsigned integer where each bit represents the state of a specific button.
392 * The bits are from the least significant bit (LSB, bit 0) to the most significant bit (MSB, bit 31).
393 * You can use bit-and (&) operator to check specific button states.
394 * Example:
395 * @code
396 * const uint32_t button_states = g_codex_pad_frame_decoder.button_states();
397 * if ((button_states & CodexPadFrameDecoder::Button::kUp) != 0) {
398 * // Up button is pressed
399 * }
400 * @endcode
401 */
402 uint32_t button_states() const;
403
404 /**
405 * @~Chinese
406 * @brief 获取指定摇杆轴的原始值（0~255）。
407 * @param[in] axis 要读取的轴。
408 * @return 该轴的当前值，中心为 0x80。
409 */
410 /**
411 * @~English
412 * @brief Get the raw value (0~255) of a specified joystick axis.
413 * @param[in] axis The axis to read.
414 * @return The current value of the axis, with center at 0x80.
415 */
416 uint8_t axis_value(const Axis axis) const;
417
418 /**
419 * @~Chinese
420 * @brief 获取所有模拟轴的当前值（返回只读数组指针）。
421 * @details 返回指向内部 4 字节数组的 const 指针，索引与 Axis 枚举对应关系：
422 * - 索引 0：左摇杆 X 轴 (Axis::kLeftStickX)
423 * - 索引 1：左摇杆 Y 轴 (Axis::kLeftStickY)
424 * - 索引 2：右摇杆 X 轴 (Axis::kRightStickX)
425 * - 索引 3：右摇杆 Y 轴 (Axis::kRightStickY)
426 * 每个值的范围 0~255，中心位置为 128 (0x80)。
427 * @return const uint8_t* 指向 4 字节轴值数组的只读指针。
428 * @note 返回的指针在 CodexPadFrameDecoder 对象生命周期内有效，下次调用 Update() 后内容会更新。
429 *
430 * 示例：
431 * @code
432 * const uint8_t *axes = g_codex_pad_frame_decoder.axis_values();
433 * uint8_t left_stick_x = axes[static_cast<size_t>(CodexPadFrameDecoder::Axis::kLeftStickX)];
434 * uint8_t left_stick_y = axes[static_cast<size_t>(CodexPadFrameDecoder::Axis::kLeftStickY)];
435 * @endcode
436 */
437 /**
438 * @~English
439 * @brief Get current values of all analog axes (returns a read-only array pointer).
440 * @details Returns a const pointer to the internal 4-byte array. Indices correspond to the Axis enumeration:
441 * - Index 0: Left stick X axis (Axis::kLeftStickX)
442 * - Index 1: Left stick Y axis (Axis::kLeftStickY)
443 * - Index 2: Right stick X axis (Axis::kRightStickX)
444 * - Index 3: Right stick Y axis (Axis::kRightStickY)
445 * Each value ranges from 0 to 255, with the neutral center at 128 (0x80).
446 * @return const uint8_t* Read-only pointer to the 4-byte axis value array.
447 * @note The returned pointer is valid for the lifetime of the CodexPadFrameDecoder object.
448 * Content will be updated after the next call to Update().
449 *
450 * Example:
451 * @code
452 * const uint8_t *axes = g_codex_pad_frame_decoder.axis_values();
453 * uint8_t left_stick_x = axes[static_cast<size_t>(CodexPadFrameDecoder::Axis::kLeftStickX)];
454 * uint8_t left_stick_y = axes[static_cast<size_t>(CodexPadFrameDecoder::Axis::kLeftStickY)];
455 * @endcode
456 */
457 const uint8_t *axis_values() const;
458
459 /**
460 * @~Chinese
461 * @brief 查询轴值是否发生变化。
462 * @param[in] axis 轴。
463 * @param[in] threshold 阈值。
464 * @retval true 轴值发生变化。
465 * @retval false 轴值未发生变化。
466 */
467 /**
468 * @~English
469 * @brief check if an axis value has changed.
470 * @param[in] axis Axis.
471 * @param[in] threshold Threshold.
472 * @retval true if the axis value has changed.
473 * @retval false if the axis value has not changed.
474 */
475 bool HasAxisValueChanged(const Axis axis, const uint8_t threshold) const;
476
477 private:
478 CodexPadFrameDecoder(const CodexPadFrameDecoder &) = delete;
479 CodexPadFrameDecoder &operator=(const CodexPadFrameDecoder &) = delete;
480
481 struct Inputs {
482 uint32_t button_states = 0;
483 uint8_t axis_values[kAxisValueNum] = {kAxisCenter, kAxisCenter, kAxisCenter, kAxisCenter};
484 };
485
486 void OnFrame(const uint8_t *data);
487
488 static void OnFrameReceived(const uint8_t *data, void *user_data);
489
490 Inputs prev_inputs_;
491 Inputs current_inputs_;
492
493 robust_frame::Parser parser_;
494
495 Stream &stream_;
496};
497
498#endif // _CODEX_PAD_FRAME_DECODER_H_
CodexPadFrameDecoder
CodexPad 手柄数据帧解码主类。
定义 codex_pad_frame_decoder.h:29
CodexPadFrameDecoder::Update
void Update()
更新解码器状态。需要在主循环中不断调用此函数，以喂入并解析字节流。
定义 codex_pad_frame_decoder.cpp:24
CodexPadFrameDecoder::button_states
uint32_t button_states() const
以位掩码形式获取所有按键的当前状态。
定义 codex_pad_frame_decoder.cpp:48
CodexPadFrameDecoder::axis_values
const uint8_t * axis_values() const
获取所有模拟轴的当前值（返回只读数组指针）。
定义 codex_pad_frame_decoder.cpp:56
CodexPadFrameDecoder::holding
bool holding(const Button button) const
查询按键是否被持续按下。
定义 codex_pad_frame_decoder.cpp:40
CodexPadFrameDecoder::HasAxisValueChanged
bool HasAxisValueChanged(const Axis axis, const uint8_t threshold) const
查询轴值是否发生变化。
定义 codex_pad_frame_decoder.cpp:60
CodexPadFrameDecoder::axis_value
uint8_t axis_value(const Axis axis) const
获取指定摇杆轴的原始值（0~255）。
定义 codex_pad_frame_decoder.cpp:52
CodexPadFrameDecoder::kAxisValueNum
static constexpr size_t kAxisValueNum
摇杆轴值的数量。
定义 codex_pad_frame_decoder.h:39
CodexPadFrameDecoder::kAxisCenter
static constexpr uint8_t kAxisCenter
摇杆轴的中心值（静止时的典型值）。
定义 codex_pad_frame_decoder.h:49
CodexPadFrameDecoder::kPayloadType
static constexpr uint8_t kPayloadType
手柄输入报告的类型标识（有效载荷的第一个字节）。
定义 codex_pad_frame_decoder.h:59
CodexPadFrameDecoder::released
bool released(const Button button) const
查询按键是否被释放。
定义 codex_pad_frame_decoder.cpp:36
CodexPadFrameDecoder::pressed
bool pressed(const Button button) const
查询按键是否被按下。
定义 codex_pad_frame_decoder.cpp:32
CodexPadFrameDecoder::Button
Button
手柄按键掩码枚举。
定义 codex_pad_frame_decoder.h:71
CodexPadFrameDecoder::Button::kSelect
@ kSelect
选择。
定义 codex_pad_frame_decoder.h:220
CodexPadFrameDecoder::Button::kStart
@ kStart
开始。
定义 codex_pad_frame_decoder.h:230
CodexPadFrameDecoder::Button::kL2
@ kL2
L2。
定义 codex_pad_frame_decoder.h:170
CodexPadFrameDecoder::Button::kL1
@ kL1
L1。
定义 codex_pad_frame_decoder.h:160
CodexPadFrameDecoder::Button::kCrossA
@ kCrossA
叉形 或者 A。
定义 codex_pad_frame_decoder.h:140
CodexPadFrameDecoder::Button::kLeft
@ kLeft
左。
定义 codex_pad_frame_decoder.h:100
CodexPadFrameDecoder::Button::kRight
@ kRight
右。
定义 codex_pad_frame_decoder.h:110
CodexPadFrameDecoder::Button::kHome
@ kHome
首页。
定义 codex_pad_frame_decoder.h:240
CodexPadFrameDecoder::Button::kL3
@ kL3
L3。
定义 codex_pad_frame_decoder.h:180
CodexPadFrameDecoder::Button::kDown
@ kDown
下。
定义 codex_pad_frame_decoder.h:90
CodexPadFrameDecoder::Button::kSquareX
@ kSquareX
方形 或者 X。
定义 codex_pad_frame_decoder.h:120
CodexPadFrameDecoder::Button::kR3
@ kR3
R3。
定义 codex_pad_frame_decoder.h:210
CodexPadFrameDecoder::Button::kR2
@ kR2
R2。
定义 codex_pad_frame_decoder.h:200
CodexPadFrameDecoder::Button::kUp
@ kUp
上。
定义 codex_pad_frame_decoder.h:80
CodexPadFrameDecoder::Button::kCircleB
@ kCircleB
圆形 或者 B。
定义 codex_pad_frame_decoder.h:150
CodexPadFrameDecoder::Button::kR1
@ kR1
R1。
定义 codex_pad_frame_decoder.h:190
CodexPadFrameDecoder::Button::kTriangleY
@ kTriangleY
三角形 或者 Y。
定义 codex_pad_frame_decoder.h:130
CodexPadFrameDecoder::CodexPadFrameDecoder
CodexPadFrameDecoder(Stream &stream)
构造函数。
定义 codex_pad_frame_decoder.cpp:9
CodexPadFrameDecoder::Axis
Axis
摇杆轴索引枚举。
定义 codex_pad_frame_decoder.h:253
CodexPadFrameDecoder::Axis::kLeftStickX
@ kLeftStickX
左摇杆X轴。
定义 codex_pad_frame_decoder.h:262
CodexPadFrameDecoder::Axis::kRightStickY
@ kRightStickY
右摇杆Y轴。
定义 codex_pad_frame_decoder.h:292
CodexPadFrameDecoder::Axis::kLeftStickY
@ kLeftStickY
左摇杆Y轴。
定义 codex_pad_frame_decoder.h:272
CodexPadFrameDecoder::Axis::kRightStickX
@ kRightStickX
右摇杆X轴。
定义 codex_pad_frame_decoder.h:282
CodexPadFrameDecoder::button_state
bool button_state(const Button button) const
查询按键是否被按下或持续按下。
定义 codex_pad_frame_decoder.cpp:44
robust_frame.h