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  Initialize();
9 
10  if (pUsb)
12 }
13 
14 uint16_t HIDUniversal::GetHidClassDescrLen(uint8_t type, uint8_t num) {
15  for (uint8_t i = 0, n = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
16  if (descrInfo[i].bDescrType == type) {
17  if (n == num)
18  return descrInfo[i].wDescriptorLength;
19  n++;
20  }
21  }
22  return 0;
23 }
24 
25 void HIDUniversal::Initialize() {
26  for (uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
27  rptParsers[i].rptId = 0;
28  rptParsers[i].rptParser = NULL;
29  }
30  for (uint8_t i = 0; i < HID_MAX_HID_CLASS_DESCRIPTORS; i++) {
31  descrInfo[i].bDescrType = 0;
32  descrInfo[i].wDescriptorLength = 0;
33  }
34  for (uint8_t i = 0; i < maxHidInterfaces; i++) {
35  hidInterfaces[i].bmInterface = 0;
36  hidInterfaces[i].bmProtocol = 0;
37 
38  for (uint8_t j = 0; j < maxEpPerInterface; j++)
39  hidInterfaces[i].epIndex[j] = 0;
40  }
41  for (uint8_t i = 0; i < totalEndpoints; i++) {
42  epInfo[i].epAddr = 0;
43  epInfo[i].maxPktSize = (i) ? 0 : 8;
44  epInfo[i].epAttribs = 0;
45  epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
46  }
47  bNumEP = 1;
48  bNumIface = 0;
49  bConfNum = 0;
50 
51  ZeroMemory(constBuffLen, prevBuf);
52 }
53 
55  for (uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
56  if (rptParsers[i].rptId == 0 && rptParsers[i].rptParser == NULL) {
57  rptParsers[i].rptId = id;
58  rptParsers[i].rptParser = prs;
59  return true;
60  }
61  }
62  return false;
63 }
64 
66  if (!bHasReportId)
67  return ((rptParsers[0].rptParser) ? rptParsers[0].rptParser : NULL);
68 
69  for (uint8_t i = 0; i < MAX_REPORT_PARSERS; i++) {
70  if (rptParsers[i].rptId == id)
71  return rptParsers[i].rptParser;
72  }
73  return NULL;
74 }
75 
76 uint8_t HIDUniversal::Init(uint8_t parent, uint8_t port, bool lowspeed) {
77  const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
78 
79  uint8_t buf[constBufSize];
80  uint8_t rcode;
81  UsbDevice *p = NULL;
82  EpInfo *oldep_ptr = NULL;
83  uint8_t len = 0;
84 
85  uint8_t num_of_conf; // number of configurations
86  //uint8_t num_of_intf; // number of interfaces
87 
88  AddressPool &addrPool = pUsb->GetAddressPool();
89 
90  USBTRACE("HU Init\r\n");
91 
92  if (bAddress)
94 
95  // Get pointer to pseudo device with address 0 assigned
96  p = addrPool.GetUsbDevicePtr(0);
97 
98  if (!p)
100 
101  if (!p->epinfo) {
102  USBTRACE("epinfo\r\n");
104  }
105 
106  // Save old pointer to EP_RECORD of address 0
107  oldep_ptr = p->epinfo;
108 
109  // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
110  p->epinfo = epInfo;
111 
112  p->lowspeed = lowspeed;
113 
114  // Get device descriptor
115  rcode = pUsb->getDevDescr(0, 0, 8, (uint8_t*)buf);
116 
117  if (!rcode)
118  len = (buf[0] > constBufSize) ? constBufSize : buf[0];
119 
120  if (rcode) {
121  // Restore p->epinfo
122  p->epinfo = oldep_ptr;
123 
124  goto FailGetDevDescr;
125  }
126 
127  // Restore p->epinfo
128  p->epinfo = oldep_ptr;
129 
130  // Allocate new address according to device class
131  bAddress = addrPool.AllocAddress(parent, false, port);
132 
133  if (!bAddress)
135 
136  // Extract Max Packet Size from the device descriptor
137  epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
138 
139  // Assign new address to the device
140  rcode = pUsb->setAddr(0, 0, bAddress);
141 
142  if (rcode) {
143  p->lowspeed = false;
144  addrPool.FreeAddress(bAddress);
145  bAddress = 0;
146  USBTRACE2("setAddr:", rcode);
147  return rcode;
148  }
149 
150  USBTRACE2("Addr:", bAddress);
151 
152  p->lowspeed = false;
153 
154  p = addrPool.GetUsbDevicePtr(bAddress);
155 
156  if (!p)
158 
159  p->lowspeed = lowspeed;
160 
161  if (len)
162  rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
163 
164  if (rcode)
165  goto FailGetDevDescr;
166 
167  num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
168 
169  // Assign epInfo to epinfo pointer
170  rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
171 
172  if (rcode)
173  goto FailSetDevTblEntry;
174 
175  USBTRACE2("NC:", num_of_conf);
176 
177  for (uint8_t i = 0; i < num_of_conf; i++) {
178  //HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
180  CP_MASK_COMPARE_CLASS> confDescrParser(this);
181 
182  //rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
183  rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
184 
185  if (rcode)
186  goto FailGetConfDescr;
187 
188  if (bNumEP > 1)
189  break;
190  } // for
191 
192  if (bNumEP < 2)
194 
195  // Assign epInfo to epinfo pointer
196  rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
197 
198  USBTRACE2("\r\nCnf:", bConfNum);
199 
200  // Set Configuration Value
201  rcode = pUsb->setConf(bAddress, 0, bConfNum);
202 
203  if (rcode)
204  goto FailSetConfDescr;
205 
206  for (uint8_t i = 0; i < bNumIface; i++) {
207  if (hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
208  continue;
209 
210  rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);
211 
212  if (rcode && rcode != hrSTALL)
213  goto FailSetIdle;
214  }
215 
216  USBTRACE("HU configured\r\n");
217 
219 
220  bPollEnable = true;
221  return 0;
222 
223 FailGetDevDescr:
225  goto Fail;
226 
227 FailSetDevTblEntry:
229  goto Fail;
230 
231 FailGetConfDescr:
233  goto Fail;
234 
235 FailSetConfDescr:
237  goto Fail;
238 
239 
240 FailSetIdle:
241  USBTRACE("SetIdle:");
242 
243 Fail:
244  NotifyFail(rcode);
245  Release();
246  return rcode;
247 }
248 
249 HIDUniversal::HIDInterface* HIDUniversal::FindInterface(uint8_t iface, uint8_t alt, uint8_t proto) {
250  for (uint8_t i = 0; i < bNumIface && i < maxHidInterfaces; i++)
251  if (hidInterfaces[i].bmInterface == iface && hidInterfaces[i].bmAltSet == alt
252  && hidInterfaces[i].bmProtocol == proto)
253  return hidInterfaces + i;
254  return NULL;
255 }
256 
257 void HIDUniversal::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
258  // If the first configuration satisfies, the others are not concidered.
259  if (bNumEP > 1 && conf != bConfNum)
260  return;
261 
262  //ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
263  //ErrorMessage<uint8_t>(PSTR("Iface Num"), iface);
264  //ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
265 
266  bConfNum = conf;
267 
268  uint8_t index = 0;
269  HIDInterface *piface = FindInterface(iface, alt, proto);
270 
271  // Fill in interface structure in case of new interface
272  if (!piface) {
273  piface = hidInterfaces + bNumIface;
274  piface->bmInterface = iface;
275  piface->bmAltSet = alt;
276  piface->bmProtocol = proto;
277  bNumIface++;
278  }
279 
280  if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
281  index = epInterruptInIndex;
282  else
283  index = epInterruptOutIndex;
284 
285  if (index) {
286  // Fill in the endpoint info structure
287  epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
288  epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
289  epInfo[bNumEP].epAttribs = 0;
290  epInfo[bNumEP].bmNakPower = USB_NAK_NOWAIT;
291 
292  // Fill in the endpoint index list
293  piface->epIndex[index] = bNumEP; //(pep->bEndpointAddress & 0x0F);
294 
295  bNumEP++;
296  }
297  //PrintEndpointDescriptor(pep);
298 }
299 
302 
303  bNumEP = 1;
304  bAddress = 0;
305  qNextPollTime = 0;
306  bPollEnable = false;
307  return 0;
308 }
309 
310 bool HIDUniversal::BuffersIdentical(uint8_t len, uint8_t *buf1, uint8_t *buf2) {
311  for (uint8_t i = 0; i < len; i++)
312  if (buf1[i] != buf2[i])
313  return false;
314  return true;
315 }
316 
317 void HIDUniversal::ZeroMemory(uint8_t len, uint8_t *buf) {
318  for (uint8_t i = 0; i < len; i++)
319  buf[i] = 0;
320 }
321 
322 void HIDUniversal::SaveBuffer(uint8_t len, uint8_t *src, uint8_t *dest) {
323  for (uint8_t i = 0; i < len; i++)
324  dest[i] = src[i];
325 }
326 
328  uint8_t rcode = 0;
329 
330  if (!bPollEnable)
331  return 0;
332 
333  if (qNextPollTime <= millis()) {
334  qNextPollTime = millis() + 50;
335 
336  uint8_t buf[constBuffLen];
337 
338  for (uint8_t i = 0; i < bNumIface; i++) {
339  uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex];
340  uint16_t read = (uint16_t)epInfo[index].maxPktSize;
341 
342  ZeroMemory(constBuffLen, buf);
343 
344  uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf);
345 
346  if (rcode) {
347  if (rcode != hrNAK)
348  USBTRACE2("Poll:", rcode);
349  return rcode;
350  }
351 
352  if (read > constBuffLen)
353  read = constBuffLen;
354 
355  bool identical = BuffersIdentical(read, buf, prevBuf);
356 
357  SaveBuffer(read, buf, prevBuf);
358 
359  if (identical)
360  return 0;
361 
362  Notify(PSTR("\r\nBuf: "), 0x80);
363 
364  for (uint8_t i = 0; i < read; i++)
365  PrintHex<uint8_t > (buf[i], 0x80);
366 
367  Notify(PSTR("\r\n"), 0x80);
368 
369  HIDReportParser *prs = GetReportParser(((bHasReportId) ? *buf : 0));
370 
371  if (prs)
372  prs->Parse(this, bHasReportId, (uint8_t)read, buf);
373  }
374  }
375  return rcode;
376 }