aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/protocol/chibios
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/protocol/chibios')
-rw-r--r--tmk_core/protocol/chibios/usb_driver.c14
-rw-r--r--tmk_core/protocol/chibios/usb_main.c29
2 files changed, 27 insertions, 16 deletions
diff --git a/tmk_core/protocol/chibios/usb_driver.c b/tmk_core/protocol/chibios/usb_driver.c
index 40bfb8eb2..cc0ce7600 100644
--- a/tmk_core/protocol/chibios/usb_driver.c
+++ b/tmk_core/protocol/chibios/usb_driver.c
@@ -80,19 +80,7 @@ static bool qmkusb_start_receive(QMKUSBDriver *qmkusbp) {
80 * Interface implementation. 80 * Interface implementation.
81 */ 81 */
82 82
83static size_t _write(void *ip, const uint8_t *bp, size_t n) { 83static size_t _write(void *ip, const uint8_t *bp, size_t n) { return obqWriteTimeout(&((QMKUSBDriver *)ip)->obqueue, bp, n, TIME_INFINITE); }
84 output_buffers_queue_t *obqueue = &((QMKUSBDriver *)ip)->obqueue;
85 chSysLock();
86 const bool full = obqIsFullI(obqueue);
87 chSysUnlock();
88 if (full || bqIsSuspendedX(obqueue)) {
89 /* Discard any writes while the queue is suspended or full, i.e. the hidraw
90 interface is not open. If we tried to send with an infinite timeout, we
91 would deadlock the keyboard otherwise. */
92 return -1;
93 }
94 return obqWriteTimeout(obqueue, bp, n, TIME_INFINITE);
95}
96 84
97static size_t _read(void *ip, uint8_t *bp, size_t n) { return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp, n, TIME_INFINITE); } 85static size_t _read(void *ip, uint8_t *bp, size_t n) { return ibqReadTimeout(&((QMKUSBDriver *)ip)->ibqueue, bp, n, TIME_INFINITE); }
98 86
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index 8adecfa71..0703cdc71 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -930,9 +930,32 @@ void send_consumer(uint16_t data) {
930#ifdef CONSOLE_ENABLE 930#ifdef CONSOLE_ENABLE
931 931
932int8_t sendchar(uint8_t c) { 932int8_t sendchar(uint8_t c) {
933 // The previous implmentation had timeouts, but I think it's better to just slow down 933 static bool timed_out = false;
934 // and make sure that everything is transferred, rather than dropping stuff 934 /* The `timed_out` state is an approximation of the ideal `is_listener_disconnected?` state.
935 return chnWrite(&drivers.console_driver.driver, &c, 1); 935 *
936 * When a 5ms timeout write has timed out, hid_listen is most likely not running, or not
937 * listening to this keyboard, so we go into the timed_out state. In this state we assume
938 * that hid_listen is most likely not gonna be connected to us any time soon, so it would
939 * be wasteful to write follow-up characters with a 5ms timeout, it would all add up and
940 * unncecessarily slow down the firmware. However instead of just dropping the characters,
941 * we write them with a TIME_IMMEDIATE timeout, which is a zero timeout,
942 * and this will succeed only if hid_listen gets connected again. When a write with
943 * TIME_IMMEDIATE timeout succeeds, we know that hid_listen is listening to us again, and
944 * we can go back to the timed_out = false state, and following writes will be executed
945 * with a 5ms timeout. The reason we don't just send all characters with the TIME_IMMEDIATE
946 * timeout is that this could cause bytes to be lost even if hid_listen is running, if there
947 * is a lot of data being sent over the console.
948 *
949 * This logic will work correctly as long as hid_listen is able to receive at least 200
950 * bytes per second. On a heavily overloaded machine that's so overloaded that it's
951 * unusable, and constantly swapping, hid_listen might have trouble receiving 200 bytes per
952 * second, so some bytes might be lost on the console.
953 */
954
955 const sysinterval_t timeout = timed_out ? TIME_IMMEDIATE : TIME_MS2I(5);
956 const size_t result = chnWriteTimeout(&drivers.console_driver.driver, &c, 1, timeout);
957 timed_out = (result == 0);
958 return result;
936} 959}
937 960
938// Just a dummy function for now, this could be exposed as a weak function 961// Just a dummy function for now, this could be exposed as a weak function