M5Unit-KEYBOARD 0.1.0 git rev:b58d024
Loading...
Searching...
No Matches
unit_Keyboard.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_KEYBOARD_UNIT_KEYBOARD_HPP
11#define M5_UNIT_KEYBOARD_UNIT_KEYBOARD_HPP
12
13#include <M5UnitComponent.hpp>
14#include <vector>
15
17
18namespace m5 {
19namespace unit {
20
25namespace keyboard {
26using key_index_t = uint8_t;
27
28using key_status_bits_t = uint64_t;
29// clang-format off
32constexpr key_status_bits_t MODIFIER_SHIFT_BIT {0x0100000000000000};
33constexpr key_status_bits_t MODIFIER_SYMBOL_BIT {0x0200000000000000};
34constexpr key_status_bits_t MODIFIER_FUNCTION_BIT{0x0400000000000000};
35constexpr key_status_bits_t MODIFIER_ALT_BIT {0x0800000000000000};
36constexpr key_status_bits_t MODIFIER_CONTROL_BIT {0x1000000000000000};
37constexpr key_status_bits_t MODIFIER_OPTION_BIT {0x2000000000000000};
41// clang-format on
42
53
58enum class Mode : uint8_t {
70};
71
72} // namespace keyboard
73
78class UnitKeyboard : public Component {
79 M5_UNIT_COMPONENT_HPP_BUILDER(UnitKeyboard, 0x00);
80
81public:
82 // 0x5F:CardKB 0x08:FacesQWERTY
83 explicit UnitKeyboard(const uint8_t addr = DEFAULT_ADDRESS) : Component(addr)
84 {
85 auto ccfg = component_config();
86 ccfg.clock = 100 * 1000U;
87 component_config(ccfg);
88 }
89 virtual ~UnitKeyboard()
90 {
91 }
92
94 virtual bool begin() override;
96 virtual void update(const bool force = false) override;
97
104 inline virtual char getchar() const
105 {
106 return released();
107 }
108
114 inline virtual uint8_t released() const
115 {
116 return updated() ? _released_key : 0;
117 }
118
119private:
120 uint8_t _released_key{}; // for old firmware
121};
122
128class UnitKeyboardBitwise : public UnitKeyboard, public PeriodicMeasurementAdapter<UnitKeyboardBitwise, uint8_t> {
129 M5_UNIT_COMPONENT_HPP_BUILDER(UnitKeyboardBitwise, 0x00);
130
131public:
132 explicit UnitKeyboardBitwise(const uint8_t addr = DEFAULT_ADDRESS)
133 : UnitKeyboard(addr), _data{new m5::container::CircularBuffer<uint8_t>(1)}
134 {
135 }
136 virtual ~UnitKeyboardBitwise()
137 {
138 }
139
141 virtual void update(const bool force = false) override;
142
145
150 inline virtual char getchar() const override
151 {
152 return (_mode == keyboard::Mode::M5UnitUnified) ? pressed() : released();
153 }
159 inline uint8_t pressed() const
160 {
161 return !empty() ? oldest() : 0x00;
162 }
167 inline virtual uint8_t released() const override
168 {
169 return (_mode == keyboard::Mode::Conventional) ? UnitKeyboard::released() : 0x00;
170 }
172
175
181 inline bool startPeriodicMeasurement(const uint32_t interval)
182 {
183 return PeriodicMeasurementAdapter<UnitKeyboardBitwise, uint8_t>::startPeriodicMeasurement(interval);
184 }
187 {
188 return PeriodicMeasurementAdapter<UnitKeyboardBitwise, uint8_t>::startPeriodicMeasurement();
189 }
195 {
196 return PeriodicMeasurementAdapter<UnitKeyboardBitwise, uint8_t>::stopPeriodicMeasurement();
197 }
199
207 {
208 return _state.now.to_ullong();
209 }
212 {
213 return _state.prev.to_ullong();
214 }
217 {
218 return _state.pressed.to_ullong();
219 }
222 {
223 return _state.released.to_ullong();
224 }
227 {
228 return _state.holding.to_ullong();
229 }
232 {
233 return _state.was_hold.to_ullong();
234 }
237 {
238 return _state.repeating.to_ullong();
239 }
242 {
243 return modifier_bits();
244 }
246
253 inline bool isModifier() const
254 {
255 return modifier_bits() != 0;
256 }
258 inline bool isShift() const
259 {
260 return modifier_bits() & keyboard::MODIFIER_SHIFT_BIT;
261 }
263 inline bool isSymbol() const
264 {
265 return modifier_bits() & keyboard::MODIFIER_SYMBOL_BIT;
266 }
268 inline bool isFunction() const
269 {
270 return modifier_bits() & keyboard::MODIFIER_FUNCTION_BIT;
271 }
273 inline bool isAlt() const
274 {
275 return modifier_bits() & keyboard::MODIFIER_ALT_BIT;
276 }
278 inline bool isControl() const
279 {
280 return modifier_bits() & keyboard::MODIFIER_CONTROL_BIT;
281 }
283 inline bool isOption() const
284 {
285 return modifier_bits() & keyboard::MODIFIER_OPTION_BIT;
286 }
287
289 inline bool isShiftEqual() const
290 {
291 return modifier_bits() == keyboard::MODIFIER_SHIFT_BIT;
292 }
294 inline bool isSymbolEqual() const
295 {
296 return modifier_bits() == keyboard::MODIFIER_SYMBOL_BIT;
297 }
299 inline bool isFunctionEqual() const
300 {
301 return modifier_bits() == keyboard::MODIFIER_FUNCTION_BIT;
302 }
304 inline bool isAltEqual() const
305 {
306 return modifier_bits() == keyboard::MODIFIER_ALT_BIT;
307 }
309 inline bool isControlEqual() const
310 {
311 return modifier_bits() == keyboard::MODIFIER_CONTROL_BIT;
312 }
314 inline bool isOptionEqual() const
315 {
316 return modifier_bits() == keyboard::MODIFIER_OPTION_BIT;
317 }
319
325 inline bool isPressed() const
326 {
327 return _state.now.any();
328 }
331 inline bool isReleased() const
332 {
333 return !isPressed();
334 }
336 inline bool wasPressed() const
337 {
338 return _state.pressed.any();
339 }
341 inline bool wasReleased() const
342 {
343 return _state.released.any();
344 }
346 inline bool isHolding() const
347 {
348 return _state.holding.any();
349 }
351 inline bool wasHold() const
352 {
353 return _state.was_hold.any();
354 }
356 inline bool isRepeating() const
357 {
358 return _state.repeating.any();
359 }
361
365
370 // inline
371 bool isPressed(const keyboard::key_index_t kidx) const
372 {
373 return (kidx < 64) && _state.now.test(kidx);
374 }
380 inline bool isReleased(const keyboard::key_index_t kidx) const
381 {
382 return !isPressed(kidx);
383 }
389 inline bool wasPressed(const keyboard::key_index_t kidx) const
390 {
391 return (kidx < 64) && _state.pressed.test(kidx);
392 }
398 inline bool wasReleased(const keyboard::key_index_t kidx) const
399 {
400 return (kidx < 64) && _state.released.test(kidx);
401 }
407 inline bool isHolding(const keyboard::key_index_t kidx) const
408 {
409 return (kidx < 64) && _state.holding.test(kidx);
410 }
416 inline bool wasHold(const keyboard::key_index_t kidx) const
417 {
418 return (kidx < 64) && _state.was_hold.test(kidx);
419 }
425 inline bool isRepeating(const keyboard::key_index_t kidx) const
426 {
427 return (kidx < 64) && _state.repeating.test(kidx);
428 }
430
439
444 inline virtual keyboard::key_index_t toKeyIndex(const char) const
445 {
446 return 0xFF;
447 }
453 inline bool isPressed(const char ch) const
454 {
455 auto kidx = toKeyIndex(ch);
456 return kidx != 0xFF && isPressed(kidx) && permitted_mode(to_mode_bits(ch));
457 }
463 inline bool isReleased(const char ch) const
464 {
465 return !isPressed(ch);
466 }
472 inline bool wasPressed(const char ch) const
473 {
474 auto kidx = toKeyIndex(ch);
475 return kidx != 0xFF && wasPressed(kidx) && permitted_mode(to_mode_bits(ch));
476 }
482 inline bool wasReleased(const char ch) const
483 {
484 auto kidx = toKeyIndex(ch);
485 return kidx != 0xFF && wasReleased(kidx) && permitted_mode(to_mode_bits(ch));
486 }
492 inline bool isHolding(const char ch) const
493 {
494 auto kidx = toKeyIndex(ch);
495 return kidx != 0xFF && isHolding(kidx) && permitted_mode(to_mode_bits(ch));
496 }
502 inline bool wasHold(const char ch) const
503 {
504 auto kidx = toKeyIndex(ch);
505 return kidx != 0xFF && wasHold(kidx) && permitted_mode(to_mode_bits(ch));
506 }
512 inline bool isRepeating(const char ch) const
513 {
514 auto kidx = toKeyIndex(ch);
515 return kidx != 0xFF && isRepeating(kidx) && permitted_mode(to_mode_bits(ch));
516 }
518
522
528 inline uint8_t firmwareVersion() const
529 {
530 return _firmware_version;
531 }
537 virtual bool readFirmwareVersion(uint8_t& ver);
539
544 inline uint32_t holdingThreshold() const
545 {
546 return _state.holding_threshold_ms;
547 }
549 inline uint32_t repeatingThreshold() const
550 {
551 return _state.repeat_initial_ms;
552 }
555 inline void setHoldingThreshold(const uint32_t ms)
556 {
557 _state.holding_threshold_ms = ms;
558 }
561 inline void setRepeatingThreshold(const uint32_t ms)
562 {
563 _state.repeat_initial_ms = ms;
564 _state.repeat_rate_ms = ms; // CardKB-style: rate == initial (legacy single-threshold behavior)
565 }
567
572
577 virtual bool readMode(keyboard::Mode& mode);
583 virtual bool writeMode(const keyboard::Mode mode);
585
586protected:
587 bool start_periodic_measurement();
588 bool start_periodic_measurement(const uint32_t interval);
589 bool stop_periodic_measurement();
590
591 bool update_new_firmware(const types::elapsed_time_t at);
592 void push_back(m5::container::CircularBuffer<uint8_t>* container, const uint8_t kidx, const uint8_t alt);
593
594 inline keyboard::key_status_bits_t modifier_bits() const
595 {
596 return keyboard::modifier_bits(_state.now.to_ullong());
597 }
598
599 inline virtual uint8_t to_mode_bits(const char) const
600 {
601 return 0x00;
602 }
603
604 inline virtual uint8_t scan_reg_addr() const
605 {
606 return 0x10;
607 }
608 inline virtual uint8_t mode_reg_addr() const
609 {
610 return 0x20;
611 }
612 inline virtual uint8_t firmware_version_reg_addr() const
613 {
614 return 0xFE;
615 }
616
617 bool permitted_mode(const uint8_t mbits) const
618 {
619 uint8_t mod8 = static_cast<uint8_t>(_state.now.to_ullong() >> 56);
620 // mod8 bit0=Shift→mbits bit1, bit1=Sym→bit2, bit2=Fn→bit3
621 return mbits & (mod8 ? (mod8 << 1) : 0x01);
622 }
623
624 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitKeyboardBitwise, uint8_t);
625
626protected:
627 std::unique_ptr<m5::container::CircularBuffer<uint8_t>> _data{}; // was Pressed keys
628 m5::unit::keyboard_bitwise::BitwiseState<64> _state;
629 uint8_t _firmware_version{};
630 keyboard::Mode _mode{keyboard::Mode::Conventional};
631};
632
633namespace keyboard {
634namespace command {
635constexpr uint8_t CMD_SCAN_REG{0x10};
636constexpr uint8_t CMD_MODE_REG{0x20};
637constexpr uint8_t CMD_FIRMWARE_VERSION_REG{0xFE};
638} // namespace command
639
640} // namespace keyboard
641
642} // namespace unit
643} // namespace m5
644#endif
Generic bit-map state tracking for keyboard-like devices.
bool isFunction() const
Is the function key pressed?
Definition unit_Keyboard.hpp:268
bool wasHold(const char ch) const
Was the specified character hold?
Definition unit_Keyboard.hpp:502
bool isOption() const
Is the option key pressed?
Definition unit_Keyboard.hpp:283
bool isControlEqual() const
Is only control pressed among the modifier keys?
Definition unit_Keyboard.hpp:309
keyboard::key_status_bits_t modifierBits() const
Get the bits of the modifier key being pressed.
Definition unit_Keyboard.hpp:241
keyboard::key_status_bits_t nowBits() const
Get the bits of the key being pressed.
Definition unit_Keyboard.hpp:206
bool isModifier() const
Is any modifier key pressed?
Definition unit_Keyboard.hpp:253
uint32_t repeatingThreshold() const
Gets the repeating threshold (ms)
Definition unit_Keyboard.hpp:549
virtual void update(const bool force=false) override
Definition unit_Keyboard.cpp:63
bool isAlt() const
Is the alt key pressed?
Definition unit_Keyboard.hpp:273
bool startPeriodicMeasurement(const uint32_t interval)
Start periodic measurement.
Definition unit_Keyboard.hpp:181
bool isOptionEqual() const
Is only option pressed among the modifier keys?
Definition unit_Keyboard.hpp:314
bool isSymbol() const
Is the symbol key pressed?
Definition unit_Keyboard.hpp:263
bool wasReleased(const keyboard::key_index_t kidx) const
Was the specified key released?
Definition unit_Keyboard.hpp:398
bool isRepeating(const char ch) const
Is the specified character repeating?
Definition unit_Keyboard.hpp:512
bool isReleased(const keyboard::key_index_t kidx) const
Is the specified key released?
Definition unit_Keyboard.hpp:380
bool wasHold() const
Was any key hold?
Definition unit_Keyboard.hpp:351
bool isHolding() const
Is any key holding?
Definition unit_Keyboard.hpp:346
void setRepeatingThreshold(const uint32_t ms)
Sets the repeating threshold.
Definition unit_Keyboard.hpp:561
bool isReleased(const char ch) const
Is the specified character released?
Definition unit_Keyboard.hpp:463
bool isPressed(const keyboard::key_index_t kidx) const
Is the specified key pressed?
Definition unit_Keyboard.hpp:371
bool wasReleased() const
Was any key released?
Definition unit_Keyboard.hpp:341
bool isRepeating(const keyboard::key_index_t kidx) const
Is the specified key repeating?
Definition unit_Keyboard.hpp:425
bool isHolding(const keyboard::key_index_t kidx) const
Is the specified key holding?
Definition unit_Keyboard.hpp:407
bool isSymbolEqual() const
Is only symbol pressed among the modifier keys?
Definition unit_Keyboard.hpp:294
uint32_t holdingThreshold() const
Gets the holding threshold (ms)
Definition unit_Keyboard.hpp:544
keyboard::key_status_bits_t wasHoldBits() const
Get the bits of the key at the moment of hold.
Definition unit_Keyboard.hpp:231
bool wasReleased(const char ch) const
Was the specified character released?
Definition unit_Keyboard.hpp:482
bool isRepeating() const
Is any key repeating?
Definition unit_Keyboard.hpp:356
keyboard::key_status_bits_t repeatingBits() const
Get the bits of the key that the software is repeatedly pressing.
Definition unit_Keyboard.hpp:236
bool isFunctionEqual() const
Is only function pressed among the modifier keys?
Definition unit_Keyboard.hpp:299
keyboard::key_status_bits_t releasedBits() const
Get the key bits at the moment they are released.
Definition unit_Keyboard.hpp:221
bool isHolding(const char ch) const
Is the specified character holding?
Definition unit_Keyboard.hpp:492
bool wasPressed(const char ch) const
Was the specified character pressed?
Definition unit_Keyboard.hpp:472
bool isShiftEqual() const
Is only shift pressed among the modifier keys?
Definition unit_Keyboard.hpp:289
keyboard::key_status_bits_t holdingBits() const
Get the bits of the held key.
Definition unit_Keyboard.hpp:226
bool isPressed() const
Is any key pressed?
Definition unit_Keyboard.hpp:325
keyboard::key_status_bits_t pressedBits() const
Get the key bits at the moment they are pressed.
Definition unit_Keyboard.hpp:216
keyboard::key_status_bits_t previousBits() const
Get the bits of the previous key pressed.
Definition unit_Keyboard.hpp:211
void setHoldingThreshold(const uint32_t ms)
Sets the holding threshold.
Definition unit_Keyboard.hpp:555
bool startPeriodicMeasurement()
Start periodic measurement using current settings.
Definition unit_Keyboard.hpp:186
bool isShift() const
Is the shift key pressed?
Definition unit_Keyboard.hpp:258
virtual uint8_t released() const override
Get the oldest released key.
Definition unit_Keyboard.hpp:167
virtual keyboard::key_index_t toKeyIndex(const char) const
Obtains the key index corresponding to the specified character.
Definition unit_Keyboard.hpp:444
virtual bool readMode(keyboard::Mode &mode)
Read the mode.
Definition unit_Keyboard.cpp:102
virtual bool readFirmwareVersion(uint8_t &ver)
Read the firmware version.
Definition unit_Keyboard.cpp:96
bool isReleased() const
Are all keys released?
Definition unit_Keyboard.hpp:331
uint8_t pressed() const
Get the oldest pressed key.
Definition unit_Keyboard.hpp:159
bool wasPressed(const keyboard::key_index_t kidx) const
Was the specified key pressed?
Definition unit_Keyboard.hpp:389
bool stopPeriodicMeasurement()
Stop periodic measurement.
Definition unit_Keyboard.hpp:194
virtual bool writeMode(const keyboard::Mode mode)
Write the mode.
Definition unit_Keyboard.cpp:113
uint8_t firmwareVersion() const
Gets the firmware version.
Definition unit_Keyboard.hpp:528
bool wasPressed() const
Was any key pressed?
Definition unit_Keyboard.hpp:336
bool isAltEqual() const
Is only alt pressed among the modifier keys?
Definition unit_Keyboard.hpp:304
bool isPressed(const char ch) const
Is the specified character pressed?
Definition unit_Keyboard.hpp:453
bool wasHold(const keyboard::key_index_t kidx) const
Was the specified key hold?
Definition unit_Keyboard.hpp:416
virtual char getchar() const override
Gets the input character.
Definition unit_Keyboard.hpp:150
bool isControl() const
Is the control key pressed?
Definition unit_Keyboard.hpp:278
virtual char getchar() const
Gets the input character.
Definition unit_Keyboard.hpp:104
virtual uint8_t released() const
Gets the released key character code if updated.
Definition unit_Keyboard.hpp:114
virtual bool begin() override
Definition unit_Keyboard.cpp:26
virtual void update(const bool force=false) override
Definition unit_Keyboard.cpp:44
For keyboard.
Top level namespace of M5Stack.
Unit-related namespace.
uint8_t key_index_t
Key index (Not character)
Definition unit_Keyboard.hpp:26
Mode
Operation mode for M5Unit-KEYBOARD firmware.
Definition unit_Keyboard.hpp:58
constexpr key_status_bits_t MODIFIER_ALT_BIT
Alt.
Definition unit_Keyboard.hpp:35
constexpr key_status_bits_t MODIFIER_SYMBOL_BIT
Symbol.
Definition unit_Keyboard.hpp:33
uint64_t key_status_bits_t
key state bits [56...63]:modifier, bits [0...55]:key bits
Definition unit_Keyboard.hpp:28
constexpr key_status_bits_t MODIFIER_CONTROL_BIT
Control.
Definition unit_Keyboard.hpp:36
constexpr key_status_bits_t MODIFIER_MASK
Shift.
Definition unit_Keyboard.hpp:38
constexpr key_status_bits_t MODIFIER_FUNCTION_BIT
Function.
Definition unit_Keyboard.hpp:34
constexpr key_status_bits_t modifier_bits(const key_status_bits_t kbs)
Gets the modifier bits from key_status_bits_t.
Definition unit_Keyboard.hpp:48
constexpr key_status_bits_t MODIFIER_SHIFT_BIT
Shift.
Definition unit_Keyboard.hpp:32
constexpr key_status_bits_t MODIFIER_OPTION_BIT
Option.
Definition unit_Keyboard.hpp:37