Ejemplo n.º 1
0
/* 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
}
Ejemplo n.º 2
0
/* 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 )
}
Ejemplo n.º 3
0
/* 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 )
}