USB Host Shield 2.0
Usb.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 /* USB functions */
18 
19 #include "Usb.h"
20 
21 static uint8_t usb_error = 0;
22 static uint8_t usb_task_state;
23 
24 /* constructor */
25 USB::USB() : bmHubPre(0) {
26  usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; //set up state machine
27  init();
28 }
29 
30 /* Initialize data structures */
31 void USB::init() {
32  //devConfigIndex = 0;
33  bmHubPre = 0;
34 }
35 
36 uint8_t USB::getUsbTaskState(void) {
37  return ( usb_task_state);
38 }
39 
40 void USB::setUsbTaskState(uint8_t state) {
41  usb_task_state = state;
42 }
43 
44 EpInfo* USB::getEpInfoEntry(uint8_t addr, uint8_t ep) {
45  UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
46 
47  if(!p || !p->epinfo)
48  return NULL;
49 
50  EpInfo *pep = p->epinfo;
51 
52  for(uint8_t i = 0; i < p->epcount; i++) {
53  if((pep)->epAddr == ep)
54  return pep;
55 
56  pep++;
57  }
58  return NULL;
59 }
60 
61 /* set device table entry */
62 
63 /* each device is different and has different number of endpoints. This function plugs endpoint record structure, defined in application, to devtable */
64 uint8_t USB::setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr) {
65  if(!eprecord_ptr)
67 
68  UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
69 
70  if(!p)
72 
73  p->address.devAddress = addr;
74  p->epinfo = eprecord_ptr;
75  p->epcount = epcount;
76 
77  return 0;
78 }
79 
80 uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_limit) {
81  UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
82 
83  if(!p)
85 
86  if(!p->epinfo)
88 
89  *ppep = getEpInfoEntry(addr, ep);
90 
91  if(!*ppep)
93 
94  *nak_limit = (0x0001UL << (((*ppep)->bmNakPower > USB_NAK_MAX_POWER) ? USB_NAK_MAX_POWER : (*ppep)->bmNakPower));
95  (*nak_limit)--;
96  /*
97  USBTRACE2("\r\nAddress: ", addr);
98  USBTRACE2(" EP: ", ep);
99  USBTRACE2(" NAK Power: ",(*ppep)->bmNakPower);
100  USBTRACE2(" NAK Limit: ", nak_limit);
101  USBTRACE("\r\n");
102  */
103  regWr(rPERADDR, addr); //set peripheral address
104 
105  uint8_t mode = regRd(rMODE);
106 
107  //Serial.print("\r\nMode: ");
108  //Serial.println( mode, HEX);
109  //Serial.print("\r\nLS: ");
110  //Serial.println(p->lowspeed, HEX);
111 
112 
113 
114  // Set bmLOWSPEED and bmHUBPRE in case of low-speed device, reset them otherwise
115  regWr(rMODE, (p->lowspeed) ? mode | bmLOWSPEED | bmHubPre : mode & ~(bmHUBPRE | bmLOWSPEED));
116 
117  return 0;
118 }
119 
120 /* Control transfer. Sets address, endpoint, fills control packet with necessary data, dispatches control packet, and initiates bulk IN transfer, */
121 /* depending on request. Actual requests are defined as inlines */
122 /* return codes: */
123 /* 00 = success */
124 
125 /* 01-0f = non-zero HRSLT */
126 uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi,
127  uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, USBReadParser *p) {
128  bool direction = false; //request direction, IN or OUT
129  uint8_t rcode;
130  SETUP_PKT setup_pkt;
131 
132  EpInfo *pep = NULL;
133  uint16_t nak_limit = 0;
134 
135  rcode = SetAddress(addr, ep, &pep, &nak_limit);
136 
137  if(rcode)
138  return rcode;
139 
140  direction = ((bmReqType & 0x80) > 0);
141 
142  /* fill in setup packet */
143  setup_pkt.ReqType_u.bmRequestType = bmReqType;
144  setup_pkt.bRequest = bRequest;
145  setup_pkt.wVal_u.wValueLo = wValLo;
146  setup_pkt.wVal_u.wValueHi = wValHi;
147  setup_pkt.wIndex = wInd;
148  setup_pkt.wLength = total;
149 
150  bytesWr(rSUDFIFO, 8, (uint8_t*) & setup_pkt); //transfer to setup packet FIFO
151 
152  rcode = dispatchPkt(tokSETUP, ep, nak_limit); //dispatch packet
153 
154  if(rcode) //return HRSLT if not zero
155  return ( rcode);
156 
157  if(dataptr != NULL) //data stage, if present
158  {
159  if(direction) //IN transfer
160  {
161  uint16_t left = total;
162 
163  pep->bmRcvToggle = 1; //bmRCVTOG1;
164 
165  while(left) {
166  // Bytes read into buffer
167 #if defined(ESP8266) || defined(ESP32)
168  yield(); // needed in order to reset the watchdog timer on the ESP8266
169 #endif
170  uint16_t read = nbytes;
171  //uint16_t read = (left<nbytes) ? left : nbytes;
172 
173  rcode = InTransfer(pep, nak_limit, &read, dataptr);
174  if(rcode == hrTOGERR) {
175  // yes, we flip it wrong here so that next time it is actually correct!
176  pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
177  continue;
178  }
179 
180  if(rcode)
181  return rcode;
182 
183  // Invoke callback function if inTransfer completed successfully and callback function pointer is specified
184  if(!rcode && p)
185  ((USBReadParser*)p)->Parse(read, dataptr, total - left);
186 
187  left -= read;
188 
189  if(read < nbytes)
190  break;
191  }
192  } else //OUT transfer
193  {
194  pep->bmSndToggle = 1; //bmSNDTOG1;
195  rcode = OutTransfer(pep, nak_limit, nbytes, dataptr);
196  }
197  if(rcode) //return error
198  return ( rcode);
199  }
200  // Status stage
201  return dispatchPkt((direction) ? tokOUTHS : tokINHS, ep, nak_limit); //GET if direction
202 }
203 
204 /* IN transfer to arbitrary endpoint. Assumes PERADDR is set. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */
205 /* Keep sending INs and writes data to memory area pointed by 'data' */
206 
207 /* rcode 0 if no errors. rcode 01-0f is relayed from dispatchPkt(). Rcode f0 means RCVDAVIRQ error,
208  fe USB xfer timeout */
209 uint8_t USB::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data, uint8_t bInterval /*= 0*/) {
210  EpInfo *pep = NULL;
211  uint16_t nak_limit = 0;
212 
213  uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit);
214 
215  if(rcode) {
216  USBTRACE3("(USB::InTransfer) SetAddress Failed ", rcode, 0x81);
217  USBTRACE3("(USB::InTransfer) addr requested ", addr, 0x81);
218  USBTRACE3("(USB::InTransfer) ep requested ", ep, 0x81);
219  return rcode;
220  }
221  return InTransfer(pep, nak_limit, nbytesptr, data, bInterval);
222 }
223 
224 uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t* data, uint8_t bInterval /*= 0*/) {
225  uint8_t rcode = 0;
226  uint8_t pktsize;
227 
228  uint16_t nbytes = *nbytesptr;
229  //printf("Requesting %i bytes ", nbytes);
230  uint8_t maxpktsize = pep->maxPktSize;
231 
232  *nbytesptr = 0;
233  regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
234 
235  // use a 'break' to exit this loop
236  while(1) {
237 #if defined(ESP8266) || defined(ESP32)
238  yield(); // needed in order to reset the watchdog timer on the ESP8266
239 #endif
240  rcode = dispatchPkt(tokIN, pep->epAddr, nak_limit); //IN packet to EP-'endpoint'. Function takes care of NAKS.
241  if(rcode == hrTOGERR) {
242  // yes, we flip it wrong here so that next time it is actually correct!
243  pep->bmRcvToggle = (regRd(rHRSL) & bmRCVTOGRD) ? 0 : 1;
244  regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
245  continue;
246  }
247  if(rcode) {
248  //printf(">>>>>>>> Problem! dispatchPkt %2.2x\r\n", rcode);
249  break; //should be 0, indicating ACK. Else return error code.
250  }
251  /* check for RCVDAVIRQ and generate error if not present
252  * the only case when absence of RCVDAVIRQ makes sense is when toggle error occurred.
253  * Need to add handling for that
254  *
255  * NOTE: I've seen this happen with SPI corruption -- xxxajk
256  */
257  if((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) {
258  //printf(">>>>>>>> Problem! NO RCVDAVIRQ!\r\n");
259  rcode = 0xf0; //receive error
260  break;
261  }
262  pktsize = regRd(rRCVBC); //number of received bytes
263  //printf("Got %i bytes \r\n", pktsize);
264  // This would be OK, but...
265  //assert(pktsize <= nbytes);
266  if(pktsize > nbytes) {
267  // This can happen. Use of assert on Arduino locks up the Arduino.
268  // So I will trim the value, and hope for the best.
269  //printf(">>>>>>>> Problem! Wanted %i bytes but got %i.\r\n", nbytes, pktsize);
270  pktsize = nbytes;
271  }
272 
273  int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr);
274 
275  if(mem_left < 0)
276  mem_left = 0;
277 
278  data = bytesRd(rRCVFIFO, ((pktsize > mem_left) ? mem_left : pktsize), data);
279 
280  regWr(rHIRQ, bmRCVDAVIRQ); // Clear the IRQ & free the buffer
281  *nbytesptr += pktsize; // add this packet's byte count to total transfer length
282 
283  /* The transfer is complete under two conditions: */
284  /* 1. The device sent a short packet (L.T. maxPacketSize) */
285  /* 2. 'nbytes' have been transferred. */
286  if((pktsize < maxpktsize) || (*nbytesptr >= nbytes)) // have we transferred 'nbytes' bytes?
287  {
288  // Save toggle value
289  pep->bmRcvToggle = ((regRd(rHRSL) & bmRCVTOGRD)) ? 1 : 0;
290  //printf("\r\n");
291  rcode = 0;
292  break;
293  } else if(bInterval > 0)
294  delay(bInterval); // Delay according to polling interval
295  } //while( 1 )
296  return ( rcode);
297 }
298 
299 /* OUT transfer to arbitrary endpoint. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */
300 /* Handles NAK bug per Maxim Application Note 4000 for single buffer transfer */
301 
302 /* rcode 0 if no errors. rcode 01-0f is relayed from HRSL */
303 uint8_t USB::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data) {
304  EpInfo *pep = NULL;
305  uint16_t nak_limit = 0;
306 
307  uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit);
308 
309  if(rcode)
310  return rcode;
311 
312  return OutTransfer(pep, nak_limit, nbytes, data);
313 }
314 
315 uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8_t *data) {
316  uint8_t rcode = hrSUCCESS, retry_count;
317  uint8_t *data_p = data; //local copy of the data pointer
318  uint16_t bytes_tosend, nak_count;
319  uint16_t bytes_left = nbytes;
320 
321  uint8_t maxpktsize = pep->maxPktSize;
322 
323  if(maxpktsize < 1 || maxpktsize > 64)
325 
326  uint32_t timeout = (uint32_t)millis() + USB_XFER_TIMEOUT;
327 
328  regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
329 
330  while(bytes_left) {
331 #if defined(ESP8266) || defined(ESP32)
332  yield(); // needed in order to reset the watchdog timer on the ESP8266
333 #endif
334  retry_count = 0;
335  nak_count = 0;
336  bytes_tosend = (bytes_left >= maxpktsize) ? maxpktsize : bytes_left;
337  bytesWr(rSNDFIFO, bytes_tosend, data_p); //filling output FIFO
338  regWr(rSNDBC, bytes_tosend); //set number of bytes
339  regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
340  while(!(regRd(rHIRQ) & bmHXFRDNIRQ)){
341 #if defined(ESP8266) || defined(ESP32)
342  yield(); // needed in order to reset the watchdog timer on the ESP8266
343 #endif
344  } //wait for the completion IRQ
345  regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
346  rcode = (regRd(rHRSL) & 0x0f);
347 
348  while(rcode && ((int32_t)((uint32_t)millis() - timeout) < 0L)) {
349 #if defined(ESP8266) || defined(ESP32)
350  yield(); // needed in order to reset the watchdog timer on the ESP8266
351 #endif
352  switch(rcode) {
353  case hrNAK:
354  nak_count++;
355  if(nak_limit && (nak_count == nak_limit))
356  goto breakout;
357  //return ( rcode);
358  break;
359  case hrTIMEOUT:
360  retry_count++;
361  if(retry_count == USB_RETRY_LIMIT)
362  goto breakout;
363  //return ( rcode);
364  break;
365  case hrTOGERR:
366  // yes, we flip it wrong here so that next time it is actually correct!
367  pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
368  regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
369  break;
370  default:
371  goto breakout;
372  }//switch( rcode
373 
374  /* process NAK according to Host out NAK bug */
375  regWr(rSNDBC, 0);
376  regWr(rSNDFIFO, *data_p);
377  regWr(rSNDBC, bytes_tosend);
378  regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
379  while(!(regRd(rHIRQ) & bmHXFRDNIRQ)){
380 #if defined(ESP8266) || defined(ESP32)
381  yield(); // needed in order to reset the watchdog timer on the ESP8266
382 #endif
383  } //wait for the completion IRQ
384  regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
385  rcode = (regRd(rHRSL) & 0x0f);
386  }//while( rcode && ....
387  bytes_left -= bytes_tosend;
388  data_p += bytes_tosend;
389  }//while( bytes_left...
390 breakout:
391 
392  pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 1 : 0; //bmSNDTOG1 : bmSNDTOG0; //update toggle
393  return ( rcode); //should be 0 in all cases
394 }
395 /* dispatch USB packet. Assumes peripheral address is set and relevant buffer is loaded/empty */
396 /* If NAK, tries to re-send up to nak_limit times */
397 /* If nak_limit == 0, do not count NAKs, exit after timeout */
398 /* If bus timeout, re-sends up to USB_RETRY_LIMIT times */
399 
400 /* return codes 0x00-0x0f are HRSLT( 0x00 being success ), 0xff means timeout */
401 uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
402  uint32_t timeout = (uint32_t)millis() + USB_XFER_TIMEOUT;
403  uint8_t tmpdata;
404  uint8_t rcode = hrSUCCESS;
405  uint8_t retry_count = 0;
406  uint16_t nak_count = 0;
407 
408  while((int32_t)((uint32_t)millis() - timeout) < 0L) {
409 #if defined(ESP8266) || defined(ESP32)
410  yield(); // needed in order to reset the watchdog timer on the ESP8266
411 #endif
412  regWr(rHXFR, (token | ep)); //launch the transfer
414 
415  while((int32_t)((uint32_t)millis() - timeout) < 0L) //wait for transfer completion
416  {
417 #if defined(ESP8266) || defined(ESP32)
418  yield(); // needed in order to reset the watchdog timer on the ESP8266
419 #endif
420  tmpdata = regRd(rHIRQ);
421 
422  if(tmpdata & bmHXFRDNIRQ) {
423  regWr(rHIRQ, bmHXFRDNIRQ); //clear the interrupt
424  rcode = 0x00;
425  break;
426  }//if( tmpdata & bmHXFRDNIRQ
427 
428  }//while ( millis() < timeout
429 
430  //if (rcode != 0x00) //exit if timeout
431  // return ( rcode);
432 
433  rcode = (regRd(rHRSL) & 0x0f); //analyze transfer result
434 
435  switch(rcode) {
436  case hrNAK:
437  nak_count++;
438  if(nak_limit && (nak_count == nak_limit))
439  return (rcode);
440  break;
441  case hrTIMEOUT:
442  retry_count++;
443  if(retry_count == USB_RETRY_LIMIT)
444  return (rcode);
445  break;
446  default:
447  return (rcode);
448  }//switch( rcode
449 
450  }//while( timeout > millis()
451  return ( rcode);
452 }
453 
454 /* USB main task. Performs enumeration/cleanup */
455 void USB::Task(void) //USB state machine
456 {
457  uint8_t rcode;
458  uint8_t tmpdata;
459  static uint32_t delay = 0;
460  //USB_DEVICE_DESCRIPTOR buf;
461  bool lowspeed = false;
462 
463  MAX3421E::Task();
464 
465  tmpdata = getVbusState();
466 
467  /* modify USB task state if Vbus changed */
468  switch(tmpdata) {
469  case SE1: //illegal state
470  usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
471  lowspeed = false;
472  break;
473  case SE0: //disconnected
474  if((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED)
475  usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
476  lowspeed = false;
477  break;
478  case LSHOST:
479 
480  lowspeed = true;
481  //intentional fallthrough
482  case FSHOST: //attached
483  if((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
484  delay = (uint32_t)millis() + USB_SETTLE_DELAY;
485  usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
486  }
487  break;
488  }// switch( tmpdata
489 
490  for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
491  if(devConfig[i])
492  rcode = devConfig[i]->Poll();
493 
494  switch(usb_task_state) {
496  init();
497 
498  for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
499  if(devConfig[i])
500  rcode = devConfig[i]->Release();
501 
502  usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
503  break;
504  case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here
505  break;
506  case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
507  break;
508  case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device
509  if((int32_t)((uint32_t)millis() - delay) >= 0L)
510  usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
511  else break; // don't fall through
513  regWr(rHCTL, bmBUSRST); //issue bus reset
515  break;
517  if((regRd(rHCTL) & bmBUSRST) == 0) {
518  tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation
519  regWr(rMODE, tmpdata);
520  usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
521  //delay = (uint32_t)millis() + 20; //20ms wait after reset per USB spec
522  }
523  break;
524  case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
525  if(regRd(rHIRQ) & bmFRAMEIRQ) {
526  //when first SOF received _and_ 20ms has passed we can continue
527  /*
528  if (delay < (uint32_t)millis()) //20ms passed
529  usb_task_state = USB_STATE_CONFIGURING;
530  */
531  usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET;
532  delay = (uint32_t)millis() + 20;
533  }
534  break;
536  if((int32_t)((uint32_t)millis() - delay) >= 0L) usb_task_state = USB_STATE_CONFIGURING;
537  else break; // don't fall through
539 
540  //Serial.print("\r\nConf.LS: ");
541  //Serial.println(lowspeed, HEX);
542 
543  rcode = Configuring(0, 0, lowspeed);
544 
545  if(rcode) {
547  usb_error = rcode;
548  usb_task_state = USB_STATE_ERROR;
549  }
550  } else
551  usb_task_state = USB_STATE_RUNNING;
552  break;
553  case USB_STATE_RUNNING:
554  break;
555  case USB_STATE_ERROR:
556  //MAX3421E::Init();
557  break;
558  } // switch( usb_task_state )
559 }
560 
561 uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) {
562  //uint8_t buf[12];
563  uint8_t rcode;
564  UsbDevice *p0 = NULL, *p = NULL;
565 
566  // Get pointer to pseudo device with address 0 assigned
567  p0 = addrPool.GetUsbDevicePtr(0);
568 
569  if(!p0)
571 
572  if(!p0->epinfo)
574 
575  p0->lowspeed = (lowspeed) ? true : false;
576 
577  // Allocate new address according to device class
578  uint8_t bAddress = addrPool.AllocAddress(parent, false, port);
579 
580  if(!bAddress)
582 
583  p = addrPool.GetUsbDevicePtr(bAddress);
584 
585  if(!p)
587 
588  p->lowspeed = lowspeed;
589 
590  // Assign new address to the device
591  rcode = setAddr(0, 0, bAddress);
592 
593  if(rcode) {
594  addrPool.FreeAddress(bAddress);
595  bAddress = 0;
596  return rcode;
597  }
598  return 0;
599 };
600 
601 uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed) {
602  //printf("AttemptConfig: parent = %i, port = %i\r\n", parent, port);
603  uint8_t retries = 0;
604 
605 again:
606  uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed);
608  if(parent == 0) {
609  // Send a bus reset on the root interface.
610  regWr(rHCTL, bmBUSRST); //issue bus reset
611  delay(102); // delay 102ms, compensate for clock inaccuracy.
612  } else {
613  // reset parent port
614  devConfig[parent]->ResetHubPort(port);
615  }
616  } else if(rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
617  delay(100);
618  retries++;
619  goto again;
620  } else if(rcode)
621  return rcode;
622 
623  rcode = devConfig[driver]->Init(parent, port, lowspeed);
624  if(rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
625  delay(100);
626  retries++;
627  goto again;
628  }
629  if(rcode) {
630  // Issue a bus reset, because the device may be in a limbo state
631  if(parent == 0) {
632  // Send a bus reset on the root interface.
633  regWr(rHCTL, bmBUSRST); //issue bus reset
634  delay(102); // delay 102ms, compensate for clock inaccuracy.
635  } else {
636  // reset parent port
637  devConfig[parent]->ResetHubPort(port);
638  }
639  }
640  return rcode;
641 }
642 
643 /*
644  * This is broken. We need to enumerate differently.
645  * It causes major problems with several devices if detected in an unexpected order.
646  *
647  *
648  * Oleg - I wouldn't do anything before the newly connected device is considered sane.
649  * i.e.(delays are not indicated for brevity):
650  * 1. reset
651  * 2. GetDevDescr();
652  * 3a. If ACK, continue with allocating address, addressing, etc.
653  * 3b. Else reset again, count resets, stop at some number (5?).
654  * 4. When max.number of resets is reached, toggle power/fail
655  * If desired, this could be modified by performing two resets with GetDevDescr() in the middle - however, from my experience, if a device answers to GDD()
656  * it doesn't need to be reset again
657  * New steps proposal:
658  * 1: get address pool instance. exit on fail
659  * 2: pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf). exit on fail.
660  * 3: bus reset, 100ms delay
661  * 4: set address
662  * 5: pUsb->setEpInfoEntry(bAddress, 1, epInfo), exit on fail
663  * 6: while (configurations) {
664  * for(each configuration) {
665  * for (each driver) {
666  * 6a: Ask device if it likes configuration. Returns 0 on OK.
667  * If successful, the driver configured device.
668  * The driver now owns the endpoints, and takes over managing them.
669  * The following will need codes:
670  * Everything went well, instance consumed, exit with success.
671  * Instance already in use, ignore it, try next driver.
672  * Not a supported device, ignore it, try next driver.
673  * Not a supported configuration for this device, ignore it, try next driver.
674  * Could not configure device, fatal, exit with fail.
675  * }
676  * }
677  * }
678  * 7: for(each driver) {
679  * 7a: Ask device if it knows this VID/PID. Acts exactly like 6a, but using VID/PID
680  * 8: if we get here, no driver likes the device plugged in, so exit failure.
681  *
682  */
683 uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
684  //uint8_t bAddress = 0;
685  //printf("Configuring: parent = %i, port = %i\r\n", parent, port);
686  uint8_t devConfigIndex;
687  uint8_t rcode = 0;
688  uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
689  USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR *>(buf);
690  UsbDevice *p = NULL;
691  EpInfo *oldep_ptr = NULL;
692  EpInfo epInfo;
693 
694  epInfo.epAddr = 0;
695  epInfo.maxPktSize = 8;
696  epInfo.bmSndToggle = 0;
697  epInfo.bmRcvToggle = 0;
698  epInfo.bmNakPower = USB_NAK_MAX_POWER;
699 
700  //delay(2000);
701  AddressPool &addrPool = GetAddressPool();
702  // Get pointer to pseudo device with address 0 assigned
703  p = addrPool.GetUsbDevicePtr(0);
704  if(!p) {
705  //printf("Configuring error: USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL\r\n");
707  }
708 
709  // Save old pointer to EP_RECORD of address 0
710  oldep_ptr = p->epinfo;
711 
712  // Temporary assign new pointer to epInfo to p->epinfo in order to
713  // avoid toggle inconsistence
714 
715  p->epinfo = &epInfo;
716 
717  p->lowspeed = lowspeed;
718  // Get device descriptor
719  rcode = getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);
720 
721  // Restore p->epinfo
722  p->epinfo = oldep_ptr;
723 
724  if(rcode) {
725  //printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n");
726  return rcode;
727  }
728 
729  // to-do?
730  // Allocate new address according to device class
731  //bAddress = addrPool.AllocAddress(parent, false, port);
732 
733  uint16_t vid = udd->idVendor;
734  uint16_t pid = udd->idProduct;
735  uint8_t klass = udd->bDeviceClass;
736  uint8_t subklass = udd->bDeviceSubClass;
737  // Attempt to configure if VID/PID or device class matches with a driver
738  // Qualify with subclass too.
739  //
740  // VID/PID & class tests default to false for drivers not yet ported
741  // subclass defaults to true, so you don't have to define it if you don't have to.
742  //
743  for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
744  if(!devConfig[devConfigIndex]) continue; // no driver
745  if(devConfig[devConfigIndex]->GetAddress()) continue; // consumed
746  if(devConfig[devConfigIndex]->DEVSUBCLASSOK(subklass) && (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass))) {
747  rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
749  break;
750  }
751  }
752 
753  if(devConfigIndex < USB_NUMDEVICES) {
754  return rcode;
755  }
756 
757 
758  // blindly attempt to configure
759  for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
760  if(!devConfig[devConfigIndex]) continue;
761  if(devConfig[devConfigIndex]->GetAddress()) continue; // consumed
762  if(devConfig[devConfigIndex]->DEVSUBCLASSOK(subklass) && (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass))) continue; // If this is true it means it must have returned USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED above
763  rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
764 
765  //printf("ERROR ENUMERATING %2.2x\r\n", rcode);
767  // in case of an error dev_index should be reset to 0
768  // in order to start from the very beginning the
769  // next time the program gets here
770  //if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE)
771  // devConfigIndex = 0;
772  return rcode;
773  }
774  }
775  // if we get here that means that the device class is not supported by any of registered classes
776  rcode = DefaultAddressing(parent, port, lowspeed);
777 
778  return rcode;
779 }
780 
781 uint8_t USB::ReleaseDevice(uint8_t addr) {
782  if(!addr)
783  return 0;
784 
785  for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
786  if(!devConfig[i]) continue;
787  if(devConfig[i]->GetAddress() == addr)
788  return devConfig[i]->Release();
789  }
790  return 0;
791 }
792 
793 #if 1
794 //get device descriptor
795 
796 uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) {
797  return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, nbytes, dataptr, NULL));
798 }
799 //get configuration descriptor
800 
801 uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) {
802  return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, nbytes, dataptr, NULL));
803 }
804 
805 /* Requests Configuration Descriptor. Sends two Get Conf Descr requests. The first one gets the total length of all descriptors, then the second one requests this
806  total length. The length of the first request can be shorter ( 4 bytes ), however, there are devices which won't work unless this length is set to 9 */
807 uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser *p) {
808  const uint8_t bufSize = 64;
809  uint8_t buf[bufSize];
810  USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR *>(buf);
811 
812  uint8_t ret = getConfDescr(addr, ep, 9, conf, buf);
813 
814  if(ret)
815  return ret;
816 
817  uint16_t total = ucd->wTotalLength;
818 
819  //USBTRACE2("\r\ntotal conf.size:", total);
820 
821  return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, total, bufSize, buf, p));
822 }
823 
824 //get string descriptor
825 
826 uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t ns, uint8_t index, uint16_t langid, uint8_t* dataptr) {
827  return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, ns, ns, dataptr, NULL));
828 }
829 //set address
830 
831 uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) {
832  uint8_t rcode = ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL);
833  //delay(2); //per USB 2.0 sect.9.2.6.3
834  delay(300); // Older spec says you should wait at least 200ms
835  return rcode;
836  //return ( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL));
837 }
838 //set configuration
839 
840 uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) {
841  return ( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL));
842 }
843 
844 #endif // defined(USB_METHODS_INLINE)
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
virtual uint8_t Poll()
Definition: UsbCore.h:149
#define USB_ERROR_EP_NOT_FOUND_IN_TBL
Definition: UsbCore.h:100
#define bmHUBPRE
Definition: max3421e.h:172
#define USB_ATTACHED_SUBSTATE_WAIT_RESET
Definition: UsbCore.h:127
#define FSHOST
Definition: max3421e.h:37
#define rHCTL
Definition: max3421e.h:181
EpInfo * epinfo
Definition: address.h:83
bool lowspeed
Definition: address.h:86
#define USB_ERROR_EPINFO_IS_NULL
Definition: UsbCore.h:96
uint8_t bmNakPower
Definition: address.h:49
EpInfo * getEpInfoEntry(uint8_t addr, uint8_t ep)
Definition: Usb.cpp:44
#define bmSOFKAENAB
Definition: max3421e.h:173
#define USB_DESCRIPTOR_STRING
Definition: usb_ch9.h:72
uint16_t wLength
Definition: UsbCore.h:198
#define USB_SETTLE_DELAY
Definition: UsbCore.h:110
#define USB_ATTACHED_SUBSTATE_SETTLE
Definition: UsbCore.h:123
uint8_t getVbusState(void)
Definition: usbhost.h:152
#define bmRCVTOGRD
Definition: max3421e.h:206
#define USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE
Definition: UsbCore.h:91
#define USB_RETRY_LIMIT
Definition: UsbCore.h:109
#define USB_REQUEST_GET_DESCRIPTOR
Definition: usb_ch9.h:44
#define USB_DESCRIPTOR_DEVICE
Definition: usb_ch9.h:70
#define bmRCVTOG1
Definition: max3421e.h:188
#define USB_ERROR_INVALID_MAX_PKT_SIZE
Definition: UsbCore.h:99
uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value)
Definition: Usb.cpp:840
#define USB_STATE_DETACHED
Definition: UsbCore.h:119
#define USB_NUMDEVICES
Definition: UsbCore.h:112
#define rRCVBC
Definition: max3421e.h:47
#define hrJERR
Definition: max3421e.h:227
uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo *eprecord_ptr)
Definition: Usb.cpp:64
virtual uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed)
Definition: UsbCore.h:141
uint8_t Task()
Definition: usbhost.h:538
#define hrSUCCESS
Definition: max3421e.h:214
#define USB_STATE_ERROR
Definition: UsbCore.h:132
uint8_t bmRequestType
Definition: UsbCore.h:179
#define bmSNDTOGRD
Definition: max3421e.h:207
uint8_t ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi, uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t *dataptr, USBReadParser *p)
Definition: Usb.cpp:126
#define USB_DESCRIPTOR_CONFIGURATION
Definition: usb_ch9.h:71
virtual UsbDevice * GetUsbDevicePtr(uint8_t addr)=0
#define bmHXFRDNIRQ
Definition: max3421e.h:153
uint8_t setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr)
Definition: Usb.cpp:831
USB(void)
Definition: Usb.cpp:25
#define USB_STATE_RUNNING
Definition: UsbCore.h:131
uint8_t epAddr
Definition: address.h:40
#define rRCVFIFO
Definition: max3421e.h:44
#define USB_NAK_MAX_POWER
Definition: address.h:34
virtual UsbDevice * GetUsbDevicePtr(uint8_t addr)
Definition: address.h:188
uint16_t wIndex
Definition: UsbCore.h:197
#define bmBUSRST
Definition: max3421e.h:183
#define tokOUT
Definition: max3421e.h:197
#define tokIN
Definition: max3421e.h:196
#define LSHOST
Definition: max3421e.h:38
#define USB_XFER_TIMEOUT
Definition: UsbCore.h:107
union SETUP_PKT::@33 wVal_u
Definition: address.h:39
#define rMODE
Definition: max3421e.h:167
void setUsbTaskState(uint8_t state)
Definition: Usb.cpp:40
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data)
Definition: Usb.cpp:303
#define hrNAK
Definition: max3421e.h:218
#define bmREQ_GET_DESCR
Definition: UsbCore.h:60
#define rSNDBC
Definition: max3421e.h:48
#define rHRSL
Definition: max3421e.h:203
#define USB_ATTACHED_SUBSTATE_RESET_DEVICE
Definition: UsbCore.h:124
uint8_t * bytesRd(uint8_t reg, uint8_t nbytes, uint8_t *data_p)
Definition: usbhost.h:317
#define tokINHS
Definition: max3421e.h:198
#define bmLOWSPEED
Definition: max3421e.h:171
virtual void ResetHubPort(uint8_t port)
Definition: UsbCore.h:157
uint8_t * bytesWr(uint8_t reg, uint8_t nbytes, uint8_t *data_p)
Definition: usbhost.h:220
uint8_t getStrDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t index, uint16_t langid, uint8_t *dataptr)
Definition: Usb.cpp:826
#define USB_REQUEST_SET_ADDRESS
Definition: usb_ch9.h:43
#define tokSETUP
Definition: max3421e.h:195
#define rHXFR
Definition: max3421e.h:192
#define rHIRQ
Definition: max3421e.h:144
uint8_t bmSndToggle
Definition: address.h:47
#define rSNDFIFO
Definition: max3421e.h:45
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE
Definition: UsbCore.h:98
uint8_t devAddress
Definition: address.h:74
#define tokOUTHS
Definition: max3421e.h:199
uint8_t getUsbTaskState(void)
Definition: Usb.cpp:36
#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL
Definition: UsbCore.h:95
#define USB_STATE_MASK
Definition: UsbCore.h:117
#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED
Definition: UsbCore.h:90
void Task(void)
Definition: Usb.cpp:455
#define USB_DETACHED_SUBSTATE_ILLEGAL
Definition: UsbCore.h:122
#define hrTIMEOUT
Definition: max3421e.h:228
#define rPERADDR
Definition: max3421e.h:179
#define bmRCVDAVIRQ
Definition: max3421e.h:148
#define USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE
Definition: UsbCore.h:125
void regWr(uint8_t reg, uint8_t data)
Definition: usbhost.h:177
#define bmRCVTOG0
Definition: max3421e.h:187
uint8_t epcount
Definition: address.h:85
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval=0)
Definition: Usb.cpp:209
#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL
Definition: UsbCore.h:93
#define USB_STATE_CONFIGURING
Definition: UsbCore.h:130
uint8_t dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit)
Definition: Usb.cpp:401
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed)
Definition: UsbCore.h:137
#define bmSNDTOG0
Definition: max3421e.h:189
uint8_t regRd(uint8_t reg)
Definition: usbhost.h:278
uint8_t maxPktSize
Definition: address.h:41
AddressPool & GetAddressPool()
Definition: UsbCore.h:226
#define USB_ERROR_INVALID_ARGUMENT
Definition: UsbCore.h:97
uint8_t Configuring(uint8_t parent, uint8_t port, bool lowspeed)
Definition: Usb.cpp:683
union SETUP_PKT::@32 ReqType_u
#define USBTRACE3(s, r, l)
Definition: macros.h:85
uint8_t bRequest
Definition: UsbCore.h:187
#define SE0
Definition: max3421e.h:35
virtual void FreeAddress(uint8_t addr)
Definition: address.h:262
virtual uint8_t Release()
Definition: UsbCore.h:145
#define bmFRAMEIRQ
Definition: max3421e.h:152
#define hrTOGERR
Definition: max3421e.h:220
#define SE1
Definition: max3421e.h:36
#define rSUDFIFO
Definition: max3421e.h:46
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub=false, uint8_t port=0)
Definition: address.h:210
#define bmREQ_SET
Definition: UsbCore.h:61
UsbDeviceAddress address
Definition: address.h:84
#define USB_REQUEST_SET_CONFIGURATION
Definition: usb_ch9.h:47
#define USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE
Definition: UsbCore.h:121
uint8_t wValueHi
Definition: UsbCore.h:194
uint8_t DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed)
Definition: Usb.cpp:561
#define USB_DETACHED_SUBSTATE_INITIALIZE
Definition: UsbCore.h:120
uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr)
defined(USB_METHODS_INLINE)
Definition: Usb.cpp:796
#define USB_ATTACHED_SUBSTATE_WAIT_SOF
Definition: UsbCore.h:126
uint8_t wValueLo
Definition: UsbCore.h:193
#define bmSNDTOG1
Definition: max3421e.h:190
uint8_t ReleaseDevice(uint8_t addr)
Definition: Usb.cpp:781
#define USB_ERROR_TRANSFER_TIMEOUT
Definition: UsbCore.h:105
#define USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET
Definition: UsbCore.h:101