Hi,
I've created a firmware application for USB composite device in LPC1343, I found an example for this Micro controller which is the composite device is composed of CDC and MSC in AN11018 from nxp for my reference. What I did I've created a composite driver using USB HIDROM and USB MSCROM running in Keil, but unfortunately when i run the firmware it didn't enumerate the device. I used both of the on-chip driver of the LPC1343 for this firmware application. It is possible to combine this two? I combine the code sample of on-chip driver for HID and MSC into one file but different function on each and call in the main function, but unfortunately it didn't worked. When I checked on the Device Manager, I found a "USB Mass Storage" with a warning sign (exclamation point). I think the device doesn't enumerated properly.Could someone help me about this?
Thanks.
> I've created a composite driver using USB HIDROM and USB MSCROM
The USB stack on the ROM (USBHID_rom and USBMem_rom) doesn't provide enough callbacks for class implementation, which requires for composite device. Start with full USBHID and USBMem source on this sample code, instead of the ROM version.
Sample Code Bundle for LPC13xx Peripherals using Keil's MDK-ARM V1.05 (Mar 28, 2011) ics.nxp.com/.../code.bundle.lpc13xx.keil.zip > Suggestion to Keil programmer (if s/he would read this post :-) It's the time to re-organize the source code for class implementation. #if USB_MSC / #if USB_HID / #if USB_CDC, etc. on the source code indicate the place where callbacks for class implementation are inserted, instead of the #if's. And then, the stack code grows more tight and universal.
Tsuneo
Hi Tsuneo,
What about combining the HID (not in ROM) and using the ISP programming is it possible to create a composite device with this?
Could you please elaborate more about the callback for class implementation is it the USB_ENDPOINT?
thanks.
> What about combining the HID (not in ROM) and using the ISP programming is it possible to create a composite device with this?
The USB ISP described in AN10986 is a stand-alone code in the boot ROM. It doesn't expose any callbacks for user's firmware. I recommend you to start with USBMem on above code bundle, and append USBHID to it.
Like class implementation, composite device is made in three steps 1) Descriptor work 2) Implement Class request handler 3) Add endpoint(s) process
1) Descriptor work Device descriptor - Change VID/PID (at least PID) to another one, to prevent conflict with the original
Configuration descriptor Append HID interface after MSC (Mass Storage Class) interface. Also, tune a couple of fields,
usbdesc.c /* USB Configuration Descriptor */ /* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor) */ const uint8_t USB_ConfigDescriptor[] = { /* Configuration 1 */ USB_CONFIGUARTION_DESC_SIZE, /* bLength */ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL( /* wTotalLength */ 1*USB_CONFIGUARTION_DESC_SIZE + 1*USB_INTERFACE_DESC_SIZE + 2*USB_ENDPOINT_DESC_SIZE + USB_INTERFACE_DESC_SIZE + // <-------------- increase by HID IF HID_DESC_SIZE + // <-------------- USB_ENDPOINT_DESC_SIZE // <-------------- ), 0x02, /* bNumInterfaces */ // <-------------- 0x01, /* bConfigurationValue: 0x01 is used to select this configuration */ 0x00, /* iConfiguration: no string to describe this configuration */ USB_CONFIG_BUS_POWERED /*|*/ /* bmAttributes */ /*USB_CONFIG_REMOTE_WAKEUP*/, USB_CONFIG_POWER_MA(100), /* bMaxPower, device power consumption is 100 mA */ /* Interface 0, Alternate Setting 0, MSC Class */ USB_INTERFACE_DESC_SIZE, /* bLength */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x00, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x02, /* bNumEndpoints */ USB_DEVICE_CLASS_STORAGE, /* bInterfaceClass */ MSC_SUBCLASS_SCSI, /* bInterfaceSubClass */ MSC_PROTOCOL_BULK_ONLY, /* bInterfaceProtocol */ 0x04, /* iInterface */ /* Endpoint, EP2 Bulk IN */ USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_IN(2), /* bEndpointAddress */ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ WBVAL(0x0040), /* wMaxPacketSize */ 0x00, /* bInterval: ignore for Bulk transfer */ /* Endpoint, EP2 Bulk OUT */ USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_OUT(2), /* bEndpointAddress */ USB_ENDPOINT_TYPE_BULK, /* bmAttributes */ WBVAL(0x0040), /* wMaxPacketSize */ 0x00, /* bInterval: ignore for Bulk transfer */ // // <------ append HID interface // /* Interface 1, Alternate Setting 0, HID Class */ USB_INTERFACE_DESC_SIZE, /* bLength */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x01, /* bInterfaceNumber */ // <-------------- 0x00, /* bAlternateSetting */ 0x01, /* bNumEndpoints */ USB_DEVICE_CLASS_HUMAN_INTERFACE, /* bInterfaceClass */ HID_SUBCLASS_NONE, /* bInterfaceSubClass */ HID_PROTOCOL_NONE, /* bInterfaceProtocol */ 0x00, /* iInterface */ /* HID Class Descriptor */ /* HID_DESC_OFFSET = 0x0012 */ HID_DESC_SIZE, /* bLength */ HID_HID_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL(0x0100), /* 1.00 */ /* bcdHID */ 0x00, /* bCountryCode */ 0x01, /* bNumDescriptors */ HID_REPORT_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL(HID_REPORT_DESC_SIZE), /* wDescriptorLength */ /* Endpoint, HID Interrupt In */ USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_IN(1), /* bEndpointAddress */ USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ WBVAL(0x0004), /* wMaxPacketSize */ 0x20, /* 32ms */ /* bInterval */ /* Terminator */ 0 /* bLength */ };
Drag in HID Report Descriptor from USBHID\usbdesc.c to USBMem
Drag in these definitions
usbdesc.h #define HID_DESC_OFFSET 0x0012 #define HID_DESC_SIZE (sizeof(HID_DESCRIPTOR)) #define HID_REPORT_DESC_SIZE (sizeof(HID_ReportDescriptor)) extern const uint8_t HID_ReportDescriptor[]; extern const uint16_t HID_ReportDescSize;
2) Class request handler Fortunately, Keil has already implemented HID class request handler on all of their examples. To enable it, modify these definitions.
usbcfg.h #define USB_EP_EVENT 0x0005 // <---- 0x0007 #define USB_HID 0 // <---- 1 #define USB_HID_IF_NUM 0 // <---- 1
Drag in these files to the project - hid.h - hiduser.h - hiduser.c
3) Endpoint(s) process Replace these routines for the HID endpoints process I don't like this implementation, but it's just for your start point :-)
usbuser.c #if USB_CONFIGURE_EVENT void USB_Configure_Event (void) { if (USB_Configuration) { /* Check if USB is configured */ GetInReport(); USB_WriteEP(0x81, &InReport, sizeof(InReport)); } } #endif void USB_EndPoint1 (uint32_t event) { switch (event) { case USB_EVT_IN: GetInReport(); USB_WriteEP(0x81, &InReport, sizeof(InReport)); break; } }
Lastly, finish the mods by merging main() on memory.c and demo.c Also, drag in demo.h
That's all
Now I can create a composite device with HID and MSC w/o using the on-chip driver. My mistake is that I put an IAD in the USB Configuration Descriptor, and yet it is not allowed as you've answered me in the other thread. You're so great.And your replies really help me. One more thing,the device has been enumerated but theirs something I want to clarify, why is it that the Mass storage device(USB icon in the left side of my monitor) it seems it is been disable.I mean it can't be ejected, and when I open the enumerated the Removable Disk it can't be opened and Insert disk window will pop up showing that Removable Disk should be inserted. Is this about the memory size?
Ummm.. On my side, it works as we expect; It mounts a disk with single file, README.TXT
On your side, sound like the MSC works, but disk contents are corrupted. Did you run it on RAM, instead of FLASH?
I posted modified source here,
www.8052.com/.../LPC134x_USBMem_HID.zip
Compare it with yours.
Tsuneo,
Thanks a lot. The only difference is the physicalMemorySize for the MSC. Now its working.
>>>>The USB ISP described in AN10986 is a stand-alone code in the boot ROM. >>>>It doesn't expose any callbacks for user's firmware.
Could you explain me more about this? What are the advantages and disadvantages for ISP? Because I want to create an application as described in AN10986 but I want to combined it with another device class(HID or cdc). Can I ask a link for the steps on creating a composite device?Coz i didn't found a document for this.
> Because I want to create an application as described in AN10986 but I want to combined it with another device class(HID or cdc).
You should not "combine" USB ISP code with your USB application. Bootloader should be independent from your application code, to guarantee recovery from failed firmware update.
Hi, is there any documentation for Sample Code Bundle for LPC13xx that you mentioned?
Tnx in advance.
I
Maybe none. Change part number at the end of this URL, and you'll see documents for your target MCU on NXP web site.
ics.nxp.com/.../
Thanks for the code. I tried porting it to the LPCxpresso environment and it almost works. The only change was to use the CodeRed header files (with GCC conventions for packed data).
The MSD part seems to work 100%.
For the HID part I updated the definition of HID_DESC_OFFSET:
/* #define HID_DESC_OFFSET 0x0012 */ #define HID_DESC_OFFSET ( 1 * USB_CONFIGUARTION_DESC_SIZE + \ 1 * USB_INTERFACE_DESC_SIZE + \ 2 * USB_ENDPOINT_DESC_SIZE + \ 1 * USB_INTERFACE_DESC_SIZE )
There is still something wrong. Running the usbhid example code we see these transactions on USBlyzer:
Select Configuration - Success Class Interface/Set Idle - Success Get Descriptor From Interface - Success
Running the composite device code we see (after a bunch of successful MSD transactions):
Select Configuration - Success Class Interface/Set Idle - Fail (Invalid Parameter) Status = 8000_0300h Get Descriptor From Interface - Fail (Invalid Parameter)
I am debugging right now, but any hints as to where the problem might lie would be appreciated - the Keil code isn't the easiest to read.
Tim