11
keypad.cpp
- Committer:
- gj_schoneveld
- Date:
- 2012-11-04
- Revision:
- 15:873a9a452ef1
- Parent:
- 14:f6c3647bf421
- Child:
- 16:a9feaa7ac039
File content as of revision 15:873a9a452ef1:
#include "keypad.h" Keypad::Keypad(PinName row3, PinName row2, PinName row1, PinName row0, PinName col3, PinName col2, PinName col1, PinName col0, int debounce_ms): _row0(row0), _row1(row1), _row2(row2), _row3(row3), _cols(col0, col1, col2, col3) { _debounce = debounce_ms; _rows[0] = &_row0; _rows[1] = &_row1; _rows[2] = &_row2; _rows[3] = &_row3; for (int r = 0; r < row_count; r++) _rows[r]->mode(PullUp); _cols.mode(OpenDrain); _cols.output(); } void Keypad::_setupFallTrigger(void) { for (int r = 0; r < row_count; r++) _rows[r]->fall(this, &Keypad::_callback); } void Keypad::Start(void) { /* make the columns zero so they can pull rows down */ _cols = 0x00; } void Keypad::Stop(void) { /* 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() { /* debounce */ int key1 = Scan(); wait_ms(_debounce); int key2 = Scan(); if (key1 != key2) return -1; else return key1; } int Keypad::Scan() { /* 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; for (c = 0; c < col_count; c++) { _cols = ~(1 << c); if (*_rows[r] == 0) break; } /* 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; } int Keypad::DebouncedScanMultiple() { /* debounce */ int key1 = ScanMultiple(); wait_ms(_debounce); int key2 = ScanMultiple(); return key1 & key2; } int Keypad::ScanMultiple() { int res = 0; for (int c = 0; c < col_count; c++) { _cols = ~(1 << c); for (int r = 0; r < row_count; r++) { if (*_rows[r] == 0) { res |= 1 << (r * col_count + c); } } } return res; } void Keypad::_callback() { /* lookup */ int position = DebouncedScan(); /* call back a valid position */ if (position >= 0) _input.call(position); }