USB Host Shield 2.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
hiduniversal.cpp
Go to the documentation of this file.
1 #include "hiduniversal.h"
2 
4  HID(p),
5  qNextPollTime(0),
6  bPollEnable(false),
7  bHasReportId(false)
8 {
9  Initialize();
10 
11  if (pUsb)
13 }
14 
15 uint16_t HIDUniversal::GetHidClassDescrLen(uint8_t type, uint8_t num)
16 {
17  for (uint8_t i=0, n=0; i<HID_MAX_HID_CLASS_DESCRIPTORS; i++)
18  {
19  if (descrInfo[i].bDescrType == type)
20  {
21  if (n == num)
22  return descrInfo[i].wDescriptorLength;
23  n ++;
24  }
25  }
26  return 0;
27 }
28 
29 void HIDUniversal::Initialize()
30 {
31  for (uint8_t i=0; i<MAX_REPORT_PARSERS; i++)
32  {
33  rptParsers[i].rptId = 0;
34  rptParsers[i].rptParser = NULL;
35  }
36  for (uint8_t i=0; i<HID_MAX_HID_CLASS_DESCRIPTORS; i++)
37  {
38  descrInfo[i].bDescrType = 0;
39  descrInfo[i].wDescriptorLength = 0;
40  }
41  for (uint8_t i=0; i<maxHidInterfaces; i++)
42  {
43  hidInterfaces[i].bmInterface = 0;
44  hidInterfaces[i].bmProtocol = 0;
45 
46  for (uint8_t j=0; j<maxEpPerInterface; j++)
47  hidInterfaces[i].epIndex[j] = 0;
48  }
49  for(uint8_t i=0; i<totalEndpoints; i++)
50  {
51  epInfo[i].epAddr = 0;
52  epInfo[i].maxPktSize = (i) ? 0 : 8;
53  epInfo[i].epAttribs = 0;
54  epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
55  }
56  bNumEP = 1;
57  bNumIface = 0;
58  bConfNum = 0;
59 
60  ZeroMemory(constBuffLen, prevBuf);
61 }
62 
64 {
65  for (uint8_t i=0; i<MAX_REPORT_PARSERS; i++)
66  {
67  if (rptParsers[i].rptId == 0 && rptParsers[i].rptParser == NULL)
68  {
69  rptParsers[i].rptId = id;
70  rptParsers[i].rptParser = prs;
71  return true;
72  }
73  }
74  return false;
75 }
76 
78 {
79  if (!bHasReportId)
80  return ((rptParsers[0].rptParser) ? rptParsers[0].rptParser : NULL);
81 
82  for (uint8_t i=0; i<MAX_REPORT_PARSERS; i++)
83  {
84  if (rptParsers[i].rptId == id)
85  return rptParsers[i].rptParser;
86  }
87  return NULL;
88 }
89 
90 uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed)
91 {
92  const uint8_t constBufSize = sizeof(USB_DEVICE_DESCRIPTOR);
93 
94  uint8_t buf[constBufSize];
95  uint8_t rcode;
96  UsbDevice *p = NULL;
97  EpInfo *oldep_ptr = NULL;
98  uint8_t len = 0;
99 
100  uint8_t num_of_conf; // number of configurations
101  uint8_t num_of_intf; // number of interfaces
102 
103  AddressPool &addrPool = pUsb->GetAddressPool();
104 
105  USBTRACE("HU Init\r\n");
106 
107  if (bAddress)
109 
110  // Get pointer to pseudo device with address 0 assigned
111  p = addrPool.GetUsbDevicePtr(0);
112 
113  if (!p)
115 
116  if (!p->epinfo)
117  {
118  USBTRACE("epinfo\r\n");
120  }
121 
122  // Save old pointer to EP_RECORD of address 0
123  oldep_ptr = p->epinfo;
124 
125  // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
126  p->epinfo = epInfo;
127 
128  p->lowspeed = lowspeed;
129 
130  //delay(200);
131 
132  // Get device descriptor
133  rcode = pUsb->getDevDescr( 0, 0, 8, (uint8_t*)buf );
134 
135  if (!rcode)
136  len = (buf[0] > constBufSize) ? constBufSize : buf[0];
137 
138  if( rcode )
139  {
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
156  epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
157 
158  // Assign new address to the device
159  rcode = pUsb->setAddr( 0, 0, bAddress );
160 
161  if (rcode)
162  {
163  p->lowspeed = false;
164  addrPool.FreeAddress(bAddress);
165  bAddress = 0;
166  USBTRACE2("setAddr:",rcode);
167  return rcode;
168  }
169 
170  USBTRACE2("Addr:", bAddress);
171 
172  p->lowspeed = false;
173 
174  p = addrPool.GetUsbDevicePtr(bAddress);
175 
176  if (!p)
178 
179  p->lowspeed = lowspeed;
180 
181  delay(500);
182 
183  if (len)
184  rcode = pUsb->getDevDescr( bAddress, 0, len, (uint8_t*)buf );
185 
186  if(rcode)
187  goto FailGetDevDescr;
188 
189  num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
190 
191  // Assign epInfo to epinfo pointer
192  rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
193 
194  if (rcode)
195  goto FailSetDevTblEntry;
196 
197  USBTRACE2("NC:", num_of_conf);
198 
199  for (uint8_t i=0; i<num_of_conf; i++)
200  {
201  //delay(1000);
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 (bNumEP > 1)
210  break;
211  } // for
212 
213  if (bNumEP < 2)
215 
216  // Assign epInfo to epinfo pointer
217  rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
218 
219  USBTRACE2("\r\nCnf:", bConfNum);
220 
221  // Set Configuration Value
222  rcode = pUsb->setConf(bAddress, 0, bConfNum);
223 
224  if (rcode)
225  goto FailSetConfDescr;
226 
227  for (uint8_t i=0; i<bNumIface; i++)
228  {
229  if (hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
230  continue;
231 
232  rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);
233 
234  if (rcode && rcode != hrSTALL)
235  goto FailSetIdle;
236  }
237 
238  USBTRACE("HU configured\r\n");
239 
241 
242  bPollEnable = true;
243  return 0;
244 
245 FailGetDevDescr:
246  USBTRACE("getDevDescr:");
247  goto Fail;
248 
249 FailSetDevTblEntry:
250  USBTRACE("setDevTblEn:");
251  goto Fail;
252 
253 FailGetConfDescr:
254  USBTRACE("getConf:");
255  goto Fail;
256 
257 FailSetConfDescr:
258  USBTRACE("setConf:");
259  goto Fail;
260 
261 FailSetProtocol:
262  USBTRACE("SetProto:");
263  goto Fail;
264 
265 FailSetIdle:
266  USBTRACE("SetIdle:");
267  goto Fail;
268 
269 FailGetReportDescr:
270  USBTRACE("GetReportDescr:");
271  goto Fail;
272 
273 Fail:
274  Serial.println(rcode, HEX);
275  Release();
276  return rcode;
277 }
278 
279 HIDUniversal::HIDInterface* HIDUniversal::FindInterface(uint8_t iface, uint8_t alt, uint8_t proto)
280 {
281  for (uint8_t i=0; i<bNumIface && i<maxHidInterfaces; i++)
282  if (hidInterfaces[i].bmInterface == iface && hidInterfaces[i].bmAltSet == alt
283  && hidInterfaces[i].bmProtocol == proto)
284  return hidInterfaces + i;
285  return NULL;
286 }
287 
288 void HIDUniversal::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep)
289 {
290  // If the first configuration satisfies, the others are not concidered.
291  if (bNumEP > 1 && conf != bConfNum)
292  return;
293 
294  //ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
295  //ErrorMessage<uint8_t>(PSTR("Iface Num"), iface);
296  //ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
297 
298  bConfNum = conf;
299 
300  uint8_t index = 0;
301  HIDInterface *piface = FindInterface(iface, alt, proto);
302 
303  // Fill in interface structure in case of new interface
304  if (!piface)
305  {
306  piface = hidInterfaces + bNumIface;
307  piface->bmInterface = iface;
308  piface->bmAltSet = alt;
309  piface->bmProtocol = proto;
310  bNumIface ++;
311  }
312 
313  if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
314  index = epInterruptInIndex;
315  else
316  index = epInterruptOutIndex;
317 
318  if (index)
319  {
320  // Fill in the endpoint info structure
321  epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
322  epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
323  epInfo[bNumEP].epAttribs = 0;
324  epInfo[bNumEP].bmNakPower = USB_NAK_NOWAIT;
325 
326  // Fill in the endpoint index list
327  piface->epIndex[index] = bNumEP; //(pep->bEndpointAddress & 0x0F);
328 
329  bNumEP ++;
330  }
331  //PrintEndpointDescriptor(pep);
332 }
333 
334 
336 {
338 
339  bNumEP = 1;
340  bAddress = 0;
341  qNextPollTime = 0;
342  bPollEnable = false;
343  return 0;
344 }
345 
346 bool HIDUniversal::BuffersIdentical(uint8_t len, uint8_t *buf1, uint8_t *buf2)
347 {
348  for (uint8_t i=0; i<len; i++)
349  if (buf1[i] != buf2[i])
350  return false;
351  return true;
352 }
353 
354 void HIDUniversal::ZeroMemory(uint8_t len, uint8_t *buf)
355 {
356  for (uint8_t i=0; i<len; i++)
357  buf[i] = 0;
358 }
359 void HIDUniversal::SaveBuffer(uint8_t len, uint8_t *src, uint8_t *dest)
360 {
361  for (uint8_t i=0; i<len; i++)
362  dest[i] = src[i];
363 }
364 
366 {
367  uint8_t rcode = 0;
368 
369  if (!bPollEnable)
370  return 0;
371 
372  if (qNextPollTime <= millis())
373  {
374  qNextPollTime = millis() + 50;
375 
376  uint8_t buf[constBuffLen];
377 
378  for (uint8_t i=0; i<bNumIface; i++)
379  {
380  uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex];
381  uint16_t read = (uint16_t)epInfo[index].maxPktSize;
382 
383  ZeroMemory(constBuffLen, buf);
384 
385  uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf);
386 
387  if (rcode)
388  {
389  if (rcode != hrNAK)
390  USBTRACE2("Poll:", rcode);
391  return rcode;
392  }
393 
394  if (read > constBuffLen)
395  read = constBuffLen;
396 
397  bool identical = BuffersIdentical(read, buf, prevBuf);
398 
399  SaveBuffer(read, buf, prevBuf);
400 
401  if (identical)
402  return 0;
403 
404  Serial.print("\r\nBuf: ");
405 
406  for (uint8_t i=0; i<read; i++)
407  PrintHex<uint8_t>(buf[i]);
408 
409  Serial.println("");
410 
411  HIDReportParser *prs = GetReportParser( ((bHasReportId) ? *buf : 0) );
412 
413  if (prs)
414  prs->Parse(this, bHasReportId, (uint8_t)read, buf);
415  }
416  }
417  return rcode;
418 }