11
Diff: keypad.cpp
- Revision:
- 11:a45e64141ce6
- Parent:
- 10:9a9ec143840b
- Child:
- 12:e6623f165199
--- a/keypad.cpp Fri Nov 02 22:42:28 2012 +0000 +++ b/keypad.cpp Sat Nov 03 23:33:52 2012 +0000 @@ -6,6 +6,10 @@ _row0(row0), _row1(row1), _row2(row2), _row3(row3), _cols(col0, col1, col2, col3) { + _rows[0] = &_row0; + _rows[1] = &_row1; + _rows[2] = &_row2; + _rows[3] = &_row3; _debounce = debounce_ms; _row0.mode(PullUp); _row1.mode(PullUp); @@ -13,71 +17,87 @@ _row3.mode(PullUp); _cols.mode(OpenDrain); _cols.output(); - _setupFallTrigger(); +} + +void Keypad::_setupFallTrigger(void) +{ + _row0.fall(this, &Keypad::_callback); + _row1.fall(this, &Keypad::_callback); + _row2.fall(this, &Keypad::_callback); + _row3.fall(this, &Keypad::_callback); } void Keypad::Start(void) { + /* make the columns zero so they can pull rows down */ _cols = 0x00; } void Keypad::Stop(void) { - _cols = 0x0F; + /* make the columns one so they cannot pull any rows down anymore */ + _cols = ~0x00; } void Keypad::CallAfterInput(uint32_t (*fptr)(uint32_t index)) { _input.attach(fptr); + _setupFallTrigger(); +} + +int Keypad::DebouncedScan() +{ + int key1 = Scan(); + + /* debounce */ + wait_ms(_debounce); + + int key2 = Scan(); + + if (key1 != key2) + return -1; + else + return key1; } -void Keypad::_callback(int row, InterruptIn &therow) +int Keypad::Scan() { - wait_ms(_debounce); - if (therow != 0) - return; + /* lookup row */ + int r = -1; + for (r = 0; r < row_count; r++) { + if (*_rows[r] == 0) + break; + } + /* if we didn't find a valid row, return */ + if (!(0 <= r && r < row_count)) + return -1; + + /* scan columns to find out which one pulls down the row */ int c = -1; - _cols = 0x0E; - if (therow == 0) - c = 0; - else { - _cols = 0x0D; - if (therow == 0) - c = 1; - else { - _cols = 0x0B; - if (therow == 0) - c = 2; - else - c = 3; - } + for (c = 0; c < col_count; c++) { + _cols = ~(1 << c); + if (*_rows[r] == 0) + break; } - _input.call(row * 4 + c); - Start(); // Re-energize all columns + + /* re-energize all columns */ + Start(); + + /* if we didn't find a valid column, return */ + if (!(0 <= c && c < col_count)) + return -1; + + return r * col_count + c; } -void Keypad::_cbRow0Fall(void) -{ - _callback(0, _row0); -} -void Keypad::_cbRow1Fall(void) +void Keypad::_callback() { - _callback(1, _row1); -} -void Keypad::_cbRow2Fall(void) -{ - _callback(2, _row2); -} -void Keypad::_cbRow3Fall(void) -{ - _callback(3, _row3); + /* lookup */ + int position = DebouncedScan(); + + /* call back a valid position */ + if (position >= 0) + _input.call(position); } -void Keypad::_setupFallTrigger(void) -{ - _row0.fall(this, &Keypad::_cbRow0Fall); - _row1.fall(this, &Keypad::_cbRow1Fall); - _row2.fall(this, &Keypad::_cbRow2Fall); - _row3.fall(this, &Keypad::_cbRow3Fall); -}