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:33:52 2012 +0000
Revision:
11:a45e64141ce6
Parent:
10:9a9ec143840b
Child:
12:e6623f165199
Added support for polling.

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