We're running a custom board with a K64 and the KSDK 2 USB stack. The system is running a custom bootloader which initializes a virtual com over USB CDC to a windows PC. The bootloader then launches an application which also uses a virtual com over USB CDC. Both the bootloader and app use the KSDK USB stack. The issue we see is as follows:
1. Start bootloader: The windows PC sees the virtual com and enumerates it properly and we can communicate over it.
2. Pre-application launch: The bootloader de-initializes the USB com (see code below). The com port disappears from Windows.
3. Bootloader launches application: The bootloader launches the application. The application code re-initializes the virtual com. In Windows, however; we get "Unknown USB Device (Device Descriptor Request Failed" with Code 43. We can plug/unplug the USB port at this point and it still doesn't enumerate properly.
To verify the application code is working properly we also tested a version of the bootloader which does not initialize the USB com. The bootloader comes up, performs no USB functionality, and then launches the application. In this case Windows properly enumerates the USB com and we can talk with the application.
The issue only appears when both the bootloader and application initialize the USB com. Initially we didn't have the bootloader de-init the com before jumping, and then added in the de-init hoping that would fix the issue but it hasn't. Searching the forums it seems there are known issues with re-connecting/disconnecting USB coms on these devices with little resolution. Has anyone encountered a similar issue?
This is the code which de-inits the com before application launch:
void VCOM_DeInit(void)
{
uint8_t irqNo;
uint8_t khciIrq[] = USB_IRQS;
irqNo = khciIrq[CONTROLLER_ID - kUSB_ControllerKhci0];
USB_DeviceSetDefaultState(s_cdcVcom.deviceHandle);
USB_DeviceStop(s_cdcVcom.deviceHandle);
USB_DeviceClassDeinit(CONTROLLER_ID);
HAL_CpuIrqUnregister(irqNo);
DisableIRQ((IRQn_Type)irqNo);
}
Hi Benjamin
There are various USB loaders that jump to a USB application so I don't know of any real problems. However, here is the de-init when jumping from the uTasker serial loader (when USB loading was enabled) as reference. It is mainly needed to ensure no pending, but disabled, interrupts aren't hanging around to surprise the new USB driver initialisation - but note that the USB regulator should not be powered down.
SYSTICK_CSR = 0;
POWER_DOWN(4, (SIM_SCGC4_UART0 | SIM_SCGC4_UART1 | SIM_SCGC4_UART2 | SIM_SCGC4_UART3 | SIM_SCGC4_USBOTG));
POWER_DOWN(1, (SIM_SCGC1_UART4 | SIM_SCGC1_UART5));
POWER_DOWN_ATOMIC(2, ENET);
POWER_DOWN(3, (SIM_SCGC3_SDHC | SIM_SCGC3_USBHS | SIM_SCGC3_USBHSPHY));
SIM_SOPT1_CLR(SIM_SOPT1_USBREGEN, SIM_SOPT1CFG_URWE);
IRQ0_31_CER = 0xffffffff;
IRQ32_63_CER = 0xffffffff;
IRQ64_95_CER = 0xffffffff;
IRQ0_31_CPR = 0xffffffff;
IRQ32_63_CPR = 0xffffffff;
IRQ64_95_CPR = 0xffffffff;
Regards
Mark
Kinetis: http://www.utasker.com/kinetis.html
Kinetis K64:
- http://www.utasker.com/kinetis/FRDM-K64F.html
- http://www.utasker.com/kinetis/TWR-K64F120M.html
- http://www.utasker.com/kinetis/TEENSY_3.5.html
- http://www.utasker.com/kinetis/Hexiwear-K64F.html
Serial Loader: http://www.utasker.com/docs/uTasker/uTaskerSerialLoader.pdf
P.S. If you have difficulties which can't be solved by de-initing you can command a SW reset instead.
You just need to save a pattern to (unused) SRAM or free registers that retain their value across resets, then get the boot loader to check it and if it matches, plus the last reset was a commanded reset, it can immediately jump to the application without touching the USB.
See the appendix of the uTasker Serial Loader Manual for a description of this process.