Question on USB_ROM_HID Example

cancel
Showing results for 
Search instead for 
Did you mean: 

Question on USB_ROM_HID Example

1,550 Views
timothymasters
Contributor II

Hi,

 

I am trying to get the NXP USB_ROM_HID Example to compile on LCPXpresso IDE. I had to change several of the statements to use the version of lpc_chip_11uxx_lib on my machine. But I am still having a problem with one line of the example to get a successful compile.

 

This is the trouble line:

 

pUsbApi = (USBD_API_T*)((*ROM **)(0x1FFF1FF8))->pUSBD);

 

The compiler error for this line is:

error: 'ROM' undeclared (first use in this function)

 

I have attached both the example main.c file and my edited version (NXP_USB.c) which compiles with the exception of the one line above to provide further information. I admit I am not sure what is going on with the USB API at all but am trying to trudge through the example to understand it. I have written embedded code for HID USB devices several times in my career at the assembly level so I have a good understanding what has to happen to get the device to configure and how to manage transactions. But I am inexperienced using the high level API.  I am sure it is much easier than the granular assembly drivers I wrote previously but I can't seem to comprehend how to utilize the USB_ROM_API.

 

If anyone could go through my file and add some comments about what is going on when the different USB API interaction is occurring, I would greatly appreciate it.

 

After I get the example to run, I am not sure how to manage the data for the endpoint0 and 1 in and out. Somewhat lost on this. 

 

Thanks

Tim

Original Attachment has been moved to: NXP_USB.c.zip

Original Attachment has been moved to: main.c.zip

Original Attachment has been moved to: compiler-error.txt.zip

0 Kudos
14 Replies

810 Views
ckphua
NXP Employee
NXP Employee

Hi Tim,

If you take the zip file from LPCOpen (LPC11U37 has the exact same as LPC11U24 except with more memory), you need to take the complete project (not just library) and compile the project from the LPCOpen :- nxp_lpcxpresso_11u37_usbd_rom_hid_generic

This should get you the example code to be loaded into the LPC11U24...

To test this, you can run a utility (under the Keil/Utility directory in the same zip file) called HIDClient.exe... this will show you the Input/Output for the HID.

CK

0 Kudos

810 Views
timothymasters
Contributor II

Hi CK,

I think I understood what you were telling me but I am getting a compile error for line 94 in the following file. Here is the snippet of error:

I have not looked at the error to see if it is something I have resolved but are you suggesting that I could take the code from this example and port it to the u24, compile it and start learning?

Any ideas on the compile error?

Thanks

Tim

If you take the zip file from LPCOpen (LPC11U37 has the exact same as LPC11U24 except with more memory), you need to take the complete project (not just library) and compile the project from the LPCOpen :- nxp_lpcxpresso_11u37_usbd_rom_hid_generic

This should get you the example code to be loaded into the LPC11U24...

To test this, you can run a utility (under the Keil/Utility directory in the same zip file) called HIDClient.exe... this will show you the Input/Output for the HID.

512-635-4963

0 Kudos

810 Views
jeremyzhou
NXP TechSupport
NXP TechSupport

Hi Timothy Masters,

In the previous reply for Dezheng Tang, you said the nxp_lpcxpresso_11u37_usbd_rom_hid_generic can be built successful, however it has some error now, and I was wondering if you can tell me what the modification you've done.
Have a great day,
Ping

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

810 Views
timothymasters
Contributor II

Hi Ping,

I created a new workspace and imported the project you recommended. I have successfully built the example. But am not sure how to utilize the example source in my project. I have built 4 successful versions of my product using LCPXpresso but all of them are using a UART for host communication.

I now need to build a version which communicates the application data over the USB as a HID Class device. I have experience developing software for USB HID devices in the past but have never used a driver API. I essentially designed my own driver in these experiences.

But I believe using the NXP USB ROM API is the best solution for my project. However, I am not very familiar with this technique and would appreciate your help. Thanks for your patience with me.

Here is the state of my project:

I have successfully compiled my application such that the host communication is abstracted from the hardware interface. In this abstraction, I have an initialization function that I want to handle the enumeration and set up the USB_IRQ_Handler. I also have a transmit buffer in which I queue the data for the host reports. So I need to find a way to service the Endpoint 1 interrupts such that I load the data successfully to IN token polls.

Requirements:

1. Method or function to enumerate my device

I believe that I can review the USB_ROM_HID example to figure out how to modify the descriptors and initialization for my project configuration. I only need 2 endpoints inclusive of the Control Endpoint 0. Endpoint 1 should be configured as an Interrupt Pipe for transmission of data packets from my application.

Can I utilize the example code much like a function call to do the following:

  • Initialize the USB descriptors with my device data

  • Connect the device to the USB

  • Enumerate the device

  • Establish endoint1 interrupt polls at a periodic rate

Here is the essential structure of main in the example:

int main(void)

{

USBD_API_INIT_PARAM_T usb_param;

USB_CORE_DESCS_T desc;

ErrorCode_t ret = LPC_OK;

Initialization of device for USB peripheral use - I understand this.

/* initialize USBD ROM API pointer. */

g_pUsbApi = (const USBD_API_T *) LPC_ROM_API->usbdApiBase;

Is the above essentially establishing a handle for the USB API?

/* initialize call back structures */

memset((void *) &usb_param, 0, sizeof(USBD_API_INIT_PARAM_T));

usb_param.usb_reg_base = LPC_USB0_BASE;

usb_param.max_num_ep = 2 + 1;

usb_param.mem_base = USB_STACK_MEM_BASE;

usb_param.mem_size = USB_STACK_MEM_SIZE;

I am not sure I understand the above but don't think I really need to.

/* Set the USB descriptors */

desc.device_desc = (uint8_t *) USB_DeviceDescriptor;

desc.string_desc = (uint8_t *) USB_StringDescriptor;

desc.high_speed_desc = USB_FsConfigDescriptor;

desc.full_speed_desc = USB_FsConfigDescriptor;

desc.device_qualifier = 0;

I need to modify the descriptors used in the above functions with my application data. Is this correct?

/* USB Initialization */

ret = USBD_API->hw->Init(&g_hUsb, &desc, &usb_param);

if (ret == LPC_OK) {

usb_param.mem_base = USB_STACK_MEM_BASE + (USB_STACK_MEM_SIZE - usb_param.mem_size);

ret =

usb_hid_init(g_hUsb,

(USB_INTERFACE_DESCRIPTOR *) &USB_FsConfigDescriptor[sizeof(USB_CONFIGURATION_DESCRIPTOR)],

&usb_param.mem_base, &usb_param.mem_size);

The above code actually sets up the USB ROM driver to enumerate with the host in a manner that is accomplished without much foreground attention by my application. Is this correct?

if (ret == LPC_OK) {

/* enable USB interrupts */

NVIC_EnableIRQ(USB0_IRQn);

Above enables interrupts that will begin once device is connected to USB. But the servicing of the interrupts is handled by the driver without much attention from my foreground application during device enumeration. Is this correct?

/* now connect */

USBD_API->hw->Connect(g_hUsb, 1);

How do I know when the enumeration is complete or when the Set Configuration command has been successfully accomplished?

}

}

while (1) {

__WFI();

}

I assume that this while loop should be deleted as my application foreground will be doing things like collecting, processing, and queuing data for transmission over endpoint1.

}

2. Method or function to load endpoint1 data such that USB_IQR_Handler successfully retrieves transmit data to host.

Below is the USB_IRQ_Handler in the example:

void USB_IRQHandler(void)

{

uint32_t *addr = (uint32_t *) LPC_USB->EPLISTSTART;

if ( LPC_USB->DEVCMDSTAT & _BIT(8) ) { /* if setup packet is received */

addr[0] &= ~(_BIT(29)); /* clear EP0_OUT stall */

addr[2] &= ~(_BIT(29)); /* clear EP0_IN stall */

}

USBD_API->hw->ISR(g_hUsb);

}

Do I need to do write code in the handler to load the endpoint1 payload and monitor the success of transmission? If so, can you provide an example of how this function is implemented through the API?

I also need to set up endpoint0 to transfer vendor specific commands in the data payload. And this will require that I need to know when the driver has endpoint0 data, and that I have a means to transmit data back to the host through endpoint0 in response to the vendor commands. But I will leave this task for a later discussion.

If you can help me understand how to accomplish Methods 1 and 2 utilizing a revision of the example code, I would be very appreciative.

Thanks

512-635-4963

0 Kudos

810 Views
jeremyzhou
NXP TechSupport
NXP TechSupport

Hi Timothy Masters,

Let me clarify it.

1) Can I utilize the example code much like a function call to do the following:

  • Initialize the USB descriptors with my device data

  • Connect the device to the USB

  • Enumerate the device

  • Establish endoint1 interrupt polls at a periodic rate

The first three process will would be done without modify any code in the hid_generic demo.

To implement sending some data to host, you should modify the attribute of the Endpoint 1 in the structure USB_FsConfigDescriptor[] in the hid_desc.c at first (Seeing below), then adding some code to implement send report data to host by through the Endpoint 1, about this implementation, I'd like to suggest you to refer to the function void Mouse_Tasks(void) in the hid_mouse demo.

     

      /* Endpoint, HID Interrupt In */
     USB_ENDPOINT_DESC_SIZE,               /* bLength */
     USB_ENDPOINT_DESCRIPTOR_TYPE,     /* bDescriptorType */
     HID_EP_IN,                              /* bEndpointAddress */
     USB_ENDPOINT_TYPE_INTERRUPT,     /* bmAttributes */
     WBVAL(0x0004),                         /* wMaxPacketSize */
     0x20,                                   /* bInterval: 16ms */
     /* Terminator */
     0     

2. Method or function to load endpoint1 data such that USB_IQR_Handler successfully retrieves transmit data to host.

   I've introduced the method to achieve it in the above answer.

Hope it helps,

Ping

0 Kudos

810 Views
jeremyzhou
NXP TechSupport
NXP TechSupport

Hi Timothy Masters,

Thank you for your interest in NXP Semiconductor products and the opportunity to serve you.

Before answer your question, I was wondering if you can tell me which chip and LPCOpen library you use.

I'm looking forward to your reply
Have a great day,
Ping

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

810 Views
timothymasters
Contributor II

Thank you for offering to help me.  I am using the LPC11U24 part and LPCXpresso v8.20_647. I import the lpc_chip_11uxx.lib for projects using this chip. The example provided by NXP provides several files which may be different implementations of the library I am using. The example also uses UART functions that are not supported in the library of my build of LCPXpresso. 

I was able to change the UART syntax to use functions from the library and eventually got the example to compile. However, the line below in the example would not compile:

pUsbApi = (USBD_API_T*)((*(ROM **)(0x1FFF1FF8))->pUSBD);

I changed the line above to as shown below and it compiled successfully:

pUsbApi = (USBD_API_T*)((LPC_ROM_API_T*)0x1FFF1FF8))->usbdApiBase;

Question:

Does the above change accomplish the desired operation intended by the statement in the example:

After successful compile of the above, my debug session causes a hard fault after execution of this line in the example:

ret = pUsbApi->hw->Init(&hUsb, &desc, &usb_param);

I have to admit that I am not sure what is going on in this example and it is probably due to my inexperience in using ROM API's. But I am not certain that the example properly initializes the USB device stack handle prior (&hUsb argument) to this statement and thus the hard fault.

I also am not confident on how to move forward with the USB_ROM_API once I get the example to run successfully. The example does not provide information on how to retrieve and write data to the endpoints.  My application will only be using the standard endpoint 0 and endpoint 1 as an interrupt pipe as HID device.  Do you have an example that provides information on how to do this once the USB interface is successfully initialized and enumerated?

Thanks for your help.

Timothy Masters

0 Kudos

810 Views
jeremyzhou
NXP TechSupport
NXP TechSupport

Hi Timothy Masters,

Thanks for your reply.

I'd highly recommend you to refer to the lpcopen_2_12_lpcxpresso_nxp_lpcxpresso_11u68 which includes some USB ROM Drivers demos and the these demos are for HID class, CDC class,etc.

Note that, you can customize the demo through the the corresponding descriptor in the xx_desc.c file.

Hope it helps.
Have a great day,
Ping

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

810 Views
timothymasters
Contributor II

Hi Ping,

Do you have a link to this example? I am not sure where I can get this example.

Thanks

Tim

512-635-4963

0 Kudos

810 Views
Dezheng_Tang
NXP Employee
NXP Employee

You probably used a very old version of the LPCOpen example. Jeremy is right, don't try to modify your code, but use the one uploaded by NXP, compile and run it first. Here is the link: http://www.nxp.com/products/software-and-tools/hardware-development-tools/lpcxpresso-boards/lpcopen-...

You should have a file called romapi_11u6x.h where the pointer to the ROM table is defined.

0 Kudos

810 Views
timothymasters
Contributor II

Hi Dezheng,

Ok. I think I imported this correctly and tried to compile. The first error I got was this snippet:

I went into usbd_hid.h and modified the violating line with the actual count of the HID descriptor as follows:

//#define HID_DESC_SIZE sizeof(HID_DESCRIPTOR)

#define HID_DESC_SIZE 22

Now I am getting an error because it cannot find the "board.h" file. Do you know how to work around this?

I am very grateful for the help on this but I believe once I get this to compile I will still need help porting it to my application using the LCP11U24.So the first milestone is getting a successful compile. After that, I am not sure how to move this over to my application. Can you instruct me on this move?

Thanks

Tim

512-635-4963

0 Kudos

810 Views
Dezheng_Tang
NXP Employee
NXP Employee

Tim,

Maybe go through the user guide for LPCOpen 2.0 first:

http://www.nxp.com/products/software-and-tools/hardware-development-tools/lpcxpresso-boards/lpcopen-...

I think you need to compile the chip and board libraries first before compiling your application.

Just spend some time compiling and running the simple blinky or USB generic HID example first before making any change. 

0 Kudos

810 Views
timothymasters
Contributor II

Hi Dezheng,

I created a new workspace and imported:

lpcopen_v2_03_lpcxpresso_nxp_lpcxpresso_11u37h

I was then able to successfully build:

nxp_lpcxpresso_11u37_usbd_rom_hid_generic

Questions:

How do I use the source from the above project in my 11U24 project?

What changes have to be made for the include files etc?

Thanks for the help.

Tim

512-635-4963

0 Kudos

810 Views
timothymasters
Contributor II

Hi,

I have already built 10 projects in this workspace successfully. It is only the USB stuff which is causing me difficulty. I imported the project and did a build of all projects and still get an error. I am not certain what you are suggesting I did wrong. Why is the "board.h" file missing?

Tim

512-635-4963

0 Kudos