|
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