Composite CDC+MSC, not working

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Composite CDC+MSC, not working

1,840 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by riscy00 on Mon Nov 30 08:41:09 MST 2015
(1) I have working code for CDC with VCOM and working code for MSC (8K RAM) which based on demo code from LPC11Uxx

(2)  I have read the AN11232 app note for which I setup the descriptor. I looked into demo code LPC1343 which has CDC+MSC descriptor.

(3) Below is the descriptor for CDC+MSC, very similar to LPC1343

(4) I discovered the code in LPC1343 is not ROM based and it very different to ROM USB in LPC11U and LPC1549 (that I used).

//
//===========================================================================USB Standard Device Descriptor
//
ALIGNED(4) const uint8_t USB_DeviceDescriptor[] = {
USB_DEVICE_DESC_SIZE,// bLength //
USB_DEVICE_DESCRIPTOR_TYPE,// bDescriptorType //
WBVAL(0x0200),// bcdUSB = USB 2.00//
USB_DEVICE_CLASS_MISCELLANEOUS,// bDeviceClass //
0x02,// bDeviceSubClass //
0x01,// bDeviceProtocol //
USB_MAX_PACKET0,// bMaxPacketSize0 //
WBVAL(0x1FC9),// idVendor //
WBVAL(0x0083),// idProduct //
WBVAL(0x0100),// bcdDevice //
0x01,// iManufacturer //
0x02,// iProduct //
0x03,// iSerialNumber //
0x01// bNumConfigurations //
};

//
// ===========================================================================USB FSConfiguration Descriptor
//  All Descriptors (Configuration, Interface, Endpoint, Class, Vendor)
//
ALIGNED(4) uint8_t USB_FsConfigDescriptor[] = {
// Configuration 1 //
USB_CONFIGURATION_DESC_SIZE,// bLength //
USB_CONFIGURATION_DESCRIPTOR_TYPE,// bDescriptorType //
WBVAL(// wTotalLength //
1 * USB_CONFIGURATION_DESC_SIZE     +
//-------------------------------------MSC Class
1 * USB_INTERFACE_DESC_SIZE         +// MSC interface //
2 * USB_ENDPOINT_DESC_SIZE      +// bulk endpoints //
//-------------------------------------CDC Class
1 * USB_INTERFACE_ASSOC_DESC_SIZE   +// interface association descriptor //
1 * USB_INTERFACE_DESC_SIZE         +// communication control interface //
0x0013                          +// CDC functions //
1 * USB_ENDPOINT_DESC_SIZE      +// interrupt endpoint //
1 * USB_INTERFACE_DESC_SIZE         +// communication data interface //
2 * USB_ENDPOINT_DESC_SIZE      +// bulk endpoints //
0
),
0x03,// bNumInterfaces //
0x01,// bConfigurationValue //
0x00,// iConfiguration //
USB_CONFIG_BUS_POWERED,// bmAttributes  //Power from USB.
USB_CONFIG_POWER_MA(500),// bMaxPower //

//==============================================================
//-------------------------------------Interface 0, Alternate Setting 0, MSC class interface descriptor //
USB_INTERFACE_DESC_SIZE,// bLength //
USB_INTERFACE_DESCRIPTOR_TYPE,// bDescriptorType //
USB_MSC_IF_NUM,// bInterfaceNumber: Number of Interface //
0x00,// bAlternateSetting: Alternate setting //
0x02,// bNumEndpoints: One endpoint used //
USB_DEVICE_CLASS_STORAGE,// bInterfaceClass: Communication Interface Class //
MSC_SUBCLASS_SCSI,// bInterfaceSubClass: Abstract Control Model //
MSC_PROTOCOL_BULK_ONLY,// bInterfaceProtocol: no protocol used //
0x04,// iInterface: //
//----------------------------------Endpoint, EP Bulk In //
USB_ENDPOINT_DESC_SIZE,// bLength //
USB_ENDPOINT_DESCRIPTOR_TYPE,// bDescriptorType //
//USB_ENDPOINT_IN(2),// bEndpointAddress //  LPC134x method.
USB_MSC_IN_EP,// bEndpointAddress //
USB_ENDPOINT_TYPE_BULK,// bmAttributes //
WBVAL(USB_FS_MAX_BULK_PACKET),// wMaxPacketSize //
0x00,// bInterval: ignore for Bulk transfer //
//----------------------------------Endpoint, EP Bulk Out //
USB_ENDPOINT_DESC_SIZE,// bLength //
USB_ENDPOINT_DESCRIPTOR_TYPE,// bDescriptorType //
//USB_ENDPOINT_OUT(2),// bEndpointAddress //  LPC134x method.
USB_MSC_OUT_EP,// bEndpointAddress //
USB_ENDPOINT_TYPE_BULK,// bmAttributes //
WBVAL(USB_FS_MAX_BULK_PACKET),// wMaxPacketSize //
0x00,// bInterval: ignore for Bulk transfer //

//==============================================================

//-------------------------------------Interface association descriptor IAD//
USB_INTERFACE_ASSOC_DESC_SIZE,// bLength //
USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE,// bDescriptorType //
USB_CDC_CIF_NUM,// bFirstInterface //
0x02,// bInterfaceCount //
CDC_COMMUNICATION_INTERFACE_CLASS,// bFunctionClass //
CDC_ABSTRACT_CONTROL_MODEL,// bFunctionSubClass //
0x00,// bFunctionProtocol //
0x06,// iFunction //

//==============================================================

//-------------------------------------Interface 0, Alternate Setting 0, Communication class interface descriptor //
USB_INTERFACE_DESC_SIZE,// bLength //
USB_INTERFACE_DESCRIPTOR_TYPE,// bDescriptorType //
USB_CDC_CIF_NUM,// bInterfaceNumber: Number of Interface //
0x00,// bAlternateSetting: Alternate setting //
0x01,// bNumEndpoints: One endpoint used //
CDC_COMMUNICATION_INTERFACE_CLASS,// bInterfaceClass: Communication Interface Class //
CDC_ABSTRACT_CONTROL_MODEL,// bInterfaceSubClass: Abstract Control Model //
0x00,// bInterfaceProtocol: no protocol used //
0x05,// iInterface: //

// Header Functional Descriptor//
0x05,// bLength: CDC header Descriptor size //
CDC_CS_INTERFACE,// bDescriptorType: CS_INTERFACE //
CDC_HEADER,// bDescriptorSubtype: Header Func Desc //
WBVAL(CDC_V1_10),// bcdCDC 1.10 //

// Call Management Functional Descriptor//
0x05,// bFunctionLength //
CDC_CS_INTERFACE,// bDescriptorType: CS_INTERFACE //
CDC_CALL_MANAGEMENT,// bDescriptorSubtype: Call Management Func Desc //
0x01,// bmCapabilities: device handles call management //
USB_CDC_DIF_NUM,// bDataInterface: CDC data IF ID //

// Abstract Control Management Functional Descriptor//
0x04,// bFunctionLength //
CDC_CS_INTERFACE,// bDescriptorType: CS_INTERFACE //
CDC_ABSTRACT_CONTROL_MANAGEMENT,// bDescriptorSubtype: Abstract Control Management desc //
0x02,// bmCapabilities: SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported //

// Union Functional Descriptor//
0x05,// bFunctionLength //
CDC_CS_INTERFACE,// bDescriptorType: CS_INTERFACE //
CDC_UNION,// bDescriptorSubtype: Union func desc //
USB_CDC_CIF_NUM,// bMasterInterface: Communication class interface is master //
USB_CDC_DIF_NUM,// bSlaveInterface0: Data class interface is slave 0 //
//-------------------------------------Endpoint 1 Descriptor//
USB_ENDPOINT_DESC_SIZE,// bLength //
USB_ENDPOINT_DESCRIPTOR_TYPE,// bDescriptorType //
//USB_ENDPOINT_IN(1),// bEndpointAddress //  LPC134x method.
USB_CDC_INT_EP,// bEndpointAddress //
USB_ENDPOINT_TYPE_INTERRUPT,// bmAttributes //
WBVAL(0x0010),// wMaxPacketSize //
0x02,// 2ms //           // bInterval //

//===========================================================

//-------------------------------------Interface 1, Alternate Setting 0, Data class interface descriptor//
USB_INTERFACE_DESC_SIZE,// bLength //
USB_INTERFACE_DESCRIPTOR_TYPE,// bDescriptorType //
USB_CDC_DIF_NUM,// bInterfaceNumber: Number of Interface //
0x00,// bAlternateSetting: no alternate setting //
0x02,// bNumEndpoints: two endpoints used //
CDC_DATA_INTERFACE_CLASS,// bInterfaceClass: Data Interface Class //
0x00,// bInterfaceSubClass: no subclass available //
0x00,// bInterfaceProtocol: no protocol used //
0x05,// iInterface: //
//-------------------------------------Endpoint, EP Bulk Out //
USB_ENDPOINT_DESC_SIZE,// bLength //
USB_ENDPOINT_DESCRIPTOR_TYPE,// bDescriptorType //
//USB_ENDPOINT_OUT(3),// bEndpointAddress //  LPC134x method.
USB_CDC_OUT_EP,// bEndpointAddress //
USB_ENDPOINT_TYPE_BULK,// bmAttributes //
WBVAL(USB_FS_MAX_BULK_PACKET),// wMaxPacketSize //
0x00,// bInterval: ignore for Bulk transfer //
//-------------------------------------Endpoint, EP Bulk In //
USB_ENDPOINT_DESC_SIZE,// bLength //
USB_ENDPOINT_DESCRIPTOR_TYPE,// bDescriptorType //
//USB_ENDPOINT_IN(3),// bEndpointAddress //  LPC134x method.
USB_CDC_IN_EP,// bEndpointAddress //
USB_ENDPOINT_TYPE_BULK,// bmAttributes //
WBVAL(64),// wMaxPacketSize //
0x00,// bInterval: ignore for Bulk transfer //
// Terminator //
0// bLength //
};


//
//=========================================================================== USB Device Qualifier (Do we need this??)
//
/*
ALIGNED(4) const uint8_t USB_DeviceQualifier[] = {
USB_DEVICE_QUALI_SIZE,// bLength
USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE,// bDescriptorType
WBVAL(0x0200),// bcdUSB: 2.00
0x00,// bDeviceClass
0x00,// bDeviceSubClass
0x00,// bDeviceProtocol
USB_MAX_PACKET0,// bMaxPacketSize0
0x01,// bNumOtherSpeedConfigurations
0x00// bReserved
};
*/


(5) Below is the init code, not sure what I am doing

void USB_Main_Init(void)// ex Main.
{
USBD_API_INIT_PARAM_T usb_param;
USB_CORE_DESCS_T desc;
ErrorCode_t ret = LPC_OK;

Chip_USB_Init();// Enable USB Clock.// enable clocks
g_pUsbApi = (const USBD_API_T *) LPC_ROM_API->pUSBD;// initialize USBD ROM API pointer.

memset((void *) &usb_param, 0, sizeof(USBD_API_INIT_PARAM_T));// initialize call back structures
usb_param.usb_reg_base = LPC_USB0_BASE;

//--------------------------------------------------------------------- Bug Fixes
/*WORKAROUND for artf44835 ROM driver BUG:
    Code clearing STALL bits in endpoint reset routine corrupts memory area
    next to the endpoint control data. For example When EP0, EP1_IN, EP1_OUT,
    EP2_IN are used we need to specify 3 here. But as a workaround for this
    issue specify 4. So that extra EPs control structure acts as padding buffer
    to avoid data corruption. Corruption of padding memory doesn’t affect the
    stack/program behaviour.
 */
usb_param.max_num_ep = 4 + 1;// May need to adjust to 4+1.
//---------------------------------------------------------------------------
usb_param.mem_base = USB_STACK_MEM_BASE;
usb_param.mem_size = USB_STACK_MEM_SIZE;

desc.device_desc = (uint8_t *) &USB_DeviceDescriptor[0];// Set the USB descriptors
desc.string_desc = (uint8_t *) &USB_StringDescriptor[0];
// Note, to pass USBCV test full-speed only devices should have both
// descriptor arrays point to same location and device_qualifier set to 0.
desc.high_speed_desc = (uint8_t *) &USB_FsConfigDescriptor[0];
desc.full_speed_desc = (uint8_t *) &USB_FsConfigDescriptor[0];
desc.device_qualifier = 0;

ret = USBD_API->hw->Init(&g_hUsb, &desc, &usb_param);// USB Initialization
if (ret == LPC_OK)
{
ret = mscDisk_init(g_hUsb, &desc, &usb_param);
ret = vcom_init(g_hUsb, &desc, &usb_param);// Init VCOM section
if (ret == LPC_OK)
{
NVIC_SetPriority(USB0_IRQn, 1);// Make sure USB and UART IRQ priorities are same for this example
NVIC_EnableIRQ(USB0_IRQn);//  enable USB interrupts
USBD_API->hw->Connect(g_hUsb, 1);// now connect
}
}
if ((vcom_connected() != 0))
vcom_write("---USB Test\n", 15);
}


(6) I have downloaded the Kiel but I could not find examples code under MCB11U00 (see page 9 within AN11232). Can you send me source code, are they rom based solution that I can work on?

I'm open for suggestion what to do next or workaround this. 
Labels (1)
0 Kudos
12 Replies

1,192 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by riscy00 on Mon Mar 14 08:13:18 MST 2016
Thank for the corrected code.

I have tested it on Window 7 and 8.1 and it remains a problem.

I had a look into USB analyser (commercial) and it seem there is other protocol need to be added to USB code to make it work correctly for Window OS that not required by Linux. Not sure which but it is missing element. I think VCOM part has something to do with it (IAD?).

0 Kudos

1,192 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by DF9DQ on Tue Mar 08 07:05:34 MST 2016
Looking at your code I noticed that it doesn't call DataRam_Initialize() in case of the composite device!
So I added that call in USB_Main_Init(), and also allowed the RAM disk content to be compiled (changed the "if defined" in ramdisk.c).

The COM port and the MSC disk work when connected to a Linux host.
0 Kudos

1,192 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by riscy00 on Tue Jan 19 11:48:03 MST 2016
Any progress?, I'm wondering if I should keeping asking or give up?

Does this silence response affirms impossibility to achieve composite MSC and VCOM for LPC1549?

Have I really tried hard enough to assist you to resolve this issue?

0 Kudos

1,192 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by riscy00 on Tue Jan 12 00:46:42 MST 2016
Hi nxp69442,

Any new about the demo code?, have you tried it out?
0 Kudos

1,192 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by riscy00 on Sat Jan 02 04:52:26 MST 2016
Hi nxp69442

I have copied over selected code as attached the code that work on LPC1549 Expresso V2, they are based on LPCOpen demo codes. 

I would be grateful if you may look at it and explain why composite MSC and CDC is not working, I think it related to endpoint issue (I now under stood logical and physical endpoint).

I have included the #define in  USB_init.h, which select CDC only which is working, MSC only which is working, it pop open the file folder window and then Composite which did not work, window 8.1 know it there but pop up format window.

//############################
#define CDC_Section
//#define MSC_Section
//#define Composite_CDCMSC
//############################


Correction: Endpoint setting are not correct.
Please modify the code within USB_Init.c

Line 113: usb_param.max_num_ep = 3 + 1;// Composite MSC/CDC....still not working but it 4 Endpoint.
Line 222: usb_param.max_num_ep = 1+1;               // MSC Only which is working fine.
Line 326: usb_param.max_num_ep = 2 + 1;            // CDC Only which is working fine.






0 Kudos

1,192 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by riscy00 on Fri Dec 18 01:27:15 MST 2015
Bump?
0 Kudos

1,192 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by riscy00 on Wed Dec 16 01:12:35 MST 2015
I'm reading the datasheet page 350 as you suggested, I admit I did not read that part, I guess I was too focused on demo code itself and USB in Window.

How to declare logical and physical endpoint that in sync with LPC1549 code which I attached earlier?

So
One logical endpoints is lost due to bug in ROM, which leave 4 physical endpoint, correct? 

for Control EP0-IN and EP0-OUT (which is 0x80 and 0x00)
for MSC, there only one logical endpoints with EP1-IN and EP1-OUT (which is 0x81,0x01)
for CDC, there only two logical endpoints with EP2-IN and EP2-OUT and EP3-INT (which is 0x82,0x02,0x83)

So I should use, correct?
// 1 EP0 for zero.
// 2 EP for CDC (EPIN, EPOUT, EPINT)
// 1 EP for MSC (EPIN and EPOUT)
// = 4 total.
     usb_param.max_num_ep = 4 + 1;which is within 5 EP maximum including the rom bug.


I still don't know how it sync endpoint to suitable code between MSC / CDC.
How to check if these implementation of endpoints are correct in context with CDC and MSC.
0 Kudos

1,192 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by riscy00 on Wed Dec 16 00:48:01 MST 2015
The host (under Window 8.1) working fine with VCOM (via putty) and MSC (which pop up file window) stand alone, but with composite it know it there is VCOM and MSC (as listed in driver window from control) but it pop up a window asking to format in MSC which fails and does not response to putty.

Has this LPC1549 or it range proven to work with both VCOM and MSC in composite?, there is no demo code except the HID and VCOM which worked fine because number of end point is smaller.

There is bug as noted in CDC demo program....... it say 3 EP.

//--------------------------------------------------------------------- Bug Fixes
/*WORKAROUND for artf44835 ROM driver BUG:
    Code clearing STALL bits in endpoint reset routine corrupts memory area
    next to the endpoint control data. For example When EP0, EP1_IN, EP1_OUT,
    EP2_IN are used we need to specify 3 here. But as a workaround for this
    issue specify 4. So that extra EPs control structure acts as padding buffer
    to avoid data corruption. Corruption of padding memory doesn’t affect the
    stack/program behaviour.
*/
// 1 EP0 for zero.
// 3 EP for CDC (EPIN, EPOUT, EPINT)
// 2 EP for MSC (EPIN and EPOUT)
// = 6 total.
//-------------------------------------------
// However the ROM only support 5 EP (#define USB_MAX_EP_NUM 5....cannot change!)

Below is the code that init it.......

void USB_IRQHandler(void)
{
USBD_API->hw->ISR(g_hUsb);
}

/**
 * @briefFind the address of interface descriptor for given class type.
 * @returnIf found returns the address of requested interface else returns NULL.
 */
USB_INTERFACE_DESCRIPTOR *find_IntfDesc(const uint8_t *pDesc, uint32_t intfClass)
{
USB_COMMON_DESCRIPTOR *pD;
USB_INTERFACE_DESCRIPTOR *pIntfDesc = 0;
uint32_t next_desc_adr;

pD = (USB_COMMON_DESCRIPTOR *) pDesc;
next_desc_adr = (uint32_t) pDesc;

while (pD->bLength) {
/* is it interface descriptor */
if (pD->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) {

pIntfDesc = (USB_INTERFACE_DESCRIPTOR *) pD;
/* did we find the right interface descriptor */
if (pIntfDesc->bInterfaceClass == intfClass) {
break;
}
}
pIntfDesc = 0;
next_desc_adr = (uint32_t) pD + pD->bLength;
pD = (USB_COMMON_DESCRIPTOR *) next_desc_adr;
}

return pIntfDesc;
}

//==================================================================
//================================================================== USB_Main_Init
// Purpose: Init USB from here.
// Input:
// Output:
// Note : Do not init GPIO here!.
//==================================================================
void USB_Main_Init(void)// ex Main.
{
USBD_API_INIT_PARAM_T usb_param;
USB_CORE_DESCS_T desc;
ErrorCode_t ret = LPC_OK;

Chip_USB_Init();// Enable USB Clock.// enable clocks
g_pUsbApi = (const USBD_API_T *) LPC_ROM_API->pUSBD;// initialize USBD ROM API pointer.

memset((void *) &usb_param, 0, sizeof(USBD_API_INIT_PARAM_T));// initialize call back structures
usb_param.usb_reg_base = LPC_USB0_BASE;

//--------------------------------------------------------------------- Bug Fixes
/*WORKAROUND for artf44835 ROM driver BUG:
    Code clearing STALL bits in endpoint reset routine corrupts memory area
    next to the endpoint control data. For example When EP0, EP1_IN, EP1_OUT,
    EP2_IN are used we need to specify 3 here. But as a workaround for this
    issue specify 4. So that extra EPs control structure acts as padding buffer
    to avoid data corruption. Corruption of padding memory doesn’t affect the
    stack/program behaviour.
 */
// 1 EP0 for zero.
// 3 EP for CDC (EPIN, EPOUT, EPINT)
// 2 EP for MSC (EPIN and EPOUT)
// = 6 total.
//-------------------------------------------
// However the ROM only support 5 EP (#define USB_MAX_EP_NUM 5....cannot change!)

usb_param.max_num_ep = 5 + 1;// CDC and MSC requires 6 + 1.
//---------------------------------------------------------------------------
usb_param.mem_base = USB_STACK_MEM_BASE;
usb_param.mem_size = USB_STACK_MEM_SIZE;

desc.device_desc = (uint8_t *) &USB_DeviceDescriptor[0];// Set the USB descriptors
desc.string_desc = (uint8_t *) &USB_StringDescriptor[0];
// Note, to pass USBCV test full-speed only devices should have both
// descriptor arrays point to same location and device_qualifier set to 0.
desc.high_speed_desc = (uint8_t *) &USB_FsConfigDescriptor[0];
desc.full_speed_desc = (uint8_t *) &USB_FsConfigDescriptor[0];
desc.device_qualifier = 0;

ret = USBD_API->hw->Init(&g_hUsb, &desc, &usb_param);// USB Initialization
if (ret == LPC_OK)
{
ret = mscDisk_init(g_hUsb, &desc, &usb_param);
if (ret == LPC_OK)
{
ret = vcom_init(g_hUsb, &desc, &usb_param);// Init VCOM section
if (ret == LPC_OK)
{
NVIC_SetPriority(USB0_IRQn, 1);// Make sure USB and UART IRQ priorities are same for this example
NVIC_EnableIRQ(USB0_IRQn);//  enable USB interrupts
USBD_API->hw->Connect(g_hUsb, 1);// now connect
}
}
}
if ((vcom_connected() != 0))
vcom_write("---USB Test\n", 15);
}

0 Kudos

1,192 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcmunich on Thu Dec 10 03:48:18 MST 2015
Hi riscy00,
When you say CDC+MSC needs 5 endpoints, you are talking about physical endpoints here.
As an example, a logical endpoint EP1 has two physical endpoints (In and Out).
You can refer to Endpoint Configuration details on page 350 of the User Manual for more details.
Your descriptors seems to be okay to me, maybe some issues on the host side?
0 Kudos

1,192 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by riscy00 on Fri Dec 04 06:10:40 MST 2015
I have modified the CDC-HID to CDC+MSC but could not make it work.

There is bug in ROM in LPC15xx, it lost 1 endpoint so it leave 4 endpoint. Where CDC+MSC need 5 Endoint, I'm not sure if this is physical or logical type?

Not sure the difference between physical and logical endpoint, can you explain?

I'm still stuck there.

I checked the descriptor from LPC1830 example which has CDC+MSC+DFU (ROM) and found be to matched. The laptop confirm the Communication and Mass Storage but the window ask to format the RAM since it cannot read them and VCOM is not working (It has COM6 but no comm response). When I change the code and descriptor for just MSC and CDC Only, it work fine. I check interface and endpoint address and it okay.   

The LPC1343 is very different to ROM based so it quite useless but it help to check descriptor.

I can send you code for you to take a look, below is the descriptor

/* Manifest constants defining interface numbers and endpoints used by a
   particular interface in this application.
 */
#define USB_MSC_IF_NUM          0
#define USB_MSC_IN_EP           0x81
#define USB_MSC_OUT_EP          0x01


/* Manifest constants defining interface numbers and endpoints used by a
   particular interface in this application.
 */
#define USB_CDC_CIF_NUM         1
#define USB_CDC_DIF_NUM         2
#define USB_CDC_IN_EP           0x82
#define USB_CDC_OUT_EP          0x02
#define USB_CDC_INT_EP          0x83


#ifdef Composite_CDCMSC
//
//===========================================================================USB Standard Device Descriptor
//
ALIGNED(4) const uint8_t USB_DeviceDescriptor[] = {
USB_DEVICE_DESC_SIZE,// bLength //
USB_DEVICE_DESCRIPTOR_TYPE,// bDescriptorType //
WBVAL(0x0200),// bcdUSB = USB 2.00//
0x00, //USB_DEVICE_CLASS_MISCELLANEOUS,// bDeviceClass //
0x00,// bDeviceSubClass //
0x01,// bDeviceProtocol //
USB_MAX_PACKET0,// bMaxPacketSize0 //
WBVAL(0x1FC9),// idVendor //
WBVAL(0x0087),// idProduct //
WBVAL(0x0100),// bcdDevice //
0x01,// iManufacturer //
0x02,// iProduct //
0x03,// iSerialNumber //
0x01// bNumConfigurations //
};

//
// ===========================================================================USB FSConfiguration Descriptor
//  All Descriptors (Configuration, Interface, Endpoint, Class, Vendor)
//
ALIGNED(4) uint8_t USB_FsConfigDescriptor[] = {
// Configuration 1 //
USB_CONFIGURATION_DESC_SIZE,// bLength //
USB_CONFIGURATION_DESCRIPTOR_TYPE,// bDescriptorType //
WBVAL(// wTotalLength //
1 * USB_CONFIGURATION_DESC_SIZE     +
//-------------------------------------MSC Class
1 * USB_INTERFACE_DESC_SIZE         +// MSC interface //
2 * USB_ENDPOINT_DESC_SIZE      +// bulk endpoints //
//-------------------------------------CDC Class
1 * USB_INTERFACE_ASSOC_DESC_SIZE   +// interface association descriptor //
1 * USB_INTERFACE_DESC_SIZE         +// communication control interface //
0x0013                          +// CDC functions //
1 * USB_ENDPOINT_DESC_SIZE      +// interrupt endpoint //
1 * USB_INTERFACE_DESC_SIZE         +// communication data interface //
2 * USB_ENDPOINT_DESC_SIZE      +// bulk endpoints //
0
),
0x03,// bNumInterfaces //
0x01,// bConfigurationValue //
0x00,// iConfiguration //
USB_CONFIG_BUS_POWERED,// bmAttributes  //Power from USB.
USB_CONFIG_POWER_MA(500),// bMaxPower //

//==============================================================MSC Section
//-------------------------------------Interface 0, Alternate Setting 0, MSC class interface descriptor //
USB_INTERFACE_DESC_SIZE,// bLength //
USB_INTERFACE_DESCRIPTOR_TYPE,// bDescriptorType //
USB_MSC_IF_NUM,// bInterfaceNumber: Number of Interface //
0x00,// bAlternateSetting: Alternate setting //
0x02,// bNumEndpoints: Two endpoint used //
USB_DEVICE_CLASS_STORAGE,// bInterfaceClass: Communication Interface Class //
MSC_SUBCLASS_SCSI,// bInterfaceSubClass: Abstract Control Model //
MSC_PROTOCOL_BULK_ONLY,// bInterfaceProtocol: no protocol used //
0x06,// iInterface: //
//----------------------------------Endpoint, EP Bulk In //
USB_ENDPOINT_DESC_SIZE,// bLength //
USB_ENDPOINT_DESCRIPTOR_TYPE,// bDescriptorType //
USB_MSC_IN_EP,// bEndpointAddress //
USB_ENDPOINT_TYPE_BULK,// bmAttributes //
WBVAL(USB_FS_MAX_BULK_PACKET),// wMaxPacketSize //
0x00,// bInterval: ignore for Bulk transfer //
//----------------------------------Endpoint, EP Bulk Out //
USB_ENDPOINT_DESC_SIZE,// bLength //
USB_ENDPOINT_DESCRIPTOR_TYPE,// bDescriptorType //
USB_MSC_OUT_EP,// bEndpointAddress //
USB_ENDPOINT_TYPE_BULK,// bmAttributes //
WBVAL(USB_FS_MAX_BULK_PACKET),// wMaxPacketSize //
0x00,// bInterval: ignore for Bulk transfer //

//==============================================================CDC Section
//-------------------------------------Interface association descriptor IAD//
USB_INTERFACE_ASSOC_DESC_SIZE,// bLength //
USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE,// bDescriptorType //
USB_CDC_CIF_NUM,// bFirstInterface //
0x02,// bInterfaceCount //
CDC_COMMUNICATION_INTERFACE_CLASS,// bFunctionClass //
CDC_ABSTRACT_CONTROL_MODEL,// bFunctionSubClass //
0x00,// bFunctionProtocol //
0x05,// iFunction //

//==============================================================
//-------------------------------------Interface 1, Alternate Setting 0, Communication class interface descriptor //
USB_INTERFACE_DESC_SIZE,// bLength //
USB_INTERFACE_DESCRIPTOR_TYPE,// bDescriptorType //
USB_CDC_CIF_NUM,// bInterfaceNumber: Number of Interface //
0x00,// bAlternateSetting: Alternate setting //
0x01,// bNumEndpoints: One endpoint used //
CDC_COMMUNICATION_INTERFACE_CLASS,// bInterfaceClass: Communication Interface Class //
CDC_ABSTRACT_CONTROL_MODEL,// bInterfaceSubClass: Abstract Control Model //
0x00,// bInterfaceProtocol: no protocol used //
0x06,// iInterface: //

// Header Functional Descriptor//
0x05,// bLength: CDC header Descriptor size //
CDC_CS_INTERFACE,// bDescriptorType: CS_INTERFACE //
CDC_HEADER,// bDescriptorSubtype: Header Func Desc //
WBVAL(CDC_V1_10),// bcdCDC 1.10 //

// Call Management Functional Descriptor//
0x05,// bFunctionLength //
CDC_CS_INTERFACE,// bDescriptorType: CS_INTERFACE //
CDC_CALL_MANAGEMENT,// bDescriptorSubtype: Call Management Func Desc //
0x01,// bmCapabilities: device handles call management //
USB_CDC_DIF_NUM,// bDataInterface: CDC data IF ID //

// Abstract Control Management Functional Descriptor//
0x04,// bFunctionLength //
CDC_CS_INTERFACE,// bDescriptorType: CS_INTERFACE //
CDC_ABSTRACT_CONTROL_MANAGEMENT,// bDescriptorSubtype: Abstract Control Management desc //
0x02,// bmCapabilities: SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported //

// Union Functional Descriptor//
0x05,// bFunctionLength //
CDC_CS_INTERFACE,// bDescriptorType: CS_INTERFACE //
CDC_UNION,// bDescriptorSubtype: Union func desc //
USB_CDC_CIF_NUM,// bMasterInterface: Communication class interface is master //
USB_CDC_DIF_NUM,// bSlaveInterface0: Data class interface is slave 0 //
//-------------------------------------Endpoint 1 Descriptor//
USB_ENDPOINT_DESC_SIZE,// bLength //
USB_ENDPOINT_DESCRIPTOR_TYPE,// bDescriptorType //
USB_CDC_INT_EP,// bEndpointAddress //
USB_ENDPOINT_TYPE_INTERRUPT,// bmAttributes //
WBVAL(0x0010),// wMaxPacketSize //
0x02,// 2ms //           // bInterval //

//===========================================================

//-------------------------------------Interface 2, Alternate Setting 0, Data class interface descriptor//
USB_INTERFACE_DESC_SIZE,// bLength //
USB_INTERFACE_DESCRIPTOR_TYPE,// bDescriptorType //
USB_CDC_DIF_NUM,// bInterfaceNumber: Number of Interface //
0x00,// bAlternateSetting: no alternate setting //
0x02,// bNumEndpoints: two endpoints used //
CDC_DATA_INTERFACE_CLASS,// bInterfaceClass: Data Interface Class //
0x00,// bInterfaceSubClass: no subclass available //
0x00,// bInterfaceProtocol: no protocol used //
0x05,// iInterface: //
//-------------------------------------Endpoint, EP Bulk Out //
USB_ENDPOINT_DESC_SIZE,// bLength //
USB_ENDPOINT_DESCRIPTOR_TYPE,// bDescriptorType //
USB_CDC_OUT_EP,// bEndpointAddress //
USB_ENDPOINT_TYPE_BULK,// bmAttributes //
WBVAL(USB_FS_MAX_BULK_PACKET),// wMaxPacketSize //
0x00,// bInterval: ignore for Bulk transfer //
//-------------------------------------Endpoint, EP Bulk In //
USB_ENDPOINT_DESC_SIZE,// bLength //
USB_ENDPOINT_DESCRIPTOR_TYPE,// bDescriptorType //
USB_CDC_IN_EP,// bEndpointAddress //
USB_ENDPOINT_TYPE_BULK,// bmAttributes //
WBVAL(64),// wMaxPacketSize //
0x00,// bInterval: ignore for Bulk transfer //
// Terminator //
0// bLength //
};


//
//=========================================================================== USB Device Qualifier (Do we need this??)
//

ALIGNED(4) const uint8_t USB_DeviceQualifier[] = {
USB_DEVICE_QUALI_SIZE,// bLength
USB_DEVICE_QUALIFIER_DESCRIPTOR_TYPE,// bDescriptorType
WBVAL(0x0200),// bcdUSB: 2.00
0x00,// bDeviceClass
0x00,// bDeviceSubClass
0x00,// bDeviceProtocol
USB_MAX_PACKET0,// bMaxPacketSize0
0x01,// bNumOtherSpeedConfigurations
0x00// bReserved
};


/* USB String Descriptor (optional) */
const uint8_t USB_StringDescriptor[] = {
/* Index 0x00: LANGID Codes */
0x04,                              /* bLength */
USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
WBVAL(0x0409), /* US English */    /* wLANGID */
/* Index 0x01: Manufacturer */
(13*2 + 2),                        /* bLength (13 Char + Type + lenght) */
USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
'I',0,
'D',0,
'T',0,
' ',0,
'E',0,
'V',0,
'K',0,
'I',0,
'T',0,
' ',0,
' ',0,
'1',0,
'5',0,
/* Index 0x02: Product */
(21*2 + 2),                        /* bLength ( 21 Char + Type + lenght) */
USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
'E',0,
'Z',0,
'K',0,
'I',0,
'T',0,
' ',0,
'C',0,
'D',0,
'C',0,
'/',0,
'M',0,
'S',0,
'C',0,
' ',0,
'(',0,
'R',0,
'G',0,
'P',0,
'1',0,
'5',0,
')',0,
/* Index 0x03: Serial Number */
(16*2 + 2),                        /* bLength (12 Char + Type + lenght) */
USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
'P',0,
'R',0,
'O',0,
'T',0,
'O',0,
'T',0,
'Y',0,
'P',0,
'E',0,
' ',0,
'2',0,
'0',0,
'1',0,
'5',0,
' ',0,
' ',0,
/* Index 0x04: Interface 0, Alternate Setting 0 */
( 6*2 + 2),                        /* bLength (6 Char + Type + lenght) */
USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
'M',0,
'e',0,
'm',0,
'o',0,
'r',0,
'y',0,
/* Index 0x05: Interface 0, Alternate Setting 0 */
( 4*2 + 2),                        /* bLength (4 Char + Type + lenght) */
USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
'V',0,
'C',0,
'O',0,
'M',0,
/* Index 0x06: Interface 0, Alternate Setting 0 */
( 8*2 + 2),                        /* bLength (4 Char + Type + lenght) */
USB_STRING_DESCRIPTOR_TYPE,        /* bDescriptorType */
'C',0,
'O',0,
'M',0,
'/',0,
'D',0,
'A',0,
'T',0,
'A',0,
};

#endif




0 Kudos

1,192 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by lpcmunich on Wed Dec 02 06:52:35 MST 2015
Hi riscy00,
I think, you are getting confused between physical and logical endpoints here.
The LPC1500 (like most LPC11Uxx parts) supports 10 physical (5 logical) endpoints.
So it's very much possible to implement a composite class device with CDC and MSC.
Regarding software examples, the AppNote AN11232 package (AN11232.zip) has the CDC+MSC composite example.
But this is not a ROM (USBD) based example.
If you are looking for ROM based, you can download the LPC1500 LPCOpen package.
And it has a composite class example (CDC+HID), unfortunately not CDC+MSC.
But there's a seperate MSC class example in the package as well.
So you just need to replace the HID with MSC in the composite example as desired by you.
Hope this helps!
0 Kudos

1,192 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by riscy00 on Tue Dec 01 05:03:54 MST 2015
I just found out that the ROM only support 5 Endpoint Max.

I calculated that
// 1 EP0 for zero.
// 3 EP for CDC (EPIN, EPOUT, EPINT)
// 2 EP for MSC (EPIN and EPOUT)
// = 6 total.
.       // dues to ROM bug, 6+1 = 7 is required.
//-------------------------------------------
// However the ROM only support 5 EP (#define USB_MAX_EP_NUM 5....cannot change!)

Does this mean impossible to use CDC+MSC due to too many endpoints, is there a workaround this?

Thanks.

R.
0 Kudos