#include #include #include #include enum encoder_state { START, CW_START, CW_NEXT, CW_FINAL, CCW_START, CCW_NEXT, CCW_FINAL, CW = 0x10, CCW = 0x20 }; /* State machine to keep track of encoder */ static const uint8_t encoder_table[7][4] = { /* 00 01 10 11*/ [START] = { START, CCW_START, CW_START, START }, [CCW_START] = { CCW_NEXT, CCW_START, START, START }, [CCW_NEXT] = { CCW_NEXT, CCW_START, CCW_FINAL, START }, [CCW_FINAL] = { CCW_NEXT, START, CCW_FINAL, START | CCW }, [CW_START] = { CW_NEXT, START, CW_START, START }, [CW_NEXT] = { CW_NEXT, CW_FINAL, CW_START, START }, [CW_FINAL] = { CW_NEXT, CW_FINAL, START, START | CW } }; struct fifo input_fifo = {0, 0, {0}}; void input_event(void) __critical __interrupt(4) { if ((port_b_data & 0x03) != 0x03) { // Encoder uint8_t state = START; uint8_t encoder; uint8_t next_state; do { encoder = port_b_data & 0x03; next_state = encoder_table[state][encoder]; state = next_state & 0x0F; } while (state != START); if (next_state == CW || next_state == CCW) fifo_push(&input_fifo, next_state); } else if (port_b_data & 0x7C) { // Key pressed for (int i = 0; i < 5; i++) { uint8_t bit = 1 << (i + 2); uint8_t state = !(port_b_data & bit); if (state) fifo_push(&input_fifo, i); } } }