diff options
Diffstat (limited to 'lib/chibios-contrib/testhal/NUMICRO/NUC123/NUTINY-SDK-NUC123-V2.0/USB_HID/usbcfg.c')
-rw-r--r-- | lib/chibios-contrib/testhal/NUMICRO/NUC123/NUTINY-SDK-NUC123-V2.0/USB_HID/usbcfg.c | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/lib/chibios-contrib/testhal/NUMICRO/NUC123/NUTINY-SDK-NUC123-V2.0/USB_HID/usbcfg.c b/lib/chibios-contrib/testhal/NUMICRO/NUC123/NUTINY-SDK-NUC123-V2.0/USB_HID/usbcfg.c new file mode 100644 index 000000000..95fe7bfb1 --- /dev/null +++ b/lib/chibios-contrib/testhal/NUMICRO/NUC123/NUTINY-SDK-NUC123-V2.0/USB_HID/usbcfg.c | |||
@@ -0,0 +1,393 @@ | |||
1 | /* | ||
2 | Copyright (C) 2016 Jonathan Struebel | ||
3 | Modifications copyright (C) 2020 Alex Lewontin | ||
4 | |||
5 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | you may not use this file except in compliance with the License. | ||
7 | You may obtain a copy of the License at | ||
8 | |||
9 | http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | |||
11 | Unless required by applicable law or agreed to in writing, software | ||
12 | distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | See the License for the specific language governing permissions and | ||
15 | limitations under the License. | ||
16 | */ | ||
17 | |||
18 | /** | ||
19 | * @file usbcfg.c | ||
20 | * @brief USB driver config. | ||
21 | * | ||
22 | * @addtogroup USB | ||
23 | * @{ | ||
24 | */ | ||
25 | #include "hal.h" | ||
26 | #include "usbcfg.h" | ||
27 | |||
28 | #define VID 0x1209 | ||
29 | #define PID 0x0003 | ||
30 | /* | ||
31 | * Endpoints to be used for USBD1. | ||
32 | */ | ||
33 | #define USBD1_DATA_REQUEST_EP 1 | ||
34 | #define USBD1_DATA_AVAILABLE_EP 1 | ||
35 | |||
36 | /* | ||
37 | * USB HID Driver structure. | ||
38 | */ | ||
39 | USBHIDDriver UHD1; | ||
40 | |||
41 | /* | ||
42 | * Data used for feedback | ||
43 | */ | ||
44 | uint8_t increment_var = 0; | ||
45 | |||
46 | /* | ||
47 | * USB Device Descriptor. | ||
48 | */ | ||
49 | static const uint8_t hid_device_descriptor_data[] = { | ||
50 | USB_DESC_DEVICE (0x0110, /* bcdUSB (1.1). */ | ||
51 | 0x00, /* bDeviceClass. */ | ||
52 | 0x00, /* bDeviceSubClass. */ | ||
53 | 0x00, /* bDeviceProtocol. */ | ||
54 | 0x40, /* bMaxPacketSize. */ | ||
55 | VID, /* idVendor. */ | ||
56 | PID, /* idProduct. */ | ||
57 | 0x000, /* bcdDevice. */ | ||
58 | 1, /* iManufacturer. */ | ||
59 | 2, /* iProduct. */ | ||
60 | 3, /* iSerialNumber. */ | ||
61 | 1) /* bNumConfigurations. */ | ||
62 | }; | ||
63 | |||
64 | /* | ||
65 | * Device Descriptor wrapper. | ||
66 | */ | ||
67 | static const USBDescriptor hid_device_descriptor = { | ||
68 | sizeof hid_device_descriptor_data, | ||
69 | hid_device_descriptor_data | ||
70 | }; | ||
71 | |||
72 | /* | ||
73 | * Configuration Descriptor tree for a HID device | ||
74 | * | ||
75 | * The HID Specifications version 1.11 require the following order: | ||
76 | * - Configuration Descriptor | ||
77 | * - Interface Descriptor | ||
78 | * - HID Descriptor | ||
79 | * - Endpoints Descriptors | ||
80 | */ | ||
81 | #define HID_DESCRIPTOR_OFFSET 18 | ||
82 | #define HID_DESCRIPTOR_SIZE USB_DESC_HID_SIZE | ||
83 | |||
84 | static const uint8_t hid_configuration_descriptor_data[] = { | ||
85 | /* Configuration Descriptor.*/ | ||
86 | USB_DESC_CONFIGURATION(41, /* wTotalLength. */ | ||
87 | 0x01, /* bNumInterfaces. */ | ||
88 | 0x01, /* bConfigurationValue. */ | ||
89 | 0, /* iConfiguration. */ | ||
90 | 0xC0, /* bmAttributes (self powered). */ | ||
91 | 50), /* bMaxPower (100mA). */ | ||
92 | /* Interface Descriptor.*/ | ||
93 | USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */ | ||
94 | 0x00, /* bAlternateSetting. */ | ||
95 | 0x02, /* bNumEndpoints. */ | ||
96 | 0x03, /* bInterfaceClass (HID Interface | ||
97 | Class). */ | ||
98 | 0x00, /* bInterfaceSubClass (None). */ | ||
99 | 0x00, /* bInterfaceProtocol (None). */ | ||
100 | 0), /* iInterface. */ | ||
101 | /* HID Descriptor.*/ | ||
102 | USB_DESC_HID (0x0110, /* bcdHID. */ | ||
103 | 0x00, /* bCountryCode. */ | ||
104 | 0x01, /* bNumDescriptors. */ | ||
105 | 0x22, /* bDescriptorType (Report | ||
106 | Descriptor). */ | ||
107 | 34), /* wDescriptorLength. */ | ||
108 | /* Endpoint 1 Descriptor.*/ | ||
109 | USB_DESC_ENDPOINT (USBD1_DATA_AVAILABLE_EP, /* bEndpointAddress.*/ | ||
110 | 0x03, /* bmAttributes (Interrupt). */ | ||
111 | 0x0040, /* wMaxPacketSize. */ | ||
112 | 0x0A), /* bInterval (10ms). */ | ||
113 | /* Endpoint 1 Descriptor.*/ | ||
114 | USB_DESC_ENDPOINT (USBD1_DATA_REQUEST_EP|0x80, /* bEndpointAddress.*/ | ||
115 | 0x03, /* bmAttributes (Interrupt). */ | ||
116 | 0x0040, /* wMaxPacketSize. */ | ||
117 | 0x0A) /* bInterval (10ms). */ | ||
118 | }; | ||
119 | |||
120 | /* | ||
121 | * Configuration Descriptor wrapper. | ||
122 | */ | ||
123 | static const USBDescriptor hid_configuration_descriptor = { | ||
124 | sizeof hid_configuration_descriptor_data, | ||
125 | hid_configuration_descriptor_data | ||
126 | }; | ||
127 | |||
128 | /* | ||
129 | * HID Descriptor wrapper. | ||
130 | */ | ||
131 | static const USBDescriptor hid_descriptor = { | ||
132 | HID_DESCRIPTOR_SIZE, | ||
133 | &hid_configuration_descriptor_data[HID_DESCRIPTOR_OFFSET] | ||
134 | }; | ||
135 | |||
136 | /* | ||
137 | * HID Report Descriptor | ||
138 | * | ||
139 | * This is the description of the format and the content of the | ||
140 | * different IN or/and OUT reports that your application can | ||
141 | * receive/send | ||
142 | * | ||
143 | * See "Device Class Definition for Human Interface Devices (HID)" | ||
144 | * (http://www.usb.org/developers/hidpage/HID1_11.pdf) for the | ||
145 | * detailed description of all the fields | ||
146 | */ | ||
147 | static const uint8_t hid_report_descriptor_data[] = { | ||
148 | USB_DESC_BYTE (0x06), /* Usage Page - */ | ||
149 | USB_DESC_WORD (0xFF00), /* Vendor Defined. */ | ||
150 | USB_DESC_BYTE (0x09), /* Usage - */ | ||
151 | USB_DESC_BYTE (0x01), /* Vendor Defined. */ | ||
152 | USB_DESC_BYTE (0xA1), /* Collection - */ | ||
153 | USB_DESC_BYTE (0x01), /* Application. */ | ||
154 | |||
155 | USB_DESC_BYTE (0x09), /* Usage - */ | ||
156 | USB_DESC_BYTE (0x01), /* Vendor Defined. */ | ||
157 | USB_DESC_BYTE (0x15), /* Logical Minimum - */ | ||
158 | USB_DESC_BYTE (0x00), /* 0. */ | ||
159 | USB_DESC_BYTE (0x26), /* Logical Maximum - */ | ||
160 | USB_DESC_WORD (0x00FF), /* 255. */ | ||
161 | USB_DESC_BYTE (0x75), /* Report size - */ | ||
162 | USB_DESC_BYTE (0x08), /* 8 bits. */ | ||
163 | USB_DESC_BYTE (0x95), /* Report count - */ | ||
164 | USB_DESC_BYTE (0x01), /* 1. */ | ||
165 | USB_DESC_BYTE (0x81), /* Input - */ | ||
166 | USB_DESC_BYTE (0x02), /* Data, Variable, Absolute. */ | ||
167 | |||
168 | USB_DESC_BYTE (0x09), /* Usage - */ | ||
169 | USB_DESC_BYTE (0x01), /* Vendor Defined. */ | ||
170 | USB_DESC_BYTE (0x15), /* Logical Minimum - */ | ||
171 | USB_DESC_BYTE (0x00), /* 0. */ | ||
172 | USB_DESC_BYTE (0x26), /* Logical Maximum - */ | ||
173 | USB_DESC_WORD (0x00FF), /* 255. */ | ||
174 | USB_DESC_BYTE (0x75), /* Report Size - */ | ||
175 | USB_DESC_BYTE (0x08), /* 8 bits. */ | ||
176 | USB_DESC_BYTE (0x95), /* Report Count - */ | ||
177 | USB_DESC_BYTE (0x01), /* 1. */ | ||
178 | USB_DESC_BYTE (0x91), /* Output - */ | ||
179 | USB_DESC_BYTE (0x02), /* Data, Variable, Absolute. */ | ||
180 | |||
181 | USB_DESC_BYTE (0xC0) /* End Collection. */ | ||
182 | }; | ||
183 | |||
184 | /* | ||
185 | * HID Report Descriptor wrapper | ||
186 | */ | ||
187 | static const USBDescriptor hid_report_descriptor = { | ||
188 | sizeof hid_report_descriptor_data, | ||
189 | hid_report_descriptor_data | ||
190 | }; | ||
191 | |||
192 | /* | ||
193 | * U.S. English language identifier. | ||
194 | */ | ||
195 | static const uint8_t usb_string_langid[] = | ||
196 | USB_DESC_STRING(USB_DESC_WORD(0x0409)); /* wLANGID (U.S. English) */ | ||
197 | |||
198 | /* | ||
199 | * Vendor string. | ||
200 | */ | ||
201 | static const uint8_t usb_string_vendor[] = | ||
202 | USB_DESC_STRING('N', 0, 'u', 0, 'v', 0, 'o', 0, 't', 0, 'o', 0, 'n', 0); | ||
203 | |||
204 | /* | ||
205 | * Serial Number string. | ||
206 | */ | ||
207 | static const uint8_t usb_string_serial[] = | ||
208 | USB_DESC_STRING('0', 0, 'x', 0, 'D', 0, 'E', 0, 'A', 0, 'D', 0, 'B', 0, 'E', 0, 'E', 0, 'F', 0); | ||
209 | |||
210 | /* | ||
211 | * Device Description string. | ||
212 | */ | ||
213 | static const uint8_t usb_string_description[] = | ||
214 | USB_DESC_STRING('C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0, 'H', 0, 'A', 0, | ||
215 | 'L', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0, ' ', 0, 'D', 0, 'e', 0, 'm', 0, 'o', 0); | ||
216 | /* | ||
217 | * Strings wrappers array. | ||
218 | */ | ||
219 | static const USBDescriptor hid_strings[] = { | ||
220 | {sizeof usb_string_langid, usb_string_langid}, | ||
221 | {sizeof usb_string_vendor, usb_string_vendor}, | ||
222 | {sizeof usb_string_description, usb_string_description}, | ||
223 | {sizeof usb_string_serial, usb_string_serial} | ||
224 | }; | ||
225 | |||
226 | /* | ||
227 | * Handles the GET_DESCRIPTOR callback. All required descriptors must be | ||
228 | * handled here. | ||
229 | */ | ||
230 | static const USBDescriptor *get_descriptor(USBDriver *usbp, | ||
231 | uint8_t dtype, | ||
232 | uint8_t dindex, | ||
233 | uint16_t lang) { | ||
234 | (void)usbp; | ||
235 | (void)lang; | ||
236 | switch (dtype) { | ||
237 | case USB_DESCRIPTOR_DEVICE: | ||
238 | return &hid_device_descriptor; | ||
239 | case USB_DESCRIPTOR_CONFIGURATION: | ||
240 | return &hid_configuration_descriptor; | ||
241 | case USB_DESCRIPTOR_STRING: | ||
242 | if (dindex < 4) | ||
243 | return &hid_strings[dindex]; | ||
244 | case USB_DESCRIPTOR_INTERFACE: | ||
245 | break; | ||
246 | case USB_DESCRIPTOR_ENDPOINT: | ||
247 | break; | ||
248 | case USB_DESCRIPTOR_HID: | ||
249 | return &hid_descriptor; | ||
250 | case HID_REPORT: | ||
251 | return &hid_report_descriptor; | ||
252 | default: | ||
253 | break; | ||
254 | } | ||
255 | return NULL; | ||
256 | } | ||
257 | |||
258 | /** | ||
259 | * @brief IN EP1 state. | ||
260 | */ | ||
261 | static USBInEndpointState ep1instate; | ||
262 | |||
263 | /** | ||
264 | * @brief OUT EP1 state. | ||
265 | */ | ||
266 | static USBOutEndpointState ep1outstate; | ||
267 | |||
268 | /** | ||
269 | * @brief EP1 initialization structure (both IN and OUT). | ||
270 | */ | ||
271 | static const USBEndpointConfig ep1config = { | ||
272 | USB_EP_MODE_TYPE_INTR, | ||
273 | NULL, | ||
274 | hidDataTransmitted, | ||
275 | hidDataReceived, | ||
276 | 0x0040, | ||
277 | 0x0040, | ||
278 | &ep1instate, | ||
279 | &ep1outstate, | ||
280 | 0, | ||
281 | NULL | ||
282 | }; | ||
283 | |||
284 | /* | ||
285 | * Handles the USB driver global events. | ||
286 | */ | ||
287 | static void usb_event(USBDriver *usbp, usbevent_t event) { | ||
288 | switch (event) { | ||
289 | case USB_EVENT_RESET: | ||
290 | return; | ||
291 | case USB_EVENT_ADDRESS: | ||
292 | return; | ||
293 | case USB_EVENT_CONFIGURED: | ||
294 | osalSysLockFromISR(); | ||
295 | |||
296 | /* Enables the endpoints specified into the configuration. | ||
297 | Note, this callback is invoked from an ISR so I-Class functions | ||
298 | must be used.*/ | ||
299 | usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config); | ||
300 | |||
301 | /* Resetting the state of the CDC subsystem.*/ | ||
302 | hidConfigureHookI(&UHD1); | ||
303 | |||
304 | osalSysUnlockFromISR(); | ||
305 | return; | ||
306 | case USB_EVENT_UNCONFIGURED: | ||
307 | return; | ||
308 | case USB_EVENT_SUSPEND: | ||
309 | return; | ||
310 | case USB_EVENT_WAKEUP: | ||
311 | return; | ||
312 | case USB_EVENT_STALLED: | ||
313 | return; | ||
314 | } | ||
315 | return; | ||
316 | } | ||
317 | |||
318 | static bool req_handler(USBDriver *usbp) { | ||
319 | size_t n; | ||
320 | |||
321 | if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) { | ||
322 | switch (usbp->setup[1]) { | ||
323 | case HID_GET_REPORT: | ||
324 | n = hidGetReport(0, &increment_var, sizeof(increment_var)); | ||
325 | usbSetupTransfer(usbp, &increment_var, n, NULL); | ||
326 | return true; | ||
327 | default: | ||
328 | return hidRequestsHook(usbp); | ||
329 | } | ||
330 | } | ||
331 | return hidRequestsHook(usbp); | ||
332 | } | ||
333 | |||
334 | /** | ||
335 | * @brief Generate HID Report | ||
336 | * @details This function generates the data for an HID report so | ||
337 | * that it can be transferred to the host. | ||
338 | * | ||
339 | * @param[in] id report ID | ||
340 | * @param[out] bp data buffer pointer | ||
341 | * @param[in] n the maximum number of bytes for data buffer | ||
342 | * @return number of bytes of report in data buffer | ||
343 | */ | ||
344 | size_t hidGetReport(uint8_t id, uint8_t *bp, size_t n) { | ||
345 | |||
346 | (void) id; | ||
347 | (void) n; | ||
348 | |||
349 | increment_var++; | ||
350 | *bp = increment_var; | ||
351 | return sizeof(increment_var); | ||
352 | } | ||
353 | |||
354 | /** | ||
355 | * @brief Set HID Report | ||
356 | * @details This function sets the data for an HID report | ||
357 | * that was transferred from the host. | ||
358 | * | ||
359 | * @param[in] id report ID | ||
360 | * @param[in] bp data buffer pointer | ||
361 | * @param[in] n the number of bytes in data buffer | ||
362 | * @return The operation status. | ||
363 | * @retval MSG_OK if the report was set. | ||
364 | */ | ||
365 | msg_t hidSetReport(uint8_t id, uint8_t *bp, size_t n) { | ||
366 | |||
367 | (void) id; | ||
368 | (void) n; | ||
369 | |||
370 | increment_var = *bp; | ||
371 | return MSG_OK; | ||
372 | } | ||
373 | |||
374 | /* | ||
375 | * USB driver configuration. | ||
376 | */ | ||
377 | const USBConfig usbcfg = { | ||
378 | usb_event, | ||
379 | get_descriptor, | ||
380 | req_handler, | ||
381 | NULL | ||
382 | }; | ||
383 | |||
384 | /* | ||
385 | * USB HID driver configuration. | ||
386 | */ | ||
387 | const USBHIDConfig usbhidcfg = { | ||
388 | &USBD1, | ||
389 | USBD1_DATA_REQUEST_EP, | ||
390 | USBD1_DATA_AVAILABLE_EP | ||
391 | }; | ||
392 | |||
393 | /** @} */ | ||