11

Dependents:   Program_R11

Committer:
gj_schoneveld
Date:
Sun Nov 04 09:49:35 2012 +0000
Revision:
13:fb6929fac0db
Parent:
12:e6623f165199
Child:
14:f6c3647bf421
Added support for polling multiple keys at the same time

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 }
gj_schoneveld 13:fb6929fac0db 89 int Keypad::DebouncedScanMultiple()
gj_schoneveld 13:fb6929fac0db 90 {
gj_schoneveld 13:fb6929fac0db 91 /* debounce */
gj_schoneveld 13:fb6929fac0db 92 int key1 = ScanMultiple();
gj_schoneveld 13:fb6929fac0db 93
gj_schoneveld 13:fb6929fac0db 94 wait_ms(_debounce);
gj_schoneveld 13:fb6929fac0db 95
gj_schoneveld 13:fb6929fac0db 96 int key2 = ScanMultiple();
gj_schoneveld 13:fb6929fac0db 97
gj_schoneveld 13:fb6929fac0db 98 return key1 & key2;
gj_schoneveld 13:fb6929fac0db 99 }
gj_schoneveld 13:fb6929fac0db 100
gj_schoneveld 13:fb6929fac0db 101 int Keypad::ScanMultiple()
gj_schoneveld 13:fb6929fac0db 102 {
gj_schoneveld 13:fb6929fac0db 103 int res = 0;
gj_schoneveld 13:fb6929fac0db 104
gj_schoneveld 13:fb6929fac0db 105 int i = 0;
gj_schoneveld 13:fb6929fac0db 106 for (int c = 0; c < col_count; c++) {
gj_schoneveld 13:fb6929fac0db 107 _cols = ~(1 << c);
gj_schoneveld 13:fb6929fac0db 108 for (int r = 0; r < row_count; r++) {
gj_schoneveld 13:fb6929fac0db 109 if (*_rows[r] == 0) {
gj_schoneveld 13:fb6929fac0db 110 res |= 1 << (r * col_count + c);
gj_schoneveld 13:fb6929fac0db 111 }
gj_schoneveld 13:fb6929fac0db 112 i++;
gj_schoneveld 13:fb6929fac0db 113 }
gj_schoneveld 13:fb6929fac0db 114 }
gj_schoneveld 13:fb6929fac0db 115
gj_schoneveld 13:fb6929fac0db 116 return res;
gj_schoneveld 13:fb6929fac0db 117 }
yoonghm 0:2df66331c109 118
gj_schoneveld 11:a45e64141ce6 119 void Keypad::_callback()
gj_schoneveld 10:9a9ec143840b 120 {
gj_schoneveld 11:a45e64141ce6 121 /* lookup */
gj_schoneveld 11:a45e64141ce6 122 int position = DebouncedScan();
gj_schoneveld 11:a45e64141ce6 123
gj_schoneveld 11:a45e64141ce6 124 /* call back a valid position */
gj_schoneveld 11:a45e64141ce6 125 if (position >= 0)
gj_schoneveld 11:a45e64141ce6 126 _input.call(position);
yoonghm 0:2df66331c109 127 }