The iPod controller that I submitted for the mbed challenge
Dependencies: mbed Motordriver PID
user_interface/keybrd.cpp
- Committer:
- networker
- Date:
- 2011-05-04
- Revision:
- 0:371773dd3dd1
File content as of revision 0:371773dd3dd1:
#include "mbed.h" #include "keybrd.h" #include <limits.h> #define KEYS (0xFC) #define PUSH (1<<1) #define ROTA (1<<3) #define ROTB (1<<4) #define INPUTS (PUSH|ROTA|ROTB) keybrd::keybrd(MCP23017& intf, PinName p): _eventhandler(0), _intf(intf), _keys(0), _lastkey(0), _pos(0), _oldpos(0), _state(0) { printf("creating keyboard\n"); _min = INT_MIN; _max = INT_MAX; //inirq = new DigitalOut(LED3); //*inirq = 0; intr = new InterruptIn(p); intr->mode(PullUp); intr->fall(this, &keybrd::handler); intf.interruptControl(PORT_A, 0); //interrupt on pin change from previous value intf.interruptControl(PORT_B, 0); //interrupt on pin change from previous value intf.interruptEnable(PORT_A, KEYS);//interrupt on key-press intf.interruptEnable(PORT_B, INPUTS);//interrupt on change of rotary encoder //printf("keyboard created\n"); } unsigned short keybrd::get() { _intf.readW(INTCAPA); raw = ~_intf.readW(GPIOA); raw &= (INPUTS<<8) | KEYS; return raw; } void keybrd::handler() { //there can be a PORT_A interrupt, meaning a change in the state of one of the 6 buttons //or a PORT_B interrupt, meaning a change in the rotary encoder/button //PORT_A, interrupt on pin_change, 3 registers: change, snapshot, actual //read actual on both ports and compare to previous //*inirq = 1; if (_intf.isbusy()) {//the i2c interrupt is busy, so we postpone the read until it has finished _intf.post(this, &keybrd::handler); //*inirq = 0; return; } unsigned short present = get();//read the relevant pins char keys = (((present>>8) & PUSH) | present); char released = _keys & ~keys;//bitmap of keys just released char pressed = keys & ~_keys;//bitmap of keys just pressed if (keys==0) _lastkey = 0; for (int i = 1; i < 8; i++) { if (released & (1<<i)) handleEvent(keyup, i); if (pressed & (1<<i)) { _lastkey = i; handleEvent(keydown, i); } } //printf("!%04X %02X %02X %d\n", present, pressed, released, _lastkey); _keys = keys; present >>= 8; present &= ROTA|ROTB; switch (_state) { case 0: if (present & ROTA) _pos--; else if (present & ROTB) _pos++; break; case ROTA: if (present & ROTB) _pos--; else if (!(present & ROTA)) _pos++; break; case ROTB: if (!(present & ROTB)) _pos--; else if (present & ROTA) _pos++; break; default://ROTA|ROTB if (!(present & ROTA)) _pos--; else if (!(present & ROTB)) _pos++; break; } if (_pos>_max) _pos = wrap ? _min : _max; else if (_pos<_min) _pos = wrap ? _max : _min; _state = present & (ROTA|ROTB); if (_state == 0) if (_pos > _oldpos) handleEvent(posup, _pos - _oldpos); else if (_pos < _oldpos) handleEvent(posdown, _oldpos - _pos); _oldpos = _pos; //*inirq = 0; }