#define	bswap16(x)	((((x) & 0xff00) >>  8) | (((x) & 0x00ff) <<  8))
#define	htole16(x)	bswap16((x))
#define	le16toh(x)	bswap16((x))

#define TRANS_TO_DEV	0x00
#define TRANS_TO_HOST	0x80
#define TRANS_TO_IF	0x01
#define TRANS_TO_EP	0x02

#define GET_STATUS      0x00
#define CLEAR_FEATURE   0x01
#define SET_FEATURE     0x03
#define SET_ADDRESS     0x05
#define GET_DESCRIPTOR  0x06
#define SET_DESCRIPTOR  0x07
#define GET_CONFIG      0x08
#define SET_CONFIG      0x09
#define GET_INTERFACE   0x0a
#define SET_INTERFACE   0x0b
#define SYNCH_FRAME     0x0c

#define DEVICE_TYPE	0x01
#define CONFIG_TYPE	0x02
#define STRING_TYPE	0x03
#define INTERFACE_TYPE	0x04
#define ENDPOINT_TYPE	0x05

#define STDCLASS        0x00
#define HIDCLASS        0x03
#define HUBCLASS	0x09	// bDeviceClass, bInterfaceClass

#define	MAX_EP	8
typedef struct {
	unsigned short  wVID, wPID;	// Vendor ID and Product ID
	unsigned char  bClass;		// 
	unsigned char  bNumOfEPs;	// actual number endpoint from slave
	unsigned char  iMfg;		// Manufacturer ID
	unsigned char  iPdt;		// Product ID
	unsigned char  bId1;
	unsigned char  bId2;
	unsigned char  bEPAddr[MAX_EP];   // bit 7 = 1 = use PID_IN, 
	unsigned char  bAttr[MAX_EP];     // ISO | Bulk | Interrupt | Control
	unsigned short  wPayLoad[MAX_EP];  // ISO range: 1-1023, Bulk: 1-64, etc
	unsigned short  bInterval[MAX_EP]; // polling interval (for LS)
	unsigned char  bData1[MAX_EP];    // DataToggle value
} USBDEV;

typedef struct {
	unsigned char	bmRequest __attribute__((packed));
	unsigned char	bRequest __attribute__((packed));
	unsigned short wValue __attribute__((packed));
	unsigned short wIndex __attribute__((packed));
	unsigned short wLength __attribute__((packed));
} SetupPKG;

typedef struct {
	unsigned char	bLength __attribute__((packed));
	unsigned char	bDescriptorType __attribute__((packed));
	unsigned short bcdUSB __attribute__((packed));
	unsigned char	bDeviceClass __attribute__((packed));
	unsigned char	bDeviceSubClass __attribute__((packed));
	unsigned char	bDeviceProtocol __attribute__((packed));
	unsigned char	bMaxPacketSize0 __attribute__((packed));
	unsigned short idVendor __attribute__((packed));
	unsigned short idProduct __attribute__((packed));
	unsigned short bcdDevice __attribute__((packed));
	unsigned char	iManufacturer __attribute__((packed));
	unsigned char	iProduct __attribute__((packed));
	unsigned char	iSerialNumber __attribute__((packed));
	unsigned char	bNumConfigurations __attribute__((packed));
} DevDesc;

// Standard Configuration Descriptor
typedef struct {
	unsigned char	bLength __attribute__((packed));	// Size of descriptor in unsigned char
	unsigned char	bType __attribute__((packed));		// Configuration
	unsigned short wLength __attribute__((packed));		// Total length
	unsigned char	bNumIntf __attribute__((packed));	// Number of interface
	unsigned char	bCV __attribute__((packed));		// bConfigurationValue
	unsigned char	bIndex __attribute__((packed));		// iConfiguration
	unsigned char	bAttr __attribute__((packed));		// Configuration Characteristic
	unsigned char	bMaxPower __attribute__((packed));	// Power config
} CfgDesc;

// Standard Interface Descriptor
typedef struct {
	unsigned char	bLength __attribute__((packed));
	unsigned char	bType __attribute__((packed));
	unsigned char	iNum __attribute__((packed));
	unsigned char	iAltString __attribute__((packed));
	unsigned char	bEndPoints __attribute__((packed));
	unsigned char	iClass __attribute__((packed));
	unsigned char	iSub __attribute__((packed)); 
	unsigned char	iProto __attribute__((packed));
	unsigned char	iIndex __attribute__((packed)); 
} IntfDesc;

// Standard EndPoint Descriptor
typedef struct{
	unsigned char	bLength __attribute__((packed));
	unsigned char	bType __attribute__((packed));
	unsigned char	bEPAdd __attribute__((packed));
	unsigned char	bAttr __attribute__((packed));
	unsigned short wPayLoad __attribute__((packed));	// low-speed this must be 0x08
	unsigned char	bInterval __attribute__((packed));
} EPDesc;

// Standard String Descriptor
typedef struct {
	unsigned char	bLength;
	unsigned char	bType;
	unsigned short wLang;
} StrDesc;
