diff options
| author | Nick Brassel <nick@tzarc.org> | 2024-03-10 22:24:17 +1100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-10 22:24:17 +1100 |
| commit | 3e1ac7a38fa4e6885053a762bc75f7c4e068eccb (patch) | |
| tree | 102642e387cebb67a840ae23ffda5d7413f33a71 /quantum/encoder.c | |
| parent | be42ea306b36bf7fac8b790452536156de8efcf6 (diff) | |
Fixes for encoder abstraction. (#23195)
Diffstat (limited to 'quantum/encoder.c')
| -rw-r--r-- | quantum/encoder.c | 92 |
1 files changed, 67 insertions, 25 deletions
diff --git a/quantum/encoder.c b/quantum/encoder.c index 735eb1cd71..0a48ac9a07 100644 --- a/quantum/encoder.c +++ b/quantum/encoder.c | |||
| @@ -15,34 +15,39 @@ __attribute__((weak)) bool should_process_encoder(void) { | |||
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | static encoder_events_t encoder_events; | 17 | static encoder_events_t encoder_events; |
| 18 | static bool signal_queue_drain = false; | ||
| 18 | 19 | ||
| 19 | void encoder_init(void) { | 20 | void encoder_init(void) { |
| 20 | memset(&encoder_events, 0, sizeof(encoder_events)); | 21 | memset(&encoder_events, 0, sizeof(encoder_events)); |
| 21 | encoder_driver_init(); | 22 | encoder_driver_init(); |
| 22 | } | 23 | } |
| 23 | 24 | ||
| 24 | static bool encoder_handle_queue(void) { | 25 | static void encoder_queue_drain(void) { |
| 25 | bool changed = false; | 26 | encoder_events.tail = encoder_events.head; |
| 26 | while (encoder_events.tail != encoder_events.head) { | 27 | encoder_events.dequeued = encoder_events.enqueued; |
| 27 | encoder_event_t event = encoder_events.queue[encoder_events.tail]; | 28 | } |
| 28 | encoder_events.tail = (encoder_events.tail + 1) % MAX_QUEUED_ENCODER_EVENTS; | ||
| 29 | 29 | ||
| 30 | static bool encoder_handle_queue(void) { | ||
| 31 | bool changed = false; | ||
| 32 | uint8_t index; | ||
| 33 | bool clockwise; | ||
| 34 | while (encoder_dequeue_event(&index, &clockwise)) { | ||
| 30 | #ifdef ENCODER_MAP_ENABLE | 35 | #ifdef ENCODER_MAP_ENABLE |
| 31 | 36 | ||
| 32 | // The delays below cater for Windows and its wonderful requirements. | 37 | // The delays below cater for Windows and its wonderful requirements. |
| 33 | action_exec(event.clockwise ? MAKE_ENCODER_CW_EVENT(event.index, true) : MAKE_ENCODER_CCW_EVENT(event.index, true)); | 38 | action_exec(clockwise ? MAKE_ENCODER_CW_EVENT(index, true) : MAKE_ENCODER_CCW_EVENT(index, true)); |
| 34 | # if ENCODER_MAP_KEY_DELAY > 0 | 39 | # if ENCODER_MAP_KEY_DELAY > 0 |
| 35 | wait_ms(ENCODER_MAP_KEY_DELAY); | 40 | wait_ms(ENCODER_MAP_KEY_DELAY); |
| 36 | # endif // ENCODER_MAP_KEY_DELAY > 0 | 41 | # endif // ENCODER_MAP_KEY_DELAY > 0 |
| 37 | 42 | ||
| 38 | action_exec(event.clockwise ? MAKE_ENCODER_CW_EVENT(event.index, false) : MAKE_ENCODER_CCW_EVENT(event.index, false)); | 43 | action_exec(clockwise ? MAKE_ENCODER_CW_EVENT(index, false) : MAKE_ENCODER_CCW_EVENT(index, false)); |
| 39 | # if ENCODER_MAP_KEY_DELAY > 0 | 44 | # if ENCODER_MAP_KEY_DELAY > 0 |
| 40 | wait_ms(ENCODER_MAP_KEY_DELAY); | 45 | wait_ms(ENCODER_MAP_KEY_DELAY); |
| 41 | # endif // ENCODER_MAP_KEY_DELAY > 0 | 46 | # endif // ENCODER_MAP_KEY_DELAY > 0 |
| 42 | 47 | ||
| 43 | #else // ENCODER_MAP_ENABLE | 48 | #else // ENCODER_MAP_ENABLE |
| 44 | 49 | ||
| 45 | encoder_update_kb(event.index, event.clockwise ? true : false); | 50 | encoder_update_kb(index, clockwise); |
| 46 | 51 | ||
| 47 | #endif // ENCODER_MAP_ENABLE | 52 | #endif // ENCODER_MAP_ENABLE |
| 48 | 53 | ||
| @@ -61,6 +66,11 @@ bool encoder_task(void) { | |||
| 61 | } | 66 | } |
| 62 | #endif // SPLIT_KEYBOARD | 67 | #endif // SPLIT_KEYBOARD |
| 63 | 68 | ||
| 69 | if (signal_queue_drain) { | ||
| 70 | signal_queue_drain = false; | ||
| 71 | encoder_queue_drain(); | ||
| 72 | } | ||
| 73 | |||
| 64 | // Let the encoder driver produce events | 74 | // Let the encoder driver produce events |
| 65 | encoder_driver_task(); | 75 | encoder_driver_task(); |
| 66 | 76 | ||
| @@ -72,39 +82,71 @@ bool encoder_task(void) { | |||
| 72 | return changed; | 82 | return changed; |
| 73 | } | 83 | } |
| 74 | 84 | ||
| 75 | bool encoder_queue_event(uint8_t index, bool clockwise) { | 85 | bool encoder_queue_full_advanced(encoder_events_t *events) { |
| 86 | return events->head == (events->tail - 1) % MAX_QUEUED_ENCODER_EVENTS; | ||
| 87 | } | ||
| 88 | |||
| 89 | bool encoder_queue_full(void) { | ||
| 90 | return encoder_queue_full_advanced(&encoder_events); | ||
| 91 | } | ||
| 92 | |||
| 93 | bool encoder_queue_empty_advanced(encoder_events_t *events) { | ||
| 94 | return events->head == events->tail; | ||
| 95 | } | ||
| 96 | |||
| 97 | bool encoder_queue_empty(void) { | ||
| 98 | return encoder_queue_empty_advanced(&encoder_events); | ||
| 99 | } | ||
| 100 | |||
| 101 | bool encoder_queue_event_advanced(encoder_events_t *events, uint8_t index, bool clockwise) { | ||
| 76 | // Drop out if we're full | 102 | // Drop out if we're full |
| 77 | if ((encoder_events.head + 1) % MAX_QUEUED_ENCODER_EVENTS == encoder_events.tail) { | 103 | if (encoder_queue_full_advanced(events)) { |
| 78 | return false; | 104 | return false; |
| 79 | } | 105 | } |
| 80 | 106 | ||
| 81 | // Append the event | 107 | // Append the event |
| 82 | encoder_event_t new_event = {.index = index, .clockwise = clockwise ? 1 : 0}; | 108 | encoder_event_t new_event = {.index = index, .clockwise = clockwise ? 1 : 0}; |
| 83 | encoder_events.queue[encoder_events.head] = new_event; | 109 | events->queue[events->head] = new_event; |
| 84 | 110 | ||
| 85 | // Increment the head index | 111 | // Increment the head index |
| 86 | encoder_events.head = (encoder_events.head + 1) % MAX_QUEUED_ENCODER_EVENTS; | 112 | events->head = (events->head + 1) % MAX_QUEUED_ENCODER_EVENTS; |
| 113 | events->enqueued++; | ||
| 87 | 114 | ||
| 88 | return true; | 115 | return true; |
| 89 | } | 116 | } |
| 90 | 117 | ||
| 91 | void encoder_retrieve_events(encoder_events_t *events) { | 118 | bool encoder_dequeue_event_advanced(encoder_events_t *events, uint8_t *index, bool *clockwise) { |
| 92 | memcpy(events, &encoder_events, sizeof(encoder_events)); | 119 | if (encoder_queue_empty_advanced(events)) { |
| 120 | return false; | ||
| 121 | } | ||
| 122 | |||
| 123 | // Retrieve the event | ||
| 124 | encoder_event_t event = events->queue[events->tail]; | ||
| 125 | *index = event.index; | ||
| 126 | *clockwise = event.clockwise; | ||
| 127 | |||
| 128 | // Increment the tail index | ||
| 129 | events->tail = (events->tail + 1) % MAX_QUEUED_ENCODER_EVENTS; | ||
| 130 | events->dequeued++; | ||
| 131 | |||
| 132 | return true; | ||
| 93 | } | 133 | } |
| 94 | 134 | ||
| 95 | #ifdef SPLIT_KEYBOARD | 135 | bool encoder_queue_event(uint8_t index, bool clockwise) { |
| 96 | void encoder_set_tail_index(uint8_t tail_index) { | 136 | return encoder_queue_event_advanced(&encoder_events, index, clockwise); |
| 97 | encoder_events.tail = tail_index; | ||
| 98 | } | 137 | } |
| 99 | 138 | ||
| 100 | void encoder_handle_slave_events(encoder_events_t *events) { | 139 | bool encoder_dequeue_event(uint8_t *index, bool *clockwise) { |
| 101 | while (events->tail != events->head) { | 140 | return encoder_dequeue_event_advanced(&encoder_events, index, clockwise); |
| 102 | encoder_event_t event = events->queue[events->tail]; | 141 | } |
| 103 | events->tail = (events->tail + 1) % MAX_QUEUED_ENCODER_EVENTS; | 142 | |
| 104 | encoder_queue_event(event.index, event.clockwise ? true : false); | 143 | void encoder_retrieve_events(encoder_events_t *events) { |
| 105 | } | 144 | memcpy(events, &encoder_events, sizeof(encoder_events)); |
| 145 | } | ||
| 146 | |||
| 147 | void encoder_signal_queue_drain(void) { | ||
| 148 | signal_queue_drain = true; | ||
| 106 | } | 149 | } |
| 107 | #endif // SPLIT_KEYBOARD | ||
| 108 | 150 | ||
| 109 | __attribute__((weak)) bool encoder_update_user(uint8_t index, bool clockwise) { | 151 | __attribute__((weak)) bool encoder_update_user(uint8_t index, bool clockwise) { |
| 110 | return true; | 152 | return true; |
