3e1ac7a38fa4e6885053a762bc75f7c4e068eccb

Author
Nick Brassel <nick@tzarc.org>
Committer
GitHub <noreply@github.com>
Date

Message

Fixes for encoder abstraction. (#23195)

Diff

This diff is truncated to protect this page.

  1diff --git a/quantum/encoder.c b/quantum/encoder.c
  2index 735eb1cd71f69cc6679b93f1aaea74e6d5874cd6..0a48ac9a07b50fa3a6d84a9215c03b6f8d4499ef 100644
  3--- a/quantum/encoder.c
  4+++ b/quantum/encoder.c
  5@@ -15,34 +15,39 @@ __attribute__((weak)) bool should_process_encoder(void) {
  6 }
  7 
  8 static encoder_events_t encoder_events;
  9+static bool             signal_queue_drain = false;
 10 
 11 void encoder_init(void) {
 12     memset(&encoder_events, 0, sizeof(encoder_events));
 13     encoder_driver_init();
 14 }
 15 
 16-static bool encoder_handle_queue(void) {
 17-    bool changed = false;
 18-    while (encoder_events.tail != encoder_events.head) {
 19-        encoder_event_t event = encoder_events.queue[encoder_events.tail];
 20-        encoder_events.tail   = (encoder_events.tail + 1) % MAX_QUEUED_ENCODER_EVENTS;
 21+static void encoder_queue_drain(void) {
 22+    encoder_events.tail     = encoder_events.head;
 23+    encoder_events.dequeued = encoder_events.enqueued;
 24+}
 25 
 26+static bool encoder_handle_queue(void) {
 27+    bool    changed = false;
 28+    uint8_t index;
 29+    bool    clockwise;
 30+    while (encoder_dequeue_event(&index, &clockwise)) {
 31 #ifdef ENCODER_MAP_ENABLE
 32 
 33         // The delays below cater for Windows and its wonderful requirements.
 34-        action_exec(event.clockwise ? MAKE_ENCODER_CW_EVENT(event.index, true) : MAKE_ENCODER_CCW_EVENT(event.index, true));
 35+        action_exec(clockwise ? MAKE_ENCODER_CW_EVENT(index, true) : MAKE_ENCODER_CCW_EVENT(index, true));
 36 #    if ENCODER_MAP_KEY_DELAY > 0
 37         wait_ms(ENCODER_MAP_KEY_DELAY);
 38 #    endif // ENCODER_MAP_KEY_DELAY > 0
 39 
 40-        action_exec(event.clockwise ? MAKE_ENCODER_CW_EVENT(event.index, false) : MAKE_ENCODER_CCW_EVENT(event.index, false));
 41+        action_exec(clockwise ? MAKE_ENCODER_CW_EVENT(index, false) : MAKE_ENCODER_CCW_EVENT(index, false));
 42 #    if ENCODER_MAP_KEY_DELAY > 0
 43         wait_ms(ENCODER_MAP_KEY_DELAY);
 44 #    endif // ENCODER_MAP_KEY_DELAY > 0
 45 
 46 #else // ENCODER_MAP_ENABLE
 47 
 48-        encoder_update_kb(event.index, event.clockwise ? true : false);
 49+        encoder_update_kb(index, clockwise);
 50 
 51 #endif // ENCODER_MAP_ENABLE
 52 
 53@@ -61,6 +66,11 @@ bool encoder_task(void) {
 54     }
 55 #endif // SPLIT_KEYBOARD
 56 
 57+    if (signal_queue_drain) {
 58+        signal_queue_drain = false;
 59+        encoder_queue_drain();
 60+    }
 61+
 62     // Let the encoder driver produce events
 63     encoder_driver_task();
 64 
 65@@ -72,39 +82,71 @@ bool encoder_task(void) {
 66     return changed;
 67 }
 68 
 69-bool encoder_queue_event(uint8_t index, bool clockwise) {
 70+bool encoder_queue_full_advanced(encoder_events_t *events) {
 71+    return events->head == (events->tail - 1) % MAX_QUEUED_ENCODER_EVENTS;
 72+}
 73+
 74+bool encoder_queue_full(void) {
 75+    return encoder_queue_full_advanced(&encoder_events);
 76+}
 77+
 78+bool encoder_queue_empty_advanced(encoder_events_t *events) {
 79+    return events->head == events->tail;
 80+}
 81+
 82+bool encoder_queue_empty(void) {
 83+    return encoder_queue_empty_advanced(&encoder_events);
 84+}
 85+
 86+bool encoder_queue_event_advanced(encoder_events_t *events, uint8_t index, bool clockwise) {
 87     // Drop out if we're full
 88-    if ((encoder_events.head + 1) % MAX_QUEUED_ENCODER_EVENTS == encoder_events.tail) {
 89+    if (encoder_queue_full_advanced(events)) {
 90         return false;
 91     }
 92 
 93     // Append the event
 94-    encoder_event_t new_event                 = {.index = index, .clockwise = clockwise ? 1 : 0};
 95-    encoder_events.queue[encoder_events.head] = new_event;
 96+    encoder_event_t new_event   = {.index = index, .clockwise = clockwise ? 1 : 0};
 97+    events->queue[events->head] = new_event;
 98 
 99     // Increment the head index
100-    encoder_events.head = (encoder_events.head + 1) % MAX_QUEUED_ENCODER_EVENTS;
101+    events->head = (events->head + 1) % MAX_QUEUED_ENCODER_EVENTS;
102+    events->enqueued++;
103 
104     return true;
105diff --git a/quantum/encoder.h b/quantum/encoder.h
106index 90414a43a06e5f1be395cc471be23eacbec7566e..317a91f1da5438be9fa62f785d03f3f86b21c0c2 100644
107--- a/quantum/encoder.h
108+++ b/quantum/encoder.h
109@@ -29,6 +29,7 @@ __attribute__((weak)) bool should_process_encoder(void);
110 void encoder_init(void);
111 bool encoder_task(void);
112 bool encoder_queue_event(uint8_t index, bool clockwise);
113+bool encoder_dequeue_event(uint8_t *index, bool *clockwise);
114 
115 bool encoder_update_kb(uint8_t index, bool clockwise);
116 bool encoder_update_user(uint8_t index, bool clockwise);
117@@ -82,6 +83,8 @@ typedef struct encoder_event_t {
118 } encoder_event_t;
119 
120 typedef struct encoder_events_t {
121+    uint8_t         enqueued;
122+    uint8_t         dequeued;
123     uint8_t         head;
124     uint8_t         tail;
125     encoder_event_t queue[MAX_QUEUED_ENCODER_EVENTS];
126@@ -90,10 +93,12 @@ typedef struct encoder_events_t {
127 // Get the current queued events
128 void encoder_retrieve_events(encoder_events_t *events);
129 
130-#    ifdef SPLIT_KEYBOARD
131-void encoder_set_tail_index(uint8_t tail_index);
132-void encoder_handle_slave_events(encoder_events_t *events);
133-#    endif // SPLIT_KEYBOARD
134+// Encoder event queue management
135+bool encoder_queue_event_advanced(encoder_events_t *events, uint8_t index, bool clockwise);
136+bool encoder_dequeue_event_advanced(encoder_events_t *events, uint8_t *index, bool *clockwise);
137+
138+// Reset the queue to be empty
139+void encoder_signal_queue_drain(void);
140 
141 #    ifdef ENCODER_MAP_ENABLE
142 #        define NUM_DIRECTIONS 2
143diff --git a/quantum/split_common/transaction_id_define.h b/quantum/split_common/transaction_id_define.h
144index 05b3bf7b625dcaede365856ede67608d1a79fca0..5bfbe2aec792513ad625094db4ea92328dbe7770 100644
145--- a/quantum/split_common/transaction_id_define.h
146+++ b/quantum/split_common/transaction_id_define.h
147@@ -31,7 +31,7 @@ enum serial_transaction_id {
148 #ifdef ENCODER_ENABLE
149     GET_ENCODERS_CHECKSUM,
150     GET_ENCODERS_DATA,
151-    PUT_ENCODER_TAIL,
152+    CMD_ENCODER_DRAIN,
153 #endif // ENCODER_ENABLE
154 
155 #ifndef DISABLE_SYNC_TIMER
156diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c
157index 2cfa83e7a3f0a35115455e72e64d41aa63f925cf..33bc9e9f575a97a2f2244f39d3b0af36c201a69c 100644
158--- a/quantum/split_common/transactions.c
159+++ b/quantum/split_common/transactions.c
160@@ -14,6 +14,7 @@
161  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
162  */
163 
164+#include <stdint.h>
165 #include <string.h>
166 #include <stddef.h>
167 
168@@ -80,8 +81,12 @@
169     { 0, 0, sizeof_member(split_shared_memory_t, member), offsetof(split_shared_memory_t, member), cb }
170 #define trans_target2initiator_initializer(member) trans_target2initiator_initializer_cb(member, NULL)
171 
172+#define trans_initiator2target_cb(cb) \
173+    { 0, 0, 0, 0, cb }
174+
175 #define transport_write(id, data, length) transport_execute_transaction(id, data, length, NULL, 0)
176 #define transport_read(id, data, length) transport_execute_transaction(id, NULL, 0, data, length)
177+#define transport_exec(id) transport_execute_transaction(id, NULL, 0, NULL, 0)
178 
179 #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER)
180 // Forward-declare the RPC callback handlers
181@@ -234,14 +239,26 @@ static void master_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_ro
182 #ifdef ENCODER_ENABLE
183 
184 static bool encoder_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) {
185-    static uint32_t  last_update = 0;
186+    static uint32_t  last_update   = 0;
187+    static uint8_t   last_checksum = 0;
188     encoder_events_t temp_events;
189 
190     bool okay = read_if_checksum_mismatch(GET_ENCODERS_CHECKSUM, GET_ENCODERS_DATA, &last_update, &temp_events, &split_shmem->encoders.events, sizeof(temp_events));
191     if (okay) {
192-        encoder_handle_slave_events(&split_shmem->encoders.events);
193-        transport_write(PUT_ENCODER_TAIL, &split_shmem->encoders.events.tail, sizeof(split_shmem->encoders.events.tail));
194-        split_shmem->encoders.checksum = crc8(&split_shmem->encoders.events, sizeof(split_shmem->encoders.events));
195+        if (last_checksum != split_shmem->encoders.checksum) {
196+            bool    actioned = false;
197+            uint8_t index;
198+            bool    clockwise;
199+            while (okay && encoder_dequeue_event_advanced(&split_shmem->encoders.events, &index, &clockwise)) {
200+                okay &= encoder_queue_event(index, clockwise);
201+                actioned = true;
202+            }
203+
204+            if (actioned) {
205+                okay &= transport_exec(CMD_ENCODER_DRAIN);
206+            }
207+            last_checksum = split_shmem->encoders.checksum;
208+        }
209     }
210     return okay;
211 }
212@@ -253,9 +270,8 @@ static void encoder_handlers_slave(matrix_row_t master_matrix[], matrix_row_t sl
213     split_shmem->encoders.checksum = crc8(&split_shmem->encoders.events, sizeof(split_shmem->encoders.events));
214 }
215 
216-static void encoder_handlers_slave_reset(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) {
217-    uint8_t tail_index = *(uint8_t *)initiator2target_buffer;
218-    encoder_set_tail_index(tail_index);
219+static void encoder_handlers_slave_drain(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) {
220+    encoder_signal_queue_drain();
221 }
222 
223 // clang-format off
224@@ -264,7 +280,7 @@ static void encoder_handlers_slave_reset(uint8_t initiator2target_buffer_size, c
225 #    define TRANSACTIONS_ENCODERS_REGISTRATIONS \
226     [GET_ENCODERS_CHECKSUM] = trans_target2initiator_initializer(encoders.checksum), \
227     [GET_ENCODERS_DATA]     = trans_target2initiator_initializer(encoders.events), \
228-    [PUT_ENCODER_TAIL]      = trans_initiator2target_initializer_cb(encoders.events.tail, encoder_handlers_slave_reset),
229+    [CMD_ENCODER_DRAIN]     = trans_initiator2target_cb(encoder_handlers_slave_drain),
230 // clang-format on
231 
232 #else // ENCODER_ENABLE