/* USB main task. Performs enumeration/cleanup */ void USB::Task( void ) //USB state machine { byte i; byte rcode; static byte tmpaddr; byte tmpdata; static unsigned long delay = 0; USB_DEVICE_DESCRIPTOR buf; tmpdata = getVbusState(); /* modify USB task state if Vbus changed */ switch( tmpdata ) { case SE1: //illegal state usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL; break; case SE0: //disconnected if(( usb_task_state & USB_STATE_MASK ) != USB_STATE_DETACHED ) { usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; } break; case FSHOST: //attached case LSHOST: if(( usb_task_state & USB_STATE_MASK ) == USB_STATE_DETACHED ) { delay = millis() + USB_SETTLE_DELAY; usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE; } break; }// switch( tmpdata //Serial.print("USB task state: "); //Serial.println( usb_task_state, HEX ); switch( usb_task_state ) { case USB_DETACHED_SUBSTATE_INITIALIZE: init(); usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE; break; case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here break; case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here break; case USB_ATTACHED_SUBSTATE_SETTLE: //setlle time for just attached device if( delay < millis() ) { usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE; } break; case USB_ATTACHED_SUBSTATE_RESET_DEVICE: regWr( rHCTL, bmBUSRST ); //issue bus reset usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE; break; case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE: if(( regRd( rHCTL ) & bmBUSRST ) == 0 ) { tmpdata = regRd( rMODE ) | bmSOFKAENAB; //start SOF generation regWr( rMODE, tmpdata ); // regWr( rMODE, bmSOFKAENAB ); usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF; delay = millis() + 20; //20ms wait after reset per USB spec } break; case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order if( regRd( rHIRQ ) & bmFRAMEIRQ ) { //when first SOF received we can continue if( delay < millis() ) { //20ms passed usb_task_state = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE; } } break; case USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE: // toggle( BPNT_0 ); devtable[ 0 ].epinfo->MaxPktSize = 8; //set max.packet size to min.allowed rcode = getDevDescr( 0, 0, 8, ( char* )&buf ); if( rcode == 0 ) { devtable[ 0 ].epinfo->MaxPktSize = buf.bMaxPacketSize0; usb_task_state = USB_STATE_ADDRESSING; } else { usb_error = USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE; usb_task_state = USB_STATE_ERROR; } break; case USB_STATE_ADDRESSING: for( i = 1; i < USB_NUMDEVICES; i++ ) { if( devtable[ i ].epinfo == NULL ) { devtable[ i ].epinfo = devtable[ 0 ].epinfo; //set correct MaxPktSize //temporary record //until plugged with real device endpoint structure rcode = setAddr( 0, 0, i ); if( rcode == 0 ) { tmpaddr = i; usb_task_state = USB_STATE_CONFIGURING; } else { usb_error = USB_STATE_ADDRESSING; //set address error usb_task_state = USB_STATE_ERROR; } break; //break if address assigned or error occured during address assignment attempt } }//for( i = 1; i < USB_NUMDEVICES; i++ if( usb_task_state == USB_STATE_ADDRESSING ) { //no vacant place in devtable usb_error = 0xfe; usb_task_state = USB_STATE_ERROR; } break; case USB_STATE_CONFIGURING: break; case USB_STATE_RUNNING: break; case USB_STATE_ERROR: break; }// switch( usb_task_state }
/* USB main task. Performs enumeration/cleanup */ void USB::Task(void) //USB state machine { uint8_t rcode; uint8_t tmpdata; static unsigned long delay = 0; //USB_DEVICE_DESCRIPTOR buf; bool lowspeed = false; MAX3421E::Task(); tmpdata = getVbusState(); /* modify USB task state if Vbus changed */ switch(tmpdata) { case SE1: //illegal state usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL; lowspeed = false; break; case SE0: //disconnected if((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED) usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; lowspeed = false; break; case LSHOST: lowspeed = true; //intentional fallthrough case FSHOST: //attached if((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) { delay = millis() + USB_SETTLE_DELAY; usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE; } break; }// switch( tmpdata for(uint8_t i = 0; i < USB_NUMDEVICES; i++) if(devConfig[i]) rcode = devConfig[i]->Poll(); switch(usb_task_state) { case USB_DETACHED_SUBSTATE_INITIALIZE: init(); for(uint8_t i = 0; i < USB_NUMDEVICES; i++) if(devConfig[i]) rcode = devConfig[i]->Release(); usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE; break; case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here break; case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here break; case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device if(delay < millis()) usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE; else break; // don't fall through case USB_ATTACHED_SUBSTATE_RESET_DEVICE: regWr(rHCTL, bmBUSRST); //issue bus reset usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE; break; case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE: if((regRd(rHCTL) & bmBUSRST) == 0) { tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation regWr(rMODE, tmpdata); usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF; //delay = millis() + 20; //20ms wait after reset per USB spec } break; case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order if(regRd(rHIRQ) & bmFRAMEIRQ) { //when first SOF received _and_ 20ms has passed we can continue /* if (delay < millis()) //20ms passed usb_task_state = USB_STATE_CONFIGURING; */ usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET; delay = millis() + 20; } break; case USB_ATTACHED_SUBSTATE_WAIT_RESET: if(delay < millis()) usb_task_state = USB_STATE_CONFIGURING; else break; // don't fall through case USB_STATE_CONFIGURING: //Serial.print("\r\nConf.LS: "); //Serial.println(lowspeed, HEX); rcode = Configuring(0, 0, lowspeed); if(rcode) { if(rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) { usb_error = rcode; usb_task_state = USB_STATE_ERROR; } } else usb_task_state = USB_STATE_RUNNING; break; case USB_STATE_RUNNING: break; case USB_STATE_ERROR: //MAX3421E::Init(); break; } // switch( usb_task_state ) }
/* USB main task. Performs enumeration/cleanup */ void USB::Task(USB_OTG_CORE_HANDLE *pdev) //USB state machine { uint8_t rcode; uint8_t tmpdata; static unsigned long delay = 0; bool lowspeed = false; STM32F2::Task(); tmpdata = getVbusState(); /* modify USB task state if Vbus changed */ switch (tmpdata) { case SE1: //illegal state usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL; lowspeed = false; break; case SE0: //disconnected if ((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED) usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; lowspeed = false; break; case LSHOST: // if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) { lowspeed = true; // } case FSHOST: //attached if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) { delay = millis() + USB_SETTLE_DELAY; usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE; STM_EVAL_LEDToggle(LED1); } break; }// switch( tmpdata for (uint8_t i = 0; i < USB_NUMDEVICES; i++) if (devConfig[i]) rcode = devConfig[i]->Poll(); switch (usb_task_state) { case USB_DETACHED_SUBSTATE_INITIALIZE: init(); for (uint8_t i = 0; i < USB_NUMDEVICES; i++) if (devConfig[i]) rcode = devConfig[i]->Release(); usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE; break; case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here break; case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here break; case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device if (delay < millis()) usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE; break; case USB_ATTACHED_SUBSTATE_RESET_DEVICE: STM_EVAL_LEDToggle(LED1); //regWr(rHCTL, bmBUSRST); //issue bus reset // what if i want to reset the specified device? (need to survey usb hub feature later) pdev->host.SofHits = 0; HCD_ResetPort(); //usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE; // the HCD_ResetPort() function will take care of a complete bus reset. so skip next phase. usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF; break; /* case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE: if ((regRd(rHCTL) & bmBUSRST) == 0) { tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation regWr(rMODE, tmpdata); usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF; //delay = millis() + 20; //20ms wait after reset per USB spec } break;*/ case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order if(pdev->host.port_need_reset) { usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE; pdev->host.port_need_reset = 0; printf("\nLS Dev, reset again"); break; } STM_EVAL_LEDToggle(LED1); //if (regRd(rHIRQ) & bmFRAMEIRQ) { if(pdev->host.SofHits) { //when first SOF received _and_ 20ms has passed we can continue usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET; delay = millis() + 20; } break; case USB_ATTACHED_SUBSTATE_WAIT_RESET: if (delay < millis()) { usb_task_state = USB_STATE_CONFIGURING; } break; case USB_STATE_CONFIGURING: STM_EVAL_LEDToggle(LED1); //Serial.print("\r\nConf.LS: "); //Serial.println(lowspeed, HEX); printf("\nTODO:Support all 8 USB pipe?"); rcode = Configuring(0, 0, lowspeed); if (rcode) { if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) { usb_error = rcode; usb_task_state = USB_STATE_ERROR; } } else usb_task_state = USB_STATE_RUNNING; break; case USB_STATE_RUNNING: break; case USB_STATE_ERROR: //MAX3421E::Init(); AddressPool &addrPool = GetAddressPool(); // Get pointer to pseudo device with address 0 assigned UsbDevice *p = addrPool.GetUsbDevicePtr(0); USBH_Free_Channel(pdev, p->epinfo->hcNumOut); USBH_Free_Channel(pdev, p->epinfo->hcNumIn); break; } // switch( usb_task_state ) }