Fork without short circuits

Dependents:   SaveKeypad

Fork of keypad by HM Yoong

No extra hardware is needed besides the wires and switches. The columns are outputs configured with open drain. The rows are inputs configured with pull up resistors. A key press pulls down its row. With scanning the column is determined thereafter.

See SaveKeypad for an example usage.

Committer:
gj_schoneveld
Date:
Sat Nov 03 23:43:46 2012 +0000
Revision:
12:e6623f165199
Parent:
11:a45e64141ce6
Child:
13:fb6929fac0db
Added polling mode. See SaveKeypad for an example.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
yoonghm 0:2df66331c109 1 #include "keypad.h"
yoonghm 0:2df66331c109 2
yoonghm 0:2df66331c109 3 Keypad::Keypad(PinName row3, PinName row2, PinName row1, PinName row0,
yoonghm 0:2df66331c109 4 PinName col3, PinName col2, PinName col1, PinName col0,
yoonghm 0:2df66331c109 5 int debounce_ms):
gj_schoneveld 10:9a9ec143840b 6 _row0(row0), _row1(row1), _row2(row2), _row3(row3),
gj_schoneveld 10:9a9ec143840b 7 _cols(col0, col1, col2, col3)
gj_schoneveld 10:9a9ec143840b 8 {
gj_schoneveld 12:e6623f165199 9 _debounce = debounce_ms;
gj_schoneveld 11:a45e64141ce6 10 _rows[0] = &_row0;
gj_schoneveld 11:a45e64141ce6 11 _rows[1] = &_row1;
gj_schoneveld 11:a45e64141ce6 12 _rows[2] = &_row2;
gj_schoneveld 11:a45e64141ce6 13 _rows[3] = &_row3;
gj_schoneveld 12:e6623f165199 14 for (int r = 0; r < row_count; r++)
gj_schoneveld 12:e6623f165199 15 _rows[r]->mode(PullUp);
gj_schoneveld 10:9a9ec143840b 16 _cols.mode(OpenDrain);
gj_schoneveld 10:9a9ec143840b 17 _cols.output();
gj_schoneveld 11:a45e64141ce6 18 }
gj_schoneveld 11:a45e64141ce6 19
gj_schoneveld 11:a45e64141ce6 20 void Keypad::_setupFallTrigger(void)
gj_schoneveld 11:a45e64141ce6 21 {
gj_schoneveld 12:e6623f165199 22 for (int r = 0; r < row_count; r++)
gj_schoneveld 12:e6623f165199 23 _rows[r]->fall(this, &Keypad::_callback);
yoonghm 0:2df66331c109 24 }
yoonghm 0:2df66331c109 25
gj_schoneveld 10:9a9ec143840b 26 void Keypad::Start(void)
gj_schoneveld 10:9a9ec143840b 27 {
gj_schoneveld 11:a45e64141ce6 28 /* make the columns zero so they can pull rows down */
yoonghm 0:2df66331c109 29 _cols = 0x00;
yoonghm 0:2df66331c109 30 }
yoonghm 0:2df66331c109 31
gj_schoneveld 10:9a9ec143840b 32 void Keypad::Stop(void)
gj_schoneveld 10:9a9ec143840b 33 {
gj_schoneveld 11:a45e64141ce6 34 /* make the columns one so they cannot pull any rows down anymore */
gj_schoneveld 11:a45e64141ce6 35 _cols = ~0x00;
gj_schoneveld 10:9a9ec143840b 36 }
gj_schoneveld 10:9a9ec143840b 37
gj_schoneveld 10:9a9ec143840b 38 void Keypad::CallAfterInput(uint32_t (*fptr)(uint32_t index))
gj_schoneveld 10:9a9ec143840b 39 {
yoonghm 0:2df66331c109 40 _input.attach(fptr);
gj_schoneveld 11:a45e64141ce6 41 _setupFallTrigger();
gj_schoneveld 11:a45e64141ce6 42 }
gj_schoneveld 11:a45e64141ce6 43
gj_schoneveld 11:a45e64141ce6 44 int Keypad::DebouncedScan()
gj_schoneveld 11:a45e64141ce6 45 {
gj_schoneveld 12:e6623f165199 46 /* debounce */
gj_schoneveld 11:a45e64141ce6 47 int key1 = Scan();
gj_schoneveld 11:a45e64141ce6 48
gj_schoneveld 11:a45e64141ce6 49 wait_ms(_debounce);
gj_schoneveld 11:a45e64141ce6 50
gj_schoneveld 11:a45e64141ce6 51 int key2 = Scan();
gj_schoneveld 11:a45e64141ce6 52
gj_schoneveld 11:a45e64141ce6 53 if (key1 != key2)
gj_schoneveld 11:a45e64141ce6 54 return -1;
gj_schoneveld 11:a45e64141ce6 55 else
gj_schoneveld 11:a45e64141ce6 56 return key1;
yoonghm 0:2df66331c109 57 }
yoonghm 0:2df66331c109 58
gj_schoneveld 11:a45e64141ce6 59 int Keypad::Scan()
gj_schoneveld 10:9a9ec143840b 60 {
gj_schoneveld 11:a45e64141ce6 61 /* lookup row */
gj_schoneveld 11:a45e64141ce6 62 int r = -1;
gj_schoneveld 11:a45e64141ce6 63 for (r = 0; r < row_count; r++) {
gj_schoneveld 11:a45e64141ce6 64 if (*_rows[r] == 0)
gj_schoneveld 11:a45e64141ce6 65 break;
gj_schoneveld 11:a45e64141ce6 66 }
yoonghm 0:2df66331c109 67
gj_schoneveld 11:a45e64141ce6 68 /* if we didn't find a valid row, return */
gj_schoneveld 11:a45e64141ce6 69 if (!(0 <= r && r < row_count))
gj_schoneveld 11:a45e64141ce6 70 return -1;
gj_schoneveld 11:a45e64141ce6 71
gj_schoneveld 11:a45e64141ce6 72 /* scan columns to find out which one pulls down the row */
yoonghm 0:2df66331c109 73 int c = -1;
gj_schoneveld 11:a45e64141ce6 74 for (c = 0; c < col_count; c++) {
gj_schoneveld 11:a45e64141ce6 75 _cols = ~(1 << c);
gj_schoneveld 11:a45e64141ce6 76 if (*_rows[r] == 0)
gj_schoneveld 11:a45e64141ce6 77 break;
yoonghm 0:2df66331c109 78 }
gj_schoneveld 11:a45e64141ce6 79
gj_schoneveld 11:a45e64141ce6 80 /* re-energize all columns */
gj_schoneveld 11:a45e64141ce6 81 Start();
gj_schoneveld 11:a45e64141ce6 82
gj_schoneveld 11:a45e64141ce6 83 /* if we didn't find a valid column, return */
gj_schoneveld 11:a45e64141ce6 84 if (!(0 <= c && c < col_count))
gj_schoneveld 11:a45e64141ce6 85 return -1;
gj_schoneveld 11:a45e64141ce6 86
gj_schoneveld 11:a45e64141ce6 87 return r * col_count + c;
yoonghm 0:2df66331c109 88 }
yoonghm 0:2df66331c109 89
gj_schoneveld 11:a45e64141ce6 90 void Keypad::_callback()
gj_schoneveld 10:9a9ec143840b 91 {
gj_schoneveld 11:a45e64141ce6 92 /* lookup */
gj_schoneveld 11:a45e64141ce6 93 int position = DebouncedScan();
gj_schoneveld 11:a45e64141ce6 94
gj_schoneveld 11:a45e64141ce6 95 /* call back a valid position */
gj_schoneveld 11:a45e64141ce6 96 if (position >= 0)
gj_schoneveld 11:a45e64141ce6 97 _input.call(position);
yoonghm 0:2df66331c109 98 }