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  /* If rcode(=rHRSL) is non-zero, untransmitted data remains in the SNDFIFO. */
392  if(rcode != 0) {
393  //Switch the FIFO containing the OUT data back under microcontroller control and reset pointer.
394  regWr(rSNDBC, 0);
395  }
396 
397  pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 1 : 0; //bmSNDTOG1 : bmSNDTOG0; //update toggle
398  return ( rcode); //should be 0 in all cases
399 }
400 /* dispatch USB packet. Assumes peripheral address is set and relevant buffer is loaded/empty */
401 /* If NAK, tries to re-send up to nak_limit times */
402 /* If nak_limit == 0, do not count NAKs, exit after timeout */
403 /* If bus timeout, re-sends up to USB_RETRY_LIMIT times */
404 
405 /* return codes 0x00-0x0f are HRSLT( 0x00 being success ), 0xff means timeout */
406 uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
407  uint32_t timeout = (uint32_t)millis() + USB_XFER_TIMEOUT;
408  uint8_t tmpdata;
409  uint8_t rcode = hrSUCCESS;
410  uint8_t retry_count = 0;
411  uint16_t nak_count = 0;
412 
413  while((int32_t)((uint32_t)millis() - timeout) < 0L) {
414 #if defined(ESP8266) || defined(ESP32)
415  yield(); // needed in order to reset the watchdog timer on the ESP8266
416 #endif
417  regWr(rHXFR, (token | ep)); //launch the transfer
419 
420  while((int32_t)((uint32_t)millis() - timeout) < 0L) //wait for transfer completion
421  {
422 #if defined(ESP8266) || defined(ESP32)
423  yield(); // needed in order to reset the watchdog timer on the ESP8266
424 #endif
425  tmpdata = regRd(rHIRQ);
426 
427  if(tmpdata & bmHXFRDNIRQ) {
428  regWr(rHIRQ, bmHXFRDNIRQ); //clear the interrupt
429  rcode = 0x00;
430  break;
431  }//if( tmpdata & bmHXFRDNIRQ
432 
433  }//while ( millis() < timeout
434 
435  //if (rcode != 0x00) //exit if timeout
436  // return ( rcode);
437 
438  rcode = (regRd(rHRSL) & 0x0f); //analyze transfer result
439 
440  switch(rcode) {
441  case hrNAK:
442  nak_count++;
443  if(nak_limit && (nak_count == nak_limit))
444  return (rcode);
445  break;
446  case hrTIMEOUT:
447  retry_count++;
448  if(retry_count == USB_RETRY_LIMIT)
449  return (rcode);
450  break;
451  default:
452  return (rcode);
453  }//switch( rcode
454 
455  }//while( timeout > millis()
456  return ( rcode);
457 }
458 
459 /* USB main task. Performs enumeration/cleanup */
460 void USB::Task(void) //USB state machine
461 {
462  uint8_t rcode;
463  uint8_t tmpdata;
464  static uint32_t delay = 0;
465  //USB_DEVICE_DESCRIPTOR buf;
466  bool lowspeed = false;
467 
468  MAX3421E::Task();
469 
470  tmpdata = getVbusState();
471 
472  /* modify USB task state if Vbus changed */
473  switch(tmpdata) {
474  case SE1: //illegal state
475  usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
476  lowspeed = false;
477  break;
478  case SE0: //disconnected
479  if((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED)
480  usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
481  lowspeed = false;
482  break;
483  case LSHOST:
484 
485  lowspeed = true;
486  //intentional fallthrough
487  case FSHOST: //attached
488  if((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
489  delay = (uint32_t)millis() + USB_SETTLE_DELAY;
490  usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
491  }
492  break;
493  }// switch( tmpdata
494 
495  for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
496  if(devConfig[i])
497  rcode = devConfig[i]->Poll();
498 
499  switch(usb_task_state) {
501  init();
502 
503  for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
504  if(devConfig[i])
505  rcode = devConfig[i]->Release();
506 
507  usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
508  break;
509  case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here
510  break;
511  case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
512  break;
513  case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device
514  if((int32_t)((uint32_t)millis() - delay) >= 0L)
515  usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
516  else break; // don't fall through
518  regWr(rHCTL, bmBUSRST); //issue bus reset
520  break;
522  if((regRd(rHCTL) & bmBUSRST) == 0) {
523  tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation
524  regWr(rMODE, tmpdata);
525  usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
526  //delay = (uint32_t)millis() + 20; //20ms wait after reset per USB spec
527  }
528  break;
529  case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
530  if(regRd(rHIRQ) & bmFRAMEIRQ) {
531  //when first SOF received _and_ 20ms has passed we can continue
532  /*
533  if (delay < (uint32_t)millis()) //20ms passed
534  usb_task_state = USB_STATE_CONFIGURING;
535  */
536  usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET;
537  delay = (uint32_t)millis() + 20;
538  }
539  break;
541  if((int32_t)((uint32_t)millis() - delay) >= 0L) usb_task_state = USB_STATE_CONFIGURING;
542  else break; // don't fall through
544 
545  //Serial.print("\r\nConf.LS: ");
546  //Serial.println(lowspeed, HEX);
547 
548  rcode = Configuring(0, 0, lowspeed);
549 
550  if(rcode) {
552  usb_error = rcode;
553  usb_task_state = USB_STATE_ERROR;
554  }
555  } else
556  usb_task_state = USB_STATE_RUNNING;
557  break;
558  case USB_STATE_RUNNING:
559  break;
560  case USB_STATE_ERROR:
561  //MAX3421E::Init();
562  break;
563  } // switch( usb_task_state )
564 }
565 
566 uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) {
567  //uint8_t buf[12];
568  uint8_t rcode;
569  UsbDevice *p0 = NULL, *p = NULL;
570 
571  // Get pointer to pseudo device with address 0 assigned
572  p0 = addrPool.GetUsbDevicePtr(0);
573 
574  if(!p0)
576 
577  if(!p0->epinfo)
579 
580  p0->lowspeed = (lowspeed) ? true : false;
581 
582  // Allocate new address according to device class
583  uint8_t bAddress = addrPool.AllocAddress(parent, false, port);
584 
585  if(!bAddress)
587 
588  p = addrPool.GetUsbDevicePtr(bAddress);
589 
590  if(!p)
592 
593  p->lowspeed = lowspeed;
594 
595  // Assign new address to the device
596  rcode = setAddr(0, 0, bAddress);
597 
598  if(rcode) {
599  addrPool.FreeAddress(bAddress);
600  bAddress = 0;
601  return rcode;
602  }
603  return 0;
604 };
605 
606 uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed) {
607  //printf("AttemptConfig: parent = %i, port = %i\r\n", parent, port);
608  uint8_t retries = 0;
609 
610 again:
611  uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed);
613  if(parent == 0) {
614  // Send a bus reset on the root interface.
615  regWr(rHCTL, bmBUSRST); //issue bus reset
616  delay(102); // delay 102ms, compensate for clock inaccuracy.
617  } else {
618  // reset parent port
619  devConfig[parent]->ResetHubPort(port);
620  }
621  } else if(rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
622  delay(100);
623  retries++;
624  goto again;
625  } else if(rcode)
626  return rcode;
627 
628  rcode = devConfig[driver]->Init(parent, port, lowspeed);
629  if(rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
630  delay(100);
631  retries++;
632  goto again;
633  }
634  if(rcode) {
635  // Issue a bus reset, because the device may be in a limbo state
636  if(parent == 0) {
637  // Send a bus reset on the root interface.
638  regWr(rHCTL, bmBUSRST); //issue bus reset
639  delay(102); // delay 102ms, compensate for clock inaccuracy.
640  } else {
641  // reset parent port
642  devConfig[parent]->ResetHubPort(port);
643  }
644  }
645  return rcode;
646 }
647 
648 /*
649  * This is broken. We need to enumerate differently.
650  * It causes major problems with several devices if detected in an unexpected order.
651  *
652  *
653  * Oleg - I wouldn't do anything before the newly connected device is considered sane.
654  * i.e.(delays are not indicated for brevity):
655  * 1. reset
656  * 2. GetDevDescr();
657  * 3a. If ACK, continue with allocating address, addressing, etc.
658  * 3b. Else reset again, count resets, stop at some number (5?).
659  * 4. When max.number of resets is reached, toggle power/fail
660  * 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()
661  * it doesn't need to be reset again
662  * New steps proposal:
663  * 1: get address pool instance. exit on fail
664  * 2: pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf). exit on fail.
665  * 3: bus reset, 100ms delay
666  * 4: set address
667  * 5: pUsb->setEpInfoEntry(bAddress, 1, epInfo), exit on fail
668  * 6: while (configurations) {
669  * for(each configuration) {
670  * for (each driver) {
671  * 6a: Ask device if it likes configuration. Returns 0 on OK.
672  * If successful, the driver configured device.
673  * The driver now owns the endpoints, and takes over managing them.
674  * The following will need codes:
675  * Everything went well, instance consumed, exit with success.
676  * Instance already in use, ignore it, try next driver.
677  * Not a supported device, ignore it, try next driver.
678  * Not a supported configuration for this device, ignore it, try next driver.
679  * Could not configure device, fatal, exit with fail.
680  * }
681  * }
682  * }
683  * 7: for(each driver) {
684  * 7a: Ask device if it knows this VID/PID. Acts exactly like 6a, but using VID/PID
685  * 8: if we get here, no driver likes the device plugged in, so exit failure.
686  *
687  */
688 uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
689  //uint8_t bAddress = 0;
690  //printf("Configuring: parent = %i, port = %i\r\n", parent, port);
691  uint8_t devConfigIndex;
692  uint8_t rcode = 0;
693  uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
694  USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR *>(buf);
695  UsbDevice *p = NULL;
696  EpInfo *oldep_ptr = NULL;
697  EpInfo epInfo;
698 
699  epInfo.epAddr = 0;
700  epInfo.maxPktSize = 8;
701  epInfo.bmSndToggle = 0;
702  epInfo.bmRcvToggle = 0;
703  epInfo.bmNakPower = USB_NAK_MAX_POWER;
704 
705  //delay(2000);
706  AddressPool &addrPool = GetAddressPool();
707  // Get pointer to pseudo device with address 0 assigned
708  p = addrPool.GetUsbDevicePtr(0);
709  if(!p) {
710  //printf("Configuring error: USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL\r\n");
712  }
713 
714  // Save old pointer to EP_RECORD of address 0
715  oldep_ptr = p->epinfo;
716 
717  // Temporary assign new pointer to epInfo to p->epinfo in order to
718  // avoid toggle inconsistence
719 
720  p->epinfo = &epInfo;
721 
722  p->lowspeed = lowspeed;
723  // Get device descriptor
724  rcode = getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);
725 
726  // Restore p->epinfo
727  p->epinfo = oldep_ptr;
728 
729  if(rcode) {
730  //printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n");
731  return rcode;
732  }
733 
734  // to-do?
735  // Allocate new address according to device class
736  //bAddress = addrPool.AllocAddress(parent, false, port);
737 
738  uint16_t vid = udd->idVendor;
739  uint16_t pid = udd->idProduct;
740  uint8_t klass = udd->bDeviceClass;
741  uint8_t subklass = udd->bDeviceSubClass;
742  // Attempt to configure if VID/PID or device class matches with a driver
743  // Qualify with subclass too.
744  //
745  // VID/PID & class tests default to false for drivers not yet ported
746  // subclass defaults to true, so you don't have to define it if you don't have to.
747  //
748  for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
749  if(!devConfig[devConfigIndex]) continue; // no driver
750  if(devConfig[devConfigIndex]->GetAddress()) continue; // consumed
751  if(devConfig[devConfigIndex]->DEVSUBCLASSOK(subklass) && (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass))) {
752  rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
754  break;
755  }
756  }
757 
758  if(devConfigIndex < USB_NUMDEVICES) {
759  return rcode;
760  }
761 
762 
763  // blindly attempt to configure
764  for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
765  if(!devConfig[devConfigIndex]) continue;
766  if(devConfig[devConfigIndex]->GetAddress()) continue; // consumed
767  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
768  rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
769 
770  //printf("ERROR ENUMERATING %2.2x\r\n", rcode);
772  // in case of an error dev_index should be reset to 0
773  // in order to start from the very beginning the
774  // next time the program gets here
775  //if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE)
776  // devConfigIndex = 0;
777  return rcode;
778  }
779  }
780  // if we get here that means that the device class is not supported by any of registered classes
781  rcode = DefaultAddressing(parent, port, lowspeed);
782 
783  return rcode;
784 }
785 
786 uint8_t USB::ReleaseDevice(uint8_t addr) {
787  if(!addr)
788  return 0;
789 
790  for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
791  if(!devConfig[i]) continue;
792  if(devConfig[i]->GetAddress() == addr)
793  return devConfig[i]->Release();
794  }
795  return 0;
796 }
797 
798 #if 1
799 //get device descriptor
800 
801 uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) {
802  return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, nbytes, dataptr, NULL));
803 }
804 //get configuration descriptor
805 
806 uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) {
807  return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, nbytes, dataptr, NULL));
808 }
809 
810 /* 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
811  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 */
812 uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser *p) {
813  const uint8_t bufSize = 64;
814  uint8_t buf[bufSize];
815  USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR *>(buf);
816 
817  uint8_t ret = getConfDescr(addr, ep, 9, conf, buf);
818 
819  if(ret)
820  return ret;
821 
822  uint16_t total = ucd->wTotalLength;
823 
824  //USBTRACE2("\r\ntotal conf.size:", total);
825 
826  return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, total, bufSize, buf, p));
827 }
828 
829 //get string descriptor
830 
831 uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t ns, uint8_t index, uint16_t langid, uint8_t* dataptr) {
832  return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, ns, ns, dataptr, NULL));
833 }
834 //set address
835 
836 uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) {
837  uint8_t rcode = ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL);
838  //delay(2); //per USB 2.0 sect.9.2.6.3
839  delay(300); // Older spec says you should wait at least 200ms
840  return rcode;
841  //return ( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL));
842 }
843 //set configuration
844 
845 uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) {
846  return ( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL));
847 }
848 
849 #endif // defined(USB_METHODS_INLINE)
#define USB_NUMDEVICES
Definition: UsbCore.h:114
#define bmREQ_GET_DESCR
Definition: UsbCore.h:62
#define USB_STATE_RUNNING
Definition: UsbCore.h:133
#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL
Definition: UsbCore.h:95
#define USB_SETTLE_DELAY
Definition: UsbCore.h:112
#define USB_ERROR_INVALID_MAX_PKT_SIZE
Definition: UsbCore.h:101
#define USB_ATTACHED_SUBSTATE_WAIT_SOF
Definition: UsbCore.h:128
#define USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE
Definition: UsbCore.h:127
#define USB_STATE_MASK
Definition: UsbCore.h:119
#define USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE
Definition: UsbCore.h:123
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE
Definition: UsbCore.h:100
#define USB_ERROR_INVALID_ARGUMENT
Definition: UsbCore.h:99
#define USB_DETACHED_SUBSTATE_INITIALIZE
Definition: UsbCore.h:122
#define USB_STATE_ERROR
Definition: UsbCore.h:134
#define USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET
Definition: UsbCore.h:103
#define USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE
Definition: UsbCore.h:93
#define USB_ATTACHED_SUBSTATE_WAIT_RESET
Definition: UsbCore.h:129
#define USB_RETRY_LIMIT
Definition: UsbCore.h:111
#define USB_ATTACHED_SUBSTATE_SETTLE
Definition: UsbCore.h:125
#define USB_STATE_CONFIGURING
Definition: UsbCore.h:132
#define USB_ERROR_EP_NOT_FOUND_IN_TBL
Definition: UsbCore.h:102
#define USB_XFER_TIMEOUT
Definition: UsbCore.h:109
#define USB_ATTACHED_SUBSTATE_RESET_DEVICE
Definition: UsbCore.h:126
#define USB_ERROR_TRANSFER_TIMEOUT
Definition: UsbCore.h:107
#define USB_STATE_DETACHED
Definition: UsbCore.h:121
#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED
Definition: UsbCore.h:92
#define USB_ERROR_EPINFO_IS_NULL
Definition: UsbCore.h:98
#define bmREQ_SET
Definition: UsbCore.h:63
#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL
Definition: UsbCore.h:97
#define USB_DETACHED_SUBSTATE_ILLEGAL
Definition: UsbCore.h:124
#define USB_NAK_MAX_POWER
Definition: address.h:34
virtual UsbDevice * GetUsbDevicePtr(uint8_t addr)=0
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub=false, uint8_t port=0)
Definition: address.h:210
virtual void FreeAddress(uint8_t addr)
Definition: address.h:262
virtual UsbDevice * GetUsbDevicePtr(uint8_t addr)
Definition: address.h:188
uint8_t Task()
Definition: usbhost.h:540
uint8_t regRd(uint8_t reg)
Definition: usbhost.h:280
void regWr(uint8_t reg, uint8_t data)
Definition: usbhost.h:179
uint8_t * bytesWr(uint8_t reg, uint8_t nbytes, uint8_t *data_p)
Definition: usbhost.h:222
uint8_t getVbusState(void)
Definition: usbhost.h:154
uint8_t * bytesRd(uint8_t reg, uint8_t nbytes, uint8_t *data_p)
Definition: usbhost.h:319
virtual void ResetHubPort(uint8_t port)
Definition: UsbCore.h:159
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed)
Definition: UsbCore.h:139
virtual uint8_t Release()
Definition: UsbCore.h:147
virtual uint8_t Poll()
Definition: UsbCore.h:151
virtual uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed)
Definition: UsbCore.h:143
uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr)
defined(USB_METHODS_INLINE)
Definition: Usb.cpp:801
uint8_t getUsbTaskState(void)
Definition: Usb.cpp:36
uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value)
Definition: Usb.cpp:845
uint8_t dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit)
Definition: Usb.cpp:406
uint8_t getStrDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t index, uint16_t langid, uint8_t *dataptr)
Definition: Usb.cpp:831
uint8_t setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr)
Definition: Usb.cpp:836
EpInfo * getEpInfoEntry(uint8_t addr, uint8_t ep)
Definition: Usb.cpp:44
uint8_t DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed)
Definition: Usb.cpp:566
uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t *dataptr)
Definition: Usb.cpp:806
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
AddressPool & GetAddressPool()
Definition: UsbCore.h:228
uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo *eprecord_ptr)
Definition: Usb.cpp:64
void setUsbTaskState(uint8_t state)
Definition: Usb.cpp:40
USB(void)
Definition: Usb.cpp:25
uint8_t ReleaseDevice(uint8_t addr)
Definition: Usb.cpp:786
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 Configuring(uint8_t parent, uint8_t port, bool lowspeed)
Definition: Usb.cpp:688
void Task(void)
Definition: Usb.cpp:460
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data)
Definition: Usb.cpp:303
@ L
#define USBTRACE3(s, r, l)
Definition: macros.h:85
#define bmFRAMEIRQ
Definition: max3421e.h:152
#define tokINHS
Definition: max3421e.h:198
#define bmSOFKAENAB
Definition: max3421e.h:173
#define rSNDBC
Definition: max3421e.h:48
#define rHRSL
Definition: max3421e.h:203
#define rMODE
Definition: max3421e.h:167
#define SE0
Definition: max3421e.h:35
#define tokIN
Definition: max3421e.h:196
#define bmSNDTOG0
Definition: max3421e.h:189
#define bmSNDTOGRD
Definition: max3421e.h:207
#define rRCVFIFO
Definition: max3421e.h:44
#define SE1
Definition: max3421e.h:36
#define hrTOGERR
Definition: max3421e.h:220
#define bmRCVTOG1
Definition: max3421e.h:188
#define tokOUT
Definition: max3421e.h:197
#define rHCTL
Definition: max3421e.h:181
#define bmHXFRDNIRQ
Definition: max3421e.h:153
#define bmHUBPRE
Definition: max3421e.h:172
#define FSHOST
Definition: max3421e.h:37
#define bmLOWSPEED
Definition: max3421e.h:171
#define tokOUTHS
Definition: max3421e.h:199
#define rHIRQ
Definition: max3421e.h:144
#define LSHOST
Definition: max3421e.h:38
#define hrJERR
Definition: max3421e.h:227
#define rHXFR
Definition: max3421e.h:192
#define rSNDFIFO
Definition: max3421e.h:45
#define hrNAK
Definition: max3421e.h:218
#define hrTIMEOUT
Definition: max3421e.h:228
#define bmBUSRST
Definition: max3421e.h:183
#define rPERADDR
Definition: max3421e.h:179
#define bmRCVTOG0
Definition: max3421e.h:187
#define tokSETUP
Definition: max3421e.h:195
#define rSUDFIFO
Definition: max3421e.h:46
#define bmRCVTOGRD
Definition: max3421e.h:206
#define bmRCVDAVIRQ
Definition: max3421e.h:148
#define hrSUCCESS
Definition: max3421e.h:214
#define bmSNDTOG1
Definition: max3421e.h:190
#define rRCVBC
Definition: max3421e.h:47
Definition: address.h:39
uint8_t bmNakPower
Definition: address.h:49
uint8_t bmRcvToggle
Definition: address.h:48
uint8_t epAddr
Definition: address.h:40
uint8_t maxPktSize
Definition: address.h:41
uint8_t bmSndToggle
Definition: address.h:47
uint8_t wValueHi
Definition: UsbCore.h:196
uint16_t wLength
Definition: UsbCore.h:200
uint16_t wIndex
Definition: UsbCore.h:199
uint8_t bRequest
Definition: UsbCore.h:189
uint8_t wValueLo
Definition: UsbCore.h:195
union SETUP_PKT::@45 wVal_u
uint8_t bmRequestType
Definition: UsbCore.h:181
union SETUP_PKT::@44 ReqType_u
uint8_t devAddress
Definition: address.h:74
UsbDeviceAddress address
Definition: address.h:84
EpInfo * epinfo
Definition: address.h:83
uint8_t epcount
Definition: address.h:85
bool lowspeed
Definition: address.h:86
#define USB_REQUEST_GET_DESCRIPTOR
Definition: usb_ch9.h:44
#define USB_DESCRIPTOR_CONFIGURATION
Definition: usb_ch9.h:71
#define USB_REQUEST_SET_CONFIGURATION
Definition: usb_ch9.h:47
#define USB_DESCRIPTOR_STRING
Definition: usb_ch9.h:72
#define USB_DESCRIPTOR_DEVICE
Definition: usb_ch9.h:70
#define USB_REQUEST_SET_ADDRESS
Definition: usb_ch9.h:43