 /*++

	VER_LEGALCOPYRIGHT_STR

Module Name:

    silabs_usb.h

Abstract:

    A top-level, across-all-repos, collection of some "useful" USB-related defines/enums

Environment:

    User or kernel mode

--*/
//
#if (_MSC_VER > 1000)
#pragma once
#endif

#ifndef	HOST_COMMON_INCLUDE_SILABS_USB_H_INCLUDED_PV1HTZ2O7E
#define	HOST_COMMON_INCLUDE_SILABS_USB_H_INCLUDED_PV1HTZ2O7E

#include	"silabs_sal.h"

#if	! defined(__cplusplus)
#define bool BOOLEAN
#endif // ! defined(__cplusplus)

// USB Descriptors
typedef enum _SILABS_USB_DESCRIPTORS_LENGTH {	// Aret hese absolutes? maxs? Or mins?
	SILABS_USB_DESCRIPTORS_LENGTH_DEVICE_DESCRIPTOR = ((BYTE)12)
	, SILABS_USB_DESCRIPTORS_LENGTH_CONFIGURATION_DESCRIPTOR = ((BYTE)9)	// not fixed size?
	, SILABS_USB_DESCRIPTORS_LENGTH_STRING_DESCRIPTOR = ((BYTE)8)
	, SILABS_USB_DESCRIPTORS_LENGTH_INTERFACE_DESCRIPTOR = ((BYTE)9)	// not fixed size?
	, SILABS_USB_DESCRIPTORS_LENGTH_ENDPOINT_DESCRIPTOR = ((BYTE)7)
} SILABS_USB_DESCRIPTORS_LENGTH, *PSILABS_USB_DESCRIPTORS_LENGTH;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_DESCRIPTORS_LENGTH(_In_ const SILABS_USB_DESCRIPTORS_LENGTH _l) {
	return ((SILABS_USB_DESCRIPTORS_LENGTH_ENDPOINT_DESCRIPTOR <= _l) || (SILABS_USB_DESCRIPTORS_LENGTH_DEVICE_DESCRIPTOR >= _l));
}
typedef enum _SILABS_USB_DESCRIPTORS_TYPE {
	SILABS_USB_DESCRIPTORS_TYPE_DEVICE_DESCRIPTOR = ((BYTE)0x01)
	, SILABS_USB_DESCRIPTORS_TYPE_CONFIGURATION_DESCRIPTOR = ((BYTE)0x02)
	, SILABS_USB_DESCRIPTORS_TYPE_STRING_DESCRIPTOR = ((BYTE)0x03)
	, SILABS_USB_DESCRIPTORS_TYPE_INTERFACE_DESCRIPTOR = ((BYTE)0x04)
	, SILABS_USB_DESCRIPTORS_TYPE_ENDPOINT_DESCRIPTOR = ((BYTE)0x05)
} SILABS_USB_DESCRIPTORS_TYPE, *PSILABS_USB_DESCRIPTORS_TYPE;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_DESCRIPTORS_TYPE(_In_ const SILABS_USB_DESCRIPTORS_TYPE _t) {
	return ((SILABS_USB_DESCRIPTORS_TYPE_DEVICE_DESCRIPTOR <= _t) && (SILABS_USB_DESCRIPTORS_TYPE_ENDPOINT_DESCRIPTOR >= _t));
}

//	Device Descriptor
//	Configuration Descriptor
//	String Descriptor
// Maximum String Lengths (in characters (not bytes required to store those characters (for multi-byte encodings)); not including any nul-termination, if present)
// Maximum Number of Characters Per String Descriptor:
//         Product        Manufacturer      Serial Number       Interface
// CP2101    126                12                63                N / A
// CP2102    126                29                63                N / A
// CP2102N   128                64                64                N / A
// CP2103    126                29                63                N / A               Note: All number are *character* counts
// CP2104    126                29                63                N / A               Note: Device stores strings as 16-bit UCS-2 character strings (I.e. two bytes per character)
// CP2105     47                12                16                   32
// CP2108    126               126               126                  126
// CP2109    126                12                63                N / A

// Product String
typedef enum _SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX {
	SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP210X = 126
	, SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP2102N = 128
	, SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP2105 = 47
} SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX, *PSILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX _l) {
	return ((SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP210X == _l) || (SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP2102N == _l) || (SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP2105 == _l));
}
typedef enum _SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX {
	SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX_CP210X = 2 * SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP210X
	, SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX_CP2102N = 2 * SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP2102N
	, SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX_CP2105 = 2 * SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_CHARS_MAX_CP2105
} SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX, *PSILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX _l) {
	return ((SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX_CP210X == _l) || (SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX_CP2102N == _l) || (SILABS_USB_STRING_DESCRIPTOR_PRODUCT_STRING_LENGTH_IN_BYTES_MAX_CP2105 == _l));
}

// Manufacturer String
typedef enum _SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_MAX_IN_CHARS {
	SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2101 = 12
	, SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2102 = 29
	, SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2102N = 128
	, SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2103 = 29
	, SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2104 = 29
	, SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2105 = 12
	, SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2108 = 126
	, SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2109 = 12
} SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX, *PSILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX _l) {
#pragma warning ( push )
#pragma warning ( disable : 6287 ) // warning C6287: redundant code: the left and right sub-expressions are identical
	return ((SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2101 == _l) || (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2102 == _l)
			|| (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2102N == _l) || (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2103 == _l)
			|| (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2104 == _l) || (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2105 == _l)
			|| (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2108 == _l) || (SILABS_USB_STRING_DESCRIPTOR_MANUFACTURER_STRING_LENGTH_IN_CHARS_MAX_CP2109 == _l));
#pragma warning ( pop )
}

// Serial Number String
typedef enum _SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX {
	SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP210X = 63
	, SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2102N = 64
	, SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2105 = 16
	, SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2108 = 126
} SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX, *PSILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX _l) {
	return ((SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP210X == _l) || (SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2102N == _l)
			|| (SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2105 == _l) || (SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2108 == _l));
}
typedef enum _SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX {
	SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP210X = 2 * SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP210X
	, SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP2102N = 2 * SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2102N
	, SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP2105 = 2 * SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2105
	, SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP2108 = 2 * SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_CHARS_MAX_CP2108
} SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX, *PSILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX _l) {
	return ((SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP210X == _l) || (SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP2102N == _l)
			|| (SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP2105 == _l) || (SILABS_USB_STRING_DESCRIPTOR_SERIAL_STRING_LENGTH_IN_BYTES_MAX_CP2108 == _l));
}

// Interface String
typedef enum _SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX {
	SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX_CP2105 = 32
	, SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX_CP2108 = 126
} SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX, *PSILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX _l) {
	return ((SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX_CP2105 == _l) || (SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX_CP2108 == _l));
}
typedef enum _SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX {
	SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX_CP2105 = 2 * SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX_CP2105
	, SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX_CP2108 = 2 * SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_CHARS_MAX_CP2108
} SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX, *PSILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX(_In_ const SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX _l) {
	return ((SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX_CP2105 == _l) || (SILABS_USB_STRING_DESCRIPTOR_INTERFACE_STRING_LENGTH_IN_BYTES_MAX_CP2108 == _l));
}

//	Interface Descriptor
//	Endpoint Descriptor

// RequestType - defined in Table 9.2 of section 9.3 of the Universal Serial Bus(USB) specification (www.usb.org).
// The RequestType field will determine the direction of the request, type of request and designated recipient.
// Data Transfer Direction
typedef enum _SILABS_USB_REQUESTTYPE_DIRECTION {
	SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE = ((BYTE)0x00)
	, SILABS_USB_REQUESTTYPE_DIRECTION_DEVICE_TO_HOST = ((BYTE)(0x01 << 7))
} SILABS_USB_REQUESTTYPE_DIRECTION, *PSILABS_USB_REQUESTTYPE_DIRECTION;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_REQUESTTYPE_DIRECTION(_In_ const SILABS_USB_REQUESTTYPE_DIRECTION _d) {
	return ((SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE == _d) || (SILABS_USB_REQUESTTYPE_DIRECTION_DEVICE_TO_HOST == _d));
}
// Bits 6-5 of RequestType indicate the type of the request (Standard, Class, or Vendor).
// Standard requests are common to all USB devices.
// Class requests are common to classes of drivers. For example, all devices conforming to the HID class will have a common set of class specific requests.
typedef enum _SILABS_USB_REQUESTTYPE_TYPE {
	SILABS_USB_REQUESTTYPE_TYPE_STANDARD = ((BYTE)0x00)
	, SILABS_USB_REQUESTTYPE_TYPE_CLASS = ((BYTE)(0x01 << 5))
	, SILABS_USB_REQUESTTYPE_TYPE_VENDOR = ((BYTE)(0x02 << 5))
	, SILABS_USB_REQUESTTYPE_TYPE_RESERVED = ((BYTE)(0x03 << 5))
} SILABS_USB_REQUESTTYPE_TYPE, *PSILABS_USB_REQUESTTYPE_TYPE;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_REQUESTTYPE_TYPE(_In_ const SILABS_USB_REQUESTTYPE_TYPE _t) {
	return ((SILABS_USB_REQUESTTYPE_TYPE_STANDARD == _t) || (SILABS_USB_REQUESTTYPE_TYPE_CLASS == _t)
			||(SILABS_USB_REQUESTTYPE_TYPE_VENDOR == _t) || (SILABS_USB_REQUESTTYPE_TYPE_RESERVED == _t));
}
// The lowest two bits of RequestType indicate the recipient of the request (device, interface, endpoint or other).
// If the recipient is the device, the lowest two bits of RequestType value must be 0.
// If the recipient is an interface, the lowest two bits of RequestType value must be 0x01.
// If the recipient is an endpoint, the lowest two bits of RequestType value must be 0x02.
typedef enum _SILABS_USB_REQUESTTYPE_RECIPIENT {
	SILABS_USB_REQUESTTYPE_RECIPIENT_HOST = ((BYTE)0x00)
	, SILABS_USB_REQUESTTYPE_RECIPIENT_DEVICE = ((BYTE)0x00)
	, SILABS_USB_REQUESTTYPE_RECIPIENT_INTERFACE = ((BYTE)0x01)
	, SILABS_USB_REQUESTTYPE_RECIPIENT_ENDPOINT = ((BYTE)0x02)
	, SILABS_USB_REQUESTTYPE_RECIPIENT_OTHER = ((BYTE)0x03)
} SILABS_USB_REQUESTTYPE_RECIPIENT, *PSILABS_USB_REQUESTTYPE_RECIPIENT;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_REQUESTTYPE_RECIPIENT(_In_ const SILABS_USB_REQUESTTYPE_RECIPIENT _r) {
	return ((SILABS_USB_REQUESTTYPE_RECIPIENT_HOST <= _r) && (_r <= SILABS_USB_REQUESTTYPE_RECIPIENT_ENDPOINT));
}

#define	SILABS_USB_REQUESTTYPE_MAKE(_direction, _type, _recipient)	((BYTE)((_direction) | (_type) | (_recipient)))
typedef enum _SILABS_USB_REQUESTTYPE {
	SILABS_USB_REQUESTTYPE_STANDARD_HOST_TO_DEVICE_DEVICE		= SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_STANDARD, SILABS_USB_REQUESTTYPE_RECIPIENT_DEVICE)
	, SILABS_USB_REQUESTTYPE_STANDARD_HOST_TO_DEVICE_INTERFACE	= SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_STANDARD, SILABS_USB_REQUESTTYPE_RECIPIENT_INTERFACE)
	, SILABS_USB_REQUESTTYPE_STANDARD_HOST_TO_DEVICE_ENDPOINT	= SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_STANDARD, SILABS_USB_REQUESTTYPE_RECIPIENT_ENDPOINT)
	, SILABS_USB_REQUESTTYPE_STANDARD_DEVICE_TO_HOST			= SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_DEVICE_TO_HOST, SILABS_USB_REQUESTTYPE_TYPE_STANDARD, SILABS_USB_REQUESTTYPE_RECIPIENT_HOST)

	, SILABS_USB_REQUESTTYPE_CLASS_HOST_TO_DEVICE_DEVICE		= SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_CLASS, SILABS_USB_REQUESTTYPE_RECIPIENT_DEVICE)
	, SILABS_USB_REQUESTTYPE_CLASS_HOST_TO_DEVICE_INTERFACE		= SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_CLASS, SILABS_USB_REQUESTTYPE_RECIPIENT_INTERFACE)
	, SILABS_USB_REQUESTTYPE_CLASS_HOST_TO_DEVICE_ENDPOINT		= SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_CLASS, SILABS_USB_REQUESTTYPE_RECIPIENT_ENDPOINT)
	, SILABS_USB_REQUESTTYPE_CLASS_DEVICE_TO_HOST				= SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_DEVICE_TO_HOST, SILABS_USB_REQUESTTYPE_TYPE_CLASS, SILABS_USB_REQUESTTYPE_RECIPIENT_HOST)

	, SILABS_USB_REQUESTTYPE_VENDOR_HOST_TO_DEVICE_DEVICE		= SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_VENDOR, SILABS_USB_REQUESTTYPE_RECIPIENT_DEVICE)
	, SILABS_USB_REQUESTTYPE_VENDOR_HOST_TO_DEVICE_INTERFACE	= SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_VENDOR, SILABS_USB_REQUESTTYPE_RECIPIENT_INTERFACE)
	, SILABS_USB_REQUESTTYPE_VENDOR_HOST_TO_DEVICE_ENDPOINT		= SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_HOST_TO_DEVICE, SILABS_USB_REQUESTTYPE_TYPE_VENDOR, SILABS_USB_REQUESTTYPE_RECIPIENT_ENDPOINT)
	, SILABS_USB_REQUESTTYPE_VENDOR_DEVICE_TO_HOST				= SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_DEVICE_TO_HOST, SILABS_USB_REQUESTTYPE_TYPE_VENDOR, SILABS_USB_REQUESTTYPE_RECIPIENT_HOST)
	, SILABS_USB_REQUESTTYPE_VENDOR_DEVICE_TO_HOST_INTERFACE	= SILABS_USB_REQUESTTYPE_MAKE(SILABS_USB_REQUESTTYPE_DIRECTION_DEVICE_TO_HOST, SILABS_USB_REQUESTTYPE_TYPE_VENDOR, SILABS_USB_REQUESTTYPE_RECIPIENT_INTERFACE)
} SILABS_USB_REQUESTTYPE, *PSILABS_USB_REQUESTTYPE;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_REQUESTTYPE(_In_ const SILABS_USB_REQUESTTYPE _r) {
	return ((SILABS_USB_REQUESTTYPE_STANDARD_HOST_TO_DEVICE_DEVICE == _r) || (SILABS_USB_REQUESTTYPE_STANDARD_HOST_TO_DEVICE_INTERFACE == _r)
			|| (SILABS_USB_REQUESTTYPE_STANDARD_HOST_TO_DEVICE_ENDPOINT == _r) || (SILABS_USB_REQUESTTYPE_STANDARD_DEVICE_TO_HOST == _r)
			|| (SILABS_USB_REQUESTTYPE_CLASS_HOST_TO_DEVICE_DEVICE == _r) || (SILABS_USB_REQUESTTYPE_CLASS_HOST_TO_DEVICE_INTERFACE == _r)
			|| (SILABS_USB_REQUESTTYPE_CLASS_HOST_TO_DEVICE_ENDPOINT == _r) || (SILABS_USB_REQUESTTYPE_CLASS_DEVICE_TO_HOST == _r)
			|| (SILABS_USB_REQUESTTYPE_VENDOR_HOST_TO_DEVICE_DEVICE == _r) || (SILABS_USB_REQUESTTYPE_VENDOR_HOST_TO_DEVICE_INTERFACE == _r)
			|| (SILABS_USB_REQUESTTYPE_VENDOR_HOST_TO_DEVICE_ENDPOINT == _r) || (SILABS_USB_REQUESTTYPE_VENDOR_DEVICE_TO_HOST == _r) || (SILABS_USB_REQUESTTYPE_VENDOR_DEVICE_TO_HOST_INTERFACE == _r));
}



// Request - defined in Table 9.3 of section 9.4 of the Universal Serial Bus(USB) specification (www.usb.org).
typedef enum _SILABS_USB_REQUEST {
	_XXX = 0x00
	
	// http://www.beyondlogic.org/usbnutshell/usb6.shtml
	// There are currently eight Standard Device requests:
	, SILABS_USB_REQUEST_STANDARD_DEVICE_GET_STATUS = 0x00
	, SILABS_USB_REQUEST_STANDARD_DEVICE_CLEAR_FEATURE = 0x01
	, SILABS_USB_REQUEST_STANDARD_DEVICE_SET_FEATURE = 0x03
	, SILABS_USB_REQUEST_STANDARD_DEVICE_SET_ADDRESS = 0x05
	, SILABS_USB_REQUEST_STANDARD_DEVICE_GET_DESCRIPTOR = 0x06
	, SILABS_USB_REQUEST_STANDARD_DEVICE_SET_DESCRIPTOR = 0x07
	, SILABS_USB_REQUEST_STANDARD_DEVICE_GET_CONFIGURATION = 0x08
	, SILABS_USB_REQUEST_STANDARD_DEVICE_SET_CONFIGURATION = 0x09

	// The specification currently defines five Standard Interface requests:
	, SILABS_USB_REQUEST_STANDARD_INTERFACE_GET_STATUS = 0x00
	, SILABS_USB_REQUEST_STANDARD_INTERFACE_CLEAR_FEATURE = 0x01
	, SILABS_USB_REQUEST_STANDARD_INTERFACE_SET_FEATURE = 0x03
	, SILABS_USB_REQUEST_STANDARD_INTERFACE_GET_INTERFACE = 0x0A
	, SILABS_USB_REQUEST_STANDARD_INTERFACE_SET_INTERFACE = 0x11

	// Standard Endpoint requests come in four varieties:
	, SILABS_USB_REQUEST_STANDARD_ENDPOINT_GET_STATUS = 0x00
	, SILABS_USB_REQUEST_STANDARD_ENDPOINT_CLEAR_FEATURE = 0x01
	, SILABS_USB_REQUEST_STANDARD_ENDPOINT_SET_FEATURE = 0x03
	, SILABS_USB_REQUEST_STANDARD_ENDPOINT_SYNCH_FRAME = 0x12

	// HID Class-specific requests
	, SILABS_USB_REQUEST_HID_CLASS_GET_REPORT = 0x01
	, SILABS_USB_REQUEST_HID_CLASS_GET_IDLE = 0x02
	, SILABS_USB_REQUEST_HID_CLASS_GET_PROTOCOL = 0x03
	// 0x04-0x08 Reserved
	, SILABS_USB_REQUEST_HID_CLASS_SET_REPORT = 0x09
	, SILABS_USB_REQUEST_HID_CLASS_SET_IDLE = 0x0A
	, SILABS_USB_REQUEST_HID_CLASS_SET_PROTOCOL = 0x0B
	
	//
	// Vendor-specific bRequest definitions CP210X
	//
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_IFC_ENABLE = 0x00
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_SET_BAUDDIV = 0x01
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_SET_LINE_CTL = 0x03
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_SET_BREAK = 0x05
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_IMM_CHAR = 0x06
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_SET_MHS = 0x07
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_GET_MDMSTS = 0x08
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_SET_XON = 0x09
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_SET_XOFF = 0x0A
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_GET_PROPS = 0x0F
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_GET_COMM_STATUS = 0x10
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_RESET = 0x11
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_PURGE = 0x12
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_SET_FLOW = 0x13
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_EMBED_EVENTS = 0x15

	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_SET_RECEIVE = 0x17	/// Sets the Receiver Max Timeout setting (microseconds)
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_GET_RECEIVE = 0x18	/// Gets the Receiver Max Timeout setting (microseconds)

	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_SET_CHARS = 0x19
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_GET_BAUDRATE = 0x1D
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP210X_SET_BAUDRATE = 0x1E

	//
	// Vendor-specific bRequest definitions USBXPRESS
	//
	, SILABS_USB_REQUEST_VENDOR_SILABS_USBXPRESS_REQUEST = 0x02

	//
	// Vendor-specific bRequest definitions SLAB_USP_SPI CP213X
	//
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_RESET_DEVICE				= 0x10
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_RO_VERSION			= 0x11

	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_GPIO_VALUES			= 0x20
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_GPIO_VALUES			= 0x21
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_GPIO_MODE_AND_LEVEL	= 0x22
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_GPIO_MODE_AND_LEVEL	= 0x23
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_CHIP_SELECT = 0x24
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_CHIP_SELECT = 0x25

	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_SPI_CONTROL_BYTES		= 0x30
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_SPI_CONTROL_BYTE		= 0x31
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_SPI_DELAY				= 0x32
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_SPI_DELAY				= 0x33
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_FULL_THRESHOLD		= 0x34
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_FULL_THRESHOLD		= 0x35
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_RTR_STOP				= 0x36
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_RTR_STOP				= 0x37
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_MULTIMASTER_STATE		= 0x38
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_MULTIMASTER_STATE		= 0x39  // Not supported
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_MULTIMASTER_CTL		= 0x40  // Not supported
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_MULTIMASTER_CONTROL	= 0x41
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_MULTIMASTER_CONFIG	= 0x42
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_MULTIMASTER_CONFIG	= 0x43
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_EVENT_COUNTER			= 0x44
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_EVENT_COUNTER			= 0x45
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_CLOCK_DIVIDER			= 0x46
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_CLOCK_DIVIDER			= 0x47

	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_USB_CONFIG	= 0x60	// Get USB Config
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_USB_CONFIG	= 0x61	// Set USB Config
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_MANU1			= 0x62	// Get Manufacturing String 1
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_MANU1			= 0x63  // Set Manufacturing String 1
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_MANU2			= 0x64	// Get Manufacturing String 2
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_MANU2			= 0x65	// Set Manufacturing String 2
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_PROD1			= 0x66	// Get Product String 1
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_PROD1			= 0x67	// Set Product String 1
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_PROD2			= 0x68	// Get Product String 2
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_PROD2			= 0x69	// Set Product String 2
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_SERIAL		= 0x6A	// Get Serial String
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_SERIAL		= 0x6B	// Set Serial String
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_PIN_CONFIG	= 0x6C	// Get GPIO configuration
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_PIN_CONFIG	= 0x6D	// Set GPIO configuration
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_LOCK_BYTE		= 0x6E	// Get Lock Byte
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_LOCK_BYTE		= 0x6F	// Set Lock Byte

	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_GET_PROM_CONFIG	= 0x70	// Get EPROM all configuration
	, SILABS_USB_REQUEST_VENDOR_SILABS_CP213X_SET_PROM_CONFIG	= 0x71	// Set EPROM all configuration

	, SILABS_USB_REQUEST_VENDOR_SPECIFIC						= 0xFF	// Meaning the Request is in Value?
} SILABS_USB_REQUEST, *PSILABS_USB_REQUEST;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_REQUEST(_In_ const SILABS_USB_REQUEST _r) {
	return ((0 <= _r) && (_r <= 0x71)) || (SILABS_USB_REQUEST_VENDOR_SPECIFIC == _r);
}

// Request - defined in Table 9.3 of section 9.4 of the Universal Serial Bus(USB) specification (www.usb.org).
// Value - varies according to the request. For an explanation of this member, see the Universal Serial Bus(USB) specification  (www.usb.org).
typedef enum _SILABS_USB_VALUE {
	SILABS_USB_VALUE_XXX = 0x00

	//
	// Vendor-specific bValue definitions USBXPRESS
	//
	, SILABS_USB_VALUE_CP210X_SET_VID = 0x3701					// Set Vid command
	, SILABS_USB_VALUE_CP210X_SET_PID = 0x3702					// Set Vid command
	, SILABS_USB_VALUE_CP210X_SET_PRODUCT_STRING = 0x3703		// Set Product String command
	, SILABS_USB_VALUE_CP210X_SET_SERIAL_NUMBER = 0x3704		// Set Serial Number command
	, SILABS_USB_VALUE_CP210X_SET_POWER_USE_ATTRIBUTES = 0x3705// Set Power Use Attributes
	, SILABS_USB_VALUE_CP210X_SET_MAX_POWER = 0x3706			// Set Max. Power
	, SILABS_USB_VALUE_CP210X_SET_DEVICE_VERSION = 0x3707		// Set Device Version
	, SILABS_USB_VALUE_CP210X_RESET = 0x3708					// Reset command
	, SILABS_USB_VALUE_CP210X_GET_BAUD_RATE = 0x3709			// get baud rate command
	, SILABS_USB_VALUE_CP210X_LOCK = 0x370A					// Lock Custom Data Command
	, SILABS_USB_VALUE_CP210X_GET_PART_NUMBER = 0x370B			// Get Part num -- USBXpress?
	, SILABS_USB_VALUE_CP210X_GET_PORT_CONFIG = 0x370C			// Get Port Config
	, SILABS_USB_VALUE_CP210X_FLUSH_BUFFER = 0x370D			// Flush Buffer Command
	, SILABS_USB_VALUE_CP210X_GET_CONFIG = 0x370e				// Get Config (on CP2102N); Get Firmware Version on CP2108 and CP2105
	, SILABS_USB_VALUE_CP210X_SET_CONFIG = 0x370F				// Set Config
	, SILABS_USB_VALUE_CP210X_GET_FIRMWARE_VERSION = 0x3710	// Get Firmware Version (actually, 0x0010 on CP2102N)
	, SILABS_USB_VALUE_CP210X_GET_FIRMWARE_VERSION_LEGACY = SILABS_USB_VALUE_CP210X_GET_CONFIG	// Get Firmware Version on CP2108 and CP2105 (overloads CP2102N's GET_CONFIG)
	, SILABS_USB_VALUE_CP210X_GET_DEVICE_MODE = 0x3711			// Get Device Mode Command

	, SILABS_USB_VALUE_CP210X_SET_MANUFACTURER_STRING = 0x3714	// Set Manufacturer String command

	, SILABS_USB_VALUE_CP210X_UPDATE_FIRMWARE = 0x37FF // Update Firmware

	//
	// Vendor-specific bValue definitions USBXPRESS
	//
	, SILABS_USB_VALUE_USBXPRESS_FLUSH_BUFFERS		= ((unsigned short)(0xFFFF & 0x0001))
	, SILABS_USB_VALUE_USBXPRESS_CLEAR_TO_SEND		= ((unsigned short)(0xFFFF & 0x0002))
	, SILABS_USB_VALUE_USBXPRESS_NOT_CLEAR_TO_SEND	= ((unsigned short)(0xFFFF & 0x0004))
	, SILABS_USB_VALUE_USBXPRESS_GET_PART_NUM		= ((unsigned short)(0xFFFF & 0x0008))
} SILABS_USB_VALUE, *PSILABS_USB_VALUE;
_Check_return_
_Success_(return == TRUE)
__inline static bool IsValidSILABS_USB_VALUE(_In_ const SILABS_USB_VALUE _v) {
	return ( (SILABS_USB_VALUE_USBXPRESS_FLUSH_BUFFERS <= _v) && (_v <= SILABS_USB_VALUE_CP210X_UPDATE_FIRMWARE));
}



#endif // !defined(HOST_COMMON_INCLUDE_SILABS_USB_H_INCLUDED_PV1HTZ2O7E)

