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"
58 //***************************************************************************
60 //***************************************************************************
63 bool udi_hid_kbd_enable(void);
64 void udi_hid_kbd_disable(void);
65 bool udi_hid_kbd_setup(void);
66 uint8_t udi_hid_kbd_getsetting(void);
68 UDC_DESC_STORAGE udi_api_t udi_api_hid_kbd = {
69 .enable = (bool(*)(void))udi_hid_kbd_enable,
70 .disable = (void (*)(void))udi_hid_kbd_disable,
71 .setup = (bool(*)(void))udi_hid_kbd_setup,
72 .getsetting = (uint8_t(*)(void))udi_hid_kbd_getsetting,
77 static uint8_t udi_hid_kbd_rate;
80 static uint8_t udi_hid_kbd_protocol;
83 uint8_t udi_hid_kbd_report_set;
85 bool udi_hid_kbd_b_report_valid;
88 uint8_t udi_hid_kbd_report[UDI_HID_KBD_REPORT_SIZE];
90 volatile bool udi_hid_kbd_b_report_trans_ongoing;
93 static uint8_t udi_hid_kbd_report_trans[UDI_HID_KBD_REPORT_SIZE];
96 UDC_DESC_STORAGE udi_hid_kbd_report_desc_t udi_hid_kbd_report_desc = {
98 0x05, 0x01, // Usage Page (Generic Desktop)
99 0x09, 0x06, // Usage (Keyboard)
100 0xA1, 0x01, // Collection (Application)
101 0x05, 0x07, // Usage Page (Keyboard)
102 0x19, 0xE0, // Usage Minimum (224)
103 0x29, 0xE7, // Usage Maximum (231)
104 0x15, 0x00, // Logical Minimum (0)
105 0x25, 0x01, // Logical Maximum (1)
106 0x75, 0x01, // Report Size (1)
107 0x95, 0x08, // Report Count (8)
108 0x81, 0x02, // Input (Data, Variable, Absolute)
109 0x81, 0x01, // Input (Constant)
110 0x19, 0x00, // Usage Minimum (0)
111 0x29, 0x65, // Usage Maximum (101)
112 0x15, 0x00, // Logical Minimum (0)
113 0x25, 0x65, // Logical Maximum (101)
114 0x75, 0x08, // Report Size (8)
115 0x95, 0x06, // Report Count (6)
116 0x81, 0x00, // Input (Data, Array)
117 0x05, 0x08, // Usage Page (LED)
118 0x19, 0x01, // Usage Minimum (1)
119 0x29, 0x05, // Usage Maximum (5)
120 0x15, 0x00, // Logical Minimum (0)
121 0x25, 0x01, // Logical Maximum (1)
122 0x75, 0x01, // Report Size (1)
123 0x95, 0x05, // Report Count (5)
124 0x91, 0x02, // Output (Data, Variable, Absolute)
125 0x95, 0x03, // Report Count (3)
126 0x91, 0x01, // Output (Constant)
127 0xC0 // End Collection
131 static bool udi_hid_kbd_setreport(void);
133 static void udi_hid_kbd_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
135 static void udi_hid_kbd_setreport_valid(void);
137 bool udi_hid_kbd_enable(void)
139 // Initialize internal values
140 udi_hid_kbd_rate = 0;
141 udi_hid_kbd_protocol = 0;
142 udi_hid_kbd_b_report_trans_ongoing = false;
143 memset(udi_hid_kbd_report, 0, UDI_HID_KBD_REPORT_SIZE);
144 udi_hid_kbd_b_report_valid = false;
145 return UDI_HID_KBD_ENABLE_EXT();
148 void udi_hid_kbd_disable(void)
150 UDI_HID_KBD_DISABLE_EXT();
153 bool udi_hid_kbd_setup(void)
155 return udi_hid_setup(&udi_hid_kbd_rate,
156 &udi_hid_kbd_protocol,
157 (uint8_t *) &udi_hid_kbd_report_desc,
158 udi_hid_kbd_setreport);
161 uint8_t udi_hid_kbd_getsetting(void)
166 static bool udi_hid_kbd_setreport(void)
168 if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8))
169 && (0 == (0xFF & udd_g_ctrlreq.req.wValue))
170 && (1 == udd_g_ctrlreq.req.wLength)) {
171 // Report OUT type on report ID 0 from USB Host
172 udd_g_ctrlreq.payload = &udi_hid_kbd_report_set;
173 udd_g_ctrlreq.callback = udi_hid_kbd_setreport_valid;
174 udd_g_ctrlreq.payload_size = 1;
180 bool udi_hid_kbd_send_report(void)
182 if (!main_b_kbd_enable) {
186 if (udi_hid_kbd_b_report_trans_ongoing) {
190 memcpy(udi_hid_kbd_report_trans, udi_hid_kbd_report, UDI_HID_KBD_REPORT_SIZE);
191 udi_hid_kbd_b_report_valid = false;
192 udi_hid_kbd_b_report_trans_ongoing =
193 udd_ep_run(UDI_HID_KBD_EP_IN | USB_EP_DIR_IN,
195 udi_hid_kbd_report_trans,
196 UDI_HID_KBD_REPORT_SIZE,
197 udi_hid_kbd_report_sent);
199 return udi_hid_kbd_b_report_trans_ongoing;
202 static void udi_hid_kbd_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep)
207 udi_hid_kbd_b_report_trans_ongoing = false;
208 if (udi_hid_kbd_b_report_valid) {
209 udi_hid_kbd_send_report();
213 static void udi_hid_kbd_setreport_valid(void)
215 //UDI_HID_KBD_CHANGE_LED(udi_hid_kbd_report_set);
220 //********************************************************************************************
222 //********************************************************************************************
225 bool udi_hid_nkro_enable(void);
226 void udi_hid_nkro_disable(void);
227 bool udi_hid_nkro_setup(void);
228 uint8_t udi_hid_nkro_getsetting(void);
230 UDC_DESC_STORAGE udi_api_t udi_api_hid_nkro = {
231 .enable = (bool(*)(void))udi_hid_nkro_enable,
232 .disable = (void (*)(void))udi_hid_nkro_disable,
233 .setup = (bool(*)(void))udi_hid_nkro_setup,
234 .getsetting = (uint8_t(*)(void))udi_hid_nkro_getsetting,
238 COMPILER_WORD_ALIGNED
239 static uint8_t udi_hid_nkro_rate;
241 COMPILER_WORD_ALIGNED
242 static uint8_t udi_hid_nkro_protocol;
244 COMPILER_WORD_ALIGNED
245 uint8_t udi_hid_nkro_report_set;
247 bool udi_hid_nkro_b_report_valid;
249 COMPILER_WORD_ALIGNED
250 uint8_t udi_hid_nkro_report[UDI_HID_NKRO_REPORT_SIZE];
252 volatile bool udi_hid_nkro_b_report_trans_ongoing;
254 COMPILER_WORD_ALIGNED
255 static uint8_t udi_hid_nkro_report_trans[UDI_HID_NKRO_REPORT_SIZE];
257 COMPILER_WORD_ALIGNED
258 UDC_DESC_STORAGE udi_hid_nkro_report_desc_t udi_hid_nkro_report_desc = {
260 0x05, 0x01, // Usage Page (Generic Desktop),
261 0x09, 0x06, // Usage (Keyboard),
262 0xA1, 0x01, // Collection (Application) - Keyboard,
265 0x75, 0x01, // Report Size (1),
266 0x95, 0x08, // Report Count (8),
267 0x15, 0x00, // Logical Minimum (0),
268 0x25, 0x01, // Logical Maximum (1),
269 0x05, 0x07, // Usage Page (Key Codes),
270 0x19, 0xE0, // Usage Minimum (224),
271 0x29, 0xE7, // Usage Maximum (231),
272 0x81, 0x02, // Input (Data, Variable, Absolute),
275 0x75, 0x01, // Report Size (1),
276 0x95, 0x05, // Report Count (5),
277 0x05, 0x08, // Usage Page (LEDs),
278 0x19, 0x01, // Usage Minimum (1),
279 0x29, 0x05, // Usage Maximum (5),
280 0x91, 0x02, // Output (Data, Variable, Absolute),
283 0x75, 0x03, // Report Size (3),
284 0x95, 0x01, // Report Count (1),
285 0x91, 0x03, // Output (Constant),
288 0x75, 0x01, // Report Size (1),
289 0x95, 0xF8, // Report Count (248),
290 0x15, 0x00, // Logical Minimum (0),
291 0x25, 0x01, // Logical Maximum (1),
292 0x05, 0x07, // Usage Page (Key Codes),
293 0x19, 0x00, // Usage Minimum (0),
294 0x29, 0xF7, // Usage Maximum (247),
295 0x81, 0x02, // Input (Data, Variable, Absolute, Bitfield),
296 0xc0, // End Collection - Keyboard
300 static bool udi_hid_nkro_setreport(void);
301 static void udi_hid_nkro_setreport_valid(void);
302 static void udi_hid_nkro_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
304 bool udi_hid_nkro_enable(void)
306 // Initialize internal values
307 udi_hid_nkro_rate = 0;
308 udi_hid_nkro_protocol = 0;
309 udi_hid_nkro_b_report_trans_ongoing = false;
310 memset(udi_hid_nkro_report, 0, UDI_HID_NKRO_REPORT_SIZE);
311 udi_hid_nkro_b_report_valid = false;
312 return UDI_HID_NKRO_ENABLE_EXT();
315 void udi_hid_nkro_disable(void)
317 UDI_HID_NKRO_DISABLE_EXT();
320 bool udi_hid_nkro_setup(void)
322 return udi_hid_setup(&udi_hid_nkro_rate,
323 &udi_hid_nkro_protocol,
324 (uint8_t *) &udi_hid_nkro_report_desc,
325 udi_hid_nkro_setreport);
328 uint8_t udi_hid_nkro_getsetting(void)
333 //keyboard receives LED report here
334 static bool udi_hid_nkro_setreport(void)
336 if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8))
337 && (0 == (0xFF & udd_g_ctrlreq.req.wValue))
338 && (1 == udd_g_ctrlreq.req.wLength)) {
339 // Report OUT type on report ID 0 from USB Host
340 udd_g_ctrlreq.payload = &udi_hid_nkro_report_set;
341 udd_g_ctrlreq.callback = udi_hid_nkro_setreport_valid; //must call routine to transform setreport to LED state
342 udd_g_ctrlreq.payload_size = 1;
348 bool udi_hid_nkro_send_report(void)
350 if (!main_b_nkro_enable) {
354 if (udi_hid_nkro_b_report_trans_ongoing) {
358 memcpy(udi_hid_nkro_report_trans, udi_hid_nkro_report, UDI_HID_NKRO_REPORT_SIZE);
359 udi_hid_nkro_b_report_valid = false;
360 udi_hid_nkro_b_report_trans_ongoing =
361 udd_ep_run(UDI_HID_NKRO_EP_IN | USB_EP_DIR_IN,
363 udi_hid_nkro_report_trans,
364 UDI_HID_NKRO_REPORT_SIZE,
365 udi_hid_nkro_report_sent);
367 return udi_hid_nkro_b_report_trans_ongoing;
370 static void udi_hid_nkro_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep)
375 udi_hid_nkro_b_report_trans_ongoing = false;
376 if (udi_hid_nkro_b_report_valid) {
377 udi_hid_nkro_send_report();
381 static void udi_hid_nkro_setreport_valid(void)
383 //UDI_HID_NKRO_CHANGE_LED(udi_hid_nkro_report_set);
388 //********************************************************************************************
389 // EXK (extra-keys) SYS-CTRL Keyboard
390 //********************************************************************************************
393 bool udi_hid_exk_enable(void);
394 void udi_hid_exk_disable(void);
395 bool udi_hid_exk_setup(void);
396 uint8_t udi_hid_exk_getsetting(void);
398 UDC_DESC_STORAGE udi_api_t udi_api_hid_exk = {
399 .enable = (bool(*)(void))udi_hid_exk_enable,
400 .disable = (void (*)(void))udi_hid_exk_disable,
401 .setup = (bool(*)(void))udi_hid_exk_setup,
402 .getsetting = (uint8_t(*)(void))udi_hid_exk_getsetting,
406 COMPILER_WORD_ALIGNED
407 static uint8_t udi_hid_exk_rate;
409 COMPILER_WORD_ALIGNED
410 static uint8_t udi_hid_exk_protocol;
412 COMPILER_WORD_ALIGNED
413 uint8_t udi_hid_exk_report_set;
415 bool udi_hid_exk_b_report_valid;
417 COMPILER_WORD_ALIGNED
418 udi_hid_exk_report_t udi_hid_exk_report;
420 static bool udi_hid_exk_b_report_trans_ongoing;
422 COMPILER_WORD_ALIGNED
423 static uint8_t udi_hid_exk_report_trans[UDI_HID_EXK_REPORT_SIZE];
425 COMPILER_WORD_ALIGNED
426 UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {
428 // System Control Collection (8 bits)
430 0x05, 0x01, // Usage Page (Generic Desktop),
431 0x09, 0x80, // Usage (System Control),
432 0xA1, 0x01, // Collection (Application),
433 0x85, 0x02, // Report ID (2) (System),
434 0x16, 0x01, 0x00, // Logical Minimum (1),
435 0x26, 0x03, 0x00, // Logical Maximum (3),
436 0x1A, 0x81, 0x00, // Usage Minimum (81) (System Power Down),
437 0x2A, 0x83, 0x00, // Usage Maximum (83) (System Wake Up),
438 0x75, 0x10, // Report Size (16),
439 0x95, 0x01, // Report Count (1),
440 0x81, 0x00, // Input (Data, Array),
441 0xC0, // End Collection - System Control
443 // Consumer Control Collection - Media Keys (16 bits)
445 0x05, 0x0C, // Usage Page (Consumer),
446 0x09, 0x01, // Usage (Consumer Control),
447 0xA1, 0x01, // Collection (Application),
448 0x85, 0x03, // Report ID (3) (Consumer),
449 0x16, 0x01, 0x00, // Logical Minimum (1),
450 0x26, 0x9C, 0x02, // Logical Maximum (668),
451 0x1A, 0x01, 0x00, // Usage Minimum (1),
452 0x2A, 0x9C, 0x02, // Usage Maximum (668),
453 0x75, 0x10, // Report Size (16),
454 0x95, 0x01, // Report Count (1),
455 0x81, 0x00, // Input (Data, Array),
456 0xC0, // End Collection - Consumer Control
460 static bool udi_hid_exk_setreport(void);
462 static void udi_hid_exk_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
464 static void udi_hid_exk_setreport_valid(void);
466 bool udi_hid_exk_enable(void)
468 // Initialize internal values
469 udi_hid_exk_rate = 0;
470 udi_hid_exk_protocol = 0;
471 udi_hid_exk_b_report_trans_ongoing = false;
472 memset(udi_hid_exk_report.raw, 0, UDI_HID_EXK_REPORT_SIZE);
473 udi_hid_exk_b_report_valid = false;
474 return UDI_HID_EXK_ENABLE_EXT();
477 void udi_hid_exk_disable(void)
479 UDI_HID_EXK_DISABLE_EXT();
482 bool udi_hid_exk_setup(void)
484 return udi_hid_setup(&udi_hid_exk_rate,
485 &udi_hid_exk_protocol,
486 (uint8_t *) &udi_hid_exk_report_desc,
487 udi_hid_exk_setreport);
490 uint8_t udi_hid_exk_getsetting(void)
495 static bool udi_hid_exk_setreport(void)
497 if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8))
498 && (0 == (0xFF & udd_g_ctrlreq.req.wValue))
499 && (1 == udd_g_ctrlreq.req.wLength)) {
500 // Report OUT type on report ID 0 from USB Host
501 udd_g_ctrlreq.payload = &udi_hid_exk_report_set;
502 udd_g_ctrlreq.callback = udi_hid_exk_setreport_valid;
503 udd_g_ctrlreq.payload_size = 1;
509 bool udi_hid_exk_send_report(void)
511 if (!main_b_exk_enable) {
515 if (udi_hid_exk_b_report_trans_ongoing) {
519 memcpy(udi_hid_exk_report_trans, udi_hid_exk_report.raw, UDI_HID_EXK_REPORT_SIZE);
520 udi_hid_exk_b_report_valid = false;
521 udi_hid_exk_b_report_trans_ongoing =
522 udd_ep_run(UDI_HID_EXK_EP_IN | USB_EP_DIR_IN,
524 udi_hid_exk_report_trans,
525 UDI_HID_EXK_REPORT_SIZE,
526 udi_hid_exk_report_sent);
528 return udi_hid_exk_b_report_trans_ongoing;
531 static void udi_hid_exk_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep)
536 udi_hid_exk_b_report_trans_ongoing = false;
537 if (udi_hid_exk_b_report_valid) {
538 udi_hid_exk_send_report();
542 static void udi_hid_exk_setreport_valid(void)
549 //********************************************************************************************
551 //********************************************************************************************
554 bool udi_hid_mou_enable(void);
555 void udi_hid_mou_disable(void);
556 bool udi_hid_mou_setup(void);
557 uint8_t udi_hid_mou_getsetting(void);
559 UDC_DESC_STORAGE udi_api_t udi_api_hid_mou = {
560 .enable = (bool(*)(void))udi_hid_mou_enable,
561 .disable = (void (*)(void))udi_hid_mou_disable,
562 .setup = (bool(*)(void))udi_hid_mou_setup,
563 .getsetting = (uint8_t(*)(void))udi_hid_mou_getsetting,
567 COMPILER_WORD_ALIGNED
568 static uint8_t udi_hid_mou_rate;
570 COMPILER_WORD_ALIGNED
571 static uint8_t udi_hid_mou_protocol;
573 //COMPILER_WORD_ALIGNED
574 //uint8_t udi_hid_mou_report_set; //No set report
576 bool udi_hid_mou_b_report_valid;
578 COMPILER_WORD_ALIGNED
579 uint8_t udi_hid_mou_report[UDI_HID_MOU_REPORT_SIZE];
581 static bool udi_hid_mou_b_report_trans_ongoing;
583 COMPILER_WORD_ALIGNED
584 static uint8_t udi_hid_mou_report_trans[UDI_HID_MOU_REPORT_SIZE];
586 COMPILER_WORD_ALIGNED
587 UDC_DESC_STORAGE udi_hid_mou_report_desc_t udi_hid_mou_report_desc = {
589 0x05, 0x01, // Usage Page (Generic Desktop),
590 0x09, 0x02, // Usage (Mouse),
591 0xA1, 0x01, // Collection (Application),
592 0x09, 0x01, // Usage (Pointer),
593 0xA1, 0x00, // Collection (Physical),
594 0x05, 0x09, // Usage Page (Buttons),
595 0x19, 0x01, // Usage Minimum (01),
596 0x29, 0x05, // Usage Maximun (05),
597 0x15, 0x00, // Logical Minimum (0),
598 0x25, 0x01, // Logical Maximum (1),
599 0x95, 0x05, // Report Count (5),
600 0x75, 0x01, // Report Size (1),
601 0x81, 0x02, // Input (Data, Variable, Absolute), ;5 button bits
602 0x95, 0x01, // Report Count (1),
603 0x75, 0x03, // Report Size (3),
604 0x81, 0x01, // Input (Constant), ;3 bit padding,
606 0x05, 0x01, // Usage Page (Generic Desktop),
607 0x09, 0x30, // Usage (X),
608 0x09, 0x31, // Usage (Y),
609 0x15, 0x81, // Logical Minimum (-127),
610 0x25, 0x7F, // Logical Maximum (127),
611 0x95, 0x02, // Report Count (2),
612 0x75, 0x08, // Report Size (8),
613 0x81, 0x06, // Input (Data, Variable, Relative), ;2 position bytes (X & Y),
615 0x09, 0x38, // Usage (Wheel),
616 0x15, 0x81, // Logical Minimum (-127),
617 0x25, 0x7F, // Logical Maximum (127),
618 0x95, 0x01, // Report Count (1),
619 0x75, 0x08, // Report Size (8),
620 0x81, 0x06, // Input (Data, Variable, Relative),
622 0x05, 0x0C, // Usage Page (Consumer),
623 0x0A, 0x38, 0x02, // Usage (AC Pan (Horizontal wheel)),
624 0x15, 0x81, // Logical Minimum (-127),
625 0x25, 0x7F, // Logical Maximum (127),
626 0x95, 0x01, // Report Count (1),
627 0x75, 0x08, // Report Size (8),
628 0x81, 0x06, // Input (Data, Variable, Relative),
630 0xC0, // End Collection,
631 0xC0, // End Collection
635 static void udi_hid_mou_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
637 bool udi_hid_mou_enable(void)
639 // Initialize internal values
640 udi_hid_mou_rate = 0;
641 udi_hid_mou_protocol = 0;
642 udi_hid_mou_b_report_trans_ongoing = false;
643 memset(udi_hid_mou_report, 0, UDI_HID_MOU_REPORT_SIZE);
644 udi_hid_mou_b_report_valid = false;
645 return UDI_HID_MOU_ENABLE_EXT();
648 void udi_hid_mou_disable(void)
650 UDI_HID_MOU_DISABLE_EXT();
653 bool udi_hid_mou_setup(void)
655 return udi_hid_setup(&udi_hid_mou_rate,
656 &udi_hid_mou_protocol,
657 (uint8_t *) &udi_hid_mou_report_desc,
661 uint8_t udi_hid_mou_getsetting(void)
666 bool udi_hid_mou_send_report(void)
668 if (!main_b_mou_enable) {
672 if (udi_hid_mou_b_report_trans_ongoing) {
676 memcpy(udi_hid_mou_report_trans, udi_hid_mou_report, UDI_HID_MOU_REPORT_SIZE);
677 udi_hid_mou_b_report_valid = false;
678 udi_hid_mou_b_report_trans_ongoing =
679 udd_ep_run(UDI_HID_MOU_EP_IN | USB_EP_DIR_IN,
681 udi_hid_mou_report_trans,
682 UDI_HID_MOU_REPORT_SIZE,
683 udi_hid_mou_report_sent);
685 return udi_hid_mou_b_report_trans_ongoing;
688 static void udi_hid_mou_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep)
693 udi_hid_mou_b_report_trans_ongoing = false;
694 if (udi_hid_mou_b_report_valid) {
695 udi_hid_mou_send_report();
701 //********************************************************************************************
703 //********************************************************************************************
706 bool udi_hid_raw_enable(void);
707 void udi_hid_raw_disable(void);
708 bool udi_hid_raw_setup(void);
709 uint8_t udi_hid_raw_getsetting(void);
711 UDC_DESC_STORAGE udi_api_t udi_api_hid_raw = {
712 .enable = (bool(*)(void))udi_hid_raw_enable,
713 .disable = (void (*)(void))udi_hid_raw_disable,
714 .setup = (bool(*)(void))udi_hid_raw_setup,
715 .getsetting = (uint8_t(*)(void))udi_hid_raw_getsetting,
719 COMPILER_WORD_ALIGNED
720 static uint8_t udi_hid_raw_rate;
722 COMPILER_WORD_ALIGNED
723 static uint8_t udi_hid_raw_protocol;
725 COMPILER_WORD_ALIGNED
726 uint8_t udi_hid_raw_report_set[UDI_HID_RAW_REPORT_SIZE];
728 static bool udi_hid_raw_b_report_valid;
730 COMPILER_WORD_ALIGNED
731 uint8_t udi_hid_raw_report[UDI_HID_RAW_REPORT_SIZE];
733 static bool udi_hid_raw_b_report_trans_ongoing;
735 COMPILER_WORD_ALIGNED
736 static uint8_t udi_hid_raw_report_trans[UDI_HID_RAW_REPORT_SIZE];
738 COMPILER_WORD_ALIGNED
739 UDC_DESC_STORAGE udi_hid_raw_report_desc_t udi_hid_raw_report_desc = {
741 0x06, // Usage Page (Vendor Defined)
743 0x0A, // Usage (Mouse)
745 0xA1, 0x01, // Collection (Application)
746 0x75, 0x08, // Report Size (8)
747 0x15, 0x00, // Logical Minimum (0)
748 0x25, 0xFF, // Logical Maximum (255)
749 0x95, 0x40, // Report Count
750 0x09, 0x01, // Usage (Input)
751 0x81, 0x02, // Input (Data
752 0x95, 0x40, // Report Count
753 0x09, 0x02, // Usage (Output)
754 0x91, 0x02, // Output (Data
755 0xC0, // End Collection - Consumer Control
759 static bool udi_hid_raw_setreport(void);
760 static void udi_hid_raw_setreport_valid(void);
762 static void udi_hid_raw_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
764 bool udi_hid_raw_enable(void)
766 // Initialize internal values
767 udi_hid_raw_rate = 0;
768 udi_hid_raw_protocol = 0;
769 udi_hid_raw_b_report_trans_ongoing = false;
770 memset(udi_hid_raw_report, 0, UDI_HID_RAW_REPORT_SIZE);
771 udi_hid_raw_b_report_valid = false;
772 return UDI_HID_RAW_ENABLE_EXT();
775 void udi_hid_raw_disable(void)
777 UDI_HID_RAW_DISABLE_EXT();
780 bool udi_hid_raw_setup(void)
782 return udi_hid_setup(&udi_hid_raw_rate,
783 &udi_hid_raw_protocol,
784 (uint8_t *) &udi_hid_raw_report_desc,
785 udi_hid_raw_setreport);
788 uint8_t udi_hid_raw_getsetting(void)
793 static bool udi_hid_raw_setreport(void)
795 if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8))
796 && (0 == (0xFF & udd_g_ctrlreq.req.wValue))
797 && (UDI_HID_RAW_REPORT_SIZE == udd_g_ctrlreq.req.wLength)) {
798 // Report OUT type on report ID 0 from USB Host
799 udd_g_ctrlreq.payload = udi_hid_raw_report_set;
800 udd_g_ctrlreq.callback = udi_hid_raw_setreport_valid; //must call routine to transform setreport to LED state
801 udd_g_ctrlreq.payload_size = UDI_HID_RAW_REPORT_SIZE;
807 bool udi_hid_raw_send_report(void)
809 if (!main_b_raw_enable) {
813 if (udi_hid_raw_b_report_trans_ongoing) {
817 memcpy(udi_hid_raw_report_trans, udi_hid_raw_report,UDI_HID_RAW_REPORT_SIZE);
818 udi_hid_raw_b_report_valid = false;
819 udi_hid_raw_b_report_trans_ongoing =
820 udd_ep_run(UDI_HID_RAW_EP_IN | USB_EP_DIR_IN,
822 udi_hid_raw_report_trans,
823 UDI_HID_RAW_REPORT_SIZE,
824 udi_hid_raw_report_sent);
826 return udi_hid_raw_b_report_trans_ongoing;
829 static void udi_hid_raw_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep)
834 udi_hid_raw_b_report_trans_ongoing = false;
835 if (udi_hid_raw_b_report_valid) {
836 udi_hid_raw_send_report();
840 static void udi_hid_raw_setreport_valid(void)
847 //********************************************************************************************
849 //********************************************************************************************
852 bool udi_hid_con_enable(void);
853 void udi_hid_con_disable(void);
854 bool udi_hid_con_setup(void);
855 uint8_t udi_hid_con_getsetting(void);
857 UDC_DESC_STORAGE udi_api_t udi_api_hid_con = {
858 .enable = (bool(*)(void))udi_hid_con_enable,
859 .disable = (void (*)(void))udi_hid_con_disable,
860 .setup = (bool(*)(void))udi_hid_con_setup,
861 .getsetting = (uint8_t(*)(void))udi_hid_con_getsetting,
865 COMPILER_WORD_ALIGNED
866 static uint8_t udi_hid_con_rate;
868 COMPILER_WORD_ALIGNED
869 static uint8_t udi_hid_con_protocol;
871 COMPILER_WORD_ALIGNED
872 uint8_t udi_hid_con_report_set[UDI_HID_CON_REPORT_SIZE];
874 bool udi_hid_con_b_report_valid;
876 COMPILER_WORD_ALIGNED
877 uint8_t udi_hid_con_report[UDI_HID_CON_REPORT_SIZE];
879 volatile bool udi_hid_con_b_report_trans_ongoing;
881 COMPILER_WORD_ALIGNED
882 static uint8_t udi_hid_con_report_trans[UDI_HID_CON_REPORT_SIZE];
884 COMPILER_WORD_ALIGNED
885 UDC_DESC_STORAGE udi_hid_con_report_desc_t udi_hid_con_report_desc = {
887 0x06, 0x31, 0xFF, // Vendor Page (PJRC Teensy compatible)
888 0x09, 0x74, // Vendor Usage (PJRC Teensy compatible)
889 0xA1, 0x01, // Collection (Application)
890 0x09, 0x75, // Usage (Vendor)
891 0x15, 0x00, // Logical Minimum (0x00)
892 0x26, 0xFF, 0x00, // Logical Maximum (0x00FF)
893 0x95, CONSOLE_EPSIZE, // Report Count
894 0x75, 0x08, // Report Size (8)
895 0x81, 0x02, // Input (Data)
896 0x09, 0x76, // Usage (Vendor)
897 0x15, 0x00, // Logical Minimum (0x00)
898 0x26, 0xFF, 0x00, // Logical Maximum (0x00FF)
899 0x95, CONSOLE_EPSIZE, // Report Count
900 0x75, 0x08, // Report Size (8)
901 0x91, 0x02, // Output (Data)
902 0xC0, // End Collection
906 static bool udi_hid_con_setreport(void);
907 static void udi_hid_con_setreport_valid(void);
909 static void udi_hid_con_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep);
911 bool udi_hid_con_enable(void)
913 // Initialize internal values
914 udi_hid_con_rate = 0;
915 udi_hid_con_protocol = 0;
916 udi_hid_con_b_report_trans_ongoing = false;
917 memset(udi_hid_con_report, 0, UDI_HID_CON_REPORT_SIZE);
918 udi_hid_con_b_report_valid = false;
919 return UDI_HID_CON_ENABLE_EXT();
922 void udi_hid_con_disable(void)
924 UDI_HID_CON_DISABLE_EXT();
927 bool udi_hid_con_setup(void)
929 return udi_hid_setup(&udi_hid_con_rate,
930 &udi_hid_con_protocol,
931 (uint8_t *) &udi_hid_con_report_desc,
932 udi_hid_con_setreport);
935 uint8_t udi_hid_con_getsetting(void)
940 static bool udi_hid_con_setreport(void)
942 if ((USB_HID_REPORT_TYPE_OUTPUT == (udd_g_ctrlreq.req.wValue >> 8))
943 && (0 == (0xFF & udd_g_ctrlreq.req.wValue))
944 && (UDI_HID_CON_REPORT_SIZE == udd_g_ctrlreq.req.wLength)) {
945 udd_g_ctrlreq.payload = udi_hid_con_report_set;
946 udd_g_ctrlreq.callback = udi_hid_con_setreport_valid;
947 udd_g_ctrlreq.payload_size = UDI_HID_CON_REPORT_SIZE;
953 bool udi_hid_con_send_report(void)
955 if (!main_b_con_enable) {
959 if (udi_hid_con_b_report_trans_ongoing) {
963 memcpy(udi_hid_con_report_trans, udi_hid_con_report,UDI_HID_CON_REPORT_SIZE);
964 udi_hid_con_b_report_valid = false;
965 udi_hid_con_b_report_trans_ongoing =
966 udd_ep_run(UDI_HID_CON_EP_IN | USB_EP_DIR_IN,
968 udi_hid_con_report_trans,
969 UDI_HID_CON_REPORT_SIZE,
970 udi_hid_con_report_sent);
972 return udi_hid_con_b_report_trans_ongoing;
975 static void udi_hid_con_report_sent(udd_ep_status_t status, iram_size_t nb_sent, udd_ep_id_t ep)
980 udi_hid_con_b_report_trans_ongoing = false;
981 if (udi_hid_con_b_report_valid) {
982 udi_hid_con_send_report();
986 static void udi_hid_con_setreport_valid(void)