µTasker Forum
µTasker Forum => NXPTM M522XX, KINETIS and i.MX RT => Topic started by: jackking 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
fnConfigureUSB(void)
function to call before suspending the task?
thanks
JK
-
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
-
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.
-
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
-
I just tried this approach and it works well. Thanks!
-
:)