KeyboardManager: a class to manage the polling of a switch-matrix keyboard
KeyboardManager.cpp
- Committer:
- osmeest
- Date:
- 2011-01-19
- Revision:
- 0:f813c207f78f
- Child:
- 1:a74ffceb67e5
File content as of revision 0:f813c207f78f:
#include "KeyboardManager.h" enum { InPortShift = 15, OutPortShift = 6 }; KeyboardManager::KeyboardManager( PortName inPort, int inLowestBit, PortName outPort, int outLowestBit, KeyEventHandler handler) : handler(handler), in(inPort, 0x0f << inLowestBit), inBitShift(inLowestBit), out(outPort, 0x0f << outLowestBit), outBitShift(outLowestBit), ticker(), scanRow(0), currentState(0), lastState(0), lastReportedState(0) { } void KeyboardManager::start() { printf("Starting KeyboardManager...\r\n"); this->in.mode(PullDown); this->ticker.attach(this, &KeyboardManager::timerHandler, 0.01); } void KeyboardManager::stop() { printf("Stopping KeyboardManager...\r\n"); this->ticker.detach(); this->in.mode(OpenDrain); } namespace { bool isSingleKey(int state) { if (state == 0) { return false; } return (state == (state & (-state))); } int getKeyId(int state) { if (state == 0) { return 0; } int key = 1; while ((state & 1) == 0) { key++; state >>= 1; } return key; } } void KeyboardManager::timerHandler() { unsigned r = 1 << (this->scanRow + this->outBitShift); out.write(r); wait_us(10); unsigned v = in.read() >> this->inBitShift; this->currentState |= (v & 0x0f) << (4 * this->scanRow); this->scanRow = (this->scanRow + 1) & 3; if (this->scanRow == 0) { if (this->currentState != this->lastState) { if (isSingleKey(this->currentState) && this->lastReportedState == 0) { int key = getKeyId(this->currentState); printf("Key pressed: %d (%04x)\r\n", key, this->currentState); if (this->handler) { this->handler(key, true); } this->lastReportedState = this->currentState; } else if (this->lastReportedState != 0 && (this->currentState & this->lastReportedState) == 0) { int key = getKeyId(this->lastReportedState); printf("Key released: %d (%04x | %04x)\r\n", key, this->currentState, this->lastReportedState); if (this->handler) { this->handler(key, false); } this->lastReportedState = 0; } this->lastState = this->currentState; } this->currentState = 0; } }