I'm currently working on porting a lot of code from our "old" systems (LPC2148, LPC2458 and LPC1778) to the brand new LPC54608. During this exercise, I had to get USB working. We use bulk transfers on 4 endpoints. One set of endpoints are used as a "request-response" pipe from a PC and the two other endpoints deliver bulk data to the PC (most debug info etc). While getting the code to work I surfed the net to see if there were some pointers as to how this should be done. It became very clear that I was not the only one with questions, most of these are due to the fact that the documentation of the USBROM that sits in many of NXPs processors is not exactly well documented.
Nevertheless, by looking at pieces of code, lots of samples and lots of experimenting I now have this working.
I thought this would be a good time to share what I have done, maybe some other could benefit from it (and NXP, you have 49 (yes, "forty nine"!) examples in the LPC54608 SDK, and not one of them shows how to do a custom class!)
Below you will find the various bits and pieces that hopefully should help you....
Now, I apologize for the formatting of the code, but the amount of work you will need to do to make it readable is far less than the time it takes to figure out how the code whould be done in the first place :smileygrin:
There might be errors or perhaps something could be done more correct etc (the code below is taken out of my test project), but see this as a starting point for you 
Endpoints (defined in app_usbd_cfg.h):
#define MAX_PACKET_SIZE 64
#define BULK_OUT_EP 0x01
#define BULK_IN_EP 0x81
#define BULK_IN_EP_TERM 0x82
#define BULK_IN_EP_LOG 0x83
Descriptors:
#include "app_usbd_cfg.h"
ALIGNED(4) const uint8_t USB_DeviceDescriptor[] = {
USB_DEVICE_DESC_SIZE,
USB_DEVICE_DESCRIPTOR_TYPE,
WBVAL(0x0200),
0x00,
0x00,
0x00,
USB_MAX_PACKET0,
WBVAL(xxxx),
WBVAL(xxxx),
WBVAL(0x0100),
0x01,
0x02,
0x03,
0x01
};
ALIGNED(4) const uint8_t USB_DeviceQualifier[] = {
USB_DEVICE_QUALI_SIZE,
USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE,
WBVAL(0x0200),
0x00,
0x00,
0x00,
USB_MAX_PACKET0,
0x01,
0x00
};
ALIGNED(4) uint8_t USB_FsConfigDescriptor[] = {
USB_CONFIGURATION_DESC_SIZE,
USB_CONFIGURATION_DESCRIPTOR_TYPE,
WBVAL(
USB_CONFIGURATION_DESC_SIZE +
USB_INTERFACE_DESC_SIZE +
4 * USB_ENDPOINT_DESC_SIZE
),
0x01,
0x01,
0x00,
USB_CONFIG_SELF_POWERED,
USB_CONFIG_POWER_MA(500),
USB_INTERFACE_DESC_SIZE,
USB_INTERFACE_DESCRIPTOR_TYPE,
0,
0,
0x04,
0xFF,
0xFF,
0x00,
0x00,
USB_ENDPOINT_DESC_SIZE,
USB_ENDPOINT_DESCRIPTOR_TYPE,
BULK_IN_EP_TERM,
USB_ENDPOINT_TYPE_BULK,
WBVAL(MAX_PACKET_SIZE),
0,
USB_ENDPOINT_DESC_SIZE,
USB_ENDPOINT_DESCRIPTOR_TYPE,
BULK_IN_EP_LOG,
USB_ENDPOINT_TYPE_BULK,
WBVAL(MAX_PACKET_SIZE),
0,
USB_ENDPOINT_DESC_SIZE,
USB_ENDPOINT_DESCRIPTOR_TYPE,
BULK_IN_EP,
USB_ENDPOINT_TYPE_BULK,
WBVAL(MAX_PACKET_SIZE),
0,
USB_ENDPOINT_DESC_SIZE,
USB_ENDPOINT_DESCRIPTOR_TYPE,
BULK_OUT_EP,
USB_ENDPOINT_TYPE_BULK,
WBVAL(MAX_PACKET_SIZE),
0,
0
};
ALIGNED(4) const uint8_t USB_StringDescriptor[] = {
0x04,
USB_STRING_DESCRIPTOR_TYPE,
WBVAL(0x0409),
(0x14),
USB_STRING_DESCRIPTOR_TYPE,
'X',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
(0x24),
USB_STRING_DESCRIPTOR_TYPE,
'X',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
' ',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
'x',0,
(0x1A),
USB_STRING_DESCRIPTOR_TYPE,
'1',0,
'2',0,
'3',0,
'4',0,
'5',0,
'6',0,
'7',0,
'8',0,
'9',0,
'A',0,
'B',0,
'C',0,
};
Handler code:
static int _HandleBulkInTerm(USBD_HANDLE_T husb, void* data, uint32_t event) {
USBD_API->hw->WriteEP(husb, BULK_IN_EP_TERM, "Hello", 5);
return LPC_OK;
}
static int _HandleBulkInLog(USBD_HANDLE_T husb, void* data, uint32_t event) {
USBD_API->hw->WriteEP(husb, BULK_IN_EP_LOG, "Hello", 5);
return LPC_OK;
}
static int _HandleBulkIn(USBD_HANDLE_T husb, void* data, uint32_t event) {
USBD_API->hw->WriteEP(husb, BULK_IN_EP, "Hello", 5);
return LPC_OK;
}
static int _HandleBulkOut(USBD_HANDLE_T husb, void* data, uint32_t event) {
if (USB_EVT_OUT == event) {
uint8_t buffer[64] = { 0 };
uint32_t length = USBD_API->hw->ReadEP(husb, BULK_OUT_EP, buffer);
}
return LPC_OK;
}
ErrorCode_t custom_init(USBD_HANDLE_T hUsb, uint8_t *pIntfDesc, USBD_API_INIT_PARAM_T *pUsbParam) {
ErrorCode_t ret = LPC_OK;
ret = USBD_API->core->RegisterEpHandler(hUsb, (((BULK_IN_EP & 0x0F) << 1) +1),_HandleBulkIn, (void*)0);
ret = USBD_API->core->RegisterEpHandler(hUsb, (((BULK_OUT_EP & 0x0F) << 1)),_HandleBulkOut, (void*)0);
ret = USBD_API->core->RegisterEpHandler(hUsb, (((BULK_IN_EP_LOG & 0x0F) << 1) +1), _HandleBulkInLog, (void*)0);
ret = USBD_API->core->RegisterEpHandler(hUsb, (((BULK_IN_EP_TERM & 0x0F) << 1) +1), _HandleBulkInTerm, (void*)0);
}
And main.c:
Chip_USB0_Init();
Chip_Clock_EnablePeriphClock(SYSCON_CLOCK_USB0_HOST_S);
*(uint32_t *)(LPC_USB0_HOST_BASE + 0x5C) |= (1 << 16);
Chip_Clock_DisablePeriphClock(SYSCON_CLOCK_USB0_HOST_S);
g_pUsbApi = (const USBD_API_T *) LPC_ROM_API->usbdApiBase;
*/
memset((void *) &usb_param, 0, sizeof(USBD_API_INIT_PARAM_T));
usb_param.usb_reg_base = LPC_USB_BASE;
usb_param.max_num_ep = 5;
usb_param.mem_base = USB_STACK_MEM_BASE;
usb_param.mem_size = USB_STACK_MEM_SIZE;
desc.device_desc = (uint8_t *) &USB_DeviceDescriptor[0];
desc.string_desc = (uint8_t *) &USB_StringDescriptor[0];
usb_param.high_speed_capable = FALSE;
desc.high_speed_desc = USB_FsConfigDescriptor;
desc.full_speed_desc = USB_FsConfigDescriptor;
desc.device_qualifier = 0;
ret = USBD_API->hw->Init(&g_hUsb, &desc, &usb_param);
if (ret == LPC_OK) {
ret = custom_init(g_hUsb, (uint8_t*)&USB_FsConfigDescriptor[sizeof(USB_CONFIGURATION_DESCRIPTOR)],&usb_param);
if (ret == LPC_OK) {
NVIC_EnableIRQ(USB_IRQn);
USBD_API->hw->Connect(g_hUsb, 1);
}
LPC_USB0->DEVCMDSTAT |= (1<<12) | (1<<13);
}