Interrupt Handling

Interrupt handling is accomplished using the following multi-level scheme.

  • Processor level kernel-aware interrupt handler
  • Device driver interrupt handler

During initialization, the device driver registers all necessary interrupt sources with the BSP interrupt management code. You can also accomplish this by plugging an interrupt vector table during compile time. Once the global interrupt vector sources are configured and an interrupt occurs, the system will call the first-level interrupt handler. The first-level interrupt handler is responsible for performing all kernel required steps prior to calling the USB device driver interrupt handler: USBD_DrvISR_Handler(). Depending on the platform architecture (that is the way the kernel handles interrupts) and the USB device controller interrupt vectors, the device driver interrupt handler implementation may follow the models below.

Single USB ISR Vector with ISR Handler Argument

If the platform architecture allows parameters to be passed to ISR handlers and the USB device controller has a single interrupt vector for the USB device, the first-level interrupt handler may be defined as:

Prototype


void  USBD_BSP_<controller>_IntHandler (void  *p_arg);


Arguments

p_arg

Pointer to USB device driver structure that must be typecast to a pointer to USBD_DRV.

Notes / Warnings

None.

Single USB ISR Vector

If the platform architecture does not allow parameters to be passed to ISR handlers and the USB device controller has a single interrupt vector for the USB device, the first-level interrupt handler may be defined as:

Prototype


void  USBD_BSP_<controller>_IntHandler (void);


Arguments

None.

Notes / Warnings

In this configuration, the pointer to the USB device driver structure must be stored globally in the driver. Since the pointer to the USB device structure is never modified, the BSP initialization function, USBD_BSP_Init(), can save its address for later use.

Multiple USB ISR Vectors with ISR Handler Arguments

If the platform architecture allows parameters to be passed to ISR handlers and the USB device controller has multiple interrupt vectors for the USB device (e.g., USB events, DMA transfers), the first-level interrupt handler may need to be split into multiple sub-handlers. Each sub-handler would be responsible for managing the status reported to the different vectors. For example, the first-level interrupt handlers for a USB device controller that redirects USB events to one interrupt vector and the status of DMA transfers to a second interrupt vector may be defined as:

Prototype


void  USBD_BSP_<controller>_EventIntHandler (void  *p_arg);
void  USBD_BSP_<controller>_DMA_IntHandler  (void  *p_arg);


Arguments

p_arg

Pointer to USB device driver structure that must be typecast to a pointer to USBD_DRV.

Notes / Warnings

None.

Multiple USB ISR Vectors

If the platform architecture does not allow parameters to be passed to ISR handlers and the USB device controller has multiple interrupt vectors for the USB device (e.g., USB events, DMA transfers), the first-level interrupt handler may need to be split into multiple sub-handlers. Each sub-handler would be responsible for managing the status reported to the different vectors. For example, the first-level interrupt handlers for a USB device controller that redirects USB events to one interrupt vector and the status of DMA transfers to a second interrupt vector may be defined as:

Prototype


void  USBD_BSP_<controller>_EventIntHandler (void);
void  USBD_BSP_<controller>_DMA_IntHandler  (void);


Arguments

None.

Notes / Warnings

In this configuration, the pointer to the USB device driver structure must be stored globally in the driver. Since the pointer to the USB device structure is never modified, the BSP initialization function, USBD_BSP_Init(), can save its address for later use.

Using USBD_DrvISR_Handler()

Table - Status Notification API
USB EventFunction associated
Connect EventUSBD_EventConn()
Disconnect EventUSBD_EventDisconn()
Reset EventUSBD_EventReset()
Suspend EventUSBD_EventSuspend()
Resume EventUSBD_EventResume()
High-Speed Handshake EventUSBD_EventHS()
Setup PacketUSBD_EventSetup()
Receive Packet CompletedUSBD_EP_RxCmpl()
Transmit Packet CompletedUSBD_EP_TxCmpl()

Each status notification API queues the event type to be processed by the USB stack’s event processing task. Upon reception of a USB event, the interrupt service routine may perform some operations associated to the event before notifying the stack. For example, the USB device controller driver must perform the proper actions for the bus reset when an interrupt request for that event is triggered. Additionally, it must also notify the USB device stack about the bus reset event by invoking the proper status notification API. In general, the device driver interrupt handler must perform the following functions:

  1. Determine which type of interrupt event occurred by reading an interrupt status register.
  2. If a receive event has occurred, the driver must post the successful completion or the error status to the USB device stack by calling USBD_EP_RxCmpl() for each transfer received.
  3. If a transmit complete event has occurred, the driver must post the successful completion or the error status to the USB device stack by calling USBD_EP_TxCmpl() for each transfer transmitted.
  4. If a setup packet event has occurred, the driver must post the setup packet data in little-endian format to the USB device stack by calling USBD_EventSetup().
  5. All other events must be posted to the USB device stack by a call to their corresponding status notification API from Table - Status Notification API. This allows the USB device stack to broadcast these event notifications to the classes.
  6. Clear local interrupt flags.