X-Git-Url: https://git.friedersdorff.com/?a=blobdiff_plain;f=tmk_core%2Fprotocol%2Fchibios%2Fusb_main.c;h=106ce0879dbbfcd2dc7e316cae1d2120c735d438;hb=3fe8e1c238fc8e15dacda1b03c0c1745a7b8e8e7;hp=9097d4e844ca58c075088bc504ac9c0113bb8de1;hpb=b1b30f167587349acbb7dc4f286a8742b8b63d00;p=max%2Ftmk_keyboard.git diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index 9097d4e8..106ce087 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -27,15 +27,34 @@ #include "sleep_led.h" #include "led.h" #endif +#include "hook.h" + +/* TMK hooks */ +__attribute__((weak)) +void hook_usb_wakeup(void) { +#ifdef SLEEP_LED_ENABLE + sleep_led_disable(); + // NOTE: converters may not accept this + led_set(host_keyboard_leds()); +#endif /* SLEEP_LED_ENABLE */ +} + + __attribute__((weak)) +void hook_usb_suspend_entry(void) { +#ifdef SLEEP_LED_ENABLE + sleep_led_enable(); +#endif /* SLEEP_LED_ENABLE */ +} + /* --------------------------------------------------------- * Global interface variables and declarations * --------------------------------------------------------- */ -uint8_t keyboard_idle = 0; -uint8_t keyboard_protocol = 1; -uint16_t keyboard_led_stats = 0; +uint8_t keyboard_idle __attribute__((aligned(2))) = 0; +uint8_t keyboard_protocol __attribute__((aligned(2))) = 1; +uint16_t keyboard_led_stats __attribute__((aligned(2))) = 0; volatile uint16_t keyboard_idle_count = 0; static virtual_timer_t keyboard_idle_timer; static void keyboard_idle_timer_cb(void *arg); @@ -795,19 +814,13 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) { case USB_EVENT_SUSPEND: //TODO: from ISR! print("[S]"); -#ifdef SLEEP_LED_ENABLE - sleep_led_enable(); -#endif /* SLEEP_LED_ENABLE */ + hook_usb_suspend_entry(); return; case USB_EVENT_WAKEUP: //TODO: from ISR! print("[W]"); suspend_wakeup_init(); -#ifdef SLEEP_LED_ENABLE - sleep_led_disable(); - // NOTE: converters may not accept this - led_set(host_keyboard_leds()); -#endif /* SLEEP_LED_ENABLE */ + hook_usb_wakeup(); return; case USB_EVENT_STALLED: @@ -1094,7 +1107,9 @@ static void keyboard_idle_timer_cb(void *arg) { if(keyboard_idle) { #endif /* NKRO_ENABLE */ /* TODO: are we sure we want the KBD_ENDPOINT? */ - usbStartTransmitI(usbp, KBD_ENDPOINT, (uint8_t *)&keyboard_report_sent, sizeof(keyboard_report_sent)); + if(!usbGetTransmitStatusI(usbp, KBD_ENDPOINT)) { + usbStartTransmitI(usbp, KBD_ENDPOINT, (uint8_t *)&keyboard_report_sent, KBD_EPSIZE); + } /* rearm the timer */ chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp); } @@ -1127,8 +1142,13 @@ void send_keyboard(report_keyboard_t *report) { * this is more efficient */ /* busy wait, should be short and not very common */ osalSysLock(); - while(usbGetTransmitStatusI(&USB_DRIVER, NKRO_ENDPOINT)) - ; + if(usbGetTransmitStatusI(&USB_DRIVER, NKRO_ENDPOINT)) { + /* Need to either suspend, or loop and call unlock/lock during + * every iteration - otherwise the system will remain locked, + * no interrupts served, so USB not going through as well. + * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ + osalThreadSuspendS(&(&USB_DRIVER)->epc[NKRO_ENDPOINT]->in_state->thread); + } usbStartTransmitI(&USB_DRIVER, NKRO_ENDPOINT, (uint8_t *)report, sizeof(report_keyboard_t)); osalSysUnlock(); } else @@ -1137,8 +1157,13 @@ void send_keyboard(report_keyboard_t *report) { /* need to wait until the previous packet has made it through */ /* busy wait, should be short and not very common */ osalSysLock(); - while(usbGetTransmitStatusI(&USB_DRIVER, KBD_ENDPOINT)) - ; + if(usbGetTransmitStatusI(&USB_DRIVER, KBD_ENDPOINT)) { + /* Need to either suspend, or loop and call unlock/lock during + * every iteration - otherwise the system will remain locked, + * no interrupts served, so USB not going through as well. + * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ + osalThreadSuspendS(&(&USB_DRIVER)->epc[KBD_ENDPOINT]->in_state->thread); + } usbStartTransmitI(&USB_DRIVER, KBD_ENDPOINT, (uint8_t *)report, KBD_EPSIZE); osalSysUnlock(); } @@ -1338,7 +1363,7 @@ int8_t sendchar(uint8_t c) { return 0; } osalSysUnlock(); - /* Timeout after 5us if the queue is full. + /* Timeout after 100us if the queue is full. * Increase this timeout if too much stuff is getting * dropped (i.e. the buffer is getting full too fast * for USB/HIDRAW to dequeue). Another possibility