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  delay( 2 ); //per USB 2.0 sect.9.2.6.3
151 
152  USBTRACE2("Addr:", bAddress);
153 
154  p->lowspeed = false;
155 
156  p = addrPool.GetUsbDevicePtr(bAddress);
157 
158  if (!p)
160 
161  p->lowspeed = lowspeed;
162 
163  if (len)
164  rcode = pUsb->getDevDescr(bAddress, 0, len, (uint8_t*)buf);
165 
166  if (rcode)
167  goto FailGetDevDescr;
168 
169  num_of_conf = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations;
170 
171  // Assign epInfo to epinfo pointer
172  rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
173 
174  if (rcode)
175  goto FailSetDevTblEntry;
176 
177  USBTRACE2("NC:", num_of_conf);
178 
179  for (uint8_t i = 0; i < num_of_conf; i++) {
180  //HexDumper<USBReadParser, uint16_t, uint16_t> HexDump;
182  CP_MASK_COMPARE_CLASS> confDescrParser(this);
183 
184  //rcode = pUsb->getConfDescr(bAddress, 0, i, &HexDump);
185  rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
186 
187  if (rcode)
188  goto FailGetConfDescr;
189 
190  if (bNumEP > 1)
191  break;
192  } // for
193 
194  if (bNumEP < 2)
196 
197  // Assign epInfo to epinfo pointer
198  rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
199 
200  USBTRACE2("\r\nCnf:", bConfNum);
201 
202  // Set Configuration Value
203  rcode = pUsb->setConf(bAddress, 0, bConfNum);
204 
205  if (rcode)
206  goto FailSetConfDescr;
207 
208  for (uint8_t i = 0; i < bNumIface; i++) {
209  if (hidInterfaces[i].epIndex[epInterruptInIndex] == 0)
210  continue;
211 
212  rcode = SetIdle(hidInterfaces[i].bmInterface, 0, 0);
213 
214  if (rcode && rcode != hrSTALL)
215  goto FailSetIdle;
216  }
217 
218  USBTRACE("HU configured\r\n");
219 
221 
222  bPollEnable = true;
223  return 0;
224 
225 FailGetDevDescr:
226 #ifdef DEBUG_USB_HOST
228  goto Fail;
229 #endif
230 
231 FailSetDevTblEntry:
232 #ifdef DEBUG_USB_HOST
234  goto Fail;
235 #endif
236 
237 FailGetConfDescr:
238 #ifdef DEBUG_USB_HOST
240  goto Fail;
241 #endif
242 
243 FailSetConfDescr:
244 #ifdef DEBUG_USB_HOST
246  goto Fail;
247 #endif
248 
249 
250 FailSetIdle:
251 #ifdef DEBUG_USB_HOST
252  USBTRACE("SetIdle:");
253 #endif
254 
255 Fail:
256 #ifdef DEBUG_USB_HOST
257  NotifyFail(rcode);
258 #endif
259  Release();
260  return rcode;
261 }
262 
263 HIDUniversal::HIDInterface* HIDUniversal::FindInterface(uint8_t iface, uint8_t alt, uint8_t proto) {
264  for (uint8_t i = 0; i < bNumIface && i < maxHidInterfaces; i++)
265  if (hidInterfaces[i].bmInterface == iface && hidInterfaces[i].bmAltSet == alt
266  && hidInterfaces[i].bmProtocol == proto)
267  return hidInterfaces + i;
268  return NULL;
269 }
270 
271 void HIDUniversal::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
272  // If the first configuration satisfies, the others are not concidered.
273  if (bNumEP > 1 && conf != bConfNum)
274  return;
275 
276  //ErrorMessage<uint8_t>(PSTR("\r\nConf.Val"), conf);
277  //ErrorMessage<uint8_t>(PSTR("Iface Num"), iface);
278  //ErrorMessage<uint8_t>(PSTR("Alt.Set"), alt);
279 
280  bConfNum = conf;
281 
282  uint8_t index = 0;
283  HIDInterface *piface = FindInterface(iface, alt, proto);
284 
285  // Fill in interface structure in case of new interface
286  if (!piface) {
287  piface = hidInterfaces + bNumIface;
288  piface->bmInterface = iface;
289  piface->bmAltSet = alt;
290  piface->bmProtocol = proto;
291  bNumIface++;
292  }
293 
294  if ((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80)
295  index = epInterruptInIndex;
296  else
297  index = epInterruptOutIndex;
298 
299  if (index) {
300  // Fill in the endpoint info structure
301  epInfo[bNumEP].epAddr = (pep->bEndpointAddress & 0x0F);
302  epInfo[bNumEP].maxPktSize = (uint8_t)pep->wMaxPacketSize;
303  epInfo[bNumEP].epAttribs = 0;
304  epInfo[bNumEP].bmNakPower = USB_NAK_NOWAIT;
305 
306  // Fill in the endpoint index list
307  piface->epIndex[index] = bNumEP; //(pep->bEndpointAddress & 0x0F);
308 
309  bNumEP++;
310  }
311  //PrintEndpointDescriptor(pep);
312 }
313 
316 
317  bNumEP = 1;
318  bAddress = 0;
319  qNextPollTime = 0;
320  bPollEnable = false;
321  return 0;
322 }
323 
324 bool HIDUniversal::BuffersIdentical(uint8_t len, uint8_t *buf1, uint8_t *buf2) {
325  for (uint8_t i = 0; i < len; i++)
326  if (buf1[i] != buf2[i])
327  return false;
328  return true;
329 }
330 
331 void HIDUniversal::ZeroMemory(uint8_t len, uint8_t *buf) {
332  for (uint8_t i = 0; i < len; i++)
333  buf[i] = 0;
334 }
335 
336 void HIDUniversal::SaveBuffer(uint8_t len, uint8_t *src, uint8_t *dest) {
337  for (uint8_t i = 0; i < len; i++)
338  dest[i] = src[i];
339 }
340 
342  uint8_t rcode = 0;
343 
344  if (!bPollEnable)
345  return 0;
346 
347  if (qNextPollTime <= millis()) {
348  qNextPollTime = millis() + 50;
349 
350  uint8_t buf[constBuffLen];
351 
352  for (uint8_t i = 0; i < bNumIface; i++) {
353  uint8_t index = hidInterfaces[i].epIndex[epInterruptInIndex];
354  uint16_t read = (uint16_t)epInfo[index].maxPktSize;
355 
356  ZeroMemory(constBuffLen, buf);
357 
358  uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[index].epAddr, &read, buf);
359 
360  if (rcode) {
361  if (rcode != hrNAK)
362  USBTRACE2("Poll:", rcode);
363  return rcode;
364  }
365 
366  if (read > constBuffLen)
367  read = constBuffLen;
368 
369  bool identical = BuffersIdentical(read, buf, prevBuf);
370 
371  SaveBuffer(read, buf, prevBuf);
372 
373  if (identical)
374  return 0;
375 
376  Notify(PSTR("\r\nBuf: "), 0x80);
377 
378  for (uint8_t i = 0; i < read; i++)
379  D_PrintHex<uint8_t > (buf[i], 0x80);
380 
381  Notify(PSTR("\r\n"), 0x80);
382 
383  HIDReportParser *prs = GetReportParser(((bHasReportId) ? *buf : 0));
384 
385  if (prs)
386  prs->Parse(this, bHasReportId, (uint8_t)read, buf);
387  }
388  }
389  return rcode;
390 }
uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t *dataptr)
Definition: Usb.cpp:764
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed)
bool bHasReportId
Definition: hiduniversal.h:51
EpInfo * epinfo
Definition: address.h:76
bool lowspeed
Definition: address.h:79
#define USB_ERROR_EPINFO_IS_NULL
Definition: UsbCore.h:67
#define hrSTALL
Definition: max3421e.h:217
uint8_t bmNakPower
Definition: address.h:42
#define NotifyFail(...)
Definition: message.h:55
static const uint8_t epInterruptOutIndex
Definition: hid.h:150
uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value)
Definition: Usb.cpp:798
#define NotifyFailGetDevDescr(...)
Definition: message.h:50
uint8_t bAddress
Definition: hid.h:146
uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo *eprecord_ptr)
Definition: Usb.cpp:64
virtual uint8_t Release()
#define CP_MASK_COMPARE_CLASS
virtual uint8_t OnInitSuccessful()
Definition: hiduniversal.h:56
#define USB_CLASS_HID
Definition: UsbCore.h:43
virtual void FreeAddress(uint8_t addr)=0
virtual uint8_t Poll()
uint8_t epAttribs
Definition: address.h:37
virtual UsbDevice * GetUsbDevicePtr(uint8_t addr)=0
#define Notify(...)
Definition: message.h:44
#define USBTRACE2(s, r)
Definition: macros.h:61
uint8_t setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr)
Definition: Usb.cpp:793
#define NotifyFailGetConfDescr(...)
Definition: message.h:52
uint8_t epAddr
Definition: address.h:33
#define USB_NAK_MAX_POWER
Definition: address.h:27
virtual HIDReportParser * GetReportParser(uint8_t id)
Definition: address.h:32
virtual void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep)
#define hrNAK
Definition: max3421e.h:216
HIDUniversal(USB *p)
Definition: hiduniversal.cpp:3
uint16_t wMaxPacketSize
Definition: usb_ch9.h:146
Definition: hid.h:143
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub=false, uint8_t port=0)=0
uint8_t bEndpointAddress
Definition: usb_ch9.h:144
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE
Definition: UsbCore.h:69
#define USB_NAK_NOWAIT
Definition: address.h:29
#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL
Definition: UsbCore.h:66
virtual void Parse(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf)=0
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data)
Definition: Usb.cpp:206
#define MAX_REPORT_PARSERS
Definition: hid.h:140
#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED
Definition: UsbCore.h:61
USB * pUsb
Definition: hid.h:145
uint8_t SetIdle(uint8_t iface, uint8_t reportID, uint8_t duration)
Definition: hid.cpp:32
static const uint8_t epInterruptInIndex
Definition: hid.h:149
#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL
Definition: UsbCore.h:64
uint8_t maxPktSize
Definition: address.h:34
AddressPool & GetAddressPool()
Definition: UsbCore.h:168
Definition: UsbCore.h:152
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev)
Definition: UsbCore.h:172
static const uint8_t totalEndpoints
Definition: hid.h:154
#define NotifyFailSetConfDescr(...)
Definition: message.h:53
#define HID_MAX_HID_CLASS_DESCRIPTORS
Definition: hid.h:141
static const uint8_t maxEpPerInterface
Definition: hid.h:153
virtual bool SetReportParser(uint8_t id, HIDReportParser *prs)
#define USBTRACE(s)
Definition: macros.h:60
uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr)
defined(USB_METHODS_INLINE)
Definition: Usb.cpp:759
#define NotifyFailSetDevTblEntry(...)
Definition: message.h:51
static const uint8_t maxHidInterfaces
Definition: hid.h:152