The iPod controller that I submitted for the mbed challenge
Dependencies: mbed Motordriver PID
Diff: user_interface/keybrd.cpp
- Revision:
- 0:371773dd3dd1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/user_interface/keybrd.cpp Wed May 04 15:41:13 2011 +0000 @@ -0,0 +1,94 @@ +#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; +} \ No newline at end of file