The iPod controller that I submitted for the mbed challenge
Dependencies: mbed Motordriver PID
user_interface/keybrd.cpp@0:371773dd3dd1, 2011-05-04 (annotated)
- Committer:
- networker
- Date:
- Wed May 04 15:41:13 2011 +0000
- Revision:
- 0:371773dd3dd1
first publication
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
networker | 0:371773dd3dd1 | 1 | #include "mbed.h" |
networker | 0:371773dd3dd1 | 2 | #include "keybrd.h" |
networker | 0:371773dd3dd1 | 3 | #include <limits.h> |
networker | 0:371773dd3dd1 | 4 | |
networker | 0:371773dd3dd1 | 5 | #define KEYS (0xFC) |
networker | 0:371773dd3dd1 | 6 | #define PUSH (1<<1) |
networker | 0:371773dd3dd1 | 7 | #define ROTA (1<<3) |
networker | 0:371773dd3dd1 | 8 | #define ROTB (1<<4) |
networker | 0:371773dd3dd1 | 9 | #define INPUTS (PUSH|ROTA|ROTB) |
networker | 0:371773dd3dd1 | 10 | |
networker | 0:371773dd3dd1 | 11 | keybrd::keybrd(MCP23017& intf, PinName p): _eventhandler(0), _intf(intf), _keys(0), _lastkey(0), _pos(0), _oldpos(0), _state(0) { |
networker | 0:371773dd3dd1 | 12 | printf("creating keyboard\n"); |
networker | 0:371773dd3dd1 | 13 | _min = INT_MIN; |
networker | 0:371773dd3dd1 | 14 | _max = INT_MAX; |
networker | 0:371773dd3dd1 | 15 | //inirq = new DigitalOut(LED3); |
networker | 0:371773dd3dd1 | 16 | //*inirq = 0; |
networker | 0:371773dd3dd1 | 17 | intr = new InterruptIn(p); |
networker | 0:371773dd3dd1 | 18 | intr->mode(PullUp); |
networker | 0:371773dd3dd1 | 19 | intr->fall(this, &keybrd::handler); |
networker | 0:371773dd3dd1 | 20 | intf.interruptControl(PORT_A, 0); //interrupt on pin change from previous value |
networker | 0:371773dd3dd1 | 21 | intf.interruptControl(PORT_B, 0); //interrupt on pin change from previous value |
networker | 0:371773dd3dd1 | 22 | intf.interruptEnable(PORT_A, KEYS);//interrupt on key-press |
networker | 0:371773dd3dd1 | 23 | intf.interruptEnable(PORT_B, INPUTS);//interrupt on change of rotary encoder |
networker | 0:371773dd3dd1 | 24 | //printf("keyboard created\n"); |
networker | 0:371773dd3dd1 | 25 | } |
networker | 0:371773dd3dd1 | 26 | |
networker | 0:371773dd3dd1 | 27 | unsigned short keybrd::get() { |
networker | 0:371773dd3dd1 | 28 | _intf.readW(INTCAPA); |
networker | 0:371773dd3dd1 | 29 | raw = ~_intf.readW(GPIOA); |
networker | 0:371773dd3dd1 | 30 | raw &= (INPUTS<<8) | KEYS; |
networker | 0:371773dd3dd1 | 31 | return raw; |
networker | 0:371773dd3dd1 | 32 | } |
networker | 0:371773dd3dd1 | 33 | |
networker | 0:371773dd3dd1 | 34 | void keybrd::handler() { |
networker | 0:371773dd3dd1 | 35 | //there can be a PORT_A interrupt, meaning a change in the state of one of the 6 buttons |
networker | 0:371773dd3dd1 | 36 | //or a PORT_B interrupt, meaning a change in the rotary encoder/button |
networker | 0:371773dd3dd1 | 37 | //PORT_A, interrupt on pin_change, 3 registers: change, snapshot, actual |
networker | 0:371773dd3dd1 | 38 | //read actual on both ports and compare to previous |
networker | 0:371773dd3dd1 | 39 | |
networker | 0:371773dd3dd1 | 40 | //*inirq = 1; |
networker | 0:371773dd3dd1 | 41 | if (_intf.isbusy()) {//the i2c interrupt is busy, so we postpone the read until it has finished |
networker | 0:371773dd3dd1 | 42 | _intf.post(this, &keybrd::handler); |
networker | 0:371773dd3dd1 | 43 | //*inirq = 0; |
networker | 0:371773dd3dd1 | 44 | return; |
networker | 0:371773dd3dd1 | 45 | } |
networker | 0:371773dd3dd1 | 46 | unsigned short present = get();//read the relevant pins |
networker | 0:371773dd3dd1 | 47 | char keys = (((present>>8) & PUSH) | present); |
networker | 0:371773dd3dd1 | 48 | char released = _keys & ~keys;//bitmap of keys just released |
networker | 0:371773dd3dd1 | 49 | char pressed = keys & ~_keys;//bitmap of keys just pressed |
networker | 0:371773dd3dd1 | 50 | if (keys==0) |
networker | 0:371773dd3dd1 | 51 | _lastkey = 0; |
networker | 0:371773dd3dd1 | 52 | for (int i = 1; i < 8; i++) { |
networker | 0:371773dd3dd1 | 53 | if (released & (1<<i)) |
networker | 0:371773dd3dd1 | 54 | handleEvent(keyup, i); |
networker | 0:371773dd3dd1 | 55 | if (pressed & (1<<i)) { |
networker | 0:371773dd3dd1 | 56 | _lastkey = i; |
networker | 0:371773dd3dd1 | 57 | handleEvent(keydown, i); |
networker | 0:371773dd3dd1 | 58 | } |
networker | 0:371773dd3dd1 | 59 | } |
networker | 0:371773dd3dd1 | 60 | //printf("!%04X %02X %02X %d\n", present, pressed, released, _lastkey); |
networker | 0:371773dd3dd1 | 61 | _keys = keys; |
networker | 0:371773dd3dd1 | 62 | |
networker | 0:371773dd3dd1 | 63 | present >>= 8; |
networker | 0:371773dd3dd1 | 64 | present &= ROTA|ROTB; |
networker | 0:371773dd3dd1 | 65 | switch (_state) { |
networker | 0:371773dd3dd1 | 66 | case 0: |
networker | 0:371773dd3dd1 | 67 | if (present & ROTA) _pos--; |
networker | 0:371773dd3dd1 | 68 | else if (present & ROTB) _pos++; |
networker | 0:371773dd3dd1 | 69 | break; |
networker | 0:371773dd3dd1 | 70 | case ROTA: |
networker | 0:371773dd3dd1 | 71 | if (present & ROTB) _pos--; |
networker | 0:371773dd3dd1 | 72 | else if (!(present & ROTA)) _pos++; |
networker | 0:371773dd3dd1 | 73 | break; |
networker | 0:371773dd3dd1 | 74 | case ROTB: |
networker | 0:371773dd3dd1 | 75 | if (!(present & ROTB)) _pos--; |
networker | 0:371773dd3dd1 | 76 | else if (present & ROTA) _pos++; |
networker | 0:371773dd3dd1 | 77 | break; |
networker | 0:371773dd3dd1 | 78 | default://ROTA|ROTB |
networker | 0:371773dd3dd1 | 79 | if (!(present & ROTA)) _pos--; |
networker | 0:371773dd3dd1 | 80 | else if (!(present & ROTB)) _pos++; |
networker | 0:371773dd3dd1 | 81 | break; |
networker | 0:371773dd3dd1 | 82 | } |
networker | 0:371773dd3dd1 | 83 | if (_pos>_max) _pos = wrap ? _min : _max; |
networker | 0:371773dd3dd1 | 84 | else if (_pos<_min) _pos = wrap ? _max : _min; |
networker | 0:371773dd3dd1 | 85 | _state = present & (ROTA|ROTB); |
networker | 0:371773dd3dd1 | 86 | |
networker | 0:371773dd3dd1 | 87 | if (_state == 0) |
networker | 0:371773dd3dd1 | 88 | if (_pos > _oldpos) |
networker | 0:371773dd3dd1 | 89 | handleEvent(posup, _pos - _oldpos); |
networker | 0:371773dd3dd1 | 90 | else if (_pos < _oldpos) |
networker | 0:371773dd3dd1 | 91 | handleEvent(posdown, _oldpos - _pos); |
networker | 0:371773dd3dd1 | 92 | _oldpos = _pos; |
networker | 0:371773dd3dd1 | 93 | //*inirq = 0; |
networker | 0:371773dd3dd1 | 94 | } |