1. Introduction 1 2. USB Demo based on MCUXpresso SDK 1 2.1 Update USB device demo: USB0->USB1 2 2.2 Update USB host demo: USB0->USB1 2 2.3 Update USB ROM demo: USB0-> USB1 3 3. USB Demo based on LPCOpen 3 4. Notes and Recap 4
Most of LPC devices integrate USB module. NXP LPC currently integrates full-speed USB (FS, Full Speed, 12Mbps) and high-speed (HS, High Speed, 480Mbps) USB.
Specifically, for the LPC series:
- Some LPCs such as LPC55xx and LPC54xxx integrate both HS USB and FS USB. Usually USB0 is FS USB and USB1 is HS USB.
- Some LPCs such as LPC43xx and LPC18xx integrate two HS USBs, so USB0 and USB1 are both HS USBs.
The two most well-known NXP software packages for LPC series are MCUXpresso SDK and LPCOpen. MCUXpresso SDK is mainly for LPC products launched in recent years, while LPCOpen is used for earlier LPC derivatives. The USB demos included in these two packages run on USB0 by default.
Most of NXP USB demos are for USB0 by default. This article is to introduce how to switch a USB0 demo to USB1 demo based on different software packages.
2. USB Demo based on MCUXpresso SDK
(e.g. LPC54XXX, LPC55XX)
The MCUXpresso SDK USB demo codes are categorized as:
- USB as Device: e.g. usb_device_cdc_vcom, usb_device_hid_generic, etc.
- USB as Host: e.g. usb_host_hid_mouse, usb_host_msd_fatfs, etc.
- USB demo based on USB ROM API: e.g. usb_rom_device_audio,usb_rom_device_cdc, etc.
2.1 Update USB device demo: USB0->USB1
Taking usb_device_cdc_vcom demo as an example. To switch to USB1, simply change the corresponding code in usb_device_config.h file as follows.
/*! @brief LPC USB IP3511 FS instance count*/
#define USB_DEVICE_CONFIG_LPCIP3511FS (0U)
/*! @brief LPC USB IP3511 HS instance count*/
#define USB_DEVICE_CONFIG_LPCIP3511HS (1U)
After the change, recompile the program to run. The program was updated to USB1 device demo.
2.2 Update USB host demo: USB0->USB1
Taking usb_host_hid_mouse demo code as an example, to switch to USB1, modify the macro definition in usb_host_config.h as follows:
#define USB_HOST_CONFIG_OHCI (0U)
#define USB_HOST_CONFIG_IP3516HS (1U)
The program is recompiled and run. The program was updated to USB1 host demo.
2.3 Update USB ROM demo: USB0-> USB1
( e.g. LPC54XXX Series)
USB ROM demo calls the USB ROM API, there is no way to switch the default USB0 to USB1 by modifying macro definitions. In order to update code to USB1 demo, the recommended steps are as below:
-USB HS DEVICE and USB PHY clock configuration
-Change to use USB HS ISR
-Locate the related buffer into USB RAM.
-Set the USB ROM handle to be HS
If user has difficulties in revising the code by self, user can apply demo code from NXP LPC online support team by creating a private case.
3. USB Demo based on LPCOpen
(e.g. LPC43XX, LPC18XX)
Some legacy LPCs run on LPCOpen, such as LPC43xx series, LPC18xx series. Their USB0 and USB1 are both high-speed. The default USB demo is for USB0 as well. To switch to USB1, we can uncomment #define USE_USB1 and comment #define USE_USB0 in app_usbd_cfg.h.
// #define USE_USB0
Taking usbd_rom_cdc_uart demo as an example:
Recompile and run, the program is updated to USB1 demo.
4. Notes and Recap
The focus of this article is on software modification of converting USB0 to USB1 on NXP SW package. Regarding the hardware, customer needs to check the specific demo board user guide. For example, when we use HS USB, it may be necessary to provide an external power supply, and the jumper also needs to be adjusted to build a well hardware environment for HS USB operation. I will not dwell on them here.
This article summarizes methods of switching USB0 to USB1 for several commonly used LPC series on MCUXpresso SDK and LPCOpen package. customers who need USB1 demo code can find the corresponding modification methods in this article for their own software and chips. Official routines are only used for demo board demos and chip learning. If for commercial usage, user needs to learn USB in depth and be responsible for own application.
New update to errata will be published regarding the vendor_usage field in the PFR. In ROM, the 16-bit monotonic counter is implemented in the upper 16 bits of the 32-bit VENDOR_USAGE field and the inverse of the monotonic counter is in the lower 16 bits. Users must take care when using the ROM API to increment the upper end of this field and write the inverse on the lower 16 bits in order for ROM to validate the value correctly.
The initial value that shall be written is 0x0000FFFF. Then the updates will be as follows: 0x0001FFFE 0x0002FFFD . . 0x0005FFFA . . 0x1010EFEF . . 0xFFFF0000
Example Code using ROM API:
*This example demonstrates the increment of the version in CFPA page as well as the vendor usage, it does not cover all use cases, so please use this as a reference only*
PRINTF("Disable Flash Protect...\r\n");
/* Initialize flash driver */
if (FFR_Init(&flashInstance) == kStatus_Success)
PRINTF("Flash init successfull!!. Halting...\r\n");
status = FFR_GetCustomerInfieldData(&flashInstance, (uint8_t *)g_CFPAData, 0x0, FLASH_FFR_MAX_PAGE_SIZE);
PRINTF("Header 0x%08x , Version 0x%08x , SecureFW Version 0x%08x , NonSecureFW Version 0x%08x\r\n", g_CFPAData, g_CFPAData, g_CFPAData, g_CFPAData);
PRINTF("ImageKey Revoke 0x%08x , Reserved 0x%08x , RothRevoke 0x%08x , Vendor Usage 0x%08x\r\n", g_CFPAData, g_CFPAData, g_CFPAData, g_CFPAData);
PRINTF("NS PIN 0x%08x , NS DFLT 0x%08x , Enable FA Mode 0x%08x , Reserved1 0x%08x\r\n", g_CFPAData, g_CFPAData, g_CFPAData, g_CFPAData);
/* Clean-up CFPA area */
g_CFPAData = 0;
g_CFPAData = 0;
/*Increase Monotonic counter*/
p32 = (uint32_t *)(uint32_t)g_CFPAData;
version = p32;
if (version == 0xFFFFFFFFu)
p32 = version;
PRINTF("Version to write: 0x%08x \r\n", version);
/*Increase Vendor Usage*/
uint32_t vendor_usage = p32;
if(vendor_usage == 0x0)
vendorUsage_right = 0xFFFF;
vendorUsage_left = 0x0000;
vendorUsage_right = vendor_usage & 0xFFFF;
vendorUsage_left = vendor_usage >> 16;
vendorUsage_left += 0x1;
vendorUsage_right -= 0x1;
vendor_usage = (vendorUsage_left << 16) | vendorUsage_right;
p32 = vendor_usage;
PRINTF("Vendor_Usage to write: 0x%08x \r\n", vendor_usage);
Status = FFR_InfieldPageWrite(&flashInstance, (uint8_t *)g_CFPAData, FLASH_FFR_MAX_PAGE_SIZE);
if (kStatus_FLASH_Success == Status)
status = kStatus_Success;
PRINTF("CFPA Write Done!\r\n");
status = kStatus_Fail;