diff --git a/include/usb/usb_ch9.h b/include/usb/usb_ch9.h new file mode 100644 index 00000000000..b83c0bcea72 --- /dev/null +++ b/include/usb/usb_ch9.h @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2020 PHYTEC Messtechnik GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief USB Chapter 9 structures and definitions + * + * This file contains the USB Chapter 9 structures definitions + * and follows, with few exceptions, the USB Specification 2.0. + */ + +#include +#include + +#ifndef ZEPHYR_INCLUDE_USB_CH9_H_ +#define ZEPHYR_INCLUDE_USB_CH9_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct usb_req_type_field { +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + uint8_t recipient : 5; + uint8_t type : 2; + uint8_t direction : 1; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + uint8_t direction : 1; + uint8_t type : 2; + uint8_t recipient : 5; +#endif +} __packed; + +/** USB Setup Data packet defined in spec. Table 9-2 */ +struct usb_setup_packet { + union { + uint8_t bmRequestType; + struct usb_req_type_field RequestType; + }; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +}; + +/** USB Setup packet RequestType Direction values (from Table 9-2) */ +#define USB_REQTYPE_DIR_TO_DEVICE 0 +#define USB_REQTYPE_DIR_TO_HOST 1 + +/** USB Setup packet RequestType Type values (from Table 9-2) */ +#define USB_REQTYPE_TYPE_STANDARD 0 +#define USB_REQTYPE_TYPE_CLASS 1 +#define USB_REQTYPE_TYPE_VENDOR 2 +#define USB_REQTYPE_TYPE_RESERVED 3 + +/** USB Setup packet RequestType Recipient values (from Table 9-2) */ +#define USB_REQTYPE_RECIPIENT_DEVICE 0 +#define USB_REQTYPE_RECIPIENT_INTERFACE 1 +#define USB_REQTYPE_RECIPIENT_ENDPOINT 2 +#define USB_REQTYPE_RECIPIENT_OTHER 3 + +/** Get data transfer direction from bmRequestType */ +#define USB_REQTYPE_GET_DIR(bmRequestType) (((bmRequestType) >> 7) & 0x01U) +/** Get request type from bmRequestType */ +#define USB_REQTYPE_GET_TYPE(bmRequestType) (((bmRequestType) >> 5) & 0x03U) +/** Get request recipient from bmRequestType */ +#define USB_REQTYPE_GET_RECIPIENT(bmRequestType) ((bmRequestType) & 0x1FU) + +/** + * @brief Check if request transfer direction is to host. + * + * @param setup Pointer to USB Setup packet + * @return true If transfer direction is to host + */ +static inline bool usb_reqtype_is_to_host(struct usb_setup_packet *setup) +{ + return setup->RequestType.direction == USB_REQTYPE_DIR_TO_HOST; +} + +/** + * @brief Check if request transfer direction is to device. + * + * @param setup Pointer to USB Setup packet + * @return true If transfer direction is to device + */ +static inline bool usb_reqtype_is_to_device(struct usb_setup_packet *setup) +{ + return setup->RequestType.direction == USB_REQTYPE_DIR_TO_DEVICE; +} + +/** USB Standard Request Codes defined in spec. Table 9-4 */ +#define USB_SREQ_GET_STATUS 0x00 +#define USB_SREQ_CLEAR_FEATURE 0x01 +#define USB_SREQ_SET_FEATURE 0x03 +#define USB_SREQ_SET_ADDRESS 0x05 +#define USB_SREQ_GET_DESCRIPTOR 0x06 +#define USB_SREQ_SET_DESCRIPTOR 0x07 +#define USB_SREQ_GET_CONFIGURATION 0x08 +#define USB_SREQ_SET_CONFIGURATION 0x09 +#define USB_SREQ_GET_INTERFACE 0x0A +#define USB_SREQ_SET_INTERFACE 0x0B +#define USB_SREQ_SYNCH_FRAME 0x0C + +/** Descriptor Types defined in spec. Table 9-5 */ +#define USB_DESC_DEVICE 1 +#define USB_DESC_CONFIGURATION 2 +#define USB_DESC_STRING 3 +#define USB_DESC_INTERFACE 4 +#define USB_DESC_ENDPOINT 5 +#define USB_DESC_DEVICE_QUALIFIER 6 +#define USB_DESC_OTHER_SPEED 7 +#define USB_DESC_INTERFACE_POWER 8 +/** Additional Descriptor Types defined in USB 3 spec. Table 9-5 */ +#define USB_DESC_OTG 9 +#define USB_DESC_DEBUG 10 +#define USB_DESC_INTERFACE_ASSOC 11 +#define USB_DESC_BOS 15 +#define USB_DESC_DEVICE_CAPABILITY 16 + +/** Class-Specific Descriptor Types as defined by + * USB Common Class Specification + */ +#define USB_DESC_CS_DEVICE 0x21 +#define USB_DESC_CS_CONFIGURATION 0x22 +#define USB_DESC_CS_STRING 0x23 +#define USB_DESC_CS_INTERFACE 0x24 +#define USB_DESC_CS_ENDPOINT 0x25 + +/** USB Standard Feature Selectors defined in spec. Table 9-6 */ +#define USB_SFS_ENDPOINT_HALT 0x00 +#define USB_SFS_REMOTE_WAKEUP 0x01 +#define USB_SFS_TEST_MODE 0x02 + +/** Bits used for GetStatus response defined in spec. Figure 9-4 */ +#define USB_GET_STATUS_SELF_POWERED BIT(0) +#define USB_GET_STATUS_REMOTE_WAKEUP BIT(1) + +/** Header of an USB descriptor */ +struct usb_desc_header { + uint8_t bLength; + uint8_t bDescriptorType; +} __packed; + +/** USB Standard Device Descriptor defined in spec. Table 9-8 */ +struct usb_device_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bcdUSB; + uint8_t bDeviceClass; + uint8_t bDeviceSubClass; + uint8_t bDeviceProtocol; + uint8_t bMaxPacketSize0; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; + uint8_t iManufacturer; + uint8_t iProduct; + uint8_t iSerialNumber; + uint8_t bNumConfigurations; +} __packed; + +/** USB Standard Configuration Descriptor defined in spec. Table 9-10 */ +struct usb_cfg_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t iConfiguration; + uint8_t bmAttributes; + uint8_t bMaxPower; +} __packed; + +/** USB Standard Interface Descriptor defined in spec. Table 9-12 */ +struct usb_if_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t iInterface; +} __packed; + +/** USB Standard Endpoint Descriptor defined in spec. Table 9-13 */ +struct usb_ep_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint16_t wMaxPacketSize; + uint8_t bInterval; +} __packed; + +/** USB Unicode (UTF16LE) String Descriptor defined in spec. Table 9-15 */ +struct usb_string_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t bString; +} __packed; + +/** USB Association Descriptor defined in USB 3 spec. Table 9-16 */ +struct usb_association_descriptor { + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bFirstInterface; + uint8_t bInterfaceCount; + uint8_t bFunctionClass; + uint8_t bFunctionSubClass; + uint8_t bFunctionProtocol; + uint8_t iFunction; +} __packed; + +/** USB Standard Configuration Descriptor Characteristics from Table 9-10 */ +#define USB_SCD_RESERVED BIT(7) +#define USB_SCD_SELF_POWERED BIT(6) +#define USB_SCD_REMOTE_WAKEUP BIT(5) +#define USB_SCD_ATTRIBUTES (USB_SCD_RESERVED | \ + COND_CODE_1(CONFIG_USB_SELF_POWERED, \ + (USB_SCD_SELF_POWERED), (0)) | \ + COND_CODE_1(CONFIG_USB_DEVICE_REMOTE_WAKEUP, \ + (USB_SCD_REMOTE_WAKEUP), (0))) + +/** USB Defined Base Class Codes from https://www.usb.org/defined-class-codes */ +#define USB_BCC_AUDIO 0x01 +#define USB_BCC_CDC_CONTROL 0x02 +#define USB_BCC_HID 0x03 +#define USB_BCC_MASS_STORAGE 0x08 +#define USB_BCC_CDC_DATA 0x0A +#define USB_BCC_VIDEO 0x0E +#define USB_BCC_WIRELESS_CONTROLLER 0xE0 +#define USB_BCC_MISCELLANEOUS 0xEF +#define USB_BCC_APPLICATION 0xFE +#define USB_BCC_VENDOR 0xFF + +/** USB Specification Release Numbers (bcdUSB Descriptor field) */ +#define USB_SRN_1_1 0x0110 +#define USB_SRN_2_0 0x0200 +#define USB_SRN_2_1 0x0210 + +#define USB_DEC_TO_BCD(dec) ((((dec) / 10) << 4) | ((dec) % 10)) + +/** USB Device release number (bcdDevice Descriptor field) */ +#define USB_BCD_DRN (USB_DEC_TO_BCD(KERNEL_VERSION_MAJOR) << 8 | \ + USB_DEC_TO_BCD(KERNEL_VERSION_MINOR)) + +/** Macro to obtain descriptor type from USB_SREQ_GET_DESCRIPTOR request */ +#define USB_GET_DESCRIPTOR_TYPE(wValue) ((uint8_t)((wValue) >> 8)) + +/** Macro to obtain descriptor index from USB_SREQ_GET_DESCRIPTOR request */ +#define USB_GET_DESCRIPTOR_INDEX(wValue) ((uint8_t)(wValue)) + +/** USB Control Endpoints OUT and IN Address */ +#define USB_CONTROL_EP_OUT 0 +#define USB_CONTROL_EP_IN 0x80 + +/** USB Control Endpoints maximum packet size (MPS) */ +#define USB_CONTROL_EP_MPS 64 + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_USB_CH9_H_ */