From 6d4ad089c5b758ad8af4f68bf385a26ec4e9653a Mon Sep 17 00:00:00 2001 From: Thomas Albers Raviola Date: Thu, 21 Nov 2024 15:55:03 +0100 Subject: Initial commit --- src/input.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 src/input.c (limited to 'src/input.c') diff --git a/src/input.c b/src/input.c new file mode 100644 index 0000000..db306ea --- /dev/null +++ b/src/input.c @@ -0,0 +1,59 @@ +#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); + } + } +} -- cgit v1.2.3