summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHombreLaser <buran@silosneeded.com>2024-06-09 17:41:40 -0600
committerHombreLaser <buran@silosneeded.com>2024-06-09 17:41:40 -0600
commit8b3bbfe03429c9dd5277d9dae030210348bda7a2 (patch)
treefd3c5683f890f22ef04b1d81f46c3f1253960ca8
Commit inicial
-rw-r--r--.gitignore3
-rw-r--r--src/keypad.cpp107
-rw-r--r--src/keypad.hpp28
3 files changed, 138 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a71aa19
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+compile_commands.json
+./examples/build/*
+*~
diff --git a/src/keypad.cpp b/src/keypad.cpp
new file mode 100644
index 0000000..2bab18e
--- /dev/null
+++ b/src/keypad.cpp
@@ -0,0 +1,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);
+ }
+}
diff --git a/src/keypad.hpp b/src/keypad.hpp
new file mode 100644
index 0000000..8a99290
--- /dev/null
+++ b/src/keypad.hpp
@@ -0,0 +1,28 @@
+#include "pico/stdlib.h"
+#define OUT true
+#define IN false
+#define KEYPAD_LEN 4
+#pragma once
+
+class Keypad {
+private:
+ // Start private attributes.
+ uint *rows{};
+ uint *cols{};
+ char chars[4][4];
+ // End private attributes.
+
+ // Start private methods.
+ void initCharArray(char chars[4][4]);
+ void init();
+ uint pressedColumn();
+ void pullPinsDown(uint *pins);
+ void restartPins();
+ // End private methods.
+public:
+ // Start public methods.
+ Keypad(uint *rows, uint *cols, char chars[4][4]);
+ bool keyPressed();
+ char getKey();
+ // End public methods.
+};