aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/protocol
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/protocol')
-rw-r--r--tmk_core/protocol/adb.c256
-rw-r--r--tmk_core/protocol/adb.h58
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.c3
-rw-r--r--tmk_core/protocol/arm_atsam/i2c_master.h4
-rw-r--r--tmk_core/protocol/arm_atsam/main_arm_atsam.c3
-rw-r--r--tmk_core/protocol/chibios/main.c3
-rw-r--r--tmk_core/protocol/chibios/usb_main.c86
-rw-r--r--tmk_core/protocol/chibios/usb_main.h11
-rw-r--r--tmk_core/protocol/lufa/lufa.c24
-rw-r--r--tmk_core/protocol/usb_descriptor.c12
-rw-r--r--tmk_core/protocol/vusb/vusb.c10
11 files changed, 352 insertions, 118 deletions
diff --git a/tmk_core/protocol/adb.c b/tmk_core/protocol/adb.c
index a23c91961..367f1b09f 100644
--- a/tmk_core/protocol/adb.c
+++ b/tmk_core/protocol/adb.c
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2011 Jun WAKO <wakojun@gmail.com> 2Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
3Copyright 2013 Shay Green <gblargg@gmail.com> 3Copyright 2013 Shay Green <gblargg@gmail.com>
4 4
5This software is licensed with a Modified BSD License. 5This software is licensed with a Modified BSD License.
@@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
41#include <avr/io.h> 41#include <avr/io.h>
42#include <avr/interrupt.h> 42#include <avr/interrupt.h>
43#include "adb.h" 43#include "adb.h"
44#include "print.h"
44 45
45// GCC doesn't inline functions normally 46// GCC doesn't inline functions normally
46#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT)) 47#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT))
@@ -59,7 +60,6 @@ static inline void place_bit1(void);
59static inline void send_byte(uint8_t data); 60static inline void send_byte(uint8_t data);
60static inline uint16_t wait_data_lo(uint16_t us); 61static inline uint16_t wait_data_lo(uint16_t us);
61static inline uint16_t wait_data_hi(uint16_t us); 62static inline uint16_t wait_data_hi(uint16_t us);
62static inline uint16_t adb_host_dev_recv(uint8_t device);
63 63
64void adb_host_init(void) { 64void adb_host_init(void) {
65 ADB_PORT &= ~(1 << ADB_DATA_BIT); 65 ADB_PORT &= ~(1 << ADB_DATA_BIT);
@@ -81,119 +81,164 @@ bool adb_host_psw(void) { return psw_in(); }
81 * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919> 81 * <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
82 * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139> 82 * <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
83 */ 83 */
84 84uint16_t adb_host_kbd_recv(void) { return adb_host_talk(ADB_ADDR_KEYBOARD, ADB_REG_0); }
85// ADB Bit Cells
86//
87// bit cell time: 70-130us
88// low part of bit0: 60-70% of bit cell
89// low part of bit1: 30-40% of bit cell
90//
91// bit cell time 70us 130us
92// --------------------------------------------
93// low part of bit0 42-49 78-91
94// high part of bit0 21-28 39-52
95// low part of bit1 21-28 39-52
96// high part of bit1 42-49 78-91
97//
98//
99// bit0:
100// 70us bit cell:
101// ____________~~~~~~
102// 42-49 21-28
103//
104// 130us bit cell:
105// ____________~~~~~~
106// 78-91 39-52
107//
108// bit1:
109// 70us bit cell:
110// ______~~~~~~~~~~~~
111// 21-28 42-49
112//
113// 130us bit cell:
114// ______~~~~~~~~~~~~
115// 39-52 78-91
116//
117// [from Apple IIgs Hardware Reference Second Edition]
118
119enum { ADDR_KEYB = 0x20, ADDR_MOUSE = 0x30 };
120
121uint16_t adb_host_kbd_recv(void) { return adb_host_dev_recv(ADDR_KEYB); }
122 85
123#ifdef ADB_MOUSE_ENABLE 86#ifdef ADB_MOUSE_ENABLE
124void adb_mouse_init(void) { return; } 87__attribute__((weak)) void adb_mouse_init(void) { return; }
88
89__attribute__((weak)) void adb_mouse_task(void) { return; }
125 90
126uint16_t adb_host_mouse_recv(void) { return adb_host_dev_recv(ADDR_MOUSE); } 91uint16_t adb_host_mouse_recv(void) { return adb_host_talk(ADB_ADDR_MOUSE, ADB_REG_0); }
127#endif 92#endif
128 93
129static inline uint16_t adb_host_dev_recv(uint8_t device) { 94// This sends Talk command to read data from register and returns length of the data.
130 uint16_t data = 0; 95uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
96 for (int8_t i = 0; i < len; i++) buf[i] = 0;
97
131 cli(); 98 cli();
132 attention(); 99 attention();
133 send_byte(device | 0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00) 100 send_byte((addr << 4) | ADB_CMD_TALK | reg);
134 place_bit0(); // Stopbit(0) 101 place_bit0(); // Stopbit(0)
102 // TODO: Service Request(Srq):
103 // Device holds low part of comannd stopbit for 140-260us
104 //
105 // Command:
106 // ......._ ______________________ ___ ............_ -------
107 // | | | | | | |
108 // Command | | | | | Data bytes | |
109 // ........|___| | 140-260 |__| |_............|___|
110 // |stop0 | Tlt Stop-to-Start |start1| |stop0 |
111 //
112 // Command without data:
113 // ......._ __________________________
114 // | |
115 // Command | |
116 // ........|___| | 140-260 |
117 // |stop0 | Tlt Stop-to-Start |
118 //
119 // Service Request:
120 // ......._ ______ ___ ............_ -------
121 // | 140-260 | | | | | |
122 // Command | Service Request | | | | Data bytes | |
123 // ........|___________________| |__| |_............|___|
124 // |stop0 | |start1| |stop0 |
125 // ......._ __________
126 // | 140-260 |
127 // Command | Service Request |
128 // ........|___________________|
129 // |stop0 |
130 // This can be happened?
131 // ......._ ______________________ ___ ............_ -----
132 // | | | | | | 140-260 |
133 // Command | | | | | Data bytes | Service Request |
134 // ........|___| | 140-260 |__| |_............|_________________|
135 // |stop0 | Tlt Stop-to-Start |start1| |stop0 |
136 //
137 // "Service requests are issued by the devices during a very specific time at the
138 // end of the reception of the command packet.
139 // If a device in need of service issues a service request, it must do so within
140 // the 65 µs of the Stop Bit’s low time and maintain the line low for a total of 300 µs."
141 //
142 // "A device sends a Service Request signal by holding the bus low during the low
143 // portion of the stop bit of any command or data transaction. The device must lengthen
144 // the stop by a minimum of 140 J.lS beyond its normal duration, as shown in Figure 8-15."
145 // http://ww1.microchip.com/downloads/en/AppNotes/00591b.pdf
135 if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored 146 if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
147 xprintf("R");
136 sei(); 148 sei();
137 return -30; // something wrong 149 return 0;
138 } 150 }
139 if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us) 151 if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
140 sei(); 152 sei();
141 return 0; // No data to send 153 return 0; // No data from device(not error);
154 }
155
156 // start bit(1)
157 if (!wait_data_hi(40)) {
158 xprintf("S");
159 sei();
160 return 0;
161 }
162 if (!wait_data_lo(100)) {
163 xprintf("s");
164 sei();
165 return 0;
142 } 166 }
143 167
144 uint8_t n = 17; // start bit + 16 data bits 168 uint8_t n = 0; // bit count
145 do { 169 do {
170 //
171 // |<- bit_cell_max(130) ->|
172 // | |<- lo ->|
173 // | | |<-hi->|
174 // _______
175 // | | |
176 // | 130-lo | lo-hi |
177 // |________| |
178 //
146 uint8_t lo = (uint8_t)wait_data_hi(130); 179 uint8_t lo = (uint8_t)wait_data_hi(130);
147 if (!lo) goto error; 180 if (!lo) goto error; // no more bit or after stop bit
148 181
149 uint8_t hi = (uint8_t)wait_data_lo(lo); 182 uint8_t hi = (uint8_t)wait_data_lo(lo);
150 if (!hi) goto error; 183 if (!hi) goto error; // stop bit extedned by Srq?
151 184
152 hi = lo - hi; 185 if (n / 8 >= len) continue; // can't store in buf
153 lo = 130 - lo;
154 186
155 data <<= 1; 187 buf[n / 8] <<= 1;
156 if (lo < hi) { 188 if ((130 - lo) < (lo - hi)) {
157 data |= 1; 189 buf[n / 8] |= 1;
158 } else if (n == 17) {
159 sei();
160 return -20;
161 } 190 }
162 } while (--n); 191 } while (++n);
163
164 // Stop bit can't be checked normally since it could have service request lenghtening
165 // and its high state never goes low.
166 if (!wait_data_hi(351) || wait_data_lo(91)) {
167 sei();
168 return -21;
169 }
170 sei();
171 return data;
172 192
173error: 193error:
174 sei(); 194 sei();
175 return -n; 195 return n / 8;
176} 196}
177 197
178void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) { 198uint16_t adb_host_talk(uint8_t addr, uint8_t reg) {
199 uint8_t len;
200 uint8_t buf[8];
201 len = adb_host_talk_buf(addr, reg, buf, 8);
202 if (len != 2) return 0;
203 return (buf[0] << 8 | buf[1]);
204}
205
206void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len) {
179 cli(); 207 cli();
180 attention(); 208 attention();
181 send_byte(cmd); 209 send_byte((addr << 4) | ADB_CMD_LISTEN | reg);
182 place_bit0(); // Stopbit(0) 210 place_bit0(); // Stopbit(0)
211 // TODO: Service Request
183 _delay_us(200); // Tlt/Stop to Start 212 _delay_us(200); // Tlt/Stop to Start
184 place_bit1(); // Startbit(1) 213 place_bit1(); // Startbit(1)
185 send_byte(data_h); 214 for (int8_t i = 0; i < len; i++) {
186 send_byte(data_l); 215 send_byte(buf[i]);
216 // xprintf("%02X ", buf[i]);
217 }
187 place_bit0(); // Stopbit(0); 218 place_bit0(); // Stopbit(0);
188 sei(); 219 sei();
189} 220}
190 221
222void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l) {
223 uint8_t buf[2] = {data_h, data_l};
224 adb_host_listen_buf(addr, reg, buf, 2);
225}
226
227void adb_host_flush(uint8_t addr) {
228 cli();
229 attention();
230 send_byte((addr << 4) | ADB_CMD_FLUSH);
231 place_bit0(); // Stopbit(0)
232 _delay_us(200); // Tlt/Stop to Start
233 sei();
234}
235
191// send state of LEDs 236// send state of LEDs
192void adb_host_kbd_led(uint8_t led) { 237void adb_host_kbd_led(uint8_t led) {
193 // Addr:Keyboard(0010), Cmd:Listen(10), Register2(10) 238 // Listen Register2
194 // send upper byte (not used) 239 // upper byte: not used
195 // send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0: 240 // lower byte: bit2=ScrollLock, bit1=CapsLock, bit0=NumLock
196 adb_host_listen(0x2A, 0, led & 0x07); 241 adb_host_listen(ADB_ADDR_KEYBOARD, ADB_REG_2, 0, led & 0x07);
197} 242}
198 243
199#ifdef ADB_PSW_BIT 244#ifdef ADB_PSW_BIT
@@ -327,7 +372,7 @@ Commands
327 372
328 bits commands 373 bits commands
329 ------------------------------------------------------ 374 ------------------------------------------------------
330 - - - - 0 0 0 0 Send Request(reset all devices) 375 - - - - 0 0 0 0 Send Reset(reset all devices)
331 A A A A 0 0 0 1 Flush(reset a device) 376 A A A A 0 0 0 1 Flush(reset a device)
332 - - - - 0 0 1 0 Reserved 377 - - - - 0 0 1 0 Reserved
333 - - - - 0 0 1 1 Reserved 378 - - - - 0 0 1 1 Reserved
@@ -435,5 +480,56 @@ Keyboard LEDs & state of keys(Register2)
435 | +----------------------------- Delete 480 | +----------------------------- Delete
436 +------------------------------- Reserved 481 +------------------------------- Reserved
437 482
483Address, Handler ID and bits(Register3)
484 1514131211 . . 8 7 . . . . . . 0
485 | | | | | | | | | | | | | | | |
486 | | | | | | | | +-+-+-+-+-+-+-+- Handler ID
487 | | | | +-+-+-+----------------- Address
488 | | | +------------------------- 0
489 | | +--------------------------- Service request enable(1 = enabled)
490 | +----------------------------- Exceptional event(alwyas 1 if not used)
491 +------------------------------- 0
492
493ADB Bit Cells
494 bit cell time: 70-130us
495 low part of bit0: 60-70% of bit cell
496 low part of bit1: 30-40% of bit cell
497
498 bit cell time 70us 130us
499 --------------------------------------------
500 low part of bit0 42-49 78-91
501 high part of bit0 21-28 39-52
502 low part of bit1 21-28 39-52
503 high part of bit1 42-49 78-91
504
505
506 bit0:
507 70us bit cell:
508 ____________~~~~~~
509 42-49 21-28
510
511 130us bit cell:
512 ____________~~~~~~
513 78-91 39-52
514
515 bit1:
516 70us bit cell:
517 ______~~~~~~~~~~~~
518 21-28 42-49
519
520 130us bit cell:
521 ______~~~~~~~~~~~~
522 39-52 78-91
523
524 [from Apple IIgs Hardware Reference Second Edition]
525
526Keyboard Handle ID
527 Apple Standard Keyboard M0116: 0x01
528 Apple Extended Keyboard M0115: 0x02
529 Apple Extended Keyboard II M3501: 0x02
530 Apple Adjustable Keybaord: 0x10
531
532 http://lxr.free-electrons.com/source/drivers/macintosh/adbhid.c?v=4.4#L802
533
438END_OF_ADB 534END_OF_ADB
439*/ 535*/
diff --git a/tmk_core/protocol/adb.h b/tmk_core/protocol/adb.h
index 34cbcf769..fe8becc2d 100644
--- a/tmk_core/protocol/adb.h
+++ b/tmk_core/protocol/adb.h
@@ -1,5 +1,5 @@
1/* 1/*
2Copyright 2011 Jun WAKO <wakojun@gmail.com> 2Copyright 2011-19 Jun WAKO <wakojun@gmail.com>
3 3
4This software is licensed with a Modified BSD License. 4This software is licensed with a Modified BSD License.
5All of this is supposed to be Free Software, Open Source, DFSG-free, 5All of this is supposed to be Free Software, Open Source, DFSG-free,
@@ -47,12 +47,60 @@ POSSIBILITY OF SUCH DAMAGE.
47#define ADB_POWER 0x7F 47#define ADB_POWER 0x7F
48#define ADB_CAPS 0x39 48#define ADB_CAPS 0x39
49 49
50/* ADB commands */
51// Default Address
52#define ADB_ADDR_0 0
53#define ADB_ADDR_DONGLE 1
54#define ADB_ADDR_KEYBOARD 2
55#define ADB_ADDR_MOUSE 3
56#define ADB_ADDR_TABLET 4
57#define ADB_ADDR_APPLIANCE 7
58#define ADB_ADDR_8 8
59#define ADB_ADDR_9 9
60#define ADB_ADDR_10 10
61#define ADB_ADDR_11 11
62#define ADB_ADDR_12 12
63#define ADB_ADDR_13 13
64#define ADB_ADDR_14 14
65#define ADB_ADDR_15 15
66// for temporary purpose, do not use for polling
67#define ADB_ADDR_TMP 15
68#define ADB_ADDR_MOUSE_POLL 10
69// Command Type
70#define ADB_CMD_RESET 0
71#define ADB_CMD_FLUSH 1
72#define ADB_CMD_LISTEN 8
73#define ADB_CMD_TALK 12
74// Register
75#define ADB_REG_0 0
76#define ADB_REG_1 1
77#define ADB_REG_2 2
78#define ADB_REG_3 3
79
80/* ADB keyboard handler id */
81#define ADB_HANDLER_STD 0x01 /* IIGS, M0116 */
82#define ADB_HANDLER_AEK 0x02 /* M0115, M3501 */
83#define ADB_HANDLER_AEK_RMOD 0x03 /* M0115, M3501, alternate mode enableing right modifiers */
84#define ADB_HANDLER_STD_ISO 0x04 /* M0118, ISO swapping keys */
85#define ADB_HANDLER_AEK_ISO 0x05 /* M0115, M3501, ISO swapping keys */
86#define ADB_HANDLER_M1242_ANSI 0x10 /* Adjustable keyboard */
87#define ADB_HANDLER_CLASSIC1_MOUSE 0x01
88#define ADB_HANDLER_CLASSIC2_MOUSE 0x02
89#define ADB_HANDLER_EXTENDED_MOUSE 0x04
90#define ADB_HANDLER_TURBO_MOUSE 0x32
91
50// ADB host 92// ADB host
51void adb_host_init(void); 93void adb_host_init(void);
52bool adb_host_psw(void); 94bool adb_host_psw(void);
95uint16_t adb_host_talk(uint8_t addr, uint8_t reg);
96uint8_t adb_host_talk_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
97void adb_host_listen(uint8_t addr, uint8_t reg, uint8_t data_h, uint8_t data_l);
98void adb_host_listen_buf(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
99void adb_host_flush(uint8_t addr);
100void adb_host_kbd_led(uint8_t led);
53uint16_t adb_host_kbd_recv(void); 101uint16_t adb_host_kbd_recv(void);
54uint16_t adb_host_mouse_recv(void); 102uint16_t adb_host_mouse_recv(void);
55void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l); 103
56void adb_host_kbd_led(uint8_t led); 104// ADB Mouse
57void adb_mouse_task(void); 105void adb_mouse_task(void);
58void adb_mouse_init(void); 106void 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 d3319ab44..dda2f85b0 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/>.
28 28
29# define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers 29# define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers
30 30
31DmacDescriptor dmac_desc;
32DmacDescriptor dmac_desc_wb;
33
31static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer 34static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer
32static uint8_t i2c_led_q_s; // Start of circular buffer 35static uint8_t i2c_led_q_s; // Start of circular buffer
33static uint8_t i2c_led_q_e; // End of circular buffer 36static 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 44dbdfbff..68773f213 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/>.
24# include "issi3733_driver.h" 24# include "issi3733_driver.h"
25# include "config.h" 25# include "config.h"
26 26
27__attribute__((__aligned__(16))) DmacDescriptor dmac_desc; 27extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc;
28__attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb; 28extern __attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;
29 29
30uint8_t I2C3733_Init_Control(void); 30uint8_t I2C3733_Init_Control(void);
31uint8_t I2C3733_Init_Drivers(void); 31uint8_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 e10be52fb..a3d1f3449 100644
--- a/tmk_core/protocol/arm_atsam/main_arm_atsam.c
+++ b/tmk_core/protocol/arm_atsam/main_arm_atsam.c
@@ -306,9 +306,6 @@ int main(void) {
306 } 306 }
307#endif // CONSOLE_ENABLE 307#endif // CONSOLE_ENABLE
308 308
309 // Run housekeeping
310 housekeeping_task_kb();
311 housekeeping_task_user();
312 } 309 }
313 310
314 return 1; 311 return 1;
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index e07c181fc..63e4c99d2 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -163,6 +163,7 @@ int main(void) {
163 keyboard_setup(); 163 keyboard_setup();
164 164
165 /* Init USB */ 165 /* Init USB */
166 usb_event_queue_init();
166 init_usb_driver(&USB_DRIVER); 167 init_usb_driver(&USB_DRIVER);
167 168
168#ifdef MIDI_ENABLE 169#ifdef MIDI_ENABLE
@@ -221,6 +222,8 @@ int main(void) {
221 222
222 /* Main loop */ 223 /* Main loop */
223 while (true) { 224 while (true) {
225 usb_event_queue_task();
226
224#if !defined(NO_USB_STARTUP_CHECK) 227#if !defined(NO_USB_STARTUP_CHECK)
225 if (USB_DRIVER.state == USB_SUSPENDED) { 228 if (USB_DRIVER.state == USB_SUSPENDED) {
226 print("[s]"); 229 print("[s]");
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index ad489fb91..13b1e34d2 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -27,6 +27,7 @@
27 27
28#include <ch.h> 28#include <ch.h>
29#include <hal.h> 29#include <hal.h>
30#include <string.h>
30 31
31#include "usb_main.h" 32#include "usb_main.h"
32 33
@@ -368,6 +369,69 @@ static usb_driver_configs_t drivers = {
368 * --------------------------------------------------------- 369 * ---------------------------------------------------------
369 */ 370 */
370 371
372#define USB_EVENT_QUEUE_SIZE 16
373usbevent_t event_queue[USB_EVENT_QUEUE_SIZE];
374uint8_t event_queue_head;
375uint8_t event_queue_tail;
376
377void usb_event_queue_init(void) {
378 // Initialise the event queue
379 memset(&event_queue, 0, sizeof(event_queue));
380 event_queue_head = 0;
381 event_queue_tail = 0;
382}
383
384static inline bool usb_event_queue_enqueue(usbevent_t event) {
385 uint8_t next = (event_queue_head + 1) % USB_EVENT_QUEUE_SIZE;
386 if (next == event_queue_tail) {
387 return false;
388 }
389 event_queue[event_queue_head] = event;
390 event_queue_head = next;
391 return true;
392}
393
394static inline bool usb_event_queue_dequeue(usbevent_t *event) {
395 if (event_queue_head == event_queue_tail) {
396 return false;
397 }
398 *event = event_queue[event_queue_tail];
399 event_queue_tail = (event_queue_tail + 1) % USB_EVENT_QUEUE_SIZE;
400 return true;
401}
402
403static inline void usb_event_suspend_handler(void) {
404#ifdef SLEEP_LED_ENABLE
405 sleep_led_enable();
406#endif /* SLEEP_LED_ENABLE */
407}
408
409static inline void usb_event_wakeup_handler(void) {
410 suspend_wakeup_init();
411#ifdef SLEEP_LED_ENABLE
412 sleep_led_disable();
413 // NOTE: converters may not accept this
414 led_set(host_keyboard_leds());
415#endif /* SLEEP_LED_ENABLE */
416}
417
418void usb_event_queue_task(void) {
419 usbevent_t event;
420 while (usb_event_queue_dequeue(&event)) {
421 switch (event) {
422 case USB_EVENT_SUSPEND:
423 usb_event_suspend_handler();
424 break;
425 case USB_EVENT_WAKEUP:
426 usb_event_wakeup_handler();
427 break;
428 default:
429 // Nothing to do, we don't handle it.
430 break;
431 }
432 }
433}
434
371/* Handles the USB driver global events 435/* Handles the USB driver global events
372 * TODO: maybe disable some things when connection is lost? */ 436 * TODO: maybe disable some things when connection is lost? */
373static void usb_event_cb(USBDriver *usbp, usbevent_t event) { 437static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
@@ -402,9 +466,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
402 osalSysUnlockFromISR(); 466 osalSysUnlockFromISR();
403 return; 467 return;
404 case USB_EVENT_SUSPEND: 468 case USB_EVENT_SUSPEND:
405#ifdef SLEEP_LED_ENABLE 469 usb_event_queue_enqueue(USB_EVENT_SUSPEND);
406 sleep_led_enable();
407#endif /* SLEEP_LED_ENABLE */
408 /* Falls into.*/ 470 /* Falls into.*/
409 case USB_EVENT_UNCONFIGURED: 471 case USB_EVENT_UNCONFIGURED:
410 /* Falls into.*/ 472 /* Falls into.*/
@@ -425,12 +487,7 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
425 qmkusbWakeupHookI(&drivers.array[i].driver); 487 qmkusbWakeupHookI(&drivers.array[i].driver);
426 chSysUnlockFromISR(); 488 chSysUnlockFromISR();
427 } 489 }
428 suspend_wakeup_init(); 490 usb_event_queue_enqueue(USB_EVENT_WAKEUP);
429#ifdef SLEEP_LED_ENABLE
430 sleep_led_disable();
431 // NOTE: converters may not accept this
432 led_set(host_keyboard_leds());
433#endif /* SLEEP_LED_ENABLE */
434 return; 491 return;
435 492
436 case USB_EVENT_STALLED: 493 case USB_EVENT_STALLED:
@@ -651,6 +708,17 @@ void init_usb_driver(USBDriver *usbp) {
651void restart_usb_driver(USBDriver *usbp) { 708void restart_usb_driver(USBDriver *usbp) {
652 usbStop(usbp); 709 usbStop(usbp);
653 usbDisconnectBus(usbp); 710 usbDisconnectBus(usbp);
711
712#if USB_SUSPEND_WAKEUP_DELAY > 0
713 // Some hubs, kvm switches, and monitors do
714 // weird things, with USB device state bouncing
715 // around wildly on wakeup, yielding race
716 // conditions that can corrupt the keyboard state.
717 //
718 // Pause for a while to let things settle...
719 wait_ms(USB_SUSPEND_WAKEUP_DELAY);
720#endif
721
654 usbStart(usbp, &usbcfg); 722 usbStart(usbp, &usbcfg);
655 usbConnectBus(usbp); 723 usbConnectBus(usbp);
656} 724}
diff --git a/tmk_core/protocol/chibios/usb_main.h b/tmk_core/protocol/chibios/usb_main.h
index eaa08d8f7..fb33c8cd0 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);
38void restart_usb_driver(USBDriver *usbp); 38void restart_usb_driver(USBDriver *usbp);
39 39
40/* --------------- 40/* ---------------
41 * USB Event queue
42 * ---------------
43 */
44
45/* Initialisation of the FIFO */
46void usb_event_queue_init(void);
47
48/* Task to dequeue and execute any handlers for the USB events on the main thread */
49void usb_event_queue_task(void);
50
51/* ---------------
41 * Keyboard header 52 * Keyboard header
42 * --------------- 53 * ---------------
43 */ 54 */
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 623aa33ff..74e48222d 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -435,7 +435,9 @@ void EVENT_USB_Device_Suspend() {
435 */ 435 */
436void EVENT_USB_Device_WakeUp() { 436void EVENT_USB_Device_WakeUp() {
437 print("[W]"); 437 print("[W]");
438#if defined(NO_USB_STARTUP_CHECK)
438 suspend_wakeup_init(); 439 suspend_wakeup_init();
440#endif
439 441
440#ifdef SLEEP_LED_ENABLE 442#ifdef SLEEP_LED_ENABLE
441 sleep_led_disable(); 443 sleep_led_disable();
@@ -1073,12 +1075,26 @@ int main(void) {
1073 print("Keyboard start.\n"); 1075 print("Keyboard start.\n");
1074 while (1) { 1076 while (1) {
1075#if !defined(NO_USB_STARTUP_CHECK) 1077#if !defined(NO_USB_STARTUP_CHECK)
1076 while (USB_DeviceState == DEVICE_STATE_Suspended) { 1078 if (USB_DeviceState == DEVICE_STATE_Suspended) {
1077 print("[s]"); 1079 print("[s]");
1078 suspend_power_down(); 1080 while (USB_DeviceState == DEVICE_STATE_Suspended) {
1079 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { 1081 suspend_power_down();
1080 USB_Device_SendRemoteWakeup(); 1082 if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
1083 USB_Device_SendRemoteWakeup();
1084 clear_keyboard();
1085
1086# if USB_SUSPEND_WAKEUP_DELAY > 0
1087 // Some hubs, kvm switches, and monitors do
1088 // weird things, with USB device state bouncing
1089 // around wildly on wakeup, yielding race
1090 // conditions that can corrupt the keyboard state.
1091 //
1092 // Pause for a while to let things settle...
1093 wait_ms(USB_SUSPEND_WAKEUP_DELAY);
1094# endif
1095 }
1081 } 1096 }
1097 suspend_wakeup_init();
1082 } 1098 }
1083#endif 1099#endif
1084 1100
diff --git a/tmk_core/protocol/usb_descriptor.c b/tmk_core/protocol/usb_descriptor.c
index 7ea4b2e37..ba7760f28 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[] = {
116# endif 116# endif
117 HID_RI_USAGE(8, 0x01), // Pointer 117 HID_RI_USAGE(8, 0x01), // Pointer
118 HID_RI_COLLECTION(8, 0x00), // Physical 118 HID_RI_COLLECTION(8, 0x00), // Physical
119 // Buttons (5 bits) 119 // Buttons (8 bits)
120 HID_RI_USAGE_PAGE(8, 0x09), // Button 120 HID_RI_USAGE_PAGE(8, 0x09), // Button
121 HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1 121 HID_RI_USAGE_MINIMUM(8, 0x01), // Button 1
122 HID_RI_USAGE_MAXIMUM(8, 0x05), // Button 5 122 HID_RI_USAGE_MAXIMUM(8, 0x08), // Button 8
123 HID_RI_LOGICAL_MINIMUM(8, 0x00), 123 HID_RI_LOGICAL_MINIMUM(8, 0x00),
124 HID_RI_LOGICAL_MAXIMUM(8, 0x01), 124 HID_RI_LOGICAL_MAXIMUM(8, 0x01),
125 HID_RI_REPORT_COUNT(8, 0x05), 125 HID_RI_REPORT_COUNT(8, 0x08),
126 HID_RI_REPORT_SIZE(8, 0x01), 126 HID_RI_REPORT_SIZE(8, 0x01),
127 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), 127 HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
128 // Button padding (3 bits)
129 HID_RI_REPORT_COUNT(8, 0x01),
130 HID_RI_REPORT_SIZE(8, 0x03),
131 HID_RI_INPUT(8, HID_IOF_CONSTANT),
132 128
133 // X/Y position (2 bytes) 129 // X/Y position (2 bytes)
134 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop 130 HID_RI_USAGE_PAGE(8, 0x01), // Generic Desktop
@@ -356,7 +352,7 @@ const USB_Descriptor_Device_t PROGMEM DeviceDescriptor = {
356 .Type = DTYPE_Device 352 .Type = DTYPE_Device
357 }, 353 },
358 .USBSpecification = VERSION_BCD(1, 1, 0), 354 .USBSpecification = VERSION_BCD(1, 1, 0),
359 355
360#if VIRTSER_ENABLE 356#if VIRTSER_ENABLE
361 .Class = USB_CSCP_IADDeviceClass, 357 .Class = USB_CSCP_IADDeviceClass,
362 .SubClass = USB_CSCP_IADDeviceSubclass, 358 .SubClass = USB_CSCP_IADDeviceSubclass,
diff --git a/tmk_core/protocol/vusb/vusb.c b/tmk_core/protocol/vusb/vusb.c
index a422903cc..9362fbde7 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[] = {
444 0x85, REPORT_ID_MOUSE, // Report ID 444 0x85, REPORT_ID_MOUSE, // Report ID
445 0x09, 0x01, // Usage (Pointer) 445 0x09, 0x01, // Usage (Pointer)
446 0xA1, 0x00, // Collection (Physical) 446 0xA1, 0x00, // Collection (Physical)
447 // Buttons (5 bits) 447 // Buttons (8 bits)
448 0x05, 0x09, // Usage Page (Button) 448 0x05, 0x09, // Usage Page (Button)
449 0x19, 0x01, // Usage Minimum (Button 1) 449 0x19, 0x01, // Usage Minimum (Button 1)
450 0x29, 0x05, // Usage Maximum (Button 5) 450 0x29, 0x08, // Usage Maximum (Button 8)
451 0x15, 0x00, // Logical Minimum (0) 451 0x15, 0x00, // Logical Minimum (0)
452 0x25, 0x01, // Logical Maximum (1) 452 0x25, 0x01, // Logical Maximum (1)
453 0x95, 0x05, // Report Count (5) 453 0x95, 0x08, // Report Count (8)
454 0x75, 0x01, // Report Size (1) 454 0x75, 0x01, // Report Size (1)
455 0x81, 0x02, // Input (Data, Variable, Absolute) 455 0x81, 0x02, // Input (Data, Variable, Absolute)
456 // Button padding (3 bits)
457 0x95, 0x01, // Report Count (1)
458 0x75, 0x03, // Report Size (3)
459 0x81, 0x03, // Input (Constant)
460 456
461 // X/Y position (2 bytes) 457 // X/Y position (2 bytes)
462 0x05, 0x01, // Usage Page (Generic Desktop) 458 0x05, 0x01, // Usage Page (Generic Desktop)