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;
}