This repository was archived by the owner on Feb 20, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhwKeys.h
111 lines (108 loc) · 2.94 KB
/
hwKeys.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#pragma once
#include "utils.h"
#include <Wire.h>
// appears to work on https://binji.github.io/wasm-clang/
// tested Nov 7 2024
class pinGrid_obj {
private:
bool _isAnalog;
bool _isEnabled;
bool _cycle_mux_pins_first;
uint_vec _colPins;
uint_vec _muxPins;
uint _colSize;
uint _muxSize;
uint _muxMaxValue;
uint _keyCount;
uint_vec _keyState;
uint _colCounter;
uint _muxCounter;
uint _gridCounter;
bool _readComplete;
void init_pin_states() {
for (auto& m : _muxPins) {
pinMode(m, OUTPUT);
}
for (auto& c : _colPins) {
if (_isAnalog) {
pinMode(c, INPUT_PULLUP);
} else {
pinMode(c, INPUT);
}
}
}
bool advanceCol() {
pinMode(_colPins[_colCounter], INPUT);
_colCounter = (++_colCounter) % _colSize;
pinMode(_colPins[_colCounter], INPUT_PULLUP);
return (!(_colCounter));
}
bool advanceMux() {
_muxCounter = (++_muxCounter) % _muxMaxValue;
for (uint b = 0; b < _muxSize; b++) {
digitalWrite(_muxPins[b], (_muxCounter >> b) & 1);
}
return (!(_muxCounter));
}
public:
uint linear_index(uint c, uint m) {
return ((c << _muxSize) | m);
}
void resume_background_process() {
_readComplete = false;
_gridCounter = 0;
}
void setup(uint_vec colPins, bool isAnalog, uint_vec muxPins, bool cycleMuxFirst = true) {
_isAnalog = isAnalog;
_colPins = colPins;
_muxPins = muxPins;
init_pin_states();
_colSize = _colPins.size();
_muxSize = _muxPins.size();
_muxMaxValue = (1u << _muxSize);
_keyCount = (_colSize << _muxSize);
_keyState.resize(_keyCount);
_colCounter = 0;
_muxCounter = 0;
_cycle_mux_pins_first = cycleMuxFirst;
resume_background_process();
}
void poll() {
if (!(_readComplete)) {
if (_isAnalog) {
_keyState[linear_index(_colCounter,_muxCounter)] = analogRead(_colPins[_colCounter]);
} else {
_keyState[linear_index(_colCounter,_muxCounter)] = digitalRead(_colPins[_colCounter]);
}
++_gridCounter;
if (_cycle_mux_pins_first) {
if (advanceMux()) {
_readComplete = advanceCol();
}
} else {
if (advanceCol()) {
_readComplete = advanceMux();
}
}
}
}
bool is_background_process_complete() {
return _readComplete;
}
int read_key_state(uint muxCtr, uint colCtr) {
return _keyState[linear_index(colCtr,muxCtr)];
}
int read_key_state(uint keyIndex) {
return _keyState[keyIndex];
}
uint colPinCount() {
return _colSize;
}
uint muxPinMaxValue() {
return _muxMaxValue;
}
uint buttonCount() {
return _keyCount;
}
};
pinGrid_obj pinGrid;