summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/config-c200.h1
-rw-r--r--firmware/export/config-e200.h2
-rw-r--r--firmware/export/config-gigabeat-s.h1
-rwxr-xr-xfirmware/export/config-hdd1630.h1
-rw-r--r--firmware/export/config-ipod4g.h1
-rw-r--r--firmware/export/config-ipodcolor.h1
-rw-r--r--firmware/export/config-ipodmini.h1
-rw-r--r--firmware/export/config-ipodmini2g.h1
-rw-r--r--firmware/export/config-ipodnano.h1
-rw-r--r--firmware/export/config-ipodvideo.h1
-rwxr-xr-xfirmware/export/config-sa9200.h1
-rw-r--r--firmware/usbstack/usb_core.c2
-rw-r--r--firmware/usbstack/usb_hid.c349
-rw-r--r--firmware/usbstack/usb_hid_usage_tables.h36
14 files changed, 322 insertions, 77 deletions
diff --git a/firmware/export/config-c200.h b/firmware/export/config-c200.h
index 654ac7b9cf..ab70396eef 100644
--- a/firmware/export/config-c200.h
+++ b/firmware/export/config-c200.h
@@ -190,6 +190,7 @@
190#define USE_ROCKBOX_USB 190#define USE_ROCKBOX_USB
191#define USB_VENDOR_ID 0x0781 191#define USB_VENDOR_ID 0x0781
192#define USB_PRODUCT_ID 0x7451 192#define USB_PRODUCT_ID 0x7451
193#define HAVE_USB_HID_MOUSE
193 194
194/* Define this if you have adjustable CPU frequency */ 195/* Define this if you have adjustable CPU frequency */
195#define HAVE_ADJUSTABLE_CPU_FREQ 196#define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-e200.h b/firmware/export/config-e200.h
index 8b7e0d68b2..18de2f65f1 100644
--- a/firmware/export/config-e200.h
+++ b/firmware/export/config-e200.h
@@ -184,7 +184,7 @@
184#define USE_ROCKBOX_USB 184#define USE_ROCKBOX_USB
185#define USB_VENDOR_ID 0x0781 185#define USB_VENDOR_ID 0x0781
186#define USB_PRODUCT_ID 0x7421 186#define USB_PRODUCT_ID 0x7421
187 187#define HAVE_USB_HID_MOUSE
188 188
189/* Define this if you have adjustable CPU frequency */ 189/* Define this if you have adjustable CPU frequency */
190#define HAVE_ADJUSTABLE_CPU_FREQ 190#define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-gigabeat-s.h b/firmware/export/config-gigabeat-s.h
index 3f001af737..ae57825388 100644
--- a/firmware/export/config-gigabeat-s.h
+++ b/firmware/export/config-gigabeat-s.h
@@ -187,6 +187,7 @@
187#define USB_PORTSCX_PHY_TYPE PORTSCX_PTS_ULPI 187#define USB_PORTSCX_PHY_TYPE PORTSCX_PTS_ULPI
188#define USB_VENDOR_ID 0x0930 188#define USB_VENDOR_ID 0x0930
189#define USB_PRODUCT_ID 0x0010 189#define USB_PRODUCT_ID 0x0010
190#define HAVE_USB_HID_MOUSE
190 191
191/* Define this if you have ATA power-off control */ 192/* Define this if you have ATA power-off control */
192#define HAVE_ATA_POWER_OFF 193#define HAVE_ATA_POWER_OFF
diff --git a/firmware/export/config-hdd1630.h b/firmware/export/config-hdd1630.h
index 05450e01c2..1d7bff3ee6 100755
--- a/firmware/export/config-hdd1630.h
+++ b/firmware/export/config-hdd1630.h
@@ -187,6 +187,7 @@
187#define USE_ROCKBOX_USB 187#define USE_ROCKBOX_USB
188#define USB_VENDOR_ID 0x0471 188#define USB_VENDOR_ID 0x0471
189#define USB_PRODUCT_ID 0x014C 189#define USB_PRODUCT_ID 0x014C
190#define HAVE_USB_HID_MOUSE
190 191
191/* Define this if you have adjustable CPU frequency */ 192/* Define this if you have adjustable CPU frequency */
192#define HAVE_ADJUSTABLE_CPU_FREQ 193#define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-ipod4g.h b/firmware/export/config-ipod4g.h
index 6c08e7533e..232e0aa5a3 100644
--- a/firmware/export/config-ipod4g.h
+++ b/firmware/export/config-ipod4g.h
@@ -183,6 +183,7 @@
183#define USE_ROCKBOX_USB 183#define USE_ROCKBOX_USB
184#define USB_VENDOR_ID 0x05ac 184#define USB_VENDOR_ID 0x05ac
185#define USB_PRODUCT_ID 0x1203 185#define USB_PRODUCT_ID 0x1203
186#define HAVE_USB_HID_MOUSE
186 187
187/* Virtual LED (icon) */ 188/* Virtual LED (icon) */
188#define CONFIG_LED LED_VIRTUAL 189#define CONFIG_LED LED_VIRTUAL
diff --git a/firmware/export/config-ipodcolor.h b/firmware/export/config-ipodcolor.h
index ea02b90964..3254c0abfb 100644
--- a/firmware/export/config-ipodcolor.h
+++ b/firmware/export/config-ipodcolor.h
@@ -160,6 +160,7 @@
160#define USE_ROCKBOX_USB 160#define USE_ROCKBOX_USB
161#define USB_VENDOR_ID 0x05ac 161#define USB_VENDOR_ID 0x05ac
162#define USB_PRODUCT_ID 0x1204 162#define USB_PRODUCT_ID 0x1204
163#define HAVE_USB_HID_MOUSE
163 164
164/* Define this if you have adjustable CPU frequency */ 165/* Define this if you have adjustable CPU frequency */
165#define HAVE_ADJUSTABLE_CPU_FREQ 166#define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-ipodmini.h b/firmware/export/config-ipodmini.h
index 9036adcc46..9cf377f99a 100644
--- a/firmware/export/config-ipodmini.h
+++ b/firmware/export/config-ipodmini.h
@@ -179,6 +179,7 @@
179#define USE_ROCKBOX_USB 179#define USE_ROCKBOX_USB
180#define USB_VENDOR_ID 0x05ac 180#define USB_VENDOR_ID 0x05ac
181#define USB_PRODUCT_ID 0x1205 181#define USB_PRODUCT_ID 0x1205
182#define HAVE_USB_HID_MOUSE
182 183
183/* Define this if you have adjustable CPU frequency */ 184/* Define this if you have adjustable CPU frequency */
184#define HAVE_ADJUSTABLE_CPU_FREQ 185#define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-ipodmini2g.h b/firmware/export/config-ipodmini2g.h
index b69810e198..dcd3113d77 100644
--- a/firmware/export/config-ipodmini2g.h
+++ b/firmware/export/config-ipodmini2g.h
@@ -186,6 +186,7 @@
186#define USE_ROCKBOX_USB 186#define USE_ROCKBOX_USB
187#define USB_VENDOR_ID 0x05ac 187#define USB_VENDOR_ID 0x05ac
188#define USB_PRODUCT_ID 0x1205 188#define USB_PRODUCT_ID 0x1205
189#define HAVE_USB_HID_MOUSE
189 190
190/* Define this if you have adjustable CPU frequency */ 191/* Define this if you have adjustable CPU frequency */
191#define HAVE_ADJUSTABLE_CPU_FREQ 192#define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-ipodnano.h b/firmware/export/config-ipodnano.h
index 31108091b9..005d2ffd9c 100644
--- a/firmware/export/config-ipodnano.h
+++ b/firmware/export/config-ipodnano.h
@@ -170,6 +170,7 @@
170#define USE_ROCKBOX_USB 170#define USE_ROCKBOX_USB
171#define USB_VENDOR_ID 0x05ac 171#define USB_VENDOR_ID 0x05ac
172#define USB_PRODUCT_ID 0x120a 172#define USB_PRODUCT_ID 0x120a
173#define HAVE_USB_HID_MOUSE
173 174
174/* Define this if you have adjustable CPU frequency */ 175/* Define this if you have adjustable CPU frequency */
175#define HAVE_ADJUSTABLE_CPU_FREQ 176#define HAVE_ADJUSTABLE_CPU_FREQ
diff --git a/firmware/export/config-ipodvideo.h b/firmware/export/config-ipodvideo.h
index bd93f8fb36..f760a5656f 100644
--- a/firmware/export/config-ipodvideo.h
+++ b/firmware/export/config-ipodvideo.h
@@ -194,6 +194,7 @@
194#define USE_ROCKBOX_USB 194#define USE_ROCKBOX_USB
195#define USB_VENDOR_ID 0x05ac 195#define USB_VENDOR_ID 0x05ac
196#define USB_PRODUCT_ID 0x1209 196#define USB_PRODUCT_ID 0x1209
197#define HAVE_USB_HID_MOUSE
197 198
198/* Virtual LED (icon) */ 199/* Virtual LED (icon) */
199#define CONFIG_LED LED_VIRTUAL 200#define CONFIG_LED LED_VIRTUAL
diff --git a/firmware/export/config-sa9200.h b/firmware/export/config-sa9200.h
index 7af50b5145..2ab538e98c 100755
--- a/firmware/export/config-sa9200.h
+++ b/firmware/export/config-sa9200.h
@@ -171,6 +171,7 @@
171#define USE_ROCKBOX_USB 171#define USE_ROCKBOX_USB
172#define USB_VENDOR_ID 0x0471 172#define USB_VENDOR_ID 0x0471
173#define USB_PRODUCT_ID 0x014f 173#define USB_PRODUCT_ID 0x014f
174#define HAVE_USB_HID_MOUSE
174 175
175/* WARNING! Enable Rockbox USB mass storage. */ 176/* WARNING! Enable Rockbox USB mass storage. */
176#ifndef BOOTLOADER 177#ifndef BOOTLOADER
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index d45c0efc90..7321d3e565 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -43,7 +43,7 @@
43#include "usb_charging_only.h" 43#include "usb_charging_only.h"
44#endif 44#endif
45 45
46#if defined(USB_ENABLE_HID) 46#ifdef USB_ENABLE_HID
47#include "usb_hid.h" 47#include "usb_hid.h"
48#endif 48#endif
49 49
diff --git a/firmware/usbstack/usb_hid.c b/firmware/usbstack/usb_hid.c
index 4eb25841bb..4e9795b210 100644
--- a/firmware/usbstack/usb_hid.c
+++ b/firmware/usbstack/usb_hid.c
@@ -28,11 +28,6 @@
28//#define LOGF_ENABLE 28//#define LOGF_ENABLE
29#include "logf.h" 29#include "logf.h"
30 30
31#define CONCAT(low, high) ((high << 8) | low)
32#define PACK_VAL1(dest, val) *(dest)++ = (val) & 0xff
33#define PACK_VAL2(dest, val) PACK_VAL1((dest), (val)); \
34 PACK_VAL1((dest), (val >> 8))
35
36/* Documents avaiable here: http://www.usb.org/developers/devclass_docs/ */ 31/* Documents avaiable here: http://www.usb.org/developers/devclass_docs/ */
37 32
38#define HID_VER 0x0110 /* 1.1 */ 33#define HID_VER 0x0110 /* 1.1 */
@@ -47,6 +42,7 @@
47#define INPUT 0x80 42#define INPUT 0x80
48#define OUTPUT 0x90 43#define OUTPUT 0x90
49#define COLLECTION 0xA0 44#define COLLECTION 0xA0
45#define COLLECTION_PHYSICAL 0x00
50#define COLLECTION_APPLICATION 0x01 46#define COLLECTION_APPLICATION 0x01
51#define END_COLLECTION 0xC0 47#define END_COLLECTION 0xC0
52/* Parts (HID1_11.pdf, page 40) */ 48/* Parts (HID1_11.pdf, page 40) */
@@ -90,24 +86,30 @@
90 86
91#define HID_BUF_SIZE_MSG 16 87#define HID_BUF_SIZE_MSG 16
92#define HID_BUF_SIZE_CMD 16 88#define HID_BUF_SIZE_CMD 16
93#define HID_BUF_SIZE_REPORT 96 89#define HID_BUF_SIZE_REPORT 160
94#define HID_NUM_BUFFERS 5 90#define HID_NUM_BUFFERS 5
95#define SET_REPORT_BUF_LEN 2 91#define SET_REPORT_BUF_LEN 2
96 92
93//#ifdef LOGF_ENABLE
97#ifdef LOGF_ENABLE 94#ifdef LOGF_ENABLE
95
98#define BUF_DUMP_BUF_LEN HID_BUF_SIZE_REPORT 96#define BUF_DUMP_BUF_LEN HID_BUF_SIZE_REPORT
99#define BUF_DUMP_PREFIX_SIZE 5 97#define BUF_DUMP_PREFIX_SIZE 5
100#define BUF_DUMP_LINE_SIZE (MAX_LOGF_ENTRY - BUF_DUMP_PREFIX_SIZE) 98#define BUF_DUMP_ITEMS_IN_LINE 8
101#define BUF_DUMP_ITEMS_IN_LINE (BUF_DUMP_LINE_SIZE / 3) 99#define BUF_DUMP_LINE_SIZE (BUF_DUMP_ITEMS_IN_LINE * 3)
102#define BUF_DUMP_NUM_LINES (BUF_DUMP_BUF_LEN / (BUF_DUMP_LINE_SIZE / 3)) 100#define BUF_DUMP_NUM_LINES (BUF_DUMP_BUF_LEN / BUF_DUMP_ITEMS_IN_LINE)
103#endif 101#endif
104 102
105#define HID_BUF_INC(i) do { (i) = ((i) + 1) % HID_NUM_BUFFERS; } while (0) 103#define HID_BUF_INC(i) do { (i) = ((i) + 1) % HID_NUM_BUFFERS; } while (0)
104#define PACK_VAL(dest, val) *(dest)++ = (val) & 0xff
106 105
107typedef enum 106typedef enum
108{ 107{
109 REPORT_ID_KEYBOARD = 1, 108 REPORT_ID_KEYBOARD = 1,
110 REPORT_ID_CONSUMER, 109 REPORT_ID_CONSUMER,
110#ifdef HAVE_USB_HID_MOUSE
111 REPORT_ID_MOUSE,
112#endif
111 REPORT_ID_COUNT, 113 REPORT_ID_COUNT,
112} report_id_t; 114} report_id_t;
113 115
@@ -164,6 +166,7 @@ typedef struct
164 /* Write the id into the buffer in the appropriate location, and returns the 166 /* Write the id into the buffer in the appropriate location, and returns the
165 * buffer length */ 167 * buffer length */
166 uint8_t (*buf_set)(unsigned char *buf, int id); 168 uint8_t (*buf_set)(unsigned char *buf, int id);
169 bool is_key_released;
167} usb_hid_report_t; 170} usb_hid_report_t;
168 171
169usb_hid_report_t usb_hid_reports[REPORT_ID_COUNT]; 172usb_hid_report_t usb_hid_reports[REPORT_ID_COUNT];
@@ -183,7 +186,7 @@ static int usb_interface;
183 186
184static void usb_hid_try_send_drv(void); 187static void usb_hid_try_send_drv(void);
185 188
186static void pack_parameter(unsigned char **dest, bool is_signed, 189static void pack_parameter(unsigned char **dest, bool is_signed, bool mark_size,
187 uint8_t parameter, uint32_t value) 190 uint8_t parameter, uint32_t value)
188{ 191{
189 uint8_t size_value = 1; /* # of bytes */ 192 uint8_t size_value = 1; /* # of bytes */
@@ -216,7 +219,7 @@ static void pack_parameter(unsigned char **dest, bool is_signed,
216 size_value++; 219 size_value++;
217 } 220 }
218 221
219 **dest = parameter | size_value; 222 **dest = parameter | (mark_size ? size_value : 0);
220 (*dest)++; 223 (*dest)++;
221 224
222 while (size_value--) 225 while (size_value--)
@@ -244,11 +247,10 @@ int usb_hid_set_first_interface(int interface)
244} 247}
245 248
246#ifdef LOGF_ENABLE 249#ifdef LOGF_ENABLE
247static unsigned char 250static unsigned char buf_dump_ar[BUF_DUMP_NUM_LINES][BUF_DUMP_LINE_SIZE + 1]
248 buf_dump_ar[BUF_DUMP_NUM_LINES][BUF_DUMP_LINE_SIZE + 1]
249 USB_DEVBSS_ATTR __attribute__((aligned(32))); 251 USB_DEVBSS_ATTR __attribute__((aligned(32)));
250 252
251void buf_dump(unsigned char *buf, size_t size) 253void buf_dump(unsigned char *buf, size_t size, char *msg)
252{ 254{
253 size_t i; 255 size_t i;
254 int line; 256 int line;
@@ -269,7 +271,7 @@ void buf_dump(unsigned char *buf, size_t size)
269 *b = 0; 271 *b = 0;
270 272
271 /* Prefix must be of len BUF_DUMP_PREFIX_SIZE */ 273 /* Prefix must be of len BUF_DUMP_PREFIX_SIZE */
272 logf("%03d: %s", i0, buf_dump_ar[line]); 274 logf("%03d: %s %s", i0, buf_dump_ar[line], msg);
273 } 275 }
274} 276}
275#else 277#else
@@ -277,26 +279,178 @@ void buf_dump(unsigned char *buf, size_t size)
277#define buf_dump(...) 279#define buf_dump(...)
278#endif 280#endif
279 281
282#define BUF_LEN_KEYBOARD 7
280static uint8_t buf_set_keyboard(unsigned char *buf, int id) 283static uint8_t buf_set_keyboard(unsigned char *buf, int id)
281{ 284{
282 memset(buf, 0, 7); 285 memset(buf, 0, BUF_LEN_KEYBOARD);
286 int key, i = 1;
283 287
284 if (HID_KEYBOARD_LEFT_CONTROL <= id && id <= HID_KEYBOARD_RIGHT_GUI) 288 /* Each key is a word in id (up to 4 keys supported) */
285 buf[0] = (1 << (id - HID_KEYBOARD_LEFT_CONTROL)); 289 while ((key = id & 0xff))
286 else 290 {
287 buf[1] = (uint8_t)id; 291 /* Each modifier key is a bit in the first byte */
292 if (HID_KEYBOARD_LEFT_CONTROL <= key && key <= HID_KEYBOARD_RIGHT_GUI)
293 buf[0] |= (1 << (key - HID_KEYBOARD_LEFT_CONTROL));
294 else /* Any other key should be set in a separate byte */
295 buf[i++] = (uint8_t)key;
288 296
289 return 7; 297 id >>= 8;
298 }
299
300 return BUF_LEN_KEYBOARD;
290} 301}
291 302
303#define BUF_LEN_CONSUMER 4
292static uint8_t buf_set_consumer(unsigned char *buf, int id) 304static uint8_t buf_set_consumer(unsigned char *buf, int id)
293{ 305{
294 memset(buf, 0, 4); 306 memset(buf, 0, BUF_LEN_CONSUMER);
295 buf[0] = (uint8_t)id; 307 buf[0] = (uint8_t)id;
296 308
297 return 4; 309 return BUF_LEN_CONSUMER;
298} 310}
299 311
312#ifdef HAVE_USB_HID_MOUSE
313#define MOUSE_WHEEL_STEP 1
314#define MOUSE_STEP 8
315#define MOUSE_BUTTON_LEFT 0x1
316#define MOUSE_BUTTON_RIGHT 0x2
317//#define MOUSE_BUTTON_MIDDLE 0x4
318#define MOUSE_BUTTON 0
319#define MOUSE_X 1
320#define MOUSE_Y 2
321#define MOUSE_WHEEL 3
322#define BUF_LEN_MOUSE 4
323#define MOUSE_ACCEL_FACTOR(count) ((count) / 2)
324#define MOUSE_DO(item, step) (buf[(item)] = ((uint8_t)(step)))
325
326static uint8_t buf_set_mouse(unsigned char *buf, int id)
327{
328 static int count = 0;
329 int step = MOUSE_STEP;
330
331 memset(buf, 0, BUF_LEN_MOUSE);
332
333 /* Set proper button */
334 switch (id)
335 {
336 case HID_MOUSE_BUTTON_LEFT:
337 case HID_MOUSE_LDRAG_UP:
338 case HID_MOUSE_LDRAG_UP_REP:
339 case HID_MOUSE_LDRAG_DOWN:
340 case HID_MOUSE_LDRAG_DOWN_REP:
341 case HID_MOUSE_LDRAG_LEFT:
342 case HID_MOUSE_LDRAG_LEFT_REP:
343 case HID_MOUSE_LDRAG_RIGHT:
344 case HID_MOUSE_LDRAG_RIGHT_REP:
345 MOUSE_DO(MOUSE_BUTTON, MOUSE_BUTTON_LEFT);
346 break;
347 case HID_MOUSE_BUTTON_RIGHT:
348 case HID_MOUSE_RDRAG_UP:
349 case HID_MOUSE_RDRAG_UP_REP:
350 case HID_MOUSE_RDRAG_DOWN:
351 case HID_MOUSE_RDRAG_DOWN_REP:
352 case HID_MOUSE_RDRAG_LEFT:
353 case HID_MOUSE_RDRAG_LEFT_REP:
354 case HID_MOUSE_RDRAG_RIGHT:
355 case HID_MOUSE_RDRAG_RIGHT_REP:
356 MOUSE_DO(MOUSE_BUTTON, MOUSE_BUTTON_RIGHT);
357 break;
358 case HID_MOUSE_BUTTON_LEFT_REL:
359 case HID_MOUSE_BUTTON_RIGHT_REL:
360 /* Keep buf empty, to mark mouse button release */
361 break;
362 default:
363 break;
364 }
365
366 /* Handle mouse accelarated movement */
367 switch (id)
368 {
369 case HID_MOUSE_UP:
370 case HID_MOUSE_DOWN:
371 case HID_MOUSE_LEFT:
372 case HID_MOUSE_RIGHT:
373 case HID_MOUSE_LDRAG_UP:
374 case HID_MOUSE_LDRAG_DOWN:
375 case HID_MOUSE_LDRAG_LEFT:
376 case HID_MOUSE_LDRAG_RIGHT:
377 case HID_MOUSE_RDRAG_UP:
378 case HID_MOUSE_RDRAG_DOWN:
379 case HID_MOUSE_RDRAG_LEFT:
380 case HID_MOUSE_RDRAG_RIGHT:
381 count = 0;
382 break;
383 case HID_MOUSE_UP_REP:
384 case HID_MOUSE_DOWN_REP:
385 case HID_MOUSE_LEFT_REP:
386 case HID_MOUSE_RIGHT_REP:
387 case HID_MOUSE_LDRAG_UP_REP:
388 case HID_MOUSE_LDRAG_DOWN_REP:
389 case HID_MOUSE_LDRAG_LEFT_REP:
390 case HID_MOUSE_LDRAG_RIGHT_REP:
391 case HID_MOUSE_RDRAG_UP_REP:
392 case HID_MOUSE_RDRAG_DOWN_REP:
393 case HID_MOUSE_RDRAG_LEFT_REP:
394 case HID_MOUSE_RDRAG_RIGHT_REP:
395 count++;
396 /* TODO: Find a better mouse accellaration algorithm */
397 step *= 1 + MOUSE_ACCEL_FACTOR(count);
398 if (step > 255)
399 step = 255;
400 break;
401 default:
402 break;
403 }
404
405 /* Move/scroll mouse */
406 switch (id)
407 {
408 case HID_MOUSE_UP:
409 case HID_MOUSE_UP_REP:
410 case HID_MOUSE_LDRAG_UP:
411 case HID_MOUSE_LDRAG_UP_REP:
412 case HID_MOUSE_RDRAG_UP:
413 case HID_MOUSE_RDRAG_UP_REP:
414 MOUSE_DO(MOUSE_Y, -step);
415 break;
416 case HID_MOUSE_DOWN:
417 case HID_MOUSE_DOWN_REP:
418 case HID_MOUSE_LDRAG_DOWN:
419 case HID_MOUSE_LDRAG_DOWN_REP:
420 case HID_MOUSE_RDRAG_DOWN:
421 case HID_MOUSE_RDRAG_DOWN_REP:
422 MOUSE_DO(MOUSE_Y, step);
423 break;
424 case HID_MOUSE_LEFT:
425 case HID_MOUSE_LEFT_REP:
426 case HID_MOUSE_LDRAG_LEFT:
427 case HID_MOUSE_LDRAG_LEFT_REP:
428 case HID_MOUSE_RDRAG_LEFT:
429 case HID_MOUSE_RDRAG_LEFT_REP:
430 MOUSE_DO(MOUSE_X, -step);
431 break;
432 case HID_MOUSE_RIGHT:
433 case HID_MOUSE_RIGHT_REP:
434 case HID_MOUSE_LDRAG_RIGHT:
435 case HID_MOUSE_LDRAG_RIGHT_REP:
436 case HID_MOUSE_RDRAG_RIGHT:
437 case HID_MOUSE_RDRAG_RIGHT_REP:
438 MOUSE_DO(MOUSE_X, step);
439 break;
440 case HID_MOUSE_SCROLL_UP:
441 MOUSE_DO(MOUSE_WHEEL, MOUSE_WHEEL_STEP);
442 break;
443 case HID_MOUSE_SCROLL_DOWN:
444 MOUSE_DO(MOUSE_WHEEL, -MOUSE_WHEEL_STEP);
445 break;
446 default:
447 break;
448 }
449
450 return BUF_LEN_MOUSE;
451}
452#endif /* HAVE_USB_HID_MOUSE */
453
300static size_t descriptor_report_get(unsigned char *dest) 454static size_t descriptor_report_get(unsigned char *dest)
301{ 455{
302 unsigned char *report = dest; 456 unsigned char *report = dest;
@@ -306,59 +460,97 @@ static size_t descriptor_report_get(unsigned char *dest)
306 usb_hid_report = &usb_hid_reports[REPORT_ID_KEYBOARD]; 460 usb_hid_report = &usb_hid_reports[REPORT_ID_KEYBOARD];
307 usb_hid_report->usage_page = HID_USAGE_PAGE_KEYBOARD_KEYPAD; 461 usb_hid_report->usage_page = HID_USAGE_PAGE_KEYBOARD_KEYPAD;
308 usb_hid_report->buf_set = buf_set_keyboard; 462 usb_hid_report->buf_set = buf_set_keyboard;
463 usb_hid_report->is_key_released = 1;
309 464
310 pack_parameter(&report, 0, USAGE_PAGE, 465 pack_parameter(&report, 0, 1, USAGE_PAGE,
311 HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS); 466 HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS);
312 PACK_VAL2(report, CONCAT(CONSUMER_USAGE, HID_GENERIC_DESKTOP_KEYBOARD)); 467 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_KEYBOARD);
313 pack_parameter(&report, 0, COLLECTION, COLLECTION_APPLICATION); 468 pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION);
314 pack_parameter(&report, 0, REPORT_ID, REPORT_ID_KEYBOARD); 469 pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_KEYBOARD);
315 pack_parameter(&report, 0, USAGE_PAGE, HID_GENERIC_DESKTOP_KEYPAD); 470 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_GENERIC_DESKTOP_KEYPAD);
316 pack_parameter(&report, 0, USAGE_MINIMUM, HID_KEYBOARD_LEFT_CONTROL); 471 pack_parameter(&report, 0, 1, USAGE_MINIMUM, HID_KEYBOARD_LEFT_CONTROL);
317 pack_parameter(&report, 0, USAGE_MAXIMUM, HID_KEYBOARD_RIGHT_GUI); 472 pack_parameter(&report, 0, 1, USAGE_MAXIMUM, HID_KEYBOARD_RIGHT_GUI);
318 pack_parameter(&report, 1, LOGICAL_MINIMUM, 0); 473 pack_parameter(&report, 1, 1, LOGICAL_MINIMUM, 0);
319 pack_parameter(&report, 1, LOGICAL_MAXIMUM, 1); 474 pack_parameter(&report, 1, 1, LOGICAL_MAXIMUM, 1);
320 pack_parameter(&report, 0, REPORT_SIZE, 1); 475 pack_parameter(&report, 0, 1, REPORT_SIZE, 1);
321 pack_parameter(&report, 0, REPORT_COUNT, 8); 476 pack_parameter(&report, 0, 1, REPORT_COUNT, 8);
322 pack_parameter(&report, 0, INPUT, MAIN_ITEM_VARIABLE); 477 pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_VARIABLE);
323 pack_parameter(&report, 0, REPORT_SIZE, 1); 478 pack_parameter(&report, 0, 1, REPORT_SIZE, 1);
324 pack_parameter(&report, 0, REPORT_COUNT, 5); 479 pack_parameter(&report, 0, 1, REPORT_COUNT, 5);
325 pack_parameter(&report, 0, USAGE_PAGE, HID_USAGE_PAGE_LEDS); 480 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_LEDS);
326 pack_parameter(&report, 0, USAGE_MINIMUM, HID_LED_NUM_LOCK); 481 pack_parameter(&report, 0, 1, USAGE_MINIMUM, HID_LED_NUM_LOCK);
327 pack_parameter(&report, 0, USAGE_MAXIMUM, HID_LED_KANA); 482 pack_parameter(&report, 0, 1, USAGE_MAXIMUM, HID_LED_KANA);
328 pack_parameter(&report, 0, OUTPUT, MAIN_ITEM_VARIABLE); 483 pack_parameter(&report, 0, 1, OUTPUT, MAIN_ITEM_VARIABLE);
329 pack_parameter(&report, 0, REPORT_SIZE, 3); 484 pack_parameter(&report, 0, 1, REPORT_SIZE, 3);
330 pack_parameter(&report, 0, REPORT_COUNT, 1); 485 pack_parameter(&report, 0, 1, REPORT_COUNT, 1);
331 pack_parameter(&report, 0, OUTPUT, MAIN_ITEM_CONSTANT); 486 pack_parameter(&report, 0, 1, OUTPUT, MAIN_ITEM_CONSTANT);
332 pack_parameter(&report, 0, REPORT_SIZE, 8); 487 pack_parameter(&report, 0, 1, REPORT_SIZE, 8);
333 pack_parameter(&report, 0, REPORT_COUNT, 6); 488 pack_parameter(&report, 0, 1, REPORT_COUNT, 6);
334 pack_parameter(&report, 1, LOGICAL_MINIMUM, 0); 489 pack_parameter(&report, 1, 1, LOGICAL_MINIMUM, 0);
335 pack_parameter(&report, 1, LOGICAL_MAXIMUM, HID_KEYBOARD_EX_SEL); 490 pack_parameter(&report, 1, 1, LOGICAL_MAXIMUM, HID_KEYBOARD_EX_SEL);
336 pack_parameter(&report, 0, USAGE_PAGE, HID_USAGE_PAGE_KEYBOARD_KEYPAD); 491 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_KEYBOARD_KEYPAD);
337 pack_parameter(&report, 0, USAGE_MINIMUM, 0); 492 pack_parameter(&report, 0, 1, USAGE_MINIMUM, 0);
338 pack_parameter(&report, 0, USAGE_MAXIMUM, HID_KEYBOARD_EX_SEL); 493 pack_parameter(&report, 0, 1, USAGE_MAXIMUM, HID_KEYBOARD_EX_SEL);
339 pack_parameter(&report, 0, INPUT, 0); 494 pack_parameter(&report, 0, 1, INPUT, 0);
340 PACK_VAL1(report, END_COLLECTION); 495 PACK_VAL(report, END_COLLECTION);
341 496
342 /* Consumer usage controls - play/pause, stop, etc. */ 497 /* Consumer usage controls - play/pause, stop, etc. */
343 usb_hid_report = &usb_hid_reports[REPORT_ID_CONSUMER]; 498 usb_hid_report = &usb_hid_reports[REPORT_ID_CONSUMER];
344 usb_hid_report->usage_page = HID_USAGE_PAGE_CONSUMER; 499 usb_hid_report->usage_page = HID_USAGE_PAGE_CONSUMER;
345 usb_hid_report->buf_set = buf_set_consumer; 500 usb_hid_report->buf_set = buf_set_consumer;
501 usb_hid_report->is_key_released = 1;
346 502
347 pack_parameter(&report, 0, USAGE_PAGE, HID_USAGE_PAGE_CONSUMER); 503 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_CONSUMER);
348 PACK_VAL2(report, CONCAT(CONSUMER_USAGE, 504 pack_parameter(&report, 0, 0, CONSUMER_USAGE,
349 HID_CONSUMER_USAGE_CONSUMER_CONTROL));
350 pack_parameter(&report, 0, COLLECTION, COLLECTION_APPLICATION);
351 pack_parameter(&report, 0, REPORT_ID, REPORT_ID_CONSUMER);
352 pack_parameter(&report, 0, REPORT_SIZE, 16);
353 pack_parameter(&report, 0, REPORT_COUNT, 2);
354 pack_parameter(&report, 1, LOGICAL_MINIMUM, 1);
355 pack_parameter(&report, 1, LOGICAL_MAXIMUM, 652);
356 pack_parameter(&report, 0, USAGE_MINIMUM,
357 HID_CONSUMER_USAGE_CONSUMER_CONTROL); 505 HID_CONSUMER_USAGE_CONSUMER_CONTROL);
358 pack_parameter(&report, 0, USAGE_MAXIMUM, HID_CONSUMER_USAGE_AC_SEND); 506 pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION);
359 pack_parameter(&report, 0, INPUT, MAIN_ITEM_NO_PREFERRED | 507 pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_CONSUMER);
508 pack_parameter(&report, 0, 1, REPORT_SIZE, 16);
509 pack_parameter(&report, 0, 1, REPORT_COUNT, 2);
510 pack_parameter(&report, 1, 1, LOGICAL_MINIMUM, 1);
511 pack_parameter(&report, 1, 1, LOGICAL_MAXIMUM, 652);
512 pack_parameter(&report, 0, 1, USAGE_MINIMUM,
513 HID_CONSUMER_USAGE_CONSUMER_CONTROL);
514 pack_parameter(&report, 0, 1, USAGE_MAXIMUM, HID_CONSUMER_USAGE_AC_SEND);
515 pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_NO_PREFERRED |
360 MAIN_ITEM_NULL_STATE); 516 MAIN_ITEM_NULL_STATE);
361 PACK_VAL1(report, END_COLLECTION); 517 PACK_VAL(report, END_COLLECTION);
518
519#ifdef HAVE_USB_HID_MOUSE
520 /* Mouse control */
521 usb_hid_report = &usb_hid_reports[REPORT_ID_MOUSE];
522 usb_hid_report->usage_page = HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS;
523 usb_hid_report->buf_set = buf_set_mouse;
524 usb_hid_report->is_key_released = 0;
525
526 pack_parameter(&report, 0, 1, USAGE_PAGE,
527 HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS);
528 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_MOUSE);
529 pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_APPLICATION);
530 pack_parameter(&report, 0, 1, REPORT_ID, REPORT_ID_MOUSE);
531 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_POINTER);
532 pack_parameter(&report, 0, 1, COLLECTION, COLLECTION_PHYSICAL);
533 pack_parameter(&report, 0, 1, USAGE_PAGE, HID_USAGE_PAGE_BUTTON);
534 pack_parameter(&report, 0, 1, USAGE_MINIMUM, 1);
535 pack_parameter(&report, 0, 1, USAGE_MAXIMUM, 8);
536 pack_parameter(&report, 1, 1, LOGICAL_MINIMUM, 0);
537 pack_parameter(&report, 1, 1, LOGICAL_MAXIMUM, 1);
538 pack_parameter(&report, 0, 1, REPORT_SIZE, 1);
539 pack_parameter(&report, 0, 1, REPORT_COUNT, 8);
540 pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_VARIABLE);
541 pack_parameter(&report, 0, 1, USAGE_PAGE,
542 HID_USAGE_PAGE_GENERIC_DESKTOP_CONTROLS);
543 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_X);
544 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_Y);
545 pack_parameter(&report, 0, 0, CONSUMER_USAGE, HID_GENERIC_DESKTOP_WHEEL);
546 pack_parameter(&report, 0, 1, LOGICAL_MINIMUM, -127 & 0xFF);
547 pack_parameter(&report, 0, 1, LOGICAL_MAXIMUM, 127);
548 pack_parameter(&report, 0, 1, REPORT_SIZE, 8);
549 pack_parameter(&report, 0, 1, REPORT_COUNT, 3);
550 pack_parameter(&report, 0, 1, INPUT, MAIN_ITEM_VARIABLE | MAIN_ITEM_RELATIVE);
551 PACK_VAL(report, END_COLLECTION);
552 PACK_VAL(report, END_COLLECTION);
553#endif /* HAVE_USB_HID_MOUSE */
362 554
363 return (size_t)((uint32_t)report - (uint32_t)dest); 555 return (size_t)((uint32_t)report - (uint32_t)dest);
364} 556}
@@ -368,6 +560,9 @@ static void descriptor_hid_get(unsigned char **dest)
368 hid_descriptor.wDescriptorLength0 = 560 hid_descriptor.wDescriptorLength0 =
369 (uint16_t)descriptor_report_get(report_descriptor); 561 (uint16_t)descriptor_report_get(report_descriptor);
370 562
563 logf("hid: desc len %u", hid_descriptor.wDescriptorLength0);
564 buf_dump(report_descriptor, hid_descriptor.wDescriptorLength0, "desc");
565
371 PACK_DATA(*dest, hid_descriptor); 566 PACK_DATA(*dest, hid_descriptor);
372} 567}
373 568
@@ -457,8 +652,8 @@ void usb_hid_transfer_complete(int ep, int dir, int status, int length)
457 * to the DAP using the host's custom driver */ 652 * to the DAP using the host's custom driver */
458static int usb_hid_set_report(struct usb_ctrlrequest *req) 653static int usb_hid_set_report(struct usb_ctrlrequest *req)
459{ 654{
460 static unsigned char buf[SET_REPORT_BUF_LEN] 655 static unsigned char buf[SET_REPORT_BUF_LEN] USB_DEVBSS_ATTR
461 USB_DEVBSS_ATTR __attribute__((aligned(32))); 656 __attribute__((aligned(32)));
462 int length; 657 int length;
463 int rc = 0; 658 int rc = 0;
464 659
@@ -645,16 +840,22 @@ void usb_hid_send(usage_page_t usage_page, int id)
645 length = report->buf_set(&buf[1], id) + 1; 840 length = report->buf_set(&buf[1], id) + 1;
646 logf("length %u", length); 841 logf("length %u", length);
647 842
843 if (!length)
844 return;
845
648 /* Key pressed */ 846 /* Key pressed */
649 buf_dump(buf, length); 847 buf_dump(buf, length, "key press");
650 usb_hid_queue(buf, length); 848 usb_hid_queue(buf, length);
651 849
652 /* Key released */ 850 if (report->is_key_released)
653 memset(buf, 0, length); 851 {
654 buf[0] = report_id; 852 /* Key released */
853 memset(buf, 0, length);
854 buf[0] = report_id;
655 855
656 buf_dump(buf, length); 856 buf_dump(buf, length, "key release");
657 usb_hid_queue(buf, length); 857 usb_hid_queue(buf, length);
858 }
658 859
659 usb_hid_try_send_drv(); 860 usb_hid_try_send_drv();
660} 861}
diff --git a/firmware/usbstack/usb_hid_usage_tables.h b/firmware/usbstack/usb_hid_usage_tables.h
index 9b64cd0328..d23c704eae 100644
--- a/firmware/usbstack/usb_hid_usage_tables.h
+++ b/firmware/usbstack/usb_hid_usage_tables.h
@@ -701,5 +701,39 @@ typedef enum usage_page
701#define HID_CONSUMER_USAGE_AC_DISRIBUTE_HORIZONTALLY 0x29B 701#define HID_CONSUMER_USAGE_AC_DISRIBUTE_HORIZONTALLY 0x29B
702#define HID_CONSUMER_USAGE_AC_DISTRIBUTE_VERTICALLY 0x29C 702#define HID_CONSUMER_USAGE_AC_DISTRIBUTE_VERTICALLY 0x29C
703 703
704#endif 704#ifdef HAVE_USB_HID_MOUSE
705/* Mouse defines (custom made - Rockbox specific) */
706#define HID_MOUSE_NONE 0x00
707#define HID_MOUSE_UP 0x01
708#define HID_MOUSE_UP_REP 0x02
709#define HID_MOUSE_DOWN 0x03
710#define HID_MOUSE_DOWN_REP 0x04
711#define HID_MOUSE_LEFT 0x05
712#define HID_MOUSE_LEFT_REP 0x06
713#define HID_MOUSE_RIGHT 0x07
714#define HID_MOUSE_RIGHT_REP 0x08
715#define HID_MOUSE_LDRAG_UP 0x09
716#define HID_MOUSE_LDRAG_UP_REP 0x0A
717#define HID_MOUSE_LDRAG_DOWN 0x0B
718#define HID_MOUSE_LDRAG_DOWN_REP 0x0C
719#define HID_MOUSE_LDRAG_LEFT 0x0D
720#define HID_MOUSE_LDRAG_LEFT_REP 0x0E
721#define HID_MOUSE_LDRAG_RIGHT 0x0F
722#define HID_MOUSE_LDRAG_RIGHT_REP 0x10
723#define HID_MOUSE_RDRAG_UP 0x11
724#define HID_MOUSE_RDRAG_UP_REP 0x12
725#define HID_MOUSE_RDRAG_DOWN 0x13
726#define HID_MOUSE_RDRAG_DOWN_REP 0x14
727#define HID_MOUSE_RDRAG_LEFT 0x15
728#define HID_MOUSE_RDRAG_LEFT_REP 0x16
729#define HID_MOUSE_RDRAG_RIGHT 0x17
730#define HID_MOUSE_RDRAG_RIGHT_REP 0x18
731#define HID_MOUSE_SCROLL_UP 0x19
732#define HID_MOUSE_SCROLL_DOWN 0x1A
733#define HID_MOUSE_BUTTON_LEFT 0x1B
734#define HID_MOUSE_BUTTON_LEFT_REL 0x1C
735#define HID_MOUSE_BUTTON_RIGHT 0x1D
736#define HID_MOUSE_BUTTON_RIGHT_REL 0x1E
737#endif /* HAVE_USB_HID_MOUSE */
705 738
739#endif