Author Topic: un-enumerate USB Device loader?  (Read 1532 times)

Offline jackking

  • Newbie
  • *
  • Posts: 34
    • View Profile
un-enumerate USB Device loader?
« on: February 27, 2024, 04:49:01 PM »
I would like to un-enumerate (disconnect) the uTasker USB device after a successful upload of a firmware file.  Is there a way to create a function opposite of the
Code: [Select]
fnConfigureUSB(void) function to call before suspending the task?

thanks
JK

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: un-enumerate USB Device loader?
« Reply #1 on: February 28, 2024, 05:46:15 PM »
Hi

I understand that your serial loader is the device: After uploading a new file the loader will usually perform a SW reset in order to continue and this also causes the device to be disconnected.

As far as I can tell there is no de-installation method that disconnects a device itself but looking at the low level de-installation after a USB reset (in the HW USB interrupt _usb_hs_otg_isr_common()):

        if ((ulInterrupts & USBHS_USBINTR_URE) != 0) {                   // handle USB reset interrupt
            fnDeInitEndpoints(ptrHSUSB, Channel);                        // abort any active endpoints and free transfer buffers
            ptrHSUSB->EPCR0 = (USBHS_EPCR_RXE | USBHS_EPCR_RXR | USBHS_EPCR_TXE | USBHS_EPCR_TXR); // reset data toggle (synchronise) on endpoint 0
            ptrHSUSB->EPSETUPSR = ptrHSUSB->EPSETUPSR;                   // clear all setup token semaphores by reading the EPSETUSR register and writing the same value back
            ptrHSUSB->EPCOMPLETE = ptrHSUSB->EPCOMPLETE;                 // clear all the endpoint complete status bits by reading the EPCOMPLETE register and writing the same value back
#if defined _WINDOWS
            ptrHSUSB->EPSETUPSR = 0;
            ptrHSUSB->EPCOMPLETE = 0;
            ptrHSUSB->USBSTS = USBHS_USBSTS_PCI;                         // usually a port change interrupt follows a reset
#endif
            if ((ptrHSUSB->PORTSC1 & USBHS_PORTSC1_PR) == 0) {           // if we are too slow responding the port reset will have completed
                ptrHSUSB->USBCMD &= ~(USBHS_USBCMD_RS);                  // ensure not in run mode
                ptrHSUSB->USBCMD = USBHS_USBCMD_RST;                     // command a hardware reset
                fnUSBHS_init(((ptrHSUSB->PORTSC1 & USBHS_PORTSC1_PFSC) == 0), (QUEUE_LIMIT)Channel, ucHS_EndpointCount[Channel]); // re-initialise the controller
                ucUSBHS_state[Channel] = 0;
            }
            else {
                ucUSBHS_state[Channel] = USBHS_STATE_RESETTING;          // the ulpi is still detecting the reset state
            }
            ptrHSUSB->USBINTR &= ~(USBHS_USBINTR_SLE);                   // disable the suspend interrupt
            ptrHSUSB->PERIODICLISTBASE_DEVICEADDR = 0;                   // reset device address
            uDisable_Interrupt();                                        // ensure interrupts remain blocked when putting messages to queue
                fnUSB_handle_frame(USB_RESET_DETECTED, 0, 0, &hs_usb_hardware[Channel]); // generic handler routine
                hs_usb_hardware[Channel].ucUSBAddress = 0;               // reset the address to revert back to the default state
            uEnable_Interrupt();                                         // re-enable interrupts
        }


I suspect that it may be necessary to either provoke such a reset or else disable the USB (eg via  USB controller reset) and execute the same, or part of this.


Could you describe exactly the goal and also how it would best be tested?

Regards

Mark


Offline jackking

  • Newbie
  • *
  • Posts: 34
    • View Profile
Re: un-enumerate USB Device loader?
« Reply #2 on: February 28, 2024, 08:10:29 PM »
Thanks, I will give that a shot.  I changed the loader to not automatically reset when the file is copied and verified via USB-MSD-DEVICE. 

I just want the USB to un-enumerate after the file copy so the drive disappears.  Then the user can either "try again" and reenumerate, or the update continues and then the user is prompted to reset (boot the application) when they choose.

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: un-enumerate USB Device loader?
« Reply #3 on: March 08, 2024, 11:38:41 PM »
John

I think I have found a simple way to command disconnecting the USB device (and, if required, reconnecting it again.

USBHS0_USBCMD ^= USBHS_USBCMD_RS;

When USBHS_USBCMD_RS is set to 0 (stop mode) it removes its D+ pull-up and so is no longer detected by the host.
When it is set again it reconnects the D+ pull-up and goes to run mode again (and the host detects it and re-enumerates it).

I added this interface so that the registers don't need to be accessed directly (portable):

    fnConfigUSB(USB_DEVICE_REF, 0); // when the parameter is 0 it toggles the RUN mode in order to disconnect/reconnect

but it may not be the best method, so experimental at the moment.
You may be able to prove the suitability for your need by directly controlling it in the register.

Regards

Mark

Offline jackking

  • Newbie
  • *
  • Posts: 34
    • View Profile
Re: un-enumerate USB Device loader?
« Reply #4 on: March 09, 2024, 11:17:07 PM »
I just tried this approach and it works well.  Thanks!


Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: un-enumerate USB Device loader?
« Reply #5 on: March 10, 2024, 04:39:14 PM »
 :)