4 * \brief USB Device Human Interface Device (HID) 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>
48 #include "usb_protocol.h"
55 * \ingroup udi_hid_group
56 * \defgroup udi_hid_group_internal Implementation of HID common library
61 * \brief Send the specific descriptors requested by SETUP request
63 * \retval true if the descriptor is supported
65 static bool udi_hid_reqstdifaceget_descriptor(uint8_t *report_desc);
67 bool udi_hid_setup( uint8_t *rate, uint8_t *protocol, uint8_t *report_desc, bool (*setup_report)(void) )
69 if (Udd_setup_is_in()) {
70 // Requests Interface GET
71 if (Udd_setup_type() == USB_REQ_TYPE_STANDARD) {
72 // Requests Standard Interface Get
73 switch (udd_g_ctrlreq.req.bRequest) {
75 case USB_REQ_GET_DESCRIPTOR:
76 return udi_hid_reqstdifaceget_descriptor(report_desc);
79 if (Udd_setup_type() == USB_REQ_TYPE_CLASS) {
80 // Requests Class Interface Get
81 switch (udd_g_ctrlreq.req.bRequest) {
83 case USB_REQ_HID_GET_REPORT:
84 return setup_report();
86 case USB_REQ_HID_GET_IDLE:
87 udd_g_ctrlreq.payload = rate;
88 udd_g_ctrlreq.payload_size = 1;
91 case USB_REQ_HID_GET_PROTOCOL:
92 udd_g_ctrlreq.payload = protocol;
93 udd_g_ctrlreq.payload_size = 1;
98 if (Udd_setup_is_out()) {
99 // Requests Interface SET
100 if (Udd_setup_type() == USB_REQ_TYPE_CLASS) {
101 // Requests Class Interface Set
102 switch (udd_g_ctrlreq.req.bRequest) {
104 case USB_REQ_HID_SET_REPORT:
105 return setup_report();
107 case USB_REQ_HID_SET_IDLE:
108 *rate = udd_g_ctrlreq.req.wValue >> 8;
111 case USB_REQ_HID_SET_PROTOCOL:
112 if (0 != udd_g_ctrlreq.req.wLength)
114 *protocol = udd_g_ctrlreq.req.wValue;
119 return false; // Request not supported
122 //---------------------------------------------
123 //------- Internal routines
125 static bool udi_hid_reqstdifaceget_descriptor(uint8_t *report_desc)
127 usb_hid_descriptor_t UDC_DESC_STORAGE *ptr_hid_desc;
129 // Get the USB descriptor which is located after the interface descriptor
130 // This descriptor must be the HID descriptor
131 ptr_hid_desc = (usb_hid_descriptor_t UDC_DESC_STORAGE *) ((uint8_t *)
132 udc_get_interface_desc() + sizeof(usb_iface_desc_t));
133 if (USB_DT_HID != ptr_hid_desc->bDescriptorType)
136 // The SETUP request can ask for:
137 // - an USB_DT_HID descriptor
138 // - or USB_DT_HID_REPORT descriptor
139 // - or USB_DT_HID_PHYSICAL descriptor
140 if (USB_DT_HID == (uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) {
141 // USB_DT_HID descriptor requested then send it
142 udd_g_ctrlreq.payload = (uint8_t *) ptr_hid_desc;
143 udd_g_ctrlreq.payload_size =
144 min(udd_g_ctrlreq.req.wLength,
145 ptr_hid_desc->bLength);
148 // The HID_X descriptor requested must correspond to report type
149 // included in the HID descriptor
150 if (ptr_hid_desc->bRDescriptorType ==
151 (uint8_t) (udd_g_ctrlreq.req.wValue >> 8)) {
152 // Send HID Report descriptor given by high level
153 udd_g_ctrlreq.payload = report_desc;
154 udd_g_ctrlreq.payload_size =
155 min(udd_g_ctrlreq.req.wLength,
156 le16_to_cpu(ptr_hid_desc->wDescriptorLength));