The iPod controller that I submitted for the mbed challenge

Dependencies:   mbed Motordriver PID

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