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