M5Unit-GESTURE 0.3.0 git rev:73e6de5
Loading...
Searching...
No Matches
unit_PAJ7620U2.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2024 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_GESTURE_UNIT_PAJ7620U2_HPP
11#define M5_UNIT_GESTURE_UNIT_PAJ7620U2_HPP
12
13#include <M5UnitComponent.hpp>
14#include <m5_utility/container/circular_buffer.hpp>
15#include <array>
16#include <memory>
17
18namespace m5 {
19namespace unit {
20
25namespace paj7620u2 {
32enum class Gesture : uint16_t {
33 None,
34 Up = 1U << 0,
35 Down = 1U << 1,
36 Left = 1U << 2,
37 Right = 1U << 3,
38 Forward = 1U << 4,
39 Backward = 1U << 5,
40 Clockwise = 1U << 6,
41 CounterClockwise = 1U << 7,
42 Wave = 1U << 8,
43 Approach = 1U << 9,
44 HasObject = 1U << 10,
45 WakeupTrigger = 1U << 11,
46 Confirm = 1U << 12,
47 Abort = 1U << 13,
48 Reserve = 1U << 14,
49 NoObject = 1U << 15,
50};
51
56enum class Mode : uint8_t {
57 Gesture,
58 Proximity,
59 Cursor,
60};
61
67enum class Frequency : int8_t {
68 Unknown = -1,
69 Normal,
70 Gaming,
71};
72
79inline float idle_time_to_hz(const uint16_t idle_time)
80{
81 return 31250.0f / (77 + idle_time);
82}
83
90inline uint16_t hz_to_idle_time(const float hz)
91{
92 if (hz <= 0.0f) {
93 return 0;
94 }
95 float v = 31250.0f / hz - 77.0f;
96 if (v < 0.0f) {
97 return 0;
98 }
99 if (v > 65535.0f) {
100 return 65535;
101 }
102 return static_cast<uint16_t>(v + 0.5f);
103}
104
109struct Data {
110 Data()
111 {
112 }
113 // Common
114 // [0,1]:gesture
115 // Proximity
116 // [2]:proximity [3]:approach
117 // Cursor
118 // [2,3]:X [4,5]:Y
119 std::array<uint8_t, 2 + 4> raw{};
122 union {
123 struct {
126 };
127 struct {
128 uint16_t cursor_x{}, cursor_y{};
129 };
130 };
131
133 inline Mode mode() const
134 {
135 return data_mode;
136 }
139 {
140 return data_gesture;
141 }
144
145 inline uint8_t brightness() const
146 {
147 return (data_mode == Mode::Proximity) ? proximity_brightness : 0;
148 }
150 inline bool approach() const
151 {
152 return (data_mode == Mode::Proximity) ? proximity_approach : false;
153 }
157
161 inline uint16_t cursorX() const
162 {
163 return (data_mode == Mode::Cursor) ? cursor_x : 0xFFFF;
164 }
169 inline uint16_t cursorY() const
170 {
171 return (data_mode == Mode::Cursor) ? cursor_y : 0xFFFF;
172 }
174};
175
176} // namespace paj7620u2
177
182class UnitPAJ7620U2 : public Component, public PeriodicMeasurementAdapter<UnitPAJ7620U2, paj7620u2::Data> {
183 M5_UNIT_COMPONENT_HPP_BUILDER(UnitPAJ7620U2, 0x73);
184
185public:
190 struct config_t {
192 bool start_periodic{true};
194 paj7620u2::Mode mode{paj7620u2::Mode::Gesture};
196 paj7620u2::Frequency frequency{paj7620u2::Frequency::Normal};
198 bool hflip{false};
200 bool vflip{true};
202 uint8_t rotation{0};
204 bool store_on_change{true};
205 };
206
211 explicit UnitPAJ7620U2(const uint8_t addr = DEFAULT_ADDRESS)
212 : Component(addr), _data{new m5::container::CircularBuffer<paj7620u2::Data>(1)}
213 {
214 auto ccfg = component_config();
215 ccfg.clock = 400 * 1000U;
216 component_config(ccfg);
217 }
220 {
221 }
222
227 virtual bool begin() override;
232 virtual void update(const bool force = false) override;
233
236
237 inline config_t config() const
238 {
239 return _cfg;
240 }
245 inline void config(const config_t& cfg)
246 {
247 _cfg = cfg;
248 }
250
253
255 {
256 return !empty() ? oldest().gesture() : paj7620u2::Gesture::None;
257 }
259 inline uint8_t brightness() const
260 {
261 return !empty() ? oldest().brightness() : 0;
262 }
264 inline bool approach() const
265 {
266 return !empty() ? oldest().approach() : false;
267 }
273 uint16_t cursorX() const
274 {
275 return !empty() ? oldest().cursorX() : 0xFFFF;
276 }
282 uint16_t cursorY() const
283 {
284 return !empty() ? oldest().cursorY() : 0xFFFF;
285 }
287
290
295 bool startPeriodicMeasurement(const uint32_t intervalMs = 0)
296 {
297 return PeriodicMeasurementAdapter<UnitPAJ7620U2, paj7620u2::Data>::startPeriodicMeasurement(intervalMs);
298 }
307 const uint32_t intervalMs)
308 {
309 return PeriodicMeasurementAdapter<UnitPAJ7620U2, paj7620u2::Data>::startPeriodicMeasurement(mode, freq,
310 intervalMs);
311 }
317 {
318 return PeriodicMeasurementAdapter<UnitPAJ7620U2, paj7620u2::Data>::stopPeriodicMeasurement();
319 }
321
327 inline uint8_t rotation() const
328 {
329 return _rotation;
330 }
343 void setRotate(const uint8_t rot)
344 {
345 _rotation = rot & 0x03;
346 }
347
350 {
351 return _frequency;
352 }
358 bool readFrequency(uint16_t& raw);
365 [[deprecated("Use readFrequency(uint16_t&) instead")]] bool readFrequency(uint8_t& raw)
366 {
367 uint16_t v{};
368 raw = 0;
369 if (readFrequency(v)) {
370 raw = static_cast<uint8_t>(v & 0xFF);
371 return true;
372 }
373 return false;
374 }
391 float readFrequencyHz();
397 bool writeFrequencyHz(const float hz);
398
401
413 bool readObjectCenter(uint16_t& x, uint16_t& y);
419 bool readObjectSize(uint16_t& sz);
425 bool existsObject(bool& exists)
426 {
427 uint8_t e{};
428 if (readNoObjectCount(e)) {
429 exists = (e == 0);
430 return true;
431 }
432 return false;
433 }
439 bool readNoObjectCount(uint8_t& cnt);
445 bool readNoMotionCount(uint8_t& cnt);
447
450
456 bool readProximity(uint8_t& brightness, uint8_t& approach);
457
467 bool readApproachThreshold(uint8_t& high, uint8_t& low);
477 bool writeApproachThreshold(const uint8_t high, const uint8_t low);
479
482
489 bool readCursor(uint16_t& x, uint16_t& y);
491
494
495 inline paj7620u2::Mode mode() const
496 {
497 return _mode;
498 }
505 bool writeMode(const paj7620u2::Mode mode);
507
513 bool readHorizontalFlip(bool& flip);
519 bool readVerticalFlip(bool& flip);
525 bool writeHorizontalFlip(const bool flip);
531 bool writeVerticalFlip(const bool flip);
532
535
540 bool enable(const bool flag);
542 inline bool enable()
543 {
544 return enable(true);
545 }
547 inline bool disable()
548 {
549 return enable(false);
550 }
552 bool suspend();
554 bool resume();
556
557protected:
558 bool start_periodic_measurement(const uint32_t intervalMs = 0);
559 bool start_periodic_measurement(const paj7620u2::Mode mode, const paj7620u2::Frequency freq,
560 const uint32_t intervalMs);
561 bool stop_periodic_measurement();
562
563 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitPAJ7620U2, paj7620u2::Data);
564
565 bool select_bank(const uint8_t bank, const bool force = false);
566
567 bool read_banked_register(const uint16_t reg, uint8_t* buf, const size_t len);
568 bool read_banked_register8(const uint16_t reg, uint8_t& value);
569 bool write_banked_register(const uint16_t reg, const uint8_t* buf, const size_t len);
570 bool write_banked_register8(const uint16_t reg, const uint8_t value);
571
572 bool update_gesture(paj7620u2::Data& d);
573 bool update_proximity(paj7620u2::Data& d);
574 bool update_cursor(paj7620u2::Data& d);
575
576 bool read_gesture(paj7620u2::Data& d);
577 bool read_proximity(paj7620u2::Data& d);
578 bool read_cursor(paj7620u2::Data& d);
579
580 bool apply_flip();
581
582 bool wakeup();
583 bool was_wakeup();
584 bool read_chip_id(uint16_t& id);
585 bool read_version(uint8_t& version);
586
587protected:
588 uint8_t _current_bank{0xFF};
589 paj7620u2::Mode _mode{};
590 paj7620u2::Frequency _frequency{};
591 uint8_t _rotation{};
592 bool _hflip{}, _vflip{true};
593
594 std::unique_ptr<m5::container::CircularBuffer<paj7620u2::Data>> _data{};
595 config_t _cfg{};
596};
597
599namespace paj7620u2 {
600namespace command {
601
602// Bank 0/1
603constexpr uint8_t BANK_SEL{0xEF};
604// high byte:bank low byte: register
605// Bank 0
606constexpr uint16_t PART_ID_LOW{0x0000};
607constexpr uint16_t PART_ID_HIGH{0x0001};
608constexpr uint16_t VERSION_ID{0x0002};
609constexpr uint16_t SW_SUSPEND_ENL{0x0003};
610
611constexpr uint16_t CURSOR_CLAMP_CENTER_X_LOW{0x003B};
612constexpr uint16_t CURSOR_CLAMP_CENTER_X_HIGH{0x003C};
613constexpr uint16_t CURSOR_CLAMP_CENTER_Y_LOW{0x003D};
614constexpr uint16_t CURSOR_CLAMP_CENTER_Y_HIGH{0x003E};
615
616constexpr uint16_t INT_FLAG_1{0x0043};
617constexpr uint16_t INT_FLAG_2{0x0044};
618
619constexpr uint16_t R_POX_UB{0x0069};
620constexpr uint16_t R_POX_LB{0x006A};
621constexpr uint16_t S_STATE{0x006B};
622constexpr uint16_t S_AVGY{0x006C};
623
624constexpr uint16_t OBJECT_CENTER_X_LOW{0x00AC};
625constexpr uint16_t OBJECT_CENTER_X_HIGH{0x00AD};
626constexpr uint16_t OBJECT_CENTER_Y_LOW{0x00AE};
627constexpr uint16_t OBJECT_CENTER_Y_HIGH{0x00AF};
628
629constexpr uint16_t OBJECT_AVG_Y{0x00B0};
630constexpr uint16_t OBJECT_SIZE_LOW{0x00B1};
631constexpr uint16_t OBJECT_SIZE_HIGH{0x00B2};
632constexpr uint16_t WAVE_ABORT_COUNT{0x00B7};
633constexpr uint16_t NO_OBJECT_COUNT{0x00B8};
634constexpr uint16_t NO_MOTION_COUNT{0x00B9};
635
636constexpr uint16_t VEL_X_LOW{0x00C3};
637constexpr uint16_t VEL_X_HIGH{0x00C4};
638constexpr uint16_t VEL_Y_LOW{0x00C5};
639constexpr uint16_t VEL_Y_HIGH{0x00C6};
640
641// Bank1
642constexpr uint16_t LS_COMP_DAVG_V{0x0104};
643constexpr uint16_t R_IDLE_TIME_LOW{0x0165};
644constexpr uint16_t R_IDLE_TIME_HIGH{0x0166};
645constexpr uint16_t R_TG_ENH{0x0172};
646} // namespace command
647} // namespace paj7620u2
649
650} // namespace unit
651} // namespace m5
652
653#endif
PAJ7620U2 unit.
Definition unit_PAJ7620U2.hpp:182
bool readProximity(uint8_t &brightness, uint8_t &approach)
Read proximity.
Definition unit_PAJ7620U2.cpp:547
bool readNoObjectCount(uint8_t &cnt)
State counter with no objects detected.
Definition unit_PAJ7620U2.cpp:524
virtual bool begin() override
Begin communication with the sensor.
Definition unit_PAJ7620U2.cpp:370
paj7620u2::Frequency frequency() const
Gets the inner frequency.
Definition unit_PAJ7620U2.hpp:349
bool startPeriodicMeasurement(const paj7620u2::Mode mode, const paj7620u2::Frequency freq, const uint32_t intervalMs)
Start periodic measurement.
Definition unit_PAJ7620U2.hpp:306
uint8_t brightness() const
Oldest brightness if Proximity mode.
Definition unit_PAJ7620U2.hpp:259
bool stopPeriodicMeasurement()
Stop periodic measurement.
Definition unit_PAJ7620U2.hpp:316
bool writeApproachThreshold(const uint8_t high, const uint8_t low)
Write the threshold for detect approach.
Definition unit_PAJ7620U2.cpp:711
void setRotate(const uint8_t rot)
Set the rotation.
Definition unit_PAJ7620U2.hpp:343
bool resume()
resume from suspended
Definition unit_PAJ7620U2.cpp:594
bool readGesture(paj7620u2::Gesture &gesture)
Read gesture.
Definition unit_PAJ7620U2.cpp:513
void config(const config_t &cfg)
Set the configuration.
Definition unit_PAJ7620U2.hpp:245
bool enable()
enable sensor
Definition unit_PAJ7620U2.hpp:542
bool writeVerticalFlip(const bool flip)
Write the vertical flipping.
Definition unit_PAJ7620U2.cpp:749
bool disable()
disable sensor
Definition unit_PAJ7620U2.hpp:547
bool readApproachThreshold(uint8_t &high, uint8_t &low)
Read the threshold for detect approach.
Definition unit_PAJ7620U2.cpp:706
bool readCursor(uint16_t &x, uint16_t &y)
Cursor position.
Definition unit_PAJ7620U2.cpp:572
bool readNoMotionCount(uint8_t &cnt)
State counter which a non-moving object is detected.
Definition unit_PAJ7620U2.cpp:530
bool readVerticalFlip(bool &flip)
Read the vertical flipping.
Definition unit_PAJ7620U2.cpp:727
bool suspend()
suspend
Definition unit_PAJ7620U2.cpp:589
bool writeHorizontalFlip(const bool flip)
Write the horizontal flipping.
Definition unit_PAJ7620U2.cpp:738
paj7620u2::Mode mode() const
Gets the detection mode.
Definition unit_PAJ7620U2.hpp:495
bool startPeriodicMeasurement(const uint32_t intervalMs=0)
Start periodic measurement in the current settings.
Definition unit_PAJ7620U2.hpp:295
bool writeFrequency(const paj7620u2::Frequency f)
Write the frequency.
Definition unit_PAJ7620U2.cpp:628
bool approach() const
Oldest approach status if Proximity mode.
Definition unit_PAJ7620U2.hpp:264
bool writeMode(const paj7620u2::Mode mode)
Write the detection mode.
Definition unit_PAJ7620U2.cpp:677
bool existsObject(bool &exists)
Is the object present within the detection range?
Definition unit_PAJ7620U2.hpp:425
bool readObjectCenter(uint16_t &x, uint16_t &y)
Object center position.
Definition unit_PAJ7620U2.cpp:559
bool readFrequency(uint8_t &raw)
Read the lower byte of R_IDLE_TIME.
Definition unit_PAJ7620U2.hpp:365
virtual void update(const bool force=false) override
Update periodic measurement data.
Definition unit_PAJ7620U2.cpp:420
virtual ~UnitPAJ7620U2()
Destructor.
Definition unit_PAJ7620U2.hpp:219
uint8_t rotation() const
Get the rotation.
Definition unit_PAJ7620U2.hpp:327
config_t config() const
Gets the configuration.
Definition unit_PAJ7620U2.hpp:237
bool readHorizontalFlip(bool &flip)
Read the horizontal flipping.
Definition unit_PAJ7620U2.cpp:716
bool readFrequency(uint16_t &raw)
Read the raw R_IDLE_TIME register value.
Definition unit_PAJ7620U2.cpp:599
uint16_t cursorY() const
Oldest cursor Y if Cursor mode.
Definition unit_PAJ7620U2.hpp:282
float readFrequencyHz()
Read the current frequency in Hz from hardware.
Definition unit_PAJ7620U2.cpp:642
bool readObjectSize(uint16_t &sz)
Read gesture object size.
Definition unit_PAJ7620U2.cpp:536
uint16_t cursorX() const
Oldest cursor X if Cursor mode.
Definition unit_PAJ7620U2.hpp:273
UnitPAJ7620U2(const uint8_t addr=DEFAULT_ADDRESS)
Constructor.
Definition unit_PAJ7620U2.hpp:211
bool writeFrequencyHz(const float hz)
Write the frequency in Hz.
Definition unit_PAJ7620U2.cpp:651
paj7620u2::Gesture gesture() const
Oldest gesture.
Definition unit_PAJ7620U2.hpp:254
Top level namespace of M5Stack.
For PAJ7620U2.
Unit-related namespace.
Settings for begin.
Definition unit_PAJ7620U2.hpp:190
bool vflip
Flip vertical if start on begin.
Definition unit_PAJ7620U2.hpp:200
paj7620u2::Mode mode
Mode if start on begin.
Definition unit_PAJ7620U2.hpp:194
bool hflip
Flip horizontal if start on begin.
Definition unit_PAJ7620U2.hpp:198
bool start_periodic
Start periodic measurement on begin?
Definition unit_PAJ7620U2.hpp:192
uint8_t rotation
Rotation if start on begin.
Definition unit_PAJ7620U2.hpp:202
paj7620u2::Frequency frequency
Frequency if start on begin.
Definition unit_PAJ7620U2.hpp:196
bool store_on_change
Store only when the value changes.
Definition unit_PAJ7620U2.hpp:204
Measurement data group.
Definition unit_PAJ7620U2.hpp:109
std::array< uint8_t, 2+4 > raw
Raw register data.
Definition unit_PAJ7620U2.hpp:119
uint8_t proximity_brightness
Proximity brightness (PS data)
Definition unit_PAJ7620U2.hpp:124
Mode mode() const
Gets the operation mode.
Definition unit_PAJ7620U2.hpp:133
Gesture data_gesture
Detected gesture.
Definition unit_PAJ7620U2.hpp:120
bool proximity_approach
Proximity approach state.
Definition unit_PAJ7620U2.hpp:125
bool approach() const
Gets the approach state (true: approach)
Definition unit_PAJ7620U2.hpp:150
uint16_t cursorX() const
Gets the cursor X of any object.
Definition unit_PAJ7620U2.hpp:161
Mode data_mode
Current operating mode.
Definition unit_PAJ7620U2.hpp:121
uint8_t brightness() const
Gets the brightness.
Definition unit_PAJ7620U2.hpp:145
Gesture gesture() const
Gets the gesture (Common)
Definition unit_PAJ7620U2.hpp:138
uint16_t cursorY() const
Gets the cursor Y of any object.
Definition unit_PAJ7620U2.hpp:169
uint16_t cursor_y
Cursor XY coordinates.
Definition unit_PAJ7620U2.hpp:128
uint16_t hz_to_idle_time(const float hz)
Convert frequency in Hz to R_IDLE_TIME register value.
Definition unit_PAJ7620U2.hpp:90
Frequency
Frequency Operating frequency.
Definition unit_PAJ7620U2.hpp:67
Gesture
Gesture type.
Definition unit_PAJ7620U2.hpp:32
@ NoObject
No object (cursor mode)
@ Approach
Approach (proximity mode)
@ HasObject
Has object (cursor mode)
@ Forward
Closer to the sensor.
@ Confirm
Confirm (confirm mode)
@ Abort
Abort (confirm mode)
@ CounterClockwise
Counterclockwise.
@ WakeupTrigger
Wakeup (trigger mode)
@ Backward
Away from the sensor.
Mode
Operation Mode.
Definition unit_PAJ7620U2.hpp:56
@ Cursor
Detect XY coordinate.
@ Proximity
Detect proximity.
float idle_time_to_hz(const uint16_t idle_time)
Convert R_IDLE_TIME register value to frequency in Hz.
Definition unit_PAJ7620U2.hpp:79