enum QDECODER_EVENT { QDECODER_EVENT_NONE = 0x00u, QDECODER_EVENT_CW = 0x80u, QDECODER_EVENT_CCW = 0x40u, }; // state is internal... needs never be exposed to callers enum QDECODER_STATE { QDECODER_STATE_START = 0x00u, QDECODER_STATE_CW_A = 0x01u, QDECODER_STATE_CW_B = 0x02u, QDECODER_STATE_CW_C = 0x03u, QDECODER_STATE_MID = 0x04u, QDECODER_STATE_CCW_A = 0x05u, QDECODER_STATE_CCW_B = 0x06u, QDECODER_STATE_CCW_C = 0x07u, }; const uint8_t QDECODER_EVENT_BITMASK = 0xC0; // events are the most significant two bits const uint8_t QDECODER_STATE_BITMASK = 0x07; // states are in the least significant three bits const uint8_t HALF_STEP_STATE_TRANSITIONS[8][4] = { // 0 = start {QDECODER_STATE_MID, QDECODER_STATE_CW_A, QDECODER_STATE_CCW_A, QDECODER_STATE_START }, // 1 = CW_A {QDECODER_EVENT_CW | QDECODER_STATE_MID, QDECODER_STATE_CW_A, QDECODER_STATE_START, QDECODER_STATE_START }, // 2 = CW_B (unused in half-step mode) {QDECODER_STATE_START, QDECODER_STATE_START, QDECODER_STATE_START, QDECODER_STATE_START }, // 3 = CW_C {QDECODER_STATE_MID, QDECODER_STATE_MID, QDECODER_STATE_CW_C, QDECODER_STATE_START | QDECODER_EVENT_CW }, // 4 = mid {QDECODER_STATE_MID, QDECODER_STATE_CCW_C, QDECODER_STATE_CW_C, QDECODER_STATE_START }, // 5 = CCW_A {QDECODER_EVENT_CCW | QDECODER_STATE_MID, QDECODER_STATE_START, QDECODER_STATE_CCW_A, QDECODER_STATE_START }, // 6 = CCW_B (unused in half-step mode) {QDECODER_STATE_START, QDECODER_STATE_START, QDECODER_STATE_START, QDECODER_STATE_START }, // 7 = CCW_C {QDECODER_STATE_MID, QDECODER_STATE_CCW_C, QDECODER_STATE_MID, QDECODER_STATE_START | QDECODER_EVENT_CCW}, }; const uint8_t FULL_STEP_STATE_TRANSITIONS[8][4] = { // 0 = start {QDECODER_STATE_START, QDECODER_STATE_CW_A, QDECODER_STATE_CCW_A, QDECODER_STATE_START }, // 1 = CW_A {QDECODER_STATE_CW_B, QDECODER_STATE_CW_A, QDECODER_STATE_START, QDECODER_STATE_START }, // 2 = CW_B {QDECODER_STATE_CW_B, QDECODER_STATE_CW_A, QDECODER_STATE_CW_C, QDECODER_STATE_START }, // 3 = CW_C {QDECODER_STATE_CW_B, QDECODER_STATE_START, QDECODER_STATE_CW_C, QDECODER_STATE_START | QDECODER_EVENT_CW }, // 4 = mid (unused in full step mode ...) {QDECODER_STATE_START, QDECODER_STATE_START, QDECODER_STATE_START, QDECODER_STATE_START }, // 5 = CCW_A {QDECODER_STATE_CCW_B, QDECODER_STATE_START, QDECODER_STATE_CCW_A, QDECODER_STATE_START }, // 6 = CCW_B {QDECODER_STATE_CCW_B, QDECODER_STATE_CCW_C, QDECODER_STATE_CCW_A, QDECODER_STATE_START }, // 7 = CCW_C {QDECODER_STATE_CCW_B, QDECODER_STATE_CCW_C, QDECODER_STATE_START, QDECODER_STATE_START | QDECODER_EVENT_CCW }, };