Cypress USB Device Middleware Library 2.0
Cypress USB Device Middleware Library 2.0

The USB Device middleware provides a full-speed USB 2.0 Chapter 9 specification -compliant device framework. It uses the USBFS driver from PDL to interface with the hardware. The middleware provides support for Audio, CDC, and HID classes. Also, it allows implementing other class support. The USB Configurator tool makes it easy to construct the USB Device descriptor.

Features:

General Description

The USB Device structure is divided into layers. The implementation is event-driven: the USBFS driver receives interrupts from the hardware and provides callbacks to the USB Device layer which implements them and provides events to the Class layer. A simplified image is shown below.

usb_dev_solution_struct.png

Include cy_usb_dev.h along with the header for the USB class to be used (cy_usb_dev_hid.h, cy_usb_dev_cdc.h, cy_usb_dev_audio.h) to get access to all the functions and other declarations in this library. If you use ModusToolbox USB Device Configurator, also include cycfg_usbdev.h.

Quick Start Guide

Cypress USB Device middleware can be used in various software environments. Refer to the Supported Software and Tools. The quickest way to get started is using the Code Examples. Cypress Semiconductor continuously extends its portfolio of code examples at Cypress Semiconductor website and at Cypress Semiconductor GitHub.

This quick start guide is for an environment configured to use for development PSoC 6 Peripheral Driver Library(psoc6pdl) included in the project.

To easily run a USB, use the ModusToolbox USBCommDevice or USBM project. The steps below show how to set up a USB Device based on a basic ModusToolbox project (like Hello_World).

The following steps set up a USB device recognized as an standard HID device - USB mouse and moves it from right to the left, and vice-versa.

Note
Some steps contain a corresponding to the figure below number in brackets.

STEP 1: Enable the USB Device middleware.

Launch ModusToolbox Library Manager and enable the USB Device middleware. This step is required only if the ModusToolbox IDE is used. Otherwise, ensure the USB Device Middleware is included in your project.

STEP 2: Generate initialization code.

  1. Launch the ModusToolbox Device Configurator Tool and switch to the Peripherals tab (#1.1).
  2. Enable the USB personality under Communication and enter Alias (#1.2). We use USBHID in Quick Start Guide
  3. Go to the Parameters pane and configure the USB personality: assign the peripheral clock divider (#1.3) for Clock (Bus Reset). Any available free divider can be used.
  4. Set Endpoint Mask to 1 to enable data endpoint 1 (#1.4) Enabled data endpoints must match the descriptor tree in the USB Configurator.
    usb_dev_device_cfg.png
  5. Switch to the System tab (#2.1).
  6. Check the IMO clock is enabled (#2.2). Select Trim with USB (#2.3)
  7. Select one of the PLLs, if your device supports more than one. Enable the PLL and set a frequency of 48 MHz (#2.4).
  8. Select the CLK_HF3 USB clock (#2.5). Assign the source clock to the CLK_PATH connected to the configured previously PLL (#2.6).
  9. Check the FLL clock is enabled (#2.7).
  10. Select File->Save to generate initialization code.
    usb_dev_system_cfg.png

STEP 3: Generate USB descriptors.

  1. Run the USB Configurator.
  2. In the Device Descriptor node, set bDeviceClass - 0x02(#3.1), iProduct - the device name to identify among connected devices. We use "USB Device Quick Start guide"(#3.2).
  3. Remove default Alternate Settings.
  4. Add HID Alternate Settings.
  5. Add HID Descriptor and select 3-Button Mouse in HID Report (#3.3).
  6. Add Endpoint Descriptor and set: direction - IN, Transfer Type - Interrupt, wMaxPacketSize - 3, bInterval - 10(#3.4).
  7. Perform File->Save to generate initialization code. If configuration is saved for the first time, choose a name (like design.cyusbdev) and save it to the project root.
    usb_dev_configurator.png

STEP 4: Update main.c

  1. Include the USB headers to get access to the generated descriptor structures, USB driver, device, and class layers APIs.
    #include "cy_pdl.h"
    #include "cy_usb_dev.h"
    #include "cy_usb_dev_audio.h"
    #include "cy_usb_dev_cdc.h"
    #include "cy_usb_dev_hid.h"
    #include "cycfg_usbdev.h"
    #include "cycfg.h"
  2. Declare the USB context global variables:
    /*******************************************************************************
    * Global constants
    *******************************************************************************/
    cy_stc_usbfs_dev_drv_context_t USBHID_context;
    cy_stc_usb_dev_context_t USBHID_devContext;
    cy_stc_usb_dev_hid_context_t USBHID_hidContext;
  3. Configure the USB interrupt structures and declare interrupt handlers (refer to the Configure Interrupts section of the USBFS driver in the PDL API Reference).
    /*******************************************************************************
    * USBFS interrupts functions and configurations
    *******************************************************************************/
    static void USBD_IsrLow(void);
    static void USBD_IsrMedium(void);
    static void USBD_IsrHigh(void);
    const cy_stc_sysint_t USBD_IntrHighConfig =
    {
    .intrSrc = (IRQn_Type) usb_interrupt_hi_IRQn,
    .intrPriority = 5U,
    };
    const cy_stc_sysint_t USBD_IntrMeduimConfig =
    {
    .intrSrc = (IRQn_Type) usb_interrupt_med_IRQn,
    .intrPriority = 6U,
    };
    const cy_stc_sysint_t USBD_IntrLowConfig =
    {
    .intrSrc = (IRQn_Type) usb_interrupt_lo_IRQn,
    .intrPriority = 7U,
    };
  4. Implement the interrupt handlers:
    /*******************************************************************************
    * Function Name: USBD_IsrHigh
    *******************************************************************************/
    static void USBD_IsrHigh(void)
    {
    /* Call interrupt processing */
    Cy_USBFS_Dev_Drv_Interrupt(USBHID_HW, Cy_USBFS_Dev_Drv_GetInterruptCauseHi(USBHID_HW),
    &USBHID_context);
    }
    /*******************************************************************************
    * Function Name: USBD_IsrMedium
    *******************************************************************************/
    static void USBD_IsrMedium(void)
    {
    /* Call interrupt processing */
    Cy_USBFS_Dev_Drv_Interrupt(USBHID_HW, Cy_USBFS_Dev_Drv_GetInterruptCauseMed(USBHID_HW),
    &USBHID_context);
    }
    /*******************************************************************************
    * Function Name: USBD_IsrLow
    *******************************************************************************/
    static void USBD_IsrLow(void)
    {
    /* Call interrupt processing */
    Cy_USBFS_Dev_Drv_Interrupt(USBHID_HW, Cy_USBFS_Dev_Drv_GetInterruptCauseLo(USBHID_HW),
    &USBHID_context);
    }
  5. Update the main() function with the USB and interrupt initialization routines:
    /* Initialize device hardware */
    init_cycfg_all();
    /* Initialize USB */
    status = Cy_USB_Dev_Init(USBHID_HW, &USBHID_config, &USBHID_context,
    &usb_devices[0], &usb_devConfig, &USBHID_devContext);
    if (CY_USB_DEV_SUCCESS != status)
    {
    /* Initialization error - stop execution */
    while(1);
    }
    status = Cy_USB_Dev_HID_Init(&usb_hidConfig, &USBHID_hidContext, &USBHID_devContext);
    if (CY_USB_DEV_SUCCESS != status)
    {
    /* HID Initialization error - stop execution */
    while(1);
    }
    /* Hook interrupt service routines */
    (void) Cy_SysInt_Init(&USBD_IntrLowConfig, &USBD_IsrLow);
    (void) Cy_SysInt_Init(&USBD_IntrMeduimConfig, &USBD_IsrMedium);
    (void) Cy_SysInt_Init(&USBD_IntrHighConfig, &USBD_IsrHigh);
    /* Enable interrupts */
    NVIC_EnableIRQ((IRQn_Type) USBD_IntrLowConfig.intrSrc);
    NVIC_EnableIRQ((IRQn_Type) USBD_IntrMeduimConfig.intrSrc);
    NVIC_EnableIRQ((IRQn_Type) USBD_IntrHighConfig.intrSrc);
    /* Enable interrupts */
    __enable_irq();
    /* Make device appear on the bus */
    Cy_USB_Dev_Connect(true, CY_USB_DEV_WAIT_FOREVER, &USBHID_devContext);
  6. Example of the routine to move mouse from right to the left, and vice-versa.
    const uint32_t CURSOR_X_POS = 1UL;
    const uint32_t MOUSE_DATA_LEN = 3UL;
    const uint32_t MOUSE_IN_EP = 1UL;
    const uint8_t CURSOR_STEP = 5U;
    const uint32_t STEPS_NUMBER = 96UL;
    uint8_t counter = 0U;
    bool moveRight = true;
    /* Mouse packet array: buttons (1st byte), X (2nd byte), Y (3rd byte) */
    mouseData[2U] = 0U; /* No changes in Y - position */
    for(;;)
    {
    /* Move mouse to the right or to the left appropriate number of steps */
    mouseData[CURSOR_X_POS] = moveRight ? CURSOR_STEP : (uint8_t)-CURSOR_STEP;
    /* Define direction of the movement */
    if (0U == counter)
    {
    counter = STEPS_NUMBER;
    moveRight = !moveRight;
    }
    /* Update mouse position */
    Cy_USB_Dev_WriteEpBlocking(MOUSE_IN_EP, mouseData, MOUSE_DATA_LEN,
    CY_USB_DEV_WAIT_FOREVER, &USBHID_devContext);
    counter--;
    Cy_SysLib_Delay(10UL);
    }

STEP 5: Build and program the device.

Connect the device to the Host PC. On the PC, verify a new USB device was enumerated as a mouse device. The mouse’s cursor shall move left to right and vice-versa.

Configuration Considerations

This section explains how to configure the USB Device for operation.

Configure USBFS driver

The driver and system resources configuration details are provided in the USBFS driver section Configuration Considerations in the PDL API Reference Manual. The provided code snippets expect that driver and system resources configuration is done.

Construct USB Device Descriptors

Run standalone USB Configurator tool to construct the USB Device descriptors. After USB Device descriptors are constructed, save generated source and header files. Add these files to your project. Open header files to get external definitions for:

These definitions will be required in the configuration steps provided below.

Configure USB Device

To initialize the USB Device middleware, call Cy_USB_Dev_Init function providing:

  • The pointer to the USBFS instance.
  • The pointer to the filled USBFS driver configuration structure cy_stc_usbfs_dev_drv_config_t.
  • The pointer to the allocated USBFS driver context structure cy_stc_usbfs_dev_drv_context_t.
  • The pointer to the generated middleware USB Device structure cy_stc_usb_dev_device_t.
  • The pointer to the generated middleware USB Device configuration structure cy_stc_usb_dev_config_t.
  • The pointer to the allocated middleware USB Device context structure cy_stc_usb_dev_context_t.

Configure USB Classes

The USB Device middleware provides support of Audio, HID, and CDC classes. Each class has own initialization function. This function must be called after Cy_USB_Dev_Init to initialize class data and register it. The class-specific request will be passed to the class handler after registration. Note that the USB Configurator tool generates HID and CDC Class configuration structures that are required class initialization. Find these structure external declaration in the generated header file.

To initialize the Audio Class, call Cy_USB_Dev_Audio_Init function providing:

To initialize the CDC Class, call Cy_USB_Dev_CDC_Init function providing:

To initialize the HID Class, call Cy_USB_Dev_HID_Init function providing:

Enable USB Device

Finally, enable the USB Device operation calling Cy_USB_Dev_Connect. This function call enables pull-up on D+ to signal USB Device connection on USB Bus. The USB Host detects device connection and starts device enumeration. It requests the device descriptors to define device capabilities and finally sets device configuration for the following operation. The Cy_USB_Dev_Connect provides an argument to block until enumeration completes or exits after the USB Device is enabled.

/* Allocate required context structures */
cy_stc_usbfs_dev_drv_context_t USBD_drvContext;
cy_stc_usb_dev_context_t USBD_devContext;
/* Initialize USB Device (status is ignored for code simplicity) */
(void) Cy_USB_Dev_Init(USBD_HW, &USBD_config, &USBD_drvContext,
&usb_devices[0], &usb_devConfig, &USBD_devContext);
/* Initialize requires USB Device Classes (status is ignored for code simplicity) */
(void) Cy_USB_Dev_Audio_Init(NULL, &USBD_audioContext, &USBD_devContext);
(void) Cy_USB_Dev_CDC_Init(&usb_cdcConfig, &USBD_cdcContext, &USBD_devContext);
(void) Cy_USB_Dev_HID_Init(&usb_hidConfig, &USBD_hidContext, &USBD_devContext);
/* Hook interrupt service routines */
(void) Cy_SysInt_Init(&USBD_IntrLowConfig, &USBD_IsrLow);
(void) Cy_SysInt_Init(&USBD_IntrMeduimConfig, &USBD_IsrMedium);
(void) Cy_SysInt_Init(&USBD_IntrHighConfig, &USBD_IsrHigh);
/* Enable interrupts */
NVIC_EnableIRQ((IRQn_Type) USBD_IntrLowConfig.intrSrc);
NVIC_EnableIRQ((IRQn_Type) USBD_IntrMeduimConfig.intrSrc);
NVIC_EnableIRQ((IRQn_Type) USBD_IntrHighConfig.intrSrc);
/* Enable global interrupts */
__enable_irq();
/* Make USB device appear on the bus */
Note
The interrupts are mandatory for the USB Device operation. Therefore, USBFS interrupts must be enabled in the NVIC and global interrupts must be enabled as well.

Design Considerations

The typical use case is that application calls the middleware API interface provided by the USB Device or Class layer to implement application logic. However, some features are provided only by the USBFS driver layer. Therefore, if the application needs them, the driver API interface must be used. The list of these features is provided in the section Driver Features.

USB Configurator

The standalone USB Configurator tool helps construct USB Device descriptors. The USB device descriptors provide to the USB Host complete information about the connected device. The tool output are generated source and header files that contain information about the USB Device: device descriptors plus structures that help access device descriptors. Generated files are mandatory for the middleware operation and must be added to your project. The header file provides access to instances of the USB Device configuration structure cy_stc_usb_dev_config_t and array of the USB Device structures cy_stc_usb_dev_device_t. Both these definitions are required for USB Device configuration. The tool also generates instances of configuration structures required for CDC and HID Class configuration.

A detailed information about USB Descriptors is provided by the USB Specification

The USB Configurator tool provides the User Guide, which can be found in the documentation.

Standard Request Support

The USB Device supports standard requests listed in the table below.

Standard RequestRequest Processing DescriptionUSB Spec Reference
CLEAR_FEATURE Clears or disables a specific feature. Support recipients: Device, Interface and Endpoint. The TEST_MODE feature selector is not supported. 9.4.1
GET_CONFIGURATION Returns the current device configuration value. 9.4.2
GET_DESCRIPTOR Returns the specified descriptor if the descriptor exists. 9.4.3
GET_INTERFACE Returns the selected alternate interface setting for the specified interface. 9.4.4
GET_STATUS Returns status for the specified recipient. Support recipients: Device, Interface, and Endpoint. 9.4.5
SET_ADDRESS Sets the device address for all future device accesses. 9.4.6
SET_CONFIGURATION Sets the device configuration. After this request, the device is ready for communication. 9.4.7
SET_DESCRIPTOR Not supported (optional request). 9.4.8
SET_FEATURE Enables a specific feature. Support recipients: Device, Interface, and Endpoint. The TEST_MODE feature selector is not supported. 9.4.9
SET_INTERFACE Allows the USB Host to select an alternate setting for the specified interface. 9.4.10
SYNCH_FRAME Not supported. 9.4.11

Audio Class

The USB Audio class can be used in a large amount of applications, either Made for iPod (MFI) or general USB Audio based. These applications consist of, but are not limited to, speakers, microphones, headsets, music creation tools (DJ equipment, guitar jacks, etc), and mixers. An additional application for the Audio class is in Musical Instrument Digital Interface (MIDI) applications. This interface uses a digital UART-like interface and allows the information to be sent across to the Host to be used with software applications, such as Apple Garage Band. Various instruments, such as electronic pianos, interface with MIDI.

A detailed description about Audio Class is provided by the USB Implementers Forum (USB-IF) Class Documentation

The Audio Class does not provide support any of Audio v1.0 or v2.0 requests processing and provides only the API interface to register Audio request handlers implemented on the application level. However, USB Configurator supports Audio v1.0 or v2.0 descriptors.

Note
The MIDI Class support is not available in this version.

CDC: Communication Device Class

Common use case for this class in a PSoC design is to replace a legacy serial (RS232) COM port with a USB connection. This allows customers to use legacy serial software while updating the communication interface to something more readily available on today's computers. The type of data that might be streamed across USB can vary depending on the end application. This could be as simple as streaming raw ADC counts to an entire command protocol. Additionally, CDC is extremely useful for debug purposes. Users can easily develop a USB interface that can send and receive information across CDC. On the Host side, GUI applications are widely available to view the data being transmitted, such as TeraTerm, Terminal, or Hyper-Terminal (depending on version of Microsoft Windows).

A detailed description about CDC class is provided by the USB Implementers Forum (USB-IF) Class Documentation

The CDC Class supports requests listed in the table below.

Class RequestRequest Processing DescriptionCommunications Class Subclass Specification for PSTN Devices
SET_LINE_CODING Allows the host to specify typical asynchronous line-character formatting properties such as: data terminal rate, number of stop bits, parity type and number of data bits. It applies to data transfers both from the Host to the Device and from the Device to the Host. 6.3.10
GET_LINE_CODING Allows the host to discover the currently configured line coding. 6.3.11
SET_CONTROL_LINE_STATE Generates RS-232/V.24 style control signals - RTS and DTR. 6.3.12

The CDC Class supports notifications listed in the table below.

Class NotificationNotification Processing DescriptionCommunications Class Subclass Specification for PSTN Devices
SERIAL_STATE Allows the Host to read the current state of the carrier detect (CD), DSR, break, and ring signal (RI). 6.3.4

HID: Human Interface Device

There are many possible use cases for HID depending on the end application. A keyboard/keypad is a common HID application that has been implemented previously with PSoC. Additionally, customers can use PSoC to implement a PC mouse or game controller device. A more generic use case seen is with regards to customers using USB as general-purpose interface between PSoC and the Host, without conforming to specific USAGE such as a Keyboard, Mouse, etc. Instead the user configures the HID descriptor to be a generic device, which allows them to transfer Vendor-Specific information, such as ADC data, button presses, etc., across the HID protocol. This allows customers to perform custom/generic data transfers over USB, without needing to provide an INF or SYS file during enumeration or worry about WHQL certification. All this is accomplished using the HID drivers that are built into all modern operation systems today. This includes Windows, Mac, and Linux.

A detailed description about HID is provided by the USB Implementers Forum (USB-IF) Class Documentation

The HID Class supports requests listed in the table below.

Class RequestRequest Processing DescriptionHID Spec Reference
GET_REPORT Allows the USB Host to receive a report via the control pipe. 7.2.1
SET_REPORT Allows the USB Host to send a report via the control pipe (set a state of input, output, or feature report controls). 7.2.2
GET_IDLE Reads the current idle rate for a particular Input report.
The recommended default idle rate (rate when the device is initialized) is 500 milliseconds for keyboards (delay before first repeat rate) and infinity for joysticks and mice.
7.2.3
SET_IDLE Sets idle rate for a particular report. This request is used to limit the reporting frequency of an interrupt in endpoint.
When the idle rate byte is 0 (zero), the duration is indefinite. The endpoint reports only when a change is detected in the report data. When the idle rate byte is non-zero, then a fixed duration is used (defined by idle rate).
7.2.4
GET_PROTOCOL Reads which protocol is currently active (either the boot or the report protocol). 7.2.5
SET_PROTOCOL Switches between the boot protocol and the report protocol (or vice versa). 7.2.6

Adding Custom Class

The USB Device middleware provides API interface that allows the user to implement custom class support. The middleware notifies registered class about following events:

To create a new custom Class, follow the steps below:

  1. Implement functions to service events (from the list above) required for class operation. Typically, class should implement service of class-specific requests therefore needs to implement functions defined by cy_cb_usb_dev_request_received_t and cy_cb_usb_dev_request_cmplt_t.
  2. Initialize instance of cy_stc_usb_dev_class_t structure using implemented service functions. Provide NULL pointer as function pointer if class does not use this event.
  3. Allocate instance of cy_stc_usb_dev_class_ll_item_t structure to provide storage for a linked list item of the class.
  4. The class might need a context to store class-specific data. If needed, define context type specific for this class and allocate it.
  5. To enable class operation, this needs to be registered using Cy_USB_Dev_RegisterClass function after USB Device middleware is initialized.

Any of supported classes can be taken as an example to implement a custom class.

Vendor-Specific Requests Support

The vendor-specific requests are STALLed by USB Device middleware by default. The exception is MS OS String vendor-specific request to retrieve an OS Feature Descriptor (Note that USB device must contain MS OS String descriptor to handle this vendor-specific by middleware). The middleware provides the Cy_USB_Dev_RegisterVendorCallbacks function to register callbacks to handle vendor-specific requests.

Allocate Data Endpoint Buffer

The application allocates buffers for data endpoints to operate. The buffer allocation depends on USBFS driver endpoint buffer access type configuration. It specifies which hardware register set 8-bit or 16-bit is used to access hardware endpoints buffer. The 16-bit access requires that the specific rules for the endpoints buffer allocation must be met (See Hardware Buffer Access section of the USBFS driver for more information).
To make endpoint buffer allocation configuration independent, use the CY_USB_DEV_ALLOC_ENDPOINT_BUFFER macro.

Self-Powered Devices

The USB Device responds to GET_STATUS requests based on the status set with the Cy_USB_Dev_SetPowerStatus function. To set the correct status, Cy_USB_Dev_SetPowerStatus must be called during initialization if USB Device is configured as self-powered. The Cy_USB_Dev_SetPowerStatus must be called any time the device changes status. A self-powered device also requires monitoring VBUS to control pull-up resistors. The pull-up resistor does not supply power to the data line until you call Cy_USB_Dev_Connect. Cy_USB_Dev_Disconnect disconnects the pull-up resistor from the data line. Find information about how to add VBUS monitoring in your application in the USBFS driver section VBUS Detection in the PDL API Reference Manual.

Timeout Function Redefinition

The USB Device middleware provides following blocking functions: Cy_USB_Dev_ReadEpBlocking, Cy_USB_Dev_WriteEpBlocking, and Cy_USB_Dev_Connect (the behavior defined by the blocking parameter of the connect function). The blocking functions parameter timeout defines how many milliseconds to wait before timeout. The SysLib driver function Cy_SysLib_Delay is used to implement a 1 millisecond wait cycle. The middleware provides function Cy_USB_Dev_OverwriteHandleTimeout that allows overriding the wait function implementation. This might be useful when an operation system is used in your application.

Note
The blocking function must be used carefully to not cause application lock-up. The preferred solution is using non-blocking functions.

Driver Features

There are driver features that do not have corresponding an API interface provided in the middleware. However, the application might need these features for USB Device implementation. If there is such a need, the driver functions must be used. These features are listed below:

  • Data Endpoint 1 - 8 Completion, SOF received and LPM transfer ACKed events notification.
  • Low power support: Suspend / Resume, Remote wakeup signaling.
  • Link Power Management (LPM) support.

Find more information in the appropriate section of the USBFS driver documentation provided in the PDL API Reference Manual.

Supported Software and Tools

This version of the USB Device Middleware was validated for the compatibility with the following Software and Tools:

Software and Tools Version
ModusToolbox Software Environment 2.0
- ModusToolbox Device Configurator 2.0
- ModusToolbox USB Device Personality in Device Configurator 1.1
- ModusToolbox USB Device Configurator 2.0
PSoC6 Peripheral Driver Library (PDL) 1.3.0
GCC Compiler 7.2.1
IAR Compiler 8.32
ARM Compiler 6 6.11

MISRA-C Compliance

The MISRA-C Compliant verification is not performed for Beta release.

MISRA Rule Rule Class (Required/Advisory) Rule Description Description of Deviation(s)
11.4 A A cast should not be performed between a pointer to object type and a different pointer to object type. A cast involving pointers is conducted with caution that the pointers are correctly aligned for the type of object being pointed to.
11.5 R A cast shall not be performed that removes any const or volatile qualification from the type addressed by a pointer.
  1. All device descriptors are stored in flash. On the USB Host get descriptor request, the pointer to descriptor is assigned to a pointer that manages data transfer losing const qualification. Despite the qualification being lost, the middleware does not perform any write access using this pointer.
  2. Some device characteristics are stored in volatile variables. On the USB Host request, the pointer to a characteristic variable is assigned to a pointer that manages data transfer losing volatile qualification. Despite the qualification being lost, this does not cause any negative impact because the data transfer is managed by the interrupt handler. The same happens when these variables are passed as parameters to memcpy or memset function.
14.7 R A function shall have a single point of exit at the end of the function. The functions can return from several points. This is typically done to improve code clarity when returning error status code if input parameters validation fails.
16.7 A A pointer parameter in a function prototype should be declared as a pointer to const if the pointer is not used to modify the addressed object. The usbfs driver and middleware defines general function prototypes and pointers to functions types but the function's implementation depends on configuration. Therefore, some functions' implementation require parameters to be pointers to const. This is not met because of the generalized implementation approach.

Errata

This section lists the known problems with the USB Device middleware.

Cypress IDKnown IssueWorkaround
DRIVERS-1401 The USB Device ignores LPM requests after wake up from Deep Sleep. Call USBFS driver Cy_USBFS_Dev_Drv_Lpm_SetResponse() after calling Cy_USBFS_Dev_Drv_Resume() to restore response to the LPM packets.
DRIVERS-1427 The USB Device modes with DMA do not work after wake up from Deep Sleep, due to incorrect restore of the ARB_CFG register. Save ARB_CFG values before entering Deep Sleep and restore it after calling of Cy_USBFS_Dev_Drv_Resume.
/* Read and save value of ARB_CFG register
* USBD_HW is a pointer to the base address of USBFS Device */
uint32_t tempReg = USBFS_DEV_ARB_CFG(USBD_HW);
/* Entering Deep Sleep */
/* Resume after Deep Sleep */
Cy_USBFS_Dev_Drv_Resume(USBD_HW, &USBD_context);
/* Restore ARB_CFG register after deep sleep */
USBFS_DEV_ARB_CFG(USBD_HW) &= (~USBFS_USBDEV_ARB_CFG_CFG_CMP_Msk);
USBFS_DEV_ARB_CFG(USBD_HW) = tempReg;
(void) USBFS_DEV_ARB_CFG(USBD_HW);

Changelog

VersionChangesReason for Change
2.0 Updated the internal processing to support USBFS driver updates. The USBFS driver is updated to v2.0.
Moved the timeout from Cy_USB_Dev_AbortEpTransfer() to the driver layer. The maximum function's wait time is significantly reduced. Align with the changes of the USBFS driver.
Changed the functions parameter name and the structure member name class to classObj. Fixed the ambiguity related to the usage of the C++ keyword class as a name.
Enclosed middleware sources within a conditional compilation to exclude the USB Device middleware for devices without USB hardware. Fixed a compilation error for devices without USB hardware.
Updated the major and minor version defines to follow the naming convention.
1.0 The initial version.

More Information

For more detail, refer to the following documents:

Note
The links to the other software component’s documentation (middleware and PDL) point to GitHub to the software latest available version. To get documentation of the specified version, download from GitHub and unzip the component archive. The documentation is available in the docs folder.