Hi, I have a question about USB HS enumeration on LPC54605J512 MCU.
I need to change the polling rate of the USB device in runtime. In order to do that I need to force the host to re-enumerate the device. I have tried to call USB_DeviceStop() and USB_DeviceRun() right after, but most of the time device fails to enumerate. Reboot MCU and start with a new configuration is not an option for my particular case.
Is there any way to do that with USB stack functions or maybe manual registers settings?
Solved! Go to Solution.
Solved this problem by adding a custom notification and device event.
Add a case kUSB_DeviceNotifyRestart in USB_DeviceNotification and call
Eventually, USB_DeviceCallback gets called with event param kUSB_DeviceEventRestart from USB task context.
This code is not breaking the internal queue of the driver.
Re enumeration worked fine after that.
Solved this problem by adding a custom notification and device event.
Add a case kUSB_DeviceNotifyRestart in USB_DeviceNotification and call
Eventually, USB_DeviceCallback gets called with event param kUSB_DeviceEventRestart from USB task context.
This code is not breaking the internal queue of the driver.
Re enumeration worked fine after that.
The call to NVIC_ClearPendingIRQ(USB1_IRQn); is invalid after the call to USB_DeviceClassInit() because you are messing up with lpcip3511.c workflow at that point.
And what's really strange that usb_echo("usbReEnumerate\r\n"); line fixes this issue. I can't explain this phenomenon.
I ran this code on a non-RTOS example and it works fine. I also tried not to call NVIC_ClearPendingIRQ(USB1_IRQn); in the RTOS example but the behavior didn't change.
What I do to re-enumerate w/o MCU reset (USB0 or USB1):
To bring the stack up:
a)call USB_DeviceInit()
b)enable USB's IRQ
c)call USB_DeviceRun()
to bring the stack down:
a)call USB_DeviceStop()
b)disable USB's IRQ
c)call USB_DeviceDeinit()
Hi, thanks for your suggestion and sorry for the late response.
I figured out that this method is working well on non-RTOS examples. But unfortunately, it doesn't with the FreeRTOS example. If I call usbReEnumerate() from other contexts, such as the timer task, the USB fails to enumerate. And I'm struggling to answer why that happening. I used lpcxpresso54628_dev_hid_mouse_freertos project with minor modifications as an experimental ground.
#define USB_DEVICE_CONFIG_LPCIP3511HS (1U)
#define USB_DEVICE_CONFIG_USE_TASK (1U)
#define USB_DEVICE_CONFIG_COMPLIANCE_TEST (1U)
#define USB_DEVICE_CONFIG_DETACH_ENABLE (1U)
In mouse.c I have added // TEST_CODE comment in places where example was modified. Basically I created a one shot 1 sec software timer, starting it after usb got configured and call usbReEnumerate() in timer callback. Modified files are in attachment.
static void usbReEnumerate(TimerHandle_t xTimer) // TEST_CODE
{
(void) xTimer;
usb_status_t res = kStatus_USB_Success;
// usb_echo("usbReEnumerate\r\n");
if (g_UsbDeviceHidMouse.attach) {
USB_DeviceStop(g_UsbDeviceHidMouse.deviceHandle); // always returns kStatus_USB_Error
g_UsbDeviceHidMouse.attach = 0; // allows ignoring suspend event after re-enable.
NVIC_DisableIRQ(USB1_IRQn);
usb_status_t res = USB_DeviceClassDeinit(CONTROLLER_ID);
// usb_status_t res = USB_DeviceDeinit(g_UsbDeviceHidMouse.deviceHandle);
// res |= USB_DeviceInit(CONTROLLER_ID, USB_DeviceCallback, &g_UsbDeviceHidMouse.deviceHandle);
res |= USB_DeviceClassInit(CONTROLLER_ID, &g_UsbDeviceHidConfigList, &g_UsbDeviceHidMouse.deviceHandle);
NVIC_ClearPendingIRQ(USB1_IRQn);
NVIC_EnableIRQ(USB1_IRQn);
USB_DeviceRun(g_UsbDeviceHidMouse.deviceHandle); // always returns kStatus_USB_Error
}
assert(kStatus_USB_Success == res);
}
I also tried to use directly USB_DeviceInit() and USB_DeviceDeinit() but that didn't work also. USB_DeviceClassInit and USB_DeviceClassDeinit eventually call those functions so I think it's not a big deal here. Strange thing happens if uncomment // usb_echo("usbReEnumerate\r\n"); After that usb re-enumerates succesfully. And that's confusing.