HID keyboard + HID generic composite device example
In this section, HID keyboard + HID generic composite device are used as an example.
USB composite device structure examples
/* Two HID classes */
usb_device_class_config_list_struct_t g_UsbDeviceCompositeConfigList =
{
g_CompositeClassConfig,
USB_DeviceCallback,
2U,
};
/* Two HID classes definition */
usb_device_class_config_struct_t g_CompositeClassConfig[2] =
{
{
USB_DeviceHidKeyboardCallback,
(class_handle_t)NULL,
&g_UsbDeviceHidKeyboardConfig,
},
{
USB_DeviceHidGenericCallback,
(class_handle_t)NULL,
&g_UsbDeviceHidGenericConfig,
}
};
/* HID generic device config */
usb_device_class_struct_t g_UsbDeviceHidGenericConfig =
{
g_UsbDeviceHidGenericInterfaceList, /* The interface list of the HID generic */
kUSB_DeviceClassTypeHid, /* The HID class type */
USB_DEVICE_CONFIGURATION_COUNT, /* The configuration count */
};
/* HID generic device interface list */
usb_device_interface_list_t g_UsbDeviceHidGenericInterfaceList[USB_DEVICE_CONFIGURATION_COUNT] =
{
{
USB_HID_GENERIC_INTERFACE_COUNT, /* The interface count of the HID generic */
g_UsbDeviceHidGenericInterfaces, /* The interfaces handle */
},
};
/* HID generic device interfaces */
usb_device_interfaces_struct_t g_UsbDeviceHidGenericInterfaces[USB_HID_GENERIC_INTERFACE_COUNT] =
{
USB_HID_GENERIC_CLASS, /* HID generic class code */
USB_HID_GENERIC_SUBCLASS, /* HID generic subclass code */
USB_HID_GENERIC_PROTOCOL, /* HID generic protocol code */
USB_HID_GENERIC_INTERFACE_INDEX, /* The interface number of the HID generic */
g_UsbDeviceHidGenericInterface, /* Interfaces handle */
sizeof(g_UsbDeviceHidGenericInterface) / sizeof(usb_device_interface_struct_t),
};
/* HID generic device interface and alternate setting device information */
usb_device_interface_struct_t g_UsbDeviceHidGenericInterface[] =
{
{
0U, /* The alternate setting of the interface */
{
USB_HID_GENERIC_ENDPOINT_COUNT, /* Endpoint count */
g_UsbDeviceHidGenericEndpoints, /* Endpoints handle */
},
}
};
/* HID generic device endpoint information for interface USB_HID_GENERIC_INTERFACE_INDEX and alternate setting is 0. */
usb_device_endpoint_struct_t g_UsbDeviceHidGenericEndpoints[USB_HID_GENERIC_ENDPOINT_COUNT] =
{
/* HID generic interrupt IN pipe */
{
USB_HID_GENERIC_ENDPOINT_IN | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
USB_ENDPOINT_INTERRUPT,
FS_HID_GENERIC_INTERRUPT_IN_PACKET_SIZE,
},
/* HID generic interrupt OUT pipe */
{
USB_HID_GENERIC_ENDPOINT_OUT | (USB_OUT << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
USB_ENDPOINT_INTERRUPT,
FS_HID_GENERIC_INTERRUPT_OUT_PACKET_SIZE,
},
};
/* HID keyboard device config */
usb_device_class_struct_t g_UsbDeviceHidKeyboardConfig =
{
g_UsbDeviceHidKeyboardInterfaceList, /* The interface list of the HID keyboard */
kUSB_DeviceClassTypeHid, /* The HID class type */
USB_DEVICE_CONFIGURATION_COUNT, /* The configuration count */
};
/* HID keyboard device interface list */
usb_device_interface_list_t g_UsbDeviceHidKeyboardInterfaceList[USB_DEVICE_CONFIGURATION_COUNT] =
{
{
USB_HID_KEYBOARD_INTERFACE_COUNT, /* The interface count of the HID keyboard */
g_UsbDeviceHidKeyboardInterfaces, /* The interfaces handle */
},
};
/* HID generic device interfaces */
usb_device_interfaces_struct_t g_UsbDeviceHidKeyboardInterfaces[USB_HID_KEYBOARD_INTERFACE_COUNT] =
{
USB_HID_KEYBOARD_CLASS, /* HID keyboard class code */
USB_HID_KEYBOARD_SUBCLASS, /* HID keyboard subclass code */
USB_HID_KEYBOARD_PROTOCOL, /* HID keyboard protocol code */
USB_HID_KEYBOARD_INTERFACE_INDEX, /* The interface number of the HID keyboard */
g_UsbDeviceHidKeyboardInterface, /* Interfaces handle */
sizeof(g_UsbDeviceHidKeyboardInterface) / sizeof(usb_device_interface_struct_t),
};
/* HID generic device interface and alternate setting device information */
usb_device_interface_struct_t g_UsbDeviceHidKeyboardInterface[] =
{
{
0U, /* The alternate setting of the interface */
{
USB_HID_KEYBOARD_ENDPOINT_COUNT, /* Endpoint count */
g_UsbDeviceHidKeyboardEndpoints, /* Endpoints handle */
},
}
};
/* HID generic device endpoint information for interface USB_HID_GENERIC_INTERFACE_INDEX and alternate setting is 0. */
usb_device_endpoint_struct_t g_UsbDeviceHidKeyboardEndpoints[USB_HID_KEYBOARD_ENDPOINT_COUNT] =
{
/* HID keyboard interrupt IN pipe */
{
USB_HID_KEYBOARD_ENDPOINT_IN | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
USB_ENDPOINT_INTERRUPT,
FS_HID_KEYBOARD_INTERRUPT_IN_PACKET_SIZE,
},
};
Parent topic:HID keyboard + HID generic composite device example
USB composite device descriptor examples
Modify the vendor ID and product ID for the device descriptor in the “usb_device_descriptor.c” file.
Change the interface number as shown in the configuration descriptor in the “usb_device_descriptor.c” file.
Merge the HID keyboard and HID generic configuration descriptor (in the “usb_device_descriptor.c” file) from the HID mouse + HID keyboard example and hid_generic example and change the endpoint number to be consistent with section USB composite device structure examples.
Parent topic:HID keyboard + HID generic composite device example
USB composite device application example
Class configuration
USB_DEVICE_CONFIG_HID is set to 2 in usb_device_config.h
USB_DEVICE_CONFIG_ENDPOINTS is set to 4 in usb_device_config.h
Parent topic:USB composite device application example
HID + HID Application structure
typedef struct _usb_device_composite_struct
{
usb_device_handle deviceHandle;
class_handle_t hidKeyboardHandle;
class_handle_t hidGenericHandle;
uint8_t speed;
uint8_t attach;
uint8_t currentConfiguration;
uint8_t currentInterfaceAlternateSetting[USB_COMPOSITE_INTERFACE_COUNT];
} usb_device_composite_struct_t;
/* HID keyboard structure */
typedef struct _usb_device_hid_keyboard_struct
{
uint8_t buffer[USB_HID_KEYBOARD_IN_BUFFER_LENGTH];
uint8_t idleRate;
} usb_device_hid_keyboard_struct_t;
/* HID generic structure */
typedef struct _usb_device_hid_generic_struct
{
uint32_t buffer[2][USB_HID_GENERIC_IN_BUFFER_LENGTH>>2];
uint8_t bufferIndex;
uint8_t idleRate;
} usb_device_hid_generic_struct_t;
Parent topic:USB composite device application example
HID + HID application
Define and initialize the configuration structure.
static usb_device_composite_struct_t g_UsbDeviceComposite; usb_device_class_struct_t g_UsbDeviceHidGenericConfig; usb_device_class_struct_t g_UsbDeviceHidKeyboardConfig; usb_device_class_config_struct_t g_CompositeClassConfig[2] = { { USB_DeviceHidKeyboardCallback, (class_handle_t)NULL, &g_UsbDeviceHidKeyboardConfig, }, { USB_DeviceHidGenericCallback, (class_handle_t)NULL, &g_UsbDeviceHidGenericConfig, } }; usb_device_class_config_list_struct_t g_UsbDeviceCompositeConfigList = { g_CompositeClassConfig, USB_DeviceCallback, 2U, };
Add USB ISR.
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) void USBHS_IRQHandler(void) { USB_DeviceEhciIsrFunction(g_UsbDeviceComposite.deviceHandle); } #endif #if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U) void USB0_IRQHandler(void) { USB_DeviceKhciIsrFunction(g_UsbDeviceComposite.deviceHandle); } #endif #if defined(USB_DEVICE_CONFIG_LPC3511IP) && (USB_DEVICE_CONFIG_LPC3511IP > 0U) void USB0_IRQHandler(void) { USB_DeviceLpc3511IpIsrFunction(g_UsbDeviceHidMouse.deviceHandle); } #endif
Enable the USB device clock.
#if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) CLOCK_EnableUsbhs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk)); USB_EhciPhyInit(CONTROLLER_ID, BOARD_XTAL0_CLK_HZ); #endif #if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U) #if ((defined FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED) && (FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED)) CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U); #else CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk)); #endif /* FSL_FEATURE_USB_KHCI_IRC48M_MODULE_CLOCK_ENABLED */ #endif #if defined(USB_DEVICE_CONFIG_LPC3511IP) && (USB_DEVICE_CONFIG_LPC3511IP > 0U) CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcFro, CLOCK_GetFreq(kCLOCK_FroHf)); #endif
Set the default state.
g_UsbDeviceComposite.speed = USB_SPEED_FULL; g_UsbDeviceComposite.attach = 0U; g_UsbDeviceComposite.hidGenericHandle = (class_handle_t)NULL; g_UsbDeviceComposite.hidKeyboardHandle = (class_handle_t)NULL; g_UsbDeviceComposite.deviceHandle = NULL;
Initialize the USB device.
if (kStatus_USB_Success != USB_DeviceClassInit(CONTROLLER_ID, &g_UsbDeviceCompositeConfigList, &g_UsbDeviceComposite.deviceHandle)) { usb_echo("USB device composite demo init failed\r\n"); return; } else { usb_echo("USB device composite demo\r\n"); … }
Save each class handle when the device is initialized successfully.
/* Get the HID keyboard class handle */ g_UsbDeviceComposite.hidKeyboardHandle = g_UsbDeviceCompositeConfigList.config[0].classHandle; /* Get the HID generic class handle */ g_UsbDeviceComposite.hidGenericHandle = g_UsbDeviceCompositeConfigList.config[1].classHandle;
Initialize the HID keyboard and HID generic application.
USB_DeviceHidKeyboardInit(&g_UsbDeviceComposite); USB_DeviceHidGenericInit(&g_UsbDeviceComposite);
Set the device ISR priority and enable the device interrupt.
NVIC_SetPriority((IRQn_Type)irqNumber, USB_DEVICE_INTERRUPT_PRIORITY); NVIC_EnableIRQ((IRQn_Type)irqNumber);
Start the device functionality.
USB_DeviceRun(g_UsbDeviceComposite.deviceHandle);
Poll the device task when the “USB_DEVICE_CONFIG_USE_TASK” is non-zero. Poll the HID keyboard and HID generic task when these tasks are implemented.
#if USB_DEVICE_CONFIG_USE_TASK #if defined(USB_DEVICE_CONFIG_EHCI) && (USB_DEVICE_CONFIG_EHCI > 0U) USB_DeviceEhciTaskFunction(g_UsbDeviceComposite.deviceHandle); #endif #if defined(USB_DEVICE_CONFIG_KHCI) && (USB_DEVICE_CONFIG_KHCI > 0U) USB_DeviceKhciTaskFunction(g_UsbDeviceComposite.deviceHandle); #endif #if defined(USB_DEVICE_CONFIG_LPC3511IP) && (USB_DEVICE_CONFIG_LPC3511IP > 0U) USB_DeviceLpc3511IpTaskFunction(g_UsbDeviceHidMouse.deviceHandle); #endif #endif
Parent topic:USB composite device application example
Parent topic:HID keyboard + HID generic composite device example