diff --git a/class_h_i_d_boot.html b/class_h_i_d_boot.html index e8dbf3d6..3289540b 100644 --- a/class_h_i_d_boot.html +++ b/class_h_i_d_boot.html @@ -159,7 +159,7 @@ Additional Inherited Members   static const uint8_t epInterruptOutIndex = 2   -static const uint8_t maxHidInterfaces = 3 +static const uint8_t maxHidInterfaces = 5   static const uint8_t maxEpPerInterface = 2   diff --git a/class_h_i_d_composite.html b/class_h_i_d_composite.html index 8422bbe7..81513aea 100644 --- a/class_h_i_d_composite.html +++ b/class_h_i_d_composite.html @@ -189,7 +189,7 @@ Additional Inherited Members   static const uint8_t epInterruptOutIndex = 2   -static const uint8_t maxHidInterfaces = 3 +static const uint8_t maxHidInterfaces = 5   static const uint8_t maxEpPerInterface = 2   @@ -445,7 +445,7 @@ Additional Inherited Members

Reimplemented from USBDeviceConfig.

-

Definition at line 340 of file hidcomposite.cpp.

+

Definition at line 354 of file hidcomposite.cpp.

@@ -474,7 +474,7 @@ Additional Inherited Members

Reimplemented from USBDeviceConfig.

-

Definition at line 355 of file hidcomposite.cpp.

+

Definition at line 369 of file hidcomposite.cpp.

@@ -618,7 +618,7 @@ Additional Inherited Members
-

Definition at line 413 of file hidcomposite.cpp.

+

Definition at line 427 of file hidcomposite.cpp.

diff --git a/class_h_i_d_universal.html b/class_h_i_d_universal.html index aac7fa69..ec0bb050 100644 --- a/class_h_i_d_universal.html +++ b/class_h_i_d_universal.html @@ -189,7 +189,7 @@ Additional Inherited Members   static const uint8_t epInterruptOutIndex = 2   -static const uint8_t maxHidInterfaces = 3 +static const uint8_t maxHidInterfaces = 5   static const uint8_t maxEpPerInterface = 2   @@ -443,7 +443,7 @@ Additional Inherited Members

Reimplemented from USBDeviceConfig.

-

Definition at line 340 of file hiduniversal.cpp.

+

Definition at line 354 of file hiduniversal.cpp.

@@ -472,7 +472,7 @@ Additional Inherited Members

Reimplemented from USBDeviceConfig.

-

Definition at line 367 of file hiduniversal.cpp.

+

Definition at line 381 of file hiduniversal.cpp.

@@ -616,7 +616,7 @@ Additional Inherited Members
-

Definition at line 423 of file hiduniversal.cpp.

+

Definition at line 437 of file hiduniversal.cpp.

diff --git a/class_p_s4_u_s_b.html b/class_p_s4_u_s_b.html index 9ff83dbe..3c3fd0ee 100644 --- a/class_p_s4_u_s_b.html +++ b/class_p_s4_u_s_b.html @@ -251,7 +251,7 @@ Additional Inherited Members   static const uint8_t epInterruptOutIndex = 2   -static const uint8_t maxHidInterfaces = 3 +static const uint8_t maxHidInterfaces = 5   static const uint8_t maxEpPerInterface = 2   diff --git a/class_p_s_buzz.html b/class_p_s_buzz.html index 7ea6efec..62a7d768 100644 --- a/class_p_s_buzz.html +++ b/class_p_s_buzz.html @@ -214,7 +214,7 @@ Additional Inherited Members   static const uint8_t epInterruptOutIndex = 2   -static const uint8_t maxHidInterfaces = 3 +static const uint8_t maxHidInterfaces = 5   static const uint8_t maxEpPerInterface = 2   diff --git a/class_u_s_b_h_i_d.html b/class_u_s_b_h_i_d.html index 8ebc77de..a91cacc9 100644 --- a/class_u_s_b_h_i_d.html +++ b/class_u_s_b_h_i_d.html @@ -166,7 +166,7 @@ Static Protected Attributes   static const uint8_t epInterruptOutIndex = 2   -static const uint8_t maxHidInterfaces = 3 +static const uint8_t maxHidInterfaces = 5   static const uint8_t maxEpPerInterface = 2   @@ -770,7 +770,7 @@ Static Protected Attributes - +
const uint8_t USBHID::maxHidInterfaces = 3const uint8_t USBHID::maxHidInterfaces = 5
diff --git a/hidcomposite_8cpp_source.html b/hidcomposite_8cpp_source.html index 3887c9a2..737e3f7e 100644 --- a/hidcomposite_8cpp_source.html +++ b/hidcomposite_8cpp_source.html @@ -63,7 +63,7 @@ $(function() {
hidcomposite.cpp
-Go to the documentation of this file.
1 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2 
3 This software may be distributed and modified under the terms of the GNU
4 General Public License version 2 (GPL2) as published by the Free Software
5 Foundation and appearing in the file GPL2.TXT included in the packaging of
6 this file. Please note that GPL2 Section 2[b] requires that all works based
7 on this software must also be made publicly available under the terms of
8 the GPL2 ("Copyleft").
9 
10 Contact information
11 -------------------
12 
13 Circuits At Home, LTD
14 Web : http://www.circuitsathome.com
15 e-mail : support@circuitsathome.com
16  */
17 
18 #include "hidcomposite.h"
19 
21 USBHID(p),
22 qNextPollTime(0),
23 pollInterval(0),
24 bPollEnable(false),
25 bHasReportId(false) {
26  Initialize();
27 
28  if(pUsb)
30 }
31 
32 uint16_t HIDComposite::GetHidClassDescrLen(uint8_t type, uint8_t num) {
33  for(uint8_t i = 0, n = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
34  if(descrInfo[i].bDescrType == type) {
35  if(n == num)
36  return descrInfo[i].wDescriptorLength;
37  n++;
38  }
39  }
40  return 0;
41 }
42 
43 void HIDComposite::Initialize() {
44  for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
45  rptParsers[i].rptId = 0;
46  rptParsers[i].rptParser = NULL;
47  }
48  for(uint8_t i = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
49  descrInfo[i].bDescrType = 0;
50  descrInfo[i].wDescriptorLength = 0;
51  }
52  for(uint8_t i = 0; i < maxHidInterfaces; i++) {
53  hidInterfaces[i].bmInterface = 0;
54  hidInterfaces[i].bmProtocol = 0;
55 
56  for(uint8_t j = 0; j < maxEpPerInterface; j++)
57  hidInterfaces[i].epIndex[j] = 0;
58  }
59  for(uint8_t i = 0; i < totalEndpoints; i++) {
60  epInfo[i].epAddr = 0;
61  epInfo[i].maxPktSize = (i) ? 0 : 8;
62  epInfo[i].bmSndToggle = 0;
63  epInfo[i].bmRcvToggle = 0;
65  }
66  bNumEP = 1;
67  bNumIface = 0;
68  bConfNum = 0;
69  pollInterval = 0;
70 }
71 
73  for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
74  if(rptParsers[i].rptId == 0 && rptParsers[i].rptParser == NULL) {
75  rptParsers[i].rptId = id;
76  rptParsers[i].rptParser = prs;
77  return true;
78  }
79  }
80  return false;
81 }
82 
84  if(!bHasReportId)
85  return ((rptParsers[0].rptParser) ? rptParsers[0].rptParser : NULL);
86 
87  for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
88  if(rptParsers[i].rptId == id)
89  return rptParsers[i].rptParser;
90  }
91  return NULL;
92 }
93 
94 uint8_t HIDComposite::Init(uint8_t parent, uint8_t port, bool lowspeed) {
95  const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
96 
97  uint8_t buf[constBufSize];
98  USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
99  uint8_t rcode;
100  UsbDevice *p = NULL;
101  EpInfo *oldep_ptr = NULL;
102  uint8_t len = 0;
103 
104  uint8_t num_of_conf; // number of configurations
105  //uint8_t num_of_intf; // number of interfaces
106 
107  AddressPool &addrPool = pUsb->GetAddressPool();
108 
109  USBTRACE("HU Init\r\n");
110 
111  if(bAddress)
113 
114  // Get pointer to pseudo device with address 0 assigned
115  p = addrPool.GetUsbDevicePtr(0);
116 
117  if(!p)
119 
120  if(!p->epinfo) {
121  USBTRACE("epinfo\r\n");
123  }
124 
125  // Save old pointer to EP_RECORD of address 0
126  oldep_ptr = p->epinfo;
127 
128  // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
129  p->epinfo = epInfo;
130 
131  p->lowspeed = lowspeed;
132 
133  // Get device descriptor
134  rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
135 
136  if(!rcode)
137  len = (buf[0] > constBufSize) ? constBufSize : buf[0];
138 
139  if(rcode) {
140  // Restore p->epinfo
141  p->epinfo = oldep_ptr;
142 
143  goto FailGetDevDescr;
144  }
145 
146  // Restore p->epinfo
147  p->epinfo = oldep_ptr;
148 
149  // Allocate new address according to device class
150  bAddress = addrPool.AllocAddress(parent, false, port);
151 
152  if(!bAddress)
154 
155  // Extract Max Packet Size from the device descriptor
157 
158  // Assign new address to the device
159  rcode = pUsb->setAddr(0, 0, bAddress);
160 
161  if(rcode) {
162  p->lowspeed = false;
163  addrPool.FreeAddress(bAddress);
164  bAddress = 0;
165  USBTRACE2("setAddr:", rcode);
166  return rcode;
167  }
168 
169  //delay(2); //per USB 2.0 sect.9.2.6.3
170 
171  USBTRACE2("Addr:", bAddress);
172 
173  p->lowspeed = false;
174 
175  p = addrPool.GetUsbDevicePtr(bAddress);
176 
177  if(!p)
179 
180  p->lowspeed = lowspeed;
181 
182  if(len)
183  rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
184 
185  if(rcode)
186  goto FailGetDevDescr;
187 
188  VID = udd->idVendor; // Can be used by classes that inherits this class to check the VID and PID of the connected device
189  PID = udd->idProduct;
190 
191  num_of_conf = udd->bNumConfigurations;
192 
193  // Assign epInfo to epinfo pointer
194  rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
195 
196  if(rcode)
197  goto FailSetDevTblEntry;
198 
199  USBTRACE2("NC:", num_of_conf);
200 
201  for(uint8_t i = 0; i < num_of_conf; i++) {
202  //HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
204  CP_MASK_COMPARE_CLASS> confDescrParser(this);
205 
206  //rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
207  rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
208 
209  if(rcode)
210  goto FailGetConfDescr;
211 
212  if(bNumEP > 1)
213  break;
214  } // for
215 
216  if(bNumEP < 2)
218 
219  // Assign epInfo to epinfo pointer
220  rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
221 
222  USBTRACE2("Cnf:", bConfNum);
223 
224  // Set Configuration Value
225  rcode = pUsb->setConf(bAddress, 0, bConfNum);
226 
227  if(rcode)
228  goto FailSetConfDescr;
229 
230  USBTRACE2("NumIface:", bNumIface);
231 
232  for(uint8_t i = 0; i < bNumIface; i++) {
233  if(hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
234  continue;
235 
236  USBTRACE2("SetIdle:", hidInterfaces[i].bmInterface);
237 
238  rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);
239 
240  if(rcode && rcode != hrSTALL)
241  goto FailSetIdle;
242  }
243 
244  USBTRACE("HU configured\r\n");
245 
247 
248  bPollEnable = true;
249  return 0;
250 
251 FailGetDevDescr:
252 #ifdef DEBUG_USB_HOST
254  goto Fail;
255 #endif
256 
257 FailSetDevTblEntry:
258 #ifdef DEBUG_USB_HOST
260  goto Fail;
261 #endif
262 
263 FailGetConfDescr:
264 #ifdef DEBUG_USB_HOST
266  goto Fail;
267 #endif
268 
269 FailSetConfDescr:
270 #ifdef DEBUG_USB_HOST
272  goto Fail;
273 #endif
274 
275 
276 FailSetIdle:
277 #ifdef DEBUG_USB_HOST
278  USBTRACE("SetIdle:");
279 #endif
280 
281 #ifdef DEBUG_USB_HOST
282 Fail:
283  NotifyFail(rcode);
284 #endif
285  Release();
286  return rcode;
287 }
288 
289 HIDComposite::HIDInterface* HIDComposite::FindInterface(uint8_t iface, uint8_t alt, uint8_t proto) {
290  for(uint8_t i = 0; i < bNumIface && i < maxHidInterfaces; i++)
291  if(hidInterfaces[i].bmInterface == iface && hidInterfaces[i].bmAltSet == alt
292  && hidInterfaces[i].bmProtocol == proto)
293  return hidInterfaces + i;
294  return NULL;
295 }
296 
297 void HIDComposite::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
298  //ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
299  //ErrorMessage<uint8_t>(PSTR("Iface Num"), iface);
300  //ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
301 
302  bConfNum = conf;
303 
304  uint8_t index = 0;
305  HIDInterface *piface = FindInterface(iface, alt, proto);
306 
307  // Fill in interface structure in case of new interface
308  if(!piface) {
309  piface = hidInterfaces + bNumIface;
310  piface->bmInterface = iface;
311  piface->bmAltSet = alt;
312  piface->bmProtocol = proto;
313  bNumIface++;
314  }
315 
317  index = (pep->bEndpointAddress & 0x80) == 0x80 ? epInterruptInIndex : epInterruptOutIndex;
318 
319  if(!SelectInterface(iface, proto))
320  index = 0;
321 
322  if(index) {
323  // Fill in the endpoint info structure
324  epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
325  epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
326  epInfo[bNumEP].bmSndToggle = 0;
327  epInfo[bNumEP].bmRcvToggle = 0;
328  epInfo[bNumEP].bmNakPower = USB_NAK_NOWAIT;
329 
330  // Fill in the endpoint index list
331  piface->epIndex[index] = bNumEP; //(pep->bEndpointAddress & 0x0F);
332 
333  if(pollInterval < pep->bInterval) // Set the polling interval as the largest polling interval obtained from endpoints
334  pollInterval = pep->bInterval;
335 
336  bNumEP++;
337  }
338 }
339 
342 
343  bNumEP = 1;
344  bAddress = 0;
345  qNextPollTime = 0;
346  bPollEnable = false;
347  return 0;
348 }
349 
350 void HIDComposite::ZeroMemory(uint8_t len, uint8_t *buf) {
351  for(uint8_t i = 0; i < len; i++)
352  buf[i] = 0;
353 }
354 
356  uint8_t rcode = 0;
357 
358  if(!bPollEnable)
359  return 0;
360 
361  if((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) {
362  qNextPollTime = (uint32_t)millis() + pollInterval;
363 
364  uint8_t buf[constBuffLen];
365 
366  for(uint8_t i = 0; i < bNumIface; i++) {
367  uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex];
368 
369  if (index == 0)
370  continue;
371 
372  uint16_t read = (uint16_t)epInfo[index].maxPktSize;
373 
374  ZeroMemory(constBuffLen, buf);
375 
376  uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf);
377 
378  if(rcode) {
379  if(rcode != hrNAK)
380  USBTRACE3("(hidcomposite.h) Poll:", rcode, 0x81);
381  continue;
382  }
383 
384  if(read == 0)
385  continue;
386 
387  if(read > constBuffLen)
388  read = constBuffLen;
389 
390 #if 0
391  Notify(PSTR("\r\nBuf: "), 0x80);
392 
393  for(uint8_t i = 0; i < read; i++) {
394  D_PrintHex<uint8_t > (buf[i], 0x80);
395  Notify(PSTR(" "), 0x80);
396  }
397 
398  Notify(PSTR("\r\n"), 0x80);
399 #endif
400  ParseHIDData(this, epInfo[index].epAddr, bHasReportId, (uint8_t)read, buf);
401 
402  HIDReportParser *prs = GetReportParser(((bHasReportId) ? *buf : 0));
403 
404  if(prs)
405  prs->Parse(this, bHasReportId, (uint8_t)read, buf);
406  }
407 
408  }
409  return rcode;
410 }
411 
412 // Send a report to interrupt out endpoint. This is NOT SetReport() request!
413 uint8_t HIDComposite::SndRpt(uint16_t nbytes, uint8_t *dataptr) {
414  return pUsb->outTransfer(bAddress, epInfo[epInterruptOutIndex].epAddr, nbytes, dataptr);
415 }
uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t *dataptr)
Definition: Usb.cpp:801
+Go to the documentation of this file.
1 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2 
3 This software may be distributed and modified under the terms of the GNU
4 General Public License version 2 (GPL2) as published by the Free Software
5 Foundation and appearing in the file GPL2.TXT included in the packaging of
6 this file. Please note that GPL2 Section 2[b] requires that all works based
7 on this software must also be made publicly available under the terms of
8 the GPL2 ("Copyleft").
9 
10 Contact information
11 -------------------
12 
13 Circuits At Home, LTD
14 Web : http://www.circuitsathome.com
15 e-mail : support@circuitsathome.com
16  */
17 
18 #include "hidcomposite.h"
19 
21 USBHID(p),
22 qNextPollTime(0),
23 pollInterval(0),
24 bPollEnable(false),
25 bHasReportId(false) {
26  Initialize();
27 
28  if(pUsb)
30 }
31 
32 uint16_t HIDComposite::GetHidClassDescrLen(uint8_t type, uint8_t num) {
33  for(uint8_t i = 0, n = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
34  if(descrInfo[i].bDescrType == type) {
35  if(n == num)
36  return descrInfo[i].wDescriptorLength;
37  n++;
38  }
39  }
40  return 0;
41 }
42 
43 void HIDComposite::Initialize() {
44  for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
45  rptParsers[i].rptId = 0;
46  rptParsers[i].rptParser = NULL;
47  }
48  for(uint8_t i = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
49  descrInfo[i].bDescrType = 0;
50  descrInfo[i].wDescriptorLength = 0;
51  }
52  for(uint8_t i = 0; i < maxHidInterfaces; i++) {
53  hidInterfaces[i].bmInterface = 0;
54  hidInterfaces[i].bmProtocol = 0;
55 
56  for(uint8_t j = 0; j < maxEpPerInterface; j++)
57  hidInterfaces[i].epIndex[j] = 0;
58  }
59  for(uint8_t i = 0; i < totalEndpoints; i++) {
60  epInfo[i].epAddr = 0;
61  epInfo[i].maxPktSize = (i) ? 0 : 8;
62  epInfo[i].bmSndToggle = 0;
63  epInfo[i].bmRcvToggle = 0;
65  }
66  bNumEP = 1;
67  bNumIface = 0;
68  bConfNum = 0;
69  pollInterval = 0;
70 }
71 
73  for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
74  if(rptParsers[i].rptId == 0 && rptParsers[i].rptParser == NULL) {
75  rptParsers[i].rptId = id;
76  rptParsers[i].rptParser = prs;
77  return true;
78  }
79  }
80  return false;
81 }
82 
84  if(!bHasReportId)
85  return ((rptParsers[0].rptParser) ? rptParsers[0].rptParser : NULL);
86 
87  for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
88  if(rptParsers[i].rptId == id)
89  return rptParsers[i].rptParser;
90  }
91  return NULL;
92 }
93 
94 uint8_t HIDComposite::Init(uint8_t parent, uint8_t port, bool lowspeed) {
95  const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
96 
97  uint8_t buf[constBufSize];
98  USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
99  uint8_t rcode;
100  UsbDevice *p = NULL;
101  EpInfo *oldep_ptr = NULL;
102  uint8_t len = 0;
103 
104  uint8_t num_of_conf; // number of configurations
105  //uint8_t num_of_intf; // number of interfaces
106 
107  AddressPool &addrPool = pUsb->GetAddressPool();
108 
109  USBTRACE("HU Init\r\n");
110 
111  if(bAddress)
113 
114  // Get pointer to pseudo device with address 0 assigned
115  p = addrPool.GetUsbDevicePtr(0);
116 
117  if(!p)
119 
120  if(!p->epinfo) {
121  USBTRACE("epinfo\r\n");
123  }
124 
125  // Save old pointer to EP_RECORD of address 0
126  oldep_ptr = p->epinfo;
127 
128  // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
129  p->epinfo = epInfo;
130 
131  p->lowspeed = lowspeed;
132 
133  // Get device descriptor
134  rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
135 
136  if(!rcode)
137  len = (buf[0] > constBufSize) ? constBufSize : buf[0];
138 
139  if(rcode) {
140  // Restore p->epinfo
141  p->epinfo = oldep_ptr;
142 
143  goto FailGetDevDescr;
144  }
145 
146  // Restore p->epinfo
147  p->epinfo = oldep_ptr;
148 
149  // Allocate new address according to device class
150  bAddress = addrPool.AllocAddress(parent, false, port);
151 
152  if(!bAddress)
154 
155  // Extract Max Packet Size from the device descriptor
157 
158  // Assign new address to the device
159  rcode = pUsb->setAddr(0, 0, bAddress);
160 
161  if(rcode) {
162  p->lowspeed = false;
163  addrPool.FreeAddress(bAddress);
164  bAddress = 0;
165  USBTRACE2("setAddr:", rcode);
166  return rcode;
167  }
168 
169  //delay(2); //per USB 2.0 sect.9.2.6.3
170 
171  USBTRACE2("Addr:", bAddress);
172 
173  p->lowspeed = false;
174 
175  p = addrPool.GetUsbDevicePtr(bAddress);
176 
177  if(!p)
179 
180  p->lowspeed = lowspeed;
181 
182  if(len)
183  rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
184 
185  if(rcode)
186  goto FailGetDevDescr;
187 
188  VID = udd->idVendor; // Can be used by classes that inherits this class to check the VID and PID of the connected device
189  PID = udd->idProduct;
190 
191  num_of_conf = udd->bNumConfigurations;
192 
193  // Assign epInfo to epinfo pointer
194  rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
195 
196  if(rcode)
197  goto FailSetDevTblEntry;
198 
199  USBTRACE2("NC:", num_of_conf);
200 
201  for(uint8_t i = 0; i < num_of_conf; i++) {
202  //HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
204  CP_MASK_COMPARE_CLASS> confDescrParser(this);
205 
206  //rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
207  rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
208 
209  if(rcode)
210  goto FailGetConfDescr;
211 
212  if(bNumEP > 1)
213  break;
214  } // for
215 
216  if(bNumEP < 2)
218 
219  // Assign epInfo to epinfo pointer
220  rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
221 
222  USBTRACE2("Cnf:", bConfNum);
223 
224  // Set Configuration Value
225  rcode = pUsb->setConf(bAddress, 0, bConfNum);
226 
227  if(rcode)
228  goto FailSetConfDescr;
229 
230  USBTRACE2("NumIface:", bNumIface);
231 
232  for(uint8_t i = 0; i < bNumIface; i++) {
233  if(hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
234  continue;
235 
236  USBTRACE2("SetIdle:", hidInterfaces[i].bmInterface);
237 
238  rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);
239 
240  if(rcode && rcode != hrSTALL)
241  goto FailSetIdle;
242  }
243 
244  USBTRACE("HU configured\r\n");
245 
247 
248  bPollEnable = true;
249  return 0;
250 
251 FailGetDevDescr:
252 #ifdef DEBUG_USB_HOST
254  goto Fail;
255 #endif
256 
257 FailSetDevTblEntry:
258 #ifdef DEBUG_USB_HOST
260  goto Fail;
261 #endif
262 
263 FailGetConfDescr:
264 #ifdef DEBUG_USB_HOST
266  goto Fail;
267 #endif
268 
269 FailSetConfDescr:
270 #ifdef DEBUG_USB_HOST
272  goto Fail;
273 #endif
274 
275 
276 FailSetIdle:
277 #ifdef DEBUG_USB_HOST
278  USBTRACE("SetIdle:");
279 #endif
280 
281 #ifdef DEBUG_USB_HOST
282 Fail:
283  NotifyFail(rcode);
284 #endif
285  Release();
286  return rcode;
287 }
288 
289 HIDComposite::HIDInterface* HIDComposite::FindInterface(uint8_t iface, uint8_t alt, uint8_t proto) {
290  for(uint8_t i = 0; i < bNumIface && i < maxHidInterfaces; i++)
291  if(hidInterfaces[i].bmInterface == iface && hidInterfaces[i].bmAltSet == alt
292  && hidInterfaces[i].bmProtocol == proto)
293  return hidInterfaces + i;
294  return NULL;
295 }
296 
297 void HIDComposite::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
298  //ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
299  //ErrorMessage<uint8_t>(PSTR("Iface Num"), iface);
300  //ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
301 
302  bConfNum = conf;
303 
304  uint8_t index = 0;
305  HIDInterface *piface = FindInterface(iface, alt, proto);
306 
307  // Fill in interface structure in case of new interface
308  if(!piface) {
309  if(bNumIface >= maxHidInterfaces) {
310  // don't overflow hidInterfaces[]
311  Notify(PSTR("\r\n HIDComposite::EndpointXtract(): Not adding HID interface because we already have "), 0x80);
312  Notify(bNumIface, 0x80);
313  Notify(PSTR(" interfaces and can't hold more. "), 0x80);
314  return;
315  }
316  piface = hidInterfaces + bNumIface;
317  piface->bmInterface = iface;
318  piface->bmAltSet = alt;
319  piface->bmProtocol = proto;
320  bNumIface++;
321  }
322 
324  index = (pep->bEndpointAddress & 0x80) == 0x80 ? epInterruptInIndex : epInterruptOutIndex;
325 
326  if(!SelectInterface(iface, proto))
327  index = 0;
328 
329  if(index) {
330  if(bNumEP >= totalEndpoints) {
331  // don't overflow epInfo[] either
332  Notify(PSTR("\r\n HIDComposite::EndpointXtract(): Not adding endpoint info because we already have "), 0x80);
333  Notify(bNumEP, 0x80);
334  Notify(PSTR(" endpoints and can't hold more. "), 0x80);
335  return;
336  }
337  // Fill in the endpoint info structure
338  epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
339  epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
340  epInfo[bNumEP].bmSndToggle = 0;
341  epInfo[bNumEP].bmRcvToggle = 0;
342  epInfo[bNumEP].bmNakPower = USB_NAK_NOWAIT;
343 
344  // Fill in the endpoint index list
345  piface->epIndex[index] = bNumEP; //(pep->bEndpointAddress & 0x0F);
346 
347  if(pollInterval < pep->bInterval) // Set the polling interval as the largest polling interval obtained from endpoints
348  pollInterval = pep->bInterval;
349 
350  bNumEP++;
351  }
352 }
353 
356 
357  bNumEP = 1;
358  bAddress = 0;
359  qNextPollTime = 0;
360  bPollEnable = false;
361  return 0;
362 }
363 
364 void HIDComposite::ZeroMemory(uint8_t len, uint8_t *buf) {
365  for(uint8_t i = 0; i < len; i++)
366  buf[i] = 0;
367 }
368 
370  uint8_t rcode = 0;
371 
372  if(!bPollEnable)
373  return 0;
374 
375  if((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) {
376  qNextPollTime = (uint32_t)millis() + pollInterval;
377 
378  uint8_t buf[constBuffLen];
379 
380  for(uint8_t i = 0; i < bNumIface; i++) {
381  uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex];
382 
383  if (index == 0)
384  continue;
385 
386  uint16_t read = (uint16_t)epInfo[index].maxPktSize;
387 
388  ZeroMemory(constBuffLen, buf);
389 
390  uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf);
391 
392  if(rcode) {
393  if(rcode != hrNAK)
394  USBTRACE3("(hidcomposite.h) Poll:", rcode, 0x81);
395  continue;
396  }
397 
398  if(read == 0)
399  continue;
400 
401  if(read > constBuffLen)
402  read = constBuffLen;
403 
404 #if 0
405  Notify(PSTR("\r\nBuf: "), 0x80);
406 
407  for(uint8_t i = 0; i < read; i++) {
408  D_PrintHex<uint8_t > (buf[i], 0x80);
409  Notify(PSTR(" "), 0x80);
410  }
411 
412  Notify(PSTR("\r\n"), 0x80);
413 #endif
414  ParseHIDData(this, epInfo[index].epAddr, bHasReportId, (uint8_t)read, buf);
415 
416  HIDReportParser *prs = GetReportParser(((bHasReportId) ? *buf : 0));
417 
418  if(prs)
419  prs->Parse(this, bHasReportId, (uint8_t)read, buf);
420  }
421 
422  }
423  return rcode;
424 }
425 
426 // Send a report to interrupt out endpoint. This is NOT SetReport() request!
427 uint8_t HIDComposite::SndRpt(uint16_t nbytes, uint8_t *dataptr) {
428  return pUsb->outTransfer(bAddress, epInfo[epInterruptOutIndex].epAddr, nbytes, dataptr);
429 }
uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t *dataptr)
Definition: Usb.cpp:801
uint8_t bmRcvToggle
Definition: address.h:48
Definition: usbhid.h:143
@@ -114,7 +114,7 @@ $(function() {
uint8_t bAddress
Definition: usbhid.h:146
uint16_t wMaxPacketSize
Definition: usb_ch9.h:153
#define bmUSB_TRANSFER_TYPE
Definition: usb_ch9.h:94
-
uint8_t Poll()
+
uint8_t Poll()
static const uint8_t maxEpPerInterface
Definition: usbhid.h:153
uint16_t PID
Definition: hidcomposite.h:66
virtual bool SelectInterface(uint8_t iface, uint8_t proto)=0
@@ -137,8 +137,8 @@ $(function() {
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval=0)
Definition: Usb.cpp:209
uint8_t bNumConfigurations
Definition: usb_ch9.h:119
#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL
Definition: UsbCore.h:93
-
uint8_t Release()
-
uint8_t SndRpt(uint16_t nbytes, uint8_t *dataptr)
+
uint8_t Release()
+
uint8_t SndRpt(uint16_t nbytes, uint8_t *dataptr)
uint8_t maxPktSize
Definition: address.h:41
AddressPool & GetAddressPool()
Definition: UsbCore.h:226
diff --git a/hidcomposite_8h_source.html b/hidcomposite_8h_source.html index 8496e9d3..4db42ef5 100644 --- a/hidcomposite_8h_source.html +++ b/hidcomposite_8h_source.html @@ -79,7 +79,7 @@ $(function() {
Definition: address.h:39
virtual uint8_t GetAddress()
Definition: hidcomposite.h:90
uint8_t bAddress
Definition: usbhid.h:146
-
uint8_t Poll()
+
uint8_t Poll()
static const uint8_t maxEpPerInterface
Definition: usbhid.h:153
uint16_t PID
Definition: hidcomposite.h:66
virtual bool SelectInterface(uint8_t iface, uint8_t proto)=0
@@ -89,8 +89,8 @@ $(function() {
static const uint8_t totalEndpoints
Definition: usbhid.h:154
void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep)
-
uint8_t Release()
-
uint8_t SndRpt(uint16_t nbytes, uint8_t *dataptr)
+
uint8_t Release()
+
uint8_t SndRpt(uint16_t nbytes, uint8_t *dataptr)
Definition: UsbCore.h:210
bool SetReportParser(uint8_t id, HIDReportParser *prs)
diff --git a/hiduniversal_8cpp_source.html b/hiduniversal_8cpp_source.html index e760a5b5..76f64492 100644 --- a/hiduniversal_8cpp_source.html +++ b/hiduniversal_8cpp_source.html @@ -63,7 +63,7 @@ $(function() {
hiduniversal.cpp
-Go to the documentation of this file.
1 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2 
3 This software may be distributed and modified under the terms of the GNU
4 General Public License version 2 (GPL2) as published by the Free Software
5 Foundation and appearing in the file GPL2.TXT included in the packaging of
6 this file. Please note that GPL2 Section 2[b] requires that all works based
7 on this software must also be made publicly available under the terms of
8 the GPL2 ("Copyleft").
9 
10 Contact information
11 -------------------
12 
13 Circuits At Home, LTD
14 Web : http://www.circuitsathome.com
15 e-mail : support@circuitsathome.com
16  */
17 
18 #include "hiduniversal.h"
19 
21 USBHID(p),
22 qNextPollTime(0),
23 pollInterval(0),
24 bPollEnable(false),
25 bHasReportId(false) {
26  Initialize();
27 
28  if(pUsb)
30 }
31 
32 uint16_t HIDUniversal::GetHidClassDescrLen(uint8_t type, uint8_t num) {
33  for(uint8_t i = 0, n = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
34  if(descrInfo[i].bDescrType == type) {
35  if(n == num)
36  return descrInfo[i].wDescriptorLength;
37  n++;
38  }
39  }
40  return 0;
41 }
42 
43 void HIDUniversal::Initialize() {
44  for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
45  rptParsers[i].rptId = 0;
46  rptParsers[i].rptParser = NULL;
47  }
48  for(uint8_t i = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
49  descrInfo[i].bDescrType = 0;
50  descrInfo[i].wDescriptorLength = 0;
51  }
52  for(uint8_t i = 0; i < maxHidInterfaces; i++) {
53  hidInterfaces[i].bmInterface = 0;
54  hidInterfaces[i].bmProtocol = 0;
55 
56  for(uint8_t j = 0; j < maxEpPerInterface; j++)
57  hidInterfaces[i].epIndex[j] = 0;
58  }
59  for(uint8_t i = 0; i < totalEndpoints; i++) {
60  epInfo[i].epAddr = 0;
61  epInfo[i].maxPktSize = (i) ? 0 : 8;
62  epInfo[i].bmSndToggle = 0;
63  epInfo[i].bmRcvToggle = 0;
65  }
66  bNumEP = 1;
67  bNumIface = 0;
68  bConfNum = 0;
69  pollInterval = 0;
70 
71  ZeroMemory(constBuffLen, prevBuf);
72 }
73 
75  for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
76  if(rptParsers[i].rptId == 0 && rptParsers[i].rptParser == NULL) {
77  rptParsers[i].rptId = id;
78  rptParsers[i].rptParser = prs;
79  return true;
80  }
81  }
82  return false;
83 }
84 
86  if(!bHasReportId)
87  return ((rptParsers[0].rptParser) ? rptParsers[0].rptParser : NULL);
88 
89  for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
90  if(rptParsers[i].rptId == id)
91  return rptParsers[i].rptParser;
92  }
93  return NULL;
94 }
95 
96 uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
97  const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
98 
99  uint8_t buf[constBufSize];
100  USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
101  uint8_t rcode;
102  UsbDevice *p = NULL;
103  EpInfo *oldep_ptr = NULL;
104  uint8_t len = 0;
105 
106  uint8_t num_of_conf; // number of configurations
107  //uint8_t num_of_intf; // number of interfaces
108 
109  AddressPool &addrPool = pUsb->GetAddressPool();
110 
111  USBTRACE("HU Init\r\n");
112 
113  if(bAddress)
115 
116  // Get pointer to pseudo device with address 0 assigned
117  p = addrPool.GetUsbDevicePtr(0);
118 
119  if(!p)
121 
122  if(!p->epinfo) {
123  USBTRACE("epinfo\r\n");
125  }
126 
127  // Save old pointer to EP_RECORD of address 0
128  oldep_ptr = p->epinfo;
129 
130  // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
131  p->epinfo = epInfo;
132 
133  p->lowspeed = lowspeed;
134 
135  // Get device descriptor
136  rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
137 
138  if(!rcode)
139  len = (buf[0] > constBufSize) ? constBufSize : buf[0];
140 
141  if(rcode) {
142  // Restore p->epinfo
143  p->epinfo = oldep_ptr;
144 
145  goto FailGetDevDescr;
146  }
147 
148  // Restore p->epinfo
149  p->epinfo = oldep_ptr;
150 
151  // Allocate new address according to device class
152  bAddress = addrPool.AllocAddress(parent, false, port);
153 
154  if(!bAddress)
156 
157  // Extract Max Packet Size from the device descriptor
159 
160  // Assign new address to the device
161  rcode = pUsb->setAddr(0, 0, bAddress);
162 
163  if(rcode) {
164  p->lowspeed = false;
165  addrPool.FreeAddress(bAddress);
166  bAddress = 0;
167  USBTRACE2("setAddr:", rcode);
168  return rcode;
169  }
170 
171  //delay(2); //per USB 2.0 sect.9.2.6.3
172 
173  USBTRACE2("Addr:", bAddress);
174 
175  p->lowspeed = false;
176 
177  p = addrPool.GetUsbDevicePtr(bAddress);
178 
179  if(!p)
181 
182  p->lowspeed = lowspeed;
183 
184  if(len)
185  rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
186 
187  if(rcode)
188  goto FailGetDevDescr;
189 
190  VID = udd->idVendor; // Can be used by classes that inherits this class to check the VID and PID of the connected device
191  PID = udd->idProduct;
192 
193  num_of_conf = udd->bNumConfigurations;
194 
195  // Assign epInfo to epinfo pointer
196  rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
197 
198  if(rcode)
199  goto FailSetDevTblEntry;
200 
201  USBTRACE2("NC:", num_of_conf);
202 
203  for(uint8_t i = 0; i < num_of_conf; i++) {
204  //HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
206  CP_MASK_COMPARE_CLASS> confDescrParser(this);
207 
208  //rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
209  rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
210 
211  if(rcode)
212  goto FailGetConfDescr;
213 
214  if(bNumEP > 1)
215  break;
216  } // for
217 
218  if(bNumEP < 2)
220 
221  // Assign epInfo to epinfo pointer
222  rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
223 
224  USBTRACE2("Cnf:", bConfNum);
225 
226  // Set Configuration Value
227  rcode = pUsb->setConf(bAddress, 0, bConfNum);
228 
229  if(rcode)
230  goto FailSetConfDescr;
231 
232  for(uint8_t i = 0; i < bNumIface; i++) {
233  if(hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
234  continue;
235 
236  rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);
237 
238  if(rcode && rcode != hrSTALL)
239  goto FailSetIdle;
240  }
241 
242  USBTRACE("HU configured\r\n");
243 
245 
246  bPollEnable = true;
247  return 0;
248 
249 FailGetDevDescr:
250 #ifdef DEBUG_USB_HOST
252  goto Fail;
253 #endif
254 
255 FailSetDevTblEntry:
256 #ifdef DEBUG_USB_HOST
258  goto Fail;
259 #endif
260 
261 FailGetConfDescr:
262 #ifdef DEBUG_USB_HOST
264  goto Fail;
265 #endif
266 
267 FailSetConfDescr:
268 #ifdef DEBUG_USB_HOST
270  goto Fail;
271 #endif
272 
273 
274 FailSetIdle:
275 #ifdef DEBUG_USB_HOST
276  USBTRACE("SetIdle:");
277 #endif
278 
279 #ifdef DEBUG_USB_HOST
280 Fail:
281  NotifyFail(rcode);
282 #endif
283  Release();
284  return rcode;
285 }
286 
287 HIDUniversal::HIDInterface* HIDUniversal::FindInterface(uint8_t iface, uint8_t alt, uint8_t proto) {
288  for(uint8_t i = 0; i < bNumIface && i < maxHidInterfaces; i++)
289  if(hidInterfaces[i].bmInterface == iface && hidInterfaces[i].bmAltSet == alt
290  && hidInterfaces[i].bmProtocol == proto)
291  return hidInterfaces + i;
292  return NULL;
293 }
294 
295 void HIDUniversal::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
296  // If the first configuration satisfies, the others are not concidered.
297  if(bNumEP > 1 && conf != bConfNum)
298  return;
299 
300  //ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
301  //ErrorMessage<uint8_t>(PSTR("Iface Num"), iface);
302  //ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
303 
304  bConfNum = conf;
305 
306  uint8_t index = 0;
307  HIDInterface *piface = FindInterface(iface, alt, proto);
308 
309  // Fill in interface structure in case of new interface
310  if(!piface) {
311  piface = hidInterfaces + bNumIface;
312  piface->bmInterface = iface;
313  piface->bmAltSet = alt;
314  piface->bmProtocol = proto;
315  bNumIface++;
316  }
317 
319  index = (pep->bEndpointAddress & 0x80) == 0x80 ? epInterruptInIndex : epInterruptOutIndex;
320 
321  if(index) {
322  // Fill in the endpoint info structure
323  epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
324  epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
325  epInfo[bNumEP].bmSndToggle = 0;
326  epInfo[bNumEP].bmRcvToggle = 0;
327  epInfo[bNumEP].bmNakPower = USB_NAK_NOWAIT;
328 
329  // Fill in the endpoint index list
330  piface->epIndex[index] = bNumEP; //(pep->bEndpointAddress & 0x0F);
331 
332  if(pollInterval < pep->bInterval) // Set the polling interval as the largest polling interval obtained from endpoints
333  pollInterval = pep->bInterval;
334 
335  bNumEP++;
336  }
337  //PrintEndpointDescriptor(pep);
338 }
339 
342 
343  bNumEP = 1;
344  bAddress = 0;
345  qNextPollTime = 0;
346  bPollEnable = false;
347  return 0;
348 }
349 
350 bool HIDUniversal::BuffersIdentical(uint8_t len, uint8_t *buf1, uint8_t *buf2) {
351  for(uint8_t i = 0; i < len; i++)
352  if(buf1[i] != buf2[i])
353  return false;
354  return true;
355 }
356 
357 void HIDUniversal::ZeroMemory(uint8_t len, uint8_t *buf) {
358  for(uint8_t i = 0; i < len; i++)
359  buf[i] = 0;
360 }
361 
362 void HIDUniversal::SaveBuffer(uint8_t len, uint8_t *src, uint8_t *dest) {
363  for(uint8_t i = 0; i < len; i++)
364  dest[i] = src[i];
365 }
366 
368  uint8_t rcode = 0;
369 
370  if(!bPollEnable)
371  return 0;
372 
373  if((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) {
374  qNextPollTime = (uint32_t)millis() + pollInterval;
375 
376  uint8_t buf[constBuffLen];
377 
378  for(uint8_t i = 0; i < bNumIface; i++) {
379  uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex];
380  uint16_t read = (uint16_t)epInfo[index].maxPktSize;
381 
382  ZeroMemory(constBuffLen, buf);
383 
384  uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf);
385 
386  if(rcode) {
387  if(rcode != hrNAK)
388  USBTRACE3("(hiduniversal.h) Poll:", rcode, 0x81);
389  return rcode;
390  }
391 
392  if(read > constBuffLen)
393  read = constBuffLen;
394 
395  bool identical = BuffersIdentical(read, buf, prevBuf);
396 
397  SaveBuffer(read, buf, prevBuf);
398 
399  if(identical)
400  return 0;
401 #if 0
402  Notify(PSTR("\r\nBuf: "), 0x80);
403 
404  for(uint8_t i = 0; i < read; i++) {
405  D_PrintHex<uint8_t > (buf[i], 0x80);
406  Notify(PSTR(" "), 0x80);
407  }
408 
409  Notify(PSTR("\r\n"), 0x80);
410 #endif
411  ParseHIDData(this, bHasReportId, (uint8_t)read, buf);
412 
413  HIDReportParser *prs = GetReportParser(((bHasReportId) ? *buf : 0));
414 
415  if(prs)
416  prs->Parse(this, bHasReportId, (uint8_t)read, buf);
417  }
418  }
419  return rcode;
420 }
421 
422 // Send a report to interrupt out endpoint. This is NOT SetReport() request!
423 uint8_t HIDUniversal::SndRpt(uint16_t nbytes, uint8_t *dataptr) {
424  return pUsb->outTransfer(bAddress, epInfo[epInterruptOutIndex].epAddr, nbytes, dataptr);
425 }
uint16_t PID
Definition: hiduniversal.h:69
+Go to the documentation of this file.
1 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2 
3 This software may be distributed and modified under the terms of the GNU
4 General Public License version 2 (GPL2) as published by the Free Software
5 Foundation and appearing in the file GPL2.TXT included in the packaging of
6 this file. Please note that GPL2 Section 2[b] requires that all works based
7 on this software must also be made publicly available under the terms of
8 the GPL2 ("Copyleft").
9 
10 Contact information
11 -------------------
12 
13 Circuits At Home, LTD
14 Web : http://www.circuitsathome.com
15 e-mail : support@circuitsathome.com
16  */
17 
18 #include "hiduniversal.h"
19 
21 USBHID(p),
22 qNextPollTime(0),
23 pollInterval(0),
24 bPollEnable(false),
25 bHasReportId(false) {
26  Initialize();
27 
28  if(pUsb)
30 }
31 
32 uint16_t HIDUniversal::GetHidClassDescrLen(uint8_t type, uint8_t num) {
33  for(uint8_t i = 0, n = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
34  if(descrInfo[i].bDescrType == type) {
35  if(n == num)
36  return descrInfo[i].wDescriptorLength;
37  n++;
38  }
39  }
40  return 0;
41 }
42 
43 void HIDUniversal::Initialize() {
44  for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
45  rptParsers[i].rptId = 0;
46  rptParsers[i].rptParser = NULL;
47  }
48  for(uint8_t i = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
49  descrInfo[i].bDescrType = 0;
50  descrInfo[i].wDescriptorLength = 0;
51  }
52  for(uint8_t i = 0; i < maxHidInterfaces; i++) {
53  hidInterfaces[i].bmInterface = 0;
54  hidInterfaces[i].bmProtocol = 0;
55 
56  for(uint8_t j = 0; j < maxEpPerInterface; j++)
57  hidInterfaces[i].epIndex[j] = 0;
58  }
59  for(uint8_t i = 0; i < totalEndpoints; i++) {
60  epInfo[i].epAddr = 0;
61  epInfo[i].maxPktSize = (i) ? 0 : 8;
62  epInfo[i].bmSndToggle = 0;
63  epInfo[i].bmRcvToggle = 0;
65  }
66  bNumEP = 1;
67  bNumIface = 0;
68  bConfNum = 0;
69  pollInterval = 0;
70 
71  ZeroMemory(constBuffLen, prevBuf);
72 }
73 
75  for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
76  if(rptParsers[i].rptId == 0 && rptParsers[i].rptParser == NULL) {
77  rptParsers[i].rptId = id;
78  rptParsers[i].rptParser = prs;
79  return true;
80  }
81  }
82  return false;
83 }
84 
86  if(!bHasReportId)
87  return ((rptParsers[0].rptParser) ? rptParsers[0].rptParser : NULL);
88 
89  for(uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
90  if(rptParsers[i].rptId == id)
91  return rptParsers[i].rptParser;
92  }
93  return NULL;
94 }
95 
96 uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
97  const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
98 
99  uint8_t buf[constBufSize];
100  USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
101  uint8_t rcode;
102  UsbDevice *p = NULL;
103  EpInfo *oldep_ptr = NULL;
104  uint8_t len = 0;
105 
106  uint8_t num_of_conf; // number of configurations
107  //uint8_t num_of_intf; // number of interfaces
108 
109  AddressPool &addrPool = pUsb->GetAddressPool();
110 
111  USBTRACE("HU Init\r\n");
112 
113  if(bAddress)
115 
116  // Get pointer to pseudo device with address 0 assigned
117  p = addrPool.GetUsbDevicePtr(0);
118 
119  if(!p)
121 
122  if(!p->epinfo) {
123  USBTRACE("epinfo\r\n");
125  }
126 
127  // Save old pointer to EP_RECORD of address 0
128  oldep_ptr = p->epinfo;
129 
130  // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
131  p->epinfo = epInfo;
132 
133  p->lowspeed = lowspeed;
134 
135  // Get device descriptor
136  rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
137 
138  if(!rcode)
139  len = (buf[0] > constBufSize) ? constBufSize : buf[0];
140 
141  if(rcode) {
142  // Restore p->epinfo
143  p->epinfo = oldep_ptr;
144 
145  goto FailGetDevDescr;
146  }
147 
148  // Restore p->epinfo
149  p->epinfo = oldep_ptr;
150 
151  // Allocate new address according to device class
152  bAddress = addrPool.AllocAddress(parent, false, port);
153 
154  if(!bAddress)
156 
157  // Extract Max Packet Size from the device descriptor
159 
160  // Assign new address to the device
161  rcode = pUsb->setAddr(0, 0, bAddress);
162 
163  if(rcode) {
164  p->lowspeed = false;
165  addrPool.FreeAddress(bAddress);
166  bAddress = 0;
167  USBTRACE2("setAddr:", rcode);
168  return rcode;
169  }
170 
171  //delay(2); //per USB 2.0 sect.9.2.6.3
172 
173  USBTRACE2("Addr:", bAddress);
174 
175  p->lowspeed = false;
176 
177  p = addrPool.GetUsbDevicePtr(bAddress);
178 
179  if(!p)
181 
182  p->lowspeed = lowspeed;
183 
184  if(len)
185  rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
186 
187  if(rcode)
188  goto FailGetDevDescr;
189 
190  VID = udd->idVendor; // Can be used by classes that inherits this class to check the VID and PID of the connected device
191  PID = udd->idProduct;
192 
193  num_of_conf = udd->bNumConfigurations;
194 
195  // Assign epInfo to epinfo pointer
196  rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
197 
198  if(rcode)
199  goto FailSetDevTblEntry;
200 
201  USBTRACE2("NC:", num_of_conf);
202 
203  for(uint8_t i = 0; i < num_of_conf; i++) {
204  //HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
206  CP_MASK_COMPARE_CLASS> confDescrParser(this);
207 
208  //rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
209  rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
210 
211  if(rcode)
212  goto FailGetConfDescr;
213 
214  if(bNumEP > 1)
215  break;
216  } // for
217 
218  if(bNumEP < 2)
220 
221  // Assign epInfo to epinfo pointer
222  rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
223 
224  USBTRACE2("Cnf:", bConfNum);
225 
226  // Set Configuration Value
227  rcode = pUsb->setConf(bAddress, 0, bConfNum);
228 
229  if(rcode)
230  goto FailSetConfDescr;
231 
232  for(uint8_t i = 0; i < bNumIface; i++) {
233  if(hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
234  continue;
235 
236  rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);
237 
238  if(rcode && rcode != hrSTALL)
239  goto FailSetIdle;
240  }
241 
242  USBTRACE("HU configured\r\n");
243 
245 
246  bPollEnable = true;
247  return 0;
248 
249 FailGetDevDescr:
250 #ifdef DEBUG_USB_HOST
252  goto Fail;
253 #endif
254 
255 FailSetDevTblEntry:
256 #ifdef DEBUG_USB_HOST
258  goto Fail;
259 #endif
260 
261 FailGetConfDescr:
262 #ifdef DEBUG_USB_HOST
264  goto Fail;
265 #endif
266 
267 FailSetConfDescr:
268 #ifdef DEBUG_USB_HOST
270  goto Fail;
271 #endif
272 
273 
274 FailSetIdle:
275 #ifdef DEBUG_USB_HOST
276  USBTRACE("SetIdle:");
277 #endif
278 
279 #ifdef DEBUG_USB_HOST
280 Fail:
281  NotifyFail(rcode);
282 #endif
283  Release();
284  return rcode;
285 }
286 
287 HIDUniversal::HIDInterface* HIDUniversal::FindInterface(uint8_t iface, uint8_t alt, uint8_t proto) {
288  for(uint8_t i = 0; i < bNumIface && i < maxHidInterfaces; i++)
289  if(hidInterfaces[i].bmInterface == iface && hidInterfaces[i].bmAltSet == alt
290  && hidInterfaces[i].bmProtocol == proto)
291  return hidInterfaces + i;
292  return NULL;
293 }
294 
295 void HIDUniversal::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
296  // If the first configuration satisfies, the others are not concidered.
297  if(bNumEP > 1 && conf != bConfNum)
298  return;
299 
300  //ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
301  //ErrorMessage<uint8_t>(PSTR("Iface Num"), iface);
302  //ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
303 
304  bConfNum = conf;
305 
306  uint8_t index = 0;
307  HIDInterface *piface = FindInterface(iface, alt, proto);
308 
309  // Fill in interface structure in case of new interface
310  if(!piface) {
311  if(bNumIface >= maxHidInterfaces) {
312  // don't overflow hidInterfaces[]
313  Notify(PSTR("\r\n HIDUniversal::EndpointXtract(): Not adding HID interface because we already have "), 0x80);
314  Notify(bNumIface, 0x80);
315  Notify(PSTR(" interfaces and can't hold more. "), 0x80);
316  return;
317  }
318  piface = hidInterfaces + bNumIface;
319  piface->bmInterface = iface;
320  piface->bmAltSet = alt;
321  piface->bmProtocol = proto;
322  bNumIface++;
323  }
324 
326  index = (pep->bEndpointAddress & 0x80) == 0x80 ? epInterruptInIndex : epInterruptOutIndex;
327 
328  if(index) {
329  if(bNumEP >= totalEndpoints) {
330  // don't overflow epInfo[] either
331  Notify(PSTR("\r\n HIDUniversal::EndpointXtract(): Not adding endpoint info because we already have "), 0x80);
332  Notify(bNumEP, 0x80);
333  Notify(PSTR(" endpoints and can't hold more. "), 0x80);
334  return;
335  }
336  // Fill in the endpoint info structure
337  epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
338  epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
339  epInfo[bNumEP].bmSndToggle = 0;
340  epInfo[bNumEP].bmRcvToggle = 0;
341  epInfo[bNumEP].bmNakPower = USB_NAK_NOWAIT;
342 
343  // Fill in the endpoint index list
344  piface->epIndex[index] = bNumEP; //(pep->bEndpointAddress & 0x0F);
345 
346  if(pollInterval < pep->bInterval) // Set the polling interval as the largest polling interval obtained from endpoints
347  pollInterval = pep->bInterval;
348 
349  bNumEP++;
350  }
351  //PrintEndpointDescriptor(pep);
352 }
353 
356 
357  bNumEP = 1;
358  bAddress = 0;
359  qNextPollTime = 0;
360  bPollEnable = false;
361  return 0;
362 }
363 
364 bool HIDUniversal::BuffersIdentical(uint8_t len, uint8_t *buf1, uint8_t *buf2) {
365  for(uint8_t i = 0; i < len; i++)
366  if(buf1[i] != buf2[i])
367  return false;
368  return true;
369 }
370 
371 void HIDUniversal::ZeroMemory(uint8_t len, uint8_t *buf) {
372  for(uint8_t i = 0; i < len; i++)
373  buf[i] = 0;
374 }
375 
376 void HIDUniversal::SaveBuffer(uint8_t len, uint8_t *src, uint8_t *dest) {
377  for(uint8_t i = 0; i < len; i++)
378  dest[i] = src[i];
379 }
380 
382  uint8_t rcode = 0;
383 
384  if(!bPollEnable)
385  return 0;
386 
387  if((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) {
388  qNextPollTime = (uint32_t)millis() + pollInterval;
389 
390  uint8_t buf[constBuffLen];
391 
392  for(uint8_t i = 0; i < bNumIface; i++) {
393  uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex];
394  uint16_t read = (uint16_t)epInfo[index].maxPktSize;
395 
396  ZeroMemory(constBuffLen, buf);
397 
398  uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf);
399 
400  if(rcode) {
401  if(rcode != hrNAK)
402  USBTRACE3("(hiduniversal.h) Poll:", rcode, 0x81);
403  return rcode;
404  }
405 
406  if(read > constBuffLen)
407  read = constBuffLen;
408 
409  bool identical = BuffersIdentical(read, buf, prevBuf);
410 
411  SaveBuffer(read, buf, prevBuf);
412 
413  if(identical)
414  return 0;
415 #if 0
416  Notify(PSTR("\r\nBuf: "), 0x80);
417 
418  for(uint8_t i = 0; i < read; i++) {
419  D_PrintHex<uint8_t > (buf[i], 0x80);
420  Notify(PSTR(" "), 0x80);
421  }
422 
423  Notify(PSTR("\r\n"), 0x80);
424 #endif
425  ParseHIDData(this, bHasReportId, (uint8_t)read, buf);
426 
427  HIDReportParser *prs = GetReportParser(((bHasReportId) ? *buf : 0));
428 
429  if(prs)
430  prs->Parse(this, bHasReportId, (uint8_t)read, buf);
431  }
432  }
433  return rcode;
434 }
435 
436 // Send a report to interrupt out endpoint. This is NOT SetReport() request!
437 uint8_t HIDUniversal::SndRpt(uint16_t nbytes, uint8_t *dataptr) {
438  return pUsb->outTransfer(bAddress, epInfo[epInterruptOutIndex].epAddr, nbytes, dataptr);
439 }
uint16_t PID
Definition: hiduniversal.h:69
uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t *dataptr)
Definition: Usb.cpp:801
uint8_t bmRcvToggle
Definition: address.h:48
uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed)
@@ -91,13 +91,13 @@ $(function() {
#define NotifyFailGetDevDescr(...)
Definition: message.h:57
HIDInterface hidInterfaces[maxHidInterfaces]
Definition: hiduniversal.h:65
uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo *eprecord_ptr)
Definition: Usb.cpp:64
-
uint8_t Release()
+
uint8_t Release()
#define CP_MASK_COMPARE_CLASS
uint16_t VID
Definition: hiduniversal.h:69
virtual uint8_t OnInitSuccessful()
Definition: hiduniversal.h:74
#define USB_CLASS_HID
Definition: UsbCore.h:72
virtual void FreeAddress(uint8_t addr)=0
-
uint8_t Poll()
+
uint8_t Poll()
virtual UsbDevice * GetUsbDevicePtr(uint8_t addr)=0
uint8_t SetIdle(uint8_t iface, uint8_t reportID, uint8_t duration)
Definition: usbhid.cpp:62
@@ -134,7 +134,7 @@ $(function() {
#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED
Definition: UsbCore.h:90
static const uint8_t totalEndpoints
Definition: usbhid.h:154
uint16_t idProduct
Definition: usb_ch9.h:114
-
uint8_t SndRpt(uint16_t nbytes, uint8_t *dataptr)
+
uint8_t SndRpt(uint16_t nbytes, uint8_t *dataptr)
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval=0)
Definition: Usb.cpp:209
uint8_t bNumConfigurations
Definition: usb_ch9.h:119
#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL
Definition: UsbCore.h:93
diff --git a/hiduniversal_8h_source.html b/hiduniversal_8h_source.html index a577d381..40b51a45 100644 --- a/hiduniversal_8h_source.html +++ b/hiduniversal_8h_source.html @@ -74,10 +74,10 @@ $(function() {
virtual void ParseHIDData(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)
Definition: hiduniversal.h:78
HIDInterface hidInterfaces[maxHidInterfaces]
Definition: hiduniversal.h:65
-
uint8_t Release()
+
uint8_t Release()
uint16_t VID
Definition: hiduniversal.h:69
virtual uint8_t OnInitSuccessful()
Definition: hiduniversal.h:74
-
uint8_t Poll()
+
uint8_t Poll()
HIDReportParser * GetReportParser(uint8_t id)
Definition: address.h:39
void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep)
@@ -87,7 +87,7 @@ $(function() {
static const uint8_t maxHidInterfaces
Definition: usbhid.h:152
static const uint8_t totalEndpoints
Definition: usbhid.h:154
-
uint8_t SndRpt(uint16_t nbytes, uint8_t *dataptr)
+
uint8_t SndRpt(uint16_t nbytes, uint8_t *dataptr)
Definition: UsbCore.h:210
virtual uint8_t GetAddress()
Definition: hiduniversal.h:93
diff --git a/usbhid_8h_source.html b/usbhid_8h_source.html index 9b681a7d..8db0f384 100644 --- a/usbhid_8h_source.html +++ b/usbhid_8h_source.html @@ -63,7 +63,7 @@ $(function() {
usbhid.h
-Go to the documentation of this file.
1 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2 
3 This software may be distributed and modified under the terms of the GNU
4 General Public License version 2 (GPL2) as published by the Free Software
5 Foundation and appearing in the file GPL2.TXT included in the packaging of
6 this file. Please note that GPL2 Section 2[b] requires that all works based
7 on this software must also be made publicly available under the terms of
8 the GPL2 ("Copyleft").
9 
10 Contact information
11 -------------------
12 
13 Circuits At Home, LTD
14 Web : http://www.circuitsathome.com
15 e-mail : support@circuitsathome.com
16  */
17 #if !defined(__USBHID_H__)
18 #define __USBHID_H__
19 
20 #include "Usb.h"
21 #include "hidusagestr.h"
22 
23 #define MAX_REPORT_PARSERS 2
24 #define HID_MAX_HID_CLASS_DESCRIPTORS 5
25 
26 #define DATA_SIZE_MASK 0x03
27 #define TYPE_MASK 0x0C
28 #define TAG_MASK 0xF0
29 
30 #define DATA_SIZE_0 0x00
31 #define DATA_SIZE_1 0x01
32 #define DATA_SIZE_2 0x02
33 #define DATA_SIZE_4 0x03
34 
35 #define TYPE_MAIN 0x00
36 #define TYPE_GLOBAL 0x04
37 #define TYPE_LOCAL 0x08
38 
39 #define TAG_MAIN_INPUT 0x80
40 #define TAG_MAIN_OUTPUT 0x90
41 #define TAG_MAIN_COLLECTION 0xA0
42 #define TAG_MAIN_FEATURE 0xB0
43 #define TAG_MAIN_ENDCOLLECTION 0xC0
44 
45 #define TAG_GLOBAL_USAGEPAGE 0x00
46 #define TAG_GLOBAL_LOGICALMIN 0x10
47 #define TAG_GLOBAL_LOGICALMAX 0x20
48 #define TAG_GLOBAL_PHYSMIN 0x30
49 #define TAG_GLOBAL_PHYSMAX 0x40
50 #define TAG_GLOBAL_UNITEXP 0x50
51 #define TAG_GLOBAL_UNIT 0x60
52 #define TAG_GLOBAL_REPORTSIZE 0x70
53 #define TAG_GLOBAL_REPORTID 0x80
54 #define TAG_GLOBAL_REPORTCOUNT 0x90
55 #define TAG_GLOBAL_PUSH 0xA0
56 #define TAG_GLOBAL_POP 0xB0
57 
58 #define TAG_LOCAL_USAGE 0x00
59 #define TAG_LOCAL_USAGEMIN 0x10
60 #define TAG_LOCAL_USAGEMAX 0x20
61 
62 /* HID requests */
63 #define bmREQ_HID_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
64 #define bmREQ_HID_IN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
65 #define bmREQ_HID_REPORT USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_INTERFACE
66 
67 /* HID constants. Not part of chapter 9 */
68 /* Class-Specific Requests */
69 #define HID_REQUEST_GET_REPORT 0x01
70 #define HID_REQUEST_GET_IDLE 0x02
71 #define HID_REQUEST_GET_PROTOCOL 0x03
72 #define HID_REQUEST_SET_REPORT 0x09
73 #define HID_REQUEST_SET_IDLE 0x0A
74 #define HID_REQUEST_SET_PROTOCOL 0x0B
75 
76 /* Class Descriptor Types */
77 #define HID_DESCRIPTOR_HID 0x21
78 #define HID_DESCRIPTOR_REPORT 0x22
79 #define HID_DESRIPTOR_PHY 0x23
80 
81 /* Protocol Selection */
82 #define USB_HID_BOOT_PROTOCOL 0x00
83 #define HID_RPT_PROTOCOL 0x01
84 
85 /* HID Interface Class Code */
86 #define HID_INTF 0x03
87 
88 /* HID Interface Class SubClass Codes */
89 #define HID_BOOT_INTF_SUBCLASS 0x01
90 
91 /* HID Interface Class Protocol Codes */
92 #define USB_HID_PROTOCOL_NONE 0x00
93 #define USB_HID_PROTOCOL_KEYBOARD 0x01
94 #define USB_HID_PROTOCOL_MOUSE 0x02
95 
96 #define HID_ITEM_TYPE_MAIN 0
97 #define HID_ITEM_TYPE_GLOBAL 1
98 #define HID_ITEM_TYPE_LOCAL 2
99 #define HID_ITEM_TYPE_RESERVED 3
100 
101 #define HID_LONG_ITEM_PREFIX 0xfe // Long item prefix value
102 
103 #define bmHID_MAIN_ITEM_TAG 0xfc // Main item tag mask
104 
105 #define bmHID_MAIN_ITEM_INPUT 0x80 // Main item Input tag value
106 #define bmHID_MAIN_ITEM_OUTPUT 0x90 // Main item Output tag value
107 #define bmHID_MAIN_ITEM_FEATURE 0xb0 // Main item Feature tag value
108 #define bmHID_MAIN_ITEM_COLLECTION 0xa0 // Main item Collection tag value
109 #define bmHID_MAIN_ITEM_END_COLLECTION 0xce // Main item End Collection tag value
110 
111 #define HID_MAIN_ITEM_COLLECTION_PHYSICAL 0
112 #define HID_MAIN_ITEM_COLLECTION_APPLICATION 1
113 #define HID_MAIN_ITEM_COLLECTION_LOGICAL 2
114 #define HID_MAIN_ITEM_COLLECTION_REPORT 3
115 #define HID_MAIN_ITEM_COLLECTION_NAMED_ARRAY 4
116 #define HID_MAIN_ITEM_COLLECTION_USAGE_SWITCH 5
117 #define HID_MAIN_ITEM_COLLECTION_USAGE_MODIFIER 6
118 
120  uint8_t bSize : 2;
121  uint8_t bType : 2;
122  uint8_t bTag : 4;
123 };
124 
126  uint8_t bmIsConstantOrData : 1;
127  uint8_t bmIsArrayOrVariable : 1;
129  uint8_t bmIsWrapOrNoWrap : 1;
132  uint8_t bmIsNullOrNoNull : 1;
134 };
135 
136 class USBHID;
137 
139 public:
140  virtual void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) = 0;
141 };
142 
143 class USBHID : public USBDeviceConfig, public UsbConfigXtracter {
144 protected:
145  USB *pUsb; // USB class instance pointer
146  uint8_t bAddress; // address
147 
148 protected:
149  static const uint8_t epInterruptInIndex = 1; // InterruptIN endpoint index
150  static const uint8_t epInterruptOutIndex = 2; // InterruptOUT endpoint index
151 
152  static const uint8_t maxHidInterfaces = 3;
153  static const uint8_t maxEpPerInterface = 2;
154  static const uint8_t totalEndpoints = (maxHidInterfaces * maxEpPerInterface + 1); // We need to make room for the control endpoint
155 
156  void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
157  void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
158 
159  virtual HIDReportParser* GetReportParser(uint8_t id __attribute__((unused))) {
160  return NULL;
161  };
162 
163 public:
164 
165  USBHID(USB *pusb) : pUsb(pusb) {
166  };
167 
168  const USB* GetUsb() {
169  return pUsb;
170  };
171 
172  virtual bool SetReportParser(uint8_t id __attribute__((unused)), HIDReportParser *prs __attribute__((unused))) {
173  return false;
174  };
175 
176  uint8_t SetProtocol(uint8_t iface, uint8_t protocol);
177  uint8_t GetProtocol(uint8_t iface, uint8_t* dataptr);
178  uint8_t GetIdle(uint8_t iface, uint8_t reportID, uint8_t* dataptr);
179  uint8_t SetIdle(uint8_t iface, uint8_t reportID, uint8_t duration);
180 
181  uint8_t GetReportDescr(uint16_t wIndex, USBReadParser *parser = NULL);
182 
183  uint8_t GetHidDescr(uint8_t ep, uint16_t nbytes, uint8_t* dataptr);
184  uint8_t GetReport(uint8_t ep, uint8_t iface, uint8_t report_type, uint8_t report_id, uint16_t nbytes, uint8_t* dataptr);
185  uint8_t SetReport(uint8_t ep, uint8_t iface, uint8_t report_type, uint8_t report_id, uint16_t nbytes, uint8_t* dataptr);
186 };
187 
188 #endif // __USBHID_H__
Definition: usbhid.h:143
+Go to the documentation of this file.
1 /* Copyright (C) 2011 Circuits At Home, LTD. All rights reserved.
2 
3 This software may be distributed and modified under the terms of the GNU
4 General Public License version 2 (GPL2) as published by the Free Software
5 Foundation and appearing in the file GPL2.TXT included in the packaging of
6 this file. Please note that GPL2 Section 2[b] requires that all works based
7 on this software must also be made publicly available under the terms of
8 the GPL2 ("Copyleft").
9 
10 Contact information
11 -------------------
12 
13 Circuits At Home, LTD
14 Web : http://www.circuitsathome.com
15 e-mail : support@circuitsathome.com
16  */
17 #if !defined(__USBHID_H__)
18 #define __USBHID_H__
19 
20 #include "Usb.h"
21 #include "hidusagestr.h"
22 
23 #define MAX_REPORT_PARSERS 2
24 #define HID_MAX_HID_CLASS_DESCRIPTORS 5
25 
26 #define DATA_SIZE_MASK 0x03
27 #define TYPE_MASK 0x0C
28 #define TAG_MASK 0xF0
29 
30 #define DATA_SIZE_0 0x00
31 #define DATA_SIZE_1 0x01
32 #define DATA_SIZE_2 0x02
33 #define DATA_SIZE_4 0x03
34 
35 #define TYPE_MAIN 0x00
36 #define TYPE_GLOBAL 0x04
37 #define TYPE_LOCAL 0x08
38 
39 #define TAG_MAIN_INPUT 0x80
40 #define TAG_MAIN_OUTPUT 0x90
41 #define TAG_MAIN_COLLECTION 0xA0
42 #define TAG_MAIN_FEATURE 0xB0
43 #define TAG_MAIN_ENDCOLLECTION 0xC0
44 
45 #define TAG_GLOBAL_USAGEPAGE 0x00
46 #define TAG_GLOBAL_LOGICALMIN 0x10
47 #define TAG_GLOBAL_LOGICALMAX 0x20
48 #define TAG_GLOBAL_PHYSMIN 0x30
49 #define TAG_GLOBAL_PHYSMAX 0x40
50 #define TAG_GLOBAL_UNITEXP 0x50
51 #define TAG_GLOBAL_UNIT 0x60
52 #define TAG_GLOBAL_REPORTSIZE 0x70
53 #define TAG_GLOBAL_REPORTID 0x80
54 #define TAG_GLOBAL_REPORTCOUNT 0x90
55 #define TAG_GLOBAL_PUSH 0xA0
56 #define TAG_GLOBAL_POP 0xB0
57 
58 #define TAG_LOCAL_USAGE 0x00
59 #define TAG_LOCAL_USAGEMIN 0x10
60 #define TAG_LOCAL_USAGEMAX 0x20
61 
62 /* HID requests */
63 #define bmREQ_HID_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
64 #define bmREQ_HID_IN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
65 #define bmREQ_HID_REPORT USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_INTERFACE
66 
67 /* HID constants. Not part of chapter 9 */
68 /* Class-Specific Requests */
69 #define HID_REQUEST_GET_REPORT 0x01
70 #define HID_REQUEST_GET_IDLE 0x02
71 #define HID_REQUEST_GET_PROTOCOL 0x03
72 #define HID_REQUEST_SET_REPORT 0x09
73 #define HID_REQUEST_SET_IDLE 0x0A
74 #define HID_REQUEST_SET_PROTOCOL 0x0B
75 
76 /* Class Descriptor Types */
77 #define HID_DESCRIPTOR_HID 0x21
78 #define HID_DESCRIPTOR_REPORT 0x22
79 #define HID_DESRIPTOR_PHY 0x23
80 
81 /* Protocol Selection */
82 #define USB_HID_BOOT_PROTOCOL 0x00
83 #define HID_RPT_PROTOCOL 0x01
84 
85 /* HID Interface Class Code */
86 #define HID_INTF 0x03
87 
88 /* HID Interface Class SubClass Codes */
89 #define HID_BOOT_INTF_SUBCLASS 0x01
90 
91 /* HID Interface Class Protocol Codes */
92 #define USB_HID_PROTOCOL_NONE 0x00
93 #define USB_HID_PROTOCOL_KEYBOARD 0x01
94 #define USB_HID_PROTOCOL_MOUSE 0x02
95 
96 #define HID_ITEM_TYPE_MAIN 0
97 #define HID_ITEM_TYPE_GLOBAL 1
98 #define HID_ITEM_TYPE_LOCAL 2
99 #define HID_ITEM_TYPE_RESERVED 3
100 
101 #define HID_LONG_ITEM_PREFIX 0xfe // Long item prefix value
102 
103 #define bmHID_MAIN_ITEM_TAG 0xfc // Main item tag mask
104 
105 #define bmHID_MAIN_ITEM_INPUT 0x80 // Main item Input tag value
106 #define bmHID_MAIN_ITEM_OUTPUT 0x90 // Main item Output tag value
107 #define bmHID_MAIN_ITEM_FEATURE 0xb0 // Main item Feature tag value
108 #define bmHID_MAIN_ITEM_COLLECTION 0xa0 // Main item Collection tag value
109 #define bmHID_MAIN_ITEM_END_COLLECTION 0xce // Main item End Collection tag value
110 
111 #define HID_MAIN_ITEM_COLLECTION_PHYSICAL 0
112 #define HID_MAIN_ITEM_COLLECTION_APPLICATION 1
113 #define HID_MAIN_ITEM_COLLECTION_LOGICAL 2
114 #define HID_MAIN_ITEM_COLLECTION_REPORT 3
115 #define HID_MAIN_ITEM_COLLECTION_NAMED_ARRAY 4
116 #define HID_MAIN_ITEM_COLLECTION_USAGE_SWITCH 5
117 #define HID_MAIN_ITEM_COLLECTION_USAGE_MODIFIER 6
118 
120  uint8_t bSize : 2;
121  uint8_t bType : 2;
122  uint8_t bTag : 4;
123 };
124 
126  uint8_t bmIsConstantOrData : 1;
127  uint8_t bmIsArrayOrVariable : 1;
129  uint8_t bmIsWrapOrNoWrap : 1;
132  uint8_t bmIsNullOrNoNull : 1;
134 };
135 
136 class USBHID;
137 
139 public:
140  virtual void Parse(USBHID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) = 0;
141 };
142 
143 class USBHID : public USBDeviceConfig, public UsbConfigXtracter {
144 protected:
145  USB *pUsb; // USB class instance pointer
146  uint8_t bAddress; // address
147 
148 protected:
149  static const uint8_t epInterruptInIndex = 1; // InterruptIN endpoint index
150  static const uint8_t epInterruptOutIndex = 2; // InterruptOUT endpoint index
151 
152  static const uint8_t maxHidInterfaces = 5;
153  static const uint8_t maxEpPerInterface = 2;
154  static const uint8_t totalEndpoints = (maxHidInterfaces * maxEpPerInterface + 1); // We need to make room for the control endpoint
155 
156  void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
157  void PrintHidDescriptor(const USB_HID_DESCRIPTOR *pDesc);
158 
159  virtual HIDReportParser* GetReportParser(uint8_t id __attribute__((unused))) {
160  return NULL;
161  };
162 
163 public:
164 
165  USBHID(USB *pusb) : pUsb(pusb) {
166  };
167 
168  const USB* GetUsb() {
169  return pUsb;
170  };
171 
172  virtual bool SetReportParser(uint8_t id __attribute__((unused)), HIDReportParser *prs __attribute__((unused))) {
173  return false;
174  };
175 
176  uint8_t SetProtocol(uint8_t iface, uint8_t protocol);
177  uint8_t GetProtocol(uint8_t iface, uint8_t* dataptr);
178  uint8_t GetIdle(uint8_t iface, uint8_t reportID, uint8_t* dataptr);
179  uint8_t SetIdle(uint8_t iface, uint8_t reportID, uint8_t duration);
180 
181  uint8_t GetReportDescr(uint16_t wIndex, USBReadParser *parser = NULL);
182 
183  uint8_t GetHidDescr(uint8_t ep, uint16_t nbytes, uint8_t* dataptr);
184  uint8_t GetReport(uint8_t ep, uint8_t iface, uint8_t report_type, uint8_t report_id, uint16_t nbytes, uint8_t* dataptr);
185  uint8_t SetReport(uint8_t ep, uint8_t iface, uint8_t report_type, uint8_t report_id, uint16_t nbytes, uint8_t* dataptr);
186 };
187 
188 #endif // __USBHID_H__
Definition: usbhid.h:143
USB * pUsb
Definition: usbhid.h:145
uint8_t bmIsConstantOrData
Definition: usbhid.h:126