4 * \brief USB Device Human Interface Device (HID) keyboard interface.
6 * Copyright (c) 2009-2015 Atmel Corporation. All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions are met:
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
22 * 3. The name of Atmel may not be used to endorse or promote products derived
23 * from this software without specific prior written permission.
25 * 4. This software may only be redistributed and used in connection with an
26 * Atmel microcontroller product.
28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
47 #include "samd51j18a.h"
50 #include "usb_protocol.h"
53 #include "udi_device_conf.h"
55 #include "udi_hid_kbd.h"
59 //***************************************************************************
61 //***************************************************************************
64 bool udi_hid_kbd_enable(void);
65 void udi_hid_kbd_disable(void);
66 bool udi_hid_kbd_setup(void);
67 uint8_t udi_hid_kbd_getsetting(void);
69 UDC_DESC_STORAGE udi_api_t udi_api_hid_kbd = {
70 .enable = (bool(*)(void))udi_hid_kbd_enable,
71 .disable = (void (*)(void))udi_hid_kbd_disable,
72 .setup = (bool(*)(void))udi_hid_kbd_setup,
73 .getsetting = (uint8_t(*)(void))udi_hid_kbd_getsetting,
78 static uint8_t udi_hid_kbd_rate;
81 static uint8_t udi_hid_kbd_protocol;
84 uint8_t udi_hid_kbd_report_set;
86 bool udi_hid_kbd_b_report_valid;
89 uint8_t udi_hid_kbd_report[UDI_HID_KBD_REPORT_SIZE];
91 volatile bool udi_hid_kbd_b_report_trans_ongoing;
94 static uint8_t udi_hid_kbd_report_trans[UDI_HID_KBD_REPORT_SIZE];
97 UDC_DESC_STORAGE udi_hid_kbd_report_desc_t udi_hid_kbd_report_desc = {
99 0x05, 0x01, // Usage Page (Generic Desktop)
100 0x09, 0x06, // Usage (Keyboard)
101 0xA1, 0x01, // Collection (Application)
102 0x05, 0x07, // Usage Page (Keyboard)
103 0x19, 0xE0, // Usage Minimum (224)
104 0x29, 0xE7, // Usage Maximum (231)
105 0x15, 0x00, // Logical Minimum (0)
106 0x25, 0x01, // Logical Maximum (1)
107 0x75, 0x01, // Report Size (1)
108 0x95, 0x08, // Report Count (8)
109 0x81, 0x02, // Input (Data, Variable, Absolute)
110 0x81, 0x01, // Input (Constant)
111 0x19, 0x00, // Usage Minimum (0)
112 0x29, 0x65, // Usage Maximum (101)
113 0x15, 0x00, // Logical Minimum (0)
114 0x25, 0x65, // Logical Maximum (101)
115 0x75, 0x08, // Report Size (8)
116 0x95, 0x06, // Report Count (6)
117 0x81, 0x00, // Input (Data, Array)
118 0x05, 0x08, // Usage Page (LED)
119 0x19, 0x01, // Usage Minimum (1)
120 0x29, 0x05, // Usage Maximum (5)
121 0x15, 0x00, // Logical Minimum (0)
122 0x25, 0x01, // Logical Maximum (1)
123 0x75, 0x01, // Report Size (1)
124 0x95, 0x05, // Report Count (5)
125 0x91, 0x02, // Output (Data, Variable, Absolute)
126 0x95, 0x03, // Report Count (3)
127 0x91, 0x01, // Output (Constant)
128 0xC0 // End Collection
132 static bool udi_hid_kbd_setreport(void);
134 static void udi_hid_kbd_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
136 static void udi_hid_kbd_setreport_valid(void);
138 bool udi_hid_kbd_enable(void)
140 // Initialize internal values
141 udi_hid_kbd_rate = 0;
142 udi_hid_kbd_protocol = 0;
143 udi_hid_kbd_b_report_trans_ongoing = false;
144 memset(udi_hid_kbd_report, 0, UDI_HID_KBD_REPORT_SIZE);
145 udi_hid_kbd_b_report_valid = false;
146 return UDI_HID_KBD_ENABLE_EXT();
149 void udi_hid_kbd_disable(void)
151 UDI_HID_KBD_DISABLE_EXT();
154 bool udi_hid_kbd_setup(void)
156 return udi_hid_setup(&udi_hid_kbd_rate,
157 &udi_hid_kbd_protocol,
158 (uint8_t *) &udi_hid_kbd_report_desc,
159 udi_hid_kbd_setreport);
162 uint8_t udi_hid_kbd_getsetting(void)
167 static bool udi_hid_kbd_setreport(void)
169 if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8))
170 && (0 == (0xFF & udd_g_ctrlreq.req.wValue))
171 && (1 == udd_g_ctrlreq.req.wLength)) {
172 // Report OUT type on report ID 0 from USB Host
173 udd_g_ctrlreq.payload = &udi_hid_kbd_report_set;
174 udd_g_ctrlreq.callback = udi_hid_kbd_setreport_valid;
175 udd_g_ctrlreq.payload_size = 1;
181 bool udi_hid_kbd_send_report(void)
183 if (!main_b_kbd_enable) {
187 if (udi_hid_kbd_b_report_trans_ongoing) {
191 memcpy(udi_hid_kbd_report_trans, udi_hid_kbd_report, UDI_HID_KBD_REPORT_SIZE);
192 udi_hid_kbd_b_report_valid = false;
193 udi_hid_kbd_b_report_trans_ongoing =
194 udd_ep_run(UDI_HID_KBD_EP_IN | USB_EP_DIR_IN,
196 udi_hid_kbd_report_trans,
197 UDI_HID_KBD_REPORT_SIZE,
198 udi_hid_kbd_report_sent);
200 return udi_hid_kbd_b_report_trans_ongoing;
203 static void udi_hid_kbd_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep)
208 udi_hid_kbd_b_report_trans_ongoing = false;
209 if (udi_hid_kbd_b_report_valid) {
210 udi_hid_kbd_send_report();
214 static void udi_hid_kbd_setreport_valid(void)
216 //UDI_HID_KBD_CHANGE_LED(udi_hid_kbd_report_set);
221 //********************************************************************************************
223 //********************************************************************************************
226 bool udi_hid_nkro_enable(void);
227 void udi_hid_nkro_disable(void);
228 bool udi_hid_nkro_setup(void);
229 uint8_t udi_hid_nkro_getsetting(void);
231 UDC_DESC_STORAGE udi_api_t udi_api_hid_nkro = {
232 .enable = (bool(*)(void))udi_hid_nkro_enable,
233 .disable = (void (*)(void))udi_hid_nkro_disable,
234 .setup = (bool(*)(void))udi_hid_nkro_setup,
235 .getsetting = (uint8_t(*)(void))udi_hid_nkro_getsetting,
239 COMPILER_WORD_ALIGNED
240 static uint8_t udi_hid_nkro_rate;
242 COMPILER_WORD_ALIGNED
243 static uint8_t udi_hid_nkro_protocol;
245 COMPILER_WORD_ALIGNED
246 uint8_t udi_hid_nkro_report_set;
248 bool udi_hid_nkro_b_report_valid;
250 COMPILER_WORD_ALIGNED
251 uint8_t udi_hid_nkro_report[UDI_HID_NKRO_REPORT_SIZE];
253 volatile bool udi_hid_nkro_b_report_trans_ongoing;
255 COMPILER_WORD_ALIGNED
256 static uint8_t udi_hid_nkro_report_trans[UDI_HID_NKRO_REPORT_SIZE];
258 COMPILER_WORD_ALIGNED
259 UDC_DESC_STORAGE udi_hid_nkro_report_desc_t udi_hid_nkro_report_desc = {
261 0x05, 0x01, // Usage Page (Generic Desktop),
262 0x09, 0x06, // Usage (Keyboard),
263 0xA1, 0x01, // Collection (Application) - Keyboard,
266 0x75, 0x01, // Report Size (1),
267 0x95, 0x08, // Report Count (8),
268 0x15, 0x00, // Logical Minimum (0),
269 0x25, 0x01, // Logical Maximum (1),
270 0x05, 0x07, // Usage Page (Key Codes),
271 0x19, 0xE0, // Usage Minimum (224),
272 0x29, 0xE7, // Usage Maximum (231),
273 0x81, 0x02, // Input (Data, Variable, Absolute),
276 0x75, 0x01, // Report Size (1),
277 0x95, 0x05, // Report Count (5),
278 0x05, 0x08, // Usage Page (LEDs),
279 0x19, 0x01, // Usage Minimum (1),
280 0x29, 0x05, // Usage Maximum (5),
281 0x91, 0x02, // Output (Data, Variable, Absolute),
284 0x75, 0x03, // Report Size (3),
285 0x95, 0x01, // Report Count (1),
286 0x91, 0x03, // Output (Constant),
289 0x75, 0x01, // Report Size (1),
290 0x95, 0xF8, // Report Count (248),
291 0x15, 0x00, // Logical Minimum (0),
292 0x25, 0x01, // Logical Maximum (1),
293 0x05, 0x07, // Usage Page (Key Codes),
294 0x19, 0x00, // Usage Minimum (0),
295 0x29, 0xF7, // Usage Maximum (247),
296 0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
297 0xc0, // End Collection - Keyboard
301 static bool udi_hid_nkro_setreport(void);
302 static void udi_hid_nkro_setreport_valid(void);
303 static void udi_hid_nkro_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
305 bool udi_hid_nkro_enable(void)
307 // Initialize internal values
308 udi_hid_nkro_rate = 0;
309 udi_hid_nkro_protocol = 0;
310 udi_hid_nkro_b_report_trans_ongoing = false;
311 memset(udi_hid_nkro_report, 0, UDI_HID_NKRO_REPORT_SIZE);
312 udi_hid_nkro_b_report_valid = false;
313 return UDI_HID_NKRO_ENABLE_EXT();
316 void udi_hid_nkro_disable(void)
318 UDI_HID_NKRO_DISABLE_EXT();
321 bool udi_hid_nkro_setup(void)
323 return udi_hid_setup(&udi_hid_nkro_rate,
324 &udi_hid_nkro_protocol,
325 (uint8_t *) &udi_hid_nkro_report_desc,
326 udi_hid_nkro_setreport);
329 uint8_t udi_hid_nkro_getsetting(void)
334 //keyboard receives LED report here
335 static bool udi_hid_nkro_setreport(void)
337 if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8))
338 && (0 == (0xFF & udd_g_ctrlreq.req.wValue))
339 && (1 == udd_g_ctrlreq.req.wLength)) {
340 // Report OUT type on report ID 0 from USB Host
341 udd_g_ctrlreq.payload = &udi_hid_nkro_report_set;
342 udd_g_ctrlreq.callback = udi_hid_nkro_setreport_valid; //must call routine to transform setreport to LED state
343 udd_g_ctrlreq.payload_size = 1;
349 bool udi_hid_nkro_send_report(void)
351 if (!main_b_nkro_enable) {
355 if (udi_hid_nkro_b_report_trans_ongoing) {
359 memcpy(udi_hid_nkro_report_trans, udi_hid_nkro_report, UDI_HID_NKRO_REPORT_SIZE);
360 udi_hid_nkro_b_report_valid = false;
361 udi_hid_nkro_b_report_trans_ongoing =
362 udd_ep_run(UDI_HID_NKRO_EP_IN | USB_EP_DIR_IN,
364 udi_hid_nkro_report_trans,
365 UDI_HID_NKRO_REPORT_SIZE,
366 udi_hid_nkro_report_sent);
368 return udi_hid_nkro_b_report_trans_ongoing;
371 static void udi_hid_nkro_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep)
376 udi_hid_nkro_b_report_trans_ongoing = false;
377 if (udi_hid_nkro_b_report_valid) {
378 udi_hid_nkro_send_report();
382 static void udi_hid_nkro_setreport_valid(void)
384 //UDI_HID_NKRO_CHANGE_LED(udi_hid_nkro_report_set);
389 //********************************************************************************************
390 // EXK (extra-keys) SYS-CTRL Keyboard
391 //********************************************************************************************
394 bool udi_hid_exk_enable(void);
395 void udi_hid_exk_disable(void);
396 bool udi_hid_exk_setup(void);
397 uint8_t udi_hid_exk_getsetting(void);
399 UDC_DESC_STORAGE udi_api_t udi_api_hid_exk = {
400 .enable = (bool(*)(void))udi_hid_exk_enable,
401 .disable = (void (*)(void))udi_hid_exk_disable,
402 .setup = (bool(*)(void))udi_hid_exk_setup,
403 .getsetting = (uint8_t(*)(void))udi_hid_exk_getsetting,
407 COMPILER_WORD_ALIGNED
408 static uint8_t udi_hid_exk_rate;
410 COMPILER_WORD_ALIGNED
411 static uint8_t udi_hid_exk_protocol;
413 COMPILER_WORD_ALIGNED
414 uint8_t udi_hid_exk_report_set;
416 bool udi_hid_exk_b_report_valid;
418 COMPILER_WORD_ALIGNED
419 udi_hid_exk_report_t udi_hid_exk_report;
421 static bool udi_hid_exk_b_report_trans_ongoing;
423 COMPILER_WORD_ALIGNED
424 static uint8_t udi_hid_exk_report_trans[UDI_HID_EXK_REPORT_SIZE];
426 COMPILER_WORD_ALIGNED
427 UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {
429 // System Control Collection (8 bits)
431 0x05, 0x01, // Usage Page (Generic Desktop),
432 0x09, 0x80, // Usage (System Control),
433 0xA1, 0x01, // Collection (Application),
434 0x85, REPORT_ID_SYSTEM, // Report ID (2) (System),
435 0x16, 0x01, 0x00, // Logical Minimum (1),
436 0x26, 0x03, 0x00, // Logical Maximum (3),
437 0x1A, 0x81, 0x00, // Usage Minimum (81) (System Power Down),
438 0x2A, 0x83, 0x00, // Usage Maximum (83) (System Wake Up),
439 0x75, 0x10, // Report Size (16),
440 0x95, 0x01, // Report Count (1),
441 0x81, 0x00, // Input (Data, Array),
442 0xC0, // End Collection - System Control
444 // Consumer Control Collection - Media Keys (16 bits)
446 0x05, 0x0C, // Usage Page (Consumer),
447 0x09, 0x01, // Usage (Consumer Control),
448 0xA1, 0x01, // Collection (Application),
449 0x85, REPORT_ID_CONSUMER, // Report ID (3) (Consumer),
450 0x16, 0x01, 0x00, // Logical Minimum (1),
451 0x26, 0x9C, 0x02, // Logical Maximum (668),
452 0x1A, 0x01, 0x00, // Usage Minimum (1),
453 0x2A, 0x9C, 0x02, // Usage Maximum (668),
454 0x75, 0x10, // Report Size (16),
455 0x95, 0x01, // Report Count (1),
456 0x81, 0x00, // Input (Data, Array),
457 0xC0, // End Collection - Consumer Control
461 static bool udi_hid_exk_setreport(void);
463 static void udi_hid_exk_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
465 static void udi_hid_exk_setreport_valid(void);
467 bool udi_hid_exk_enable(void)
469 // Initialize internal values
470 udi_hid_exk_rate = 0;
471 udi_hid_exk_protocol = 0;
472 udi_hid_exk_b_report_trans_ongoing = false;
473 memset(udi_hid_exk_report.raw, 0, UDI_HID_EXK_REPORT_SIZE);
474 udi_hid_exk_b_report_valid = false;
475 return UDI_HID_EXK_ENABLE_EXT();
478 void udi_hid_exk_disable(void)
480 UDI_HID_EXK_DISABLE_EXT();
483 bool udi_hid_exk_setup(void)
485 return udi_hid_setup(&udi_hid_exk_rate,
486 &udi_hid_exk_protocol,
487 (uint8_t *) &udi_hid_exk_report_desc,
488 udi_hid_exk_setreport);
491 uint8_t udi_hid_exk_getsetting(void)
496 static bool udi_hid_exk_setreport(void)
498 if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8))
499 && (0 == (0xFF & udd_g_ctrlreq.req.wValue))
500 && (1 == udd_g_ctrlreq.req.wLength)) {
501 // Report OUT type on report ID 0 from USB Host
502 udd_g_ctrlreq.payload = &udi_hid_exk_report_set;
503 udd_g_ctrlreq.callback = udi_hid_exk_setreport_valid;
504 udd_g_ctrlreq.payload_size = 1;
510 bool udi_hid_exk_send_report(void)
512 if (!main_b_exk_enable) {
516 if (udi_hid_exk_b_report_trans_ongoing) {
520 memcpy(udi_hid_exk_report_trans, udi_hid_exk_report.raw, UDI_HID_EXK_REPORT_SIZE);
521 udi_hid_exk_b_report_valid = false;
522 udi_hid_exk_b_report_trans_ongoing =
523 udd_ep_run(UDI_HID_EXK_EP_IN | USB_EP_DIR_IN,
525 udi_hid_exk_report_trans,
526 UDI_HID_EXK_REPORT_SIZE,
527 udi_hid_exk_report_sent);
529 return udi_hid_exk_b_report_trans_ongoing;
532 static void udi_hid_exk_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep)
537 udi_hid_exk_b_report_trans_ongoing = false;
538 if (udi_hid_exk_b_report_valid) {
539 udi_hid_exk_send_report();
543 static void udi_hid_exk_setreport_valid(void)
550 //********************************************************************************************
552 //********************************************************************************************
555 bool udi_hid_mou_enable(void);
556 void udi_hid_mou_disable(void);
557 bool udi_hid_mou_setup(void);
558 uint8_t udi_hid_mou_getsetting(void);
560 UDC_DESC_STORAGE udi_api_t udi_api_hid_mou = {
561 .enable = (bool(*)(void))udi_hid_mou_enable,
562 .disable = (void (*)(void))udi_hid_mou_disable,
563 .setup = (bool(*)(void))udi_hid_mou_setup,
564 .getsetting = (uint8_t(*)(void))udi_hid_mou_getsetting,
568 COMPILER_WORD_ALIGNED
569 static uint8_t udi_hid_mou_rate;
571 COMPILER_WORD_ALIGNED
572 static uint8_t udi_hid_mou_protocol;
574 //COMPILER_WORD_ALIGNED
575 //uint8_t udi_hid_mou_report_set; //No set report
577 bool udi_hid_mou_b_report_valid;
579 COMPILER_WORD_ALIGNED
580 uint8_t udi_hid_mou_report[UDI_HID_MOU_REPORT_SIZE];
582 static bool udi_hid_mou_b_report_trans_ongoing;
584 COMPILER_WORD_ALIGNED
585 static uint8_t udi_hid_mou_report_trans[UDI_HID_MOU_REPORT_SIZE];
587 COMPILER_WORD_ALIGNED
588 UDC_DESC_STORAGE udi_hid_mou_report_desc_t udi_hid_mou_report_desc = {
590 0x05, 0x01, // Usage Page (Generic Desktop),
591 0x09, 0x02, // Usage (Mouse),
592 0xA1, 0x01, // Collection (Application),
593 0x09, 0x01, // Usage (Pointer),
594 0xA1, 0x00, // Collection (Physical),
595 0x05, 0x09, // Usage Page (Buttons),
596 0x19, 0x01, // Usage Minimum (01),
597 0x29, 0x05, // Usage Maximun (05),
598 0x15, 0x00, // Logical Minimum (0),
599 0x25, 0x01, // Logical Maximum (1),
600 0x95, 0x05, // Report Count (5),
601 0x75, 0x01, // Report Size (1),
602 0x81, 0x02, // Input (Data, Variable, Absolute), ;5 button bits
603 0x95, 0x01, // Report Count (1),
604 0x75, 0x03, // Report Size (3),
605 0x81, 0x01, // Input (Constant), ;3 bit padding,
607 0x05, 0x01, // Usage Page (Generic Desktop),
608 0x09, 0x30, // Usage (X),
609 0x09, 0x31, // Usage (Y),
610 0x15, 0x81, // Logical Minimum (-127),
611 0x25, 0x7F, // Logical Maximum (127),
612 0x95, 0x02, // Report Count (2),
613 0x75, 0x08, // Report Size (8),
614 0x81, 0x06, // Input (Data, Variable, Relative), ;2 position bytes (X & Y),
616 0x09, 0x38, // Usage (Wheel),
617 0x15, 0x81, // Logical Minimum (-127),
618 0x25, 0x7F, // Logical Maximum (127),
619 0x95, 0x01, // Report Count (1),
620 0x75, 0x08, // Report Size (8),
621 0x81, 0x06, // Input (Data, Variable, Relative),
623 0x05, 0x0C, // Usage Page (Consumer),
624 0x0A, 0x38, 0x02, // Usage (AC Pan (Horizontal wheel)),
625 0x15, 0x81, // Logical Minimum (-127),
626 0x25, 0x7F, // Logical Maximum (127),
627 0x95, 0x01, // Report Count (1),
628 0x75, 0x08, // Report Size (8),
629 0x81, 0x06, // Input (Data, Variable, Relative),
631 0xC0, // End Collection,
632 0xC0, // End Collection
636 static void udi_hid_mou_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
638 bool udi_hid_mou_enable(void)
640 // Initialize internal values
641 udi_hid_mou_rate = 0;
642 udi_hid_mou_protocol = 0;
643 udi_hid_mou_b_report_trans_ongoing = false;
644 memset(udi_hid_mou_report, 0, UDI_HID_MOU_REPORT_SIZE);
645 udi_hid_mou_b_report_valid = false;
646 return UDI_HID_MOU_ENABLE_EXT();
649 void udi_hid_mou_disable(void)
651 UDI_HID_MOU_DISABLE_EXT();
654 bool udi_hid_mou_setup(void)
656 return udi_hid_setup(&udi_hid_mou_rate,
657 &udi_hid_mou_protocol,
658 (uint8_t *) &udi_hid_mou_report_desc,
662 uint8_t udi_hid_mou_getsetting(void)
667 bool udi_hid_mou_send_report(void)
669 if (!main_b_mou_enable) {
673 if (udi_hid_mou_b_report_trans_ongoing) {
677 memcpy(udi_hid_mou_report_trans, udi_hid_mou_report, UDI_HID_MOU_REPORT_SIZE);
678 udi_hid_mou_b_report_valid = false;
679 udi_hid_mou_b_report_trans_ongoing =
680 udd_ep_run(UDI_HID_MOU_EP_IN | USB_EP_DIR_IN,
682 udi_hid_mou_report_trans,
683 UDI_HID_MOU_REPORT_SIZE,
684 udi_hid_mou_report_sent);
686 return udi_hid_mou_b_report_trans_ongoing;
689 static void udi_hid_mou_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep)
694 udi_hid_mou_b_report_trans_ongoing = false;
695 if (udi_hid_mou_b_report_valid) {
696 udi_hid_mou_send_report();
702 //********************************************************************************************
704 //********************************************************************************************
707 bool udi_hid_raw_enable(void);
708 void udi_hid_raw_disable(void);
709 bool udi_hid_raw_setup(void);
710 uint8_t udi_hid_raw_getsetting(void);
712 UDC_DESC_STORAGE udi_api_t udi_api_hid_raw = {
713 .enable = (bool(*)(void))udi_hid_raw_enable,
714 .disable = (void (*)(void))udi_hid_raw_disable,
715 .setup = (bool(*)(void))udi_hid_raw_setup,
716 .getsetting = (uint8_t(*)(void))udi_hid_raw_getsetting,
720 COMPILER_WORD_ALIGNED
721 static uint8_t udi_hid_raw_rate;
723 COMPILER_WORD_ALIGNED
724 static uint8_t udi_hid_raw_protocol;
726 COMPILER_WORD_ALIGNED
727 uint8_t udi_hid_raw_report_set[UDI_HID_RAW_REPORT_SIZE];
729 static bool udi_hid_raw_b_report_valid;
731 COMPILER_WORD_ALIGNED
732 uint8_t udi_hid_raw_report[UDI_HID_RAW_REPORT_SIZE];
734 static bool udi_hid_raw_b_report_trans_ongoing;
736 COMPILER_WORD_ALIGNED
737 static uint8_t udi_hid_raw_report_trans[UDI_HID_RAW_REPORT_SIZE];
739 COMPILER_WORD_ALIGNED
740 UDC_DESC_STORAGE udi_hid_raw_report_desc_t udi_hid_raw_report_desc = {
742 0x06, // Usage Page (Vendor Defined)
744 0x0A, // Usage (Mouse)
746 0xA1, 0x01, // Collection (Application)
747 0x75, 0x08, // Report Size (8)
748 0x15, 0x00, // Logical Minimum (0)
749 0x25, 0xFF, // Logical Maximum (255)
750 0x95, 0x40, // Report Count
751 0x09, 0x01, // Usage (Input)
752 0x81, 0x02, // Input (Data
753 0x95, 0x40, // Report Count
754 0x09, 0x02, // Usage (Output)
755 0x91, 0x02, // Output (Data
756 0xC0, // End Collection - Consumer Control
760 static bool udi_hid_raw_setreport(void);
761 static void udi_hid_raw_setreport_valid(void);
763 static void udi_hid_raw_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
765 bool udi_hid_raw_enable(void)
767 // Initialize internal values
768 udi_hid_raw_rate = 0;
769 udi_hid_raw_protocol = 0;
770 udi_hid_raw_b_report_trans_ongoing = false;
771 memset(udi_hid_raw_report, 0, UDI_HID_RAW_REPORT_SIZE);
772 udi_hid_raw_b_report_valid = false;
773 return UDI_HID_RAW_ENABLE_EXT();
776 void udi_hid_raw_disable(void)
778 UDI_HID_RAW_DISABLE_EXT();
781 bool udi_hid_raw_setup(void)
783 return udi_hid_setup(&udi_hid_raw_rate,
784 &udi_hid_raw_protocol,
785 (uint8_t *) &udi_hid_raw_report_desc,
786 udi_hid_raw_setreport);
789 uint8_t udi_hid_raw_getsetting(void)
794 static bool udi_hid_raw_setreport(void)
796 if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8))
797 && (0 == (0xFF & udd_g_ctrlreq.req.wValue))
798 && (UDI_HID_RAW_REPORT_SIZE == udd_g_ctrlreq.req.wLength)) {
799 // Report OUT type on report ID 0 from USB Host
800 udd_g_ctrlreq.payload = udi_hid_raw_report_set;
801 udd_g_ctrlreq.callback = udi_hid_raw_setreport_valid; //must call routine to transform setreport to LED state
802 udd_g_ctrlreq.payload_size = UDI_HID_RAW_REPORT_SIZE;
808 bool udi_hid_raw_send_report(void)
810 if (!main_b_raw_enable) {
814 if (udi_hid_raw_b_report_trans_ongoing) {
818 memcpy(udi_hid_raw_report_trans, udi_hid_raw_report,UDI_HID_RAW_REPORT_SIZE);
819 udi_hid_raw_b_report_valid = false;
820 udi_hid_raw_b_report_trans_ongoing =
821 udd_ep_run(UDI_HID_RAW_EP_IN | USB_EP_DIR_IN,
823 udi_hid_raw_report_trans,
824 UDI_HID_RAW_REPORT_SIZE,
825 udi_hid_raw_report_sent);
827 return udi_hid_raw_b_report_trans_ongoing;
830 static void udi_hid_raw_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep)
835 udi_hid_raw_b_report_trans_ongoing = false;
836 if (udi_hid_raw_b_report_valid) {
837 udi_hid_raw_send_report();
841 static void udi_hid_raw_setreport_valid(void)
848 //********************************************************************************************
850 //********************************************************************************************
853 bool udi_hid_con_enable(void);
854 void udi_hid_con_disable(void);
855 bool udi_hid_con_setup(void);
856 uint8_t udi_hid_con_getsetting(void);
858 UDC_DESC_STORAGE udi_api_t udi_api_hid_con = {
859 .enable = (bool(*)(void))udi_hid_con_enable,
860 .disable = (void (*)(void))udi_hid_con_disable,
861 .setup = (bool(*)(void))udi_hid_con_setup,
862 .getsetting = (uint8_t(*)(void))udi_hid_con_getsetting,
866 COMPILER_WORD_ALIGNED
867 static uint8_t udi_hid_con_rate;
869 COMPILER_WORD_ALIGNED
870 static uint8_t udi_hid_con_protocol;
872 COMPILER_WORD_ALIGNED
873 uint8_t udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE];
875 bool udi_hid_con_b_report_valid;
877 COMPILER_WORD_ALIGNED
878 uint8_t udi_hid_con_report[UDI_HID_CON_REPORT_SIZE];
880 volatile bool udi_hid_con_b_report_trans_ongoing;
882 COMPILER_WORD_ALIGNED
883 static uint8_t udi_hid_con_report_trans[UDI_HID_CON_REPORT_SIZE];
885 COMPILER_WORD_ALIGNED
886 UDC_DESC_STORAGE udi_hid_con_report_desc_t udi_hid_con_report_desc = {
888 0x06, 0x31, 0xFF, // Vendor Page (PJRC Teensy compatible)
889 0x09, 0x74, // Vendor Usage (PJRC Teensy compatible)
890 0xA1, 0x01, // Collection (Application)
891 0x09, 0x75, // Usage (Vendor)
892 0x15, 0x00, // Logical Minimum (0x00)
893 0x26, 0xFF, 0x00, // Logical Maximum (0x00FF)
894 0x95, CONSOLE_EPSIZE, // Report Count
895 0x75, 0x08, // Report Size (8)
896 0x81, 0x02, // Input (Data)
897 0x09, 0x76, // Usage (Vendor)
898 0x15, 0x00, // Logical Minimum (0x00)
899 0x26, 0xFF, 0x00, // Logical Maximum (0x00FF)
900 0x95, CONSOLE_EPSIZE, // Report Count
901 0x75, 0x08, // Report Size (8)
902 0x91, 0x02, // Output (Data)
903 0xC0, // End Collection
907 static bool udi_hid_con_setreport(void);
908 static void udi_hid_con_setreport_valid(void);
910 static void udi_hid_con_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
912 bool udi_hid_con_enable(void)
914 // Initialize internal values
915 udi_hid_con_rate = 0;
916 udi_hid_con_protocol = 0;
917 udi_hid_con_b_report_trans_ongoing = false;
918 memset(udi_hid_con_report, 0, UDI_HID_CON_REPORT_SIZE);
919 udi_hid_con_b_report_valid = false;
920 return UDI_HID_CON_ENABLE_EXT();
923 void udi_hid_con_disable(void)
925 UDI_HID_CON_DISABLE_EXT();
928 bool udi_hid_con_setup(void)
930 return udi_hid_setup(&udi_hid_con_rate,
931 &udi_hid_con_protocol,
932 (uint8_t *) &udi_hid_con_report_desc,
933 udi_hid_con_setreport);
936 uint8_t udi_hid_con_getsetting(void)
941 static bool udi_hid_con_setreport(void)
943 if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8))
944 && (0 == (0xFF & udd_g_ctrlreq.req.wValue))
945 && (UDI_HID_CON_REPORT_SIZE == udd_g_ctrlreq.req.wLength)) {
946 udd_g_ctrlreq.payload = udi_hid_con_report_set;
947 udd_g_ctrlreq.callback = udi_hid_con_setreport_valid;
948 udd_g_ctrlreq.payload_size = UDI_HID_CON_REPORT_SIZE;
954 bool udi_hid_con_send_report(void)
956 if (!main_b_con_enable) {
960 if (udi_hid_con_b_report_trans_ongoing) {
964 memcpy(udi_hid_con_report_trans, udi_hid_con_report,UDI_HID_CON_REPORT_SIZE);
965 udi_hid_con_b_report_valid = false;
966 udi_hid_con_b_report_trans_ongoing =
967 udd_ep_run(UDI_HID_CON_EP_IN | USB_EP_DIR_IN,
969 udi_hid_con_report_trans,
970 UDI_HID_CON_REPORT_SIZE,
971 udi_hid_con_report_sent);
973 return udi_hid_con_b_report_trans_ongoing;
976 static void udi_hid_con_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep)
981 udi_hid_con_b_report_trans_ongoing = false;
982 if (udi_hid_con_b_report_valid) {
983 udi_hid_con_send_report();
987 static void udi_hid_con_setreport_valid(void)