diff options
| -rw-r--r-- | quantum/encoder.c | 92 | ||||
| -rw-r--r-- | quantum/encoder.h | 13 | ||||
| -rw-r--r-- | quantum/split_common/transaction_id_define.h | 2 | ||||
| -rw-r--r-- | quantum/split_common/transactions.c | 32 |
4 files changed, 101 insertions, 38 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; |
diff --git a/quantum/encoder.h b/quantum/encoder.h index 90414a43a0..317a91f1da 100644 --- a/quantum/encoder.h +++ b/quantum/encoder.h | |||
| @@ -29,6 +29,7 @@ __attribute__((weak)) bool should_process_encoder(void); | |||
| 29 | void encoder_init(void); | 29 | void encoder_init(void); |
| 30 | bool encoder_task(void); | 30 | bool encoder_task(void); |
| 31 | bool encoder_queue_event(uint8_t index, bool clockwise); | 31 | bool encoder_queue_event(uint8_t index, bool clockwise); |
| 32 | bool encoder_dequeue_event(uint8_t *index, bool *clockwise); | ||
| 32 | 33 | ||
| 33 | bool encoder_update_kb(uint8_t index, bool clockwise); | 34 | bool encoder_update_kb(uint8_t index, bool clockwise); |
| 34 | bool encoder_update_user(uint8_t index, bool clockwise); | 35 | bool encoder_update_user(uint8_t index, bool clockwise); |
| @@ -82,6 +83,8 @@ typedef struct encoder_event_t { | |||
| 82 | } encoder_event_t; | 83 | } encoder_event_t; |
| 83 | 84 | ||
| 84 | typedef struct encoder_events_t { | 85 | typedef struct encoder_events_t { |
| 86 | uint8_t enqueued; | ||
| 87 | uint8_t dequeued; | ||
| 85 | uint8_t head; | 88 | uint8_t head; |
| 86 | uint8_t tail; | 89 | uint8_t tail; |
| 87 | encoder_event_t queue[MAX_QUEUED_ENCODER_EVENTS]; | 90 | encoder_event_t queue[MAX_QUEUED_ENCODER_EVENTS]; |
| @@ -90,10 +93,12 @@ typedef struct encoder_events_t { | |||
| 90 | // Get the current queued events | 93 | // Get the current queued events |
| 91 | void encoder_retrieve_events(encoder_events_t *events); | 94 | void encoder_retrieve_events(encoder_events_t *events); |
| 92 | 95 | ||
| 93 | # ifdef SPLIT_KEYBOARD | 96 | // Encoder event queue management |
| 94 | void encoder_set_tail_index(uint8_t tail_index); | 97 | bool encoder_queue_event_advanced(encoder_events_t *events, uint8_t index, bool clockwise); |
| 95 | void encoder_handle_slave_events(encoder_events_t *events); | 98 | bool encoder_dequeue_event_advanced(encoder_events_t *events, uint8_t *index, bool *clockwise); |
| 96 | # endif // SPLIT_KEYBOARD | 99 | |
| 100 | // Reset the queue to be empty | ||
| 101 | void encoder_signal_queue_drain(void); | ||
| 97 | 102 | ||
| 98 | # ifdef ENCODER_MAP_ENABLE | 103 | # ifdef ENCODER_MAP_ENABLE |
| 99 | # define NUM_DIRECTIONS 2 | 104 | # define NUM_DIRECTIONS 2 |
diff --git a/quantum/split_common/transaction_id_define.h b/quantum/split_common/transaction_id_define.h index 05b3bf7b62..5bfbe2aec7 100644 --- a/quantum/split_common/transaction_id_define.h +++ b/quantum/split_common/transaction_id_define.h | |||
| @@ -31,7 +31,7 @@ enum serial_transaction_id { | |||
| 31 | #ifdef ENCODER_ENABLE | 31 | #ifdef ENCODER_ENABLE |
| 32 | GET_ENCODERS_CHECKSUM, | 32 | GET_ENCODERS_CHECKSUM, |
| 33 | GET_ENCODERS_DATA, | 33 | GET_ENCODERS_DATA, |
| 34 | PUT_ENCODER_TAIL, | 34 | CMD_ENCODER_DRAIN, |
| 35 | #endif // ENCODER_ENABLE | 35 | #endif // ENCODER_ENABLE |
| 36 | 36 | ||
| 37 | #ifndef DISABLE_SYNC_TIMER | 37 | #ifndef DISABLE_SYNC_TIMER |
diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c index 2cfa83e7a3..33bc9e9f57 100644 --- a/quantum/split_common/transactions.c +++ b/quantum/split_common/transactions.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | #include <stdint.h> | ||
| 17 | #include <string.h> | 18 | #include <string.h> |
| 18 | #include <stddef.h> | 19 | #include <stddef.h> |
| 19 | 20 | ||
| @@ -80,8 +81,12 @@ | |||
| 80 | { 0, 0, sizeof_member(split_shared_memory_t, member), offsetof(split_shared_memory_t, member), cb } | 81 | { 0, 0, sizeof_member(split_shared_memory_t, member), offsetof(split_shared_memory_t, member), cb } |
| 81 | #define trans_target2initiator_initializer(member) trans_target2initiator_initializer_cb(member, NULL) | 82 | #define trans_target2initiator_initializer(member) trans_target2initiator_initializer_cb(member, NULL) |
| 82 | 83 | ||
| 84 | #define trans_initiator2target_cb(cb) \ | ||
| 85 | { 0, 0, 0, 0, cb } | ||
| 86 | |||
| 83 | #define transport_write(id, data, length) transport_execute_transaction(id, data, length, NULL, 0) | 87 | #define transport_write(id, data, length) transport_execute_transaction(id, data, length, NULL, 0) |
| 84 | #define transport_read(id, data, length) transport_execute_transaction(id, NULL, 0, data, length) | 88 | #define transport_read(id, data, length) transport_execute_transaction(id, NULL, 0, data, length) |
| 89 | #define transport_exec(id) transport_execute_transaction(id, NULL, 0, NULL, 0) | ||
| 85 | 90 | ||
| 86 | #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) | 91 | #if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) |
| 87 | // Forward-declare the RPC callback handlers | 92 | // Forward-declare the RPC callback handlers |
| @@ -234,14 +239,26 @@ static void master_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_ro | |||
| 234 | #ifdef ENCODER_ENABLE | 239 | #ifdef ENCODER_ENABLE |
| 235 | 240 | ||
| 236 | static bool encoder_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { | 241 | static bool encoder_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { |
| 237 | static uint32_t last_update = 0; | 242 | static uint32_t last_update = 0; |
| 243 | static uint8_t last_checksum = 0; | ||
| 238 | encoder_events_t temp_events; | 244 | encoder_events_t temp_events; |
| 239 | 245 | ||
| 240 | bool okay = read_if_checksum_mismatch(GET_ENCODERS_CHECKSUM, GET_ENCODERS_DATA, &last_update, &temp_events, &split_shmem->encoders.events, sizeof(temp_events)); | 246 | bool okay = read_if_checksum_mismatch(GET_ENCODERS_CHECKSUM, GET_ENCODERS_DATA, &last_update, &temp_events, &split_shmem->encoders.events, sizeof(temp_events)); |
| 241 | if (okay) { | 247 | if (okay) { |
| 242 | encoder_handle_slave_events(&split_shmem->encoders.events); | 248 | if (last_checksum != split_shmem->encoders.checksum) { |
| 243 | transport_write(PUT_ENCODER_TAIL, &split_shmem->encoders.events.tail, sizeof(split_shmem->encoders.events.tail)); | 249 | bool actioned = false; |
| 244 | split_shmem->encoders.checksum = crc8(&split_shmem->encoders.events, sizeof(split_shmem->encoders.events)); | 250 | uint8_t index; |
| 251 | bool clockwise; | ||
| 252 | while (okay && encoder_dequeue_event_advanced(&split_shmem->encoders.events, &index, &clockwise)) { | ||
| 253 | okay &= encoder_queue_event(index, clockwise); | ||
| 254 | actioned = true; | ||
| 255 | } | ||
| 256 | |||
| 257 | if (actioned) { | ||
| 258 | okay &= transport_exec(CMD_ENCODER_DRAIN); | ||
| 259 | } | ||
| 260 | last_checksum = split_shmem->encoders.checksum; | ||
| 261 | } | ||
| 245 | } | 262 | } |
| 246 | return okay; | 263 | return okay; |
| 247 | } | 264 | } |
| @@ -253,9 +270,8 @@ static void encoder_handlers_slave(matrix_row_t master_matrix[], matrix_row_t sl | |||
| 253 | split_shmem->encoders.checksum = crc8(&split_shmem->encoders.events, sizeof(split_shmem->encoders.events)); | 270 | split_shmem->encoders.checksum = crc8(&split_shmem->encoders.events, sizeof(split_shmem->encoders.events)); |
| 254 | } | 271 | } |
| 255 | 272 | ||
| 256 | static void encoder_handlers_slave_reset(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { | 273 | static void encoder_handlers_slave_drain(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { |
| 257 | uint8_t tail_index = *(uint8_t *)initiator2target_buffer; | 274 | encoder_signal_queue_drain(); |
| 258 | encoder_set_tail_index(tail_index); | ||
| 259 | } | 275 | } |
| 260 | 276 | ||
| 261 | // clang-format off | 277 | // clang-format off |
| @@ -264,7 +280,7 @@ static void encoder_handlers_slave_reset(uint8_t initiator2target_buffer_size, c | |||
| 264 | # define TRANSACTIONS_ENCODERS_REGISTRATIONS \ | 280 | # define TRANSACTIONS_ENCODERS_REGISTRATIONS \ |
| 265 | [GET_ENCODERS_CHECKSUM] = trans_target2initiator_initializer(encoders.checksum), \ | 281 | [GET_ENCODERS_CHECKSUM] = trans_target2initiator_initializer(encoders.checksum), \ |
| 266 | [GET_ENCODERS_DATA] = trans_target2initiator_initializer(encoders.events), \ | 282 | [GET_ENCODERS_DATA] = trans_target2initiator_initializer(encoders.events), \ |
| 267 | [PUT_ENCODER_TAIL] = trans_initiator2target_initializer_cb(encoders.events.tail, encoder_handlers_slave_reset), | 283 | [CMD_ENCODER_DRAIN] = trans_initiator2target_cb(encoder_handlers_slave_drain), |
| 268 | // clang-format on | 284 | // clang-format on |
| 269 | 285 | ||
| 270 | #else // ENCODER_ENABLE | 286 | #else // ENCODER_ENABLE |
