1+ /* Copyright (c) 2015, Arduino LLC
2+ **
3+ ** Original code (pre-library): Copyright (c) 2011, Peter Barrett
4+ **
5+ ** Permission to use, copy, modify, and/or distribute this software for
6+ ** any purpose with or without fee is hereby granted, provided that the
7+ ** above copyright notice and this permission notice appear in all copies.
8+ **
9+ ** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10+ ** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11+ ** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
12+ ** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
13+ ** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
14+ ** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
15+ ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
16+ ** SOFTWARE.
17+ */
18+
19+ #include " USB/PluggableUSB.h"
20+ #include " HID.h"
21+
22+ HID_ HID;
23+
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 ;
52+
53+ int HID_GetInterface (uint8_t * interfaceNum)
54+ {
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 )
61+ };
62+ return USBD_SendControl (0 ,&_hidInterface,sizeof (_hidInterface));
63+ }
64+
65+ int HID_GetDescriptor (int8_t t)
66+ {
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->cb ->descriptor ,current->cb ->length );
72+ current = current->next ;
73+ }
74+ return total;
75+ } else {
76+ return 0 ;
77+ }
78+ }
79+
80+ void HID_::AppendDescriptor (HIDDescriptorListNode *node)
81+ {
82+ if (modules_count == 0 ) {
83+ rootNode = node;
84+ } else {
85+ HIDDescriptorListNode *current = rootNode;
86+ while (current->next != NULL ) {
87+ current = current->next ;
88+ }
89+ current->next = node;
90+ }
91+ modules_count++;
92+ sizeof_hidReportDescriptor += node->cb ->length ;
93+ }
94+
95+ void HID_::SendReport (uint8_t id, const void * data, int len)
96+ {
97+ uint8_t p[64 ];
98+ const uint8_t *d = reinterpret_cast <const uint8_t *>(data);
99+
100+ 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 );
104+ }
105+
106+ bool HID_Setup (USBSetup& setup, uint8_t i)
107+ {
108+ if (HID_INTERFACE != i) {
109+ 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+ }
125+ }
126+
127+ if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType)
128+ {
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+ }
140+ }
141+ return false ;
142+ }
143+ }
144+
145+ HID_::HID_ (void )
146+ {
147+ static uint8_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);
163+ }
164+
165+ int HID_::begin (void )
166+ {
167+ return 0 ;
168+ }
0 commit comments