|
13 | 13 | ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
14 | 14 | ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
15 | 15 | ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
16 |
| -** SOFTWARE. |
| 16 | +** SOFTWARE. |
17 | 17 | */
|
18 | 18 |
|
19 |
| -#include "USB/PluggableUSB.h" |
20 | 19 | #include "HID.h"
|
21 | 20 |
|
22 |
| -HID_ HID; |
| 21 | +#if defined(USBCON) |
23 | 22 |
|
24 |
| -static uint8_t HID_ENDPOINT_INT; |
25 |
| - |
26 |
| -//================================================================================ |
27 |
| -//================================================================================ |
28 |
| - |
29 |
| -// HID report descriptor |
30 |
| - |
31 |
| -#define LSB(_x) ((_x) & 0xFF) |
32 |
| -#define MSB(_x) ((_x) >> 8) |
33 |
| - |
34 |
| -#define RAWHID_USAGE_PAGE 0xFFC0 |
35 |
| -#define RAWHID_USAGE 0x0C00 |
36 |
| -#define RAWHID_TX_SIZE 64 |
37 |
| -#define RAWHID_RX_SIZE 64 |
38 |
| - |
39 |
| -static uint8_t HID_INTERFACE; |
40 |
| - |
41 |
| -HIDDescriptor _hidInterface; |
42 |
| - |
43 |
| -static HIDDescriptorListNode* rootNode = NULL; |
44 |
| -static uint8_t sizeof_hidReportDescriptor = 0; |
45 |
| -static uint8_t modules_count = 0; |
46 |
| -//================================================================================ |
47 |
| -//================================================================================ |
48 |
| -// Driver |
49 |
| - |
50 |
| -uint8_t _hid_protocol = 1; |
51 |
| -uint8_t _hid_idle = 1; |
| 23 | +HID_& HID() |
| 24 | +{ |
| 25 | + static HID_ obj; |
| 26 | + return obj; |
| 27 | +} |
52 | 28 |
|
53 |
| -int HID_GetInterface(uint8_t* interfaceNum) |
| 29 | +int HID_::getInterface(uint8_t* interfaceCount) |
54 | 30 | {
|
55 |
| - interfaceNum[0] += 1; // uses 1 |
56 |
| - _hidInterface = |
57 |
| - { |
58 |
| - D_INTERFACE(HID_INTERFACE,1,3,0,0), |
59 |
| - D_HIDREPORT(sizeof_hidReportDescriptor), |
60 |
| - D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01) |
| 31 | + *interfaceCount += 1; // uses 1 |
| 32 | + HIDDescriptor hidInterface = { |
| 33 | + D_INTERFACE(pluggedInterface, 1, USB_DEVICE_CLASS_HUMAN_INTERFACE, HID_SUBCLASS_NONE, HID_PROTOCOL_NONE), |
| 34 | + D_HIDREPORT(descriptorSize), |
| 35 | + D_ENDPOINT(USB_ENDPOINT_IN(pluggedEndpoint), USB_ENDPOINT_TYPE_INTERRUPT, 0x40, 0x01) |
61 | 36 | };
|
62 |
| - return USBD_SendControl(0,&_hidInterface,sizeof(_hidInterface)); |
| 37 | + return USBD_SendControl(0, &hidInterface, sizeof(hidInterface)); |
63 | 38 | }
|
64 | 39 |
|
65 |
| -int HID_GetDescriptor(int8_t t) |
| 40 | +int HID_::getDescriptor(USBSetup& setup) |
66 | 41 | {
|
67 |
| - if (HID_REPORT_DESCRIPTOR_TYPE == t) { |
68 |
| - HIDDescriptorListNode* current = rootNode; |
69 |
| - int total = 0; |
70 |
| - while(current != NULL) { |
71 |
| - total += USBD_SendControl(0,current->data,current->length); |
72 |
| - current = current->next; |
73 |
| - } |
74 |
| - return total; |
75 |
| - } else { |
76 |
| - return 0; |
| 42 | + // Check if this is a HID Class Descriptor request |
| 43 | + if (setup.bmRequestType != REQUEST_DEVICETOHOST_STANDARD_INTERFACE) { return 0; } |
| 44 | + if (setup.wValueH != HID_REPORT_DESCRIPTOR_TYPE) { return 0; } |
| 45 | + |
| 46 | + // In a HID Class Descriptor wIndex cointains the interface number |
| 47 | + if (setup.wIndex != pluggedInterface) { return 0; } |
| 48 | + |
| 49 | + int total = 0; |
| 50 | + HIDSubDescriptor* node; |
| 51 | + for (node = rootNode; node; node = node->next) { |
| 52 | + int res = USBD_SendControl(0, node->data, node->length); |
| 53 | + if (res == -1) |
| 54 | + return -1; |
| 55 | + total += res; |
77 | 56 | }
|
| 57 | + return total; |
78 | 58 | }
|
79 | 59 |
|
80 |
| -void HID_::AppendDescriptor(HIDDescriptorListNode *node) |
| 60 | +void HID_::AppendDescriptor(HIDSubDescriptor *node) |
81 | 61 | {
|
82 |
| - if (modules_count == 0) { |
| 62 | + if (!rootNode) { |
83 | 63 | rootNode = node;
|
84 | 64 | } else {
|
85 |
| - HIDDescriptorListNode *current = rootNode; |
86 |
| - while(current->next != NULL) { |
| 65 | + HIDSubDescriptor *current = rootNode; |
| 66 | + while (current->next) { |
87 | 67 | current = current->next;
|
88 | 68 | }
|
89 | 69 | current->next = node;
|
90 | 70 | }
|
91 |
| - modules_count++; |
92 |
| - sizeof_hidReportDescriptor += node->length; |
| 71 | + descriptorSize += node->length; |
93 | 72 | }
|
94 | 73 |
|
95 | 74 | void HID_::SendReport(uint8_t id, const void* data, int len)
|
96 | 75 | {
|
97 | 76 | uint8_t p[64];
|
98 |
| - const uint8_t *d = reinterpret_cast<const uint8_t *>(data); |
99 |
| - |
100 | 77 | p[0] = id;
|
101 |
| - for (uint32_t i=0; i<len; i++) |
102 |
| - p[i+1] = d[i]; |
103 |
| - USBD_Send(HID_TX, p, len+1); |
| 78 | + memcpy(&p[1], data, len); |
| 79 | + USBD_Send(pluggedEndpoint, p, len+1); |
104 | 80 | }
|
105 | 81 |
|
106 |
| -bool HID_Setup(USBSetup& setup, uint8_t i) |
| 82 | +bool HID_::setup(USBSetup& setup) |
107 | 83 | {
|
108 |
| - if (HID_INTERFACE != i) { |
| 84 | + if (pluggedInterface != setup.wIndex) { |
109 | 85 | return false;
|
110 |
| - } else { |
111 |
| - uint8_t r = setup.bRequest; |
112 |
| - uint8_t requestType = setup.bmRequestType; |
113 |
| - if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) |
114 |
| - { |
115 |
| - if (HID_GET_REPORT == r) |
116 |
| - { |
117 |
| - //HID_GetReport(); |
118 |
| - return true; |
119 |
| - } |
120 |
| - if (HID_GET_PROTOCOL == r) |
121 |
| - { |
122 |
| - //Send8(_hid_protocol); // TODO |
123 |
| - return true; |
124 |
| - } |
| 86 | + } |
| 87 | + |
| 88 | + uint8_t request = setup.bRequest; |
| 89 | + uint8_t requestType = setup.bmRequestType; |
| 90 | + |
| 91 | + if (requestType == REQUEST_DEVICETOHOST_CLASS_INTERFACE) |
| 92 | + { |
| 93 | + if (request == HID_GET_REPORT) { |
| 94 | + // TODO: HID_GetReport(); |
| 95 | + return true; |
| 96 | + } |
| 97 | + if (request == HID_GET_PROTOCOL) { |
| 98 | + // TODO: Send8(protocol); |
| 99 | + return true; |
| 100 | + } |
| 101 | + if (request == HID_GET_IDLE) { |
| 102 | + // TODO: Send8(idle); |
| 103 | + } |
| 104 | + } |
| 105 | + |
| 106 | + if (requestType == REQUEST_HOSTTODEVICE_CLASS_INTERFACE) |
| 107 | + { |
| 108 | + if (request == HID_SET_PROTOCOL) { |
| 109 | + // The USB Host tells us if we are in boot or report mode. |
| 110 | + // This only works with a real boot compatible device. |
| 111 | + protocol = setup.wValueL; |
| 112 | + return true; |
125 | 113 | }
|
126 |
| - |
127 |
| - if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) |
| 114 | + if (request == HID_SET_IDLE) { |
| 115 | + idle = setup.wValueL; |
| 116 | + return true; |
| 117 | + } |
| 118 | + if (request == HID_SET_REPORT) |
128 | 119 | {
|
129 |
| - if (HID_SET_PROTOCOL == r) |
130 |
| - { |
131 |
| - _hid_protocol = setup.wValueL; |
132 |
| - return true; |
133 |
| - } |
134 |
| - |
135 |
| - if (HID_SET_IDLE == r) |
136 |
| - { |
137 |
| - _hid_idle = setup.wValueL; |
138 |
| - return true; |
139 |
| - } |
| 120 | + //uint8_t reportID = setup.wValueL; |
| 121 | + //uint16_t length = setup.wLength; |
| 122 | + //uint8_t data[length]; |
| 123 | + // Make sure to not read more data than USB_EP_SIZE. |
| 124 | + // You can read multiple times through a loop. |
| 125 | + // The first byte (may!) contain the reportID on a multreport. |
| 126 | + //USB_RecvControl(data, length); |
140 | 127 | }
|
141 |
| - return false; |
142 | 128 | }
|
| 129 | + |
| 130 | + return false; |
143 | 131 | }
|
144 | 132 |
|
145 |
| -HID_::HID_(void) |
| 133 | +HID_::HID_(void) : PluggableUSBModule(1, 1, epType), |
| 134 | + rootNode(NULL), descriptorSize(0), |
| 135 | + protocol(1), idle(1) |
146 | 136 | {
|
147 |
| - static uint32_t endpointType[1]; |
148 |
| - |
149 |
| - endpointType[0] = EP_TYPE_INTERRUPT_IN; |
150 |
| - |
151 |
| - static PUSBCallbacks cb = { |
152 |
| - .setup = &HID_Setup, |
153 |
| - .getInterface = &HID_GetInterface, |
154 |
| - .getDescriptor = &HID_GetDescriptor, |
155 |
| - .numEndpoints = 1, |
156 |
| - .numInterfaces = 1, |
157 |
| - .endpointType = endpointType, |
158 |
| - }; |
159 |
| - |
160 |
| - static PUSBListNode node(&cb); |
161 |
| - |
162 |
| - HID_ENDPOINT_INT = PUSB_AddFunction(&node, &HID_INTERFACE); |
| 137 | + epType[0] = EP_TYPE_INTERRUPT_IN; |
| 138 | + PluggableUSB().plug(this); |
163 | 139 | }
|
164 | 140 |
|
165 | 141 | int HID_::begin(void)
|
166 | 142 | {
|
167 | 143 | return 0;
|
168 | 144 | }
|
| 145 | + |
| 146 | +#endif /* if defined(USBCON) */ |
0 commit comments