Index: rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/samd21_host.c
===================================================================
--- rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/samd21_host.c	(revision 136)
+++ rtos_arduino/trunk/arduino_lib/hardware/arduino/samd/cores/arduino/USB/samd21_host.c	(revision 224)
@@ -1,32 +1,38 @@
-/* ----------------------------------------------------------------------------
- *         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.
- * ----------------------------------------------------------------------------
- */
+/*
+  Copyright (c) 2014 Arduino LLC.  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
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  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.
+  See the GNU Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+/*
+** Modified 04/04/2016 by Arduino.org development team
+*/
+
+
 
 #include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "../Arduino.h"
+#include "variant.h"
+#include "USB_host.h"
+#include "samd21_host.h"
+#include "sam.h"
+#include "wiring_digital.h"
+#include "wiring_private.h"
+
+#define HOST_DEFINED
 
 #ifdef HOST_DEFINED
@@ -35,22 +41,24 @@
 #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;
 
- __attribute__((__aligned__(4))) UsbHostDescriptor usb_pipe_table[USB_EPT_NUM];
+__attribute__((__aligned__(4))) volatile UsbHostDescriptor usb_pipe_table[USB_EPT_NUM];
+
+extern void (*gpf_isr)(void);
 
 
 // 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
+#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
+#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
+#define NVM_USB_PAD_TRIM_POS       55
+#define NVM_USB_PAD_TRIM_SIZE      3
+
+static void UHD_ISR(void);
 
 /**
@@ -60,45 +68,50 @@
 {
 	uint32_t pad_transn;
-    uint32_t pad_transp;
-    uint32_t pad_trim;
+	uint32_t pad_transp;
+	uint32_t pad_trim;
+	uint32_t i;
+
+//	USB_SetHandler(&USB_Handler);
+	USB_SetHandler(&UHD_ISR);
 
 	/* Enable USB clock */
 	PM->APBBMASK.reg |= PM_APBBMASK_USB;
 
-	/* Set up the USB DP/DN pins */
-	PORT->Group[0].PINCFG[PIN_PA24G_USB_DM].bit.PMUXEN = 1;
-	PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg &= ~(0xF << (4 * (PIN_PA24G_USB_DM & 0x01u)));
-	PORT->Group[0].PMUX[PIN_PA24G_USB_DM/2].reg |= MUX_PA24G_USB_DM << (4 * (PIN_PA24G_USB_DM & 0x01u));
-	PORT->Group[0].PINCFG[PIN_PA25G_USB_DP].bit.PMUXEN = 1;
-	PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg &= ~(0xF << (4 * (PIN_PA25G_USB_DP & 0x01u)));
-	PORT->Group[0].PMUX[PIN_PA25G_USB_DP/2].reg |= MUX_PA25G_USB_DP << (4 * (PIN_PA25G_USB_DP & 0x01u));
+	/* Set up the USB DP/DM pins */
+	pinPeripheral( 33ul, PIO_COM );
+	pinPeripheral( 34ul, PIO_COM );
 
 	/* ----------------------------------------------------------------------------------------------
-	 * Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference)
-	 */
-	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID( 6 ) | // Generic Clock Multiplexer 6
-					GCLK_CLKCTRL_GEN_GCLK0 | // Generic Clock Generator 0 is source
-					GCLK_CLKCTRL_CLKEN ;
-
-	while ( GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY )
-	{
-	/* Wait for synchronization */
+	* Put Generic Clock Generator 0 as source for Generic Clock Multiplexer 6 (USB reference)
+	*/
+	GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(6) |        // Generic Clock Multiplexer 6
+						GCLK_CLKCTRL_GEN_GCLK0 |    // Generic Clock Generator 0 is source
+						GCLK_CLKCTRL_CLKEN;
+
+	while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY)
+	{
+		/* Wait for synchronization */
 	}
 
 	/* Reset */
 	USB->HOST.CTRLA.bit.SWRST = 1;
-	while (USB->HOST.SYNCBUSY.bit.SWRST) {
+	while (USB->HOST.SYNCBUSY.bit.SWRST)
+	{
 		/* Sync wait */
 	}
 
-	udd_enable();
+	//  uhd_enable();
+	USB->DEVICE.CTRLA.reg |= USB_CTRLA_ENABLE | USB_CTRLA_MODE;
+	uhd_force_host_mode();
+	while (USB->HOST.SYNCBUSY.reg == USB_SYNCBUSY_ENABLE);
 
 	/* 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 = (*((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;
 	}
@@ -106,10 +119,11 @@
 	USB->HOST.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 = (*((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;
 	}
@@ -117,10 +131,11 @@
 	USB->HOST.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 = (*((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;
 	}
@@ -128,42 +143,43 @@
 	USB->HOST.PADCAL.bit.TRIM = pad_trim;
 
+
 	/* Set the configuration */
-	udd_force_host_mode();
-	udd_device_run_in_standby();
-    // Set address of USB SRAM
-	USB->HOST.DESCADD.reg = (uint32_t)(&usb_endpoint_table[0]);
-	// For USB_SPEED_FULL 
-	udd_force_full_speed();
- 	for (uint32_t i = 0; i < sizeof(usb_endpoint_table); i++) {
- 		(*(uint32_t *)(&usb_endpoint_table[0]+i)) = 0;
- 	}
+	uhd_run_in_standby();
+	// Set address of USB SRAM
+	USB->HOST.DESCADD.reg = (uint32_t)(&usb_pipe_table[0]);
+	// For USB_SPEED_FULL
+	uhd_force_full_speed();
+	for (i = 0; i < sizeof(usb_pipe_table); i++)
+	{
+		(*(uint32_t *)(&usb_pipe_table[0] + i)) = 0;
+	}
 
 	uhd_state = UHD_STATE_NO_VBUS;
 
+	// Put VBUS on USB port
+	pinMode( 32ul, OUTPUT );
+	digitalWrite( 32ul, HIGH );
+
+	uhd_enable_connection_int();
+
+	USB->HOST.INTENSET.reg = USB_HOST_INTENSET_DCONN;
+	USB->HOST.INTENSET.reg = USB_HOST_INTENSET_WAKEUP;
+	USB->HOST.INTENSET.reg = USB_HOST_INTENSET_DDISC;
+
 	USB->HOST.CTRLB.bit.VBUSOK = 1;
 
 	// Configure interrupts
-	NVIC_SetPriority((IRQn_Type) USB_IRQn, 0UL);
-	NVIC_EnableIRQ((IRQn_Type) USB_IRQn);
-}
-
-//static void UHD_ISR(void)
-void USB_Handler(void)
-{
-	uint16_t flags;
-	uint8_t i;
-	uint8_t ept_int;
-
-	ept_int = udd_endpoint_interrupt();
-	
-	/* Not endpoint interrupt */
-	if (0 == ept_int)
-	{
-
-
-	}
-	else
-	{
-		/* host interrupts */
+	NVIC_SetPriority((IRQn_Type)USB_IRQn, 0UL);
+	NVIC_EnableIRQ((IRQn_Type)USB_IRQn);
+}
+
+
+static void UHD_ISR(void)
+//void USB_Handler(void)
+{
+   uint16_t flags;
+
+	if (USB->HOST.CTRLA.bit.MODE) {
+		/*host mode ISR */
 
 		/* get interrupt flags */
@@ -171,54 +187,62 @@
 
 		/* host SOF interrupt */
-		if (flags & USB_HOST_INTFLAG_HSOF) {
+		if (flags & USB_HOST_INTFLAG_HSOF)
+		{
 			/* clear the flag */
 			USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_HSOF;
-			uhd_state = UHD_STATE_CONNECTED;
+			uhd_state             = UHD_STATE_CONNECTED;
 			return;
 		}
 
 		/* host reset interrupt */
-		if (flags & USB_HOST_INTFLAG_RST) {
+		if (flags & USB_HOST_INTFLAG_RST)
+		{
 			/* clear the flag */
 			USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_RST;
-			uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR;
+			uhd_state             = UHD_STATE_DISCONNECTED;    //UHD_STATE_ERROR;
 			return;
 		}
 
 		/* host upstream resume interrupts */
-		if (flags & USB_HOST_INTFLAG_UPRSM) {
+		if (flags & USB_HOST_INTFLAG_UPRSM)
+		{
 			/* clear the flags */
 			USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_UPRSM;
-			uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR;
+			uhd_state             = UHD_STATE_DISCONNECTED;    //UHD_STATE_ERROR;
 			return;
 		}
 
 		/* host downstream resume interrupts */
-		if (flags & USB_HOST_INTFLAG_DNRSM) {
+		if (flags & USB_HOST_INTFLAG_DNRSM)
+		{
 			/* clear the flags */
 			USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_DNRSM;
-			uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR;
+			uhd_state             = UHD_STATE_DISCONNECTED;    //UHD_STATE_ERROR;
 			return;
 		}
 
 		/* host wakeup interrupts */
-		if (flags & USB_HOST_INTFLAG_WAKEUP) {
+		if (flags & USB_HOST_INTFLAG_WAKEUP)
+		{
 			/* clear the flags */
 			USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_WAKEUP;
-			uhd_state = UHD_STATE_CONNECTED; //UHD_STATE_ERROR;
+			uhd_state             = UHD_STATE_CONNECTED;    //UHD_STATE_ERROR;
 			return;
 		}
 
 		/* host ram access interrupt  */
-		if (flags & USB_HOST_INTFLAG_RAMACER) {
+		if (flags & USB_HOST_INTFLAG_RAMACER)
+		{
 			/* clear the flag */
 			USB->HOST.INTFLAG.reg = USB_HOST_INTFLAG_RAMACER;
-			uhd_state = UHD_STATE_DISCONNECTED; //UHD_STATE_ERROR;
+			uhd_state             = UHD_STATE_DISCONNECTED;    //UHD_STATE_ERROR;
 			return;
 		}
 
 		/* host connect interrupt */
-		if (flags & USB_HOST_INTFLAG_DCONN) {
-			TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Connection INT\r\n");)
+		if (flags & USB_HOST_INTFLAG_DCONN)
+		{
+			TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Connection INT\r\n");
+							)
 			/* clear the flag */
 			uhd_ack_connection();
@@ -231,7 +255,9 @@
 		}
 
-		/* host disconnect interrupt 	*/
-		if (flags & USB_HOST_INTFLAG_DDISC) {
-			TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Disconnection INT\r\n");)
+		/* host disconnect interrupt  */
+		if (flags & USB_HOST_INTFLAG_DDISC)
+		{
+			TRACE_UOTGHS_HOST(printf(">>> UHD_ISR : Disconnection INT\r\n");
+							)
 			/* clear the flag */
 			uhd_ack_disconnection();
@@ -246,19 +272,11 @@
 			return;
 		}
-
-	}
-
-}
-
-
-
-
-/**
- * \brief Trigger a USB bus reset.
- */
-void UHD_BusReset(void)
-{
-	USB->HOST.CTRLB.bit.BUSRESET = 1;;
-}
+	}
+	else {
+		while(1);
+	}
+}
+
+
 
 /**
@@ -269,7 +287,6 @@
 uhd_vbus_state_t UHD_GetVBUSState(void)
 {
-	return uhd_state;
-}
-
+   return uhd_state;
+}
 
 
@@ -283,31 +300,20 @@
  * \retval 1 error.
  */
-uint32_t UHD_Pipe0_Alloc(uint32_t ul_add, uint32_t ul_ep_size)
-{
-	struct usb_host_pipe_config cfg;
-
-	if (ep_size < 8)
-	{
-		return 0;
-	}
-
-	/* set pipe config */
-	USB->HOST.HostPipe[0].PCFG.bit.BK = 0;
-	USB->HOST.HostPipe[0].PCFG.bit.PTYPE = USB_HOST_PIPE_TYPE_CONTROL;
-	USB->HOST.HostPipe[0].BINTERVAL.reg = 0;
-	USB->HOST.HostPipe[0].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_SETUP;
-
-	memset((uint8_t *)&usb_pipe_table[pipe_num], 0, sizeof(usb_pipe_table[0]));
-	usb_pipe_table[pipe_num].HostDescBank[0].CTRL_PIPE.bit.PDADDR = 0;
-	usb_pipe_table[pipe_num].HostDescBank[0].CTRL_PIPE.bit.PEPNUM = 0;
-	usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.SIZE = 0x03;  // 64 bytes
-
-	USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TRCPT_Msk;
-	USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TRFAIL | USB_HOST_PINTENSET_PERR;
-	USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TXSTP;
-	USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_STALL;
-
-	return 1;
-}
+uint32_t UHD_Pipe0_Alloc(uint32_t ul_add , uint32_t ul_ep_size)
+{
+	(void)(ul_add); // Unused argument
+
+	if( USB->HOST.STATUS.reg & USB_HOST_STATUS_SPEED(1) )
+		ul_ep_size = USB_PCKSIZE_SIZE_8_BYTES;  // Low Speed
+	else
+		ul_ep_size = USB_PCKSIZE_SIZE_64_BYTES; // Full Speed
+
+	USB->HOST.HostPipe[0].PCFG.bit.PTYPE = 1; //USB_HOST_PCFG_PTYPE_CTRL;
+	usb_pipe_table[0].HostDescBank[0].CTRL_PIPE.bit.PEPNUM = 0;
+	usb_pipe_table[0].HostDescBank[0].PCKSIZE.bit.SIZE = ul_ep_size;
+
+	return 0;
+}
+
 
 /**
@@ -336,32 +342,39 @@
 {
 	/* set pipe config */
-	USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.BK = ul_nb_bank;
-	USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTYPE = ul_type;
-	USB->HOST.HostPipe[ul_dev_ep].BINTERVAL.reg = ul_interval;
-
-	if (ul_dir & USB_EP_DIR_IN)
-	{
-		USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_IN;
-		USB->HOST.HostPipe[ul_dev_ep].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY;
-	}
+	USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.BK    = ul_nb_bank;
+	USB->HOST.HostPipe[ul_dev_ep].PCFG.reg &= ~USB_HOST_PCFG_MASK;  // USB->HOST.HostPipe[0].PCFG.bit.PTYPE = 1; //USB_HOST_PCFG_PTYPE_CTRL;
+	USB->HOST.HostPipe[ul_dev_ep].PCFG.reg |= ul_type;
+	USB->HOST.HostPipe[ul_dev_ep].BINTERVAL.reg  = ul_interval;
+
+   if (ul_dir & USB_EP_DIR_IN)
+   {
+      USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTOKEN = USB_HOST_PCFG_PTOKEN_IN;
+      USB->HOST.HostPipe[ul_dev_ep].PSTATUSSET.reg  = USB_HOST_PSTATUSSET_BK0RDY;
+   }
+   else
+   {
+      USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTOKEN = USB_HOST_PCFG_PTOKEN_OUT;
+      USB->HOST.HostPipe[ul_dev_ep].PSTATUSCLR.reg  = USB_HOST_PSTATUSCLR_BK0RDY;
+   }
+
+	if( USB->HOST.STATUS.reg & USB_HOST_STATUS_SPEED(1) )
+	   ul_maxsize = USB_PCKSIZE_SIZE_8_BYTES;  // Low Speed
 	else
-	{
-		USB->HOST.HostPipe[ul_dev_ep].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_OUT;
-		USB->HOST.HostPipe[ul_dev_ep].PSTATUSCLR.reg =  USB_HOST_PSTATUSCLR_BK0RDY;
-	}
-
-	memset((uint8_t *)&usb_descriptor_table.usb_pipe_table[ul_dev_ep], 0, sizeof(usb_pipe_table[ul_dev_ep]));
-
-	usb_descriptor_table.usb_pipe_table[ul_dev_ep].HostDescBank[0].CTRL_PIPE.bit.PDADDR = ul_dev_addr;
-	usb_descriptor_table.usb_pipe_table[ul_dev_ep].HostDescBank[0].CTRL_PIPE.bit.PEPNUM = ul_dev_ep;
-	usb_descriptor_table.usb_pipe_table[ul_dev_ep].HostDescBank[0].PCKSIZE.bit.SIZE = 0x03;  // 64 bytes
-
-	USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TRCPT_Msk;
-	USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_TRFAIL | USB_HOST_PINTENSET_PERR;
-	USB->HOST.HostPipe[pipe_num].PINTENSET.reg = USB_HOST_PINTENSET_STALL;
-
-	return 1;
-}
-
+	   ul_maxsize = USB_PCKSIZE_SIZE_64_BYTES; // Full Speed
+
+   memset((uint8_t *)&usb_pipe_table[ul_dev_ep], 0, sizeof(usb_pipe_table[ul_dev_ep]));
+
+   usb_pipe_table[ul_dev_ep].HostDescBank[0].CTRL_PIPE.bit.PDADDR = ul_dev_addr;
+   usb_pipe_table[ul_dev_ep].HostDescBank[0].CTRL_PIPE.bit.PEPNUM = ul_dev_ep;
+   usb_pipe_table[ul_dev_ep].HostDescBank[0].PCKSIZE.bit.SIZE     = ul_maxsize;
+
+   return 1;
+}
+
+
+void UHD_Pipe_CountZero(uint32_t ul_pipe)
+{
+	usb_pipe_table[ul_pipe].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0;
+}
 
 /**
@@ -372,12 +385,8 @@
 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);
-
-	// The Pipe is frozen and no additional requests will be sent to the device on this pipe address.
-	USB->HOST.HostPipe[pipe_num].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE;
-}
+   // The Pipe is frozen and no additional requests will be sent to the device on this pipe address.
+   USB->HOST.HostPipe[ul_pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE;
+}
+
 
 /**
@@ -390,25 +399,26 @@
  * \return number of data read.
  */
-uint32_t UHD_Pipe_Read(uint32_t pipe_num, uint32_t buf_size, uint8_t* buf)
-{
-	if (USB->HOST.HostPipe[pipe_num].PCFG.bit.PTYPE == USB_HOST_PIPE_TYPE_DISABLE)
-	{
-		return 0;
-	}
-
-	/* get pipe config from setting register */
-	usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].ADDR.reg = (uint32_t)buf;
-	usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = 0;
-	usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = buf_size;
-	USB->HOST.HostPipe[pipe_num].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_IN;
-
-	/* Start transfer */
-	USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY;
-
-	// Unfreeze pipe
-	USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_PFREEZE;
-
-	return buf_size;
-}
+uint32_t UHD_Pipe_Read(uint32_t pipe_num, uint32_t buf_size, uint8_t *buf)
+{
+   if (USB->HOST.HostPipe[pipe_num].PCFG.bit.PTYPE == USB_HOST_PTYPE_DIS)
+   {
+      return 0;
+   }
+
+   /* get pipe config from setting register */
+   usb_pipe_table[pipe_num].HostDescBank[0].ADDR.reg = (uint32_t)buf;
+   usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT        = 0;
+   usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = buf_size;
+   USB->HOST.HostPipe[pipe_num].PCFG.bit.PTOKEN = USB_HOST_PCFG_PTOKEN_IN;
+
+   /* Start transfer */
+   USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY;
+
+   // Unfreeze pipe
+   USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_PFREEZE;
+
+   return buf_size;
+}
+
 
 /**
@@ -419,20 +429,10 @@
  * \param data Buffer containing data to write.
  */
-void UHD_Pipe_Write(uint32_t ul_pipe, uint32_t ul_size, uint8_t* data)
-{
-
-	if (USB->HOST.HostPipe[pipe_num].PCFG.bit.PTYPE == USB_HOST_PIPE_TYPE_DISABLE) 
-	{
-		return 0;
-	}
-
-	/* get pipe config from setting register */
-	usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].ADDR.reg = (uint32_t)buf;
-	usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = buf_size;
-	usb_descriptor_table.usb_pipe_table[pipe_num].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 0;
-	USB->HOST.HostPipe[pipe_num].PCFG.bit.PTOKEN = USB_HOST_PIPE_TOKEN_OUT;
-
-
-	return 1;
+void UHD_Pipe_Write(uint32_t ul_pipe, uint32_t ul_size, uint8_t *buf)
+{
+   /* get pipe config from setting register */
+   usb_pipe_table[ul_pipe].HostDescBank[0].ADDR.reg = (uint32_t)buf;
+   usb_pipe_table[ul_pipe].HostDescBank[0].PCKSIZE.bit.BYTE_COUNT = ul_size;
+   usb_pipe_table[ul_pipe].HostDescBank[0].PCKSIZE.bit.MULTI_PACKET_SIZE = 0;
 }
 
@@ -445,10 +445,29 @@
 void UHD_Pipe_Send(uint32_t ul_pipe, uint32_t ul_token_type)
 {
-	/* Start transfer */
-	USB->HOST.HostPipe[pipe_num].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY;
-
+	USB->HOST.HostPipe[ul_pipe].PCFG.bit.PTOKEN = ul_token_type;
+
+   /* Start transfer */
+	if(ul_token_type == USB_HOST_PCFG_PTOKEN_SETUP )
+	{
+		USB->HOST.HostPipe[ul_pipe].PINTFLAG.reg = USB_HOST_PINTFLAG_TXSTP;
+		USB->HOST.HostPipe[ul_pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY;
+	}
+	else if(ul_token_type == USB_HOST_PCFG_PTOKEN_IN )
+	{
+		USB->HOST.HostPipe[ul_pipe].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_BK0RDY;
+	}
+	else
+	{
+		USB->HOST.HostPipe[ul_pipe].PINTFLAG.reg = USB_HOST_PINTFLAG_TRCPT(1);  // Transfer Complete 0
+		USB->HOST.HostPipe[ul_pipe].PSTATUSSET.reg = USB_HOST_PSTATUSSET_BK0RDY;
+	}
+   
 	// Unfreeze pipe
-	USB->HOST.HostPipe[pipe_num].PSTATUSCLR.reg = USB_HOST_PSTATUSCLR_PFREEZE;
-}
+    uhd_unfreeze_pipe(ul_pipe);
+}
+
+#define USB_HOST_PINTFLAG_TRCPT_Pos 0            /**< \brief (USB_HOST_PINTFLAG) Transfer Complete 0/1 Interrupt Flag */
+#define USB_HOST_PINTFLAG_TRCPT_Msk (0x3u << USB_HOST_PINTFLAG_TRCPT_Pos)
+#define USB_HOST_PINTFLAG_TRCPT(value) ((USB_HOST_PINTFLAG_TRCPT_Msk & ((value) << USB_HOST_PINTFLAG_TRCPT_Pos)))
 
 /**
@@ -463,24 +482,40 @@
 uint32_t UHD_Pipe_Is_Transfer_Complete(uint32_t ul_pipe, uint32_t ul_token_type)
 {
-
-	// Freeze pipe
-	USB->HOST.HostPipe[pipe_num].PSTATUSSET.reg = USB_HOST_PSTATUSSET_PFREEZE;
-	switch(uhd_ctrl_request_phase) {
-		case UHD_CTRL_REQ_PHASE_DATA_IN:
-		_uhd_ctrl_phase_data_in(p_callback_para->transfered_size);
-		break;
-		case UHD_CTRL_REQ_PHASE_ZLP_IN:
-		_uhd_ctrl_request_end(UHD_TRANS_NOERROR);
-		break;
-		case UHD_CTRL_REQ_PHASE_DATA_OUT:
-		_uhd_ctrl_phase_data_out();
-		break;
-		case UHD_CTRL_REQ_PHASE_ZLP_OUT:
-		_uhd_ctrl_request_end(UHD_TRANS_NOERROR);
-		break;
-	}
-	return 0;
-}
-
-#endif 
-
+   // Check for transfer completion depending on token type
+   switch (ul_token_type)
+   {
+      case USB_HOST_PCFG_PTOKEN_SETUP:
+         if (Is_uhd_setup_ready(ul_pipe))
+         {
+            uhd_ack_setup_ready(ul_pipe);
+            uhd_freeze_pipe(ul_pipe);
+            return 1;
+         }
+		 break;
+
+      case USB_HOST_PCFG_PTOKEN_IN:
+         if (Is_uhd_in_received(ul_pipe))
+         {
+            // IN packet received
+            uhd_ack_in_received(ul_pipe);
+			// Freeze will stop after the transfer
+			uhd_freeze_pipe(ul_pipe);
+            return 1;
+         }
+		 break;
+ 
+      case USB_HOST_PCFG_PTOKEN_OUT:
+         if (Is_uhd_out_ready(ul_pipe))
+         {
+            // OUT packet sent
+            uhd_ack_out_ready(ul_pipe);
+            uhd_freeze_pipe(ul_pipe);
+            return 1;
+         }
+		 break;
+   }
+
+   return 0;
+}
+
+#endif //  HOST_DEFINED
