/** **************************************************************************************** * @addtogroup PIOS PIOS Core hardware abstraction layer * @{ * @addtogroup PIOS_USB_DEFS USB standard types and definitions * @brief USB standard types and definitions * @{ * * @file pios_usb_defs.h * @author The LibrePilot Project, http://www.librepilot.org Copyright (C) 2015-2016. * The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @brief USB Standard types and definitions * @see The GNU Public License (GPL) Version 3 * ***************************************************************************************/ /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef PIOS_USB_DEFS_H #define PIOS_USB_DEFS_H #include /* uint*_t */ enum usb_desc_types { USB_DESC_TYPE_DEVICE = 0x01, USB_DESC_TYPE_CONFIGURATION = 0x02, USB_DESC_TYPE_STRING = 0x03, USB_DESC_TYPE_INTERFACE = 0x04, USB_DESC_TYPE_ENDPOINT = 0x05, USB_DESC_TYPE_IAD = 0x0B, USB_DESC_TYPE_HID = 0x21, USB_DESC_TYPE_REPORT = 0x22, USB_DESC_TYPE_CLASS_SPECIFIC = 0x24, } __attribute__((packed)); enum usb_interface_class { USB_INTERFACE_CLASS_CDC = 0x02, USB_INTERFACE_CLASS_HID = 0x03, USB_INTERFACE_CLASS_DATA = 0x0A, } __attribute__((packed)); enum usb_cdc_desc_subtypes { USB_CDC_DESC_SUBTYPE_HEADER = 0x00, USB_CDC_DESC_SUBTYPE_CALLMGMT = 0x01, USB_CDC_DESC_SUBTYPE_ABSTRACT_CTRL = 0x02, USB_CDC_DESC_SUBTYPE_UNION = 0x06, } __attribute__((packed)); enum usb_ep_attr { USB_EP_ATTR_TT_CONTROL = 0x00, USB_EP_ATTR_TT_ISOCHRONOUS = 0x01, USB_EP_ATTR_TT_BULK = 0x02, USB_EP_ATTR_TT_INTERRUPT = 0x03, } __attribute__((packed)); /* Standard macros to convert from host endian to USB endian (ie. little endian) */ #if __BIG_ENDIAN__ #define htousbs(v) \ ((uint16_t)( \ ((((v) >> 0) & 0xFF) << 8) | \ ((((v) >> 8) & 0xFF) << 0))) #define htousbl(v) \ ((uint32_t)( \ ((((v) >> 0) & 0xFF) << 24) | \ ((((v) >> 8) & 0xFF) << 16) | \ ((((v) >> 16) & 0xFF) << 8) | \ ((((v) >> 24) & 0xFF) << 0))) #else #define htousbs(v) (v) #define htousbl(v) (v) #endif #define usbstoh(v) htousbs(v) #define usbltoh(v) htousbl(v) #define USB_EP_IN(ep) ((uint8_t)(0x80 | ((ep) & 0xF))) #define USB_EP_OUT(ep) ((uint8_t)(0x00 | ((ep) & 0xF))) #define HID_ITEM_TYPE_MAIN 0x0 #define HID_ITEM_TYPE_GLOBAL 0x1 #define HID_ITEM_TYPE_LOCAL 0x2 #define HID_ITEM_TYPE_RSVD 0x3 #define HID_TAG_GLOBAL_USAGE_PAGE 0x0 /* 0b0000 */ #define HID_TAG_GLOBAL_LOGICAL_MIN 0x1 /* 0b0001 */ #define HID_TAG_GLOBAL_LOGICAL_MAX 0x2 /* 0b0010 */ #define HID_TAG_GLOBAL_PHYS_MIN 0x3 /* 0b0011 */ #define HID_TAG_GLOBAL_PHYS_MAX 0x4 /* 0b0100 */ #define HID_TAG_GLOBAL_UNIT_EXP 0x5 /* 0b0101 */ #define HID_TAG_GLOBAL_UNIT 0x6 /* 0b0110 */ #define HID_TAG_GLOBAL_REPORT_SIZE 0x7 /* 0b0111 */ #define HID_TAG_GLOBAL_REPORT_ID 0x8 /* 0b1000 */ #define HID_TAG_GLOBAL_REPORT_CNT 0x9 /* 0b1001 */ #define HID_TAG_GLOBAL_PUSH 0xA /* 0b1010 */ #define HID_TAG_GLOBAL_POP 0xB /* 0b1011 */ #define HID_TAG_MAIN_INPUT 0x8 /* 0b1000 */ #define HID_TAG_MAIN_OUTPUT 0x9 /* 0b1001 */ #define HID_TAG_MAIN_COLLECTION 0xA /* 0b1010 */ #define HID_TAG_MAIN_FEATURE 0xB /* 0b1011 */ #define HID_TAG_MAIN_ENDCOLLECTION 0xC /* 0b1100 */ #define HID_TAG_LOCAL_USAGE 0x0 /* 0b0000 */ #define HID_TAG_LOCAL_USAGE_MIN 0x1 /* 0b0001 */ #define HID_TAG_LOCAL_USAGE_MAX 0x2 /* 0b0010 */ #define HID_TAG_LOCAL_DESIG_INDEX 0x3 /* 0b0011 */ #define HID_TAG_LOCAL_DESIG_MIN 0x4 /* 0b0100 */ #define HID_TAG_LOCAL_DESIG_MAX 0x5 /* 0b0101 */ /* There is no value defined for 0x6 */ #define HID_TAG_LOCAL_STRING_INDEX 0x7 /* 0b0111 */ #define HID_TAG_LOCAL_STRING_MIN 0x8 /* 0b1000 */ #define HID_TAG_LOCAL_STRING_MAX 0x9 /* 0b1001 */ #define HID_TAG_LOCAL_DELIMITER 0xA /* 0b1010 */ #define HID_TAG_RSVD 0xF /* 0b1111 */ #define HID_ITEM_SIZE_0 0 #define HID_ITEM_SIZE_1 1 #define HID_ITEM_SIZE_2 2 #define HID_ITEM_SIZE_4 3 /* Yes, 4 bytes is represented with a size field = 3 */ #define HID_SHORT_ITEM(tag, type, size) \ ( \ (((tag) & 0xF) << 4) | \ (((type) & 0x3) << 2) | \ (((size) & 0x3) << 0)) /* Long items have a fixed prefix */ #define HID_LONG_ITEM HID_SHORT_ITEM(HID_TAG_RSVD, HID_ITEM_TYPE_RSVD, HID_ITEM_SIZE_2) #define HID_MAIN_ITEM_0(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_MAIN, HID_ITEM_SIZE_0) #define HID_MAIN_ITEM_1(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_MAIN, HID_ITEM_SIZE_1) #define HID_MAIN_ITEM_2(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_MAIN, HID_ITEM_SIZE_2) #define HID_MAIN_ITEM_4(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_MAIN, HID_ITEM_SIZE_4) #define HID_GLOBAL_ITEM_0(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_GLOBAL, HID_ITEM_SIZE_0) #define HID_GLOBAL_ITEM_1(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_GLOBAL, HID_ITEM_SIZE_1) #define HID_GLOBAL_ITEM_2(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_GLOBAL, HID_ITEM_SIZE_2) #define HID_GLOBAL_ITEM_4(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_GLOBAL, HID_ITEM_SIZE_4) #define HID_LOCAL_ITEM_0(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_LOCAL, HID_ITEM_SIZE_0) #define HID_LOCAL_ITEM_1(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_LOCAL, HID_ITEM_SIZE_1) #define HID_LOCAL_ITEM_2(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_LOCAL, HID_ITEM_SIZE_2) #define HID_LOCAL_ITEM_4(tag) HID_SHORT_ITEM((tag), HID_ITEM_TYPE_LOCAL, HID_ITEM_SIZE_4) struct usb_device_desc { 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; } __attribute__((packed)); struct usb_configuration_desc { uint8_t bLength; uint8_t bDescriptorType; uint16_t wTotalLength; uint8_t bNumInterfaces; uint8_t bConfigurationValue; uint8_t iConfiguration; uint8_t bmAttributes; uint8_t bMaxPower; } __attribute__((packed)); struct usb_interface_association_desc { uint8_t bLength; uint8_t bDescriptorType; uint8_t bFirstInterface; uint8_t bInterfaceCount; uint8_t bFunctionClass; uint8_t bFunctionSubClass; uint8_t bFunctionProtocol; uint8_t iInterface; } __attribute__((packed)); struct usb_interface_desc { uint8_t bLength; uint8_t bDescriptorType; uint8_t bInterfaceNumber; uint8_t bAlternateSetting; uint8_t bNumEndpoints; uint8_t bInterfaceClass; uint8_t bInterfaceSubClass; uint8_t nInterfaceProtocol; uint8_t iInterface; } __attribute__((packed)); struct usb_hid_desc { uint8_t bLength; uint8_t bDescriptorType; uint16_t bcdHID; uint8_t bCountryCode; uint8_t bNumDescriptors; uint8_t bClassDescriptorType; uint16_t wItemLength; } __attribute__((packed)); struct usb_endpoint_desc { uint8_t bLength; uint8_t bDescriptorType; uint8_t bEndpointAddress; uint8_t bmAttributes; uint16_t wMaxPacketSize; uint8_t bInterval; } __attribute__((packed)); struct usb_setup_request { uint8_t bmRequestType; uint8_t bRequest; uint16_t wValue; uint16_t wIndex; uint16_t wLength; } __attribute__((packed)); #define USB_REQ_TYPE_STANDARD 0x00 #define USB_REQ_TYPE_CLASS 0x20 #define USB_REQ_TYPE_VENDOR 0x40 #define USB_REQ_TYPE_MASK 0x60 #define USB_REQ_RECIPIENT_DEVICE 0x00 #define USB_REQ_RECIPIENT_INTERFACE 0x01 #define USB_REQ_RECIPIENT_ENDPOINT 0x02 #define USB_REQ_RECIPIENT_MASK 0x03 enum usb_standard_requests { USB_REQ_GET_STATUS = 0x00, USB_REQ_CLEAR_FEATURE = 0x01, /* what is 0x02? */ USB_REQ_SET_FEATURE = 0x03, /* what is 0x04? */ USB_REQ_SET_ADDRESS = 0x05, USB_REQ_GET_DESCRIPTOR = 0x06, USB_REQ_SET_DESCRIPTOR = 0x07, USB_REQ_GET_CONFIGURATION = 0x08, USB_REQ_SET_CONFIGURATION = 0x09, USB_REQ_GET_INTERFACE = 0x0A, USB_REQ_SET_INTERFACE = 0x0B, USB_REQ_SYNCH_FRAME = 0x0C, }; enum usb_hid_requests { USB_HID_REQ_GET_REPORT = 0x01, USB_HID_REQ_GET_IDLE = 0x02, USB_HID_REQ_GET_PROTOCOL = 0x03, /* 0x04-0x08 Reserved */ USB_HID_REQ_SET_REPORT = 0x09, USB_HID_REQ_SET_IDLE = 0x0A, USB_HID_REQ_SET_PROTOCOL = 0x0B, }; enum usb_cdc_requests { USB_CDC_REQ_SET_LINE_CODING = 0x20, USB_CDC_REQ_GET_LINE_CODING = 0x21, USB_CDC_REQ_SET_CONTROL_LINE_STATE = 0x22, }; struct usb_cdc_header_func_desc { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint16_t bcdCDC; } __attribute__((packed)); struct usb_cdc_callmgmt_func_desc { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bmCapabilities; uint8_t bDataInterface; } __attribute__((packed)); struct usb_cdc_acm_func_desc { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bmCapabilities; } __attribute__((packed)); struct usb_cdc_union_func_desc { uint8_t bLength; uint8_t bDescriptorType; uint8_t bDescriptorSubType; uint8_t bMasterInterface; uint8_t bSlaveInterface; } __attribute__((packed)); #define USB_LANGID_ENGLISH_US 0x0409 struct usb_string_langid { uint8_t bLength; uint8_t bDescriptorType; uint16_t bLangID; } __attribute__((packed)); struct usb_cdc_line_coding { uint32_t dwDTERate; uint8_t bCharFormat; uint8_t bParityType; uint8_t bDataBits; } __attribute__((packed)); enum usb_cdc_line_coding_stop { USB_CDC_LINE_CODING_STOP_1 = 0, USB_CDC_LINE_CODING_STOP_1_5 = 1, USB_CDC_LINE_CODING_STOP_2 = 2, } __attribute__((packed)); enum usb_cdc_line_coding_parity { USB_CDC_LINE_CODING_PARITY_NONE = 0, USB_CDC_LINE_CODING_PARITY_ODD = 1, USB_CDC_LINE_CODING_PARITY_EVEN = 2, USB_CDC_LINE_CODING_PARITY_MARK = 3, USB_CDC_LINE_CODING_PARITY_SPACE = 4, } __attribute__((packed)); struct usb_cdc_serial_state_report { uint8_t bmRequestType; uint8_t bNotification; uint16_t wValue; uint16_t wIndex; uint16_t wLength; uint16_t bmUartState; } __attribute__((packed)); enum usb_cdc_notification { USB_CDC_NOTIFICATION_SERIAL_STATE = 0x20, } __attribute__((packed)); /* * OpenPilot Specific USB Definitions */ #define USB_VENDOR_ID_OPENPILOT 0x20A0 enum usb_product_ids { USB_PRODUCT_ID_OPENPILOT_MAIN = 0x415A, USB_PRODUCT_ID_COPTERCONTROL = 0x415B, USB_PRODUCT_ID_OPLINK = 0x415C, USB_PRODUCT_ID_CC3D = 0x415D, USB_PRODUCT_ID_REVOLUTION = 0x415E, USB_PRODUCT_ID_SPARKY2 = 0x41D0, // was 0x415E during LP testing USB_PRODUCT_ID_OSD = 0x4194, USB_PRODUCT_ID_SPARE = 0x4195, } __attribute__((packed)); enum usb_op_board_ids { USB_OP_BOARD_ID_OPENPILOT_MAIN = 1, /* Board ID 2 may be unused or AHRS */ USB_OP_BOARD_ID_OPLINK = 3, USB_OP_BOARD_ID_COPTERCONTROL = 4, USB_OP_BOARD_ID_REVOLUTION = 5, USB_OP_BOARD_ID_SPARKY2 = 5, USB_OP_BOARD_ID_OSD = 6, } __attribute__((packed)); enum usb_op_board_modes { USB_OP_BOARD_MODE_BL = 1, USB_OP_BOARD_MODE_FW = 2, } __attribute__((packed)); #define USB_OP_DEVICE_VER(board_id, board_mode) \ ( \ ((board_id & 0xFF) << 8) | \ ((board_mode & 0xFF) << 0)) #endif /* PIOS_USB_DEFS_H */