]> git.donarmstrong.com Git - qmk_firmware.git/blob - ps2_vusb/keyboard_vusb.c
6ea19575904a4af3c92dc383c4e91ef9156be9a7
[qmk_firmware.git] / ps2_vusb / keyboard_vusb.c
1 #include "usbdrv.h"
2 #include "usb_keycodes.h"
3 #include "keyboard.h"
4 #include "print.h"
5
6 static report_t report0;
7 static report_t report1;
8 static report_t *report = &report0;
9 static report_t *report_prev = &report1;
10
11 void report_send(void)
12 {
13     if (usbInterruptIsReady()){
14         usbSetInterrupt((void *)report, sizeof(*report));
15     }
16 }
17
18 report_t *report_get(void)
19 {
20     return report;
21 }
22
23 uint8_t report_mods(void)
24 {
25     return report->mods;
26 }
27
28 uint8_t *report_keys(void)
29 {
30     return report->keys;
31 }
32
33 bool report_has_key(void)
34 {
35     for (int i = 0; i < REPORT_KEYS; i++) {
36         if (report->keys[i])
37             return true;
38     }
39     return false;
40 }
41
42 void report_add_mod(uint8_t mod)
43 {
44     report->mods |= mod;
45 }
46
47 void report_add_key(uint8_t code)
48 {
49     int8_t i = 0;
50     int8_t empty = -1;
51     for (; i < REPORT_KEYS; i++) {
52         if (report_prev->keys[i] == code) {
53             report->keys[i] = code;
54             break;
55         }
56         if (empty == -1 && report_prev->keys[i] == KB_NO && report->keys[i] == KB_NO) {
57             empty = i;
58         }
59     }
60     if (i == REPORT_KEYS && empty != -1) {
61         report->keys[empty] = code;
62     }
63 }
64
65 void report_add_code(uint8_t code)
66 {
67     if (IS_MOD(code)) {
68         report_add_mod(code);
69     } else {
70         report_add_key(code);
71     }
72 }
73
74 void report_swap(void)
75 {
76     report_t *tmp = report_prev;
77     report_prev = report;
78     report = tmp;
79 }
80
81 void report_clear(void)
82 {
83     report->mods = 0;
84     for (int8_t i = 0; i < REPORT_KEYS; i++) {
85         report->keys[i] = 0;
86     }
87 }
88
89
90 static uchar    idleRate;   /* repeat rate for keyboards, never used for mice */
91 usbMsgLen_t usbFunctionSetup(uchar data[8])
92 {
93 usbRequest_t    *rq = (void *)data;
94
95     print("Setup: ");
96     if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){    /* class request type */
97         print("CLASS: ");
98         phex(rq->bRequest);
99         if(rq->bRequest == USBRQ_HID_GET_REPORT){
100             print("GET_REPORT");
101             /* we only have one report type, so don't look at wValue */
102             usbMsgPtr = (void *)report;
103             return sizeof(*report);
104         }else if(rq->bRequest == USBRQ_HID_GET_IDLE){
105             print("GET_IDLE: ");
106             phex(idleRate);
107             usbMsgPtr = &idleRate;
108             return 1;
109         }else if(rq->bRequest == USBRQ_HID_SET_IDLE){
110             idleRate = rq->wValue.bytes[1];
111             print("SET_IDLE: ");
112             phex(idleRate);
113         }
114         print("\n");
115     }else{
116         print("VENDOR\n");
117         /* no vendor specific requests implemented */
118     }
119     return 0;   /* default for not implemented requests: return no data back to host */
120 }
121
122
123 PROGMEM char usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {
124     0x05, 0x01,          // Usage Page (Generic Desktop),
125     0x09, 0x06,          // Usage (Keyboard),
126     0xA1, 0x01,          // Collection (Application),
127     0x75, 0x01,          //   Report Size (1),
128     0x95, 0x08,          //   Report Count (8),
129     0x05, 0x07,          //   Usage Page (Key Codes),
130     0x19, 0xE0,          //   Usage Minimum (224),
131     0x29, 0xE7,          //   Usage Maximum (231),
132     0x15, 0x00,          //   Logical Minimum (0),
133     0x25, 0x01,          //   Logical Maximum (1),
134     0x81, 0x02,          //   Input (Data, Variable, Absolute), ;Modifier byte
135     0x95, 0x01,          //   Report Count (1),
136     0x75, 0x08,          //   Report Size (8),
137     0x81, 0x03,          //   Input (Constant),                 ;Reserved byte
138     0x95, 0x05,          //   Report Count (5),
139     0x75, 0x01,          //   Report Size (1),
140     0x05, 0x08,          //   Usage Page (LEDs),
141     0x19, 0x01,          //   Usage Minimum (1),
142     0x29, 0x05,          //   Usage Maximum (5),
143     0x91, 0x02,          //   Output (Data, Variable, Absolute), ;LED report
144     0x95, 0x01,          //   Report Count (1),
145     0x75, 0x03,          //   Report Size (3),
146     0x91, 0x03,          //   Output (Constant),                 ;LED report padding
147     0x95, 0x06,          //   Report Count (6),
148     0x75, 0x08,          //   Report Size (8),
149     0x15, 0x00,          //   Logical Minimum (0),
150     0x25, 0xFF,          //   Logical Maximum(255),
151     0x05, 0x07,          //   Usage Page (Key Codes),
152     0x19, 0x00,          //   Usage Minimum (0),
153     0x29, 0xFF,          //   Usage Maximum (255),
154     0x81, 0x00,          //   Input (Data, Array),
155     0xc0                 // End Collection
156 };