USBD ROM Stack  2.0
ROM based USB device stack
Developing with USB Device ROM Stack

This section introduces you to application development using USB ROM stack. The topics in this section describe high-level USB concepts and provide step-by-step instructions on implementing a USB device using USB ROM stack. For detailed information on USB concepts, see USB specifications at usb.org.

For advanced user who wants to change the default stack behavior by implementing custom overrides see Customizing USBD ROM Core Layer.

Prerequisites

Step1: Define USB descriptors

A USB device provides information about itself in data structures called USB descriptors to a host during enumeration process. Hence user application should create these descriptors as per the application and provide it to the ROM stack. So that the stack takes care of responding to the standard USB requests generated by the host. See Defining USB Descriptors for more details on how to define these descriptor arrays accepted by the stack.

Step2: Initializing the USBD ROM Stack

To initialize the USBD ROM stack configure the initialization parameters.

/* USB Initialization */
ret = USBD_API->hw->Init(&g_hUsb, &desc, &usb_param);
if (ret == LPC_OK) {
..... do some USB stuff...
}

Step3: Connecting USB IRQ handler

USBD ROM stack implements the interrupt handler for USB device controller and invokes the USBD ROM stack routines according to the event type. Hence application should connect this handler to the application vector table. This is done by calling USBD_HW_API_T::ISR from the USB IRQ handler as shown in the code snippet below. The USBD ROM handle passed to the ISR() routine is the one obtained in previous step.

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

Step4: Initialize and attach ROM class drivers

USBD ROM stack implements several function drivers as part of its class layer. These function drivers can be attached to their corresponding interface to handle the class specific request associated with that interface. Most of the class/function drivers implemented by the USBD ROM stack take care of the class requests sent on the default control endpoint and leave most of the data handling done on bulk/isochronous endpoints to the application. Except Mass Storage class driver which implement bulk-only handler to parse SCSI commands. See individual class driver module help pages to learn more about its behavior.

In the following example Mass Storage class driver is attached to the only interface (interface 0, alt 0) present in the device configuration shown in Defining USB Configuration Descriptors Array section.

Step5: Initialize and attach custom class drivers

To implement custom class driver or usb.org defined standard class driver which is not supported by the ROM stack, the following steps need to be followed.

Step6: Enable IRQ and connect the device.

Once the core, device controller and class drivers are initialized the stack is ready to receive the packets from host. Even if the device is physically connected to the host using an USB cable the host does not recognize the presence of device until the D+ line is pulled up using 1.5K ohm resistor (LPC device controllers operate in high-speed or full-speed mode only). To enable the connection the application software should call USBD_HW_API_T::Connect with enable set to 1. Before enabling the connection the application should enable the USB interrupt.

NVIC_EnableIRQ(USB0_IRQn); // enable USB0 interrupts
/* now connect */
USBD_API->hw->Connect(g_hUsb, 1);

Subsections :