From a48627b3e5189837d7f183270c88c2b7494ab8c5 Mon Sep 17 00:00:00 2001
From: Thibaut VIARD <thibaut.viard@atmel.com>
Date: Mon, 12 May 2014 20:09:09 +0200
Subject: [PATCH]  Bringing USB files in name of JcB

---
 cores/arduino/USB/CDC.cpp                     |  39 +-
 cores/arduino/USB/HID.cpp                     |  15 +-
 cores/arduino/USB/USBAPI.h                    |  20 +-
 cores/arduino/USB/USBCore.cpp                 | 403 ++++------
 cores/arduino/USB/USBCore.h                   |   8 +-
 cores/arduino/USB/USBDesc.h                   |   2 +-
 cores/arduino/USB/USB_device.h                | 412 ++++++++++
 cores/arduino/USB/USB_host.h                  |  78 ++
 cores/arduino/USB/samd21_device.c             | 713 ++++++++++++++++++
 cores/arduino/USB/samd21_device.h             | 622 +++++++++++++++
 cores/arduino/USB/samd21_host.c               | 489 ++++++++++++
 cores/arduino/USB/samd21_host.h               | 399 ++++++++++
 .../build_as6/test.atsln                      |  20 +
 .../build_as6/test.atsuo                      | Bin 0 -> 39424 bytes
 .../build_as6/test.cppproj                    | 498 ++++++++++++
 .../validation_usb_device/build_gcc/Makefile  |  31 +-
 .../validation_usb_device/build_gcc/debug.mk  |   4 +-
 .../validation_usb_device/build_gcc/gcc.mk    |  54 +-
 .../build_gcc/test_usb_device.mk              | 208 ++---
 .../validation_usb_device/test_usb_device.cpp |  51 +-
 20 files changed, 3653 insertions(+), 413 deletions(-)
 create mode 100644 cores/arduino/USB/USB_device.h
 create mode 100644 cores/arduino/USB/USB_host.h
 create mode 100644 cores/arduino/USB/samd21_device.c
 create mode 100644 cores/arduino/USB/samd21_device.h
 create mode 100644 cores/arduino/USB/samd21_host.c
 create mode 100644 cores/arduino/USB/samd21_host.h
 create mode 100644 cores/arduino/validation_usb_device/build_as6/test.atsln
 create mode 100644 cores/arduino/validation_usb_device/build_as6/test.atsuo
 create mode 100644 cores/arduino/validation_usb_device/build_as6/test.cppproj

diff --git a/cores/arduino/USB/CDC.cpp b/cores/arduino/USB/CDC.cpp
index 84a4e913..fd93a5e0 100644
--- a/cores/arduino/USB/CDC.cpp
+++ b/cores/arduino/USB/CDC.cpp
@@ -14,10 +14,22 @@
 ** SOFTWARE.
 */
 
-#include "Arduino.h"
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+
+// Include Atmel headers
+#include "sam.h"
+#include "wiring_constants.h"
+#include "USBCore.h"
+#include "USB_device.h"
+#include "USBDesc.h"
 #include "USBAPI.h"
+//#include "samd21_device.h"
+
 #include "Reset.h"
 
+
 #ifdef CDC_ENABLED
 
 #define CDC_SERIAL_BUFFER_SIZE	512
@@ -159,15 +171,15 @@ void Serial_::end(void)
 
 void Serial_::accept(void)
 {
-	static uint32_t guard = 0;
+//	static uint32_t guard = 0;
 
 	// synchronized access to guard
-	do {
-		if (__LDREXW(&guard) != 0) {
-			__CLREX();
-			return;  // busy
-		}
-	} while (__STREXW(1, &guard) != 0); // retry until write succeed
+//JCB	do {
+//		if (__LDREXW(&guard) != 0) {
+//			__CLREX();
+//			return;  // busy
+//		}
+//	} while (__STREXW(1, &guard) != 0); // retry until write succeed
 
 	ring_buffer *buffer = &cdc_rx_buffer;
 	uint32_t i = (uint32_t)(buffer->head+1) % CDC_SERIAL_BUFFER_SIZE;
@@ -179,7 +191,8 @@ void Serial_::accept(void)
 	while (i != buffer->tail) {
 		uint32_t c;
 		if (!USBD_Available(CDC_RX)) {
-			udd_ack_fifocon(CDC_RX);
+            UDD_ReleaseRX(CDC_RX);
+			//JCB udd_ack_fifocon(CDC_RX);
 			break;
 		}
 		c = USBD_Recv(CDC_RX);
@@ -191,7 +204,7 @@ void Serial_::accept(void)
 	}
 
 	// release the guard
-	guard = 0;
+//	guard = 0;
 }
 
 int Serial_::available(void)
@@ -280,8 +293,8 @@ size_t Serial_::write(uint8_t c) {
 Serial_::operator bool()
 {
 	// this is here to avoid spurious opening after upload
-	if (millis() < 500)
-		return false;
+//	if (millis() < 500)
+//		return false;
 
 	bool result = false;
 
@@ -290,7 +303,7 @@ Serial_::operator bool()
 		result = true;
 	}
 
-	delay(10);
+//	delay(10);
 	return result;
 }
 
diff --git a/cores/arduino/USB/HID.cpp b/cores/arduino/USB/HID.cpp
index c243f495..6994c14b 100644
--- a/cores/arduino/USB/HID.cpp
+++ b/cores/arduino/USB/HID.cpp
@@ -14,11 +14,19 @@
 ** SOFTWARE.
 */
 
-#include "Arduino.h"
-
 #ifdef HID_ENABLED
 
+#include "USBAPI.h"
+#include "Reset.h"
+#include "USBCore.h"
+#include "USBDesc.h"
+#include "sam.h"
+#include "USB_device.h"
+
 //#define RAWHID_ENABLED
+#ifdef __cplusplus
+extern "C"{
+#endif // __cplusplus
 
 //	Singletons for mouse and keyboard
 
@@ -196,6 +204,9 @@ bool WEAK HID_Setup(Setup& setup)
 	}
 	return false;
 }
+#ifdef __cplusplus
+}
+#endif
 
 //================================================================================
 //================================================================================
diff --git a/cores/arduino/USB/USBAPI.h b/cores/arduino/USB/USBAPI.h
index 3cf601e9..7fa8b471 100644
--- a/cores/arduino/USB/USBAPI.h
+++ b/cores/arduino/USB/USBAPI.h
@@ -19,8 +19,20 @@
 #ifndef __USBAPI__
 #define __USBAPI__
 
+
+/* Define attribute */
+#if defined   ( __CC_ARM   ) /* Keil uVision 4 */
+    #define WEAK (__attribute__ ((weak)))
+#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */
+    #define WEAK __weak
+#elif defined (  __GNUC__  ) /* GCC CS */
+    #define WEAK __attribute__ ((weak))
+#endif
+
+
 #if defined __cplusplus
 
+#include "Stream.h"
 #include "RingBuffer.h"
 
 //================================================================================
@@ -49,7 +61,7 @@ private:
 	RingBuffer *_cdc_rx_buffer;
 public:
 	void begin(uint32_t baud_count);
-	void begin(uint32_t baud_count, uint8_t config);
+	void begin(unsigned long, uint8_t);
 	void end(void);
 
 	virtual int available(void);
@@ -189,7 +201,7 @@ bool	MSC_Data(uint8_t rx,uint8_t tx);
 
 //================================================================================
 //================================================================================
-//	CSC 'Driver'
+//	CDC 'Driver'
 
 int		CDC_GetInterface(uint8_t* interfaceNum);
 int		CDC_GetOtherInterface(uint8_t* interfaceNum);
@@ -217,5 +229,5 @@ uint32_t USBD_Recv(uint32_t ep);							// non-blocking
 void USBD_Flush(uint32_t ep);
 uint32_t USBD_Connected(void);
 
-#endif
-#endif
+#endif  // __cplusplus
+#endif  // __USBAPI__
diff --git a/cores/arduino/USB/USBCore.cpp b/cores/arduino/USB/USBCore.cpp
index 7876762b..807462fb 100644
--- a/cores/arduino/USB/USBCore.cpp
+++ b/cores/arduino/USB/USBCore.cpp
@@ -13,16 +13,40 @@
 ** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 ** SOFTWARE.
 */
-
-#include "Arduino.h"
-#include "USBAPI.h"
-#include "Reset.h"
+#include <stdlib.h>
 #include <stdio.h>
+#include <stdint.h>
+// Include Atmel headers
+#include "sam.h"
+#include "wiring_constants.h"
+#include "USBCore.h"
+#include "USB_device.h"   // needed for USB PID define
+#include "USBDesc.h"
+#include "USBAPI.h"
+
+#define TRACE_CORE(x)	x
+//#define TRACE_CORE(x)
+
+// USB Device
+#define USB_VID            0x2341 // arduino LLC vid
+#define USB_PID_LEONARDO   0x0034
+#define USB_PID_MICRO      0x0035
+#define USB_PID_DUE        0x003E
+#define USB_PID_ZERO       0x004D
+
+
+#define EP_TYPE_CONTROL          0
+#ifdef CDC_ENABLED
+#define EP_TYPE_INTERRUPT_IN     1       // CDC_ENDPOINT_ACM
+#define EP_TYPE_BULK_OUT         2       // CDC_ENDPOINT_OUT
+#define EP_TYPE_BULK_IN          3       // CDC_ENDPOINT_IN
+#endif
+#ifdef HID_ENABLED
+#define EP_TYPE_INTERRUPT_IN_HID 4       // HID_ENDPOINT_INT
+#endif
 
-//#define TRACE_CORE(x)	x
-#define TRACE_CORE(x)
 
-static const uint32_t EndPoints[] =
+static const uint8_t EndPoints[] =
 {
 	EP_TYPE_CONTROL,
 
@@ -90,18 +114,18 @@ const DeviceDescriptor USB_DeviceDescriptor =
 const DeviceDescriptor USB_DeviceDescriptorA =
 	D_DEVICE(DEVICE_CLASS,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1);
 
-const DeviceDescriptor USB_DeviceQualifier =
-	D_QUALIFIER(0x00,0x00,0x00,64,1);
-
-//! 7.1.20 Test Mode Support
-static const unsigned char test_packet_buffer[] = {
-    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,                // JKJKJKJK * 9
-    0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,                     // JJKKJJKK * 8
-    0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,                     // JJJJKKKK * 8
-    0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // JJJJJJJKKKKKKK * 8
-    0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,                          // JJJJJJJK * 8
-    0xFC,0x7E,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0x7E                 // {JKKKKKKK * 10}, JK
-};
+//const DeviceDescriptor USB_DeviceQualifier =
+//	D_QUALIFIER(0x00,0x00,0x00,64,1);
+//
+////! 7.1.20 Test Mode Support
+//static const unsigned char test_packet_buffer[] = {
+//    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,                // JKJKJKJK * 9
+//    0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,                     // JJKKJJKK * 8
+//    0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,                     // JJJJKKKK * 8
+//    0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // JJJJJJJKKKKKKK * 8
+//    0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,                          // JJJJJJJK * 8
+//    0xFC,0x7E,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0x7E                 // {JKKKKKKK * 10}, JK
+//};
 
 //==================================================================
 //==================================================================
@@ -115,23 +139,23 @@ uint32_t _cdcComposite = 0;
 //==================================================================
 
 #define USB_RECV_TIMEOUT
-class LockEP
-{
-	irqflags_t flags;
-public:
-	LockEP(uint32_t ep) : flags(cpu_irq_save())
-	{
-	}
-	~LockEP()
-	{
-		cpu_irq_restore(flags);
-	}
-};
+//class LockEP
+//{
+//	irqflags_t flags;
+//public:
+//	LockEP(uint32_t ep) : flags(cpu_irq_save())
+//	{
+//	}
+//	~LockEP()
+//	{
+//		cpu_irq_restore(flags);
+//	}
+//};
 
 //	Number of bytes, assumes a rx endpoint
 uint32_t USBD_Available(uint32_t ep)
 {
-	LockEP lock(ep);
+//	LockEP lock(ep);
 	return UDD_FifoByteCount(ep & 0xF);
 }
 
@@ -142,7 +166,7 @@ uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len)
 	if (!_usbConfiguration || len < 0)
 		return -1;
 
-	LockEP lock(ep);
+//	LockEP lock(ep);
 	uint32_t n = UDD_FifoByteCount(ep & 0xF);
 	len = min(n,len);
 	n = len;
@@ -263,7 +287,7 @@ static bool USB_SendStringDescriptor(const uint8_t *string, int wLength) {
 //	TODO
 int USBD_RecvControl(void* d, uint32_t len)
 {
-	UDD_WaitOUT();
+//	UDD_WaitOUT();
 	UDD_Recv(EP0, (uint8_t*)d, len);
 	UDD_ClearOUT();
 
@@ -312,23 +336,23 @@ int USBD_SendInterfaces(void)
 	return interfaces;
 }
 
-int USBD_SendOtherInterfaces(void)
-{
-	int total = 0;
-	uint8_t interfaces = 0;
-
-#ifdef CDC_ENABLED
-	total = CDC_GetOtherInterface(&interfaces);
-#endif
-
-#ifdef HID_ENABLED
-	total += HID_GetInterface(&interfaces);
-#endif
-
-	total = total; // Get rid of compiler warning
-	TRACE_CORE(printf("=> USBD_SendInterfaces, total=%d interfaces=%d\r\n", total, interfaces);)
-	return interfaces;
-}
+//int USBD_SendOtherInterfaces(void)
+//{
+//	int total = 0;
+//	uint8_t interfaces = 0;
+//
+//#ifdef CDC_ENABLED
+//	total = CDC_GetOtherInterface(&interfaces);
+//#endif
+//
+//#ifdef HID_ENABLED
+//	total += HID_GetInterface(&interfaces);
+//#endif
+//
+//	total = total; // Get rid of compiler warning
+//	TRACE_CORE(printf("=> USBD_SendInterfaces, total=%d interfaces=%d\r\n", total, interfaces);)
+//	return interfaces;
+//}
 
 //	Construct a dynamic configuration descriptor
 //	This really needs dynamic endpoint allocation etc
@@ -342,9 +366,9 @@ static bool USBD_SendConfiguration(int maxlen)
 	//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);)
 	//TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));)
 
-_Pragma("pack(1)")
-	ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
-_Pragma("pack()")
+//JCB _Pragma("pack(1)")
+	ConfigDescriptor config = D_CONFIG((uint16_t)(_cmark + sizeof(ConfigDescriptor)),(uint8_t)interfaces);
+//JCB  _Pragma("pack()")
 	//TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);)
 
 	//TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);)
@@ -356,28 +380,28 @@ _Pragma("pack()")
 	return true;
 }
 
-static bool USBD_SendOtherConfiguration(int maxlen)
-{
-	//	Count and measure interfaces
-	USBD_InitControl(0);
-	//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);)
-	int interfaces = USBD_SendOtherInterfaces();
-	//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);)
-	//TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));)
-
-_Pragma("pack(1)")
-	ConfigDescriptor config = D_OTHERCONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
-_Pragma("pack()")
-	//TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);)
-
-	//TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);)
-
-	//	Now send them
-	USBD_InitControl(maxlen);
-	USBD_SendControl(0,&config,sizeof(ConfigDescriptor));
-	USBD_SendOtherInterfaces();
-	return true;
-}
+//static bool USBD_SendOtherConfiguration(int maxlen)
+//{
+//	//	Count and measure interfaces
+//	USBD_InitControl(0);
+//	//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);)
+//	int interfaces = USBD_SendOtherInterfaces();
+//	//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);)
+//	//TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));)
+//
+//_Pragma("pack(1)")
+//	ConfigDescriptor config = D_OTHERCONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
+//_Pragma("pack()")
+//	//TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);)
+//
+//	//TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);)
+//
+//	//	Now send them
+//	USBD_InitControl(maxlen);
+//	USBD_SendControl(0,&config,sizeof(ConfigDescriptor));
+//	USBD_SendOtherInterfaces();
+//	return true;
+//}
 
 static bool USBD_SendDescriptor(Setup& setup)
 {
@@ -431,22 +455,22 @@ static bool USBD_SendDescriptor(Setup& setup)
 			desc_length = setup.wLength;
 		}
 	}
-	else if (USB_DEVICE_QUALIFIER == t)
-	{
-		// Device qualifier descriptor requested
-		desc_addr = (const uint8_t*)&USB_DeviceQualifier;
-        if( *desc_addr > setup.wLength ) {
-            desc_length = setup.wLength;
-        }
-    }
-    else if (USB_OTHER_SPEED_CONFIGURATION == t)
-    {
-		// Other configuration descriptor requested
-		return USBD_SendOtherConfiguration(setup.wLength);
-    }
+//	else if (USB_DEVICE_QUALIFIER == t)
+//	{
+//		// Device qualifier descriptor requested
+//		desc_addr = (const uint8_t*)&USB_DeviceQualifier;
+//        if( *desc_addr > setup.wLength ) {
+//            desc_length = setup.wLength;
+//        }
+//    }
+//    else if (USB_OTHER_SPEED_CONFIGURATION == t)
+//    {
+//		// Other configuration descriptor requested
+//		return USBD_SendOtherConfiguration(setup.wLength);
+//    }
     else
     {
-        //printf("Device ERROR");
+        TRACE_CORE(printf("Device ERROR");)
     }
 
 	if (desc_addr == 0)
@@ -466,131 +490,26 @@ static bool USBD_SendDescriptor(Setup& setup)
 }
 
 
-static void USB_SendZlp( void )
-{
-    while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[0] & UOTGHS_DEVEPTISR_TXINI ) )
-    {
-        if((UOTGHS->UOTGHS_DEVISR & UOTGHS_DEVISR_SUSP) == UOTGHS_DEVISR_SUSP)
-        {
-            return;
-        }
-    }
-    UOTGHS->UOTGHS_DEVEPTICR[0] = UOTGHS_DEVEPTICR_TXINIC;
-}
-
-
-static void Test_Mode_Support( uint8_t wIndex )
-{
-    uint8_t i;
-	uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(2);
-
-	switch( wIndex )
-	{
-		case 4:
-			//Test mode Test_Packet:
-			//Upon command, a port must repetitively transmit the following test packet until
-			//the exit action is taken. This enables the testing of rise and fall times, eye
-			//patterns, jitter, and any other dynamic waveform specifications.
-			//The test packet is made up by concatenating the following strings.
-			//(Note: For J/K NRZI data, and for NRZ data, the bit on the left is the first one
-			//transmitted. "S" indicates that a bit stuff occurs, which inserts an "extra" NRZI data bit.
-			//"* N" is used to indicate N occurrences of a string of bits or symbols.)
-			//A port in Test_Packet mode must send this packet repetitively. The inter-packet timing
-			//must be no less than the minimum allowable inter-packet gap as defined in Section 7.1.18 and
-			//no greater than 125 us.
-
-			// Send ZLP
-			USB_SendZlp();
-
-			UOTGHS->UOTGHS_DEVDMA[0].UOTGHS_DEVDMACONTROL = 0; // raz
-			UOTGHS->UOTGHS_DEVDMA[1].UOTGHS_DEVDMACONTROL = 0; // raz
-
-			// Configure endpoint 2, 64 bytes, direction IN, type BULK, 1 bank
-			UOTGHS->UOTGHS_DEVEPTCFG[2] = UOTGHS_DEVEPTCFG_EPSIZE_64_BYTE
-												 | UOTGHS_DEVEPTCFG_EPDIR_IN
-												 | UOTGHS_DEVEPTCFG_EPTYPE_BLK
-												 | UOTGHS_DEVEPTCFG_EPBK_1_BANK;
-			// Check if the configuration is ok
-			UOTGHS->UOTGHS_DEVEPTCFG[2] |= UOTGHS_DEVEPTCFG_ALLOC;
-			while((UOTGHS->UOTGHS_DEVEPTISR[2]&UOTGHS_DEVEPTISR_CFGOK)==0) {}
-			UOTGHS->UOTGHS_DEVEPT |= UOTGHS_DEVEPT_EPEN2;
-			// Write FIFO
-			for( i=0; i<sizeof(test_packet_buffer); i++)
-			{
-				ptr_dest[i] = test_packet_buffer[i];;
-			}
-			// Tst PACKET
-			UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTPCKT;
-			// Send packet
-			UOTGHS->UOTGHS_DEVEPTICR[2] = UOTGHS_DEVEPTICR_TXINIC;
-			UOTGHS->UOTGHS_DEVEPTIDR[2] = UOTGHS_DEVEPTIDR_FIFOCONC;
-			for(;;);
-//      break;
-
-		case 1:
-			//Test mode Test_J:
-			//Upon command, a port's transceiver must enter the high-speed J state and remain in that
-			//state until the exit action is taken. This enables the testing of the high output drive
-			//level on the D+ line.
-			// Send a ZLP
-			USB_SendZlp();
-			UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTJ;
-			for(;;);
-//      break;
-
-		case 2:
-			//Test mode Test_K:
-			//Upon command, a port's transceiver must enter the high-speed K state and remain in
-			//that state until the exit action is taken. This enables the testing of the high output drive
-			//level on the D- line.
-			// Send a ZLP
-			USB_SendZlp();
-			UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTK;
-			for(;;);
-//		break;
-
-		case 3:
-			//Test mode Test_SE0_NAK:
-			//Upon command, a port's transceiver must enter the high-speed receive mode
-			//and remain in that mode until the exit action is taken. This enables the testing
-			//of output impedance, low level output voltage, and loading characteristics.
-			//In addition, while in this mode, upstream facing ports (and only upstream facing ports)
-			//must respond to any IN token packet with a NAK handshake (only if the packet CRC is
-			//determined to be correct) within the normal allowed device response time. This enables testing of
-			//the device squelch level circuitry and, additionally, provides a general purpose stimulus/response
-			//test for basic functional testing.
-
-			// Send a ZLP
-			USB_SendZlp();
-			UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SUSPEC
-							   | UOTGHS_DEVIDR_MSOFEC
-							   | UOTGHS_DEVIDR_SOFEC
-							   | UOTGHS_DEVIDR_EORSTEC
-							   | UOTGHS_DEVIDR_WAKEUPEC
-							   | UOTGHS_DEVIDR_EORSMEC
-							   | UOTGHS_DEVIDR_UPRSMEC
-							   | UOTGHS_DEVIDR_PEP_0
-							   | UOTGHS_DEVIDR_PEP_1
-							   | UOTGHS_DEVIDR_PEP_2
-							   | UOTGHS_DEVIDR_PEP_3
-							   | UOTGHS_DEVIDR_PEP_4
-							   | UOTGHS_DEVIDR_PEP_5
-							   | UOTGHS_DEVIDR_PEP_6
-							   | UOTGHS_DEVIDR_DMA_1
-							   | UOTGHS_DEVIDR_DMA_2
-							   | UOTGHS_DEVIDR_DMA_3
-							   | UOTGHS_DEVIDR_DMA_4
-							   | UOTGHS_DEVIDR_DMA_5
-							   | UOTGHS_DEVIDR_DMA_6;
-			for(;;);
-//		break;
-	}
-}
+//static void USB_SendZlp( void )
+//{
+//    //while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[0] & UOTGHS_DEVEPTISR_TXINI ) )
+//    while (!(USB->DEVICE.DeviceEndpoint[EP0].EPSTATUS.reg &  USB_DEVICE_EPSTATUSCLR_BK1RDY))
+//    {
+//        //if((UOTGHS->UOTGHS_DEVISR & UOTGHS_DEVISR_SUSP) == UOTGHS_DEVISR_SUSP)
+//        if((USB->DEVICE.INTFLAG.reg & USB_DEVICE_INTFLAG_SUSPEND) == USB_DEVICE_INTFLAG_SUSPEND)
+//        {
+//            return;
+//        }
+//    }
+//    //UOTGHS->UOTGHS_DEVEPTICR[0] = UOTGHS_DEVEPTICR_TXINIC;
+//    USB->DEVICE.DeviceEndpoint[EP0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY;
+//}
+//
 
 
 //unsigned int iii=0;
 //	Endpoint 0 interrupt
-static void USB_ISR(void)
+void USB_Handler(void)
 {
 //    printf("ISR=0x%X\n\r", UOTGHS->UOTGHS_DEVISR); // jcb
 //    if( iii++ > 1500 ) while(1); // jcb
@@ -601,12 +520,12 @@ static void USB_ISR(void)
 
 		// Reset USB address to 0
 		udd_configure_address(0);
-		udd_enable_address();
+		//udd_enable_address();
 
 		// Configure EP 0
         UDD_InitEP(0, EP_TYPE_CONTROL);
 		udd_enable_setup_received_interrupt(0);
-		udd_enable_endpoint_interrupt(0);
+	//	udd_enable_endpoint_interrupt(0);
 
         _usbConfiguration = 0;
 		udd_ack_reset();
@@ -645,7 +564,7 @@ static void USB_ISR(void)
 		if (requestType & REQUEST_DEVICETOHOST)
 		{
 			TRACE_CORE(puts(">>> EP0 Int: IN Request\r\n");)
-			UDD_WaitIN();
+//JCB			UDD_WaitIN();
 		}
 		else
 		{
@@ -719,26 +638,26 @@ static void USB_ISR(void)
                     //USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest));
 	    			UDD_Send8(EP0, 0);
                 }
-                if( setup.wValueL == 2) // TEST_MODE
-                {
-                    // 7.1.20 Test Mode Support, 9.4.9 SetFeature
-                    if( (setup.bmRequestType == 0 /*USBGenericRequest_DEVICE*/) &&
-                        ((setup.wIndex & 0x000F) == 0) )
-                    {
-                        // the lower byte of wIndex must be zero
-                        // the most significant byte of wIndex is used to specify the specific test mode
-
-                        UOTGHS->UOTGHS_DEVIDR &= ~UOTGHS_DEVIDR_SUSPEC;
-                        UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_SPDCONF_HIGH_SPEED; // remove suspend ?
-
-                        Test_Mode_Support( (setup.wIndex & 0xFF00)>>8 );
-                    }
-                }
+//                if( setup.wValueL == 2) // TEST_MODE
+//                {
+//                    // 7.1.20 Test Mode Support, 9.4.9 SetFeature
+//                    if( (setup.bmRequestType == 0 /*USBGenericRequest_DEVICE*/) &&
+//                        ((setup.wIndex & 0x000F) == 0) )
+//                    {
+//                        // the lower byte of wIndex must be zero
+//                        // the most significant byte of wIndex is used to specify the specific test mode
+//
+//                        UOTGHS->UOTGHS_DEVIDR &= ~UOTGHS_DEVIDR_SUSPEC;
+//                        UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_SPDCONF_HIGH_SPEED; // remove suspend ?
+//
+//                        Test_Mode_Support( (setup.wIndex & 0xFF00)>>8 );
+//                    }
+//                }
 			}
 			else if (SET_ADDRESS == r)
 			{
 				TRACE_CORE(puts(">>> EP0 Int: SET_ADDRESS\r\n");)
-				UDD_WaitIN();
+//JCB				UDD_WaitIN();
 				UDD_SetAddress(setup.wValueL);
 			}
 			else if (GET_DESCRIPTOR == r)
@@ -768,7 +687,7 @@ static void USB_ISR(void)
 #ifdef CDC_ENABLED
 					// Enable interrupt for CDC reception from host (OUT packet)
 					udd_enable_out_received_interrupt(CDC_RX);
-					udd_enable_endpoint_interrupt(CDC_RX);
+			//		udd_enable_endpoint_interrupt(CDC_RX);
 #endif
 				}
 				else
@@ -792,7 +711,7 @@ static void USB_ISR(void)
 		{
 			TRACE_CORE(puts(">>> EP0 Int: ClassInterfaceRequest\r\n");)
 
-			UDD_WaitIN(); // Workaround: need tempo here, else CDC serial won't open correctly
+//JCB			UDD_WaitIN(); // Workaround: need tempo here, else CDC serial won't open correctly
 
 			USBD_InitControl(setup.wLength); // Max length of transfer
 			ok = USBD_ClassInterfaceRequest(setup);
@@ -806,7 +725,7 @@ static void USB_ISR(void)
 		else
 		{
 			TRACE_CORE(puts(">>> EP0 Int: Stall\r\n");)
-			UDD_Stall();
+			UDD_Stall(0);
 		}
 	}
 }
@@ -823,7 +742,7 @@ uint32_t USBD_Connected(void)
 {
 	uint8_t f = UDD_GetFrameNumber();
 
-	delay(3);
+//delay(3); //JCB
 
 	return f != UDD_GetFrameNumber();
 }
@@ -836,12 +755,14 @@ USBDevice_ USBDevice;
 
 USBDevice_::USBDevice_()
 {
-	UDD_SetStack(&USB_ISR);
-
-	if (UDD_Init() == 0UL)
-	{
-		_usbInitialized=1UL;
-	}
+	//UDD_SetStack(&USB_ISR);
+
+//	if (UDD_Init() == 0UL)
+//	{
+//		_usbInitialized=1UL;
+//	}
+	UDD_Init();
+	_usbInitialized=1UL;
 }
 
 bool USBDevice_::attach(void)
@@ -858,7 +779,7 @@ bool USBDevice_::attach(void)
   }
 }
 
-bool USBDevice_::detach(void)
+bool USBDevice_::detach()
 {
 	if (_usbInitialized != 0UL)
 	{
diff --git a/cores/arduino/USB/USBCore.h b/cores/arduino/USB/USBCore.h
index b01d7576..8d1bfd52 100644
--- a/cores/arduino/USB/USBCore.h
+++ b/cores/arduino/USB/USBCore.h
@@ -287,8 +287,8 @@ _Pragma("pack()")
 #define D_CONFIG(_totalLength,_interfaces) \
 	{ 9, 2, _totalLength,_interfaces, 1, 0, USB_CONFIG_SELF_POWERED, USB_CONFIG_POWER_MA(500) }
 
-#define D_OTHERCONFIG(_totalLength,_interfaces) \
-	{ 9, 7, _totalLength,_interfaces, 1, 0, USB_CONFIG_SELF_POWERED, USB_CONFIG_POWER_MA(500) }
+//#define D_OTHERCONFIG(_totalLength,_interfaces) 
+//	{ 9, 7, _totalLength,_interfaces, 1, 0, USB_CONFIG_SELF_POWERED, USB_CONFIG_POWER_MA(500) }
 
 #define D_INTERFACE(_n,_numEndpoints,_class,_subClass,_protocol) \
 	{ 9, 4, _n, 0, _numEndpoints, _class,_subClass, _protocol, 0 }
@@ -296,8 +296,8 @@ _Pragma("pack()")
 #define D_ENDPOINT(_addr,_attr,_packetSize, _interval) \
 	{ 7, 5, _addr,_attr,_packetSize, _interval }
 
-#define D_QUALIFIER(_class,_subClass,_proto,_packetSize0,_configs) \
-	{ 10, 6, 0x200, _class,_subClass,_proto,_packetSize0,_configs }
+//#define D_QUALIFIER(_class,_subClass,_proto,_packetSize0,_configs) 
+//	{ 10, 6, 0x200, _class,_subClass,_proto,_packetSize0,_configs }
 
 #define D_IAD(_firstInterface, _count, _class, _subClass, _protocol) \
 	{ 8, 11, _firstInterface, _count, _class, _subClass, _protocol, 0 }
diff --git a/cores/arduino/USB/USBDesc.h b/cores/arduino/USB/USBDesc.h
index 878095e2..49b85115 100644
--- a/cores/arduino/USB/USBDesc.h
+++ b/cores/arduino/USB/USBDesc.h
@@ -18,7 +18,7 @@
 #define __USBDESC_H__
 
 #define CDC_ENABLED
-#define HID_ENABLED
+//#define HID_ENABLED
 
 #ifdef CDC_ENABLED
 #define CDC_INTERFACE_COUNT	2
diff --git a/cores/arduino/USB/USB_device.h b/cores/arduino/USB/USB_device.h
new file mode 100644
index 00000000..db909352
--- /dev/null
+++ b/cores/arduino/USB/USB_device.h
@@ -0,0 +1,412 @@
+/* ----------------------------------------------------------------------------
+ *         SAM Software Package License
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2011-2012, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition is met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef USB_DEVICE_H_INCLUDED
+#define USB_DEVICE_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "samd21_device.h"
+
+extern void UDD_WaitIN(void);
+//extern void UDD_WaitOUT(void);
+extern void UDD_ClearIN(void);
+extern void UDD_ClearOUT(void);
+extern uint32_t UDD_WaitForINOrOUT(void);
+extern void UDD_ClearRxFlag(unsigned char bEndpoint);
+extern uint32_t UDD_ReceivedSetupInt(void);
+extern void UDD_ClearSetupInt(void);
+//extern uint32_t UDD_ReadWriteAllowed(uint32_t ep);
+extern uint32_t UDD_FifoByteCount(uint32_t ep);
+extern uint8_t UDD_FifoFree(void);
+extern void UDD_ReleaseRX(uint32_t ep);
+extern void UDD_ReleaseTX(uint32_t ep);
+extern uint8_t UDD_FrameNumber(void);
+extern uint8_t UDD_GetConfiguration(void);
+
+extern uint32_t UDD_Send(uint32_t ep, const void* data, uint32_t len);
+extern void UDD_Send8(uint32_t ep,  uint8_t data );
+extern uint8_t UDD_Recv8(uint32_t ep);
+extern void UDD_Recv(uint32_t ep, uint8_t* data, uint32_t len);
+
+extern void UDD_InitEndpoints(const uint8_t* eps_table, const uint8_t ul_eps_table_size);
+extern void UDD_InitControl(int end);
+extern uint32_t UDD_Init(void);
+extern void UDD_InitEP( uint32_t ul_ep, uint32_t ul_ep_cfg );
+
+extern void UDD_Attach(void);
+extern void UDD_Detach(void);
+
+//extern void UDD_SetStack(void (*pf_isr)(void));
+extern void UDD_SetAddress(uint32_t addr);
+extern void UDD_Stall(uint32_t ep);
+extern uint32_t UDD_GetFrameNumber(void);
+
+/*! \name Usual Types
+ */
+
+//! @{
+
+typedef unsigned char           Bool; //!< Boolean.
+#ifndef __cplusplus
+#if !defined(__bool_true_false_are_defined)
+typedef unsigned char           bool; //!< Boolean.
+#endif
+#endif
+typedef int8_t                  S8;  //!< 8-bit signed integer.
+typedef uint8_t                 U8;  //!< 8-bit unsigned integer.
+typedef int16_t                 S16;  //!< 16-bit signed integer.
+typedef uint16_t                U16;  //!< 16-bit unsigned integer.
+typedef uint16_t                le16_t;
+typedef uint16_t                be16_t;
+typedef int32_t                 S32;  //!< 32-bit signed integer.
+typedef uint32_t                U32;  //!< 32-bit unsigned integer.
+typedef uint32_t                le32_t;
+typedef uint32_t                be32_t;
+typedef int64_t                 S64;  //!< 64-bit signed integer.
+typedef uint64_t                U64;  //!< 64-bit unsigned integer.
+typedef float                   F32;  //!< 32-bit floating-point number.
+typedef double                  F64;  //!< 64-bit floating-point number.
+typedef uint32_t                iram_size_t;
+
+//! @}
+
+/*! \name Bit-Field Handling
+ */
+//! @{
+
+/*! \brief Reads the bits of a value specified by a given bit-mask.
+ *
+ * \param value Value to read bits from.
+ * \param mask  Bit-mask indicating bits to read.
+ *
+ * \return Read bits.
+ */
+#define Rd_bits( value, mask)        ((value) & (mask))
+
+/*! \brief Writes the bits of a C lvalue specified by a given bit-mask.
+ *
+ * \param lvalue  C lvalue to write bits to.
+ * \param mask    Bit-mask indicating bits to write.
+ * \param bits    Bits to write.
+ *
+ * \return Resulting value with written bits.
+ */
+#define Wr_bits(lvalue, mask, bits)  ((lvalue) = ((lvalue) & ~(mask)) |\
+                                                 ((bits  ) &  (mask)))
+
+/*! \brief Tests the bits of a value specified by a given bit-mask.
+ *
+ * \param value Value of which to test bits.
+ * \param mask  Bit-mask indicating bits to test.
+ *
+ * \return \c 1 if at least one of the tested bits is set, else \c 0.
+ */
+#define Tst_bits( value, mask)  (Rd_bits(value, mask) != 0)
+
+/*! \brief Clears the bits of a C lvalue specified by a given bit-mask.
+ *
+ * \param lvalue  C lvalue of which to clear bits.
+ * \param mask    Bit-mask indicating bits to clear.
+ *
+ * \return Resulting value with cleared bits.
+ */
+#define Clr_bits(lvalue, mask)  ((lvalue) &= ~(mask))
+
+/*! \brief Sets the bits of a C lvalue specified by a given bit-mask.
+ *
+ * \param lvalue  C lvalue of which to set bits.
+ * \param mask    Bit-mask indicating bits to set.
+ *
+ * \return Resulting value with set bits.
+ */
+#define Set_bits(lvalue, mask)  ((lvalue) |=  (mask))
+
+/*! \brief Toggles the bits of a C lvalue specified by a given bit-mask.
+ *
+ * \param lvalue  C lvalue of which to toggle bits.
+ * \param mask    Bit-mask indicating bits to toggle.
+ *
+ * \return Resulting value with toggled bits.
+ */
+#define Tgl_bits(lvalue, mask)  ((lvalue) ^=  (mask))
+
+/*! \brief Reads the bit-field of a value specified by a given bit-mask.
+ *
+ * \param value Value to read a bit-field from.
+ * \param mask  Bit-mask indicating the bit-field to read.
+ *
+ * \return Read bit-field.
+ */
+#define Rd_bitfield( value, mask)           (Rd_bits( value, mask) >> ctz(mask))
+
+/*! \brief Writes the bit-field of a C lvalue specified by a given bit-mask.
+ *
+ * \param lvalue    C lvalue to write a bit-field to.
+ * \param mask      Bit-mask indicating the bit-field to write.
+ * \param bitfield  Bit-field to write.
+ *
+ * \return Resulting value with written bit-field.
+ */
+#define Wr_bitfield(lvalue, mask, bitfield) (Wr_bits(lvalue, mask, (U32)(bitfield) << ctz(mask)))
+
+//! @}
+
+/*! \name Token Paste
+ *
+ * Paste N preprocessing tokens together, these tokens being allowed to be \#defined.
+ *
+ * May be used only within macros with the tokens passed as arguments if the tokens are \#defined.
+ *
+ * For example, writing TPASTE2(U, WIDTH) within a macro \#defined by
+ * UTYPE(WIDTH) and invoked as UTYPE(UL_WIDTH) with UL_WIDTH \#defined as 32 is
+ * equivalent to writing U32.
+ */
+
+//! @{
+
+#define TPASTE2( a, b)                            a##b
+#define TPASTE3( a, b, c)                         a##b##c
+#define TPASTE4( a, b, c, d)                      a##b##c##d
+#define TPASTE5( a, b, c, d, e)                   a##b##c##d##e
+#define TPASTE6( a, b, c, d, e, f)                a##b##c##d##e##f
+#define TPASTE7( a, b, c, d, e, f, g)             a##b##c##d##e##f##g
+#define TPASTE8( a, b, c, d, e, f, g, h)          a##b##c##d##e##f##g##h
+#define TPASTE9( a, b, c, d, e, f, g, h, i)       a##b##c##d##e##f##g##h##i
+#define TPASTE10(a, b, c, d, e, f, g, h, i, j)    a##b##c##d##e##f##g##h##i##j
+
+//! @}
+
+/*! \name Absolute Token Paste
+ *
+ * Paste N preprocessing tokens together, these tokens being allowed to be \#defined.
+ *
+ * No restriction of use if the tokens are \#defined.
+ *
+ * For example, writing ATPASTE2(U, UL_WIDTH) anywhere with UL_WIDTH \#defined
+ * as 32 is equivalent to writing U32.
+ */
+
+//! @{
+
+#define ATPASTE2( a, b)                           TPASTE2( a, b)
+#define ATPASTE3( a, b, c)                        TPASTE3( a, b, c)
+#define ATPASTE4( a, b, c, d)                     TPASTE4( a, b, c, d)
+#define ATPASTE5( a, b, c, d, e)                  TPASTE5( a, b, c, d, e)
+#define ATPASTE6( a, b, c, d, e, f)               TPASTE6( a, b, c, d, e, f)
+#define ATPASTE7( a, b, c, d, e, f, g)            TPASTE7( a, b, c, d, e, f, g)
+#define ATPASTE8( a, b, c, d, e, f, g, h)         TPASTE8( a, b, c, d, e, f, g, h)
+#define ATPASTE9( a, b, c, d, e, f, g, h, i)      TPASTE9( a, b, c, d, e, f, g, h, i)
+#define ATPASTE10(a, b, c, d, e, f, g, h, i, j)   TPASTE10(a, b, c, d, e, f, g, h, i, j)
+
+//! @}
+
+/*! \brief Counts the trailing zero bits of the given value considered as a 32-bit integer.
+ *
+ * \param u Value of which to count the trailing zero bits.
+ *
+ * \return The count of trailing zero bits in \a u.
+ */
+#if (defined __GNUC__) || (defined __CC_ARM)
+#   define ctz(u)              __builtin_ctz(u)
+#else
+#   define ctz(u)              ((u) & (1ul <<  0) ?  0 : \
+                                (u) & (1ul <<  1) ?  1 : \
+                                (u) & (1ul <<  2) ?  2 : \
+                                (u) & (1ul <<  3) ?  3 : \
+                                (u) & (1ul <<  4) ?  4 : \
+                                (u) & (1ul <<  5) ?  5 : \
+                                (u) & (1ul <<  6) ?  6 : \
+                                (u) & (1ul <<  7) ?  7 : \
+                                (u) & (1ul <<  8) ?  8 : \
+                                (u) & (1ul <<  9) ?  9 : \
+                                (u) & (1ul << 10) ? 10 : \
+                                (u) & (1ul << 11) ? 11 : \
+                                (u) & (1ul << 12) ? 12 : \
+                                (u) & (1ul << 13) ? 13 : \
+                                (u) & (1ul << 14) ? 14 : \
+                                (u) & (1ul << 15) ? 15 : \
+                                (u) & (1ul << 16) ? 16 : \
+                                (u) & (1ul << 17) ? 17 : \
+                                (u) & (1ul << 18) ? 18 : \
+                                (u) & (1ul << 19) ? 19 : \
+                                (u) & (1ul << 20) ? 20 : \
+                                (u) & (1ul << 21) ? 21 : \
+                                (u) & (1ul << 22) ? 22 : \
+                                (u) & (1ul << 23) ? 23 : \
+                                (u) & (1ul << 24) ? 24 : \
+                                (u) & (1ul << 25) ? 25 : \
+                                (u) & (1ul << 26) ? 26 : \
+                                (u) & (1ul << 27) ? 27 : \
+                                (u) & (1ul << 28) ? 28 : \
+                                (u) & (1ul << 29) ? 29 : \
+                                (u) & (1ul << 30) ? 30 : \
+                                (u) & (1ul << 31) ? 31 : \
+                                32)
+#endif
+
+/*! \name Zero-Bit Counting
+ *
+ * Under GCC, __builtin_clz and __builtin_ctz behave like macros when
+ * applied to constant expressions (values known at compile time), so they are
+ * more optimized than the use of the corresponding assembly instructions and
+ * they can be used as constant expressions e.g. to initialize objects having
+ * static storage duration, and like the corresponding assembly instructions
+ * when applied to non-constant expressions (values unknown at compile time), so
+ * they are more optimized than an assembly periphrasis. Hence, clz and ctz
+ * ensure a possible and optimized behavior for both constant and non-constant
+ * expressions.
+ */
+//! @{
+
+/*! \brief Counts the leading zero bits of the given value considered as a 32-bit integer.
+ *
+ * \param u Value of which to count the leading zero bits.
+ *
+ * \return The count of leading zero bits in \a u.
+ */
+#if (defined __GNUC__) || (defined __CC_ARM)
+#   define clz(u)              __builtin_clz(u)
+#elif (defined __ICCARM__)
+#   define clz(u)              __CLZ(u)
+#else
+#   define clz(u)              (((u) == 0)          ? 32 : \
+                                ((u) & (1ul << 31)) ?  0 : \
+                                ((u) & (1ul << 30)) ?  1 : \
+                                ((u) & (1ul << 29)) ?  2 : \
+                                ((u) & (1ul << 28)) ?  3 : \
+                                ((u) & (1ul << 27)) ?  4 : \
+                                ((u) & (1ul << 26)) ?  5 : \
+                                ((u) & (1ul << 25)) ?  6 : \
+                                ((u) & (1ul << 24)) ?  7 : \
+                                ((u) & (1ul << 23)) ?  8 : \
+                                ((u) & (1ul << 22)) ?  9 : \
+                                ((u) & (1ul << 21)) ? 10 : \
+                                ((u) & (1ul << 20)) ? 11 : \
+                                ((u) & (1ul << 19)) ? 12 : \
+                                ((u) & (1ul << 18)) ? 13 : \
+                                ((u) & (1ul << 17)) ? 14 : \
+                                ((u) & (1ul << 16)) ? 15 : \
+                                ((u) & (1ul << 15)) ? 16 : \
+                                ((u) & (1ul << 14)) ? 17 : \
+                                ((u) & (1ul << 13)) ? 18 : \
+                                ((u) & (1ul << 12)) ? 19 : \
+                                ((u) & (1ul << 11)) ? 20 : \
+                                ((u) & (1ul << 10)) ? 21 : \
+                                ((u) & (1ul <<  9)) ? 22 : \
+                                ((u) & (1ul <<  8)) ? 23 : \
+                                ((u) & (1ul <<  7)) ? 24 : \
+                                ((u) & (1ul <<  6)) ? 25 : \
+                                ((u) & (1ul <<  5)) ? 26 : \
+                                ((u) & (1ul <<  4)) ? 27 : \
+                                ((u) & (1ul <<  3)) ? 28 : \
+                                ((u) & (1ul <<  2)) ? 29 : \
+                                ((u) & (1ul <<  1)) ? 30 : \
+                                31)
+#endif
+
+/*! \name Mathematics
+ *
+ * The same considerations as for clz and ctz apply here but GCC does not
+ * provide built-in functions to access the assembly instructions abs, min and
+ * max and it does not produce them by itself in most cases, so two sets of
+ * macros are defined here:
+ *   - Abs, Min and Max to apply to constant expressions (values known at
+ *     compile time);
+ *   - abs, min and max to apply to non-constant expressions (values unknown at
+ *     compile time), abs is found in stdlib.h.
+ */
+//! @{
+
+///*! \brief Takes the absolute value of \a a.
+// *
+// * \param a Input value.
+// *
+// * \return Absolute value of \a a.
+// *
+// * \note More optimized if only used with values known at compile time.
+// */
+//#define Abs(a)              (((a) <  0 ) ? -(a) : (a))
+//
+///*! \brief Takes the minimal value of \a a and \a b.
+// *
+// * \param a Input value.
+// * \param b Input value.
+// *
+// * \return Minimal value of \a a and \a b.
+// *
+// * \note More optimized if only used with values known at compile time.
+// */
+//#define Min(a, b)           (((a) < (b)) ?  (a) : (b))
+//
+///*! \brief Takes the maximal value of \a a and \a b.
+// *
+// * \param a Input value.
+// * \param b Input value.
+// *
+// * \return Maximal value of \a a and \a b.
+// *
+// * \note More optimized if only used with values known at compile time.
+// */
+//#define Max(a, b)           (((a) > (b)) ?  (a) : (b))
+//
+//// abs() is already defined by stdlib.h
+//
+///*! \brief Takes the minimal value of \a a and \a b.
+// *
+// * \param a Input value.
+// * \param b Input value.
+// *
+// * \return Minimal value of \a a and \a b.
+// *
+// * \note More optimized if only used with values unknown at compile time.
+// */
+//#define min(a, b)   Min(a, b)
+//
+///*! \brief Takes the maximal value of \a a and \a b.
+// *
+// * \param a Input value.
+// * \param b Input value.
+// *
+// * \return Maximal value of \a a and \a b.
+// *
+// * \note More optimized if only used with values unknown at compile time.
+// */
+//#define max(a, b)   Max(a, b)
+//
+////! @}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USB_DEVICE_H_INCLUDED */
diff --git a/cores/arduino/USB/USB_host.h b/cores/arduino/USB/USB_host.h
new file mode 100644
index 00000000..73221c46
--- /dev/null
+++ b/cores/arduino/USB/USB_host.h
@@ -0,0 +1,78 @@
+/* ----------------------------------------------------------------------------
+ *         SAM Software Package License
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2011-2012, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition is met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef USB_HOST_H_INCLUDED
+#define USB_HOST_H_INCLUDED
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define tokSETUP		UOTGHS_HSTPIPCFG_PTOKEN_SETUP
+#define tokIN			UOTGHS_HSTPIPCFG_PTOKEN_IN
+#define tokOUT			UOTGHS_HSTPIPCFG_PTOKEN_OUT
+#define tokINHS			UOTGHS_HSTPIPCFG_PTOKEN_IN
+#define tokOUTHS		UOTGHS_HSTPIPCFG_PTOKEN_OUT
+
+//! \brief Device speed
+/*typedef enum {
+	UHD_SPEED_LOW  = 0,
+	UHD_SPEED_FULL = 1,
+	UHD_SPEED_HIGH = 2,
+} uhd_speed_t;*/
+
+//! States of USBB interface
+typedef enum {
+	UHD_STATE_NO_VBUS = 0,
+	UHD_STATE_DISCONNECTED = 1,
+	UHD_STATE_CONNECTED = 2,
+	UHD_STATE_ERROR = 3,
+} uhd_vbus_state_t;
+
+//extern uhd_speed_t uhd_get_speed(void);
+
+extern void UHD_SetStack(void (*pf_isr)(void));
+extern void UHD_Init(void);
+extern void UHD_BusReset(void);
+extern uhd_vbus_state_t UHD_GetVBUSState(void);
+extern uint32_t UHD_Pipe0_Alloc(uint32_t ul_add, uint32_t ul_ep_size);
+extern uint32_t UHD_Pipe_Alloc(uint32_t ul_dev_addr, uint32_t ul_dev_ep, uint32_t ul_type, uint32_t ul_dir, uint32_t ul_maxsize, uint32_t ul_interval, uint32_t ul_nb_bank);
+extern void UHD_Pipe_Free(uint32_t ul_pipe);
+extern uint32_t UHD_Pipe_Read(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data);
+extern void UHD_Pipe_Write(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data);
+extern void UHD_Pipe_Send(uint32_t ul_pipe, uint32_t ul_token_type);
+extern uint32_t UHD_Pipe_Is_Transfer_Complete(uint32_t ul_pipe, uint32_t ul_token_type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* USB_HOST_H_INCLUDED */
diff --git a/cores/arduino/USB/samd21_device.c b/cores/arduino/USB/samd21_device.c
new file mode 100644
index 00000000..65fb503f
--- /dev/null
+++ b/cores/arduino/USB/samd21_device.c
@@ -0,0 +1,713 @@
+/* ----------------------------------------------------------------------------
+ *         SAM Software Package License
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2011-2012, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition is met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+
+#include "variant.h"
+#include "USB_device.h"
+#include "samd21_device.h"
+#include "sam.h"
+
+#ifdef __cplusplus
+extern "C"{
+#endif // __cplusplus
+
+#ifdef SAMD_SERIES
+extern uint8_t usb_device_endpoint_is_configured(uint8_t ep);
+
+#define TRACE_DEVICE(x)	x
+//#define TRACE_DEVICE(x)
+
+// Endpoint transfer direction is IN
+#define  USB_EP_DIR_IN        0x80
+// Endpoint transfer direction is OUT
+#define  USB_EP_DIR_OUT       0x00
+
+extern void (*gpf_isr)(void);
+
+static volatile uint32_t ul_send_fifo_ptr[USB_EPT_NUM];
+static volatile uint32_t ul_recv_fifo_ptr[USB_EPT_NUM];
+
+/**
+ * USB SRAM data containing pipe descriptor table
+ * The content of the USB SRAM can be :
+ * - modified by USB hardware interface to update pipe status.
+ *   Thereby, it is read by software.
+ * - modified by USB software to control pipe.
+ *   Thereby, it is read by hardware.
+ * This data section is volatile.
+ */
+
+#if (defined __GNUC__) || defined(__CC_ARM)
+#define COMPILER_WORD_ALIGNED         __attribute__((__aligned__(4)))
+#elif (defined __ICCARM__)
+#define COMPILER_WORD_ALIGNED         _Pragma("data_alignment = 4")
+#endif
+
+#ifdef __ICCARM__
+_Pragma("pack(4)")
+#else
+COMPILER_WORD_ALIGNED
+#endif
+union {
+	UsbDeviceDescriptor usb_endpoint_table[USB_EPT_NUM];
+	UsbHostDescriptor usb_pipe_table[USB_PIPE_NUM];
+} usb_descriptor_table; 
+_Pragma("pack()")
+
+
+//void (*gpf_isr)(void) = (0UL);
+//
+//void UOTGHS_Handler( void )
+//{
+//	if (gpf_isr)
+//		gpf_isr();
+//} 
+//void UDD_SetStack(void (*pf_isr)(void))
+//{
+//	gpf_isr = pf_isr;
+//}
+
+// NVM Software Calibration Area Mapping
+// USB TRANSN calibration value. Should be written to the USB PADCAL register.
+#define NVM_USB_PAD_TRANSN_POS  45
+#define NVM_USB_PAD_TRANSN_SIZE 5
+// USB TRANSP calibration value. Should be written to the USB PADCAL register.
+#define NVM_USB_PAD_TRANSP_POS  50
+#define NVM_USB_PAD_TRANSP_SIZE 5
+// USB TRIM calibration value. Should be written to the USB PADCAL register.
+#define NVM_USB_PAD_TRIM_POS  55
+#define NVM_USB_PAD_TRIM_SIZE 3
+
+uint32_t UDD_Init(void)
+{
+	uint32_t i;
+	uint32_t pad_transn;
+    uint32_t  pad_transp;
+    uint32_t  pad_trim;
+//	struct system_pinmux_config pin_config;
+//	struct system_gclk_chan_config gclk_chan_config;
+//
+//	/* Turn on the digital interface clock */
+//	system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBB, PM_APBBMASK_USB);
+//
+//	/* Set up the USB DP/DN pins */
+//	system_pinmux_get_config_defaults(&pin_config);
+//	pin_config.mux_position = MUX_PA24G_USB_DM;
+//	system_pinmux_pin_set_config(PIN_PA24G_USB_DM, &pin_config);
+//	pin_config.mux_position = MUX_PA25G_USB_DP;
+//	system_pinmux_pin_set_config(PIN_PA25G_USB_DP, &pin_config);
+//
+//	/* Setup clock for module */
+//	system_gclk_chan_get_config_defaults(&gclk_chan_config);
+//	gclk_chan_config.source_generator = module_config->source_generator;
+//	system_gclk_chan_set_config(USB_GCLK_ID, &gclk_chan_config);
+//	system_gclk_chan_enable(USB_GCLK_ID);
+//	pin_config.mux_position = MUX_PB14H_GCLK_IO0;
+//	pin_config.direction    = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
+//	system_pinmux_pin_set_config(PIN_PB14H_GCLK_IO0, &pin_config);
+
+	/* Reset */
+	USB->DEVICE.CTRLA.bit.SWRST = 1;
+	while (USB->DEVICE.SYNCBUSY.bit.SWRST) {
+		/* Sync wait */
+	}
+
+	/* Load Pad Calibration */
+	pad_transn =( *((uint32_t *)(NVMCTRL_OTP4)  // Non-Volatile Memory Controller
+			+ (NVM_USB_PAD_TRANSN_POS / 32))
+		>> (NVM_USB_PAD_TRANSN_POS % 32))
+		& ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1);
+
+	if (pad_transn == 0x1F) {  // maximum value (31)
+		pad_transn = 5;
+	}
+
+	USB->DEVICE.PADCAL.bit.TRANSN = pad_transn;
+
+	pad_transp =( *((uint32_t *)(NVMCTRL_OTP4)
+			+ (NVM_USB_PAD_TRANSP_POS / 32))
+			>> (NVM_USB_PAD_TRANSP_POS % 32))
+			& ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1);
+
+	if (pad_transp == 0x1F) {  // maximum value (31)
+		pad_transp = 29;
+	}
+
+	USB->DEVICE.PADCAL.bit.TRANSP = pad_transp;
+
+	pad_trim =( *((uint32_t *)(NVMCTRL_OTP4)
+			+ (NVM_USB_PAD_TRIM_POS / 32))
+			>> (NVM_USB_PAD_TRIM_POS % 32))
+			& ((1 << NVM_USB_PAD_TRIM_SIZE) - 1);
+
+	if (pad_trim == 0x7) {  // maximum value (7)
+		pad_trim = 3;
+	}
+
+	USB->DEVICE.PADCAL.bit.TRIM = pad_trim;
+
+	/* Set the configuration */
+	udd_force_device_mode();
+	udd_device_run_in_standby();
+    // Set address of USB SRAM
+	USB->DEVICE.DESCADD.reg = (uint32_t)(&usb_descriptor_table.usb_endpoint_table[0]);
+	// For USB_SPEED_FULL 
+	udd_force_full_speed();
+	// For USB_LOW_FULL 
+	//udd_force_low_speed();
+
+    // Clear USB RAM
+//	memset((uint8_t *)(&usb_descriptor_table.usb_endpoint_table[0]), 0,
+//			sizeof(usb_descriptor_table.usb_endpoint_table));
+
+	for (i = 0; i < sizeof(usb_descriptor_table.usb_endpoint_table); i++) {
+		(*(uint32_t *)(&usb_descriptor_table.usb_endpoint_table[0]+i)) = 0;
+	}
+
+    
+//	/*  device callback related */
+//	for (i = 0; i < USB_DEVICE_CALLBACK_N; i++) {
+//		module_inst->device_callback[i] = NULL;
+//	}
+//	for (i = 0; i < USB_EPT_NUM; i++) {
+//		for(j = 0; j < USB_DEVICE_EP_CALLBACK_N; j++) {
+//			module_inst->device_endpoint_callback[i][j] = NULL;
+//		}
+//	}
+//	module_inst->device_registered_callback_mask = 0;
+//	module_inst->device_enabled_callback_mask = 0;
+//	for (j = 0; j < USB_EPT_NUM; j++) {
+//		module_inst->device_endpoint_registered_callback_mask[j] = 0;
+//		module_inst->device_endpoint_enabled_callback_mask[j] = 0;
+//	}
+
+	/* Enable interrupts for this USB module */
+//	system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_USB);
+	// Configure interrupts
+	NVIC_SetPriority((IRQn_Type) USB_IRQn, 0UL);
+	NVIC_EnableIRQ((IRQn_Type) USB_IRQn);
+
+//    uint32_t i;
+//
+//	for (i = 0; i < USB_EPT_NUM; ++i)
+//	{
+//		ul_send_fifo_ptr[i] = 0;
+//		ul_recv_fifo_ptr[i] = 0;
+//	}
+//
+//	// Enables the USB Clock
+//	pmc_enable_periph_clk(ID_USB);
+//	pmc_enable_upll_clock();
+//	pmc_switch_udpck_to_upllck(0); // div=0+1
+//	pmc_enable_udpck();
+//
+//	// Configure interrupts
+//	NVIC_SetPriority((IRQn_Type) USB_IRQn, 0UL);
+//	NVIC_EnableIRQ((IRQn_Type) USB_IRQn);
+//
+//	// Always authorize asynchrone USB interrupts to exit from sleep mode
+//	//   for SAM3 USB wake up device except BACKUP mode
+//	//pmc_set_fast_startup_input(PMC_FSMR_USBAL);
+//
+//	// ID pin not used then force device mode
+////	otg_disable_id_pin();
+//	udd_force_device_mode();
+//
+//	// Enable USB hardware
+//
+//    // The Pad Calibration values must be loaded from the NVM Software Calibration Area into the USB Pad Calibration
+//    // register by software, before enabling the USB, to achieve the specified accuracy. Refer to “NVM Software Calibration
+//    // Area Mapping” on page 21 for further details.
+//    JCB TODO;
+//
+//    //	otg_disable_pad();
+////	otg_enable_pad();
+//	udd_enable();
+////	otg_unfreeze_clock();
+//
+//	// Check USB clock
+//	//while (!Is_otg_clock_usable())
+//	//	;
+//
+//	// Force full Speed
+//	udd_force_full_speed();
+//
+//	//otg_ack_vbus_transition();
+//	// Force Vbus interrupt in case of Vbus always with a high level
+//	// This is possible with a short timing between a Host mode stop/start.
+//	/*if (Is_otg_vbus_high()) {
+//		otg_raise_vbus_transition();
+//	}
+//	otg_enable_vbus_interrupt();*/
+////	otg_freeze_clock();
+//
+	return 0UL ;
+}
+
+void UDD_Attach(void)
+{
+//	irqflags_t flags = cpu_irq_save();
+
+	TRACE_DEVICE(printf("=> UDD_Attach\r\n");)
+
+    // Authorize attach if Vbus is present
+	udd_attach_device();
+
+	// Enable USB line events
+	udd_enable_reset_interrupt();
+
+    // usefull for debug
+    udd_enable_sof_interrupt();
+
+//	cpu_irq_restore(flags);
+}
+
+void UDD_Detach(void)
+{
+	TRACE_DEVICE(printf("=> UDD_Detach\r\n");)
+    udd_detach_device();
+}
+
+
+/**
+ * \brief Check if current endpoint is configured
+ *
+ * \param module_inst   Pointer to USB software instance struct
+ * \param ep            Endpoint address (direction & number)
+ *
+ * \return \c true if endpoint is configured and ready to use
+ */
+uint8_t usb_device_endpoint_is_configured(uint8_t ep)
+{
+	uint8_t ep_num = ep & 0xF;
+	uint8_t flag;
+
+	if (ep & USB_EP_DIR_IN) {
+		flag = USB->DEVICE.DeviceEndpoint[ep_num].EPCFG.bit.EPTYPE1;
+	} else {
+		flag = USB->DEVICE.DeviceEndpoint[ep_num].EPCFG.bit.EPTYPE0;
+	}
+	return( flag != 0 );  // JCB to be checked
+}
+
+
+
+
+//// CONTROL configuration:
+//enum status_code usb_device_endpoint_set_config(struct usb_module *module_inst,
+		//struct usb_device_endpoint_config *ep_config)
+void UDD_InitEP( uint32_t ul_ep_nb, uint32_t ul_ep_cfg )
+{
+	/* Sanity check arguments */
+//	Assert(module_inst);
+//	Assert(ep_config);
+
+	TRACE_DEVICE(printf("=> UDD_InitEP : init EP %lu\r\n", (unsigned long)ul_ep_nb);)
+
+    if ((USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE0_Msk) == 0 && \
+        (USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPCFG.reg & USB_DEVICE_EPCFG_EPTYPE1_Msk) == 0) {
+
+        USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPCFG.reg = USB_DEVICE_EPCFG_EPTYPE0(1) | USB_DEVICE_EPCFG_EPTYPE1(1);
+        USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY;
+        USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK1RDY;
+    } else {
+		TRACE_DEVICE(printf("=> UDD_InitEP : ERROR ALREADY INITIALIZED EP %lu\r\n", (unsigned long)ul_ep_nb);)
+		while(1);
+    }
+
+    usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[0].PCKSIZE.reg &= ~USB_DEVICE_PCKSIZE_AUTO_ZLP;
+    usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[1].PCKSIZE.reg &= ~USB_DEVICE_PCKSIZE_AUTO_ZLP;
+
+    usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[0].PCKSIZE.bit.SIZE = 0x3;  // for 64 bytes
+    usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[1].PCKSIZE.bit.SIZE = 0x3;  // for 64 bytes
+}
+
+
+
+
+void UDD_InitEndpoints(const uint8_t* eps_table, const uint8_t ul_eps_table_size)
+{
+	uint8_t ul_ep_nb;
+	uint8_t ep_bank;
+
+	for (ul_ep_nb = 1; ul_ep_nb < ul_eps_table_size; ul_ep_nb++)
+	{
+//		// Configure EP
+//		UOTGHS->UOTGHS_DEVEPTCFG[ul_ep_nb] = eps_table[ul_ep_nb];
+//		// Enable EP
+//		udd_enable_endpoint(ul_ep_nb);
+//
+//		if (!Is_udd_endpoint_configured(ul_ep_nb)) {
+//			TRACE_DEVICE(printf("=> UDD_InitEP : ERROR FAILED TO INIT EP %lu\r\n", ul_ep_nb);)
+//			while(1);
+//		}
+
+        TRACE_DEVICE(printf("=> UDD_InitEndpoints : init EP %lu\r\n", (unsigned long)ul_ep_nb);)
+
+        USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPCFG.reg = eps_table[ul_ep_nb]& 0xEF;
+        ep_bank = eps_table[ul_ep_nb] >> 7;
+        USB->DEVICE.DeviceEndpoint[ul_ep_nb].EPSTATUSCLR.reg = ep_bank;
+        // JCB only 1 bank ????
+
+        usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[ep_bank].PCKSIZE.bit.SIZE = 0x06; // for 512
+
+//        if (true == ep_config->auto_zlp) {
+            usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[ep_bank].PCKSIZE.reg |= USB_DEVICE_PCKSIZE_AUTO_ZLP;
+//        } else {
+//            usb_descriptor_table.usb_endpoint_table[ul_ep_nb].DeviceDescBank[ep_bank].PCKSIZE.reg &= ~USB_DEVICE_PCKSIZE_AUTO_ZLP;
+//        }
+    }
+}
+
+//// Wait until ready to accept IN packet.
+//void UDD_WaitIN(void)
+//{
+//	while (!(UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_TXINI))
+//		;
+//}
+//
+//void UDD_WaitOUT(void)
+//{
+//	while (!(UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_RXOUTI))
+//		;
+//}
+
+// Send packet.
+void UDD_ClearIN(void)
+{
+	TRACE_DEVICE(printf("=> UDD_ClearIN: sent %lu bytes\r\n", (unsigned long)ul_send_fifo_ptr[EP0]);)
+
+	//UOTGHS->UOTGHS_DEVEPTICR[EP0] = UOTGHS_DEVEPTICR_TXINIC;
+	USB->DEVICE.DeviceEndpoint[EP0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY;
+	ul_send_fifo_ptr[EP0] = 0;
+}
+
+void UDD_ClearOUT(void)
+{
+	//UOTGHS->UOTGHS_DEVEPTICR[EP0] = UOTGHS_DEVEPTICR_RXOUTIC;
+	USB->DEVICE.DeviceEndpoint[EP0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY;
+
+	ul_recv_fifo_ptr[EP0] = 0;
+}
+
+// Wait for IN FIFO to be ready to accept data or OUT FIFO to receive data.
+// Return true if new IN FIFO buffer available.
+uint32_t UDD_WaitForINOrOUT(void)
+{
+    while (!(USB->DEVICE.DeviceEndpoint[EP0].EPSTATUS.reg & (USB_DEVICE_EPSTATUSCLR_BK0RDY | USB_DEVICE_EPSTATUSCLR_BK1RDY)))
+      ;
+//	while (!(UOTGHS->UOTGHS_DEVEPTISR[EP0] & (UOTGHS_DEVEPTISR_TXINI | UOTGHS_DEVEPTISR_RXOUTI)))
+//		;
+//	return ((UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_RXOUTI) == 0);
+
+    return ((USB->DEVICE.DeviceEndpoint[EP0].EPSTATUS.reg & USB_DEVICE_EPSTATUSCLR_BK0RDY));
+}
+
+
+/**
+ * \brief Start setup packet read job on a endpoint
+ *
+ * \param module_inst Pointer to USB device module instance
+ * \param pbuf        Pointer to buffer
+ *
+ * \return Status of procedure
+ * \retval STATUS_OK Job started successfully
+ * \retval STATUS_ERR_DENIED Endpoint is not ready
+ */
+//enum status_code usb_device_endpoint_setup_buffer_job(struct usb_module *module_inst,
+//		uint8_t* pbuf)
+//{
+//	/* Sanity check arguments */
+//	Assert(module_inst);
+//	Assert(module_inst->hw);
+//
+//
+//	return STATUS_OK;
+//}
+uint8_t udd_ctrl_buffer[64];
+
+
+uint32_t UDD_ReceivedSetupInt(void)
+{
+	/* get endpoint configuration from setting register */
+	usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].ADDR.reg = (uint32_t)udd_ctrl_buffer;
+	usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 8;
+	usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0;
+	USB->DEVICE.DeviceEndpoint[0].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY;
+
+//	return UOTGHS->UOTGHS_DEVEPTISR[EP0] & UOTGHS_DEVEPTISR_RXSTPI;
+    return (USB->DEVICE.DeviceEndpoint[0].EPSTATUS.reg &  USB_DEVICE_EPSTATUSCLR_BK0RDY);
+}
+
+void UDD_ClearSetupInt(void)
+{
+	//UOTGHS->UOTGHS_DEVEPTICR[EP0] = (UOTGHS_DEVEPTICR_RXSTPIC);
+	USB->DEVICE.DeviceEndpoint[EP0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY;
+}
+
+uint32_t UDD_Send(uint32_t ep, const void* data, uint32_t len)
+{
+	const uint8_t *ptr_src = data;
+//	uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ep);
+	uint32_t i;
+
+	TRACE_DEVICE(printf("=> UDD_Send (1): ep=%lu ul_send_fifo_ptr=%lu len=%lu\r\n", (unsigned long)ep, (unsigned long)ul_send_fifo_ptr[ep], (unsigned long)len);)
+
+//	while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_TXINI )) {}
+    while (!(USB->DEVICE.DeviceEndpoint[ep].EPSTATUS.reg &  USB_DEVICE_EPSTATUSCLR_BK1RDY))
+      ;
+
+    usb_descriptor_table.usb_endpoint_table[0].DeviceDescBank[0].ADDR.reg = (uint32_t)&ul_send_fifo_ptr[ep];
+
+	if (ep == EP0)
+	{
+		if (ul_send_fifo_ptr[ep] + len > EP0_SIZE)
+			len = EP0_SIZE - ul_send_fifo_ptr[ep];
+	}
+	else
+	{
+		ul_send_fifo_ptr[ep] = 0;
+	}
+//	for (i = 0, ptr_dest += ul_send_fifo_ptr[ep]; i < len; ++i)
+//		*ptr_dest++ = *ptr_src++;
+
+	ul_send_fifo_ptr[ep] += len;//i;
+
+	if (ep == EP0)
+	{
+		TRACE_DEVICE(printf("=> UDD_Send (2): ep=%lu ptr_dest=%lu maxlen=%d\r\n", (unsigned long)ep, (unsigned long)ul_send_fifo_ptr[ep], EP0_SIZE);)
+		if (ul_send_fifo_ptr[ep] == EP0_SIZE)
+		{
+			UDD_ClearIN();	// Fifo is full, release this packet
+        }
+	}
+	else
+	{
+		//UOTGHS->UOTGHS_DEVEPTICR[ep] = UOTGHS_DEVEPTICR_TXINIC;
+        USB->DEVICE.DeviceEndpoint[EP0].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY;
+		//UOTGHS->UOTGHS_DEVEPTIDR[ep] = UOTGHS_DEVEPTIDR_FIFOCONC;
+	}
+	return len;
+}
+
+void UDD_Send8(uint32_t ep,  uint8_t data )
+{
+//	uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ep);
+//
+//	TRACE_DEVICE(printf("=> UDD_Send8 : ul_send_fifo_ptr=%lu data=0x%x\r\n", ul_send_fifo_ptr[ep], data);)
+//
+//	ptr_dest[ul_send_fifo_ptr[ep]] = data;
+//	ul_send_fifo_ptr[ep] += 1;
+
+	uint8_t flag;
+	flag = (uint8_t)(USB->DEVICE.DeviceEndpoint[ep].EPCFG.bit.EPTYPE1);
+	if (flag == 0) {   // Bank1 is disabled
+		return;
+	};
+
+	/* get endpoint configuration from setting register */
+	usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[1].ADDR.reg = (uint32_t)&data;
+	usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[1].PCKSIZE.bit.MULTI_PACKET_SIZE = 0;
+	usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT = 8;
+	USB->DEVICE.DeviceEndpoint[ep].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY;
+}
+
+uint8_t UDD_Recv8(uint32_t ep)
+{
+//	uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(ep);
+//	uint8_t data = ptr_dest[ul_recv_fifo_ptr[ep]];
+
+	TRACE_DEVICE(printf("=> UDD_Recv8 : ep=%d\r\n", (char)ep);)
+
+//	ul_recv_fifo_ptr[ep] += 1;
+//	return data;
+
+      
+    volatile uint8_t data;
+
+    usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[0].ADDR.reg = (uint32_t)&data;
+	usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 8;
+	usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0;
+	USB->DEVICE.DeviceEndpoint[ep].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY;
+
+	TRACE_DEVICE(printf("=> UDD_Recv8 : data=%lu\r\n", (unsigned long)data);)
+
+    return data;
+}
+
+void UDD_Recv(uint32_t ep, uint8_t* data, uint32_t len)
+{
+//	uint8_t *ptr_src = (uint8_t *) &udd_get_endpoint_fifo_access8(ep);
+//	uint8_t *ptr_dest = data;
+//	uint32_t i;
+//
+//	for (i = 0, ptr_src += ul_recv_fifo_ptr[ep]; i < len; ++i)
+//		*ptr_dest++ = *ptr_src++;
+//
+//	ul_recv_fifo_ptr[ep] += i;
+
+	TRACE_DEVICE(printf("=> UDD_Recv : data=%lu, len=%d\r\n", data[0], (char)len);)
+
+    usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[0].ADDR.reg = (uint32_t)data;
+	usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = len;
+	usb_descriptor_table.usb_endpoint_table[ep].DeviceDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0;
+	USB->DEVICE.DeviceEndpoint[ep].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY;
+}
+
+void UDD_Stall(uint32_t ep)
+{
+//	UOTGHS->UOTGHS_DEVEPT = (UOTGHS_DEVEPT_EPEN0 << EP0);
+//	UOTGHS->UOTGHS_DEVEPTIER[EP0] = UOTGHS_DEVEPTIER_STALLRQS;
+	uint8_t ep_num = ep & 0xF;
+
+	// Stall endpoint
+	if (ep & USB_EP_DIR_IN) {
+		USB->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1;
+	} else {
+		USB->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0;
+	}
+}
+//		if (ep & USB_EP_DIR_IN) {
+//			module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_STALL1;
+//		} else {
+//			module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENSET.reg = USB_DEVICE_EPINTENSET_STALL0;
+//		}
+//		if (ep & USB_EP_DIR_IN) {
+//			module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_STALL1;
+//		} else {
+//			module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTENCLR.reg = USB_DEVICE_EPINTENCLR_STALL0;
+//		}
+//	if (ep & USB_EP_DIR_IN) {
+//		return (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1);
+//	} else {
+//		return (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0);
+//	}
+//	// Stall endpoint
+//	if (ep & USB_EP_DIR_IN) {
+//		module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ1;
+//	} else {
+//		module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_STALLRQ0;
+//	}
+//
+//	if (ep & USB_EP_DIR_IN) {
+//		if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ1) {
+//			// Remove stall request
+//			module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ1;
+//			if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL1) {
+//				module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL1;
+//				// The Stall has occurred, then reset data toggle
+//				module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLIN;
+//			}
+//		}
+//	} else {
+//		if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUS.reg & USB_DEVICE_EPSTATUSSET_STALLRQ0) {
+//			// Remove stall request
+//			module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_STALLRQ0;
+//			if (module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL0) {
+//				module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL0;
+//				// The Stall has occurred, then reset data toggle
+//				module_inst->hw->DEVICE.DeviceEndpoint[ep_num].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSSET_DTGLOUT;
+//			}
+//		}
+//	}
+//				// endpoint transfer stall interrupt
+//				if (flags & USB_DEVICE_EPINTFLAG_STALL_Msk) {
+//					if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL1) {
+//						_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL1;
+//						ep_callback_para.endpoint_address = USB_EP_DIR_IN | i;
+//					} else if (_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg & USB_DEVICE_EPINTFLAG_STALL0) {
+//						_usb_instances->hw->DEVICE.DeviceEndpoint[i].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_STALL0;
+//						ep_callback_para.endpoint_address = USB_EP_DIR_OUT | i;
+//					}
+//
+//					if (flags_run & USB_DEVICE_EPINTFLAG_STALL_Msk) {
+//						(_usb_instances->device_endpoint_callback[i][USB_DEVICE_ENDPOINT_CALLBACK_STALL])(_usb_instances,&ep_callback_para);
+//					}
+//					return;
+//				}
+
+uint32_t UDD_FifoByteCount(uint32_t ep)
+{
+	uint8_t ep_num = ep & 0xF;
+
+	//return ((UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_BYCT_Msk) >> UOTGHS_DEVEPTISR_BYCT_Pos);
+	//return (USB->DEVICE.PCKSIZE.reg & USB_DEVICE_PCKSIZE_BYTE_COUNT_Msk);
+	return ((uint16_t)(usb_descriptor_table.usb_endpoint_table[ep_num].DeviceDescBank[1].PCKSIZE.bit.BYTE_COUNT));
+}
+
+void UDD_ReleaseRX(uint32_t ep)
+{
+	TRACE_DEVICE(puts("=> UDD_ReleaseRX\r\n");)
+//	UOTGHS->UOTGHS_DEVEPTICR[ep] = (UOTGHS_DEVEPTICR_NAKOUTIC | UOTGHS_DEVEPTICR_RXOUTIC);
+	//UOTGHS->UOTGHS_DEVEPTICR[ep] = UOTGHS_DEVEPTICR_RXOUTIC;
+	USB->DEVICE.DeviceEndpoint[ep].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY;
+    USB->DEVICE.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT0;
+    //UOTGHS->UOTGHS_DEVEPTIDR[ep] = UOTGHS_DEVEPTIDR_FIFOCONC;
+	ul_recv_fifo_ptr[ep] = 0;
+}
+
+void UDD_ReleaseTX(uint32_t ep)
+{
+	TRACE_DEVICE(printf("=> UDD_ReleaseTX ep=%lu\r\n", (unsigned long)ep);)
+//	UOTGHS->UOTGHS_DEVEPTICR[ep] = (UOTGHS_DEVEPTICR_NAKINIC | UOTGHS_DEVEPTICR_RXOUTIC | UOTGHS_DEVEPTICR_TXINIC);
+	//UOTGHS->UOTGHS_DEVEPTICR[ep] = UOTGHS_DEVEPTICR_TXINIC;
+    USB->DEVICE.DeviceEndpoint[ep].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK1RDY;
+    USB->DEVICE.DeviceEndpoint[ep].EPINTFLAG.reg = USB_DEVICE_EPINTFLAG_TRCPT1;
+	//UOTGHS->UOTGHS_DEVEPTIDR[ep] = UOTGHS_DEVEPTIDR_FIFOCONC;
+	ul_send_fifo_ptr[ep] = 0;
+}
+
+// Return true if the current bank is not full.
+//uint32_t UDD_ReadWriteAllowed(uint32_t ep)
+//{
+//	//return (UOTGHS->UOTGHS_DEVEPTISR[ep] & UOTGHS_DEVEPTISR_RWALL);
+//    return 1;
+//}
+
+void UDD_SetAddress(uint32_t addr)
+{
+	TRACE_DEVICE(printf("=> UDD_SetAddress : setting address to %lu\r\n", (unsigned long)addr);)
+
+	udd_configure_address(addr);
+	//udd_enable_address();
+}
+
+uint32_t UDD_GetFrameNumber(void)
+{
+	return udd_frame_number();
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SAMD_SERIES */
+
diff --git a/cores/arduino/USB/samd21_device.h b/cores/arduino/USB/samd21_device.h
new file mode 100644
index 00000000..c92140cd
--- /dev/null
+++ b/cores/arduino/USB/samd21_device.h
@@ -0,0 +1,622 @@
+/* ----------------------------------------------------------------------------
+ *         SAM Software Package License
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2011-2012, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition is met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef SAMD21_DEVICE_H_INCLUDED
+#define SAMD21_DEVICE_H_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EP0				0
+#define EP0_SIZE		64
+#define EPX_SIZE		512  // 512 for Full Speed, EPT size max is 1024
+
+#define EP_SINGLE_64 (0x32UL) // EP0
+#define EP_DOUBLE_64 (0x36UL) // Other endpoints
+
+
+
+#define USB_REGWRITEPROTECT()        PAC0->WPCLR.reg = (1<<5)
+
+
+/*
+// Control Endpoint
+#define EP_TYPE_CONTROL				(USB_DEVICE_EPCFG_EPTYPE0(1) | USB_DEVICE_EPCFG_EPTYPE1(1))
+
+// CDC Endpoints
+#define EP_TYPE_BULK_IN				(USB_DEVICE_EPCFG_EPTYPE1(3) | USB_DEVICE_EPSTATUSCLR_BK1RDY)
+
+#define EP_TYPE_BULK_OUT          	(USB_DEVICE_EPCFG_EPTYPE0(3) | USB_DEVICE_EPSTATUSCLR_BK0RDY)
+
+#define EP_TYPE_INTERRUPT_IN      	(USB_DEVICE_EPCFG_EPTYPE1(4) | USB_DEVICE_EPSTATUSCLR_BK1RDY)
+
+// HID Endpoints
+#define EP_TYPE_INTERRUPT_IN_HID	(USB_DEVICE_EPCFG_EPTYPE1(4) | USB_DEVICE_EPSTATUSCLR_BK1RDY)
+
+// Various definitions
+#define EP_TYPE_INTERRUPT_OUT		(USB_DEVICE_EPCFG_EPTYPE0(4) | USB_DEVICE_EPSTATUSCLR_BK0RDY)
+
+
+*/
+//! \ingroup usb_device_group
+//! \defgroup udd_group USB Device Driver (UDD)
+//! UOTGHS low-level driver for USB device mode
+//!
+//! @{
+
+/*#ifndef UOTGHS_DEVEPTCFG_EPDIR_Pos*/
+/*// Bit pos is not defined in SAM header file but we need it.*/
+/*# define UOTGHS_DEVEPTCFG_EPDIR_Pos 8*/
+/*#endif*/
+
+//! @name UOTGHS Device IP properties
+//! These macros give access to IP properties
+//! @{
+  //! Get maximal number of endpoints
+#define udd_get_endpoint_max_nbr()             (7)
+#define UDD_MAX_PEP_NB                         (udd_get_endpoint_max_nbr() + 1)
+  //! Get maximal number of banks of endpoints
+#define udd_get_endpoint_bank_max_nbr(ep)      ((ep == 0) ? 1 : 2)
+  //! Get maximal size of endpoint (3X, 1024/64)
+#define udd_get_endpoint_size_max(ep)          (64)  // for bulk full speed
+  //! Get DMA support of endpoints
+#define Is_udd_endpoint_dma_supported(ep)      (((ep) >= 1) ? true : false)
+  //! Get High Band Width support of endpoints
+#define Is_udd_endpoint_high_bw_supported(ep)  (((ep) >= 1) ? true : false)
+//! @}
+
+//! @name USB Device speeds management
+//! @{
+// Force device low speed mode
+#define udd_force_low_speed()               USB_REGWRITEPROTECT(); USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_SPDCONF_Msk; USB->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_SPDCONF_1_Val
+// Force full speed mode
+#define udd_force_full_speed()              USB_REGWRITEPROTECT(); USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_SPDCONF_Msk
+
+
+
+/*
+//! @name UOTGHS Device vbus management
+//! @{
+#define udd_enable_vbus_interrupt()       (USB->UOTGHS_CTRL |= UOTGHS_CTRL_VBUSTE)
+#define udd_disable_vbus_interrupt()      (Clr_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE))
+#define Is_udd_vbus_interrupt_enabled()   (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE))
+#define Is_udd_vbus_high()                (Tst_bits(USB->UOTGHS_SR, UOTGHS_SR_VBUS))
+#define Is_udd_vbus_low()                 (!Is_udd_vbus_high())
+#define udd_ack_vbus_transition()         (USB->UOTGHS_SCR = UOTGHS_SCR_VBUSTIC)
+#define udd_raise_vbus_transition()       (USB->UOTGHS_SFR = UOTGHS_SFR_VBUSTIS)
+#define Is_udd_vbus_transition()          (Tst_bits(USB->UOTGHS_SR, UOTGHS_SR_VBUSTI))
+//! @}
+*/
+
+
+// Attaches to USB bus
+#define udd_attach_device()                  USB_REGWRITEPROTECT(); USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH
+#define udd_detach_device()                  USB_REGWRITEPROTECT(); USB->DEVICE.CTRLB.reg |= USB_DEVICE_CTRLB_DETACH
+
+//! @name UOTGHS device bus events control
+//! These macros manage the UOTGHS Device bus events.
+//! @{
+
+//! Initiates a remote wake-up event
+//! @{
+//#define udd_initiate_remote_wake_up()     (USB->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_RMWKUP)
+//#define Is_udd_pending_remote_wake_up()   (Tst_bits(USB->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_RMWKUP))
+//! @}
+
+//! Manage upstream resume event (=remote wakeup)
+//! The USB driver sends a resume signal called "Upstream Resume"
+//! @{
+#define udd_enable_remote_wake_up_interrupt()     (USB->UOTGHS_DEVIER = UOTGHS_DEVIER_UPRSMES)
+#define udd_disable_remote_wake_up_interrupt()    (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_UPRSMEC)
+#define Is_udd_remote_wake_up_interrupt_enabled() (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_UPRSME))
+#define udd_ack_remote_wake_up_start()            (USB->UOTGHS_DEVICR = UOTGHS_DEVICR_UPRSMC)
+#define udd_raise_remote_wake_up_start()          (USB->UOTGHS_DEVIFR = UOTGHS_DEVIFR_UPRSMS)
+#define Is_udd_remote_wake_up_start()             (Tst_bits(USB->UOTGHS_DEVISR, UOTGHS_DEVISR_UPRSM))
+//! @}
+
+//! Manage downstream resume event (=remote wakeup from host)
+//! The USB controller detects a valid "End of Resume" signal initiated by the host
+//! @{
+#define udd_enable_resume_interrupt()             (USB->UOTGHS_DEVIER = UOTGHS_DEVIER_EORSMES)
+#define udd_disable_resume_interrupt()            (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_EORSMEC)
+#define Is_udd_resume_interrupt_enabled()         (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_EORSME))
+#define udd_ack_resume()                          (USB->UOTGHS_DEVICR = UOTGHS_DEVICR_EORSMC)
+#define udd_raise_resume()                        (USB->UOTGHS_DEVIFR = UOTGHS_DEVIFR_EORSMS)
+#define Is_udd_resume()                           (Tst_bits(USB->UOTGHS_DEVISR, UOTGHS_DEVISR_EORSM))
+//! @}
+
+//! Manage wake-up event (=usb line activity)
+//! The USB controller is reactivated by a filtered non-idle signal from the lines
+//! @{
+#define udd_enable_wake_up_interrupt()            (USB->UOTGHS_DEVIER = UOTGHS_DEVIER_WAKEUPES)
+#define udd_disable_wake_up_interrupt()           (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_WAKEUPEC)
+#define Is_udd_wake_up_interrupt_enabled()        (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_WAKEUPE))
+#define udd_ack_wake_up()                         (USB->UOTGHS_DEVICR = UOTGHS_DEVICR_WAKEUPC)
+#define udd_raise_wake_up()                       (USB->UOTGHS_DEVIFR = UOTGHS_DEVIFR_WAKEUPS)
+#define Is_udd_wake_up()                          (Tst_bits(USB->UOTGHS_DEVISR, UOTGHS_DEVISR_WAKEUP))
+//! @}
+
+//! Manage reset event
+//! Set when a USB "End of Reset" has been detected
+//! @{
+#define udd_enable_reset_interrupt()              USB->DEVICE.INTENSET.reg = USB_DEVICE_INTENSET_EORST
+#define udd_disable_reset_interrupt()             (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_EORSTEC)
+#define Is_udd_reset_interrupt_enabled()          (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_EORSTE))
+#define udd_ack_reset()                           USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_EORST //(USB->UOTGHS_DEVICR = UOTGHS_DEVICR_EORSTC)
+#define udd_raise_reset()                         (USB->UOTGHS_DEVIFR = UOTGHS_DEVIFR_EORSTS)
+//#define Is_udd_reset()                          (Tst_bits(USB->UOTGHS_DEVISR, UOTGHS_DEVISR_EORST))
+#define Is_udd_reset()                            USB->DEVICE.INTFLAG.reg & USB_DEVICE_INTFLAG_EORST
+//! @}
+
+//! Manage start of frame (SOF) event
+//! @{
+#define udd_enable_sof_interrupt()                USB->DEVICE.INTENSET.reg = USB_DEVICE_INTENSET_SOF
+#define udd_disable_sof_interrupt()               (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SOFEC)
+#define Is_udd_sof_interrupt_enabled()            (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_SOFE))
+#define udd_ack_sof()                             USB->DEVICE.INTFLAG.reg = USB_DEVICE_INTFLAG_SOF //(USB->UOTGHS_DEVICR = UOTGHS_DEVICR_SOFC)
+#define udd_raise_sof()                           (USB->UOTGHS_DEVIFR = UOTGHS_DEVIFR_SOFS)
+#define Is_udd_sof()                              (USB->DEVICE.INTENSET.reg & USB_DEVICE_INTENSET_SOF) //(Tst_bits(USB->UOTGHS_DEVISR, UOTGHS_DEVISR_SOF))
+#define udd_frame_number()                        ((USB->DEVICE.FNUM.reg & USB_DEVICE_FNUM_FNUM_Msk) >> USB_DEVICE_FNUM_FNUM_Pos)
+#define Is_udd_frame_number_crc_error()           (Tst_bits(USB->UOTGHS_DEVFNUM, UOTGHS_DEVFNUM_FNCERR))
+//! @}
+
+
+//! Manage suspend event
+//! @{
+#define udd_enable_suspend_interrupt()            (USB->UOTGHS_DEVIER = UOTGHS_DEVIER_SUSPES)
+#define udd_disable_suspend_interrupt()           (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SUSPEC)
+#define Is_udd_suspend_interrupt_enabled()        (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_SUSPE))
+#define udd_ack_suspend()                         (USB->UOTGHS_DEVICR = UOTGHS_DEVICR_SUSPC)
+#define udd_raise_suspend()                       (USB->UOTGHS_DEVIFR = UOTGHS_DEVIFR_SUSPS)
+#define Is_udd_suspend()                          (Tst_bits(USB->UOTGHS_DEVISR, UOTGHS_DEVISR_SUSP))
+//! @}
+
+//! @}
+
+//! @name UOTGHS device address control
+//! These macros manage the UOTGHS Device address.
+//! @{
+  //! enables USB device address
+#define udd_enable_address()                      (USB->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_ADDEN)
+  //! disables USB device address
+#define udd_disable_address()                     (Clr_bits(USB->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_ADDEN))
+#define Is_udd_address_enabled()                  (Tst_bits(USB->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_ADDEN))
+  //! configures the USB device address and enable it.
+#define udd_configure_address(address)            USB->DEVICE.DADD.reg = USB_DEVICE_DADD_ADDEN | address
+  //! gets the currently configured USB device address
+#define udd_get_configured_address()              (Rd_bitfield(USB->UOTGHS_DEVCTRL, UOTGHS_DEVCTRL_UADD_Msk))
+//! @}
+
+
+//! @name UOTGHS Device endpoint drivers
+//! These macros manage the common features of the endpoints.
+//! @{
+
+//! Generic macro for UOTGHS registers that can be arrayed
+//! @{
+//#define UOTGHS_ARRAY(reg,index)                   ((&(USB->reg))[(index)])
+//! @}
+
+//! @name UOTGHS Device endpoint configuration
+//! @{
+  //! enables the selected endpoint
+//#define udd_enable_endpoint(ep)                   (USB->UOTGHS_DEVEPT |= UOTGHS_DEVEPT_EPEN0 << (ep))
+  //! disables the selected endpoint
+//#define udd_disable_endpoint(ep)                  (Clr_bits(USB->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPEN0 << (ep)))
+  //! tests if the selected endpoint is enabled
+//#define Is_udd_endpoint_enabled(ep)               (Tst_bits(USB->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPEN0 << (ep)))
+  //! resets the selected endpoint
+#define udd_reset_endpoint(ep)                                         \
+	do {                                                               \
+		Set_bits(USB->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPRST0 << (ep)); \
+		Clr_bits(USB->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPRST0 << (ep)); \
+	} while (0)
+  //! Tests if the selected endpoint is being reset
+#define Is_udd_resetting_endpoint(ep)             (Tst_bits(USB->UOTGHS_DEVEPT, UOTGHS_DEVEPT_EPRST0 << (ep)))
+
+  //! Configures the selected endpoint type
+#define udd_configure_endpoint_type(ep, type)     (Wr_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPTYPE_Msk, type))
+  //! Gets the configured selected endpoint type
+#define udd_get_endpoint_type(ep)                 (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPTYPE_Msk))
+  //! Enables the bank autoswitch for the selected endpoint
+#define udd_enable_endpoint_bank_autoswitch(ep)   (Set_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_AUTOSW))
+  //! Disables the bank autoswitch for the selected endpoint
+#define udd_disable_endpoint_bank_autoswitch(ep)    (Clr_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_AUTOSW))
+#define Is_udd_endpoint_bank_autoswitch_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_AUTOSW))
+  //! Configures the selected endpoint direction
+#define udd_configure_endpoint_direction(ep, dir) (Wr_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPDIR, dir))
+  //! Gets the configured selected endpoint direction
+#define udd_get_endpoint_direction(ep)            (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPDIR))
+#define Is_udd_endpoint_in(ep)                    (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPDIR))
+  //! Bounds given integer size to allowed range and rounds it up to the nearest
+  //! available greater size, then applies register format of UOTGHS controller
+  //! for endpoint size bit-field.
+#define udd_format_endpoint_size(size)            (32 - clz(((uint32_t)min(max(size, 8), 1024) << 1) - 1) - 1 - 3)
+  //! Configures the selected endpoint size
+#define udd_configure_endpoint_size(ep, size)     (Wr_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPSIZE_Msk, udd_format_endpoint_size(size)))
+  //! Gets the configured selected endpoint size
+#define udd_get_endpoint_size(ep)                 (8 << Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPSIZE_Msk))
+  //! Configures the selected endpoint number of banks
+#define udd_configure_endpoint_bank(ep, bank)     (Wr_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPBK_Msk, bank))
+  //! Gets the configured selected endpoint number of banks
+#define udd_get_endpoint_bank(ep)                 (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPBK_Msk)+1)
+  //! Allocates the configuration selected endpoint in DPRAM memory
+#define udd_allocate_memory(ep)                   (Set_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_ALLOC))
+  //! un-allocates the configuration selected endpoint in DPRAM memory
+#define udd_unallocate_memory(ep)                 (Clr_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_ALLOC))
+#define Is_udd_memory_allocated(ep)               (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_ALLOC))
+
+  //! Configures selected endpoint in one step
+#define udd_configure_endpoint(ep, type, dir, size, bank) (\
+	Wr_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTCFG[0], ep), UOTGHS_DEVEPTCFG_EPTYPE_Msk |\
+			UOTGHS_DEVEPTCFG_EPDIR  |\
+			UOTGHS_DEVEPTCFG_EPSIZE_Msk |\
+			UOTGHS_DEVEPTCFG_EPBK_Msk ,   \
+			(((uint32_t)(type) << UOTGHS_DEVEPTCFG_EPTYPE_Pos) & UOTGHS_DEVEPTCFG_EPTYPE_Msk) |\
+			(((uint32_t)(dir ) << UOTGHS_DEVEPTCFG_EPDIR_Pos ) & UOTGHS_DEVEPTCFG_EPDIR) |\
+			( (uint32_t)udd_format_endpoint_size(size) << UOTGHS_DEVEPTCFG_EPSIZE_Pos) |\
+			(((uint32_t)(bank) << UOTGHS_DEVEPTCFG_EPBK_Pos) & UOTGHS_DEVEPTCFG_EPBK_Msk))\
+)
+  //! Tests if current endpoint is configured
+#define Is_udd_endpoint_configured(ep)            (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_CFGOK))
+  //! Returns the control direction
+#define udd_control_direction()                   (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], EP_CONTROL), UOTGHS_DEVEPTISR_CTRLDIR))
+
+  //! Resets the data toggle sequence
+#define udd_reset_data_toggle(ep)                 (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_RSTDTS)
+  //! Tests if the data toggle sequence is being reset
+#define Is_udd_data_toggle_reset(ep)              (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_RSTDT))
+  //! Returns data toggle
+#define udd_data_toggle(ep)                       (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_DTSEQ_Msk))
+//! @}
+
+
+//! @name UOTGHS Device control endpoint
+//! These macros control the endpoints.
+//! @{
+
+//! @name UOTGHS Device control endpoint interrupts
+//! These macros control the endpoints interrupts.
+//! @{
+  //! Enables the selected endpoint interrupt
+#define udd_enable_endpoint_interrupt(ep)         (USB->UOTGHS_DEVIER = UOTGHS_DEVIER_PEP_0 << (ep))
+  //! Disables the selected endpoint interrupt
+#define udd_disable_endpoint_interrupt(ep)        (USB->UOTGHS_DEVIDR = UOTGHS_DEVIDR_PEP_0 << (ep))
+  //! Tests if the selected endpoint interrupt is enabled
+//#define Is_udd_endpoint_interrupt_enabled(ep)     (Tst_bits(USB->UOTGHS_DEVIMR, UOTGHS_DEVIMR_PEP_0 << (ep)))
+  //! Tests if an interrupt is triggered by the selected endpoint
+#define Is_udd_endpoint_interrupt(ep)             ((USB->DEVICE.EPINTSMRY.reg & (1<<ep)) != 0 )
+  //! Returns the lowest endpoint number generating an endpoint interrupt or MAX_PEP_NB if none
+#define udd_get_interrupt_endpoint_number()       (ctz(((USB->UOTGHS_DEVISR >> UOTGHS_DEVISR_PEP_Pos) & \
+                                                   (USB->UOTGHS_DEVIMR >> UOTGHS_DEVIMR_PEP_Pos)) |     \
+                                                   (1 << MAX_PEP_NB)))
+#define UOTGHS_DEVISR_PEP_Pos   12
+#define UOTGHS_DEVIMR_PEP_Pos   12
+//! @}
+
+//! @name UOTGHS Device control endpoint errors
+//! These macros control the endpoint errors.
+//! @{
+  //! Enables the STALL handshake
+#define udd_enable_stall_handshake(ep)            (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_STALLRQS)
+  //! Disables the STALL handshake
+#define udd_disable_stall_handshake(ep)           (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_STALLRQC)
+  //! Tests if STALL handshake request is running
+#define Is_udd_endpoint_stall_requested(ep)       (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_STALLRQ))
+  //! Tests if STALL sent
+#define Is_udd_stall(ep)                          (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_STALLEDI))
+  //! ACKs STALL sent
+#define udd_ack_stall(ep)                         (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_STALLEDIC)
+  //! Raises STALL sent
+#define udd_raise_stall(ep)                       (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_STALLEDIS)
+  //! Enables STALL sent interrupt
+#define udd_enable_stall_interrupt(ep)            (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_STALLEDES)
+  //! Disables STALL sent interrupt
+#define udd_disable_stall_interrupt(ep)           (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_STALLEDEC)
+  //! Tests if STALL sent interrupt is enabled
+#define Is_udd_stall_interrupt_enabled(ep)        (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_STALLEDE))
+
+  //! Tests if NAK OUT received
+#define Is_udd_nak_out(ep)                        (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_NAKOUTI))
+  //! ACKs NAK OUT received
+#define udd_ack_nak_out(ep)                       (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_NAKOUTIC)
+  //! Raises NAK OUT received
+#define udd_raise_nak_out(ep)                     (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_NAKOUTIS)
+  //! Enables NAK OUT interrupt
+#define udd_enable_nak_out_interrupt(ep)          (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_NAKOUTES)
+  //! Disables NAK OUT interrupt
+#define udd_disable_nak_out_interrupt(ep)         (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_NAKOUTEC)
+  //! Tests if NAK OUT interrupt is enabled
+#define Is_udd_nak_out_interrupt_enabled(ep)      (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_NAKOUTE))
+
+  //! Tests if NAK IN received
+#define Is_udd_nak_in(ep)                         (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_NAKINI))
+  //! ACKs NAK IN received
+#define udd_ack_nak_in(ep)                        (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_NAKINIC)
+  //! Raises NAK IN received
+#define udd_raise_nak_in(ep)                      (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_NAKINIS)
+  //! Enables NAK IN interrupt
+#define udd_enable_nak_in_interrupt(ep)           (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_NAKINES)
+  //! Disables NAK IN interrupt
+#define udd_disable_nak_in_interrupt(ep)          (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_NAKINEC)
+  //! Tests if NAK IN interrupt is enabled
+#define Is_udd_nak_in_interrupt_enabled(ep)       (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_NAKINE))
+
+  //! ACKs endpoint isochronous overflow interrupt
+#define udd_ack_overflow_interrupt(ep)            (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_OVERFIC)
+  //! Raises endpoint isochronous overflow interrupt
+#define udd_raise_overflow_interrupt(ep)          (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_OVERFIS)
+  //! Tests if an overflow occurs
+#define Is_udd_overflow(ep)                       (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_OVERFI))
+  //! Enables overflow interrupt
+#define udd_enable_overflow_interrupt(ep)         (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_OVERFES)
+  //! Disables overflow interrupt
+#define udd_disable_overflow_interrupt(ep)        (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_OVERFEC)
+  //! Tests if overflow interrupt is enabled
+#define Is_udd_overflow_interrupt_enabled(ep)     (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_OVERFE))
+
+  //! ACKs endpoint isochronous underflow interrupt
+#define udd_ack_underflow_interrupt(ep)           (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_UNDERFIC)
+  //! Raises endpoint isochronous underflow interrupt
+#define udd_raise_underflow_interrupt(ep)         (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_UNDERFIS)
+  //! Tests if an underflow occurs
+#define Is_udd_underflow(ep)                      (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_UNDERFI))
+  //! Enables underflow interrupt
+#define udd_enable_underflow_interrupt(ep)        (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_UNDERFES)
+  //! Disables underflow interrupt
+#define udd_disable_underflow_interrupt(ep)       (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_UNDERFEC)
+  //! Tests if underflow interrupt is enabled
+#define Is_udd_underflow_interrupt_enabled(ep)    (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_UNDERFE))
+
+  //! Tests if CRC ERROR ISO OUT detected
+#define Is_udd_crc_error(ep)                      (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_CRCERRI))
+  //! ACKs CRC ERROR ISO OUT detected
+#define udd_ack_crc_error(ep)                     (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_CRCERRIC)
+  //! Raises CRC ERROR ISO OUT detected
+#define udd_raise_crc_error(ep)                   (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_CRCERRIS)
+  //! Enables CRC ERROR ISO OUT detected interrupt
+#define udd_enable_crc_error_interrupt(ep)        (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_CRCERRES)
+  //! Disables CRC ERROR ISO OUT detected interrupt
+#define udd_disable_crc_error_interrupt(ep)       (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_CRCERREC)
+  //! Tests if CRC ERROR ISO OUT detected interrupt is enabled
+#define Is_udd_crc_error_interrupt_enabled(ep)    (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_CRCERRE))
+//! @}
+
+//! @name UOTGHS Device control endpoint transfer
+//! These macros control the endpoint transfer.
+//! @{
+
+  //! Tests if endpoint read allowed
+#define Is_udd_read_enabled(ep)                   (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_RWALL))
+  //! Tests if endpoint write allowed
+#define Is_udd_write_enabled(ep)                  (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_RWALL))
+
+  //! Returns the byte count
+#define udd_byte_count(ep)                        (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_BYCT_Msk))
+  //! Clears FIFOCON bit
+#define udd_ack_fifocon(ep)                       (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_FIFOCONC)
+  //! Tests if FIFOCON bit set
+#define Is_udd_fifocon(ep)                        (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_FIFOCON))
+
+  //! Returns the number of busy banks
+#define udd_nb_busy_bank(ep)                      (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_NBUSYBK_Msk))
+  //! Returns the number of the current bank
+#define udd_current_bank(ep)                      (Rd_bitfield(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_CURRBK_Msk))
+  //! Kills last bank
+#define udd_kill_last_in_bank(ep)                 (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_KILLBKS)
+#define Is_udd_kill_last(ep)                      (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_KILLBK))
+  //! Tests if last bank killed
+#define Is_udd_last_in_bank_killed(ep)            (!Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_KILLBK))
+  //! Forces all banks full (OUT) or free (IN) interrupt
+#define udd_force_bank_interrupt(ep)              (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_NBUSYBKS)
+  //! Unforces all banks full (OUT) or free (IN) interrupt
+#define udd_unforce_bank_interrupt(ep)            (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_NBUSYBKS)
+  //! Enables all banks full (OUT) or free (IN) interrupt
+#define udd_enable_bank_interrupt(ep)             (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_NBUSYBKES)
+  //! Disables all banks full (OUT) or free (IN) interrupt
+#define udd_disable_bank_interrupt(ep)            (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_NBUSYBKEC)
+  //! Tests if all banks full (OUT) or free (IN) interrupt enabled
+#define Is_udd_bank_interrupt_enabled(ep)         (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_NBUSYBKE))
+
+  //! Tests if SHORT PACKET received
+#define Is_udd_short_packet(ep)                   (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_SHORTPACKET))
+  //! ACKs SHORT PACKET received
+#define udd_ack_short_packet(ep)                  (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_SHORTPACKETC)
+  //! Raises SHORT PACKET received
+#define udd_raise_short_packet(ep)                (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_SHORTPACKETS)
+  //! Enables SHORT PACKET received interrupt
+#define udd_enable_short_packet_interrupt(ep)     (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_SHORTPACKETES)
+  //! Disables SHORT PACKET received interrupt
+#define udd_disable_short_packet_interrupt(ep)    (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_SHORTPACKETEC)
+  //! Tests if SHORT PACKET received interrupt is enabled
+#define Is_udd_short_packet_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_SHORTPACKETE))
+
+  //! Tests if SETUP received
+#define Is_udd_setup_received(ep)                    (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_RXSTPI))
+  //! ACKs SETUP received
+#define udd_ack_setup_received(ep)                   (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_RXSTPIC)
+  //! Raises SETUP received
+#define udd_raise_setup_received(ep)                 (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_RXSTPIS)
+  //! Enables SETUP received interrupt
+//#define udd_enable_setup_received_interrupt(ep)    (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_RXSTPES)
+#define udd_enable_setup_received_interrupt(ep)      USB->DEVICE.DeviceEndpoint[ep].EPINTENCLR.reg = USB_DEVICE_EPINTFLAG_RXSTP
+  //! Disables SETUP received interrupt
+#define udd_disable_setup_received_interrupt(ep)     (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_RXSTPEC)
+  //! Tests if SETUP received interrupt is enabled
+#define Is_udd_setup_received_interrupt_enabled(ep)  (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_RXSTPE))
+
+  //! Tests if OUT received
+#define Is_udd_out_received(ep)                   (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_RXOUTI))
+  //! ACKs OUT received
+#define udd_ack_out_received(ep)                  USB->DEVICE.DeviceEndpoint[ep].EPSTATUSCLR.reg = USB_DEVICE_EPSTATUSCLR_BK0RDY; //(UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_RXOUTIC)
+  //! Raises OUT received
+#define udd_raise_out_received(ep)                (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_RXOUTIS)
+  //! Enables OUT received interrupt
+#define udd_enable_out_received_interrupt(ep)     USB->DEVICE.DeviceEndpoint[ep].EPSTATUSSET.reg = USB_DEVICE_EPSTATUSSET_BK0RDY;  //(UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_RXOUTES)
+  //! Disables OUT received interrupt
+#define udd_disable_out_received_interrupt(ep)    (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_RXOUTEC)
+  //! Tests if OUT received interrupt is enabled
+#define Is_udd_out_received_interrupt_enabled(ep) (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_RXOUTE))
+
+  //! Tests if IN sending
+#define Is_udd_in_send(ep)                        (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTISR[0], ep), UOTGHS_DEVEPTISR_TXINI))
+  //! ACKs IN sending
+#define udd_ack_in_send(ep)                       (UOTGHS_ARRAY(UOTGHS_DEVEPTICR[0], ep) = UOTGHS_DEVEPTICR_TXINIC)
+  //! Raises IN sending
+#define udd_raise_in_send(ep)                     (UOTGHS_ARRAY(UOTGHS_DEVEPTIFR[0], ep) = UOTGHS_DEVEPTIFR_TXINIS)
+  //! Enables IN sending interrupt
+#define udd_enable_in_send_interrupt(ep)          (UOTGHS_ARRAY(UOTGHS_DEVEPTIER[0], ep) = UOTGHS_DEVEPTIER_TXINES)
+  //! Disables IN sending interrupt
+#define udd_disable_in_send_interrupt(ep)         (UOTGHS_ARRAY(UOTGHS_DEVEPTIDR[0], ep) = UOTGHS_DEVEPTIDR_TXINEC)
+  //! Tests if IN sending interrupt is enabled
+#define Is_udd_in_send_interrupt_enabled(ep)      (Tst_bits(UOTGHS_ARRAY(UOTGHS_DEVEPTIMR[0], ep), UOTGHS_DEVEPTIMR_TXINE))
+
+
+  //! 8-bit access to FIFO data register of selected endpoint.
+  //! @param ep Endpoint of which to access FIFO data register
+  //! @return Volatile 8-bit data pointer to FIFO data register
+  //! @warning It is up to the user of this macro to make sure that all accesses
+  //! are aligned with their natural boundaries
+  //! @warning It is up to the user of this macro to make sure that used HSB
+  //! addresses are identical to the DPRAM internal pointer modulo 32 bits.
+#define udd_get_endpoint_fifo_access8(ep) \
+		(((volatile uint8_t (*)[0x8000])UOTGHS_RAM_ADDR)[(ep)])
+
+//! @}
+
+/*********************************************************************************************************************/
+
+//! @name UOTGHS IP properties
+//! These macros give access to IP properties (not defined in 3X)
+//! @{
+   //! Get IP name part 1 or 2
+#define otg_get_ip_name()
+#define otg_data_memory_barrier()
+   //! Get IP version
+#define otg_get_ip_version()
+   //! Get DPRAM size (FIFO maximal size) in bytes
+#define otg_get_dpram_size()
+   //! Get size of USBB PB address space
+#define otg_get_ip_paddress_size()
+//! @}
+
+//! @name UOTGHS OTG ID pin management
+//! The ID pin come from the USB OTG connector (A and B receptable) and
+//! allows to select the USB mode host or device.
+//! The USBB hardware can manage it automaticaly. This feature is optional.
+//! When otg_ID_PIN equals true in conf_usb_host.h, the USB_ID must be defined in board.h.
+//!
+//! @{
+   //! PIO, PIO ID and MASK for USB_ID according to configuration from OTG_ID
+#define OTG_ID_PIN                          USB_ID_GPIO
+#define OTG_ID_FUNCTION                     USB_ID_FLAGS
+   //! Input USB_ID from its pin
+#define otg_input_id_pin() do {                     \
+    pio_configure_pin(OTG_ID_PIN, OTG_ID_FUNCTION); \
+} while (0)
+
+   //! Enable external OTG_ID pin (listened to by USB)
+#define otg_enable_id_pin()                 (Set_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_UIDE))
+   //! Disable external OTG_ID pin (ignored by USB)
+#define otg_disable_id_pin()                (Clr_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_UIDE))
+   //! Test if external OTG_ID pin enabled (listened to by USB)
+#define Is_otg_id_pin_enabled()             (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_UIDE))
+// Force device mode
+#define udd_force_device_mode()             (USB->DEVICE.CTRLA.reg &= ~USB_CTRLA_MODE)
+// Run in Standby
+#define udd_device_run_in_standby()         (USB->DEVICE.CTRLA.reg |= USB_CTRLA_RUNSTDBY) 
+   //! Test if device mode is forced
+//#define Is_otg_device_mode_forced()         (!Is_otg_id_pin_enabled() && Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_UIMOD))
+// Force host mode
+#define otg_force_host_mode()               (USB->DEVICE.CTRLA.reg |= USB_CTRLA_MODE)
+   //! Test if host mode is forced
+#define Is_otg_host_mode_forced()           (!Is_otg_id_pin_enabled() && !Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_UIMOD))
+
+//! @name UOTGHS OTG ID pin interrupt management
+//! These macros manage the ID pin interrupt
+//! @{
+#define otg_enable_id_interrupt()           (Set_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_IDTE))
+#define otg_disable_id_interrupt()          (Clr_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_IDTE))
+#define Is_otg_id_interrupt_enabled()       (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_IDTE))
+#define Is_otg_id_device()                  (Tst_bits(USB->UOTGHS_SR, UOTGHS_SR_ID))
+#define Is_otg_id_host()                    (!Is_otg_id_device())
+#define otg_ack_id_transition()             (USB->UOTGHS_SCR = UOTGHS_SCR_IDTIC)
+#define otg_raise_id_transition()           (USB->UOTGHS_SFR = UOTGHS_SFR_IDTIS)
+#define Is_otg_id_transition()              (Tst_bits(USB->UOTGHS_SR, UOTGHS_SR_IDTI))
+//! @}
+
+
+//! @name USBB OTG Vbus management
+//! @{
+#define otg_enable_vbus_interrupt()         (Set_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE))
+//#define otg_disable_vbus_interrupt()        (Clr_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE))
+//#define Is_otg_vbus_interrupt_enabled()     (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_VBUSTE))
+//#define Is_otg_vbus_high()                  ((USB->CTRLB & USB_CTRLB_VBUSOK) == USB_CTRLB_VBUSOK)
+#define is_usb_vbus_high()                  port_pin_get_input_level(USB_VBUS_PIN)
+
+//#define Is_otg_vbus_low()                   (!Is_otg_vbus_high())
+#define otg_ack_vbus_transition()           (USB->UOTGHS_SCR = UOTGHS_SCR_VBUSTIC)
+#define otg_raise_vbus_transition()         (USB->UOTGHS_SFR = UOTGHS_SFR_VBUSTIS)
+#define Is_otg_vbus_transition()            (Tst_bits(USB->UOTGHS_SR, UOTGHS_SR_VBUSTI))
+//! @}
+
+//! @name UOTGHS OTG main management
+//! These macros allows to enable/disable pad and UOTGHS hardware
+//! @{
+  //! Enable USB macro
+#define udd_enable()                        (USB->DEVICE.CTRLA.reg |= USB_CTRLA_ENABLE)
+//(Set_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_USBE))
+  //! Disable USB macro
+#define udd_disable()                       (USB->DEVICE.CTRLA.reg &= ~USB_CTRLA_ENABLE)
+//#define Is_otg_enabled()                    (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_USBE))
+
+  //! Enable OTG pad
+//#define otg_enable_pad()                    (Set_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_OTGPADE))
+  //! Disable OTG pad
+//#define otg_disable_pad()                   (Clr_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_OTGPADE))
+//#define Is_otg_pad_enabled()                (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_OTGPADE))
+
+  //! Check Clock Usable
+  //! For parts with HS feature, this one corresponding at UTMI clock
+//#define Is_otg_clock_usable()               (Tst_bits(USB->UOTGHS_SR, UOTGHS_SR_CLKUSABLE))
+
+  //! Stop (freeze) internal USB clock
+//#define otg_freeze_clock()                  (Set_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK))
+//#define otg_unfreeze_clock()                (Clr_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK))
+//#define Is_otg_clock_frozen()               (Tst_bits(USB->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK))
+
+//! @}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SAMD21_DEVICE_H_INCLUDED */
+
diff --git a/cores/arduino/USB/samd21_host.c b/cores/arduino/USB/samd21_host.c
new file mode 100644
index 00000000..26262ee3
--- /dev/null
+++ b/cores/arduino/USB/samd21_host.c
@@ -0,0 +1,489 @@
+/* ----------------------------------------------------------------------------
+ *         SAM Software Package License
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2011-2012, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition is met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#include <stdio.h>
+
+#if SAM3XA_SERIES
+
+//#define TRACE_UOTGHS_HOST(x)	x
+#define TRACE_UOTGHS_HOST(x)
+
+extern void (*gpf_isr)(void);
+
+// Handle UOTGHS Host driver state
+static uhd_vbus_state_t uhd_state = UHD_STATE_NO_VBUS;
+
+/**
+ * \brief Interrupt sub routine for USB Host state machine management.
+ */
+static void UHD_ISR(void)
+{
+	// Manage dis/connection event
+	if (Is_uhd_disconnection() && Is_uhd_disconnection_int_enabled()) {
+		TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Disconnection INT\r\n");)
+		uhd_ack_disconnection();
+		uhd_disable_disconnection_int();
+		// Stop reset signal, in case of disconnection during reset
+		uhd_stop_reset();
+		// Disable wakeup/resumes interrupts,
+		// in case of disconnection during suspend mode
+		//UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_HWUPIEC
+		//		| UOTGHS_HSTIDR_RSMEDIEC
+		//		| UOTGHS_HSTIDR_RXRSMIEC;
+		uhd_ack_connection();
+		uhd_enable_connection_int();
+		uhd_state = UHD_STATE_DISCONNECTED;
+		return;
+	}
+	if (Is_uhd_connection() && Is_uhd_connection_int_enabled()) {
+		TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Connection INT\r\n");)
+		uhd_ack_connection();
+		uhd_disable_connection_int();
+		uhd_ack_disconnection();
+		uhd_enable_disconnection_int();
+		//uhd_enable_sof();
+		uhd_state = UHD_STATE_CONNECTED;
+		return;
+	}
+
+	// Manage Vbus error
+	if (Is_uhd_vbus_error_interrupt())
+	{
+		TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : VBUS error INT\r\n");)
+		uhd_ack_vbus_error_interrupt();
+		uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR;
+		return;
+	}
+
+	// Check USB clock ready after asynchronous interrupt
+	while (!Is_otg_clock_usable())
+		;
+	otg_unfreeze_clock();
+
+	// Manage Vbus state change
+	if (Is_otg_vbus_transition())
+	{
+		otg_ack_vbus_transition();
+		if (Is_otg_vbus_high())
+		{
+			TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : VBUS transition INT : UHD_STATE_DISCONNECT\r\n");)
+			uhd_state = UHD_STATE_DISCONNECTED;
+		}
+		else
+		{
+			TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : VBUS transition INT : UHD_STATE_NO_VBUS\r\n");)
+			otg_freeze_clock();
+			uhd_state = UHD_STATE_NO_VBUS;
+		}
+		TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : VBUS transition INT : done.\r\n");)
+		return;
+	}
+
+	// Other errors
+	if (Is_uhd_errors_interrupt())
+	{
+		TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Other error INT\r\n");)
+		uhd_ack_errors_interrupt();
+		return;
+	}
+}
+
+/**
+ * \brief Set the interrupt sub routines callback for USB interrupts.
+ *
+ * \param pf_isr the ISR address.
+ */
+void UHD_SetStack(void (*pf_isr)(void))
+{
+	gpf_isr = pf_isr;
+}
+
+/**
+ * \brief Initialize the UOTGHS host driver.
+ */
+void UHD_Init(void)
+{
+	irqflags_t flags;
+
+	// To avoid USB interrupt before end of initialization
+	flags = cpu_irq_save();
+
+	// Setup USB Host interrupt callback
+	UHD_SetStack(&UHD_ISR);
+
+	// Enables the USB Clock
+	pmc_enable_upll_clock();
+	pmc_switch_udpck_to_upllck(0); // div=0+1
+	pmc_enable_udpck();
+	pmc_enable_periph_clk(ID_UOTGHS);
+
+	// Always authorize asynchronous USB interrupts to exit of sleep mode
+	// For SAM3 USB wake up device except BACKUP mode
+	NVIC_SetPriority((IRQn_Type) ID_UOTGHS, 0);
+	NVIC_EnableIRQ((IRQn_Type) ID_UOTGHS);
+
+	// ID pin not used then force host mode
+	otg_disable_id_pin();
+	otg_force_host_mode();
+
+	// Signal is active low (because all SAM3X Pins are high after startup)
+	// Hence VBOF must be low after connection request to power up the remote device
+	// uhd_set_vbof_active_low();
+
+	// According to the Arduino Due circuit the VBOF must be active high to power up the remote device
+	uhd_set_vbof_active_high();
+
+	otg_enable_pad();
+	otg_enable();
+
+	otg_unfreeze_clock();
+
+	// Check USB clock
+	while (!Is_otg_clock_usable())
+		;
+
+	// Clear all interrupts that may have been set by a previous host mode
+	UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_DCONNIC | UOTGHS_HSTICR_DDISCIC
+			| UOTGHS_HSTICR_HSOFIC  | UOTGHS_HSTICR_HWUPIC
+			| UOTGHS_HSTICR_RSMEDIC | UOTGHS_HSTICR_RSTIC
+			| UOTGHS_HSTICR_RXRSMIC;
+
+	otg_ack_vbus_transition();
+
+	// Enable Vbus change and error interrupts
+	// Disable automatic Vbus control after Vbus error
+	Set_bits(UOTGHS->UOTGHS_CTRL,
+		UOTGHS_CTRL_VBUSHWC | UOTGHS_CTRL_VBUSTE | UOTGHS_CTRL_VBERRE);
+
+	uhd_enable_vbus();
+
+	// Force Vbus interrupt when Vbus is always high
+	// This is possible due to a short timing between a Host mode stop/start.
+	if (Is_otg_vbus_high())
+	{
+		otg_raise_vbus_transition();
+	}
+
+	// Enable main control interrupt
+	// Connection, SOF and reset
+	UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTICR_DCONNIC;
+
+	otg_freeze_clock();
+
+	uhd_state = UHD_STATE_NO_VBUS;
+
+	cpu_irq_restore(flags);
+}
+
+/**
+ * \brief Trigger a USB bus reset.
+ */
+void UHD_BusReset(void)
+{
+	uhd_start_reset();
+}
+
+/**
+ * \brief Get VBUS state.
+ *
+ * \return VBUS status.
+ */
+uhd_vbus_state_t UHD_GetVBUSState(void)
+{
+	return uhd_state;
+}
+
+/*uhd_speed_t uhd_get_speed(void)
+{
+	switch (uhd_get_speed_mode())
+	{
+		case UOTGHS_SR_SPEED_HIGH_SPEED:
+			return UHD_SPEED_HIGH;
+
+		case UOTGHS_SR_SPEED_FULL_SPEED:
+			return UHD_SPEED_FULL;
+
+		case UOTGHS_SR_SPEED_LOW_SPEED:
+			return UHD_SPEED_LOW;
+
+		default:
+			return UHD_SPEED_LOW;
+	}
+}*/
+
+/**
+ * \brief Allocate FIFO for pipe 0.
+ *
+ * \param ul_add Address of remote device for pipe 0.
+ * \param ul_ep_size Actual size of the FIFO in bytes.
+ *
+ * \retval 0 success.
+ * \retval 1 error.
+ */
+uint32_t UHD_Pipe0_Alloc(uint32_t ul_add, uint32_t ul_ep_size)
+{
+	if (ul_ep_size < 8)
+	{
+		TRACE_UOTGHS_HOST(printf("/!\\ UHD_EP0_Alloc : incorrect pipe size!\r\n");)
+		return 1;
+	}
+
+	if (Is_uhd_pipe_enabled(0))
+	{
+		// Pipe is already allocated
+		return 0;
+	}
+
+	uhd_enable_pipe(0);
+	uhd_configure_pipe(0, 	// Pipe 0
+			0, 				// No frequency
+			0, 				// Enpoint 0
+			UOTGHS_HSTPIPCFG_PTYPE_CTRL,
+			UOTGHS_HSTPIPCFG_PTOKEN_SETUP,
+			ul_ep_size,
+			UOTGHS_HSTPIPCFG_PBK_1_BANK, 0);
+
+	uhd_allocate_memory(0);
+
+	if (!Is_uhd_pipe_configured(0))
+	{
+		TRACE_UOTGHS_HOST(printf("/!\\ UHD_EP0_Alloc : incorrect pipe settings!\r\n");)
+		uhd_disable_pipe(0);
+		return 1;
+	}
+
+	uhd_configure_address(0, ul_add);
+
+	return 0;
+}
+
+/**
+ * \brief Allocate a new pipe.
+ *
+ * \note UOTGHS maximum pipe number is limited to 10, meaning that only a limited
+ * amount of devices can be connected. Unfortunately, using only one pipe shared accross
+ * various endpoints and devices is not possible because the UOTGHS IP does not allow to
+ * change the data toggle value through register interface.
+ *
+ * \param ul_dev_addr Address of remote device.
+ * \param ul_dev_ep Targeted endpoint of remote device.
+ * \param ul_type Pipe type.
+ * \param ul_dir Pipe direction.
+ * \param ul_maxsize Pipe size.
+ * \param ul_interval Polling interval (if applicable to pipe type).
+ * \param ul_nb_bank Number of banks associated with this pipe.
+ *
+ * \return the newly allocated pipe number on success, 0 otherwise.
+ */
+uint32_t UHD_Pipe_Alloc(uint32_t ul_dev_addr, uint32_t ul_dev_ep, uint32_t ul_type, uint32_t ul_dir, uint32_t ul_maxsize, uint32_t ul_interval, uint32_t ul_nb_bank)
+{
+	uint32_t ul_pipe = 1;
+
+	for (ul_pipe = 1; ul_pipe < UOTGHS_EPT_NUM; ++ul_pipe)
+	{
+		if (Is_uhd_pipe_enabled(ul_pipe))
+		{
+			continue;
+		}
+
+		uhd_enable_pipe(ul_pipe);
+
+		uhd_configure_pipe(ul_pipe, ul_interval, ul_dev_ep, ul_type, ul_dir,
+				ul_maxsize, ul_nb_bank, UOTGHS_HSTPIPCFG_AUTOSW);
+
+		uhd_allocate_memory(ul_pipe);
+
+		if (!Is_uhd_pipe_configured(ul_pipe))
+		{
+			uhd_disable_pipe(ul_pipe);
+			return 0;
+		}
+
+		uhd_configure_address(ul_pipe, ul_dev_addr);
+
+		// Pipe is configured and allocated successfully
+		return ul_pipe;
+	}
+
+	return 0;
+}
+
+/**
+ * \brief Free a pipe.
+ *
+ * \param ul_pipe Pipe number to free.
+ */
+void UHD_Pipe_Free(uint32_t ul_pipe)
+{
+	// Unalloc pipe
+	uhd_disable_pipe(ul_pipe);
+	uhd_unallocate_memory(ul_pipe);
+	uhd_reset_pipe(ul_pipe);
+}
+
+/**
+ * \brief Read from a pipe.
+ *
+ * \param ul_pipe Pipe number.
+ * \param ul_size Maximum number of data to read.
+ * \param data Buffer to store the data.
+ *
+ * \return number of data read.
+ */
+uint32_t UHD_Pipe_Read(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data)
+{
+	uint8_t *ptr_ep_data = 0;
+	uint8_t nb_byte_received = 0;
+	uint32_t ul_nb_trans = 0;
+
+	// Get information to read data
+	nb_byte_received = uhd_byte_count(ul_pipe);
+
+	ptr_ep_data = (uint8_t *) & uhd_get_pipe_fifo_access(ul_pipe, 8);
+
+	// Copy data from pipe to payload buffer
+	while (ul_size && nb_byte_received) {
+		*data++ = *ptr_ep_data++;
+		ul_nb_trans++;
+		ul_size--;
+		nb_byte_received--;
+	}
+
+	return ul_nb_trans;
+}
+
+/**
+ * \brief Write into a pipe.
+ *
+ * \param ul_pipe Pipe number.
+ * \param ul_size Maximum number of data to read.
+ * \param data Buffer containing data to write.
+ */
+void UHD_Pipe_Write(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data)
+{
+	volatile uint8_t *ptr_ep_data = 0;
+	uint32_t i = 0;
+
+	// Check pipe
+	if (!Is_uhd_pipe_enabled(ul_pipe))
+	{
+		// Endpoint not valid
+		TRACE_UOTGHS_HOST(printf("/!\\ UHD_EP_Send : pipe is not enabled!\r\n");)
+		return;
+	}
+
+	ptr_ep_data = (volatile uint8_t *)&uhd_get_pipe_fifo_access(ul_pipe, 8);
+	for (i = 0; i < ul_size; ++i)
+		*ptr_ep_data++ = *data++;
+}
+
+/**
+ * \brief Send a pipe content.
+ *
+ * \param ul_pipe Pipe number.
+ * \param ul_token_type Token type.
+ */
+void UHD_Pipe_Send(uint32_t ul_pipe, uint32_t ul_token_type)
+{
+	// Check pipe
+	if (!Is_uhd_pipe_enabled(ul_pipe))
+	{
+		// Endpoint not valid
+		TRACE_UOTGHS_HOST(printf("/!\\ UHD_EP_Send : pipe %lu is not enabled!\r\n", ul_pipe);)
+		return;
+	}
+
+	// Set token type for zero length packet
+	// When actually using the FIFO, pipe token MUST be configured first
+	uhd_configure_pipe_token(ul_pipe, ul_token_type);
+
+	// Clear interrupt flags
+	uhd_ack_setup_ready(ul_pipe);
+	uhd_ack_in_received(ul_pipe);
+	uhd_ack_out_ready(ul_pipe);
+	uhd_ack_short_packet(ul_pipe);
+	uhd_ack_nak_received(ul_pipe);
+
+	// Send actual packet
+	uhd_ack_fifocon(ul_pipe);
+	uhd_unfreeze_pipe(ul_pipe);
+}
+
+/**
+ * \brief Check for pipe transfer completion.
+ *
+ * \param ul_pipe Pipe number.
+ * \param ul_token_type Token type.
+ *
+ * \retval 0 transfer is not complete.
+ * \retval 1 transfer is complete.
+ */
+uint32_t UHD_Pipe_Is_Transfer_Complete(uint32_t ul_pipe, uint32_t ul_token_type)
+{
+	// Check for transfer completion depending on token type
+	switch (ul_token_type)
+	{
+		case UOTGHS_HSTPIPCFG_PTOKEN_SETUP:
+			if (Is_uhd_setup_ready(ul_pipe))
+			{
+				uhd_freeze_pipe(ul_pipe);
+				uhd_ack_setup_ready(ul_pipe);
+				return 1;
+			}
+
+		case UOTGHS_HSTPIPCFG_PTOKEN_IN:
+			if (Is_uhd_in_received(ul_pipe))
+			{
+				// In case of low USB speed and with a high CPU frequency,
+				// a ACK from host can be always running on USB line
+				// then wait end of ACK on IN pipe.
+				while(!Is_uhd_pipe_frozen(ul_pipe))
+					;
+
+				// IN packet received
+				uhd_ack_in_received(ul_pipe);
+
+				return 1;
+			}
+
+		case UOTGHS_HSTPIPCFG_PTOKEN_OUT:
+			if (Is_uhd_out_ready(ul_pipe))
+			{
+				// OUT packet sent
+				uhd_freeze_pipe(ul_pipe);
+				uhd_ack_out_ready(ul_pipe);
+
+				return 1;
+			}
+	}
+
+	return 0;
+}
+
+#endif /* SAM3XA_SERIES */
diff --git a/cores/arduino/USB/samd21_host.h b/cores/arduino/USB/samd21_host.h
new file mode 100644
index 00000000..c3b2186f
--- /dev/null
+++ b/cores/arduino/USB/samd21_host.h
@@ -0,0 +1,399 @@
+/* ----------------------------------------------------------------------------
+ *         SAM Software Package License
+ * ----------------------------------------------------------------------------
+ * Copyright (c) 2011-2012, Atmel Corporation
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following condition is met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the disclaimer below.
+ *
+ * Atmel's name may not be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef UOTGHS_HOST_H_INCLUDED
+#define UOTGHS_HOST_H_INCLUDED
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//! \ingroup usb_host_group
+//! \defgroup uhd_group USB Host Driver (UHD)
+//! UOTGHS low-level driver for USB host mode
+//!
+//! @{
+
+//! @name UOTGHS Host IP properties
+//!
+//! @{
+//! Get maximal number of endpoints
+#define uhd_get_pipe_max_nbr()                (9)
+#define UOTGHS_EPT_NUM                        (uhd_get_pipe_max_nbr()+1)
+//! @}
+
+//! @name Host Vbus line control
+//!
+//! VBOF is an optional output pin which allows to enable or disable
+//! the external VBus generator.
+//!
+//! @{
+//! Enables hardware control of USB_VBOF output pin when a Vbus error occur
+#define uhd_enable_vbus_error_hw_control()    (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSHWC))
+//! Disables hardware control of USB_VBOF output pin when a Vbus error occur
+#define uhd_disable_vbus_error_hw_control()   (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSHWC))
+
+//! Pin and function for USB_VBOF according to configuration from USB_VBOF
+#define USB_VBOF_PIN            USB_VBOF_GPIO
+#define USB_VBOF_FUNCTION       USB_VBOF_FLAGS
+//! Output USB_VBOF onto its pin
+#define uhd_output_vbof_pin() do {\
+	pio_configure_pin(USB_VBOF_PIN, USB_VBOF_FUNCTION); \
+} while (0)
+
+//! Set USB_VBOF output pin polarity
+#define uhd_set_vbof_active_high()            (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSPO))
+#define uhd_set_vbof_active_low()             (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBUSPO))
+//! Requests VBus activation
+#define uhd_enable_vbus()                     (Set_bits(UOTGHS->UOTGHS_SFR, UOTGHS_SR_VBUSRQ))
+//! Requests VBus deactivation
+#define uhd_disable_vbus()                    (Set_bits(UOTGHS->UOTGHS_SCR, UOTGHS_SR_VBUSRQ))
+//! Tests if VBus activation has been requested
+#define Is_uhd_vbus_enabled()                 (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBUSRQ))
+//! @}
+
+//! @name Host Vbus line monitoring
+//!
+//! The VBus level is always checked by USBC hardware.
+//!
+//! @{
+#define uhd_enable_vbus_error_interrupt()     (Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE))
+#define uhd_disable_vbus_error_interrupt()    (Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE))
+#define Is_uhd_vbus_error_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE))
+#define uhd_ack_vbus_error_interrupt()        (Set_bits(UOTGHS->UOTGHS_SCR, UOTGHS_SCR_VBERRIC))
+#define Is_uhd_vbus_error_interrupt()         (Tst_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_VBERRI))
+//! @}
+
+#define uhd_ack_errors_interrupt()            (UOTGHS->UOTGHS_SCR = (UOTGHS_SCR_VBERRIC|UOTGHS_SCR_BCERRIC|UOTGHS_SCR_HNPERRIC|UOTGHS_SCR_STOIC))
+#define Is_uhd_errors_interrupt()             (Tst_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_VBERRE|UOTGHS_CTRL_BCERRE|UOTGHS_CTRL_HNPERRE|UOTGHS_CTRL_STOE))
+#define uhd_enable_suspend_error_interrupt()
+#define uhd_enable_hnp_error_interrupt()
+#define uhd_enable_bconn_error_interrupt()
+
+//! @name USB device connection/disconnection monitoring
+//! @{
+#define uhd_enable_connection_int()           (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_DCONNIES)
+#define uhd_disable_connection_int()          (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_DCONNIEC)
+#define Is_uhd_connection_int_enabled()       (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_DCONNIE))
+#define uhd_ack_connection()                  (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_DCONNIC)
+#define Is_uhd_connection()                   (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_DCONNI))
+
+#define uhd_enable_disconnection_int()        (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_DDISCIES)
+#define uhd_disable_disconnection_int()       (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_DDISCIEC)
+#define Is_uhd_disconnection_int_enabled()    (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_DDISCIE))
+#define uhd_ack_disconnection()               (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_DDISCIC)
+#define Is_uhd_disconnection()                (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_DDISCI))
+//! @}
+
+//! @name USB device speed control
+//! @{
+#define uhd_get_speed_mode()                  (Rd_bits(UOTGHS->UOTGHS_SR, UOTGHS_SR_SPEED_Msk))
+#define Is_uhd_low_speed_mode()                 (uhd_get_speed_mode() == UOTGHS_SR_SPEED_LOW_SPEED)
+#define Is_uhd_full_speed_mode()                (uhd_get_speed_mode() == UOTGHS_SR_SPEED_FULL_SPEED)
+#define Is_uhd_high_speed_mode()                (uhd_get_speed_mode() == UOTGHS_SR_SPEED_HIGH_SPEED)
+//! Enable high speed mode
+# define uhd_enable_high_speed_mode()        (Wr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SPDCONF_Msk, UOTGHS_HSTCTRL_SPDCONF_HIGH_SPEED))
+//! Disable high speed mode
+# define uhd_disable_high_speed_mode()       (Wr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SPDCONF_Msk, UOTGHS_HSTCTRL_SPDCONF_FORCED_FS))
+//! @}
+
+//! @name Bus events control
+//! These macros manage the bus events: reset, SOF, resume, wakeup.
+//! @{
+
+//! Initiates a reset event
+//! @{
+#define uhd_start_reset()                            (Set_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESET))
+#define Is_uhd_starting_reset()                      (Tst_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESET))
+#define uhd_stop_reset()                             (Clr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESET))
+
+#define uhd_enable_reset_sent_interrupt()            (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_RSTIES)
+#define uhd_disable_reset_sent_interrupt()           (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_RSTIEC)
+#define Is_uhd_reset_sent_interrupt_enabled()        (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_RSTIE))
+#define uhd_ack_reset_sent()                         (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_RSTIC)
+#define Is_uhd_reset_sent()                          (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_RSTI))
+//! @}
+
+//! Initiates a SOF events
+//! @{
+#define uhd_enable_sof()                             (Set_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SOFE))
+#define uhd_disable_sof()                            (Clr_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SOFE))
+#define Is_uhd_sof_enabled()                         (Tst_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_SOFE))
+#define uhd_get_sof_number()                         ((UOTGHS->UOTGHS_HSTFNUM&UOTGHS_HSTFNUM_FNUM_Msk)>>UOTGHS_HSTFNUM_FNUM_Pos)
+#define uhd_get_microsof_number()                    ((UOTGHS->UOTGHS_HSTFNUM&UOTGHS_HSTFNUM_MFNUM_Msk)>>UOTGHS_HSTFNUM_MFNUM_Pos)
+#define uhd_get_frame_position()                     (Rd_bits(UOTGHS->UOTGHS_HSTFNUM, UOTGHS_HSTFNUM_FLENHIGH_Msk))
+#define uhd_enable_sof_interrupt()                   (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_HSOFIES)
+#define uhd_disable_sof_interrupt()                  (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_HSOFIEC)
+#define Is_uhd_sof_interrupt_enabled()               (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_HSOFIE))
+#define uhd_ack_sof()                                (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_HSOFIC)
+#define Is_uhd_sof()                                 (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_HSOFI))
+//! @}
+
+//! Initiates a resume event
+//! It is called downstream resume event.
+//! @{
+#define uhd_send_resume()                            (Set_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESUME))
+#define Is_uhd_sending_resume()                      (Tst_bits(UOTGHS->UOTGHS_HSTCTRL, UOTGHS_HSTCTRL_RESUME))
+
+#define uhd_enable_downstream_resume_interrupt()     (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_RSMEDIES)
+#define uhd_disable_downstream_resume_interrupt()    (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_RSMEDIEC)
+#define Is_uhd_downstream_resume_interrupt_enabled() (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_RSMEDIE))
+#define uhd_ack_downstream_resume()                  (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_RSMEDIC)
+#define Is_uhd_downstream_resume()                   (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_RSMEDI))
+//! @}
+
+//! Detection of a wake-up event
+//! A wake-up event is received when the host controller is in the suspend mode:
+//! - and an upstream resume from the peripheral is detected.
+//! - and a peripheral disconnection is detected.
+//! @{
+#define uhd_enable_wakeup_interrupt()                (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_HWUPIES)
+#define uhd_disable_wakeup_interrupt()               (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_HWUPIEC)
+#define Is_uhd_wakeup_interrupt_enabled()            (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_HWUPIE))
+#define uhd_ack_wakeup()                             (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_HWUPIC)
+#define Is_uhd_wakeup()                              (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_HWUPI))
+
+#define uhd_enable_upstream_resume_interrupt()       (UOTGHS->UOTGHS_HSTIER = UOTGHS_HSTIER_RXRSMIES)
+#define uhd_disable_upstream_resume_interrupt()      (UOTGHS->UOTGHS_HSTIDR = UOTGHS_HSTIDR_RXRSMIEC)
+#define Is_uhd_upstream_resume_interrupt_enabled()   (Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_RXRSMIE))
+#define uhd_ack_upstream_resume()                    (UOTGHS->UOTGHS_HSTICR = UOTGHS_HSTICR_RXRSMIC)
+#define Is_uhd_upstream_resume()                     (Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_RXRSMI))
+//! @}
+//! @}
+
+
+//! @name Pipes management
+//! @{
+
+//! USB address of pipes
+//! @{
+#define uhd_configure_address(p, addr) \
+		(Wr_bitfield((&UOTGHS->UOTGHS_HSTADDR1)[(p)>>2], \
+		UOTGHS_HSTADDR1_HSTADDRP0_Msk << (((p)&0x03)<<3), addr))
+#define uhd_get_configured_address(p) \
+		(Rd_bitfield((&UOTGHS->UOTGHS_HSTADDR1)[(p)>>2], \
+		UOTGHS_HSTADDR1_HSTADDRP0_Msk << (((p)&0x03)<<3)))
+//! @}
+
+//! Pipe enable
+//! Enable, disable, reset, freeze
+//! @{
+#define uhd_enable_pipe(p) \
+		(Set_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p)))
+#define uhd_disable_pipe(p) \
+		(Clr_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p)))
+#define Is_uhd_pipe_enabled(p) \
+		(Tst_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p)))
+#define uhd_reset_pipe(p) \
+		(Set_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p))); \
+		(Clr_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p)))
+#define Is_uhd_resetting_pipe(p) \
+		(Tst_bits(UOTGHS->UOTGHS_HSTPIP, UOTGHS_HSTPIP_PEN0 << (p)))
+#define uhd_freeze_pipe(p)                       (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_PFREEZES)
+#define uhd_unfreeze_pipe(p)                     (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_PFREEZEC)
+#define Is_uhd_pipe_frozen(p)                    (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_PFREEZE))
+#define uhd_reset_data_toggle(p)                 (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_RSTDTS)
+#define Is_uhd_data_toggle_reset(p)              (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_RSTDT))
+//! @}
+
+//! Pipe configuration
+//! @{
+#define uhd_configure_pipe_int_req_freq(p,freq)  (Wr_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_INTFRQ_Msk, (freq)))
+#define uhd_get_pipe_int_req_freq(p)             (Rd_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_INTFRQ_Msk))
+#define uhd_configure_pipe_endpoint_number(p,ep) (Wr_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PEPNUM_Msk, (ep)))
+#define uhd_get_pipe_endpoint_address(p) \
+		(uhd_is_pipe_in(p) ?\
+			(uhd_get_pipe_endpoint_number(p) | USB_EP_DIR_IN) :\
+			(uhd_get_pipe_endpoint_number(p) | USB_EP_DIR_OUT))
+#define uhd_get_pipe_endpoint_number(p)          (Rd_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], (UOTGHS_HSTPIPCFG_PEPNUM_Msk)))
+#define uhd_configure_pipe_type(p, type)         (Wr_bitfield(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTYPE_Msk, type))
+#define uhd_get_pipe_type(p)                     (Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTYPE_Msk))
+#define uhd_enable_pipe_bank_autoswitch(p)       (Set_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_AUTOSW))
+#define uhd_disable_pipe_bank_autoswitch(p)      (Clr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_AUTOSW))
+#define Is_uhd_pipe_bank_autoswitch_enabled(p)   (Tst_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_AUTOSW))
+#define uhd_configure_pipe_token(p, token)       (Wr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTOKEN_Msk, token))
+#define uhd_get_pipe_token(p)                    (Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PTOKEN_Msk))
+#define uhd_is_pipe_in(p)                        (UOTGHS_HSTPIPCFG_PTOKEN_IN==uhd_get_pipe_token(p))
+#define uhd_is_pipe_out(p)                       (UOTGHS_HSTPIPCFG_PTOKEN_OUT==uhd_get_pipe_token(p))
+//! Bounds given integer size to allowed range and rounds it up to the nearest
+//! available greater size, then applies register format of UOTGHS controller
+//! for pipe size bit-field.
+#define uhd_format_pipe_size(size) \
+		(32 - clz(((uint32_t)min(max(size, 8), 1024) << 1) - 1) - 1 - 3)
+#define uhd_configure_pipe_size(p,size) \
+		(Wr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PSIZE_Msk, uhd_format_pipe_size(size)))
+#define uhd_get_pipe_size(p)                     (8<<((Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], (UOTGHS_HSTPIPCFG_PSIZE_Msk)))>> UOTGHS_HSTPIPCFG_PSIZE_Pos))
+#define uhd_configure_pipe_bank(p,bank)          (Wr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PBK_Msk, (bank)))
+#define uhd_get_pipe_bank(p)                     (Rd_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PBK_Msk))
+#define uhd_allocate_memory(p)                   (Set_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_ALLOC))
+#define uhd_unallocate_memory(p)                 (Clr_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_ALLOC))
+#define Is_uhd_memory_allocated(p)               (Tst_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_ALLOC))
+
+//! Enable PING management only available in HS mode
+#  define uhd_enable_ping(p)                     (Set_bits(UOTGHS->UOTGHS_HSTPIPCFG[p], UOTGHS_HSTPIPCFG_PINGEN))
+//#endif
+#define uhd_configure_pipe(p, freq, ep_num, type, token, size, bank, bank_switch) \
+	(UOTGHS->UOTGHS_HSTPIPCFG[p] = \
+		(bank)|\
+		((uhd_format_pipe_size(size)<<UOTGHS_HSTPIPCFG_PSIZE_Pos)&UOTGHS_HSTPIPCFG_PSIZE_Msk)|\
+		((token)&UOTGHS_HSTPIPCFG_PTOKEN_Msk)|\
+		((type)&UOTGHS_HSTPIPCFG_PTYPE_Msk)|\
+		(((ep_num)<<UOTGHS_HSTPIPCFG_PEPNUM_Pos)&UOTGHS_HSTPIPCFG_PEPNUM_Msk)|\
+		bank_switch |\
+		(((freq)<<UOTGHS_HSTPIPCFG_INTFRQ_Pos)&UOTGHS_HSTPIPCFG_INTFRQ_Msk))
+
+#define Is_uhd_pipe_configured(p)                (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_CFGOK))
+//! @}
+
+//! Pipe main interrupts management
+//! @{
+#define uhd_enable_pipe_interrupt(p) 		(UOTGHS->UOTGHS_HSTIER = (UOTGHS_HSTIER_PEP_0 << (p)))
+#define uhd_disable_pipe_interrupt(p) 		(UOTGHS->UOTGHS_HSTIDR = (UOTGHS_HSTIDR_PEP_0 << (p)))
+#define Is_uhd_pipe_interrupt_enabled(p) 	(Tst_bits(UOTGHS->UOTGHS_HSTIMR, UOTGHS_HSTIMR_PEP_0 << (p)))
+#define Is_uhd_pipe_interrupt(p) 		(Tst_bits(UOTGHS->UOTGHS_HSTISR, UOTGHS_HSTISR_PEP_0 << (p)))
+//! returns the lowest pipe number generating a pipe interrupt or UOTGHS_EPT_NUM if none
+#define uhd_get_interrupt_pipe_number() \
+	(ctz(((UOTGHS->UOTGHS_HSTISR >> 8) & (UOTGHS->UOTGHS_HSTIMR >> 8)) | (1 << UOTGHS_EPT_NUM)))
+//! @}
+
+//! Pipe overflow and underflow for isochronous and interrupt endpoints
+//! @{
+#define uhd_enable_overflow_interrupt(p)         (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_OVERFIES)
+#define uhd_disable_overflow_interrupt(p)        (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_OVERFIEC)
+#define Is_uhd_overflow_interrupt_enabled(p)     (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_OVERFIE))
+#define uhd_ack_overflow_interrupt(p)            (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_OVERFIC)
+#define Is_uhd_overflow(p)                       (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_OVERFI))
+
+#define uhd_enable_underflow_interrupt(p)        (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_UNDERFIES)
+#define uhd_disable_underflow_interrupt(p)       (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_UNDERFIEC)
+#define Is_uhd_underflow_interrupt_enabled(p)    (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_UNDERFIE))
+#define uhd_ack_underflow_interrupt(p)           (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_UNDERFIC)
+#define Is_uhd_underflow(p)                      (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_UNDERFI))
+//! @}
+
+//! USB packet errors management
+//! @{
+#define uhd_enable_stall_interrupt(p)            (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_RXSTALLDES)
+#define uhd_disable_stall_interrupt(p)           (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_RXSTALLDEC)
+#define Is_uhd_stall_interrupt_enabled(p)        (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_RXSTALLDE))
+#define uhd_ack_stall(p)                         (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_RXSTALLDIC)
+#define Is_uhd_stall(p)                          (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RXSTALLDI))
+
+#define uhd_enable_pipe_error_interrupt(p)       (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_PERRES)
+#define uhd_disable_pipe_error_interrupt(p)      (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_PERREC)
+#define Is_uhd_pipe_error_interrupt_enabled(p)   (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_PERRE))
+#define uhd_ack_all_errors(p)                    (UOTGHS->UOTGHS_HSTPIPERR[p] = 0UL)
+#define Is_uhd_pipe_error(p)                     (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_PERRI))
+#define uhd_error_status(p)                      (UOTGHS->UOTGHS_HSTPIPERR[p])
+#define Is_uhd_bad_data_toggle(p)                (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_DATATGL))
+#define Is_uhd_data_pid_error(p)                 (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_DATAPID))
+#define Is_uhd_pid_error(p)                      (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_PID))
+#define Is_uhd_timeout_error(p)                  (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_TIMEOUT))
+#define Is_uhd_crc16_error(p)                    (Tst_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_CRC16))
+#define uhd_get_error_counter(p)                 (Rd_bits(UOTGHS->UOTGHS_HSTPIPERR[p], UOTGHS_HSTPIPERR_COUNTER))
+//! @}
+
+//! Pipe data management
+//! @{
+#define uhd_data_toggle(p)                       (Rd_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_DTSEQ))
+
+#define uhd_enable_bank_interrupt(p)             (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_NBUSYBKES)
+#define uhd_disable_bank_interrupt(p)            (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_NBUSYBKEC)
+#define Is_uhd_bank_interrupt_enabled(p)         (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_NBUSYBKE))
+#define uhd_nb_busy_bank(p)                      (Rd_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_NBUSYBK_Msk))
+#define uhd_current_bank(p)                      (Rd_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_CURRBK_Msk ))
+
+#define uhd_enable_short_packet_interrupt(p)     (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_SHORTPACKETES)
+#define uhd_disable_short_packet_interrupt(p)    (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_SHORTPACKETIEC)
+#define Is_uhd_short_packet_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_SHORTPACKETIE))  )
+#define uhd_ack_short_packet(p)                  (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_SHORTPACKETIC)
+#define Is_uhd_short_packet(p)                   (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_SHORTPACKETI))
+#define uhd_byte_count(p)                        (Rd_bitfield(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_PBYCT_Msk))
+
+#define Is_uhd_fifocon(p)                        (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_FIFOCON))
+#define uhd_ack_fifocon(p)                       (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_FIFOCONC)
+
+#define uhd_enable_setup_ready_interrupt(p)      (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_TXSTPES)
+#define uhd_disable_setup_ready_interrupt(p)     (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_TXSTPEC)
+#define Is_uhd_setup_ready_interrupt_enabled(p)  (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_TXSTPE))
+#define uhd_ack_setup_ready(p)                   (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_TXSTPIC)
+#define Is_uhd_setup_ready(p)                    (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_TXSTPI))
+
+#define uhd_enable_in_received_interrupt(p)      (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_RXINES)
+#define uhd_disable_in_received_interrupt(p)     (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_RXINEC)
+#define Is_uhd_in_received_interrupt_enabled(p)  (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_RXINE))
+#define uhd_ack_in_received(p)                   (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_RXINIC)
+#define Is_uhd_in_received(p)                    (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RXINI))
+
+#define uhd_enable_out_ready_interrupt(p)        (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_TXOUTES)
+#define uhd_disable_out_ready_interrupt(p)       (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_TXOUTEC)
+#define Is_uhd_out_ready_interrupt_enabled(p)    (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_TXOUTE))
+#define uhd_ack_out_ready(p)                     (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_TXOUTIC)
+#define Is_uhd_out_ready(p)                      (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_TXOUTI))
+#define uhd_raise_out_ready(p)                   (UOTGHS->UOTGHS_HSTPIPIFR[p] = UOTGHS_HSTPIPIFR_TXOUTIS)
+
+#define uhd_enable_nak_received_interrupt(p)     (UOTGHS->UOTGHS_HSTPIPIER[p] = UOTGHS_HSTPIPIER_NAKEDES)
+#define uhd_disable_nak_received_interrupt(p)    (UOTGHS->UOTGHS_HSTPIPIDR[p] = UOTGHS_HSTPIPIDR_NAKEDEC)
+#define Is_uhd_nak_received_interrupt_enabled(p) (Tst_bits(UOTGHS->UOTGHS_HSTPIPIMR[p], UOTGHS_HSTPIPIMR_NAKEDE))
+#define uhd_ack_nak_received(p)                  (UOTGHS->UOTGHS_HSTPIPICR[p] = UOTGHS_HSTPIPICR_NAKEDIC)
+#define Is_uhd_nak_received(p)                   (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_NAKEDI))
+
+#define Is_uhd_read_enabled(p)                   (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RWALL))
+#define Is_uhd_write_enabled(p)                  (Tst_bits(UOTGHS->UOTGHS_HSTPIPISR[p], UOTGHS_HSTPIPISR_RWALL ))
+
+#define uhd_enable_continuous_in_mode(p)         (Set_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INMODE))
+#define uhd_disable_continuous_in_mode(p)        (Clr_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INMODE))
+#define Is_uhd_continuous_in_mode_enabled(p)     (Tst_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INMODE))
+
+#define uhd_in_request_number(p, in_num)         (Set_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], (in_num)-1))
+#define uhd_get_in_request_number(p)             (((Rd_bits(UOTGHS->UOTGHS_HSTPIPINRQ[p], UOTGHS_HSTPIPINRQ_INRQ_Msk))>>UOTGHS_HSTPIPINRQ_INRQ_Pos)+1)
+//! @}
+
+//! Maximum transfer size on USB DMA
+#define UHD_PIPE_MAX_TRANS 0x8000
+
+//! Get 64-, 32-, 16- or 8-bit access to FIFO data register of selected pipe.
+//! @param p      Target Pipe number
+//! @param scale  Data scale in bits: 64, 32, 16 or 8
+//! @return       Volatile 64-, 32-, 16- or 8-bit data pointer to FIFO data register
+//! @warning It is up to the user of this macro to make sure that all accesses
+//! are aligned with their natural boundaries except 64-bit accesses which
+//! require only 32-bit alignment.
+//! @warning It is up to the user of this macro to make sure that used HSB
+//! addresses are identical to the DPRAM internal pointer modulo 32 bits.
+#define uhd_get_pipe_fifo_access(p, scale) \
+	(((volatile TPASTE2(U, scale) (*)[UHD_PIPE_MAX_TRANS / ((scale) / 8)])UOTGHS_RAM_ADDR)[(p)])
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UOTGHS_HOST_H_INCLUDED */
diff --git a/cores/arduino/validation_usb_device/build_as6/test.atsln b/cores/arduino/validation_usb_device/build_as6/test.atsln
new file mode 100644
index 00000000..749e8031
--- /dev/null
+++ b/cores/arduino/validation_usb_device/build_as6/test.atsln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Atmel Studio Solution File, Format Version 11.00
+Project("{E66E83B9-2572-4076-B26E-6BE79FF3018A}") = "test", "test.cppproj", "{B3F859AD-E162-4C2F-9684-EAC6932FEC80}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|ARM = Debug|ARM
+		Release|ARM = Release|ARM
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{B3F859AD-E162-4C2F-9684-EAC6932FEC80}.Debug|ARM.ActiveCfg = Debug|ARM
+		{B3F859AD-E162-4C2F-9684-EAC6932FEC80}.Debug|ARM.Build.0 = Debug|ARM
+		{B3F859AD-E162-4C2F-9684-EAC6932FEC80}.Release|ARM.ActiveCfg = Release|ARM
+		{B3F859AD-E162-4C2F-9684-EAC6932FEC80}.Release|ARM.Build.0 = Release|ARM
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/cores/arduino/validation_usb_device/build_as6/test.atsuo b/cores/arduino/validation_usb_device/build_as6/test.atsuo
new file mode 100644
index 0000000000000000000000000000000000000000..16114ce77c4ab38e10352482fd18769e67ea3cec
GIT binary patch
literal 39424
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

literal 0
HcmV?d00001

diff --git a/cores/arduino/validation_usb_device/build_as6/test.cppproj b/cores/arduino/validation_usb_device/build_as6/test.cppproj
new file mode 100644
index 00000000..75f3f8f4
--- /dev/null
+++ b/cores/arduino/validation_usb_device/build_as6/test.cppproj
@@ -0,0 +1,498 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectVersion>6.2</ProjectVersion>
+    <ToolchainName>com.Atmel.ARMGCC.CPP</ToolchainName>
+    <ProjectGuid>{b3f859ad-e162-4c2f-9684-eac6932fec80}</ProjectGuid>
+    <avrdevice>ATSAMD21G18A</avrdevice>
+    <avrdeviceseries>none</avrdeviceseries>
+    <OutputType>Executable</OutputType>
+    <Language>CPP</Language>
+    <OutputFileName>$(MSBuildProjectName)</OutputFileName>
+    <OutputFileExtension>.elf</OutputFileExtension>
+    <OutputDirectory>$(MSBuildProjectDirectory)\$(Configuration)</OutputDirectory>
+    <AssemblyName>test</AssemblyName>
+    <Name>test</Name>
+    <RootNamespace>test</RootNamespace>
+    <ToolchainFlavour>Native</ToolchainFlavour>
+    <KeepTimersRunning>true</KeepTimersRunning>
+    <OverrideVtor>false</OverrideVtor>
+    <CacheFlash>false</CacheFlash>
+    <ProgFlashFromRam>true</ProgFlashFromRam>
+    <RamSnippetAddress>0x20000000</RamSnippetAddress>
+    <UncachedRange />
+    <OverrideVtorValue>exception_table</OverrideVtorValue>
+    <BootSegment>2</BootSegment>
+    <eraseonlaunchrule>1</eraseonlaunchrule>
+    <AsfFrameworkConfig>
+      <framework-data xmlns="">
+        <options />
+        <configurations />
+        <files />
+        <documentation help="" />
+        <offline-documentation help="" />
+        <dependencies>
+          <content-extension eid="atmel.asf" uuidref="Atmel.ASF" version="3.17.0" />
+        </dependencies>
+      </framework-data>
+    </AsfFrameworkConfig>
+    <avrtool>com.atmel.avrdbg.tool.edbg</avrtool>
+    <avrtoolinterface>SWD</avrtoolinterface>
+    <com_atmel_avrdbg_tool_samice>
+      <ToolOptions>
+        <InterfaceProperties>
+        </InterfaceProperties>
+        <InterfaceName>SWD</InterfaceName>
+      </ToolOptions>
+      <ToolType>com.atmel.avrdbg.tool.samice</ToolType>
+      <ToolNumber>28001042</ToolNumber>
+      <ToolName>SAM-ICE</ToolName>
+    </com_atmel_avrdbg_tool_samice>
+    <UseGdb>True</UseGdb>
+    <com_atmel_avrdbg_tool_edbg>
+      <ToolOptions>
+        <InterfaceProperties>
+          <SwdClock>4000000</SwdClock>
+        </InterfaceProperties>
+        <InterfaceName>SWD</InterfaceName>
+      </ToolOptions>
+      <ToolType>com.atmel.avrdbg.tool.edbg</ToolType>
+      <ToolNumber>ATML2320021800000003</ToolNumber>
+      <ToolName>EDBG</ToolName>
+    </com_atmel_avrdbg_tool_edbg>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+    <ToolchainSettings>
+      <ArmGccCpp>
+        <armgcc.common.outputfiles.hex>True</armgcc.common.outputfiles.hex>
+        <armgcc.common.outputfiles.lss>True</armgcc.common.outputfiles.lss>
+        <armgcc.common.outputfiles.eep>True</armgcc.common.outputfiles.eep>
+        <armgcc.common.outputfiles.bin>True</armgcc.common.outputfiles.bin>
+        <armgcc.common.outputfiles.srec>True</armgcc.common.outputfiles.srec>
+        <armgcc.compiler.symbols.DefSymbols>
+          <ListValues>
+            <Value>NDEBUG</Value>
+          </ListValues>
+        </armgcc.compiler.symbols.DefSymbols>
+        <armgcc.compiler.directories.IncludePaths>
+          <ListValues>
+            <Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value>
+            <Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value>
+            <Value>../../..</Value>
+            <Value>../../../USB</Value>
+            <Value>../../../../../variants/arduino_zero</Value>
+          </ListValues>
+        </armgcc.compiler.directories.IncludePaths>
+        <armgcc.compiler.optimization.level>Optimize for size (-Os)</armgcc.compiler.optimization.level>
+        <armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>
+        <armgcc.compiler.warnings.AllWarnings>True</armgcc.compiler.warnings.AllWarnings>
+        <armgcccpp.compiler.symbols.DefSymbols>
+          <ListValues>
+            <Value>NDEBUG</Value>
+          </ListValues>
+        </armgcccpp.compiler.symbols.DefSymbols>
+        <armgcccpp.compiler.directories.IncludePaths>
+          <ListValues>
+            <Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value>
+            <Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value>
+            <Value>../../..</Value>
+            <Value>../../../USB</Value>
+            <Value>../../../../../variants/arduino_zero</Value>
+          </ListValues>
+        </armgcccpp.compiler.directories.IncludePaths>
+        <armgcccpp.compiler.optimization.level>Optimize for size (-Os)</armgcccpp.compiler.optimization.level>
+        <armgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>
+        <armgcccpp.compiler.warnings.AllWarnings>True</armgcccpp.compiler.warnings.AllWarnings>
+        <armgcccpp.linker.libraries.Libraries>
+          <ListValues>
+            <Value>libm</Value>
+          </ListValues>
+        </armgcccpp.linker.libraries.Libraries>
+        <armgcccpp.linker.libraries.LibrarySearchPaths>
+          <ListValues>
+            <Value>../cmsis/linkerScripts</Value>
+          </ListValues>
+        </armgcccpp.linker.libraries.LibrarySearchPaths>
+        <armgcccpp.linker.optimization.GarbageCollectUnusedSections>True</armgcccpp.linker.optimization.GarbageCollectUnusedSections>
+        <armgcccpp.linker.miscellaneous.LinkerFlags>-Tsamd21g18a_flash.ld</armgcccpp.linker.miscellaneous.LinkerFlags>
+        <armgcccpp.preprocessingassembler.general.IncludePaths>
+          <ListValues>
+            <Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value>
+            <Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value>
+            <Value>../../..</Value>
+            <Value>../../../USB</Value>
+            <Value>../../../../../variants/arduino_zero</Value>
+          </ListValues>
+        </armgcccpp.preprocessingassembler.general.IncludePaths>
+      </ArmGccCpp>
+    </ToolchainSettings>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+    <ToolchainSettings>
+      <ArmGccCpp>
+        <armgcc.common.outputfiles.hex>True</armgcc.common.outputfiles.hex>
+        <armgcc.common.outputfiles.lss>True</armgcc.common.outputfiles.lss>
+        <armgcc.common.outputfiles.eep>True</armgcc.common.outputfiles.eep>
+        <armgcc.common.outputfiles.bin>True</armgcc.common.outputfiles.bin>
+        <armgcc.common.outputfiles.srec>True</armgcc.common.outputfiles.srec>
+        <armgcc.compiler.general.ChangeDefaultCharTypeUnsigned>True</armgcc.compiler.general.ChangeDefaultCharTypeUnsigned>
+        <armgcc.compiler.symbols.DefSymbols>
+          <ListValues>
+            <Value>DEBUG</Value>
+          </ListValues>
+        </armgcc.compiler.symbols.DefSymbols>
+        <armgcc.compiler.directories.DefaultIncludePath>False</armgcc.compiler.directories.DefaultIncludePath>
+        <armgcc.compiler.directories.IncludePaths>
+          <ListValues>
+            <Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value>
+            <Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value>
+            <Value>../../..</Value>
+            <Value>../../../USB</Value>
+            <Value>../../../../../variants/arduino_zero</Value>
+          </ListValues>
+        </armgcc.compiler.directories.IncludePaths>
+        <armgcc.compiler.optimization.level>Optimize (-O1)</armgcc.compiler.optimization.level>
+        <armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcc.compiler.optimization.PrepareFunctionsForGarbageCollection>
+        <armgcc.compiler.optimization.PrepareDataForGarbageCollection>True</armgcc.compiler.optimization.PrepareDataForGarbageCollection>
+        <armgcc.compiler.optimization.DebugLevel>Maximum (-g3)</armgcc.compiler.optimization.DebugLevel>
+        <armgcc.compiler.warnings.AllWarnings>True</armgcc.compiler.warnings.AllWarnings>
+        <armgcc.compiler.miscellaneous.OtherFlags>-std=c99</armgcc.compiler.miscellaneous.OtherFlags>
+        <armgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>True</armgcccpp.compiler.general.ChangeDefaultCharTypeUnsigned>
+        <armgcccpp.compiler.symbols.DefSymbols>
+          <ListValues>
+            <Value>DEBUG</Value>
+            <Value>USB_VID=0x2341</Value>
+            <Value>USB_PID=0x004d</Value>
+          </ListValues>
+        </armgcccpp.compiler.symbols.DefSymbols>
+        <armgcccpp.compiler.directories.DefaultIncludePath>False</armgcccpp.compiler.directories.DefaultIncludePath>
+        <armgcccpp.compiler.directories.IncludePaths>
+          <ListValues>
+            <Value>../../../../../../../tools/CMSIS/Device/ATMEL</Value>
+            <Value>../../../../../../../tools/CMSIS/CMSIS/Include</Value>
+            <Value>../../..</Value>
+            <Value>../../../USB</Value>
+            <Value>../../../../../variants/arduino_zero</Value>
+          </ListValues>
+        </armgcccpp.compiler.directories.IncludePaths>
+        <armgcccpp.compiler.optimization.level>Optimize (-O1)</armgcccpp.compiler.optimization.level>
+        <armgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>True</armgcccpp.compiler.optimization.PrepareFunctionsForGarbageCollection>
+        <armgcccpp.compiler.optimization.PrepareDataForGarbageCollection>True</armgcccpp.compiler.optimization.PrepareDataForGarbageCollection>
+        <armgcccpp.compiler.optimization.DebugLevel>Maximum (-g3)</armgcccpp.compiler.optimization.DebugLevel>
+        <armgcccpp.compiler.warnings.AllWarnings>True</armgcccpp.compiler.warnings.AllWarnings>
+        <armgcccpp.compiler.miscellaneous.OtherFlags>-std=c++98</armgcccpp.compiler.miscellaneous.OtherFlags>
+        <armgcccpp.linker.general.UseNewlibNano>True</armgcccpp.linker.general.UseNewlibNano>
+        <armgcccpp.linker.libraries.Libraries>
+          <ListValues>
+            <Value>libm</Value>
+          </ListValues>
+        </armgcccpp.linker.libraries.Libraries>
+        <armgcccpp.linker.libraries.LibrarySearchPaths>
+          <ListValues>
+            <Value>../../../../../variants/arduino_zero/linker_scripts/gcc</Value>
+          </ListValues>
+        </armgcccpp.linker.libraries.LibrarySearchPaths>
+        <armgcccpp.linker.optimization.GarbageCollectUnusedSections>True</armgcccpp.linker.optimization.GarbageCollectUnusedSections>
+        <armgcccpp.linker.memorysettings.ExternalRAM />
+        <armgcccpp.linker.miscellaneous.LinkerFlags>-Tflash.ld</armgcccpp.linker.miscellaneous.LinkerFlags>
+        <armgcccpp.assembler.general.IncludePaths>
+          <ListValues>
+            <Value>../../..</Value>
+          </ListValues>
+        </armgcccpp.assembler.general.IncludePaths>
+        <armgcccpp.assembler.debugging.DebugLevel>Default (-g)</armgcccpp.assembler.debugging.DebugLevel>
+        <armgcccpp.preprocessingassembler.general.DefaultIncludePath>False</armgcccpp.preprocessingassembler.general.DefaultIncludePath>
+        <armgcccpp.preprocessingassembler.general.IncludePaths>
+          <ListValues>
+            <Value>../../..</Value>
+          </ListValues>
+        </armgcccpp.preprocessingassembler.general.IncludePaths>
+        <armgcccpp.preprocessingassembler.debugging.DebugLevel>Default (-Wa,-g)</armgcccpp.preprocessingassembler.debugging.DebugLevel>
+      </ArmGccCpp>
+    </ToolchainSettings>
+  </PropertyGroup>
+  <ItemGroup>
+    <Folder Include="core" />
+    <Folder Include="core\validation_usb_device" />
+    <Folder Include="core\USB" />
+    <Folder Include="variant" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\..\..\..\variants\arduino_zero\pins_arduino.h">
+      <SubType>compile</SubType>
+      <Link>variant\pins_arduino.h</Link>
+    </Compile>
+    <Compile Include="..\..\..\..\variants\arduino_zero\variant.cpp">
+      <SubType>compile</SubType>
+      <Link>variant\variant.cpp</Link>
+    </Compile>
+    <Compile Include="..\..\..\..\variants\arduino_zero\variant.h">
+      <SubType>compile</SubType>
+      <Link>variant\variant.h</Link>
+    </Compile>
+    <Compile Include="..\..\Arduino.h">
+      <SubType>compile</SubType>
+      <Link>core\Arduino.h</Link>
+    </Compile>
+    <Compile Include="..\..\binary.h">
+      <SubType>compile</SubType>
+      <Link>core\binary.h</Link>
+    </Compile>
+    <Compile Include="..\..\Client.h">
+      <SubType>compile</SubType>
+      <Link>core\Client.h</Link>
+    </Compile>
+    <Compile Include="..\..\delay.c">
+      <SubType>compile</SubType>
+      <Link>core\delay.c</Link>
+    </Compile>
+    <Compile Include="..\..\delay.h">
+      <SubType>compile</SubType>
+      <Link>core\delay.h</Link>
+    </Compile>
+    <Compile Include="..\..\HardwareSerial.h">
+      <SubType>compile</SubType>
+      <Link>core\HardwareSerial.h</Link>
+    </Compile>
+    <Compile Include="..\..\hooks.c">
+      <SubType>compile</SubType>
+      <Link>core\hooks.c</Link>
+    </Compile>
+    <Compile Include="..\..\IPAddress.cpp">
+      <SubType>compile</SubType>
+      <Link>core\IPAddress.cpp</Link>
+    </Compile>
+    <Compile Include="..\..\IPAddress.h">
+      <SubType>compile</SubType>
+      <Link>core\IPAddress.h</Link>
+    </Compile>
+    <Compile Include="..\..\itoa.c">
+      <SubType>compile</SubType>
+      <Link>core\itoa.c</Link>
+    </Compile>
+    <Compile Include="..\..\itoa.h">
+      <SubType>compile</SubType>
+      <Link>core\itoa.h</Link>
+    </Compile>
+    <Compile Include="..\..\Print.cpp">
+      <SubType>compile</SubType>
+      <Link>core\Print.cpp</Link>
+    </Compile>
+    <Compile Include="..\..\Print.h">
+      <SubType>compile</SubType>
+      <Link>core\Print.h</Link>
+    </Compile>
+    <Compile Include="..\..\Printable.h">
+      <SubType>compile</SubType>
+      <Link>core\Printable.h</Link>
+    </Compile>
+    <Compile Include="..\..\Reset.cpp">
+      <SubType>compile</SubType>
+      <Link>core\Reset.cpp</Link>
+    </Compile>
+    <Compile Include="..\..\Reset.h">
+      <SubType>compile</SubType>
+      <Link>core\Reset.h</Link>
+    </Compile>
+    <Compile Include="..\..\RingBuffer.cpp">
+      <SubType>compile</SubType>
+      <Link>core\RingBuffer.cpp</Link>
+    </Compile>
+    <Compile Include="..\..\RingBuffer.h">
+      <SubType>compile</SubType>
+      <Link>core\RingBuffer.h</Link>
+    </Compile>
+    <Compile Include="..\..\SERCOM.cpp">
+      <SubType>compile</SubType>
+      <Link>core\SERCOM.cpp</Link>
+    </Compile>
+    <Compile Include="..\..\SERCOM.h">
+      <SubType>compile</SubType>
+      <Link>core\SERCOM.h</Link>
+    </Compile>
+    <Compile Include="..\..\Server.h">
+      <SubType>compile</SubType>
+      <Link>core\Server.h</Link>
+    </Compile>
+    <Compile Include="..\..\startup.c">
+      <SubType>compile</SubType>
+      <Link>core\startup.c</Link>
+    </Compile>
+    <Compile Include="..\..\Stream.cpp">
+      <SubType>compile</SubType>
+      <Link>core\Stream.cpp</Link>
+    </Compile>
+    <Compile Include="..\..\Stream.h">
+      <SubType>compile</SubType>
+      <Link>core\Stream.h</Link>
+    </Compile>
+    <Compile Include="..\..\syscalls.c">
+      <SubType>compile</SubType>
+      <Link>core\syscalls.c</Link>
+    </Compile>
+    <Compile Include="..\..\syscalls.h">
+      <SubType>compile</SubType>
+      <Link>core\syscalls.h</Link>
+    </Compile>
+    <Compile Include="..\..\Tone.h">
+      <SubType>compile</SubType>
+      <Link>core\Tone.h</Link>
+    </Compile>
+    <Compile Include="..\..\Udp.h">
+      <SubType>compile</SubType>
+      <Link>core\Udp.h</Link>
+    </Compile>
+    <Compile Include="..\..\WCharacter.h">
+      <SubType>compile</SubType>
+      <Link>core\WCharacter.h</Link>
+    </Compile>
+    <Compile Include="..\..\WInterrupts.h">
+      <SubType>compile</SubType>
+      <Link>core\WInterrupts.h</Link>
+    </Compile>
+    <Compile Include="..\..\wiring.c">
+      <SubType>compile</SubType>
+      <Link>core\wiring.c</Link>
+    </Compile>
+    <Compile Include="..\..\wiring.h">
+      <SubType>compile</SubType>
+      <Link>core\wiring.h</Link>
+    </Compile>
+    <Compile Include="..\..\wiring_analog.h">
+      <SubType>compile</SubType>
+      <Link>core\wiring_analog.h</Link>
+    </Compile>
+    <Compile Include="..\..\wiring_constants.h">
+      <SubType>compile</SubType>
+      <Link>core\wiring_constants.h</Link>
+    </Compile>
+    <Compile Include="..\..\wiring_digital.c">
+      <SubType>compile</SubType>
+      <Link>core\wiring_digital.c</Link>
+    </Compile>
+    <Compile Include="..\..\wiring_digital.h">
+      <SubType>compile</SubType>
+      <Link>core\wiring_digital.h</Link>
+    </Compile>
+    <Compile Include="..\..\wiring_private.h">
+      <SubType>compile</SubType>
+      <Link>core\wiring_private.h</Link>
+    </Compile>
+    <Compile Include="..\..\wiring_pulse.h">
+      <SubType>compile</SubType>
+      <Link>core\wiring_pulse.h</Link>
+    </Compile>
+    <Compile Include="..\..\wiring_shift.c">
+      <SubType>compile</SubType>
+      <Link>core\wiring_shift.c</Link>
+    </Compile>
+    <Compile Include="..\..\wiring_shift.h">
+      <SubType>compile</SubType>
+      <Link>core\wiring_shift.h</Link>
+    </Compile>
+    <Compile Include="..\..\WMath.cpp">
+      <SubType>compile</SubType>
+      <Link>core\WMath.cpp</Link>
+    </Compile>
+    <Compile Include="..\..\WMath.h">
+      <SubType>compile</SubType>
+      <Link>core\WMath.h</Link>
+    </Compile>
+    <Compile Include="..\..\WString.cpp">
+      <SubType>compile</SubType>
+      <Link>core\WString.cpp</Link>
+    </Compile>
+    <Compile Include="..\..\WString.h">
+      <SubType>compile</SubType>
+      <Link>core\WString.h</Link>
+    </Compile>
+    <Compile Include="..\..\WVariant.h">
+      <SubType>compile</SubType>
+      <Link>core\WVariant.h</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\Uart.cpp">
+      <SubType>compile</SubType>
+      <Link>core\Uart.cpp</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\Uart.h">
+      <SubType>compile</SubType>
+      <Link>core\Uart.h</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\CDC.cpp">
+      <SubType>compile</SubType>
+      <Link>core\USB\CDC.cpp</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\HID.cpp">
+      <SubType>compile</SubType>
+      <Link>core\USB\HID.cpp</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\samd21_device.c">
+      <SubType>compile</SubType>
+      <Link>core\USB\samd21_device.c</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\samd21_device.h">
+      <SubType>compile</SubType>
+      <Link>core\USB\samd21_device.h</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\samd21_host.h">
+      <SubType>compile</SubType>
+      <Link>core\USB\samd21_host.h</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\USBAPI.h">
+      <SubType>compile</SubType>
+      <Link>core\USB\USBAPI.h</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\USBCore.cpp">
+      <SubType>compile</SubType>
+      <Link>core\USB\USBCore.cpp</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\USBCore.h">
+      <SubType>compile</SubType>
+      <Link>core\USB\USBCore.h</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\USBDesc.h">
+      <SubType>compile</SubType>
+      <Link>core\USB\USBDesc.h</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\USB_device.h">
+      <SubType>compile</SubType>
+      <Link>core\USB\USB_device.h</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\USB\USB_host.h">
+      <SubType>compile</SubType>
+      <Link>core\USB\USB_host.h</Link>
+    </Compile>
+    <Compile Include="C:\jcb\support\arduino\ArduinoZero\hardware\arduino\samd\cores\arduino\validation_usb_device\test_usb_device.cpp">
+      <SubType>compile</SubType>
+      <Link>core\validation_usb_device\test_usb_device.cpp</Link>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="..\..\HOWTO - compiling a project.txt">
+      <SubType>compile</SubType>
+      <Link>core\HOWTO - compiling a project.txt</Link>
+    </None>
+    <None Include="..\..\Tone.cpp.disabled">
+      <SubType>compile</SubType>
+      <Link>core\Tone.cpp.disabled</Link>
+    </None>
+    <None Include="..\..\WInterrupts.c.disabled">
+      <SubType>compile</SubType>
+      <Link>core\WInterrupts.c.disabled</Link>
+    </None>
+    <None Include="..\..\wiring_analog.c.disabled">
+      <SubType>compile</SubType>
+      <Link>core\wiring_analog.c.disabled</Link>
+    </None>
+    <None Include="..\..\wiring_digital.c.old">
+      <SubType>compile</SubType>
+      <Link>core\wiring_digital.c.old</Link>
+    </None>
+    <None Include="..\..\wiring_pulse.cpp.disabled">
+      <SubType>compile</SubType>
+      <Link>core\wiring_pulse.cpp.disabled</Link>
+    </None>
+  </ItemGroup>
+  <Import Project="$(AVRSTUDIO_EXE_PATH)\\Vs\\Compiler.targets" />
+</Project>
\ No newline at end of file
diff --git a/cores/arduino/validation_usb_device/build_gcc/Makefile b/cores/arduino/validation_usb_device/build_gcc/Makefile
index 3f88f26e..852324a9 100644
--- a/cores/arduino/validation_usb_device/build_gcc/Makefile
+++ b/cores/arduino/validation_usb_device/build_gcc/Makefile
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2011 Arduino.  All right reserved.
+#  Copyright (c) 2014 Arduino.  All right reserved.
 #
 #  This library is free software; you can redistribute it and/or
 #  modify it under the terms of the GNU Lesser General Public
@@ -16,26 +16,37 @@
 #  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #
 
-SUBMAKE_OPTIONS=--no-builtin-rules --no-builtin-variables
+SUBMAKE_OPTIONS=--no-builtin-rules --no-builtin-variables --no-print-directory
 
 #-------------------------------------------------------------------------------
 # Rules
 #-------------------------------------------------------------------------------
 
-all: test_usb_device
+all: clean test
+
+test: test_usb_device
+
+debug: debug_test_usb_device
+
+clean: clean_test_usb_device
 
 .PHONY: test_usb_device
-test:
+test_usb_device:
+	@echo ------------------------------------------------------------------------------------
 	@echo --- Making test_usb_device
-	@$(MAKE) DEBUG=1 $(SUBMAKE_OPTIONS) -f test_usb_device.mk
+	@$(MAKE) DEBUG=1 VARIANT=arduino_zero $(SUBMAKE_OPTIONS) -f test_usb_device.mk test
+	@echo ------------------------------------------------------------------------------------
 
 .PHONY: clean
-clean:
+clean_test_usb_device:
+	@echo ------------------------------------------------------------------------------------
 	@echo --- Cleaning test_usb_device
-	@$(MAKE) DEBUG=1 $(SUBMAKE_OPTIONS) -f test_usb_device.mk $@
+	@$(MAKE) DEBUG=1 VARIANT=arduino_zero $(SUBMAKE_OPTIONS) -f test_usb_device.mk clean
+	@echo ------------------------------------------------------------------------------------
 
 .PHONY: debug
-debug:
+debug_test_usb_device:
+	@echo ------------------------------------------------------------------------------------
 	@echo --- Debugging test_usb_device
-	@$(MAKE) DEBUG=1 $(SUBMAKE_OPTIONS) -f test_usb_device.mk $@
-
+	@$(MAKE) DEBUG=1 VARIANT=arduino_zero $(SUBMAKE_OPTIONS) -f test_usb_device.mk debug
+	@echo ------------------------------------------------------------------------------------
diff --git a/cores/arduino/validation_usb_device/build_gcc/debug.mk b/cores/arduino/validation_usb_device/build_gcc/debug.mk
index a3cc2337..17cd2107 100644
--- a/cores/arduino/validation_usb_device/build_gcc/debug.mk
+++ b/cores/arduino/validation_usb_device/build_gcc/debug.mk
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2011 Arduino.  All right reserved.
+#  Copyright (c) 2014 Arduino.  All right reserved.
 #
 #  This library is free software; you can redistribute it and/or
 #  modify it under the terms of the GNU Lesser General Public
@@ -8,7 +8,7 @@
 #
 #  This library 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.
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
 #  See the GNU Lesser General Public License for more details.
 #
 #  You should have received a copy of the GNU Lesser General Public
diff --git a/cores/arduino/validation_usb_device/build_gcc/gcc.mk b/cores/arduino/validation_usb_device/build_gcc/gcc.mk
index 36951b46..9b4f7b60 100644
--- a/cores/arduino/validation_usb_device/build_gcc/gcc.mk
+++ b/cores/arduino/validation_usb_device/build_gcc/gcc.mk
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2011 Arduino.  All right reserved.
+#  Copyright (c) 2014 Arduino.  All right reserved.
 #
 #  This library is free software; you can redistribute it and/or
 #  modify it under the terms of the GNU Lesser General Public
@@ -8,7 +8,7 @@
 #
 #  This library 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. 
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 #  See the GNU Lesser General Public License for more details.
 #
 #  You should have received a copy of the GNU Lesser General Public
@@ -16,26 +16,18 @@
 #  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #
 
-# Tool suffix when cross-compiling
-#CROSS_COMPILE = ../../../../tools/CodeSourcery_arm/bin/arm-none-eabi-
-#CROSS_COMPILE = C:/CodeSourcery_2011.03-42/bin/arm-none-eabi-
-CROSS_COMPILE = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-
-
 # Compilation tools
-AR = $(CROSS_COMPILE)ar
-CC = $(CROSS_COMPILE)gcc
-CXX = $(CROSS_COMPILE)g++
-AS = $(CROSS_COMPILE)as
-GDB = $(CROSS_COMPILE)gdb
-SIZE = $(CROSS_COMPILE)size
-NM = $(CROSS_COMPILE)nm
-OBJCOPY = $(CROSS_COMPILE)objcopy
-
-ifeq ($(OS),Windows_NT)
-RM=cs-rm -Rf
-else
+AR = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-ar
+CC = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-gcc
+#CXX = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-g++
+CXX = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-gcc
+AS = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-as
+GDB = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-gdb
+SIZE = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-size
+NM = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-nm
+OBJCOPY = $(ARM_GCC_TOOLCHAIN)/arm-none-eabi-objcopy
+
 RM=rm -Rf
-endif
 
 SEP=\\
 
@@ -54,12 +46,14 @@ CFLAGS += -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long
 CFLAGS += -Wunreachable-code
 CFLAGS += -Wcast-align
 
-CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections -nostdlib -std=c99
-CFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D$(VARIANT)
+CFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m0plus -mthumb -mlong-calls -ffunction-sections -nostdlib -std=c99
+CFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(DEVICE) -D$(VARIANT)
 
 # To reduce application size use only integer printf function.
 CFLAGS += -Dprintf=iprintf
 
+
+
 # ---------------------------------------------------------------------------------------
 # CPP Flags
 
@@ -73,13 +67,23 @@ CPPFLAGS += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations
 CPPFLAGS += -Wpacked -Wredundant-decls -Winline -Wlong-long
 
 #-fno-rtti -fno-exceptions
-CPPFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m3 -mthumb -mlong-calls -ffunction-sections -std=c++98
-CPPFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(CHIP)
+CPPFLAGS += --param max-inline-insns-single=500 -mcpu=cortex-m0plus -mthumb -mlong-calls -ffunction-sections -fdata-sections -std=c++98
+CPPFLAGS += $(OPTIMIZATION) $(INCLUDES) -D$(DEVICE) -D$(VARIANT)
 
 # To reduce application size use only integer printf function.
 CPPFLAGS += -Dprintf=iprintf
 
+
+
 # ---------------------------------------------------------------------------------------
 # ASM Flags
 
-ASFLAGS = -mcpu=cortex-m3 -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES)
+ASFLAGS = -mcpu=cortex-m0plus -mthumb -Wall -g $(OPTIMIZATION) $(INCLUDES)
+
+
+
+# ---------------------------------------------------------------------------------------
+# LD Flags
+
+LDFLAGS= -mcpu=cortex-m0plus -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols
+
diff --git a/cores/arduino/validation_usb_device/build_gcc/test_usb_device.mk b/cores/arduino/validation_usb_device/build_gcc/test_usb_device.mk
index 336bbc60..bbcf7978 100644
--- a/cores/arduino/validation_usb_device/build_gcc/test_usb_device.mk
+++ b/cores/arduino/validation_usb_device/build_gcc/test_usb_device.mk
@@ -1,5 +1,5 @@
 #
-#  Copyright (c) 2011 Arduino.  All right reserved.
+#  Copyright (c) 2014 Arduino.  All right reserved.
 #
 #  This library is free software; you can redistribute it and/or
 #  modify it under the terms of the GNU Lesser General Public
@@ -16,69 +16,44 @@
 #  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #
 
-# Makefile for compiling libArduino
-.SUFFIXES: .o .a .c .s
+# Makefile for compiling usb device
+.SUFFIXES: .o .a .c .cpp .s
 
 # putting default variant
 ifeq ("$(VARIANT)", "")
-#VARIANT=sam3s_ek
-#VARIANT=sam3u_ek
-VARIANT=arduino_due_x
+VARIANT=arduino_zero
 endif
 
-ifeq ("$(VARIANT)", "sam3s_ek")
-CHIP=__SAM3S4C__
-VARIANT_PATH = ../../../../atmel/sam/variants/$(VARIANT)
-else ifeq ("$(VARIANT)", "sam3u_ek")
-CHIP=__SAM3U4E__
-VARIANT_PATH = ../../../../atmel/sam/variants/$(VARIANT)
-else ifeq ("$(VARIANT)", "sam3x_ek")
-CHIP=__SAM3X8H__
-VARIANT_PATH = ../../../../atmel/sam/variants/$(VARIANT)
-else ifeq ("$(VARIANT)", "arduino_due_u")
-CHIP=__SAM3U4E__
-VARIANT_PATH = ../../../../variants/$(VARIANT)
-else ifeq ("$(VARIANT)", "arduino_due_x")
-CHIP=__SAM3X8E__
-VARIANT_PATH = ../../../../variants/$(VARIANT)
+ifeq ("$(VARIANT)", "arduino_zero")
+DEVICE=__SAMD21G18A__
 endif
 
-TOOLCHAIN=gcc
+ifeq ($(DEVICE), __SAMD21G18A__)
+DEVICE_NAME=samd21g18
+DEVICE_SERIE=samd21
+else ifeq ($(DEVICE), __SAMD21J18A__)
+DEVICE_NAME=samd21j18
+DEVICE_SERIE=samd21
+endif
 
 #-------------------------------------------------------------------------------
 # Path
 #-------------------------------------------------------------------------------
-
-# Libraries
-PROJECT_BASE_PATH = ./..
-SYSTEM_PATH = ../../../../system
-
-ifeq ($(CHIP), __SAM3S4C__)
-CHIP_NAME=sam3s4c
-CHIP_SERIE=sam3s
-else ifeq ($(CHIP), __SAM3U4E__)
-CHIP_NAME=sam3u4e
-CHIP_SERIE=sam3u
-else ifeq ($(CHIP), __SAM3N4C__)
-CHIP_NAME=sam3n4c
-CHIP_SERIE=sam3n
-else ifeq ($(CHIP), __SAM3X8H__)
-CHIP_NAME=sam3x8h
-CHIP_SERIE=sam3xa
-else ifeq ($(CHIP), __SAM3X8E__)
-CHIP_NAME=sam3x8e
-CHIP_SERIE=sam3xa
-else
-endif
-
-CMSIS_ROOT_PATH = $(SYSTEM_PATH)/CMSIS
+HARDWARE_PATH=../../../../../..
+ARCH_PATH=$(HARDWARE_PATH)/arduino/samd
+ARDUINO_CORE_PATH=$(ARCH_PATH)/cores/arduino
+ARDUINO_USB_PATH=$(ARDUINO_CORE_PATH)/USB
+VARIANT_PATH = $(ARCH_PATH)/variants/$(VARIANT)
+TOOLS_PATH = $(HARDWARE_PATH)/tools
+CMSIS_ROOT_PATH=$(TOOLS_PATH)/CMSIS
 CMSIS_ARM_PATH=$(CMSIS_ROOT_PATH)/CMSIS/Include
 CMSIS_ATMEL_PATH=$(CMSIS_ROOT_PATH)/Device/ATMEL
-CMSIS_CHIP_PATH=$(CMSIS_ROOT_PATH)/Device/ATMEL/$(CHIP_SERIE)
+#CMSIS_DEVICE_PATH=$(CMSIS_ROOT_PATH)/Device/ATMEL/$(DEVICE_SERIE)
+
+PROJECT_BASE_PATH = ..
+
+TOOLCHAIN=gcc
 
-ARDUINO_CORE_PATH=$(PROJECT_BASE_PATH)/..
-ARDUINO_USB_PATH=$(PROJECT_BASE_PATH)/../USB
-ARDUINO_USB_HOST_PATH=$(PROJECT_BASE_PATH)/../../../system/USBHost
 
 # Output directories
 OUTPUT_PATH = debug_$(VARIANT)
@@ -87,21 +62,17 @@ OUTPUT_PATH = debug_$(VARIANT)
 # Files
 #-------------------------------------------------------------------------------
 
-vpath %.h $(PROJECT_BASE_PATH)/.. $(VARIANT_PATH) $(SYSTEM_PATH) $(CMSIS_ARM_PATH)
-vpath %.cpp $(PROJECT_BASE_PATH)
+vpath %.cpp $(PROJECT_BASE_PATH) $(ARDUINO_CORE_PATH) $(VARIANT_PATH) $(ARDUINO_USB_PATH)
+vpath %.c $(PROJECT_BASE_PATH) $(ARDUINO_CORE_PATH) $(VARIANT_PATH) $(ARDUINO_USB_PATH)
 
-VPATH+=$(PROJECT_BASE_PATH)
+#VPATH+=$(PROJECT_BASE_PATH)
 
-INCLUDES = -I$(PROJECT_BASE_PATH)/..
+INCLUDES = -I$(ARDUINO_CORE_PATH)
+INCLUDES += -I$(ARDUINO_USB_PATH)
 INCLUDES += -I$(VARIANT_PATH)
-#INCLUDES += -I$(VARIANT_PATH)/..
-#INCLUDES += -I$(SYSTEM_PATH)
-INCLUDES += -I$(SYSTEM_PATH)/libsam
 INCLUDES += -I$(CMSIS_ARM_PATH)
 INCLUDES += -I$(CMSIS_ATMEL_PATH)
-INCLUDES += -I$(CMSIS_CHIP_PATH)
-INCLUDES += -I$(ARDUINO_USB_PATH)
-INCLUDES += -I$(ARDUINO_USB_HOST_PATH)
+#INCLUDES += -I$(CMSIS_DEVICE_PATH)
 
 #-------------------------------------------------------------------------------
 ifdef DEBUG
@@ -116,6 +87,9 @@ endif
 
 include $(TOOLCHAIN).mk
 
+CFLAGS += -DUSB_VID=0x2341 -DUSB_PID=0x004d
+CPPFLAGS += -DUSB_VID=0x2341 -DUSB_PID=0x004d
+
 #-------------------------------------------------------------------------------
 ifdef DEBUG
 OUTPUT_OBJ=debug
@@ -125,19 +99,44 @@ OUTPUT_OBJ=release
 LIBS_POSTFIX=rel
 endif
 
-OUTPUT_BIN=test_$(TOOLCHAIN)_$(LIBS_POSTFIX)
-LIBS=-Wl,--start-group -lgcc -lc -lstdc++ -lsam_$(CHIP_NAME)_$(TOOLCHAIN)_$(LIBS_POSTFIX) -larduino_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX) -lvariant_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX) -Wl,--end-group
+OUTPUT_BIN=test_usb_device_$(TOOLCHAIN)_$(LIBS_POSTFIX)
+LIBS=-Wl,--start-group -lgcc -lc -lstdc++ -Wl,--end-group
 
 LIB_PATH =-L$(PROJECT_BASE_PATH)/..
 LIB_PATH+=-L=/lib/thumb2
 #LIB_PATH+=-L=/../lib/gcc/arm-none-eabi/4.5.2/thumb2
 
-LDFLAGS= -mcpu=cortex-m3 -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols
+#-------------------------------------------------------------------------------
+# C source files and objects
+#-------------------------------------------------------------------------------
+#C_SRC=$(wildcard $(PROJECT_BASE_PATH)/*.c)
+#C_SRC+=$(wildcard $(ARDUINO_CORE_PATH)/*.c)
+#C_SRC+=$(wildcard $(VARIANT_PATH)/*.c)
+#C_SRC=$(wildcard $(ARDUINO_USB_PATH)/*.c)
+
+C_SRC=$(ARDUINO_USB_PATH)/samd21_device.c
+C_SRC+=$(ARDUINO_CORE_PATH)/startup.c
+C_SRC+=$(ARDUINO_CORE_PATH)/syscalls.c
+
+C_OBJ_TEMP = $(patsubst %.c, %.o, $(notdir $(C_SRC)))
+
+# during development, remove some files
+C_OBJ_FILTER=
+
+C_OBJ=$(filter-out $(C_OBJ_FILTER), $(C_OBJ_TEMP))
 
 #-------------------------------------------------------------------------------
 # CPP source files and objects
 #-------------------------------------------------------------------------------
 CPP_SRC=$(wildcard $(PROJECT_BASE_PATH)/*.cpp)
+#CPP_SRC+=$(wildcard $(ARDUINO_CORE_PATH)/*.cpp)
+#CPP_SRC+=$(wildcard $(VARIANT_PATH)/*.cpp)
+#CPP_SRC+=$(wildcard $(ARDUINO_USB_PATH)/*.cpp)
+
+CPP_SRC+=$(ARDUINO_USB_PATH)/USBCore.cpp
+CPP_SRC+=$(ARDUINO_USB_PATH)/CDC.cpp
+CPP_SRC+=$(ARDUINO_USB_PATH)/HID.cpp
+#CPP_SRC+=$(VARIANT_PATH)/variant.cpp   ##//JCB needed, but not compile
 
 CPP_OBJ_TEMP = $(patsubst %.cpp, %.o, $(notdir $(CPP_SRC)))
 
@@ -151,48 +150,72 @@ CPP_OBJ=$(filter-out $(CPP_OBJ_FILTER), $(CPP_OBJ_TEMP))
 #-------------------------------------------------------------------------------
 all: test
 
-test: create_output libsam_$(CHIP_NAME)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a libarduino_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a libvariant_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a $(OUTPUT_BIN)
+test: create_output $(OUTPUT_BIN)
 
 
 .PHONY: create_output
 create_output:
+	@echo ------------------------------------------------------------------------------------
 	@echo --- Preparing $(VARIANT) files in $(OUTPUT_PATH) $(OUTPUT_BIN)
-#	@echo -------------------------
-#	@echo *$(INCLUDES)
-#	@echo -------------------------
-#	@echo *$(C_SRC)
-#	@echo -------------------------
-#	@echo *$(C_OBJ)
-#	@echo -------------------------
-#	@echo *$(addprefix $(OUTPUT_PATH)/, $(C_OBJ))
-#	@echo -------------------------
-#	@echo *$(CPP_SRC)
-#	@echo -------------------------
-#	@echo *$(CPP_OBJ)
-#	@echo -------------------------
-#	@echo *$(addprefix $(OUTPUT_PATH)/, $(CPP_OBJ))
-#	@echo -------------------------
-#	@echo *$(A_SRC)
-#	@echo -------------------------
+	@echo -
+	@echo -
+	@echo INCLUDES -------------------------
+	@echo $(INCLUDES)
+	@echo -
+	@echo -
+	@echo C_SRC -------------------------
+	@echo $(C_SRC)
+	@echo -
+	@echo -
+	@echo C_OBJ -------------------------
+	@echo $(C_OBJ)
+	@echo -
+	@echo -
+	@echo C_OBJ prefix -------------------------
+	@echo $(addprefix $(OUTPUT_PATH)/, $(C_OBJ))
+	@echo -
+	@echo -
+	@echo CPP_SRC -------------------------
+	@echo $(CPP_SRC)
+	@echo -
+	@echo -
+	@echo CPP_OBJ -------------------------
+	@echo $(CPP_OBJ)
+	@echo -
+	@echo -
+	@echo CPP_OBJ prefix -------------------------
+	@echo $(addprefix $(OUTPUT_PATH)/, $(CPP_OBJ))
+#	@echo A_SRC -------------------------
+#	@echo $(A_SRC)
+	@echo -------------------------
 
 	-@mkdir $(OUTPUT_PATH) 1>NUL 2>&1
+	@echo ------------------------------------------------------------------------------------
+
+$(addprefix $(OUTPUT_PATH)/,$(C_OBJ)): $(OUTPUT_PATH)/%.o: %.c
+	@echo Current folder is $(shell cd) - $@ $^
+#	@"$(CC)" -c $(CFLAGS) $< -o $@
+#	"$(CC)" -v -c $(CFLAGS) $< -o $@
+	"$(CC)" -c $(CFLAGS) $< -o $@ 
 
 $(addprefix $(OUTPUT_PATH)/,$(CPP_OBJ)): $(OUTPUT_PATH)/%.o: %.cpp
-#	@"$(CC)" -c $(CPPFLAGS) $< -o $@
-	@"$(CXX)" -c $(CPPFLAGS) $< -o $@
-#	@"$(CXX)" -v -c $(CPPFLAGS) $< -o $@
+	@echo Current folder is $(shell cd) - $@ $^
+#	@"$(CXX)" -c $(CPPFLAGS) $< -o $@
+#	"$(CXX)" -v -c $(CPPFLAGS) $< -o $@
+	"$(CXX)" -c $(CPPFLAGS) $< -o $@
 
 $(OUTPUT_BIN): $(addprefix $(OUTPUT_PATH)/, $(C_OBJ)) $(addprefix $(OUTPUT_PATH)/, $(CPP_OBJ)) $(addprefix $(OUTPUT_PATH)/, $(A_OBJ))
 	@"$(CC)" $(LIB_PATH) $(LDFLAGS) -T"$(VARIANT_PATH)/linker_scripts/gcc/flash.ld" -Wl,-Map,$(OUTPUT_PATH)/$@.map -o $(OUTPUT_PATH)/$@.elf $^ $(LIBS)
-#	@"$(CC)" $(LIB_PATH) $(LDFLAGS) -T"$(VARIANT_PATH)/linker_scripts/gcc/sram.ld" -Wl,-Map,$(OUTPUT_PATH)/$@.map -o $(OUTPUT_PATH)/$@.elf $^ $(LIBS)
 	@"$(NM)" $(OUTPUT_PATH)/$@.elf >$(OUTPUT_PATH)/$@.elf.txt
 	@"$(OBJCOPY)" -O binary $(OUTPUT_PATH)/$@.elf $(OUTPUT_PATH)/$@.bin
 	$(SIZE) $^ $(OUTPUT_PATH)/$@.elf
 
 .PHONY: clean
 clean:
-	@echo --- Cleaning test files
+	@echo ------------------------------------------------------------------------------------
+	@echo --- Cleaning test files for $(VARIANT)
 	-@$(RM) $(OUTPUT_PATH) 1>NUL 2>&1
+	@echo ------------------------------------------------------------------------------------
 
 #	-$(RM) $(OUTPUT_PATH)/test.o
 #	-$(RM) $(OUTPUT_PATH)/$(OUTPUT_BIN).elf
@@ -202,17 +225,4 @@ clean:
 
 debug: test
 	@"$(GDB)" -x "$(VARIANT_PATH)/debug_scripts/gcc/$(VARIANT)_flash.gdb" -ex "reset" -readnow -se $(OUTPUT_PATH)/$(OUTPUT_BIN).elf
-#	@"$(GDB)" -w -x "$(VARIANT_PATH)/debug_scripts/gcc/$(VARIANT)_sram.gdb" -ex "reset" -readnow -se $(OUTPUT_PATH)/$(OUTPUT_BIN).elf
-
-libsam_$(CHIP_NAME)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a:
-	@echo Building $@
-	@$(MAKE) -C $(SYSTEM_PATH)/libsam/build_gcc -f Makefile $@
-
-libarduino_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a:
-	@echo Building $@
-	$(MAKE) -C $(ARDUINO_CORE_PATH)/build_gcc -f Makefile $(VARIANT)
-
-libvariant_$(VARIANT)_$(TOOLCHAIN)_$(LIBS_POSTFIX).a:
-	@echo Building $@
-	$(MAKE) -C $(VARIANT_PATH)/build_gcc -f Makefile $(VARIANT)
 
diff --git a/cores/arduino/validation_usb_device/test_usb_device.cpp b/cores/arduino/validation_usb_device/test_usb_device.cpp
index 8f3f226c..47db951a 100644
--- a/cores/arduino/validation_usb_device/test_usb_device.cpp
+++ b/cores/arduino/validation_usb_device/test_usb_device.cpp
@@ -16,23 +16,50 @@
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
-#include "variant.h"
-#include <stdio.h>
+#define ARDUINO_MAIN
+#include "Arduino.h" 
 
-void setup() {
-	Serial.begin(57600);
+
+
+
+void setup(void) {
+	Serial.begin(115200);
+	
+#ifdef HID_ENABLED
 	Mouse.begin();
+#endif
 }
 
-void loop() {
+void loop(void) {
+
+#ifdef HID_ENABLED
 	Mouse.move(1, 0, 0);
+#endif
 
-	if (Serial.available() > 0)
-	{
-		char inChar = Serial.read();
-		Serial.print(inChar);
-		Serial1.print(inChar);
-	}
+//	if (Serial.available() > 0)
+//	{
+//		char inChar = Serial.read();
+//		Serial.print(inChar);
+//		Serial1.print(inChar);
+//	}
 
-	delay(10);
+//	delay(10);
+}
+
+int main(void)
+{
+	//JCB init();   not compile at this time
+    //JCB already in Reset_Handler  SystemInit();
+
+	USBDevice.attach();
+	
+	setup();
+    
+	for (;;) {
+		loop();
+		if (serialEventRun) serialEventRun();
+	}
+        
+	return 0;
 }
+ 
\ No newline at end of file
-- 
GitLab