The iPod controller that I submitted for the mbed challenge

Dependencies:   mbed Motordriver PID

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers keybrd.cpp Source File

keybrd.cpp

00001 #include "mbed.h"
00002 #include "keybrd.h"
00003 #include <limits.h>
00004 
00005 #define KEYS    (0xFC)
00006 #define PUSH    (1<<1)
00007 #define ROTA    (1<<3)
00008 #define ROTB    (1<<4)
00009 #define INPUTS  (PUSH|ROTA|ROTB)
00010 
00011 keybrd::keybrd(MCP23017& intf, PinName p): _eventhandler(0), _intf(intf), _keys(0), _lastkey(0), _pos(0), _oldpos(0), _state(0)  {
00012 printf("creating keyboard\n");
00013    _min = INT_MIN;
00014    _max = INT_MAX;
00015 //inirq = new DigitalOut(LED3);
00016 //*inirq = 0;
00017     intr = new InterruptIn(p);
00018     intr->mode(PullUp);
00019     intr->fall(this, &keybrd::handler);
00020     intf.interruptControl(PORT_A, 0); //interrupt on pin change from previous value
00021     intf.interruptControl(PORT_B, 0); //interrupt on pin change from previous value
00022     intf.interruptEnable(PORT_A, KEYS);//interrupt on key-press
00023     intf.interruptEnable(PORT_B, INPUTS);//interrupt on change of rotary encoder
00024 //printf("keyboard created\n");
00025 }
00026 
00027 unsigned short keybrd::get() {
00028     _intf.readW(INTCAPA);
00029     raw = ~_intf.readW(GPIOA);
00030     raw &= (INPUTS<<8) | KEYS;
00031     return raw;
00032 }
00033 
00034 void keybrd::handler() {
00035 //there can be a PORT_A interrupt, meaning a change in the state of one of the 6 buttons
00036 //or a PORT_B interrupt, meaning a change in the rotary encoder/button
00037 //PORT_A, interrupt on pin_change, 3 registers: change, snapshot, actual
00038 //read actual on both ports and compare to previous
00039 
00040 //*inirq = 1;
00041     if (_intf.isbusy()) {//the i2c interrupt is busy, so we postpone the read until it has finished
00042       _intf.post(this, &keybrd::handler);
00043 //*inirq = 0;
00044       return;
00045     }
00046     unsigned short present = get();//read the relevant pins
00047     char keys = (((present>>8) & PUSH) | present);
00048     char released = _keys & ~keys;//bitmap of keys just released
00049     char pressed = keys & ~_keys;//bitmap of keys just pressed
00050     if (keys==0)
00051       _lastkey = 0;
00052     for (int i = 1; i < 8; i++) {
00053         if (released & (1<<i))
00054             handleEvent(keyup, i);
00055         if (pressed & (1<<i)) {
00056             _lastkey = i;
00057             handleEvent(keydown, i);
00058         }
00059     }
00060 //printf("!%04X %02X %02X %d\n", present, pressed, released, _lastkey);
00061     _keys = keys;
00062     
00063     present >>= 8;
00064     present &= ROTA|ROTB;
00065     switch (_state) {
00066         case 0:
00067             if (present & ROTA) _pos--;
00068             else if (present & ROTB) _pos++;
00069             break;
00070         case ROTA:
00071             if (present & ROTB) _pos--;
00072             else if (!(present & ROTA)) _pos++;
00073             break;
00074         case ROTB:
00075             if (!(present & ROTB)) _pos--;
00076             else if (present & ROTA) _pos++;
00077             break;
00078         default://ROTA|ROTB
00079             if (!(present & ROTA)) _pos--;
00080             else if (!(present & ROTB)) _pos++;
00081             break;
00082     }
00083     if (_pos>_max) _pos = wrap ? _min : _max;
00084     else if (_pos<_min) _pos = wrap ? _max : _min;
00085     _state = present & (ROTA|ROTB);
00086     
00087     if (_state == 0)
00088         if (_pos > _oldpos)
00089             handleEvent(posup, _pos - _oldpos);
00090         else if (_pos < _oldpos)
00091             handleEvent(posdown, _oldpos - _pos);
00092     _oldpos = _pos;
00093  //*inirq = 0;
00094 }