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
|
#include "hardware/gpio.h"
#include "keypad.hpp"
Keypad::Keypad(uint *rows, uint *cols, char chars[4][4]) :
rows{rows}, cols{cols}
{
initCharArray(chars);
init();
}
/*
* Get pressed key.
*/
char Keypad::getKey() {
int column_index = pressedColumn();
int row_index;
if(column_index < 0)
return '\0';
pullPinsDown(cols);
for(int i = 0; i < KEYPAD_LEN; ++i) {
gpio_put(rows[i], 1);
int row_state = gpio_get(rows[i]);
int column_state = gpio_get(cols[column_index]);
if(row_state & column_state) {
row_index = i;
break;
}
}
restartPins();
return chars[row_index][column_index];
}
/*
* See if a key is pressed.
* All columns are pulled up, so if a key is pressed,
* its corresponding column should be pulled down.
*/
bool Keypad::keyPressed() {
return pressedColumn() < 0;
}
/*
* Copy the char matrix passed to the constructor to
* the object's chars attribute.
*/
void Keypad::initCharArray(char chars[4][4]) {
for(int i = 0; i < KEYPAD_LEN; ++i) {
for(int j = 0; j < KEYPAD_LEN; ++j)
this->chars[i][j] = chars[i][j];
}
}
/*
* Initialize the GPIO pins that will be used by the
* keypad.
* row pins: pulled low and set as outputs.
* column pins: pulled high and set as inputs.
*/
void Keypad::init() {
for (int i = 0; i < KEYPAD_LEN; ++i) {
gpio_init(rows[i]);
gpio_init(cols[i]);
gpio_set_dir(rows[i], OUT);
gpio_set_dir(cols[i], IN);
gpio_pull_down(rows[i]);
gpio_pull_up(cols[i]);
}
}
/*
* Get the column that's being pressed.
* If no column is getting pressed (i.e, no button
* is getting pressed) return -1, otherwise return
* the index of the column being pressed.
*/
uint Keypad::pressedColumn() {
for (int i = 0; i < KEYPAD_LEN; ++i) {
if(!gpio_get(cols[i]))
return i;
}
return -1;
}
/*
* Pull every GPIO pin in pins down.
*/
void Keypad::pullPinsDown(uint *pins) {
for(int i = 0; i < KEYPAD_LEN; ++i)
gpio_pull_down(pins[i]);
}
/*
* Leave the state of pins as it was before reading.
* (Columns pulled up, rows pulled down);
*/
void Keypad::restartPins() {
for(int i = 0; i < KEYPAD_LEN; ++i) {
gpio_pull_up(cols[i]);
gpio_put(rows[i], 0);
}
}
|