diff options
Diffstat (limited to 'tmk_core/protocol')
| -rw-r--r-- | tmk_core/protocol/adb.c | 256 | ||||
| -rw-r--r-- | tmk_core/protocol/adb.h | 58 | ||||
| -rw-r--r-- | tmk_core/protocol/arm_atsam/i2c_master.c | 3 | ||||
| -rw-r--r-- | tmk_core/protocol/arm_atsam/i2c_master.h | 4 | ||||
| -rw-r--r-- | tmk_core/protocol/arm_atsam/main_arm_atsam.c | 4 | ||||
| -rw-r--r-- | tmk_core/protocol/chibios/main.c | 3 | ||||
| -rw-r--r-- | tmk_core/protocol/chibios/usb_main.c | 95 | ||||
| -rw-r--r-- | tmk_core/protocol/chibios/usb_main.h | 11 | ||||
| -rw-r--r-- | tmk_core/protocol/lufa/lufa.c | 25 | ||||
| -rw-r--r-- | tmk_core/protocol/m0110.c | 8 | ||||
| -rw-r--r-- | tmk_core/protocol/ps2_mouse.c | 2 | ||||
| -rw-r--r-- | tmk_core/protocol/usb_descriptor.c | 12 | ||||
| -rw-r--r-- | tmk_core/protocol/vusb/main.c | 7 | ||||
| -rw-r--r-- | tmk_core/protocol/vusb/vusb.c | 10 | 
14 files changed, 359 insertions, 139 deletions
| diff --git a/tmk_core/protocol/adb.c b/tmk_core/protocol/adb.c index a23c919619..367f1b09fa 100644 --- a/tmk_core/protocol/adb.c +++ b/tmk_core/protocol/adb.c @@ -1,5 +1,5 @@  /* -Copyright 2011 Jun WAKO <wakojun@gmail.com> +Copyright 2011-19 Jun WAKO <wakojun@gmail.com>  Copyright 2013 Shay Green <gblargg@gmail.com>  This software is licensed with a Modified BSD License. @@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.  #include <avr/io.h>  #include <avr/interrupt.h>  #include "adb.h" +#include "print.h"  // GCC doesn't inline functions normally  #define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT)) @@ -59,7 +60,6 @@ static inline void     place_bit1(void);  static inline void     send_byte(uint8_t data);  static inline uint16_t wait_data_lo(uint16_t us);  static inline uint16_t wait_data_hi(uint16_t us); -static inline uint16_t adb_host_dev_recv(uint8_t device);  void adb_host_init(void) {      ADB_PORT &= ~(1 << ADB_DATA_BIT); @@ -81,119 +81,164 @@ bool adb_host_psw(void) { return psw_in(); }   * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>   * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>   */ - -// ADB Bit Cells -// -// bit cell time: 70-130us -// low part of bit0: 60-70% of bit cell -// low part of bit1: 30-40% of bit cell -// -//    bit cell time         70us        130us -//    -------------------------------------------- -//    low  part of bit0     42-49       78-91 -//    high part of bit0     21-28       39-52 -//    low  part of bit1     21-28       39-52 -//    high part of bit1     42-49       78-91 -// -// -// bit0: -//    70us bit cell: -//      ____________~~~~~~ -//      42-49        21-28 -// -//    130us bit cell: -//      ____________~~~~~~ -//      78-91        39-52 -// -// bit1: -//    70us bit cell: -//      ______~~~~~~~~~~~~ -//      21-28        42-49 -// -//    130us bit cell: -//      ______~~~~~~~~~~~~ -//      39-52        78-91 -// -// [from Apple IIgs Hardware Reference Second Edition] - -enum { ADDR_KEYB = 0x20, ADDR_MOUSE = 0x30 }; - -uint16_t adb_host_kbd_recv(void) { return adb_host_dev_recv(ADDR_KEYB); } +uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); }  #ifdef ADB_MOUSE_ENABLE -void adb_mouse_init(void) { return; } +__attribute__((weak)) void adb_mouse_init(void) { return; } + +__attribute__((weak)) void adb_mouse_task(void) { return; } -uint16_t adb_host_mouse_recv(void) { return adb_host_dev_recv(ADDR_MOUSE); } +uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); }  #endif -static inline uint16_t adb_host_dev_recv(uint8_t device) { -    uint16_t data = 0; +// This sends Talk command to read data from register and returns length of the data. +uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) { +    for (int8_t i = 0; i < len; i++) buf[i] = 0; +      cli();      attention(); -    send_byte(device | 0x0C);  // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00) -    place_bit0();              // Stopbit(0) +    send_byte((addr << 4) | ADB_CMD_TALK | reg); +    place_bit0();  // Stopbit(0) +    // TODO: Service Request(Srq): +    // Device holds low part of comannd stopbit for 140-260us +    // +    // Command: +    // ......._     ______________________    ___ ............_     ------- +    //         |   |                      |  |   |             |   | +    // Command |   |                      |  |   | Data bytes  |   | +    // ........|___|  |     140-260       |__|   |_............|___| +    //         |stop0 | Tlt Stop-to-Start |start1|             |stop0 | +    // +    // Command without data: +    // ......._     __________________________ +    //         |   | +    // Command |   | +    // ........|___|  |     140-260       | +    //         |stop0 | Tlt Stop-to-Start | +    // +    // Service Request: +    // ......._                     ______    ___ ............_     ------- +    //         |     140-260       |      |  |   |             |   | +    // Command |  Service Request  |      |  |   | Data bytes  |   | +    // ........|___________________|      |__|   |_............|___| +    //         |stop0 |                   |start1|             |stop0 | +    // ......._                     __________ +    //         |     140-260       | +    // Command |  Service Request  | +    // ........|___________________| +    //         |stop0 | +    // This can be happened? +    // ......._     ______________________    ___ ............_                   ----- +    //         |   |                      |  |   |             |    140-260      | +    // Command |   |                      |  |   | Data bytes  | Service Request | +    // ........|___|  |     140-260       |__|   |_............|_________________| +    //         |stop0 | Tlt Stop-to-Start |start1|             |stop0 | +    // +    // "Service requests are issued by the devices during a very specific time at the +    // end of the reception of the command packet. +    // If a device in need of service issues a service request, it must do so within +    // the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs." +    // +    // "A device sends a Service Request signal by holding the bus low during the low +    // portion of the stop bit of any command or data transaction. The device must lengthen +    // the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15." +    // http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf      if (!wait_data_hi(500)) {  // Service Request(310us Adjustable Keyboard): just ignored +        xprintf("R");          sei(); -        return -30;  // something wrong +        return 0;      }      if (!wait_data_lo(500)) {  // Tlt/Stop to Start(140-260us)          sei(); -        return 0;  // No data to send +        return 0;  // No data from device(not error); +    } + +    // start bit(1) +    if (!wait_data_hi(40)) { +        xprintf("S"); +        sei(); +        return 0; +    } +    if (!wait_data_lo(100)) { +        xprintf("s"); +        sei(); +        return 0;      } -    uint8_t n = 17;  // start bit + 16 data bits +    uint8_t n = 0;  // bit count      do { +        // +        // |<- bit_cell_max(130) ->| +        // |        |<-   lo     ->| +        // |        |       |<-hi->| +        //           _______ +        // |        |       | +        // | 130-lo | lo-hi | +        // |________|       | +        //          uint8_t lo = (uint8_t)wait_data_hi(130); -        if (!lo) goto error; +        if (!lo) goto error;  // no more bit or after stop bit          uint8_t hi = (uint8_t)wait_data_lo(lo); -        if (!hi) goto error; +        if (!hi) goto error;  // stop bit extedned by Srq? -        hi = lo - hi; -        lo = 130 - lo; +        if (n / 8 >= len) continue;  // can't store in buf -        data <<= 1; -        if (lo < hi) { -            data |= 1; -        } else if (n == 17) { -            sei(); -            return -20; +        buf[n / 8] <<= 1; +        if ((130 - lo) < (lo - hi)) { +            buf[n / 8] |= 1;          } -    } while (--n); - -    // Stop bit can't be checked normally since it could have service request lenghtening -    // and its high state never goes low. -    if (!wait_data_hi(351) || wait_data_lo(91)) { -        sei(); -        return -21; -    } -    sei(); -    return data; +    } while (++n);  error:      sei(); -    return -n; +    return n / 8;  } -void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) { +uint16_t adb_host_talk(uint8_t addr, uint8_t reg) { +    uint8_t len; +    uint8_t buf[8]; +    len = adb_host_talk_buf(addr, reg, buf, 8); +    if (len != 2) return 0; +    return (buf[0] << 8 | buf[1]); +} + +void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {      cli();      attention(); -    send_byte(cmd); -    place_bit0();    // Stopbit(0) +    send_byte((addr << 4) | ADB_CMD_LISTEN | reg); +    place_bit0();  // Stopbit(0) +    // TODO: Service Request      _delay_us(200);  // Tlt/Stop to Start      place_bit1();    // Startbit(1) -    send_byte(data_h); -    send_byte(data_l); +    for (int8_t i = 0; i < len; i++) { +        send_byte(buf[i]); +        // xprintf("%02X ", buf[i]); +    }      place_bit0();  // Stopbit(0);      sei();  } +void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) { +    uint8_t buf[2] = {data_h, data_l}; +    adb_host_listen_buf(addr, reg, buf, 2); +} + +void adb_host_flush(uint8_t addr) { +    cli(); +    attention(); +    send_byte((addr << 4) | ADB_CMD_FLUSH); +    place_bit0();    // Stopbit(0) +    _delay_us(200);  // Tlt/Stop to Start +    sei(); +} +  // send state of LEDs  void adb_host_kbd_led(uint8_t led) { -    // Addr:Keyboard(0010), Cmd:Listen(10), Register2(10) -    // send upper byte (not used) -    // send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0: -    adb_host_listen(0x2A, 0, led & 0x07); +    // Listen Register2 +    //  upper byte: not used +    //  lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock +    adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07);  }  #ifdef ADB_PSW_BIT @@ -327,7 +372,7 @@ Commands      bits                commands      ------------------------------------------------------ -    - - - - 0 0 0 0     Send Request(reset all devices) +    - - - - 0 0 0 0     Send Reset(reset all devices)      A A A A 0 0 0 1     Flush(reset a device)      - - - - 0 0 1 0     Reserved      - - - - 0 0 1 1     Reserved @@ -435,5 +480,56 @@ Keyboard LEDs & state of keys(Register2)       | +-----------------------------   Delete       +-------------------------------   Reserved +Address, Handler ID and bits(Register3) +    1514131211 . . 8 7 . . . . . . 0 +     | | | | | | | | | | | | | | | | +     | | | | | | | | +-+-+-+-+-+-+-+-   Handler ID +     | | | | +-+-+-+-----------------   Address +     | | | +-------------------------   0 +     | | +---------------------------   Service request enable(1 = enabled) +     | +-----------------------------   Exceptional event(alwyas 1 if not used) +     +-------------------------------   0 + +ADB Bit Cells +    bit cell time: 70-130us +    low part of bit0: 60-70% of bit cell +    low part of bit1: 30-40% of bit cell + +       bit cell time         70us        130us +       -------------------------------------------- +       low  part of bit0     42-49       78-91 +       high part of bit0     21-28       39-52 +       low  part of bit1     21-28       39-52 +       high part of bit1     42-49       78-91 + + +    bit0: +       70us bit cell: +         ____________~~~~~~ +         42-49        21-28 + +       130us bit cell: +         ____________~~~~~~ +         78-91        39-52 + +    bit1: +       70us bit cell: +         ______~~~~~~~~~~~~ +         21-28        42-49 + +       130us bit cell: +         ______~~~~~~~~~~~~ +         39-52        78-91 + +    [from Apple IIgs Hardware Reference Second Edition] + +Keyboard Handle ID +    Apple Standard Keyboard M0116:      0x01 +    Apple Extended Keyboard M0115:      0x02 +    Apple Extended Keyboard II M3501:   0x02 +    Apple Adjustable Keybaord:          0x10 + +    http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802 +  END_OF_ADB  */ diff --git a/tmk_core/protocol/adb.h b/tmk_core/protocol/adb.h index 34cbcf7691..fe8becc2d5 100644 --- a/tmk_core/protocol/adb.h +++ b/tmk_core/protocol/adb.h @@ -1,5 +1,5 @@  /* -Copyright 2011 Jun WAKO <wakojun@gmail.com> +Copyright 2011-19 Jun WAKO <wakojun@gmail.com>  This software is licensed with a Modified BSD License.  All of this is supposed to be Free Software, Open Source, DFSG-free, @@ -47,12 +47,60 @@ POSSIBILITY OF SUCH DAMAGE.  #define ADB_POWER 0x7F  #define ADB_CAPS 0x39 +/* ADB commands */ +// Default Address +#define ADB_ADDR_0 0 +#define ADB_ADDR_DONGLE 1 +#define ADB_ADDR_KEYBOARD 2 +#define ADB_ADDR_MOUSE 3 +#define ADB_ADDR_TABLET 4 +#define ADB_ADDR_APPLIANCE 7 +#define ADB_ADDR_8 8 +#define ADB_ADDR_9 9 +#define ADB_ADDR_10 10 +#define ADB_ADDR_11 11 +#define ADB_ADDR_12 12 +#define ADB_ADDR_13 13 +#define ADB_ADDR_14 14 +#define ADB_ADDR_15 15 +// for temporary purpose, do not use for polling +#define ADB_ADDR_TMP 15 +#define ADB_ADDR_MOUSE_POLL 10 +// Command Type +#define ADB_CMD_RESET 0 +#define ADB_CMD_FLUSH 1 +#define ADB_CMD_LISTEN 8 +#define ADB_CMD_TALK 12 +// Register +#define ADB_REG_0 0 +#define ADB_REG_1 1 +#define ADB_REG_2 2 +#define ADB_REG_3 3 + +/* ADB keyboard handler id */ +#define ADB_HANDLER_STD 0x01        /* IIGS, M0116 */ +#define ADB_HANDLER_AEK 0x02        /* M0115, M3501 */ +#define ADB_HANDLER_AEK_RMOD 0x03   /* M0115, M3501, alternate mode enableing right modifiers */ +#define ADB_HANDLER_STD_ISO 0x04    /* M0118, ISO swapping keys */ +#define ADB_HANDLER_AEK_ISO 0x05    /* M0115, M3501, ISO swapping keys */ +#define ADB_HANDLER_M1242_ANSI 0x10 /* Adjustable keyboard */ +#define ADB_HANDLER_CLASSIC1_MOUSE 0x01 +#define ADB_HANDLER_CLASSIC2_MOUSE 0x02 +#define ADB_HANDLER_EXTENDED_MOUSE 0x04 +#define ADB_HANDLER_TURBO_MOUSE 0x32 +  // ADB host  void     adb_host_init(void);  bool     adb_host_psw(void); +uint16_t adb_host_talk(uint8_t addr, uint8_t reg); +uint8_t  adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len); +void     adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l); +void     adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len); +void     adb_host_flush(uint8_t addr); +void     adb_host_kbd_led(uint8_t led);  uint16_t adb_host_kbd_recv(void);  uint16_t adb_host_mouse_recv(void); -void     adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l); -void     adb_host_kbd_led(uint8_t led); -void     adb_mouse_task(void); -void     adb_mouse_init(void); + +// ADB Mouse +void adb_mouse_task(void); +void adb_mouse_init(void); diff --git a/tmk_core/protocol/arm_atsam/i2c_master.c b/tmk_core/protocol/arm_atsam/i2c_master.c index d3319ab447..dda2f85b00 100644 --- a/tmk_core/protocol/arm_atsam/i2c_master.c +++ b/tmk_core/protocol/arm_atsam/i2c_master.c @@ -28,6 +28,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #    define I2C_LED_USE_DMA 1  // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers +DmacDescriptor dmac_desc; +DmacDescriptor dmac_desc_wb; +  static uint8_t i2c_led_q[I2C_Q_SIZE];  // I2C queue circular buffer  static uint8_t i2c_led_q_s;            // Start of circular buffer  static uint8_t i2c_led_q_e;            // End of circular buffer diff --git a/tmk_core/protocol/arm_atsam/i2c_master.h b/tmk_core/protocol/arm_atsam/i2c_master.h index 44dbdfbffa..68773f213f 100644 --- a/tmk_core/protocol/arm_atsam/i2c_master.h +++ b/tmk_core/protocol/arm_atsam/i2c_master.h @@ -24,8 +24,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.  #    include "issi3733_driver.h"  #    include "config.h" -__attribute__((__aligned__(16))) DmacDescriptor dmac_desc; -__attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb; +extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc; +extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;  uint8_t I2C3733_Init_Control(void);  uint8_t I2C3733_Init_Drivers(void); diff --git a/tmk_core/protocol/arm_atsam/main_arm_atsam.c b/tmk_core/protocol/arm_atsam/main_arm_atsam.c index e10be52fb8..e4e79d3510 100644 --- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c +++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c @@ -305,10 +305,6 @@ int main(void) {              // dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired);          }  #endif  // CONSOLE_ENABLE - -        // Run housekeeping -        housekeeping_task_kb(); -        housekeeping_task_user();      }      return 1; diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c index e07c181fc8..63e4c99d21 100644 --- a/tmk_core/protocol/chibios/main.c +++ b/tmk_core/protocol/chibios/main.c @@ -163,6 +163,7 @@ int main(void) {      keyboard_setup();      /* Init USB */ +    usb_event_queue_init();      init_usb_driver(&USB_DRIVER);  #ifdef MIDI_ENABLE @@ -221,6 +222,8 @@ int main(void) {      /* Main loop */      while (true) { +        usb_event_queue_task(); +  #if !defined(NO_USB_STARTUP_CHECK)          if (USB_DRIVER.state == USB_SUSPENDED) {              print("[s]"); diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c index ad489fb916..8adecfa719 100644 --- a/tmk_core/protocol/chibios/usb_main.c +++ b/tmk_core/protocol/chibios/usb_main.c @@ -27,6 +27,7 @@  #include <ch.h>  #include <hal.h> +#include <string.h>  #include "usb_main.h" @@ -368,6 +369,69 @@ static usb_driver_configs_t drivers = {   * ---------------------------------------------------------   */ +#define USB_EVENT_QUEUE_SIZE 16 +usbevent_t event_queue[USB_EVENT_QUEUE_SIZE]; +uint8_t    event_queue_head; +uint8_t    event_queue_tail; + +void usb_event_queue_init(void) { +    // Initialise the event queue +    memset(&event_queue, 0, sizeof(event_queue)); +    event_queue_head = 0; +    event_queue_tail = 0; +} + +static inline bool usb_event_queue_enqueue(usbevent_t event) { +    uint8_t next = (event_queue_head + 1) % USB_EVENT_QUEUE_SIZE; +    if (next == event_queue_tail) { +        return false; +    } +    event_queue[event_queue_head] = event; +    event_queue_head              = next; +    return true; +} + +static inline bool usb_event_queue_dequeue(usbevent_t *event) { +    if (event_queue_head == event_queue_tail) { +        return false; +    } +    *event           = event_queue[event_queue_tail]; +    event_queue_tail = (event_queue_tail + 1) % USB_EVENT_QUEUE_SIZE; +    return true; +} + +static inline void usb_event_suspend_handler(void) { +#ifdef SLEEP_LED_ENABLE +    sleep_led_enable(); +#endif /* SLEEP_LED_ENABLE */ +} + +static inline void usb_event_wakeup_handler(void) { +    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 */ +} + +void usb_event_queue_task(void) { +    usbevent_t event; +    while (usb_event_queue_dequeue(&event)) { +        switch (event) { +            case USB_EVENT_SUSPEND: +                usb_event_suspend_handler(); +                break; +            case USB_EVENT_WAKEUP: +                usb_event_wakeup_handler(); +                break; +            default: +                // Nothing to do, we don't handle it. +                break; +        } +    } +} +  /* Handles the USB driver global events   * TODO: maybe disable some things when connection is lost? */  static void usb_event_cb(USBDriver *usbp, usbevent_t event) { @@ -402,9 +466,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {              osalSysUnlockFromISR();              return;          case USB_EVENT_SUSPEND: -#ifdef SLEEP_LED_ENABLE -            sleep_led_enable(); -#endif /* SLEEP_LED_ENABLE */ +            usb_event_queue_enqueue(USB_EVENT_SUSPEND);              /* Falls into.*/          case USB_EVENT_UNCONFIGURED:              /* Falls into.*/ @@ -425,12 +487,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {                  qmkusbWakeupHookI(&drivers.array[i].driver);                  chSysUnlockFromISR();              } -            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 */ +            usb_event_queue_enqueue(USB_EVENT_WAKEUP);              return;          case USB_EVENT_STALLED: @@ -651,6 +708,17 @@ void init_usb_driver(USBDriver *usbp) {  void restart_usb_driver(USBDriver *usbp) {      usbStop(usbp);      usbDisconnectBus(usbp); + +#if USB_SUSPEND_WAKEUP_DELAY > 0 +    // Some hubs, kvm switches, and monitors do +    // weird things, with USB device state bouncing +    // around wildly on wakeup, yielding race +    // conditions that can corrupt the keyboard state. +    // +    // Pause for a while to let things settle... +    wait_ms(USB_SUSPEND_WAKEUP_DELAY); +#endif +      usbStart(usbp, &usbcfg);      usbConnectBus(usbp);  } @@ -806,7 +874,7 @@ void send_mouse(report_mouse_t *report) {  }  #else  /* MOUSE_ENABLE */ -void   send_mouse(report_mouse_t *report) { (void)report; } +void send_mouse(report_mouse_t *report) { (void)report; }  #endif /* MOUSE_ENABLE */  /* --------------------------------------------------------- @@ -885,15 +953,8 @@ void console_task(void) {      } while (size > 0);  } -#else  /* CONSOLE_ENABLE */ -int8_t sendchar(uint8_t c) { -    (void)c; -    return 0; -}  #endif /* CONSOLE_ENABLE */ -void _putchar(char character) { sendchar(character); } -  #ifdef RAW_ENABLE  void raw_hid_send(uint8_t *data, uint8_t length) {      // TODO: implement variable size packet diff --git a/tmk_core/protocol/chibios/usb_main.h b/tmk_core/protocol/chibios/usb_main.h index eaa08d8f79..fb33c8cd0f 100644 --- a/tmk_core/protocol/chibios/usb_main.h +++ b/tmk_core/protocol/chibios/usb_main.h @@ -38,6 +38,17 @@ void init_usb_driver(USBDriver *usbp);  void restart_usb_driver(USBDriver *usbp);  /* --------------- + * USB Event queue + * --------------- + */ + +/* Initialisation of the FIFO */ +void usb_event_queue_init(void); + +/* Task to dequeue and execute any handlers for the USB events on the main thread */ +void usb_event_queue_task(void); + +/* ---------------   * Keyboard header   * ---------------   */ diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 623aa33ff5..bd9daaac90 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -435,7 +435,9 @@ void EVENT_USB_Device_Suspend() {   */  void EVENT_USB_Device_WakeUp() {      print("[W]"); +#if defined(NO_USB_STARTUP_CHECK)      suspend_wakeup_init(); +#endif  #ifdef SLEEP_LED_ENABLE      sleep_led_disable(); @@ -1023,7 +1025,6 @@ static void setup_usb(void) {      // for Console_Task      USB_Device_EnableSOFEvents(); -    print_set_sendchar(sendchar);  }  /** \brief Main @@ -1073,12 +1074,26 @@ int main(void) {      print("Keyboard start.\n");      while (1) {  #if !defined(NO_USB_STARTUP_CHECK) -        while (USB_DeviceState == DEVICE_STATE_Suspended) { +        if (USB_DeviceState == DEVICE_STATE_Suspended) {              print("[s]"); -            suspend_power_down(); -            if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { -                USB_Device_SendRemoteWakeup(); +            while (USB_DeviceState == DEVICE_STATE_Suspended) { +                suspend_power_down(); +                if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { +                    USB_Device_SendRemoteWakeup(); +                    clear_keyboard(); + +#    if USB_SUSPEND_WAKEUP_DELAY > 0 +                    // Some hubs, kvm switches, and monitors do +                    // weird things, with USB device state bouncing +                    // around wildly on wakeup, yielding race +                    // conditions that can corrupt the keyboard state. +                    // +                    // Pause for a while to let things settle... +                    wait_ms(USB_SUSPEND_WAKEUP_DELAY); +#    endif +                }              } +            suspend_wakeup_init();          }  #endif diff --git a/tmk_core/protocol/m0110.c b/tmk_core/protocol/m0110.c index b02a6933d2..64f2fa50ab 100644 --- a/tmk_core/protocol/m0110.c +++ b/tmk_core/protocol/m0110.c @@ -95,11 +95,11 @@ void m0110_init(void) {          uint8_t data;          m0110_send(M0110_MODEL);          data = m0110_recv(); -        print("m0110_init model: "); phex(data); print("\n"); +        print("m0110_init model: "); print_hex8(data); print("\n");          m0110_send(M0110_TEST);          data = m0110_recv(); -        print("m0110_init test: "); phex(data); print("\n"); +        print("m0110_init test: "); print_hex8(data); print("\n");      */  } @@ -122,7 +122,7 @@ uint8_t m0110_send(uint8_t data) {      return 1;  ERROR:      print("m0110_send err: "); -    phex(m0110_error); +    print_hex8(m0110_error);      print("\n");      _delay_ms(500);      idle(); @@ -146,7 +146,7 @@ uint8_t m0110_recv(void) {      return data;  ERROR:      print("m0110_recv err: "); -    phex(m0110_error); +    print_hex8(m0110_error);      print("\n");      _delay_ms(500);      idle(); diff --git a/tmk_core/protocol/ps2_mouse.c b/tmk_core/protocol/ps2_mouse.c index 8df465026b..5415453a05 100644 --- a/tmk_core/protocol/ps2_mouse.c +++ b/tmk_core/protocol/ps2_mouse.c @@ -190,7 +190,7 @@ static inline void ps2_mouse_clear_report(report_mouse_t *mouse_report) {  static inline void ps2_mouse_print_report(report_mouse_t *mouse_report) {      if (!debug_mouse) return;      print("ps2_mouse: ["); -    phex(mouse_report->buttons); +    print_hex8(mouse_report->buttons);      print("|");      print_hex8((uint8_t)mouse_report->x);      print(" "); diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c index 7ea4b2e37c..ba7760f283 100644 --- a/tmk_core/protocol/usb_descriptor.c +++ b/tmk_core/protocol/usb_descriptor.c @@ -116,19 +116,15 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {  #    endif          HID_RI_USAGE(8, 0x01),             // Pointer          HID_RI_COLLECTION(8, 0x00),        // Physical -            // Buttons (5 bits) +            // Buttons (8 bits)              HID_RI_USAGE_PAGE(8, 0x09),    // Button              HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1 -            HID_RI_USAGE_MAXIMUM(8, 0x05), // Button 5 +            HID_RI_USAGE_MAXIMUM(8, 0x08), // Button 8              HID_RI_LOGICAL_MINIMUM(8, 0x00),              HID_RI_LOGICAL_MAXIMUM(8, 0x01), -            HID_RI_REPORT_COUNT(8, 0x05), +            HID_RI_REPORT_COUNT(8, 0x08),              HID_RI_REPORT_SIZE(8, 0x01),              HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), -            // Button padding (3 bits) -            HID_RI_REPORT_COUNT(8, 0x01), -            HID_RI_REPORT_SIZE(8, 0x03), -            HID_RI_INPUT(8, HID_IOF_CONSTANT),              // X/Y position (2 bytes)              HID_RI_USAGE_PAGE(8, 0x01),    // Generic Desktop @@ -356,7 +352,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {          .Type                   = DTYPE_Device      },      .USBSpecification           = VERSION_BCD(1, 1, 0), -     +  #if VIRTSER_ENABLE      .Class                      = USB_CSCP_IADDeviceClass,      .SubClass                   = USB_CSCP_IADDeviceSubclass, diff --git a/tmk_core/protocol/vusb/main.c b/tmk_core/protocol/vusb/main.c index 2e8bb2fbbc..3f93ef6d24 100644 --- a/tmk_core/protocol/vusb/main.c +++ b/tmk_core/protocol/vusb/main.c @@ -74,12 +74,7 @@ static void usb_remote_wakeup(void) {   *   * FIXME: Needs doc   */ -static void setup_usb(void) { -    initForUsbConnectivity(); - -    // for Console_Task -    print_set_sendchar(sendchar); -} +static void setup_usb(void) { initForUsbConnectivity(); }  /** \brief Main   * diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c index a422903ccf..9362fbde78 100644 --- a/tmk_core/protocol/vusb/vusb.c +++ b/tmk_core/protocol/vusb/vusb.c @@ -444,19 +444,15 @@ const PROGMEM uchar shared_hid_report[] = {      0x85, REPORT_ID_MOUSE,  //   Report ID      0x09, 0x01,             //   Usage (Pointer)      0xA1, 0x00,             //   Collection (Physical) -    // Buttons (5 bits) +    // Buttons (8 bits)      0x05, 0x09,  //     Usage Page (Button)      0x19, 0x01,  //     Usage Minimum (Button 1) -    0x29, 0x05,  //     Usage Maximum (Button 5) +    0x29, 0x08,  //     Usage Maximum (Button 8)      0x15, 0x00,  //     Logical Minimum (0)      0x25, 0x01,  //     Logical Maximum (1) -    0x95, 0x05,  //     Report Count (5) +    0x95, 0x08,  //     Report Count (8)      0x75, 0x01,  //     Report Size (1)      0x81, 0x02,  //     Input (Data, Variable, Absolute) -    // Button padding (3 bits) -    0x95, 0x01,  //     Report Count (1) -    0x75, 0x03,  //     Report Size (3) -    0x81, 0x03,  //     Input (Constant)      // X/Y position (2 bytes)      0x05, 0x01,  //     Usage Page (Generic Desktop) | 
