M5Unit-GESTURE 0.2.0 git rev:70c2663
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
158 inline uint16_t cursorX() const
159 {
160 return (data_mode == Mode::Cursor) ? cursor_x : 0xFFFF;
161 }
163 inline uint16_t cursorY() const
164 {
165 return (data_mode == Mode::Cursor) ? cursor_y : 0xFFFF;
166 }
168};
169
170} // namespace paj7620u2
171
176class UnitPAJ7620U2 : public Component, public PeriodicMeasurementAdapter<UnitPAJ7620U2, paj7620u2::Data> {
177 M5_UNIT_COMPONENT_HPP_BUILDER(UnitPAJ7620U2, 0x73);
178
179public:
184 struct config_t {
186 bool start_periodic{true};
188 paj7620u2::Mode mode{paj7620u2::Mode::Gesture};
190 paj7620u2::Frequency frequency{paj7620u2::Frequency::Normal};
192 bool hflip{false};
194 bool vflip{true};
196 uint8_t rotation{0};
198 bool store_on_change{true};
199 };
200
205 explicit UnitPAJ7620U2(const uint8_t addr = DEFAULT_ADDRESS)
206 : Component(addr), _data{new m5::container::CircularBuffer<paj7620u2::Data>(1)}
207 {
208 auto ccfg = component_config();
209 ccfg.clock = 400 * 1000U;
210 component_config(ccfg);
211 }
214 {
215 }
216
221 virtual bool begin() override;
226 virtual void update(const bool force = false) override;
227
230
232 {
233 return _cfg;
234 }
236 inline void config(const config_t& cfg)
237 {
238 _cfg = cfg;
239 }
241
244
246 {
247 return !empty() ? oldest().gesture() : paj7620u2::Gesture::None;
248 }
250 inline uint8_t brightness() const
251 {
252 return !empty() ? oldest().brightness() : 0;
253 }
255 inline bool approach() const
256 {
257 return !empty() ? oldest().approach() : false;
258 }
260 uint16_t cursorX() const
261 {
262 return !empty() ? oldest().cursorX() : 0xFFFF;
263 }
265 uint16_t cursorY() const
266 {
267 return !empty() ? oldest().cursorY() : 0xFFFF;
268 }
270
273
278 bool startPeriodicMeasurement(const uint32_t intervalMs = 0)
279 {
280 return PeriodicMeasurementAdapter<UnitPAJ7620U2, paj7620u2::Data>::startPeriodicMeasurement(intervalMs);
281 }
290 const uint32_t intervalMs)
291 {
292 return PeriodicMeasurementAdapter<UnitPAJ7620U2, paj7620u2::Data>::startPeriodicMeasurement(mode, freq,
293 intervalMs);
294 }
300 {
301 return PeriodicMeasurementAdapter<UnitPAJ7620U2, paj7620u2::Data>::stopPeriodicMeasurement();
302 }
304
310 inline uint8_t rotation() const
311 {
312 return _rotation;
313 }
326 void setRotate(const uint8_t rot)
327 {
328 _rotation = rot & 0x03;
329 }
330
333 {
334 return _frequency;
335 }
341 bool readFrequency(uint16_t& raw);
358 float readFrequencyHz();
364 bool writeFrequencyHz(const float hz);
365
368
380 bool readObjectCenter(uint16_t& x, uint16_t& y);
386 bool readObjectSize(uint16_t& sz);
392 bool existsObject(bool& exists)
393 {
394 uint8_t e{};
395 if (readNoObjectCount(e)) {
396 exists = (e == 0);
397 return true;
398 }
399 return false;
400 }
406 bool readNoObjectCount(uint8_t& cnt);
412 bool readNoMotionCount(uint8_t& cnt);
414
417
423 bool readProximity(uint8_t& brightness, uint8_t& approach);
424
434 bool readApproachThreshold(uint8_t& high, uint8_t& low);
444 bool writeApproachThreshold(const uint8_t high, const uint8_t low);
446
449
456 bool readCursor(uint16_t& x, uint16_t& y);
458
461
462 inline paj7620u2::Mode mode() const
463 {
464 return _mode;
465 }
471 bool writeMode(const paj7620u2::Mode mode);
473
479 bool readHorizontalFlip(bool& flip);
485 bool readVerticalFlip(bool& flip);
491 bool writeHorizontalFlip(const bool flip);
497 bool writeVerticalFlip(const bool flip);
498
501
506 bool enable(const bool flag);
508 inline bool enable()
509 {
510 return enable(true);
511 }
513 inline bool disable()
514 {
515 return enable(false);
516 }
518 bool suspend();
520 bool resume();
522
523protected:
524 bool start_periodic_measurement(const uint32_t intervalMs = 0);
525 bool start_periodic_measurement(const paj7620u2::Mode mode, const paj7620u2::Frequency freq,
526 const uint32_t intervalMs);
527 bool stop_periodic_measurement();
528
529 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitPAJ7620U2, paj7620u2::Data);
530
531 bool select_bank(const uint8_t bank, const bool force = false);
532
533 bool read_banked_register(const uint16_t reg, uint8_t* buf, const size_t len);
534 bool read_banked_register8(const uint16_t reg, uint8_t& value);
535 bool write_banked_register(const uint16_t reg, const uint8_t* buf, const size_t len);
536 bool write_banked_register8(const uint16_t reg, const uint8_t value);
537
538 bool update_gesture(paj7620u2::Data& d);
539 bool update_proximity(paj7620u2::Data& d);
540 bool update_cursor(paj7620u2::Data& d);
541
542 bool read_gesture(paj7620u2::Data& d);
543 bool read_proximity(paj7620u2::Data& d);
544 bool read_cursor(paj7620u2::Data& d);
545
546 bool wakeup();
547 bool was_wakeup();
548 bool read_chip_id(uint16_t& id);
549 bool read_version(uint8_t& version);
550
551protected:
552 uint8_t _current_bank{0xFF};
553 paj7620u2::Mode _mode{};
554 paj7620u2::Frequency _frequency{};
555 uint8_t _rotation{};
556
557 std::unique_ptr<m5::container::CircularBuffer<paj7620u2::Data>> _data{};
558 config_t _cfg{};
559};
560
562namespace paj7620u2 {
563namespace command {
564
565// Bank 0/1
566constexpr uint8_t BANK_SEL{0xEF};
567// high byte:bank low byte: register
568// Bank 0
569constexpr uint16_t PART_ID_LOW{0x0000};
570constexpr uint16_t PART_ID_HIGH{0x0001};
571constexpr uint16_t VERSION_ID{0x0002};
572constexpr uint16_t SW_SUSPEND_ENL{0x0003};
573
574constexpr uint16_t CURSOR_CLAMP_CENTER_X_LOW{0x003B};
575constexpr uint16_t CURSOR_CLAMP_CENTER_X_HIGH{0x003C};
576constexpr uint16_t CURSOR_CLAMP_CENTER_Y_LOW{0x003D};
577constexpr uint16_t CURSOR_CLAMP_CENTER_Y_HIGH{0x003E};
578
579constexpr uint16_t INT_FLAG_1{0x0043};
580constexpr uint16_t INT_FLAG_2{0x0044};
581
582constexpr uint16_t R_POX_UB{0x0069};
583constexpr uint16_t R_POX_LB{0x006A};
584constexpr uint16_t S_STATE{0x006B};
585constexpr uint16_t S_AVGY{0x006C};
586
587constexpr uint16_t OBJECT_CENTER_X_LOW{0x00AC};
588constexpr uint16_t OBJECT_CENTER_X_HIGH{0x00AD};
589constexpr uint16_t OBJECT_CENTER_Y_LOW{0x00AE};
590constexpr uint16_t OBJECT_CENTER_Y_HIGH{0x00AF};
591
592constexpr uint16_t OBJECT_AVG_Y{0x00B0};
593constexpr uint16_t OBJECT_SIZE_LOW{0x00B1};
594constexpr uint16_t OBJECT_SIZE_HIGH{0x00B2};
595constexpr uint16_t WAVE_ABORT_COUNT{0x00B7};
596constexpr uint16_t NO_OBJECT_COUNT{0x00B8};
597constexpr uint16_t NO_MOTION_COUNT{0x00B9};
598
599constexpr uint16_t VEL_X_LOW{0x00C3};
600constexpr uint16_t VEL_X_HIGH{0x00C4};
601constexpr uint16_t VEL_Y_LOW{0x00C5};
602constexpr uint16_t VEL_Y_HIGH{0x00C6};
603
604// Bank1
605constexpr uint16_t LS_COMP_DAVG_V{0x0104};
606constexpr uint16_t R_IDLE_TIME_LOW{0x0165};
607constexpr uint16_t R_IDLE_TIME_HIGH{0x0166};
608constexpr uint16_t R_TG_ENH{0x0172};
609} // namespace command
610} // namespace paj7620u2
612
613} // namespace unit
614} // namespace m5
615
616#endif
PAJ7620U2 unit.
Definition unit_PAJ7620U2.hpp:176
bool readProximity(uint8_t &brightness, uint8_t &approach)
Read proximity.
Definition unit_PAJ7620U2.cpp:558
bool readNoObjectCount(uint8_t &cnt)
State counter with no objects detected.
Definition unit_PAJ7620U2.cpp:535
virtual bool begin() override
Begin communication with the sensor.
Definition unit_PAJ7620U2.cpp:381
paj7620u2::Frequency frequency() const
Gets the inner frequency.
Definition unit_PAJ7620U2.hpp:332
bool startPeriodicMeasurement(const paj7620u2::Mode mode, const paj7620u2::Frequency freq, const uint32_t intervalMs)
Start periodic measurement.
Definition unit_PAJ7620U2.hpp:289
uint8_t brightness() const
Oldest brightness if Proximity mode.
Definition unit_PAJ7620U2.hpp:250
bool stopPeriodicMeasurement()
Stop periodic measurement.
Definition unit_PAJ7620U2.hpp:299
bool writeApproachThreshold(const uint8_t high, const uint8_t low)
Write the threshold for detect approach.
Definition unit_PAJ7620U2.cpp:720
void setRotate(const uint8_t rot)
Set the rotation.
Definition unit_PAJ7620U2.hpp:326
bool resume()
resume from suspended
Definition unit_PAJ7620U2.cpp:605
bool readGesture(paj7620u2::Gesture &gesture)
Read gesture.
Definition unit_PAJ7620U2.cpp:524
config_t config()
Gets the configuration.
Definition unit_PAJ7620U2.hpp:231
void config(const config_t &cfg)
Set the configuration.
Definition unit_PAJ7620U2.hpp:236
bool enable()
enable sensor
Definition unit_PAJ7620U2.hpp:508
bool writeVerticalFlip(const bool flip)
Write the vertical flipping.
Definition unit_PAJ7620U2.cpp:757
bool disable()
disable sensor
Definition unit_PAJ7620U2.hpp:513
bool readApproachThreshold(uint8_t &high, uint8_t &low)
Read the threshold for detect approach.
Definition unit_PAJ7620U2.cpp:715
bool readCursor(uint16_t &x, uint16_t &y)
Cursor position.
Definition unit_PAJ7620U2.cpp:583
bool readNoMotionCount(uint8_t &cnt)
State counter which a non-moving object is detected.
Definition unit_PAJ7620U2.cpp:541
bool readVerticalFlip(bool &flip)
Read the vertical flipping.
Definition unit_PAJ7620U2.cpp:736
bool suspend()
suspend
Definition unit_PAJ7620U2.cpp:600
bool writeHorizontalFlip(const bool flip)
Write the horizontal flipping.
Definition unit_PAJ7620U2.cpp:747
paj7620u2::Mode mode() const
Gets the detection mode.
Definition unit_PAJ7620U2.hpp:462
bool startPeriodicMeasurement(const uint32_t intervalMs=0)
Start periodic measurement in the current settings.
Definition unit_PAJ7620U2.hpp:278
bool writeFrequency(const paj7620u2::Frequency f)
Write the frequency.
Definition unit_PAJ7620U2.cpp:639
bool approach() const
Oldest approach status if Proximity mode.
Definition unit_PAJ7620U2.hpp:255
bool writeMode(const paj7620u2::Mode mode)
Write the detection mode.
Definition unit_PAJ7620U2.cpp:685
bool existsObject(bool &exists)
Is the object present within the detection range?
Definition unit_PAJ7620U2.hpp:392
bool readObjectCenter(uint16_t &x, uint16_t &y)
Object center position.
Definition unit_PAJ7620U2.cpp:570
virtual void update(const bool force=false) override
Update periodic measurement data.
Definition unit_PAJ7620U2.cpp:429
virtual ~UnitPAJ7620U2()
Destructor.
Definition unit_PAJ7620U2.hpp:213
uint8_t rotation() const
Get the rotation.
Definition unit_PAJ7620U2.hpp:310
bool readHorizontalFlip(bool &flip)
Read the horizontal flipping.
Definition unit_PAJ7620U2.cpp:725
bool readFrequency(uint16_t &raw)
Read the raw R_IDLE_TIME register value.
Definition unit_PAJ7620U2.cpp:610
uint16_t cursorY() const
Oldest cursor Y if Cursor mode.
Definition unit_PAJ7620U2.hpp:265
float readFrequencyHz()
Read the current frequency in Hz from hardware.
Definition unit_PAJ7620U2.cpp:653
bool readObjectSize(uint16_t &sz)
Read gesture object size.
Definition unit_PAJ7620U2.cpp:547
uint16_t cursorX() const
Oldest cursor X if Cursor mode.
Definition unit_PAJ7620U2.hpp:260
UnitPAJ7620U2(const uint8_t addr=DEFAULT_ADDRESS)
Constructor.
Definition unit_PAJ7620U2.hpp:205
bool writeFrequencyHz(const float hz)
Write the frequency in Hz.
Definition unit_PAJ7620U2.cpp:662
paj7620u2::Gesture gesture() const
Oldest gesture.
Definition unit_PAJ7620U2.hpp:245
Top level namespace of M5stack.
For PAJ7620U2.
Unit-related namespace.
Settings for begin.
Definition unit_PAJ7620U2.hpp:184
bool vflip
Flip vertical if start on begin.
Definition unit_PAJ7620U2.hpp:194
paj7620u2::Mode mode
Mode if start on begin.
Definition unit_PAJ7620U2.hpp:188
bool hflip
Flip horizontal if start on begin.
Definition unit_PAJ7620U2.hpp:192
bool start_periodic
Start periodic measurement on begin?
Definition unit_PAJ7620U2.hpp:186
uint8_t rotation
Rotation if start on begin.
Definition unit_PAJ7620U2.hpp:196
paj7620u2::Frequency frequency
Frequency if start on begin.
Definition unit_PAJ7620U2.hpp:190
bool store_on_change
Store only when value is a change.
Definition unit_PAJ7620U2.hpp:198
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
Detect the approach?
Definition unit_PAJ7620U2.hpp:150
uint16_t cursorX() const
Gets the cursor X of any object.
Definition unit_PAJ7620U2.hpp:158
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:163
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
Counter clock wise.
@ 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