diff --git a/examples_x035/usbdevice.incomplete/Makefile b/examples_x035/usbdevice.incomplete/Makefile
index e28de11d4d8c5b2e5246370353a8a4809f881311..adabf99a779fb5e00e982b4db7f26cec3654269b 100644
--- a/examples_x035/usbdevice.incomplete/Makefile
+++ b/examples_x035/usbdevice.incomplete/Makefile
@@ -2,7 +2,7 @@ all : flash
 
 TARGET:=usbdevice
 TARGET_MCU:=CH32X035
-ADDITIONAL_C_FILES:=fsusb.c
+ADDITIONAL_C_FILES:=fsusb.c descriptor.c
 
 include ../../ch32v003fun/ch32v003fun.mk
 
diff --git a/examples_x035/usbdevice.incomplete/descriptor.c b/examples_x035/usbdevice.incomplete/descriptor.c
new file mode 100644
index 0000000000000000000000000000000000000000..2d1b2f6d84fc1e3af41d79bd0c7bacfa65d0a47e
--- /dev/null
+++ b/examples_x035/usbdevice.incomplete/descriptor.c
@@ -0,0 +1,266 @@
+/********************************** (C) COPYRIGHT *******************************
+ * File Name          : composite_km_desc.h
+ * Author             : WCH
+ * Version            : V1.0.0
+ * Date               : 2023/04/06
+ * Description        : All descriptors for the keyboard and mouse composite device.
+*********************************************************************************
+* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
+* Attention: This software (modified or not) and binary are used for 
+* microcontroller manufactured by Nanjing Qinheng Microelectronics.
+*******************************************************************************/
+
+
+/*******************************************************************************/
+/* Header File */
+#include "descriptor.h"
+
+/*******************************************************************************/
+/* Device Descriptor */
+const uint8_t MyDevDescr[ ] =
+{
+    0x12,                                                   // bLength
+    0x01,                                                   // bDescriptorType
+    0x00, 0x02,                                             // bcdUSB
+    0x00,                                                   // bDeviceClass
+    0x00,                                                   // bDeviceSubClass
+    0x00,                                                   // bDeviceProtocol
+    DEF_USBD_UEP0_SIZE,                                     // bMaxPacketSize0
+    (uint8_t)DEF_USB_VID, (uint8_t)( DEF_USB_VID >> 8 ),    // idVendor
+    (uint8_t)DEF_USB_PID, (uint8_t)( DEF_USB_PID >> 8 ),    // idProduct
+    0x00, DEF_IC_PRG_VER,                                   // bcdDevice
+    0x01,                                                   // iManufacturer
+    0x02,                                                   // iProduct
+    0x03,                                                   // iSerialNumber
+    0x01,                                                   // bNumConfigurations
+};
+
+/* Configuration Descriptor Set */
+const uint8_t MyCfgDescr[ ] =
+{
+    /* Configuration Descriptor */
+    0x09,                                                   // bLength
+    0x02,                                                   // bDescriptorType
+    0x3B, 0x00,                                             // wTotalLength
+    0x02,                                                   // bNumInterfaces
+    0x01,                                                   // bConfigurationValue
+    0x00,                                                   // iConfiguration
+    0xA0,                                                   // bmAttributes: Bus Powered; Remote Wakeup
+    0x32,                                                   // MaxPower: 100mA
+
+    /* Interface Descriptor (Keyboard) */
+    0x09,                                                   // bLength
+    0x04,                                                   // bDescriptorType
+    0x00,                                                   // bInterfaceNumber
+    0x00,                                                   // bAlternateSetting
+    0x01,                                                   // bNumEndpoints
+    0x03,                                                   // bInterfaceClass
+    0x01,                                                   // bInterfaceSubClass
+    0x01,                                                   // bInterfaceProtocol: Keyboard
+    0x00,                                                   // iInterface
+
+    /* HID Descriptor (Keyboard) */
+    0x09,                                                   // bLength
+    0x21,                                                   // bDescriptorType
+    0x11, 0x01,                                             // bcdHID
+    0x00,                                                   // bCountryCode
+    0x01,                                                   // bNumDescriptors
+    0x22,                                                   // bDescriptorType
+    0x3E, 0x00,                                             // wDescriptorLength
+
+    /* Endpoint Descriptor (Keyboard) */
+    0x07,                                                   // bLength
+    0x05,                                                   // bDescriptorType
+    0x81,                                                   // bEndpointAddress: IN Endpoint 1
+    0x03,                                                   // bmAttributes
+    0x08, 0x00,                                             // wMaxPacketSize
+    0x0A,                                                   // bInterval: 10mS
+
+    /* Interface Descriptor (Mouse) */
+    0x09,                                                   // bLength
+    0x04,                                                   // bDescriptorType
+    0x01,                                                   // bInterfaceNumber
+    0x00,                                                   // bAlternateSetting
+    0x01,                                                   // bNumEndpoints
+    0x03,                                                   // bInterfaceClass
+    0x01,                                                   // bInterfaceSubClass
+    0x02,                                                   // bInterfaceProtocol: Mouse
+    0x00,                                                   // iInterface
+
+    /* HID Descriptor (Mouse) */
+    0x09,                                                   // bLength
+    0x21,                                                   // bDescriptorType
+    0x10, 0x01,                                             // bcdHID
+    0x00,                                                   // bCountryCode
+    0x01,                                                   // bNumDescriptors
+    0x22,                                                   // bDescriptorType
+    0x34, 0x00,                                             // wDescriptorLength
+
+    /* Endpoint Descriptor (Mouse) */
+    0x07,                                                   // bLength
+    0x05,                                                   // bDescriptorType
+    0x82,                                                   // bEndpointAddress: IN Endpoint 2
+    0x03,                                                   // bmAttributes
+    0x08, 0x00,                                             // wMaxPacketSize
+    0x01                                                    // bInterval: 1mS
+};
+
+/* Keyboard Report Descriptor */
+const uint8_t KeyRepDesc[ ] =
+{
+    0x05, 0x01,                                             // Usage Page (Generic Desktop)
+    0x09, 0x06,                                             // Usage (Keyboard)
+    0xA1, 0x01,                                             // Collection (Application)
+    0x05, 0x07,                                             // Usage Page (Key Codes)
+    0x19, 0xE0,                                             // Usage Minimum (224)
+    0x29, 0xE7,                                             // Usage Maximum (231)
+    0x15, 0x00,                                             // Logical Minimum (0)
+    0x25, 0x01,                                             // Logical Maximum (1)
+    0x75, 0x01,                                             // Report Size (1)
+    0x95, 0x08,                                             // Report Count (8)
+    0x81, 0x02,                                             // Input (Data,Variable,Absolute)
+    0x95, 0x01,                                             // Report Count (1)
+    0x75, 0x08,                                             // Report Size (8)
+    0x81, 0x01,                                             // Input (Constant)
+    0x95, 0x03,                                             // Report Count (3)
+    0x75, 0x01,                                             // Report Size (1)
+    0x05, 0x08,                                             // Usage Page (LEDs)
+    0x19, 0x01,                                             // Usage Minimum (1)
+    0x29, 0x03,                                             // Usage Maximum (3)
+    0x91, 0x02,                                             // Output (Data,Variable,Absolute)
+    0x95, 0x05,                                             // Report Count (5)
+    0x75, 0x01,                                             // Report Size (1)
+    0x91, 0x01,                                             // Output (Constant,Array,Absolute)
+    0x95, 0x06,                                             // Report Count (6)
+    0x75, 0x08,                                             // Report Size (8)
+    0x26, 0xFF, 0x00,                                       // Logical Maximum (255)
+    0x05, 0x07,                                             // Usage Page (Key Codes)
+    0x19, 0x00,                                             // Usage Minimum (0)
+    0x29, 0x91,                                             // Usage Maximum (145)
+    0x81, 0x00,                                             // Input(Data,Array,Absolute)
+    0xC0                                                    // End Collection
+};
+
+/* Mouse Report Descriptor */
+const uint8_t MouseRepDesc[ ] =
+{
+    0x05, 0x01,                                             // Usage Page (Generic Desktop)
+    0x09, 0x02,                                             // Usage (Mouse)
+    0xA1, 0x01,                                             // Collection (Application)
+    0x09, 0x01,                                             // Usage (Pointer)
+    0xA1, 0x00,                                             // Collection (Physical)
+    0x05, 0x09,                                             // Usage Page (Button)
+    0x19, 0x01,                                             // Usage Minimum (Button 1)
+    0x29, 0x03,                                             // Usage Maximum (Button 3)
+    0x15, 0x00,                                             // Logical Minimum (0)
+    0x25, 0x01,                                             // Logical Maximum (1)
+    0x75, 0x01,                                             // Report Size (1)
+    0x95, 0x03,                                             // Report Count (3)
+    0x81, 0x02,                                             // Input (Data,Variable,Absolute)
+    0x75, 0x05,                                             // Report Size (5)
+    0x95, 0x01,                                             // Report Count (1)
+    0x81, 0x01,                                             // Input (Constant,Array,Absolute)
+    0x05, 0x01,                                             // Usage Page (Generic Desktop)
+    0x09, 0x30,                                             // Usage (X)
+    0x09, 0x31,                                             // Usage (Y)
+    0x09, 0x38,                                             // Usage (Wheel)
+    0x15, 0x81,                                             // Logical Minimum (-127)
+    0x25, 0x7F,                                             // Logical Maximum (127)
+    0x75, 0x08,                                             // Report Size (8)
+    0x95, 0x03,                                             // Report Count (3)
+    0x81, 0x06,                                             // Input (Data,Variable,Relative)
+    0xC0,                                                   // End Collection
+    0xC0                                                    // End Collection
+};
+
+/* Qualifier Descriptor */
+const uint8_t  MyQuaDesc[ ] =
+{
+    0x0A,                                                   // bLength
+    0x06,                                                   // bDescriptorType
+    0x00, 0x02,                                             // bcdUSB
+    0x00,                                                   // bDeviceClass
+    0x00,                                                   // bDeviceSubClass
+    0x00,                                                   // bDeviceProtocol
+    0x40,                                                   // bMaxPacketSize0
+    0x00,                                                   // bNumConfigurations
+    0x00                                                    // bReserved
+};
+
+/* Language Descriptor */
+const uint8_t MyLangDescr[ ] =
+{
+    0x04,
+    0x03,
+    0x09,
+    0x04
+};
+
+/* Manufacturer Descriptor */
+const uint8_t MyManuInfo[ ] =
+{
+    0x0E,
+    0x03,
+    'w',
+    0,
+    'c',
+    0,
+    'h',
+    0,
+    '.',
+    0,
+    'c',
+    0,
+    'n',
+    0
+};
+
+/* Product Information */
+const uint8_t MyProdInfo[ ]  =
+{
+    0x12,
+    0x03,
+    'C',
+    0,
+    'H',
+    0,
+    '3',
+    0,
+    '2',
+    0,
+    'x',
+    0,
+    '0',
+    0,
+    '3',
+    0,
+    '5',
+    0
+};
+
+/* Serial Number Information */
+const uint8_t  MySerNumInfo[ ] =
+{
+    0x16,
+    0x03,
+    '0',
+    0,
+    '1',
+    0,
+    '2',
+    0,
+    '3',
+    0,
+    '4',
+    0,
+    '5',
+    0,
+    '6',
+    0,
+    '7',
+    0,
+    '8',
+    0,
+    '9',
+    0
+};
diff --git a/examples_x035/usbdevice.incomplete/descriptor.h b/examples_x035/usbdevice.incomplete/descriptor.h
new file mode 100644
index 0000000000000000000000000000000000000000..b746eecf181c3d60b5038245638a58163145e811
--- /dev/null
+++ b/examples_x035/usbdevice.incomplete/descriptor.h
@@ -0,0 +1,92 @@
+/********************************** (C) COPYRIGHT *******************************
+ * File Name          : usbd_descriptor.h
+ * Author             : WCH
+ * Version            : V1.0.0
+ * Date               : 2023/04/06
+ * Description        : All descriptors for the keyboard and mouse composite device.
+*********************************************************************************
+* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
+* Attention: This software (modified or not) and binary are used for 
+* microcontroller manufactured by Nanjing Qinheng Microelectronics.
+*******************************************************************************/
+
+
+#ifndef __USBD_DESC_H
+#define __USBD_DESC_H
+
+/*******************************************************************************/
+/* Header File */
+#include "stdint.h"
+
+/*******************************************************************************/
+/* Macro Definition */
+
+/* File Version */
+#define DEF_FILE_VERSION              0x01
+
+/* USB Device Info */
+#define DEF_USB_VID                   0x1A86
+#define DEF_USB_PID                   0xFE00
+
+/* USB Device Descriptor, Device Serial Number(bcdDevice) */
+#define DEF_IC_PRG_VER                DEF_FILE_VERSION
+
+/* USB Device Endpoint Size */
+#define DEF_USBD_UEP0_SIZE            64     /* usb hs/fs device end-point 0 size */
+/* HS */
+#define DEF_USBD_HS_PACK_SIZE         512    /* usb hs device max bluk/int pack size */
+#define DEF_USBD_HS_ISO_PACK_SIZE     1024   /* usb hs device max iso pack size */
+/* FS */
+#define DEF_USBD_FS_PACK_SIZE         64     /* usb fs device max bluk/int pack size */
+#define DEF_USBD_FS_ISO_PACK_SIZE     1023   /* usb fs device max iso pack size */
+/* LS */
+#define DEf_USBD_LS_UEP0_SIZE         8      /* usb ls device end-point 0 size */
+#define DEF_USBD_LS_PACK_SIZE         64     /* usb ls device max int pack size */
+
+/* USB Device Endpoint1-6 Size */
+/* HS */
+#define DEF_USB_EP1_HS_SIZE           DEF_USBD_HS_PACK_SIZE
+#define DEF_USB_EP2_HS_SIZE           DEF_USBD_HS_PACK_SIZE
+#define DEF_USB_EP3_HS_SIZE           DEF_USBD_HS_PACK_SIZE
+#define DEF_USB_EP4_HS_SIZE           DEF_USBD_HS_PACK_SIZE
+#define DEF_USB_EP5_HS_SIZE           DEF_USBD_HS_PACK_SIZE
+#define DEF_USB_EP6_HS_SIZE           DEF_USBD_HS_PACK_SIZE
+/* FS */
+#define DEF_USB_EP1_FS_SIZE           DEF_USBD_FS_PACK_SIZE
+#define DEF_USB_EP2_FS_SIZE           DEF_USBD_FS_PACK_SIZE
+#define DEF_USB_EP3_FS_SIZE           DEF_USBD_FS_PACK_SIZE
+#define DEF_USB_EP4_FS_SIZE           DEF_USBD_FS_PACK_SIZE
+#define DEF_USB_EP5_FS_SIZE           DEF_USBD_FS_PACK_SIZE
+#define DEF_USB_EP6_FS_SIZE           DEF_USBD_FS_PACK_SIZE
+/* LS */
+/* ... */
+
+/* USB Device Descriptor Length */
+/* Note: If a descriptor does not exist, set the length to 0. */
+#define DEF_USBD_DEVICE_DESC_LEN      ( (uint16_t)MyDevDescr[ 0 ] )
+#define DEF_USBD_CONFIG_DESC_LEN   ( (uint16_t)MyCfgDescr[ 2 ] + ( (uint16_t)MyCfgDescr[ 3 ] << 8 ) )
+#define DEF_USBD_REPORT_DESC_LEN_KB   0x3E
+#define DEF_USBD_REPORT_DESC_LEN_MS   0x34
+#define DEF_USBD_LANG_DESC_LEN        ( (uint16_t)MyLangDescr[ 0 ] )
+#define DEF_USBD_MANU_DESC_LEN        ( (uint16_t)MyManuInfo[ 0 ] )
+#define DEF_USBD_PROD_DESC_LEN        ( (uint16_t)MyProdInfo[ 0 ] )
+#define DEF_USBD_SN_DESC_LEN          ( (uint16_t)MySerNumInfo[ 0 ] )
+#define DEF_USBD_QUALFY_DESC_LEN      ( (uint16_t)MyQuaDesc[ 0 ])
+#define DEF_USBD_BOS_DESC_LEN         0
+#define DEF_USBD_FS_OTH_DESC_LEN      0
+#define DEF_USBD_HS_OTH_DESC_LEN      0
+
+
+/*******************************************************************************/
+/* Descriptor Declaration */
+extern const uint8_t MyDevDescr[ ];
+extern const uint8_t MyCfgDescr[ ];
+extern const uint8_t KeyRepDesc[ ];
+extern const uint8_t MouseRepDesc[ ];
+extern const uint8_t MyQuaDesc[ ];
+extern const uint8_t MyLangDescr[ ];
+extern const uint8_t MyManuInfo[ ];
+extern const uint8_t MyProdInfo[ ];
+extern const uint8_t MySerNumInfo[ ];
+
+#endif
diff --git a/examples_x035/usbdevice.incomplete/fsusb.c b/examples_x035/usbdevice.incomplete/fsusb.c
index 67b225e523167fb7b24ca849d88a72c948ff4264..f29487bbe34ee2270c313971cdd26db8f9e69372 100644
--- a/examples_x035/usbdevice.incomplete/fsusb.c
+++ b/examples_x035/usbdevice.incomplete/fsusb.c
@@ -1,10 +1,27 @@
 #include "fsusb.h"
 #include "ch32v003fun.h"
+#include <string.h>
 
 uint32_t USBDEBUG0, USBDEBUG1, USBDEBUG2;
-uint8_t  EP0_DATA[64] __attribute__((aligned(32)));
 
-void USBFS_IRQHandler() __attribute__((section(".text.vector_handler")))  __attribute__((interrupt));
+
+// based on https://github.com/openwch/ch32x035/tree/main/EVT/EXAM/USB/USBFS/DEVICE/CompositeKM/User
+
+#define DEF_USBD_UEP0_SIZE		   64	 /* usb hs/fs device end-point 0 size */
+#define EP_SIZE 64
+
+#define DEF_UEP_IN                    0x80
+#define DEF_UEP_OUT                   0x00
+
+#define DEF_UEP0 0
+#define DEF_UEP1 1
+#define DEF_UEP2 2
+#define DEF_UEP3 3
+#define DEF_UEP4 4
+#define DEF_UEP5 5
+#define DEF_UEP6 6
+#define DEF_UEP7 7
+#define NUM_EP 8
 
 // Mask for the combined USBFSD->INT_FG + USBFSD->INT_ST
 #define CRB_U_IS_NAK     (1<<7)
@@ -15,55 +32,693 @@ void USBFS_IRQHandler() __attribute__((section(".text.vector_handler")))  __attr
 #define CRB_UIF_SUSPEND  (1<<2)
 #define CRB_UIF_TRANSFER (1<<1)
 #define CRB_UIF_BUS_RST  (1<<0)
-#define CSETUP_ACT       (1<<15)
+#define CSETUP_ACT	   (1<<15)
 #define CRB_UIS_TOG_OK   (1<<14)
 #define CMASK_UIS_TOKEN  (3<<12)
 #define CMASK_UIS_ENDP   (0xf<<8)
 
-#define CUIS_TOKEN_OUT        0x0
-#define CUIS_TOKEN_SOF        0x1
-#define CUIS_TOKEN_IN         0x2
-#define CUIS_TOKEN_SETUP      0x3
+#define CUSBFS_UIS_ENDP_MASK		 0x0
+
+#define CUIS_TOKEN_OUT		0x0
+#define CUIS_TOKEN_SOF		0x1
+#define CUIS_TOKEN_IN		 0x2
+#define CUIS_TOKEN_SETUP	  0x3
+
+
+// Hardware specific
+
+/* R8_USB_CTRL */
+#define USBFS_UC_HOST_MODE          0x80
+#define USBFS_UC_LOW_SPEED          0x40
+#define USBFS_UC_DEV_PU_EN          0x20
+#define USBFS_UC_SYS_CTRL_MASK      0x30
+#define USBFS_UC_SYS_CTRL0          0x00
+#define USBFS_UC_SYS_CTRL1          0x10
+#define USBFS_UC_SYS_CTRL2          0x20
+#define USBFS_UC_SYS_CTRL3          0x30
+#define USBFS_UC_INT_BUSY           0x08
+#define USBFS_UC_RESET_SIE          0x04
+#define USBFS_UC_CLR_ALL            0x02
+#define USBFS_UC_DMA_EN             0x01
+
+/* R8_USB_INT_EN */
+#define USBFS_UIE_DEV_SOF           0x80
+#define USBFS_UIE_DEV_NAK           0x40
+#define USBFS_UIE_FIFO_OV           0x10
+#define USBFS_UIE_HST_SOF           0x08
+#define USBFS_UIE_SUSPEND           0x04
+#define USBFS_UIE_TRANSFER          0x02
+#define USBFS_UIE_DETECT            0x01
+#define USBFS_UIE_BUS_RST           0x01
+
+/* R8_USB_DEV_AD */
+#define USBFS_UDA_GP_BIT            0x80
+#define USBFS_USB_ADDR_MASK         0x7F
+
+/* R8_USB_MIS_ST */
+#define USBFS_UMS_SOF_PRES          0x80
+#define USBFS_UMS_SOF_ACT           0x40
+#define USBFS_UMS_SIE_FREE          0x20
+#define USBFS_UMS_R_FIFO_RDY        0x10
+#define USBFS_UMS_BUS_RESET         0x08
+#define USBFS_UMS_SUSPEND           0x04
+#define USBFS_UMS_DM_LEVEL          0x02
+#define USBFS_UMS_DEV_ATTACH        0x01
+
+// XXX TODO: Put these in a struct.
+
+/* Setup Request */
+volatile uint8_t  USBFS_SetupReqCode;
+volatile uint8_t  USBFS_SetupReqType;
+volatile uint16_t USBFS_SetupReqValue;
+volatile uint16_t USBFS_SetupReqIndex;
+volatile uint16_t USBFS_SetupReqLen;
+
+/* USB Device Status */
+volatile uint8_t  USBFS_DevConfig;
+volatile uint8_t  USBFS_DevAddr;
+volatile uint8_t  USBFS_DevSleepStatus;
+volatile uint8_t  USBFS_DevEnumStatus;
+
+/* Endpoint Buffer */
+__attribute__ ((aligned(4))) uint8_t USBFS_EP0_Buf[64];
+__attribute__ ((aligned(4))) uint8_t USBFS_EP1_Buf[64];
+__attribute__ ((aligned(4))) uint8_t USBFS_EP2_Buf[64];
+#define pUSBFS_SetupReqPak                 ((PUSB_SETUP_REQ)USBFS_EP0_Buf)
+
+
+int USBFS_HidIdle[2];
+int USBFS_HidProtocol[2];
+
+const uint8_t  *pUSBFS_Descr;
+
+/* USB IN Endpoint Busy Flag */
+volatile uint8_t  USBFS_Endp_Busy[NUM_EP];
+
+
+
+
+void USBFS_IRQHandler() __attribute__((section(".text.vector_handler")))  __attribute__((interrupt));
+
+
 
 void USBFS_IRQHandler()
 {
+	// Based on https://github.com/openwch/ch32x035/blob/main/EVT/EXAM/USB/USBFS/DEVICE/CompositeKM/User/ch32x035_usbfs_device.c
+
 	// Combined FG + ST flag.
-	uint16_t intfgst = *(uint16_t*)(&USBFSD->INT_FG);
+	uint16_t intfgst = *(uint16_t*)(&USBFS->INT_FG);
+	int len = 0, errflag = 0;
 
 	GPIOA->BSHR = 1;
 
 	// TODO: Check if needs to be do-while to re-check.
+	if( intfgst & CRB_UIF_TRANSFER )
+	{
+		int token = ( intfgst & CMASK_UIS_TOKEN) >> 12;
+		int ep = intfgst & CUSBFS_UIS_ENDP_MASK;
+		switch ( token )
+		{
+		case CUIS_TOKEN_IN:
+			switch( ep )
+			{
+				/* end-point 0 data in interrupt */
+				case DEF_UEP0:
+					if( USBFS_SetupReqLen == 0 )
+					{
+						USBFS->UEP0_CTRL_H = USBFS_UEP_R_TOG | USBFS_UEP_R_RES_ACK;
+					}
 
+					if ( ( USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD )
+					{
+						/* Non-standard request endpoint 0 Data upload */
+					}
+					else
+					{
+						switch( USBFS_SetupReqCode )
+						{
+							case USB_GET_DESCRIPTOR:
+								len = USBFS_SetupReqLen >= DEF_USBD_UEP0_SIZE ? DEF_USBD_UEP0_SIZE : USBFS_SetupReqLen;
+								memcpy( USBFS_EP0_Buf, pUSBFS_Descr, len );
+								USBFS_SetupReqLen -= len;
+								pUSBFS_Descr += len;
+								USBFS->UEP0_TX_LEN = len;
+								USBFS->UEP0_CTRL_H ^= USBFS_UEP_T_TOG;
+								break;
 
-    if( intfgst & CRB_UIF_TRANSFER )
-    {
-        switch ( ( intfgst & CMASK_UIS_TOKEN) >> 12)
-        {
-            case CUIS_TOKEN_IN:
-                switch ( intst & ( USBFS_UIS_TOKEN_M
+							case USB_SET_ADDRESS:
+								USBFS->DEV_ADDR = ( USBFS->DEV_ADDR & USBFS_UDA_GP_BIT ) | USBFS_DevAddr;
+								break;
+
+							default:
+								break;
+						}
+					}
+					break;
+
+				/* end-point 1 data in interrupt */
+				case DEF_UEP1:
+					USBFS->UEP1_CTRL_H = ( USBFS->UEP1_CTRL_H & ~USBFS_UEP_T_RES_MASK ) | USBFS_UEP_T_RES_NAK;
+					USBFS->UEP1_CTRL_H ^= USBFS_UEP_T_TOG;
+					USBFS_Endp_Busy[ DEF_UEP1 ] = 0;
+					break;
+
+				/* end-point 2 data in interrupt */
+				case DEF_UEP2:
+					USBFS->UEP2_CTRL_H = ( USBFS->UEP2_CTRL_H & ~USBFS_UEP_T_RES_MASK ) | USBFS_UEP_T_RES_NAK;
+					USBFS->UEP2_CTRL_H ^= USBFS_UEP_T_TOG;
+					USBFS_Endp_Busy[ DEF_UEP2 ] = 0;
+					break;
+
+				default :
+					break;
+			}
+			break;
+
+		/* data-out stage processing */
+		case CUIS_TOKEN_OUT:
+			switch( ep )
+			{
+				/* end-point 0 data out interrupt */
+				case DEF_UEP0:
+					if( intfgst & CRB_UIS_TOG_OK )
+					{
+						if( ( USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD )
+						{
+							if( ( USBFS_SetupReqType & USB_REQ_TYP_MASK ) == USB_REQ_TYP_CLASS )
+							{
+								switch( USBFS_SetupReqCode )
+								{
+									case HID_SET_REPORT:
+										//KB_LED_Cur_Status = USBFS_EP0_Buf[ 0 ];
+										// Do stuff...
+										USBFS_SetupReqLen = 0;
+										break;
+									default:
+										break;
+								}
+							}
+						}
+						else
+						{
+							/* Standard request end-point 0 Data download */
+							/* Add your code here */
+						}
+					}
+					if( USBFS_SetupReqLen == 0 )
+					{
+						USBFS->UEP0_TX_LEN  = 0;
+						USBFS->UEP0_CTRL_H = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_ACK;
+					}
+					break;
+
+				default:
+					break;
+			}
+			break;
+
+		/* Setup stage processing */
+		case CUIS_TOKEN_SETUP:
+			USBFS->UEP0_CTRL_H = USBFS_UEP_T_TOG|USBFS_UEP_T_RES_NAK|USBFS_UEP_R_TOG|USBFS_UEP_R_RES_NAK;
+
+			/* Store All Setup Values */
+			USBFS_SetupReqType  = pUSBFS_SetupReqPak->bRequestType;
+			USBFS_SetupReqCode  = pUSBFS_SetupReqPak->bRequest;
+			USBFS_SetupReqLen   = pUSBFS_SetupReqPak->wLength;
+			USBFS_SetupReqValue = pUSBFS_SetupReqPak->wValue;
+			USBFS_SetupReqIndex = pUSBFS_SetupReqPak->wIndex;
+			len = 0;
+			errflag = 0;
+
+			if( ( USBFS_SetupReqType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD )
+			{
+				if( ( USBFS_SetupReqType & USB_REQ_TYP_MASK ) == USB_REQ_TYP_CLASS )
+				{
+					/* Class Request */
+					switch( USBFS_SetupReqCode )
+					{
+						case HID_SET_REPORT:
+							break;
+
+						case HID_SET_IDLE:
+							if( USBFS_SetupReqIndex == 0x00 )
+							{
+								USBFS_HidIdle[ 0 ] = (uint8_t)( USBFS_SetupReqValue >> 8 );
+							}
+							else if( USBFS_SetupReqIndex == 0x01 )
+							{
+								USBFS_HidIdle[ 1 ] = (uint8_t)( USBFS_SetupReqValue >> 8 );
+							}
+							else
+							{
+								errflag = 0xFF;
+							}
+							break;
+
+						case HID_SET_PROTOCOL:
+							if( USBFS_SetupReqIndex == 0x00 )
+							{
+								USBFS_HidProtocol[ 0 ] = (uint8_t)USBFS_SetupReqValue;
+							}
+							else if( USBFS_SetupReqIndex == 0x01 )
+							{
+								USBFS_HidProtocol[ 1 ] = (uint8_t)USBFS_SetupReqValue;
+							}
+							else
+							{
+								errflag = 0xFF;
+							}
+							break;
+
+						case HID_GET_IDLE:
+							if( USBFS_SetupReqIndex == 0x00 )
+							{
+								USBFS_EP0_Buf[ 0 ] = USBFS_HidIdle[ 0 ];
+								len = 1;
+							}
+							else if( USBFS_SetupReqIndex == 0x01 )
+							{
+								USBFS_EP0_Buf[ 0 ] = USBFS_HidIdle[ 1 ];
+								len = 1;
+							}
+							else
+							{
+								errflag = 0xFF;
+							}
+							break;
+
+						case HID_GET_PROTOCOL:
+							if( USBFS_SetupReqIndex == 0x00 )
+							{
+								USBFS_EP0_Buf[ 0 ] = USBFS_HidProtocol[ 0 ];
+								len = 1;
+							}
+							else if( USBFS_SetupReqIndex == 0x01 )
+							{
+								USBFS_EP0_Buf[ 0 ] = USBFS_HidProtocol[ 1 ];
+								len = 1;
+							}
+							else
+							{
+								errflag = 0xFF;
+							}
+							break;
 
-/*	while( ( flags = USBFS->INT_FG & 0x9f ) )
+						default:
+							errflag = 0xFF;
+							break;
+					}
+				}
+			}
+			else
+			{
+				/* usb standard request processing */
+				switch( USBFS_SetupReqCode )
+				{
+					/* get device/configuration/string/report/... descriptors */
+					case USB_GET_DESCRIPTOR:
+						switch( (uint8_t)( USBFS_SetupReqValue >> 8 ) )
+						{
+							/* get usb device descriptor */
+							case USB_DESCR_TYP_DEVICE:
+								pUSBFS_Descr = MyDevDescr;
+								len = DEF_USBD_DEVICE_DESC_LEN;
+								break;
+
+							/* get usb configuration descriptor */
+							case USB_DESCR_TYP_CONFIG:
+								pUSBFS_Descr = MyCfgDescr;
+								len = DEF_USBD_CONFIG_DESC_LEN;
+								break;
+
+							/* get usb hid descriptor */
+							case USB_DESCR_TYP_HID:
+								if( USBFS_SetupReqIndex == 0x00 )
+								{
+									pUSBFS_Descr = &MyCfgDescr[ 18 ];
+									len = 9;
+								}
+								else if( USBFS_SetupReqIndex == 0x01 )
+								{
+									pUSBFS_Descr = &MyCfgDescr[ 43 ];
+									len = 9;
+								}
+								else
+								{
+									errflag = 0xFF;
+								}
+								break;
+
+							/* get usb report descriptor */
+							case USB_DESCR_TYP_REPORT:
+								if( USBFS_SetupReqIndex == 0x00 )
+								{
+									pUSBFS_Descr = KeyRepDesc;
+									len = DEF_USBD_REPORT_DESC_LEN_KB;
+								}
+								else if( USBFS_SetupReqIndex == 0x01 )
+								{
+									pUSBFS_Descr = MouseRepDesc;
+									len = DEF_USBD_REPORT_DESC_LEN_MS;
+								}
+								else
+								{
+									errflag = 0xFF;
+								}
+								break;
+
+							/* get usb string descriptor */
+							case USB_DESCR_TYP_STRING:
+								switch( (uint8_t)( USBFS_SetupReqValue & 0xFF ) )
+								{
+									/* Descriptor 0, Language descriptor */
+									case DEF_STRING_DESC_LANG:
+										pUSBFS_Descr = MyLangDescr;
+										len = DEF_USBD_LANG_DESC_LEN;
+										break;
+
+									/* Descriptor 1, Manufacturers String descriptor */
+									case DEF_STRING_DESC_MANU:
+										pUSBFS_Descr = MyManuInfo;
+										len = DEF_USBD_MANU_DESC_LEN;
+										break;
+
+									/* Descriptor 2, Product String descriptor */
+									case DEF_STRING_DESC_PROD:
+										pUSBFS_Descr = MyProdInfo;
+										len = DEF_USBD_PROD_DESC_LEN;
+										break;
+
+									/* Descriptor 3, Serial-number String descriptor */
+									case DEF_STRING_DESC_SERN:
+										pUSBFS_Descr = MySerNumInfo;
+										len = DEF_USBD_SN_DESC_LEN;
+										break;
+
+									default:
+										errflag = 0xFF;
+										break;
+								}
+								break;
+
+							default :
+								errflag = 0xFF;
+								break;
+						}
+
+						/* Copy Descriptors to Endp0 DMA buffer */
+						if( USBFS_SetupReqLen > len )
+						{
+							USBFS_SetupReqLen = len;
+						}
+						len = ( USBFS_SetupReqLen >= DEF_USBD_UEP0_SIZE ) ? DEF_USBD_UEP0_SIZE : USBFS_SetupReqLen;
+						memcpy( USBFS_EP0_Buf, pUSBFS_Descr, len );
+USBDEBUG0 = USBFS_EP0_Buf[3];
+						pUSBFS_Descr += len;
+						break;
+
+					/* Set usb address */
+					case USB_SET_ADDRESS:
+						USBFS_DevAddr = (uint8_t)( USBFS_SetupReqValue & 0xFF );
+						break;
+
+					/* Get usb configuration now set */
+					case USB_GET_CONFIGURATION:
+						USBFS_EP0_Buf[ 0 ] = USBFS_DevConfig;
+						if( USBFS_SetupReqLen > 1 )
+						{
+							USBFS_SetupReqLen = 1;
+						}
+						break;
+
+					/* Set usb configuration to use */
+					case USB_SET_CONFIGURATION:
+						USBFS_DevConfig = (uint8_t)( USBFS_SetupReqValue & 0xFF );
+						USBFS_DevEnumStatus = 0x01;
+						break;
+
+					/* Clear or disable one usb feature */
+					case USB_CLEAR_FEATURE:
+						if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE )
+						{
+							/* clear one device feature */
+							if( (uint8_t)( USBFS_SetupReqValue & 0xFF ) == USB_REQ_FEAT_REMOTE_WAKEUP )
+							{
+								/* clear usb sleep status, device not prepare to sleep */
+								USBFS_DevSleepStatus &= ~0x01;
+							}
+							else
+							{
+								errflag = 0xFF;
+							}
+						}
+						else if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP )
+						{
+							if( (uint8_t)( USBFS_SetupReqValue & 0xFF ) == USB_REQ_FEAT_ENDP_HALT )
+							{
+								/* Clear End-point Feature */
+								switch( (uint8_t)( USBFS_SetupReqIndex & 0xFF ) )
+								{
+									case ( DEF_UEP_IN | DEF_UEP1 ):
+										/* Set End-point 1 OUT ACK */
+										USBFS->UEP1_CTRL_H = USBFS_UEP_T_RES_NAK;
+										break;
+
+									case ( DEF_UEP_IN | DEF_UEP2 ):
+										/* Set End-point 2 IN NAK */
+										USBFS->UEP2_CTRL_H = USBFS_UEP_T_RES_NAK;
+										break;
+
+									default:
+										errflag = 0xFF;
+										break;
+								}
+							}
+							else
+							{
+								errflag = 0xFF;
+							}
+						}
+						else
+						{
+							errflag = 0xFF;
+						}
+						break;
+
+					/* set or enable one usb feature */
+					case USB_SET_FEATURE:
+						if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE )
+						{
+							/* Set Device Feature */
+							if( (uint8_t)( USBFS_SetupReqValue & 0xFF ) == USB_REQ_FEAT_REMOTE_WAKEUP )
+							{
+								if( MyCfgDescr[ 7 ] & 0x20 )
+								{
+									/* Set Wake-up flag, device prepare to sleep */
+									USBFS_DevSleepStatus |= 0x01;
+								}
+								else
+								{
+									errflag = 0xFF;
+								}
+							}
+							else
+							{
+								errflag = 0xFF;
+							}
+						}
+						else if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP )
+						{
+							/* Set Endpoint Feature */
+							if( (uint8_t)( USBFS_SetupReqValue & 0xFF ) == USB_REQ_FEAT_ENDP_HALT )
+							{
+								switch( (uint8_t)( USBFS_SetupReqIndex & 0xFF ) )
+								{
+									case ( DEF_UEP_IN | DEF_UEP1 ):
+										USBFS->UEP1_CTRL_H = ( USBFS->UEP1_CTRL_H & ~USBFS_UEP_T_RES_MASK ) | USBFS_UEP_T_RES_STALL;
+										break;
+
+									case ( DEF_UEP_IN | DEF_UEP2 ):
+										USBFS->UEP2_CTRL_H = ( USBFS->UEP2_CTRL_H & ~USBFS_UEP_T_RES_MASK ) | USBFS_UEP_T_RES_STALL;
+										break;
+
+									default:
+										errflag = 0xFF;
+										break;
+								}
+							}
+							else
+							{
+								errflag = 0xFF;
+							}
+						}
+						else
+						{
+							errflag = 0xFF;
+						}
+						break;
+
+					/* This request allows the host to select another setting for the specified interface  */
+					case USB_GET_INTERFACE:
+						USBFS_EP0_Buf[ 0 ] = 0x00;
+						if( USBFS_SetupReqLen > 1 )
+						{
+							USBFS_SetupReqLen = 1;
+						}
+						break;
+
+					case USB_SET_INTERFACE:
+						break;
+
+					/* host get status of specified device/interface/end-points */
+					case USB_GET_STATUS:
+						USBFS_EP0_Buf[ 0 ] = 0x00;
+						USBFS_EP0_Buf[ 1 ] = 0x00;
+						if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_DEVICE )
+						{
+							if( USBFS_DevSleepStatus & 0x01 )
+							{
+								USBFS_EP0_Buf[ 0 ] = 0x02;
+							}
+							else
+							{
+								USBFS_EP0_Buf[ 0 ] = 0x00;
+							}
+						}
+						else if( ( USBFS_SetupReqType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP )
+						{
+							if( (uint8_t)( USBFS_SetupReqIndex & 0xFF ) == ( DEF_UEP_IN | DEF_UEP1 ) )
+							{
+								if( ( USBFS->UEP1_CTRL_H & USBFS_UEP_T_RES_MASK ) == USBFS_UEP_T_RES_STALL )
+								{
+									USBFS_EP0_Buf[ 0 ] = 0x01;
+								}
+							}
+							else if( (uint8_t)( USBFS_SetupReqIndex & 0xFF ) == ( DEF_UEP_IN | DEF_UEP2 ) )
+							{
+								if( ( USBFS->UEP2_CTRL_H & USBFS_UEP_T_RES_MASK ) == USBFS_UEP_T_RES_STALL )
+								{
+									USBFS_EP0_Buf[ 0 ] = 0x01;
+								}
+							}
+							else
+							{
+								errflag = 0xFF;
+							}
+						}
+						else
+						{
+							errflag = 0xFF;
+						}
+						if( USBFS_SetupReqLen > 2 )
+						{
+							USBFS_SetupReqLen = 2;
+						}
+						break;
+
+					default:
+						errflag = 0xFF;
+						break;
+				}
+			}
+
+			/* errflag = 0xFF means a request not support or some errors occurred, else correct */
+			if( errflag == 0xFF )
+			{
+				/* if one request not support, return stall */
+				USBFS->UEP0_CTRL_H = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_STALL|USBFS_UEP_R_TOG | USBFS_UEP_R_RES_STALL;
+			}
+			else
+			{
+				/* end-point 0 data Tx/Rx */
+				if( USBFS_SetupReqType & DEF_UEP_IN )
+				{
+					len = ( USBFS_SetupReqLen > DEF_USBD_UEP0_SIZE )? DEF_USBD_UEP0_SIZE : USBFS_SetupReqLen;
+					USBFS_SetupReqLen -= len;
+					USBFS->UEP0_TX_LEN = len;
+					USBFS->UEP0_CTRL_H = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_ACK;
+				}
+				else
+				{
+					if( USBFS_SetupReqLen == 0 )
+					{
+						USBFS->UEP0_TX_LEN = 0;
+						USBFS->UEP0_CTRL_H = USBFS_UEP_T_TOG | USBFS_UEP_T_RES_ACK;
+					}
+					else
+					{
+						USBFS->UEP0_CTRL_H = USBFS_UEP_R_TOG | USBFS_UEP_R_RES_ACK;
+					}
+				}
+			}
+			break;
+
+		/* Sof pack processing */
+		case CUIS_TOKEN_SOF:
+			break;
+
+		default :
+			break;
+		}
+	}
+	else if( intfgst & CRB_UIF_BUS_RST )
 	{
-		if( flags & RB_UIF_TRANSFER )
+		/* usb reset interrupt processing */
+		USBFS_DevConfig = 0;
+		USBFS_DevAddr = 0;
+		USBFS_DevSleepStatus = 0;
+		USBFS_DevEnumStatus = 0;
+
+		USBFS->DEV_ADDR = 0;
+		USBFS_Device_Endp_Init( );
+	}
+	else if( intfgst & CRB_UIF_SUSPEND )
+	{
+		/* usb suspend interrupt processing */
+		if( USBFS->MIS_ST & USBFS_UMS_SUSPEND )
 		{
-			// Handle transfer.
-			USBDEBUG0++;
+			USBFS_DevSleepStatus |= 0x02;
+			if( USBFS_DevSleepStatus == 0x03 )
+			{
+				/* Handling usb sleep here */
+				//TODO: MCU_Sleep_Wakeup_Operate( );
+			}
 		}
-		if( flags & RB_UIF_BUS_RST )
+		else
 		{
-			// Handle transfer.
-			USBDEBUG0+=1000;
+			USBFS_DevSleepStatus &= ~0x02;
 		}
-		//USBDEBUG0 = USBFS->INT_FG;
-		USBFS->INT_FG = flags;
 	}
-*/
 
-	*(uint16_t*)(&USBFSD->INT_FG) = intfgst;
-	//intfgst = *(uint16_t*)(&USBFSD->INT_FG);
+	// Handle any other interrupts and just clear them out.
+	*(uint16_t*)(&USBFS->INT_FG) = intfgst;
+
+	//intfgst = *(uint16_t*)(&USBFS->INT_FG);
 	GPIOA->BSHR = 1<<16;
 }
 
+void USBFS_Device_Endp_Init()
+{
+	USBFS->UEP4_1_MOD = EP_SIZE;
+	USBFS->UEP2_3_MOD = EP_SIZE;
+	USBFS->UEP567_MOD = 0;
+
+	USBFS->UEP0_DMA = (intptr_t)USBFS_EP0_Buf;
+	USBFS->UEP1_DMA = (intptr_t)USBFS_EP1_Buf;
+	USBFS->UEP2_DMA = (intptr_t)USBFS_EP2_Buf;
+
+	USBFS->UEP0_CTRL_H = USBFS_UEP_R_RES_ACK | USBFS_UEP_T_RES_NAK;
+	USBFS->UEP1_CTRL_H = USBFS_UEP_T_RES_NAK;
+	USBFS->UEP2_CTRL_H = USBFS_UEP_T_RES_NAK;
+
+    /* Clear End-points Busy Status */
+    for(uint8_t i=0; i< sizeof(USBFS_Endp_Busy)/sizeof(USBFS_Endp_Busy[0]); i++ )
+    {
+        USBFS_Endp_Busy[ i ] = 0;
+    }
+}
+
+
 void USBFS_Poll()
 {
 	USBDEBUG2 = USBFS->INT_ST;//EP0_DATA[1];
@@ -84,13 +739,12 @@ int FSUSBSetup()
 
 	// Enter device mode.
 	USBFS->INT_EN = RB_UIE_SUSPEND | RB_UIE_TRANSFER | RB_UIE_BUS_RST;
-	USBFS->UEP4_1_MOD = 0;
-	USBFS->UEP2_3_MOD = 0;
-	USBFS->UEP567_MOD = 0;
-	USBFS->UEP0_DMA = ((intptr_t)EP0_DATA) & 0x7fff;
-    USBFS->DEV_ADDR = 0x00;
+	USBFS->DEV_ADDR = 0x00;
 	USBFS->UDEV_CTRL = RB_UD_PD_DIS | RB_UD_PORT_EN;
 
+	USBFS_Device_Endp_Init();
+
+
 	// Go on-bus.
 
 	// From the TRM:
diff --git a/examples_x035/usbdevice.incomplete/fsusb.h b/examples_x035/usbdevice.incomplete/fsusb.h
index 76f794e439975a20c3502bac08fcada6e80904c6..31f589e0462fb9cc3ea1262ccc8cde42a654e455 100644
--- a/examples_x035/usbdevice.incomplete/fsusb.h
+++ b/examples_x035/usbdevice.incomplete/fsusb.h
@@ -3,10 +3,378 @@
 
 #include <stdint.h>
 
+#include "descriptor.h"
+
 extern uint32_t USBDEBUG0, USBDEBUG1, USBDEBUG2;
 
 int FSUSBSetup();
 void USBFS_Poll();
 
+
+// XXX TODO: Put the below in an object.
+
+/*******************************************************************************/
+/* Variable Definition */
+/* Global */
+extern const    uint8_t  *pUSBFS_Descr;
+
+/* Setup Request */
+extern volatile uint8_t  USBFS_SetupReqCode;
+extern volatile uint8_t  USBFS_SetupReqType;
+extern volatile uint16_t USBFS_SetupReqValue;
+extern volatile uint16_t USBFS_SetupReqIndex;
+extern volatile uint16_t USBFS_SetupReqLen;
+
+/* USB Device Status */
+extern volatile uint8_t  USBFS_DevConfig;
+extern volatile uint8_t  USBFS_DevAddr;
+extern volatile uint8_t  USBFS_DevSleepStatus;
+extern volatile uint8_t  USBFS_DevEnumStatus;
+
+/* Endpoint Buffer */
+extern __attribute__ ((aligned(4))) uint8_t USBFS_EP0_Buf[];
+extern __attribute__ ((aligned(4))) uint8_t USBFS_EP2_Buf[];
+
+
+/* USB IN Endpoint Busy Flag */
+extern volatile uint8_t  USBFS_Endp_Busy[ ];
+
+
+// ABOVE: TOOD: REWRITE!
+
+// Copied from x035 documentation.
+
+#define USBFSD_UEP_MOD_BASE         0x5000000C
+#define USBFSD_UEP_DMA_BASE         0x50000010
+#define USBFSD_UEP_LEN_BASE         0x50000030
+#define USBFSD_UEP_CTL_BASE         0x50000032
+#define USBFSD_UEP_RX_EN            0x08
+#define USBFSD_UEP_TX_EN            0x04
+#define USBFSD_UEP_BUF_MOD          0x01
+#define DEF_UEP_DMA_LOAD            0 /* Direct the DMA address to the data to be processed */
+#define DEF_UEP_CPY_LOAD            1 /* Use memcpy to move data to a buffer */
+#define USBFSD_UEP_MOD( N )         (*((volatile uint8_t *)( USBFSD_UEP_MOD_BASE + N )))
+#define USBFSD_UEP_TX_CTRL( N )     (*((volatile uint8_t *)( USBFSD_UEP_CTL_BASE + N * 0x04 )))
+#define USBFSD_UEP_RX_CTRL( N )     (*((volatile uint8_t *)( USBFSD_UEP_CTL_BASE + N * 0x04 + 1 )))
+#define USBFSD_UEP_DMA( N )         (*((volatile uint32_t *)( USBFSD_UEP_DMA_BASE + N * 0x04 )))
+#define USBFSD_UEP_BUF( N )         ((uint8_t *)(*((volatile uint32_t *)( USBFSD_UEP_DMA_BASE + N * 0x04 ))) + 0x20000000)
+#define USBFSD_UEP_TLEN( N )        (*((volatile uint16_t *)( USBFSD_UEP_LEN_BASE + N * 0x04 )))
+
+
+
+/* R8_UEPn_TX_CTRL */
+#define USBFS_UEP_T_AUTO_TOG        (1<<4)      // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
+#define USBFS_UEP_T_TOG             (1<<6)      // prepared data toggle flag of USB endpoint X transmittal (IN): 0=DATA0, 1=DATA1
+#define USBFS_UEP_T_RES_MASK        (3<<0)      // bit mask of handshake response type for USB endpoint X transmittal (IN)
+#define USBFS_UEP_T_RES_ACK         (0<<1)
+#define USBFS_UEP_T_RES_NONE        (1<<0)
+#define USBFS_UEP_T_RES_NAK         (1<<1)
+#define USBFS_UEP_T_RES_STALL       (3<<0)
+// bUEP_T_RES1 & bUEP_T_RES0: handshake response type for USB endpoint X transmittal (IN)
+//   00: DATA0 or DATA1 then expecting ACK (ready)
+//   01: DATA0 or DATA1 then expecting no response, time out from host, for non-zero endpoint isochronous transactions
+//   10: NAK (busy)
+//   11: STALL (error)
+// host aux setup
+
+/* R8_UEPn_RX_CTRL, n=0-7 */
+#define USBFS_UEP_R_AUTO_TOG        (1<<4)      // enable automatic toggle after successful transfer completion on endpoint 1/2/3: 0=manual toggle, 1=automatic toggle
+#define USBFS_UEP_R_TOG             (1<<7)      // expected data toggle flag of USB endpoint X receiving (OUT): 0=DATA0, 1=DATA1
+#define USBFS_UEP_R_RES_MASK        (3<<2)      // bit mask of handshake response type for USB endpoint X receiving (OUT)
+#define USBFS_UEP_R_RES_ACK         (0<<3)
+#define USBFS_UEP_R_RES_NONE        (1<<2)
+#define USBFS_UEP_R_RES_NAK         (1<<3)
+#define USBFS_UEP_R_RES_STALL       (3<<2)
+
+
+/* R8_USB_DEV_AD */
+#define USBFS_UDA_GP_BIT            0x80
+#define USBFS_USB_ADDR_MASK         0x7F
+
+
+/* USB Setup Request */
+typedef struct __attribute__((packed)) _USB_SETUP_REQ
+{
+    uint8_t  bRequestType;
+    uint8_t  bRequest;
+    uint16_t wValue;
+    uint16_t wIndex;
+    uint16_t wLength;
+} USB_SETUP_REQ, *PUSB_SETUP_REQ;
+
+/* USB Device Descriptor */
+typedef struct __attribute__((packed)) _USB_DEVICE_DESCR
+{
+    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;
+} USB_DEV_DESCR, *PUSB_DEV_DESCR;
+
+/* USB Configuration Descriptor */
+typedef struct __attribute__((packed)) _USB_CONFIG_DESCR
+{
+    uint8_t  bLength;
+    uint8_t  bDescriptorType;
+    uint16_t wTotalLength;
+    uint8_t  bNumInterfaces;
+    uint8_t  bConfigurationValue;
+    uint8_t  iConfiguration;
+    uint8_t  bmAttributes;
+    uint8_t  MaxPower;
+} USB_CFG_DESCR, *PUSB_CFG_DESCR;
+
+/* USB Interface Descriptor */
+typedef struct __attribute__((packed)) _USB_INTERF_DESCR
+{
+    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;
+} USB_ITF_DESCR, *PUSB_ITF_DESCR;
+
+/* USB Endpoint Descriptor */
+typedef struct __attribute__((packed)) _USB_ENDPOINT_DESCR
+{
+    uint8_t  bLength;
+    uint8_t  bDescriptorType;
+    uint8_t  bEndpointAddress;
+    uint8_t  bmAttributes;
+    uint8_t  wMaxPacketSizeL;
+    uint8_t  wMaxPacketSizeH;
+    uint8_t  bInterval;
+} USB_ENDP_DESCR, *PUSB_ENDP_DESCR;
+
+/* USB Configuration Descriptor Set */
+typedef struct __attribute__((packed)) _USB_CONFIG_DESCR_LONG
+{
+    USB_CFG_DESCR  cfg_descr;
+    USB_ITF_DESCR  itf_descr;
+    USB_ENDP_DESCR endp_descr[ 1 ];
+} USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG;
+
+/* USB HUB Descriptor */
+typedef struct __attribute__((packed)) _USB_HUB_DESCR
+{
+    uint8_t  bDescLength;
+    uint8_t  bDescriptorType;
+    uint8_t  bNbrPorts;
+    uint8_t  wHubCharacteristicsL;
+    uint8_t  wHubCharacteristicsH;
+    uint8_t  bPwrOn2PwrGood;
+    uint8_t  bHubContrCurrent;
+    uint8_t  DeviceRemovable;
+    uint8_t  PortPwrCtrlMask;
+} USB_HUB_DESCR, *PUSB_HUB_DESCR;
+
+/* USB HID Descriptor */
+typedef struct __attribute__((packed)) _USB_HID_DESCR
+{
+    uint8_t  bLength;
+    uint8_t  bDescriptorType;
+    uint16_t bcdHID;
+    uint8_t  bCountryCode;
+    uint8_t  bNumDescriptors;
+    uint8_t  bDescriptorTypeX;
+    uint8_t  wDescriptorLengthL;
+    uint8_t  wDescriptorLengthH;
+} USB_HID_DESCR, *PUSB_HID_DESCR;
+
+
+/*******************************************************************************/
+/* USB Communication Related Macro Definition */
+
+/* USB PID */
+#ifndef USB_PID_SETUP
+#define USB_PID_NULL                0x00
+#define USB_PID_SOF                 0x05
+#define USB_PID_SETUP               0x0D
+#define USB_PID_IN                  0x09
+#define USB_PID_OUT                 0x01
+#define USB_PID_NYET                0x06
+#define USB_PID_ACK                 0x02
+#define USB_PID_NAK                 0x0A
+#define USB_PID_STALL               0x0E
+#define USB_PID_DATA0               0x03
+#define USB_PID_DATA1               0x0B
+#define USB_PID_PRE                 0x0C
+#endif
+
+/* USB standard device request code */
+#ifndef USB_GET_DESCRIPTOR
+#define USB_GET_STATUS              0x00
+#define USB_CLEAR_FEATURE           0x01
+#define USB_SET_FEATURE             0x03
+#define USB_SET_ADDRESS             0x05
+#define USB_GET_DESCRIPTOR          0x06
+#define USB_SET_DESCRIPTOR          0x07
+#define USB_GET_CONFIGURATION       0x08
+#define USB_SET_CONFIGURATION       0x09
+#define USB_GET_INTERFACE           0x0A
+#define USB_SET_INTERFACE           0x0B
+#define USB_SYNCH_FRAME             0x0C
+#endif
+
+#define DEF_STRING_DESC_LANG        0x00
+#define DEF_STRING_DESC_MANU        0x01
+#define DEF_STRING_DESC_PROD        0x02
+#define DEF_STRING_DESC_SERN        0x03
+
+/* USB hub class request code */
+#ifndef HUB_GET_DESCRIPTOR
+#define HUB_GET_STATUS              0x00
+#define HUB_CLEAR_FEATURE           0x01
+#define HUB_GET_STATE               0x02
+#define HUB_SET_FEATURE             0x03
+#define HUB_GET_DESCRIPTOR          0x06
+#define HUB_SET_DESCRIPTOR          0x07
+#endif
+
+/* USB HID class request code */
+#ifndef HID_GET_REPORT
+#define HID_GET_REPORT              0x01
+#define HID_GET_IDLE                0x02
+#define HID_GET_PROTOCOL            0x03
+#define HID_SET_REPORT              0x09
+#define HID_SET_IDLE                0x0A
+#define HID_SET_PROTOCOL            0x0B
+#endif
+
+/* Bit Define for USB Request Type */
+#ifndef USB_REQ_TYP_MASK
+#define USB_REQ_TYP_IN              0x80
+#define USB_REQ_TYP_OUT             0x00
+#define USB_REQ_TYP_READ            0x80
+#define USB_REQ_TYP_WRITE           0x00
+#define USB_REQ_TYP_MASK            0x60
+#define USB_REQ_TYP_STANDARD        0x00
+#define USB_REQ_TYP_CLASS           0x20
+#define USB_REQ_TYP_VENDOR          0x40
+#define USB_REQ_TYP_RESERVED        0x60
+#define USB_REQ_RECIP_MASK          0x1F
+#define USB_REQ_RECIP_DEVICE        0x00
+#define USB_REQ_RECIP_INTERF        0x01
+#define USB_REQ_RECIP_ENDP          0x02
+#define USB_REQ_RECIP_OTHER         0x03
+#define USB_REQ_FEAT_REMOTE_WAKEUP  0x01
+#define USB_REQ_FEAT_ENDP_HALT      0x00
+#endif
+
+/* USB Descriptor Type */
+#ifndef USB_DESCR_TYP_DEVICE
+#define USB_DESCR_TYP_DEVICE        0x01
+#define USB_DESCR_TYP_CONFIG        0x02
+#define USB_DESCR_TYP_STRING        0x03
+#define USB_DESCR_TYP_INTERF        0x04
+#define USB_DESCR_TYP_ENDP          0x05
+#define USB_DESCR_TYP_QUALIF        0x06
+#define USB_DESCR_TYP_SPEED         0x07
+#define USB_DESCR_TYP_OTG           0x09
+#define USB_DESCR_TYP_BOS           0X0F
+#define USB_DESCR_TYP_HID           0x21
+#define USB_DESCR_TYP_REPORT        0x22
+#define USB_DESCR_TYP_PHYSIC        0x23
+#define USB_DESCR_TYP_CS_INTF       0x24
+#define USB_DESCR_TYP_CS_ENDP       0x25
+#define USB_DESCR_TYP_HUB           0x29
+#endif
+
+/* USB Device Class */
+#ifndef USB_DEV_CLASS_HUB
+#define USB_DEV_CLASS_RESERVED      0x00
+#define USB_DEV_CLASS_AUDIO         0x01
+#define USB_DEV_CLASS_COMMUNIC      0x02
+#define USB_DEV_CLASS_HID           0x03
+#define USB_DEV_CLASS_MONITOR       0x04
+#define USB_DEV_CLASS_PHYSIC_IF     0x05
+#define USB_DEV_CLASS_POWER         0x06
+#define USB_DEV_CLASS_PRINTER       0x07
+#define USB_DEV_CLASS_STORAGE       0x08
+#define USB_DEV_CLASS_HUB           0x09
+#define USB_DEV_CLASS_VEN_SPEC      0xFF
+#endif
+
+/* USB Hub Class Request */
+#ifndef HUB_GET_HUB_DESCRIPTOR
+#define HUB_CLEAR_HUB_FEATURE       0x20
+#define HUB_CLEAR_PORT_FEATURE      0x23
+#define HUB_GET_BUS_STATE           0xA3
+#define HUB_GET_HUB_DESCRIPTOR      0xA0
+#define HUB_GET_HUB_STATUS          0xA0
+#define HUB_GET_PORT_STATUS         0xA3
+#define HUB_SET_HUB_DESCRIPTOR      0x20
+#define HUB_SET_HUB_FEATURE         0x20
+#define HUB_SET_PORT_FEATURE        0x23
+#endif
+
+/* Hub Class Feature Selectors */
+#ifndef HUB_PORT_RESET
+#define HUB_C_HUB_LOCAL_POWER       0
+#define HUB_C_HUB_OVER_CURRENT      1
+#define HUB_PORT_CONNECTION         0
+#define HUB_PORT_ENABLE             1
+#define HUB_PORT_SUSPEND            2
+#define HUB_PORT_OVER_CURRENT       3
+#define HUB_PORT_RESET              4
+#define HUB_PORT_POWER              8
+#define HUB_PORT_LOW_SPEED          9
+#define HUB_C_PORT_CONNECTION       16
+#define HUB_C_PORT_ENABLE           17
+#define HUB_C_PORT_SUSPEND          18
+#define HUB_C_PORT_OVER_CURRENT     19
+#define HUB_C_PORT_RESET            20
+#endif
+
+/* USB HID Class Request Code */
+#ifndef HID_GET_REPORT
+#define HID_GET_REPORT              0x01
+#define HID_GET_IDLE                0x02
+#define HID_GET_PROTOCOL            0x03
+#define HID_SET_REPORT              0x09
+#define HID_SET_IDLE                0x0A
+#define HID_SET_PROTOCOL            0x0B
+#endif
+
+/* USB UDisk */
+#ifndef USB_BO_CBW_SIZE
+#define USB_BO_CBW_SIZE             0x1F
+#define USB_BO_CSW_SIZE             0x0D
+#endif
+#ifndef USB_BO_CBW_SIG0
+#define USB_BO_CBW_SIG0             0x55
+#define USB_BO_CBW_SIG1             0x53
+#define USB_BO_CBW_SIG2             0x42
+#define USB_BO_CBW_SIG3             0x43
+#define USB_BO_CSW_SIG0             0x55
+#define USB_BO_CSW_SIG1             0x53
+#define USB_BO_CSW_SIG2             0x42
+#define USB_BO_CSW_SIG3             0x53
+#endif
+
+/* USB CDC Class request code */
+#ifndef CDC_GET_LINE_CODING
+#define CDC_GET_LINE_CODING         0X21                                      /* This request allows the host to find out the currently configured line coding */
+#define CDC_SET_LINE_CODING         0x20                                      /* Configures DTE rate, stop-bits, parity, and number-of-character */
+#define CDC_SET_LINE_CTLSTE         0X22                                      /* This request generates RS-232/V.24 style control signals */
+#define CDC_SEND_BREAK              0X23                                      /* Sends special carrier modulation used to specify RS-232 style break */
+#endif
+/*******************************************************************************/
+
+
 #endif