USB device stack - Added support for the logo/windows key to USB keyboard.

Dependents:   randomSearch

Fork of USBDevice by mbed official

Revision:
46:378357d7e90d
Parent:
35:a8484e16c2f3
diff -r 0f216c4e75e5 -r 378357d7e90d USBDevice/TARGET_RENESAS/TARGET_RZ_A1H/usb0/src/common/usb0_function_dataio.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/USBDevice/TARGET_RENESAS/TARGET_RZ_A1H/usb0/src/common/usb0_function_dataio.c	Tue Mar 31 16:15:39 2015 +0100
@@ -0,0 +1,2933 @@
+/*******************************************************************************
+* DISCLAIMER
+* This software is supplied by Renesas Electronics Corporation and is only
+* intended for use with Renesas products. No other uses are authorized. This
+* software is owned by Renesas Electronics Corporation and is protected under
+* all applicable laws, including copyright laws.
+* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
+* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
+* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
+* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
+* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
+* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
+* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
+* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+* Renesas reserves the right, without notice, to make changes to this software
+* and to discontinue the availability of this software. By using this software,
+* you agree to the additional terms and conditions found by accessing the
+* following link:
+* http://www.renesas.com/disclaimer
+* Copyright (C) 2012 - 2014 Renesas Electronics Corporation. All rights reserved.
+*******************************************************************************/
+/*******************************************************************************
+* File Name    : usb0_function_dataio.c
+* $Rev: 1116 $
+* $Date:: 2014-07-09 16:29:19 +0900#$
+* Device(s)    : RZ/A1H
+* Tool-Chain   :
+* OS           : None
+* H/W Platform :
+* Description  : RZ/A1H R7S72100 USB Sample Program
+* Operation    :
+* Limitations  :
+*******************************************************************************/
+
+
+/*******************************************************************************
+Includes   <System Includes> , "Project Includes"
+*******************************************************************************/
+#include "usb0_function.h"
+
+
+/*******************************************************************************
+Typedef definitions
+*******************************************************************************/
+
+
+/*******************************************************************************
+Macro definitions
+*******************************************************************************/
+
+
+/*******************************************************************************
+Imported global variables and functions (from other files)
+*******************************************************************************/
+
+
+/*******************************************************************************
+Exported global variables and functions (to be accessed by other files)
+*******************************************************************************/
+
+
+/*******************************************************************************
+Private global variables and functions
+*******************************************************************************/
+static uint16_t g_usb0_function_mbw[(USB_FUNCTION_MAX_PIPE_NO + 1)];
+
+static void     usb0_function_start_receive_trns_c(uint16_t pipe, uint32_t size, uint8_t *data);
+static void     usb0_function_start_receive_trns_d0(uint16_t pipe, uint32_t size, uint8_t *data);
+static void     usb0_function_start_receive_trns_d1(uint16_t pipe, uint32_t size, uint8_t *data);
+static void     usb0_function_start_receive_dma_d0(uint16_t pipe, uint32_t size, uint8_t *data);
+static void     usb0_function_start_receive_dma_d1(uint16_t pipe, uint32_t size, uint8_t *data);
+static uint16_t usb0_function_read_dma_d0(uint16_t pipe);
+static uint16_t usb0_function_read_dma_d1(uint16_t pipe);
+static uint16_t usb0_function_write_dma_d0(uint16_t pipe);
+static uint16_t usb0_function_write_dma_d1(uint16_t pipe);
+
+static void     usb0_function_read_c_fifo(uint16_t pipe, uint16_t count);
+static void     usb0_function_write_c_fifo(uint16_t Pipe, uint16_t count);
+static void     usb0_function_read_d0_fifo(uint16_t pipe, uint16_t count);
+static void     usb0_function_write_d0_fifo(uint16_t pipe, uint16_t count);
+static void     usb0_function_read_d1_fifo(uint16_t pipe, uint16_t count);
+static void     usb0_function_write_d1_fifo(uint16_t pipe, uint16_t count);
+
+static void     usb0_function_clear_transaction_counter(uint16_t pipe);
+static void     usb0_function_set_transaction_counter(uint16_t pipe, uint32_t count);
+
+static uint32_t usb0_function_com_get_dmasize(uint32_t trncount, uint32_t dtptr);
+
+static uint16_t usb0_function_set_dfacc_d0(uint16_t mbw, uint32_t count);
+static uint16_t usb0_function_set_dfacc_d1(uint16_t mbw, uint32_t count);
+
+
+/*******************************************************************************
+* Function Name: usb0_function_start_send_transfer
+* Description  : Starts the USB data communication using pipe specified by the argument.
+* Arguments    : uint16_t  pipe    ; Pipe Number
+*              : uint32_t size     ; Data Size
+*              : uint8_t  *data    ; Data Address
+* Return Value : DEVDRV_USBF_WRITEEND           ; Write end
+*              : DEVDRV_USBF_WRITESHRT          ; short data
+*              : DEVDRV_USBF_WRITING            ; Continue of data write
+*              : DEVDRV_USBF_WRITEDMA           ; Write DMA
+*              : DEVDRV_USBF_FIFOERROR          ; FIFO status
+*******************************************************************************/
+uint16_t usb0_function_start_send_transfer (uint16_t pipe, uint32_t size, uint8_t * data)
+{
+    uint16_t status;
+    uint16_t usefifo;
+    uint16_t mbw;
+
+    g_usb0_function_data_count[pipe]   = size;
+    g_usb0_function_data_pointer[pipe] = (uint8_t *)data;
+    g_usb0_function_pipe_status[pipe]  = DEVDRV_USBF_PIPE_WAIT;
+
+    usb0_function_clear_bemp_sts(pipe);
+    usb0_function_clear_brdy_sts(pipe);
+    usb0_function_clear_nrdy_sts(pipe);
+
+    mbw = usb0_function_get_mbw(size, (uint32_t)data);
+
+    usefifo = (uint16_t)(g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE);
+
+    switch (usefifo)
+    {
+        case USB_FUNCTION_D0FIFO_USE:
+        case USB_FUNCTION_D0FIFO_DMA:
+            usefifo = USB_FUNCTION_D0USE;
+        break;
+
+        case USB_FUNCTION_D1FIFO_USE:
+        case USB_FUNCTION_D1FIFO_DMA:
+            usefifo = USB_FUNCTION_D1USE;
+        break;
+
+        default:
+            usefifo = USB_FUNCTION_CUSE;
+        break;
+    };
+
+    usb0_function_set_curpipe(USB_FUNCTION_PIPE0, usefifo, DEVDRV_USBF_NO, mbw);
+
+    usb0_function_clear_transaction_counter(pipe);
+
+    usb0_function_aclrm(pipe);
+
+    status = usb0_function_write_buffer(pipe);
+
+    if (status != DEVDRV_USBF_FIFOERROR)
+    {
+        usb0_function_set_pid_buf(pipe);
+    }
+
+    return status;
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_write_buffer
+* Description  : Writes data in the buffer allocated in the pipe specified by
+*              : the argument. The FIFO for using is set in the pipe definition table.
+* Arguments    : uint16_t pipe      ; Pipe Number
+* Return Value : DEVDRV_USBF_WRITEEND           ; Write end
+*              : DEVDRV_USBF_WRITESHRT          ; short data
+*              : DEVDRV_USBF_WRITING            ; Continue of data write
+*              : DEVDRV_USBF_WRITEDMA           ; Write DMA
+*              : DEVDRV_USBF_FIFOERROR          ; FIFO status
+*******************************************************************************/
+uint16_t usb0_function_write_buffer (uint16_t pipe)
+{
+    uint16_t status;
+    uint16_t usefifo;
+
+    g_usb0_function_PipeIgnore[pipe] = 0;
+    usefifo = (uint16_t)(g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE);
+
+    switch (usefifo)
+    {
+        case USB_FUNCTION_D0FIFO_USE:
+            status = usb0_function_write_buffer_d0(pipe);
+        break;
+
+        case USB_FUNCTION_D1FIFO_USE:
+            status = usb0_function_write_buffer_d1(pipe);
+        break;
+
+        case USB_FUNCTION_D0FIFO_DMA:
+            status = usb0_function_write_dma_d0(pipe);
+        break;
+
+        case USB_FUNCTION_D1FIFO_DMA:
+            status = usb0_function_write_dma_d1(pipe);
+        break;
+
+        default:
+            status = usb0_function_write_buffer_c(pipe);
+        break;
+    };
+
+    switch (status)
+    {
+        case DEVDRV_USBF_WRITING:                       /* Continue of data write */
+            usb0_function_enable_nrdy_int(pipe);        /* Error (NORES or STALL) */
+            usb0_function_enable_brdy_int(pipe);        /* Enable Ready Interrupt */
+        break;
+
+        case DEVDRV_USBF_WRITEEND:                      /* End of data write */
+        case DEVDRV_USBF_WRITESHRT:                     /* End of data write */
+            usb0_function_disable_brdy_int(pipe);       /* Disable Ready Interrupt */
+            usb0_function_clear_nrdy_sts(pipe);
+            usb0_function_enable_nrdy_int(pipe);        /* Error (NORES or STALL) */
+            /* for last transfer */
+            usb0_function_enable_bemp_int(pipe);        /* Enable Empty Interrupt */
+        break;
+
+        case DEVDRV_USBF_WRITEDMA:                      /* DMA write */
+            usb0_function_clear_nrdy_sts(pipe);
+            usb0_function_enable_nrdy_int(pipe);        /* Error (NORES or STALL) */
+        break;
+
+        case DEVDRV_USBF_FIFOERROR:                     /* FIFO access status */
+        default:
+            usb0_function_disable_brdy_int(pipe);       /* Disable Ready Interrupt */
+            usb0_function_disable_bemp_int(pipe);       /* Disable Empty Interrupt */
+            g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_FIFOERROR;
+        break;
+    }
+
+    return status;                      /* End or Err or Continue */
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_write_buffer_c
+* Description  : Writes data in the buffer allocated in the pipe specified in
+*              : the argument. Writes data by CPU transfer using CFIFO.
+* Arguments    : uint16_t pipe      ; Pipe Number
+* Return Value : DEVDRV_USBF_WRITEEND           ; Write end
+*              : DEVDRV_USBF_WRITESHRT          ; short data
+*              : DEVDRV_USBF_WRITING            ; Continue of data write
+*              : DEVDRV_USBF_WRITEDMA           ; Write DMA
+*              : DEVDRV_USBF_FIFOERROR          ; FIFO status
+*******************************************************************************/
+uint16_t usb0_function_write_buffer_c (uint16_t pipe)
+{
+    uint32_t count;
+    uint16_t size;
+    uint16_t buffer;
+    uint16_t mxps;
+    uint16_t status;
+    uint16_t mbw;
+
+    if (g_usb0_function_CtrZeroLengthFlag == 1)
+    {
+        g_usb0_function_CtrZeroLengthFlag = 0;                  /* Zero Length Packet Flag CLR */
+        return DEVDRV_USBF_WRITEEND;
+    }
+
+    mbw = usb0_function_get_mbw(g_usb0_function_data_count[pipe], (uint32_t)g_usb0_function_data_pointer[pipe]);
+    if (pipe == USB_FUNCTION_PIPE0)
+    {
+        buffer = usb0_function_change_fifo_port(pipe, USB_FUNCTION_CUSE, USB_FUNCTION_CFIFO_WRITE, mbw);
+    }
+    else
+    {
+        buffer = usb0_function_change_fifo_port(pipe, USB_FUNCTION_CUSE, DEVDRV_USBF_NO, mbw);
+    }
+
+    if (buffer == DEVDRV_USBF_FIFOERROR)                        /* FIFO access status */
+    {
+        return DEVDRV_USBF_FIFOERROR;
+    }
+
+    size = usb0_function_get_buf_size(pipe);                    /* Data buffer size */
+    mxps = usb0_function_get_mxps(pipe);                        /* Max Packet Size */
+
+    if (g_usb0_function_data_count[pipe] <= (uint32_t)size)
+    {
+        status = DEVDRV_USBF_WRITEEND;                          /* write continues */
+        count  = g_usb0_function_data_count[pipe];
+
+        if (count == 0)
+        {
+            status = DEVDRV_USBF_WRITESHRT;                     /* Null Packet is end of write */
+        }
+
+        if ((count % mxps) != 0)
+        {
+            status = DEVDRV_USBF_WRITESHRT;                     /* Short Packet is end of write */
+        }
+    }
+    else
+    {
+        status = DEVDRV_USBF_WRITING;                           /* write continues */
+        count  = (uint32_t)size;
+    }
+
+    usb0_function_write_c_fifo(pipe, (uint16_t)count);
+
+    if (g_usb0_function_data_count[pipe] < (uint32_t)size)
+    {
+        g_usb0_function_data_count[pipe] = 0;
+
+        if (RZA_IO_RegRead_16(&USB200.CFIFOCTR, USB_CFIFOCTR_BVAL_SHIFT, USB_CFIFOCTR_BVAL) == 0)
+        {
+            USB200.CFIFOCTR = USB_FUNCTION_BITBVAL;             /* Short Packet */
+            g_usb0_function_CtrZeroLengthFlag = 1;              /* Zero Length Packet Flag */
+        }
+    }
+    else
+    {
+        g_usb0_function_data_count[pipe] -= count;
+    }
+
+    return status;                                              /* End or Err or Continue */
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_write_buffer_d0
+* Description  : Writes data in the buffer allocated in the pipe specified in the argument.
+*              : Writes data by CPU transfer using D0FIFO.
+* Arguments    : uint16_t pipe      ; Pipe Number
+* Return Value : DEVDRV_USBF_WRITEEND           ; Write end
+*              : DEVDRV_USBF_WRITESHRT          ; short data
+*              : DEVDRV_USBF_WRITING            ; Continue of data write
+*              : DEVDRV_USBF_WRITEDMA           ; Write DMA
+*              : DEVDRV_USBF_FIFOERROR          ; FIFO status
+*******************************************************************************/
+uint16_t usb0_function_write_buffer_d0 (uint16_t pipe)
+{
+    uint32_t count;
+    uint16_t size;
+    uint16_t buffer;
+    uint16_t mxps;
+    uint16_t status;
+    uint16_t mbw;
+
+    mbw    = usb0_function_get_mbw(g_usb0_function_data_count[pipe], (uint32_t)g_usb0_function_data_pointer[pipe]);
+    buffer = usb0_function_change_fifo_port(pipe, USB_FUNCTION_D0USE, DEVDRV_USBF_NO, mbw);
+    if (buffer == DEVDRV_USBF_FIFOERROR)                        /* FIFO access status */
+    {
+        return DEVDRV_USBF_FIFOERROR;
+    }
+
+    size = usb0_function_get_buf_size(pipe);                    /* Data buffer size */
+    mxps = usb0_function_get_mxps(pipe);                        /* Max Packet Size */
+
+    if (g_usb0_function_data_count[pipe] <= (uint32_t)size)
+    {
+        status = DEVDRV_USBF_WRITEEND;                          /* write continues */
+        count  = g_usb0_function_data_count[pipe];
+
+        if (count == 0)
+        {
+            status = DEVDRV_USBF_WRITESHRT;                     /* Null Packet is end of write */
+        }
+
+        if ((count % mxps) != 0)
+        {
+            status = DEVDRV_USBF_WRITESHRT;                     /* Short Packet is end of write */
+        }
+    }
+    else
+    {
+        status = DEVDRV_USBF_WRITING;                           /* write continues */
+        count  = (uint32_t)size;
+    }
+
+    usb0_function_write_d0_fifo(pipe, (uint16_t)count);
+
+    if (g_usb0_function_data_count[pipe] < (uint32_t)size)
+    {
+        g_usb0_function_data_count[pipe] = 0;
+        if (RZA_IO_RegRead_16(&USB200.D0FIFOCTR, USB_DnFIFOCTR_BVAL_SHIFT, USB_DnFIFOCTR_BVAL) == 0)
+        {
+            USB200.D0FIFOCTR = USB_FUNCTION_BITBVAL;            /* Short Packet */
+        }
+    }
+    else
+    {
+        g_usb0_function_data_count[pipe] -= count;
+    }
+
+    return status;                                              /* End or Err or Continue */
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_write_buffer_d1
+* Description  : Writes data in the buffer allocated in the pipe specified in the argument.
+*              : Writes data by CPU transfer using D1FIFO.
+* Arguments    : uint16_t pipe      ; Pipe Number
+* Return Value : DEVDRV_USBF_WRITEEND           ; Write end
+*              : DEVDRV_USBF_WRITESHRT          ; short data
+*              : DEVDRV_USBF_WRITING            ; Continue of data write
+*              : DEVDRV_USBF_WRITEDMA           ; Write DMA
+*              : DEVDRV_USBF_FIFOERROR          ; FIFO status
+*******************************************************************************/
+uint16_t usb0_function_write_buffer_d1 (uint16_t pipe)
+{
+    uint32_t count;
+    uint16_t size;
+    uint16_t buffer;
+    uint16_t mxps;
+    uint16_t status;
+    uint16_t mbw;
+
+    mbw = usb0_function_get_mbw(g_usb0_function_data_count[pipe], (uint32_t)g_usb0_function_data_pointer[pipe]);
+    buffer = usb0_function_change_fifo_port(pipe, USB_FUNCTION_D1USE, DEVDRV_USBF_NO, mbw);
+
+    if (buffer == DEVDRV_USBF_FIFOERROR)                        /* FIFO access status */
+    {
+        return DEVDRV_USBF_FIFOERROR;
+    }
+
+    size = usb0_function_get_buf_size(pipe);                    /* Data buffer size */
+    mxps = usb0_function_get_mxps(pipe);                        /* Max Packet Size */
+
+    if (g_usb0_function_data_count[pipe] <= (uint32_t)size)
+    {
+        status = DEVDRV_USBF_WRITEEND;                          /* write continues */
+        count  = g_usb0_function_data_count[pipe];
+
+        if (count == 0)
+        {
+            status = DEVDRV_USBF_WRITESHRT;                     /* Null Packet is end of write */
+        }
+
+        if ((count % mxps) != 0)
+        {
+            status = DEVDRV_USBF_WRITESHRT;                     /* Short Packet is end of write */
+        }
+    }
+    else
+    {
+        status = DEVDRV_USBF_WRITING;                           /* write continues */
+        count  = (uint32_t)size;
+    }
+
+    usb0_function_write_d1_fifo(pipe, (uint16_t)count);
+
+    if (g_usb0_function_data_count[pipe] < (uint32_t)size)
+    {
+        g_usb0_function_data_count[pipe] = 0;
+
+        if (RZA_IO_RegRead_16(&USB200.D1FIFOCTR, USB_DnFIFOCTR_BVAL_SHIFT, USB_DnFIFOCTR_BVAL) == 0)
+        {
+            USB200.D1FIFOCTR = USB_FUNCTION_BITBVAL;            /* Short Packet */
+        }
+    }
+    else
+    {
+        g_usb0_function_data_count[pipe] -= count;
+    }
+
+    return status;                                              /* End or Err or Continue */
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_write_dma_d0
+* Description  : Writes data in the buffer allocated in the pipe specified in the argument.
+*              : Writes data by DMA transfer using D0FIFO.
+*              : The DMA-ch for using is specified by Userdef_USB_usb0_function_start_dma().
+* Arguments    : uint16_t pipe     ; Pipe Number
+* Return Value : DEVDRV_USBF_WRITEEND           : Write end
+*              : DEVDRV_USBF_WRITESHRT          : short data
+*              : DEVDRV_USBF_WRITING            : Continue of data write
+*              : DEVDRV_USBF_WRITEDMA           : Write DMA
+*              : DEVDRV_USBF_FIFOERROR          : FIFO status
+*******************************************************************************/
+static uint16_t usb0_function_write_dma_d0 (uint16_t pipe)
+{
+    uint32_t count;
+    uint16_t size;
+    uint16_t buffer;
+    uint16_t status;
+    uint16_t mbw;
+    uint16_t dfacc = 0;
+
+    mbw = usb0_function_get_mbw(g_usb0_function_data_count[pipe], (uint32_t)g_usb0_function_data_pointer[pipe]);
+    buffer = usb0_function_change_fifo_port(pipe, USB_FUNCTION_D0DMA, DEVDRV_USBF_NO, mbw);
+
+    if (buffer == DEVDRV_USBF_FIFOERROR)                            /* FIFO access status */
+    {
+        return DEVDRV_USBF_FIFOERROR;
+    }
+
+    size  = usb0_function_get_buf_size(pipe);                       /* Data buffer size */
+    count = g_usb0_function_data_count[pipe];
+
+    if (count != 0)
+    {
+        g_usb0_function_DmaPipe[USB_FUNCTION_D0FIFO] = pipe;
+
+        if ((count % size) != 0)
+        {
+            g_usb0_function_DmaBval[USB_FUNCTION_D0FIFO] = 1;
+        }
+        else
+        {
+            g_usb0_function_DmaBval[USB_FUNCTION_D0FIFO] = 0;
+        }
+
+        dfacc = usb0_function_set_dfacc_d0(mbw, count);
+
+        if (mbw == USB_FUNCTION_BITMBW_32)
+        {
+            g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].size = 2;  /* 32bit transfer */
+        }
+        else if (mbw == USB_FUNCTION_BITMBW_16)
+        {
+            g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].size = 1;  /* 16bit transfer */
+        }
+        else
+        {
+            g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].size = 0;  /* 8bit transfer */
+        }
+
+        g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].fifo   = USB_FUNCTION_D0FIFO_DMA;
+        g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].dir    = USB_FUNCTION_BUF2FIFO;
+        g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].buffer = (uint32_t)g_usb0_function_data_pointer[pipe];
+        g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].bytes  = count;
+
+        Userdef_USB_usb0_function_start_dma(&g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO], dfacc);
+
+        usb0_function_set_curpipe2(pipe, USB_FUNCTION_D0DMA, DEVDRV_USBF_NO, mbw, dfacc);
+
+        RZA_IO_RegWrite_16(&USB200.D0FIFOSEL, 1, USB_DnFIFOSEL_DREQE_SHIFT, USB_DnFIFOSEL_DREQE);
+
+        g_usb0_function_data_count[pipe]    = 0;
+        g_usb0_function_data_pointer[pipe] += count;
+        status = DEVDRV_USBF_WRITEDMA;                              /* DMA write  */
+    }
+    else
+    {
+        if (RZA_IO_RegRead_16(&USB200.D0FIFOCTR, USB_DnFIFOCTR_BVAL_SHIFT, USB_DnFIFOCTR_BVAL) == 0)
+        {
+            RZA_IO_RegWrite_16(&USB200.D0FIFOCTR, 1, USB_DnFIFOCTR_BVAL_SHIFT, USB_DnFIFOCTR_BVAL); /* Short Packet */
+        }
+        status = DEVDRV_USBF_WRITESHRT;                             /* Short Packet is end of write */
+    }
+
+    return status;                                                  /* End or Err or Continue */
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_write_dma_d1
+* Description  : Writes data in the buffer allocated in the pipe specified in the argument.
+*              : Writes data by DMA transfer using D1FIFO.
+*              : The DMA-ch for using is specified by Userdef_USB_usb0_function_start_dma().
+* Arguments    : uint16_t pipe      ; Pipe Number
+* Return Value : DEVDRV_USBF_WRITEEND           : Write end
+*              : DEVDRV_USBF_WRITESHRT          : short data
+*              : DEVDRV_USBF_WRITING            : Continue of data write
+*              : DEVDRV_USBF_WRITEDMA           : Write DMA
+*              : DEVDRV_USBF_FIFOERROR          : FIFO status
+*******************************************************************************/
+static uint16_t usb0_function_write_dma_d1 (uint16_t pipe)
+{
+    uint32_t count;
+    uint16_t size;
+    uint16_t buffer;
+    uint16_t status;
+    uint16_t mbw;
+    uint16_t dfacc=0;
+
+    mbw = usb0_function_get_mbw(g_usb0_function_data_count[pipe], (uint32_t)g_usb0_function_data_pointer[pipe]);
+    buffer = usb0_function_change_fifo_port(pipe, USB_FUNCTION_D1DMA, DEVDRV_USBF_NO, mbw);
+
+    if (buffer == DEVDRV_USBF_FIFOERROR)                            /* FIFO access status */
+    {
+        return DEVDRV_USBF_FIFOERROR;
+    }
+
+    size  = usb0_function_get_buf_size(pipe);                       /* Data buffer size */
+    count = g_usb0_function_data_count[pipe];
+
+    if (count != 0)
+    {
+        g_usb0_function_DmaPipe[USB_FUNCTION_D1FIFO] = pipe;
+        if ((count % size) != 0)
+        {
+            g_usb0_function_DmaBval[USB_FUNCTION_D1FIFO] = 1;
+        }
+        else
+        {
+            g_usb0_function_DmaBval[USB_FUNCTION_D1FIFO] = 0;
+        }
+
+        dfacc = usb0_function_set_dfacc_d1(mbw, count);
+
+        if (mbw == USB_FUNCTION_BITMBW_32)
+        {
+            g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].size = 2;  /* 32bit transfer */
+        }
+        else if (mbw == USB_FUNCTION_BITMBW_16)
+        {
+            g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].size = 1;  /* 16bit transfer */
+        }
+        else
+        {
+            g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].size = 0;  /* 8bit transfer */
+        }
+
+        g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].fifo   = USB_FUNCTION_D1FIFO_DMA;
+        g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].dir    = USB_FUNCTION_BUF2FIFO;
+        g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].buffer = (uint32_t)g_usb0_function_data_pointer[pipe];
+        g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].bytes  = count;
+
+        Userdef_USB_usb0_function_start_dma(&g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO], dfacc);
+
+        usb0_function_set_curpipe2(pipe, USB_FUNCTION_D1DMA, DEVDRV_USBF_NO, mbw, dfacc);
+
+        RZA_IO_RegWrite_16(&USB200.D1FIFOSEL, 1, USB_DnFIFOSEL_DREQE_SHIFT, USB_DnFIFOSEL_DREQE);
+
+        g_usb0_function_data_count[pipe]    = 0;
+        g_usb0_function_data_pointer[pipe] += count;
+
+        status = DEVDRV_USBF_WRITEDMA;                             /* DMA write  */
+    }
+    else
+    {
+        if (RZA_IO_RegRead_16(&USB200.D1FIFOCTR, USB_DnFIFOCTR_BVAL_SHIFT, USB_DnFIFOCTR_BVAL) == 0)
+        {
+            RZA_IO_RegWrite_16(&USB200.D1FIFOCTR, 1, USB_DnFIFOCTR_BVAL_SHIFT, USB_DnFIFOCTR_BVAL); /* Short Packet */
+        }
+        status = DEVDRV_USBF_WRITESHRT;                             /* Short Packet is end of write */
+    }
+
+    return status;                                                  /* End or Err or Continue */
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_start_receive_transfer
+* Description  : Starts USB data reception using the pipe specified in the argument.
+*              : The FIFO for using is set in the pipe definition table.
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint32_t size      ; Data Size
+*              : uint8_t *data      ; Data Address
+* Return Value : none
+*******************************************************************************/
+void usb0_function_start_receive_transfer (uint16_t pipe, uint32_t size, uint8_t * data)
+{
+    uint16_t usefifo;
+
+    usb0_function_clear_bemp_sts(pipe);
+    usb0_function_clear_brdy_sts(pipe);
+    usb0_function_clear_nrdy_sts(pipe);
+
+    usefifo = (uint16_t)(g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE);
+
+    switch (usefifo)
+    {
+        case USB_FUNCTION_D0FIFO_USE:
+            usb0_function_start_receive_trns_d0(pipe, size, data);
+        break;
+
+        case USB_FUNCTION_D1FIFO_USE:
+            usb0_function_start_receive_trns_d1(pipe, size, data);
+        break;
+
+        case USB_FUNCTION_D0FIFO_DMA:
+            usb0_function_start_receive_dma_d0(pipe, size, data);
+        break;
+
+        case USB_FUNCTION_D1FIFO_DMA:
+            usb0_function_start_receive_dma_d1(pipe, size, data);
+        break;
+
+        default:
+            usb0_function_start_receive_trns_c(pipe, size, data);
+        break;
+    }
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_start_receive_trns_c
+* Description  : Reads data from the buffer allocated in the pipe specified in the argument.
+*              : Reads data by CPU transfer using CFIFO.
+*              : When storing data in the buffer allocated in the pipe specified in the
+*              : argument, BRDY interrupt is generated to read data
+*              : in the interrupt.
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint32_t size      ; Data Size
+*              : uint8_t *data      ; Data Address
+* Return Value : none
+*******************************************************************************/
+static void usb0_function_start_receive_trns_c (uint16_t pipe, uint32_t size, uint8_t * data)
+{
+    uint16_t mbw;
+
+    usb0_function_set_pid_nak(pipe);
+    g_usb0_function_data_count[pipe]   = size;
+    g_usb0_function_data_pointer[pipe] = (uint8_t *)data;
+    g_usb0_function_PipeIgnore[pipe]   = 0;
+
+    g_usb0_function_PipeDataSize[pipe] = size;
+    g_usb0_function_pipe_status[pipe]  = DEVDRV_USBF_PIPE_WAIT;
+
+    mbw = usb0_function_get_mbw(size, (uint32_t)data);
+    usb0_function_set_curpipe(USB_FUNCTION_PIPE0, USB_FUNCTION_CUSE, USB_FUNCTION_CFIFO_READ, mbw);
+    USB200.CFIFOCTR = USB_FUNCTION_BITBCLR;
+
+    usb0_function_set_transaction_counter(pipe, size);
+
+    usb0_function_aclrm(pipe);
+
+    usb0_function_enable_nrdy_int(pipe);
+    usb0_function_enable_brdy_int(pipe);
+
+    usb0_function_set_pid_buf(pipe);
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_start_receive_trns_d0
+* Description  : Reads data from the buffer allocated in the pipe specified in the argument.
+*              : Reads data by CPU transfer using D0FIFO.
+*              : This function does not read data from the buffer.
+*              : When storing data in the buffer allocated in the pipe specified
+*              : in the argument, BRDY interrupt is generated to read data in the
+*              : interrupt.
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint32_t size      ; Data Size
+*              : uint8_t *data      ; Data Address
+* Return Value : none
+*******************************************************************************/
+static void usb0_function_start_receive_trns_d0 (uint16_t pipe, uint32_t size, uint8_t * data)
+{
+    uint16_t mbw;
+
+    usb0_function_set_pid_nak(pipe);
+    g_usb0_function_data_count[pipe]   = size;
+    g_usb0_function_data_pointer[pipe] = (uint8_t *)data;
+    g_usb0_function_PipeIgnore[pipe]   = 0;
+
+    g_usb0_function_PipeDataSize[pipe] = size;
+    g_usb0_function_pipe_status[pipe]  = DEVDRV_USBF_PIPE_WAIT;
+
+    mbw = usb0_function_get_mbw(size, (uint32_t)data);
+    usb0_function_set_curpipe(USB_FUNCTION_PIPE0, USB_FUNCTION_D0USE, DEVDRV_USBF_NO, mbw);
+
+    usb0_function_set_transaction_counter(pipe, size);
+
+    usb0_function_aclrm(pipe);
+
+    usb0_function_enable_nrdy_int(pipe);
+    usb0_function_enable_brdy_int(pipe);
+
+    usb0_function_set_pid_buf(pipe);
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_start_receive_trns_d1
+* Description  : Reads data from the buffer allocated in the pipe specified in the argument.
+*              : Reads data by CPU transfer using D1FIFO.
+*              : This function does not read data from the buffer.
+*              : When storing data in the buffer allocated in the pipe specified
+*              : in the argument, BRDY interrupt is generated to read data.
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint32_t size      ; Data Size
+*              : uint8_t *data      ; Data Address
+* Return Value : none
+*******************************************************************************/
+static void usb0_function_start_receive_trns_d1 (uint16_t pipe, uint32_t size, uint8_t * data)
+{
+    uint16_t mbw;
+
+    usb0_function_set_pid_nak(pipe);
+    g_usb0_function_data_count[pipe]   = size;
+    g_usb0_function_data_pointer[pipe] = (uint8_t *)data;
+    g_usb0_function_PipeIgnore[pipe]   = 0;
+
+    g_usb0_function_PipeDataSize[pipe] = size;
+    g_usb0_function_pipe_status[pipe]  = DEVDRV_USBF_PIPE_WAIT;
+
+    mbw = usb0_function_get_mbw(size, (uint32_t)data);
+    usb0_function_set_curpipe(USB_FUNCTION_PIPE0, USB_FUNCTION_D1USE, DEVDRV_USBF_NO, mbw);
+
+    usb0_function_set_transaction_counter(pipe, size);
+
+    usb0_function_aclrm(pipe);
+
+    usb0_function_enable_nrdy_int(pipe);
+    usb0_function_enable_brdy_int(pipe);
+
+    usb0_function_set_pid_buf(pipe);
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_start_receive_dma_d0
+* Description  : Reads data from the buffer allocated in the pipe specified in the argument.
+*              : Reads data by DMA transfer using D0FIFO.
+*              : This function does not read data from the buffer.
+*              : When storing data in the buffer allocated in the pipe specified
+*              : in the argument, delivered read request to DMAC to read data from
+*              : the buffer by DMAC.
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint32_t size      ; Data Size
+*              : uint8_t *data      ; Data Address
+* Return Value : none
+*******************************************************************************/
+static void usb0_function_start_receive_dma_d0 (uint16_t pipe, uint32_t size, uint8_t * data)
+{
+    uint16_t mbw;
+
+    usb0_function_set_pid_nak(pipe);
+    g_usb0_function_data_count[pipe]   = size;
+    g_usb0_function_data_pointer[pipe] = (uint8_t *)data;
+    g_usb0_function_PipeIgnore[pipe]   = 0;
+
+    g_usb0_function_PipeDataSize[pipe] = 0;
+    g_usb0_function_pipe_status[pipe]  = DEVDRV_USBF_PIPE_WAIT;
+
+    mbw = usb0_function_get_mbw(size, (uint32_t)data);
+    usb0_function_set_curpipe(USB_FUNCTION_PIPE0, USB_FUNCTION_D0USE, DEVDRV_USBF_NO, mbw);
+
+    usb0_function_set_transaction_counter(pipe, size);
+
+    usb0_function_aclrm(pipe);
+
+    if (RZA_IO_RegRead_16(&g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 1)
+    {
+        usb0_function_read_dma(pipe);
+
+        usb0_function_enable_nrdy_int(pipe);
+        usb0_function_enable_brdy_int(pipe);
+    }
+    else
+    {
+        usb0_function_enable_nrdy_int(pipe);
+        usb0_function_enable_brdy_int(pipe);
+    }
+
+    usb0_function_set_pid_buf(pipe);
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_start_receive_dma_d1
+* Description  : Read data from the buffer allocated in the pipe specified in the argument.
+*              : Reads data by DMA transfer using D0FIFO.
+*              : This function does not read data from the buffer.
+*              : When storing data in the buffer allocated in the pipe specified
+*              : in the argument, delivered read request to DMAC to read data from
+*              : the buffer by DMAC.
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint32_t size      ; Data Size
+*              : uint8_t *data      ; Data Address
+* Return Value : none
+*******************************************************************************/
+static void usb0_function_start_receive_dma_d1 (uint16_t pipe, uint32_t size, uint8_t * data)
+{
+    uint16_t mbw;
+
+    usb0_function_set_pid_nak(pipe);
+    g_usb0_function_data_count[pipe]   = size;
+    g_usb0_function_data_pointer[pipe] = (uint8_t *)data;
+    g_usb0_function_PipeIgnore[pipe]   = 0;
+
+    g_usb0_function_PipeDataSize[pipe] = 0;
+    g_usb0_function_pipe_status[pipe]  = DEVDRV_USBF_PIPE_WAIT;
+
+    mbw = usb0_function_get_mbw(size, (uint32_t)data);
+    usb0_function_set_curpipe(USB_FUNCTION_PIPE0, USB_FUNCTION_D1USE, DEVDRV_USBF_NO, mbw);
+
+    usb0_function_set_transaction_counter(pipe, size);
+
+    usb0_function_aclrm(pipe);
+
+    if (RZA_IO_RegRead_16(&g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 1)
+    {
+        usb0_function_read_dma(pipe);
+
+        usb0_function_enable_nrdy_int(pipe);
+        usb0_function_enable_brdy_int(pipe);
+    }
+    else
+    {
+        usb0_function_enable_nrdy_int(pipe);
+        usb0_function_enable_brdy_int(pipe);
+    }
+
+    usb0_function_set_pid_buf(pipe);
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_read_buffer
+* Description  : Reads data from the buffer allocated in the pipe specified
+*              : in the argument.
+*              : Uses FIF0 set in the pipe definition table.
+* Arguments    : uint16_t pipe     ; Pipe Number
+* Return Value : USB_FUNCTION_READEND          ; Read end
+*              : USB_FUNCTION_READSHRT         ; short data
+*              : USB_FUNCTION_READING          ; Continue of data read
+*              : USB_FUNCTION_READOVER         ; buffer over
+*              : DEVDRV_USBF_FIFOERROR         ; FIFO status
+*******************************************************************************/
+uint16_t usb0_function_read_buffer (uint16_t pipe)
+{
+    uint16_t status;
+
+    g_usb0_function_PipeIgnore[pipe] = 0;
+
+    if ((g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) == USB_FUNCTION_D0FIFO_USE)
+    {
+        status = usb0_function_read_buffer_d0(pipe);
+    }
+    else if ((g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) == USB_FUNCTION_D1FIFO_USE)
+    {
+        status = usb0_function_read_buffer_d1(pipe);
+    }
+    else
+    {
+        status = usb0_function_read_buffer_c(pipe);
+    }
+
+    switch (status)
+    {
+        case USB_FUNCTION_READING:                                      /* Continue of data read */
+        break;
+
+        case USB_FUNCTION_READEND:                                      /* End of data read */
+        case USB_FUNCTION_READSHRT:                                     /* End of data read */
+            usb0_function_disable_brdy_int(pipe);
+            g_usb0_function_PipeDataSize[pipe] -= g_usb0_function_data_count[pipe];
+            g_usb0_function_pipe_status[pipe]   = DEVDRV_USBF_PIPE_DONE;
+        break;
+
+        case USB_FUNCTION_READOVER:                                     /* buffer over */
+            if ((g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) == USB_FUNCTION_D0FIFO_USE)
+            {
+                USB200.D0FIFOCTR = USB_FUNCTION_BITBCLR;                /* Clear BCLR */
+            }
+            else if ((g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) == USB_FUNCTION_D1FIFO_USE)
+            {
+                USB200.D1FIFOCTR = USB_FUNCTION_BITBCLR;                /* Clear BCLR */
+            }
+            else
+            {
+                USB200.CFIFOCTR = USB_FUNCTION_BITBCLR;                 /* Clear BCLR */
+            }
+            usb0_function_disable_brdy_int(pipe);                       /* Disable Ready Interrupt */
+            g_usb0_function_PipeDataSize[pipe] -= g_usb0_function_data_count[pipe];
+            g_usb0_function_pipe_status[pipe]   = DEVDRV_USBF_FIFOERROR;
+        break;
+
+        case DEVDRV_USBF_FIFOERROR:                                     /* FIFO access status */
+        default:
+            usb0_function_disable_brdy_int(pipe);                       /* Disable Ready Interrupt */
+            g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_FIFOERROR;
+        break;
+    }
+
+    return status;                                                      /* End or Err or Continue */
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_read_buffer_c
+* Description  : Reads data from the buffer allocated in the pipe specified in the argument.
+*              : Reads data by CPU transfer using CFIFO.
+* Arguments    : uint16_t pipe     ; Pipe Number
+* Return Value : USB_FUNCTION_READEND          ; Read end
+*              : USB_FUNCTION_READSHRT         ; short data
+*              : USB_FUNCTION_READING          ; Continue of data read
+*              : USB_FUNCTION_READOVER         ; buffer over
+*              : DEVDRV_USBF_FIFOERROR         ; FIFO status
+*******************************************************************************/
+uint16_t usb0_function_read_buffer_c (uint16_t pipe)
+{
+    uint32_t count;
+    uint32_t dtln;
+    uint16_t buffer;
+    uint16_t mxps;
+    uint16_t status;
+    uint16_t mbw;
+
+    mbw    = usb0_function_get_mbw(g_usb0_function_data_count[pipe], (uint32_t)g_usb0_function_data_pointer[pipe]);
+    buffer = usb0_function_change_fifo_port(pipe, USB_FUNCTION_CUSE, DEVDRV_USBF_NO, mbw);
+
+    if (buffer == DEVDRV_USBF_FIFOERROR)                        /* FIFO access status */
+    {
+        return DEVDRV_USBF_FIFOERROR;
+    }
+
+    dtln = (uint32_t)(buffer & USB_FUNCTION_BITDTLN);
+    mxps = usb0_function_get_mxps(pipe);                        /* Max Packet Size */
+
+    if (g_usb0_function_data_count[pipe] < dtln)                /* Buffer Over ? */
+    {
+        status = USB_FUNCTION_READOVER;
+        usb0_function_set_pid_nak(pipe);                        /* Set NAK */
+        count = g_usb0_function_data_count[pipe];
+    }
+    else if (g_usb0_function_data_count[pipe] == dtln)          /* just Receive Size */
+    {
+        status = USB_FUNCTION_READEND;
+        usb0_function_set_pid_nak(pipe);                        /* Set NAK */
+        count = dtln;
+
+        if (count == 0)
+        {
+            status = USB_FUNCTION_READSHRT;                     /* Null Packet receive */
+        }
+
+        if ((count % mxps) != 0)
+        {
+            status = USB_FUNCTION_READSHRT;                     /* Short Packet receive */
+        }
+    }
+    else                                                        /* continue Receive data */
+    {
+        status = USB_FUNCTION_READING;
+        count  = dtln;
+
+        if (count == 0)
+        {
+            status = USB_FUNCTION_READSHRT;                     /* Null Packet receive */
+            usb0_function_set_pid_nak(pipe);                    /* Set NAK */
+        }
+
+        if ((count % mxps) != 0)
+        {
+            status = USB_FUNCTION_READSHRT;                     /* Short Packet receive */
+            usb0_function_set_pid_nak(pipe);                    /* Set NAK */
+        }
+    }
+
+    if (count == 0)                                             /* 0 length packet */
+    {
+        USB200.CFIFOCTR = USB_FUNCTION_BITBCLR;                 /* Clear BCLR */
+    }
+    else
+    {
+        usb0_function_read_c_fifo(pipe, (uint16_t)count);
+    }
+
+    g_usb0_function_data_count[pipe] -= count;
+
+    return status;                                              /* End or Err or Continue */
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_read_buffer_d0
+* Description  : Reads data from the buffer allocated in the pipe specified in
+*              : the argument.
+*              : Reads data by CPU transfer using D0FIFO.
+* Arguments    : uint16_t pipe     ; Pipe Number
+* Return Value : USB_FUNCTION_READEND          ; Read end
+*              : USB_FUNCTION_READSHRT         ; short data
+*              : USB_FUNCTION_READING          ; Continue of data read
+*              : USB_FUNCTION_READOVER         ; buffer over
+*              : DEVDRV_USBF_FIFOERROR         ; FIFO status
+*******************************************************************************/
+uint16_t usb0_function_read_buffer_d0 (uint16_t pipe)
+{
+    uint32_t count;
+    uint32_t dtln;
+    uint16_t buffer;
+    uint16_t mxps;
+    uint16_t status;
+    uint16_t mbw;
+    uint16_t pipebuf_size;
+
+    mbw    = usb0_function_get_mbw(g_usb0_function_data_count[pipe], (uint32_t)g_usb0_function_data_pointer[pipe]);
+    buffer = usb0_function_change_fifo_port(pipe, USB_FUNCTION_D0USE, DEVDRV_USBF_NO, mbw);
+
+    if (buffer == DEVDRV_USBF_FIFOERROR)                        /* FIFO access status */
+    {
+        return DEVDRV_USBF_FIFOERROR;
+    }
+
+    dtln = (uint32_t)(buffer & USB_FUNCTION_BITDTLN);
+    mxps = usb0_function_get_mxps(pipe);                        /* Max Packet Size */
+
+    if (g_usb0_function_data_count[pipe] < dtln)                /* Buffer Over ? */
+    {
+        status = USB_FUNCTION_READOVER;
+        usb0_function_set_pid_nak(pipe);                        /* Set NAK */
+        count = g_usb0_function_data_count[pipe];
+    }
+    else if (g_usb0_function_data_count[pipe] == dtln)          /* just Receive Size */
+    {
+        status = USB_FUNCTION_READEND;
+        usb0_function_set_pid_nak(pipe);                        /* Set NAK */
+        count = dtln;
+
+        if (count == 0)
+        {
+            status = USB_FUNCTION_READSHRT;                     /* Null Packet receive */
+        }
+
+        if ((count % mxps) != 0)
+        {
+            status = USB_FUNCTION_READSHRT;                     /* Short Packet receive */
+        }
+    }
+    else                                                        /* continue Receive data */
+    {
+        status = USB_FUNCTION_READING;
+        count  = dtln;
+
+        if (count == 0)
+        {
+            status = USB_FUNCTION_READSHRT;                     /* Null Packet receive */
+            usb0_function_set_pid_nak(pipe);                    /* Set NAK */
+        }
+
+        if ((count % mxps) != 0)
+        {
+            status = USB_FUNCTION_READSHRT;                     /* Short Packet receive */
+            usb0_function_set_pid_nak(pipe);                    /* Set NAK */
+        }
+        else
+        {
+            pipebuf_size = usb0_function_get_buf_size(pipe);    /* Data buffer size */
+
+            if (count != pipebuf_size)
+            {
+                status = USB_FUNCTION_READSHRT;                 /* Short Packet receive */
+                usb0_function_set_pid_nak(pipe);                /* Set NAK */
+            }
+        }
+    }
+
+    if (count == 0)                                             /* 0 length packet */
+    {
+        USB200.D0FIFOCTR = USB_FUNCTION_BITBCLR;                /* Clear BCLR */
+    }
+    else
+    {
+        usb0_function_read_d0_fifo(pipe, (uint16_t)count);
+    }
+
+    g_usb0_function_data_count[pipe] -= count;
+
+    return status;                                              /* End or Err or Continue */
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_read_buffer_d1
+* Description  : Reads data from the buffer allocated in the pipe specified
+*              : in the argument.
+*              : Reads data by CPU transfer using D1FIFO.
+* Arguments    : uint16_t pipe     ; Pipe Number
+* Return Value : USB_FUNCTION_READEND          ; Read end
+*              : USB_FUNCTION_READSHRT         ; short data
+*              : USB_FUNCTION_READING          ; Continue of data read
+*              : USB_FUNCTION_READOVER         ; buffer over
+*              : DEVDRV_USBF_FIFOERROR         ; FIFO status
+*******************************************************************************/
+uint16_t usb0_function_read_buffer_d1 (uint16_t pipe)
+{
+    uint32_t count;
+    uint32_t dtln;
+    uint16_t buffer;
+    uint16_t mxps;
+    uint16_t status;
+    uint16_t mbw;
+    uint16_t pipebuf_size;
+
+    mbw    = usb0_function_get_mbw(g_usb0_function_data_count[pipe], (uint32_t)g_usb0_function_data_pointer[pipe]);
+    buffer = usb0_function_change_fifo_port(pipe, USB_FUNCTION_D1USE, DEVDRV_USBF_NO, mbw);
+
+    if (buffer == DEVDRV_USBF_FIFOERROR)                        /* FIFO access status */
+    {
+        return DEVDRV_USBF_FIFOERROR;
+    }
+
+    dtln = (uint32_t)(buffer & USB_FUNCTION_BITDTLN);
+    mxps = usb0_function_get_mxps(pipe);                        /* Max Packet Size */
+
+    if (g_usb0_function_data_count[pipe] < dtln)                /* Buffer Over ? */
+    {
+        status = USB_FUNCTION_READOVER;
+        usb0_function_set_pid_nak(pipe);                        /* Set NAK */
+        count = g_usb0_function_data_count[pipe];
+    }
+    else if (g_usb0_function_data_count[pipe] == dtln)          /* just Receive Size */
+    {
+        status = USB_FUNCTION_READEND;
+        usb0_function_set_pid_nak(pipe);                        /* Set NAK */
+        count = dtln;
+        if (count == 0)
+        {
+            status = USB_FUNCTION_READSHRT;                     /* Null Packet receive */
+        }
+
+        if ((count % mxps) != 0)
+        {
+            status = USB_FUNCTION_READSHRT;                     /* Short Packet receive */
+        }
+    }
+    else                                                        /* continue Receive data */
+    {
+        status = USB_FUNCTION_READING;
+        count  = dtln;
+        if (count == 0)
+        {
+            status = USB_FUNCTION_READSHRT;                     /* Null Packet receive */
+            usb0_function_set_pid_nak(pipe);                    /* Set NAK */
+        }
+
+        if ((count % mxps) != 0)
+        {
+            status = USB_FUNCTION_READSHRT;                     /* Short Packet receive */
+            usb0_function_set_pid_nak(pipe);                    /* Set NAK */
+        }
+        else
+        {
+            pipebuf_size = usb0_function_get_buf_size(pipe);    /* Data buffer size */
+
+            if (count != pipebuf_size)
+            {
+                status = USB_FUNCTION_READSHRT;                 /* Short Packet receive */
+                usb0_function_set_pid_nak(pipe);                /* Set NAK */
+            }
+        }
+    }
+
+    if (count == 0)                                             /* 0 length packet */
+    {
+        USB200.D1FIFOCTR = USB_FUNCTION_BITBCLR;                /* Clear BCLR */
+    }
+    else
+    {
+        usb0_function_read_d1_fifo(pipe, (uint16_t)count);
+    }
+
+    g_usb0_function_data_count[pipe] -= count;
+
+    return status;                                              /* End or Err or Continue */
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_read_dma
+* Description  : Reads data from the buffer allocated in the pipe specified
+*              : in the argument.
+*              : Reads data by DMA transfer using D0FIFO or D1FIFO.
+* Arguments    : uint16_t pipe     ; Pipe Number
+* Return Value : USB_FUNCTION_READEND          ; Read end
+*              : USB_FUNCTION_READSHRT         ; short data
+*              : USB_FUNCTION_READING          ; Continue of data read
+*              : USB_FUNCTION_READOVER         ; buffer over
+*              : DEVDRV_USBF_FIFOERROR         ; FIFO status
+*******************************************************************************/
+uint16_t usb0_function_read_dma (uint16_t pipe)
+{
+    uint16_t status;
+
+    g_usb0_function_PipeIgnore[pipe] = 0;
+    if ((g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) == USB_FUNCTION_D0FIFO_DMA)
+    {
+        status = usb0_function_read_dma_d0(pipe);
+    }
+    else
+    {
+        status = usb0_function_read_dma_d1(pipe);
+    }
+
+    switch (status)
+    {
+        case USB_FUNCTION_READING:                                      /* Continue of data read */
+        break;
+
+        case USB_FUNCTION_READZERO:                                     /* End of data read */
+            usb0_function_disable_brdy_int(pipe);
+            g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE;
+        break;
+
+        case USB_FUNCTION_READEND:                                      /* End of data read */
+        case USB_FUNCTION_READSHRT:                                     /* End of data read */
+            usb0_function_disable_brdy_int(pipe);
+
+            if (RZA_IO_RegRead_16(&g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 1)
+            {
+                g_usb0_function_PipeDataSize[pipe] -= g_usb0_function_data_count[pipe];
+            }
+        break;
+
+        case USB_FUNCTION_READOVER:                                     /* buffer over */
+            usb0_function_disable_brdy_int(pipe);                       /* Disable Ready Interrupt */
+
+            if (RZA_IO_RegRead_16(&g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 1)
+            {
+                g_usb0_function_PipeDataSize[pipe] -= g_usb0_function_data_count[pipe];
+            }
+            g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_FIFOERROR;
+        break;
+
+        case DEVDRV_USBF_FIFOERROR:                                     /* FIFO access status */
+        default:
+            usb0_function_disable_brdy_int(pipe);                       /* Disable Ready Interrupt */
+            g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_FIFOERROR;
+        break;
+    }
+
+    return status;                                                      /* End or Err or Continue */
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_read_dma_d0
+* Description  : Writes data in the buffer allocated in the pipe specified
+*              : in the argument.
+*              : Reads data by DMA transfer using D0FIFO.
+* Arguments    : uint16_t pipe     ; Pipe Number
+* Return Value : USB_FUNCTION_READEND          ; Read end
+*              : USB_FUNCTION_READSHRT         ; short data
+*              : USB_FUNCTION_READZERO         ; zero data
+*              : USB_FUNCTION_READING          ; Continue of data read
+*              : USB_FUNCTION_READOVER         ; buffer over
+*              : DEVDRV_USBF_FIFOERROR         ; FIFO status
+*******************************************************************************/
+static uint16_t usb0_function_read_dma_d0 (uint16_t pipe)
+{
+    uint32_t count;
+    uint32_t dtln;
+    uint16_t buffer;
+    uint16_t mxps;
+    uint16_t status;
+    uint16_t mbw;
+    uint16_t dfacc = 0;
+    uint16_t pipebuf_size;
+
+    g_usb0_function_DmaStatus[USB_FUNCTION_D0FIFO] = USB_FUNCTION_DMA_READY;
+
+    mbw = usb0_function_get_mbw(g_usb0_function_data_count[pipe], (uint32_t)g_usb0_function_data_pointer[pipe]);
+
+    if (RZA_IO_RegRead_16(&g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 1)
+    {
+        count  = g_usb0_function_data_count[pipe];
+        status = USB_FUNCTION_READING;
+    }
+    else
+    {
+        buffer = usb0_function_change_fifo_port(pipe, USB_FUNCTION_D0DMA, DEVDRV_USBF_NO, mbw);
+
+        if (buffer == DEVDRV_USBF_FIFOERROR)                        /* FIFO access status */
+        {
+            return DEVDRV_USBF_FIFOERROR;
+        }
+
+        dtln = (uint32_t)(buffer & USB_FUNCTION_BITDTLN);
+        mxps = usb0_function_get_mxps(pipe);                        /* Max Packet Size */
+
+        if (g_usb0_function_data_count[pipe] < dtln)                /* Buffer Over ? */
+        {
+            status = USB_FUNCTION_READOVER;
+            count  = g_usb0_function_data_count[pipe];
+        }
+        else if (g_usb0_function_data_count[pipe] == dtln)          /* just Receive Size */
+        {
+            status = USB_FUNCTION_READEND;
+            count  = dtln;
+            if (count == 0)
+            {
+                status = USB_FUNCTION_READSHRT;                     /* Null Packet receive */
+            }
+
+            if ((count % mxps) != 0)
+            {
+                status = USB_FUNCTION_READSHRT;                     /* Short Packet receive */
+            }
+        }
+        else                                                        /* continue Receive data */
+        {
+            status = USB_FUNCTION_READING;
+            count  = dtln;
+
+            if (count == 0)
+            {
+                status = USB_FUNCTION_READSHRT;                     /* Null Packet receive */
+            }
+
+            if ((count % mxps) != 0)
+            {
+                status = USB_FUNCTION_READSHRT;                     /* Short Packet receive */
+            }
+            else
+            {
+                pipebuf_size = usb0_function_get_buf_size(pipe);    /* Data buffer size */
+                if (count != pipebuf_size)
+                {
+                    status = USB_FUNCTION_READSHRT;                 /* Short Packet receive */
+                }
+            }
+        }
+    }
+
+    if (count == 0)                                                 /* 0 length packet */
+    {
+        if (RZA_IO_RegRead_16(&g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0)
+        {
+            USB200.D0FIFOCTR = USB_FUNCTION_BITBCLR;                /* Clear BCLR */
+            status = USB_FUNCTION_READZERO;                         /* Null Packet receive */
+        }
+        else
+        {
+            usb0_function_set_curpipe(pipe, USB_FUNCTION_D0DMA, DEVDRV_USBF_NO, mbw);
+                                                                    /* transaction counter No set */
+                                                                    /* FRDY = 1, DTLN = 0 -> BRDY */
+        }
+    }
+    else
+    {
+        dfacc = usb0_function_set_dfacc_d0(mbw, count);
+
+        if (mbw == USB_FUNCTION_BITMBW_32)
+        {
+            g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].size = 2;  /* 32bit transfer */
+        }
+        else if (mbw == USB_FUNCTION_BITMBW_16)
+        {
+            g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].size = 1;  /* 16bit transfer */
+        }
+        else
+        {
+            g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].size = 0;  /* 8bit transfer */
+        }
+
+        g_usb0_function_DmaPipe[USB_FUNCTION_D0FIFO] = pipe;        /* not use in read operation */
+        g_usb0_function_DmaBval[USB_FUNCTION_D0FIFO] = 0;           /* not use in read operation */
+
+        g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].fifo   = USB_FUNCTION_D0FIFO_DMA;
+        g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].dir    = USB_FUNCTION_FIFO2BUF;
+        g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].buffer = (uint32_t)g_usb0_function_data_pointer[pipe];
+        g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO].bytes  = count;
+
+        if (status == USB_FUNCTION_READING)
+        {
+            g_usb0_function_DmaStatus[USB_FUNCTION_D0FIFO] = USB_FUNCTION_DMA_BUSY;
+        }
+        else
+        {
+            g_usb0_function_DmaStatus[USB_FUNCTION_D0FIFO] = USB_FUNCTION_DMA_BUSYEND;
+        }
+
+        Userdef_USB_usb0_function_start_dma(&g_usb0_function_DmaInfo[USB_FUNCTION_D0FIFO], dfacc);
+
+        usb0_function_set_curpipe2(pipe, USB_FUNCTION_D0DMA, DEVDRV_USBF_NO, mbw, dfacc);
+
+        RZA_IO_RegWrite_16(&USB200.D0FIFOSEL,
+                            1,
+                            USB_DnFIFOSEL_DREQE_SHIFT,
+                            USB_DnFIFOSEL_DREQE);
+    }
+
+    if (RZA_IO_RegRead_16(&g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0)
+    {
+        g_usb0_function_data_count[pipe]   -= count;
+        g_usb0_function_data_pointer[pipe] += count;
+        g_usb0_function_PipeDataSize[pipe] += count;
+    }
+
+    return status;                                                  /* End or Err or Continue */
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_read_dma_d1
+* Description  : Reads data from the buffer allocated in the pipe specified in
+*              : the argument.
+*              : Reads data by DMA transfer using D1FIFO.
+* Arguments    : uint16_t pipe     ; Pipe Number
+* Return Value : USB_FUNCTION_READEND          ; Read end
+*              : USB_FUNCTION_READSHRT         ; short data
+*              : USB_FUNCTION_READZERO         ; zero data
+*              : USB_FUNCTION_READING          ; Continue of data read
+*              : USB_FUNCTION_READOVER         ; buffer over
+*              : DEVDRV_USBF_FIFOERROR         ; FIFO status
+*******************************************************************************/
+static uint16_t usb0_function_read_dma_d1 (uint16_t pipe)
+{
+    uint32_t count;
+    uint32_t dtln;
+    uint16_t buffer;
+    uint16_t mxps;
+    uint16_t status;
+    uint16_t mbw;
+    uint16_t dfacc=0;
+    uint16_t pipebuf_size;
+
+    g_usb0_function_DmaStatus[USB_FUNCTION_D1FIFO] = USB_FUNCTION_DMA_READY;
+
+    mbw = usb0_function_get_mbw(g_usb0_function_data_count[pipe], (uint32_t)g_usb0_function_data_pointer[pipe]);
+
+    if (RZA_IO_RegRead_16(&g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 1)
+    {
+        count  = g_usb0_function_data_count[pipe];
+        status = USB_FUNCTION_READING;
+    }
+    else
+    {
+        buffer = usb0_function_change_fifo_port(pipe, USB_FUNCTION_D1DMA, DEVDRV_USBF_NO, mbw);
+        if (buffer == DEVDRV_USBF_FIFOERROR)                        /* FIFO access status */
+        {
+            return DEVDRV_USBF_FIFOERROR;
+        }
+
+        dtln = (uint32_t)(buffer & USB_FUNCTION_BITDTLN);
+        mxps = usb0_function_get_mxps(pipe);                        /* Max Packet Size */
+
+        if (g_usb0_function_data_count[pipe] < dtln)                /* Buffer Over ? */
+        {
+            status = USB_FUNCTION_READOVER;
+            count  = g_usb0_function_data_count[pipe];
+        }
+        else if (g_usb0_function_data_count[pipe] == dtln)          /* just Receive Size */
+        {
+            status = USB_FUNCTION_READEND;
+            count  = dtln;
+            if (count == 0)
+            {
+                status = USB_FUNCTION_READSHRT;                     /* Null Packet receive */
+            }
+
+            if ((count % mxps) != 0)
+            {
+                status = USB_FUNCTION_READSHRT;                     /* Short Packet receive */
+            }
+        }
+        else                                                        /* continue Receive data */
+        {
+            status = USB_FUNCTION_READING;
+            count  = dtln;
+            if (count == 0)
+            {
+                status = USB_FUNCTION_READSHRT;                     /* Null Packet receive */
+            }
+
+            if ((count % mxps) != 0)
+            {
+                status = USB_FUNCTION_READSHRT;                     /* Short Packet receive */
+            }
+            else
+            {
+                pipebuf_size = usb0_function_get_buf_size(pipe);    /* Data buffer size */
+                if (count != pipebuf_size)
+                {
+                    status = USB_FUNCTION_READSHRT;                 /* Short Packet receive */
+                }
+            }
+        }
+    }
+
+    if (count == 0)                                                 /* 0 length packet */
+    {
+        if (RZA_IO_RegRead_16(&g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0)
+        {
+            USB200.D1FIFOCTR = USB_FUNCTION_BITBCLR;                /* Clear BCLR */
+            status = USB_FUNCTION_READZERO;                         /* Null Packet receive */
+        }
+        else
+        {
+            usb0_function_set_curpipe(pipe, USB_FUNCTION_D1DMA, DEVDRV_USBF_NO, mbw);
+                                                                    /* transaction counter No set */
+                                                                    /* FRDY = 1, DTLN = 0 -> BRDY */
+        }
+    }
+    else
+    {
+        dfacc = usb0_function_set_dfacc_d1(mbw, count);
+
+        if (mbw == USB_FUNCTION_BITMBW_32)
+        {
+            g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].size = 2;  /* 32bit transfer */
+        }
+        else if (mbw == USB_FUNCTION_BITMBW_16)
+        {
+            g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].size = 1;  /* 16bit transfer */
+        }
+        else
+        {
+            g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].size = 0;  /* 8bit transfer */
+        }
+
+        g_usb0_function_DmaPipe[USB_FUNCTION_D1FIFO] = pipe;        /* not use in read operation */
+        g_usb0_function_DmaBval[USB_FUNCTION_D1FIFO] = 0;           /* not use in read operation */
+
+        g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].fifo   = USB_FUNCTION_D1FIFO_DMA;
+        g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].dir    = USB_FUNCTION_FIFO2BUF;
+        g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].buffer = (uint32_t)g_usb0_function_data_pointer[pipe];
+        g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO].bytes  = count;
+
+        if (status == USB_FUNCTION_READING)
+        {
+            g_usb0_function_DmaStatus[USB_FUNCTION_D1FIFO] = USB_FUNCTION_DMA_BUSY;
+        }
+        else
+        {
+            g_usb0_function_DmaStatus[USB_FUNCTION_D1FIFO] = USB_FUNCTION_DMA_BUSYEND;
+        }
+
+        Userdef_USB_usb0_function_start_dma(&g_usb0_function_DmaInfo[USB_FUNCTION_D1FIFO], dfacc);
+
+        usb0_function_set_curpipe2(pipe, USB_FUNCTION_D1DMA, DEVDRV_USBF_NO, mbw, dfacc);
+
+        RZA_IO_RegWrite_16(&USB200.D1FIFOSEL,
+                            1,
+                            USB_DnFIFOSEL_DREQE_SHIFT,
+                            USB_DnFIFOSEL_DREQE);
+    }
+
+    if (RZA_IO_RegRead_16(&g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0)
+    {
+        g_usb0_function_data_count[pipe]   -= count;
+        g_usb0_function_data_pointer[pipe] += count;
+        g_usb0_function_PipeDataSize[pipe] += count;
+    }
+
+    return status;                                                  /* End or Err or Continue */
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_change_fifo_port
+* Description  : Allocates FIF0 specified by the argument in the pipe assigned
+*              : by the argument. After allocating FIF0, waits in the software
+*              : till the corresponding pipe becomes ready.
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint16_t fifosel   ; Select FIFO
+*              : uint16_t isel      ; FIFO Access Direction
+*              : uint16_t mbw       ; FIFO Port Access Bit Width
+* Return Value : DEVDRV_USBF_FIFOERROR         ; Error
+*              : Others            ; CFIFOCTR/D0FIFOCTR/D1FIFOCTR Register Value
+*******************************************************************************/
+uint16_t usb0_function_change_fifo_port (uint16_t pipe, uint16_t fifosel, uint16_t isel, uint16_t mbw)
+{
+    uint16_t buffer;
+    uint32_t loop;
+    volatile uint32_t loop2;
+
+    usb0_function_set_curpipe(pipe, fifosel, isel, mbw);
+
+    for (loop = 0; loop < 4; loop++)
+    {
+        switch (fifosel)
+        {
+            case USB_FUNCTION_CUSE:
+                buffer = USB200.CFIFOCTR;
+            break;
+
+            case USB_FUNCTION_D0USE:
+            case USB_FUNCTION_D0DMA:
+                buffer = USB200.D0FIFOCTR;
+            break;
+
+            case USB_FUNCTION_D1USE:
+            case USB_FUNCTION_D1DMA:
+                buffer = USB200.D1FIFOCTR;
+            break;
+
+            default:
+                buffer = 0;
+            break;
+        }
+
+        if ((buffer & USB_FUNCTION_BITFRDY) == USB_FUNCTION_BITFRDY)
+        {
+            return buffer;
+        }
+
+        loop2 = 25;
+        while (loop2-- > 0)
+        {
+            /* wait */
+        }
+    }
+
+    return DEVDRV_USBF_FIFOERROR;
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_set_curpipe
+* Description  : Allocates FIF0 specified by the argument in the pipe assigned
+*              : by the argument.
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint16_t fifosel   ; Select FIFO
+*              : uint16_t isel      ; FIFO Access Direction
+*              : uint16_t mbw       ; FIFO Port Access Bit Width
+* Return Value : none
+*******************************************************************************/
+void usb0_function_set_curpipe (uint16_t pipe, uint16_t fifosel, uint16_t isel, uint16_t mbw)
+{
+    uint16_t buffer;
+    uint32_t loop;
+    volatile uint32_t loop2;
+
+    g_usb0_function_mbw[pipe] = mbw;
+
+    switch (fifosel)
+    {
+        case USB_FUNCTION_CUSE:
+            buffer  = USB200.CFIFOSEL;
+            buffer &= (uint16_t)~(USB_FUNCTION_BITISEL | USB_FUNCTION_BITCURPIPE);
+            buffer |= (uint16_t)(~isel & USB_FUNCTION_BITISEL);
+            USB200.CFIFOSEL = buffer;
+
+            for (loop = 0; loop < 4; loop++)
+            {
+                if ((USB200.CFIFOSEL & (USB_FUNCTION_BITISEL | USB_FUNCTION_BITCURPIPE)) ==
+                        (buffer & (USB_FUNCTION_BITISEL | USB_FUNCTION_BITCURPIPE)))
+                {
+                    break;
+                }
+
+                loop2 = 100;
+
+                while (loop2-- > 0)
+                {
+                    /* wait */
+                }
+            }
+            buffer &= (uint16_t)~(USB_FUNCTION_BITISEL | USB_FUNCTION_BITCURPIPE | USB_FUNCTION_BITMBW);
+            buffer |= (uint16_t)(isel | pipe | mbw);
+            USB200.CFIFOSEL = buffer;
+
+            for (loop = 0; loop < 4; loop++)
+            {
+                if ((USB200.CFIFOSEL & (USB_FUNCTION_BITISEL | USB_FUNCTION_BITCURPIPE)) ==
+                        (buffer & (USB_FUNCTION_BITISEL | USB_FUNCTION_BITCURPIPE)))
+                {
+                    break;
+                }
+
+                loop2 = 100;
+
+                while (loop2-- > 0)
+                {
+                    /* wait */
+                }
+            }
+        break;
+
+        case USB_FUNCTION_D0DMA:
+        case USB_FUNCTION_D0USE:
+            buffer  = USB200.D0FIFOSEL;
+            buffer &= (uint16_t)~(USB_FUNCTION_BITCURPIPE);
+            USB200.D0FIFOSEL = buffer;
+
+            for (loop = 0; loop < 4; loop++)
+            {
+                if ((USB200.D0FIFOSEL & USB_FUNCTION_BITCURPIPE) ==
+                        (buffer & USB_FUNCTION_BITCURPIPE))
+                {
+                    break;
+                }
+
+                loop2 = 100;
+
+                while (loop2-- > 0)
+                {
+                    /* wait */
+                }
+            }
+            buffer &= (uint16_t)~(USB_FUNCTION_BITCURPIPE | USB_FUNCTION_BITMBW);
+            buffer |= (uint16_t)(pipe | mbw);
+            USB200.D0FIFOSEL = buffer;
+
+            for (loop = 0; loop < 4; loop++)
+            {
+                if ((USB200.D0FIFOSEL & USB_FUNCTION_BITCURPIPE) ==
+                        (buffer & USB_FUNCTION_BITCURPIPE))
+                {
+                    break;
+                }
+
+                loop2 = 100;
+                while (loop2-- > 0)
+                {
+                    /* wait */
+                }
+            }
+        break;
+
+        case USB_FUNCTION_D1DMA:
+        case USB_FUNCTION_D1USE:
+            buffer  = USB200.D1FIFOSEL;
+            buffer &= (uint16_t)~(USB_FUNCTION_BITCURPIPE);
+            USB200.D1FIFOSEL = buffer;
+
+            for (loop = 0; loop < 4; loop++)
+            {
+                if ((USB200.D1FIFOSEL & USB_FUNCTION_BITCURPIPE) ==
+                        (buffer & USB_FUNCTION_BITCURPIPE))
+                {
+                    break;
+                }
+
+                loop2 = 100;
+
+                while (loop2-- > 0)
+                {
+                    /* wait */
+                }
+            }
+            buffer &= (uint16_t)~(USB_FUNCTION_BITCURPIPE | USB_FUNCTION_BITMBW);
+            buffer |= (uint16_t)(pipe | mbw);
+            USB200.D1FIFOSEL = buffer;
+
+            for (loop = 0; loop < 4; loop++)
+            {
+                if ((USB200.D1FIFOSEL & USB_FUNCTION_BITCURPIPE) ==
+                        (buffer & USB_FUNCTION_BITCURPIPE))
+                {
+                    break;
+                }
+
+                loop2 = 100;
+
+                while (loop2-- > 0)
+                {
+                    /* wait */
+                }
+            }
+        break;
+
+        default:
+        break;
+    }
+
+    /* Cautions !!!
+     * Depending on the external bus speed of CPU, you may need to wait for 450ns here.
+     * For details, please look at the data sheet.   */
+    loop2 = 100;
+
+    while (loop2-- > 0)
+    {
+        /* wait */
+    }
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_set_curpipe2
+* Description  : Allocates FIF0 specified by the argument in the pipe assigned
+*              : by the argument.
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint16_t fifosel   ; Select FIFO
+*              : uint16_t isel      ; FIFO Access Direction
+*              : uint16_t mbw       ; FIFO Port Access Bit Width
+*              : uint16_t dfacc     ; DFACC Access mode
+* Return Value : none
+*******************************************************************************/
+void usb0_function_set_curpipe2 (uint16_t pipe, uint16_t fifosel, uint16_t isel, uint16_t mbw, uint16_t dfacc)
+{
+    uint16_t buffer;
+    uint32_t loop;
+#ifdef  __USB_FUNCTION_DF_ACC_ENABLE__
+    uint32_t dummy;
+#endif
+    volatile uint32_t loop2;
+
+    g_usb0_function_mbw[pipe] = mbw;
+
+    switch (fifosel)
+    {
+        case USB_FUNCTION_CUSE:
+            buffer  = USB200.CFIFOSEL;
+            buffer &= (uint16_t)~(USB_FUNCTION_BITISEL | USB_FUNCTION_BITCURPIPE);
+            buffer |= (uint16_t)(~isel & USB_FUNCTION_BITISEL);
+            USB200.CFIFOSEL = buffer;
+
+            for (loop = 0; loop < 4; loop++)
+            {
+                if ((USB200.CFIFOSEL & (USB_FUNCTION_BITISEL | USB_FUNCTION_BITCURPIPE)) ==
+                        (buffer & (USB_FUNCTION_BITISEL | USB_FUNCTION_BITCURPIPE)))
+                {
+                    break;
+                }
+
+                loop2 = 100;
+                while (loop2-- > 0)
+                {
+                    /* wait */
+                }
+            }
+            buffer &= (uint16_t)~(USB_FUNCTION_BITISEL | USB_FUNCTION_BITCURPIPE | USB_FUNCTION_BITMBW);
+            buffer |= (uint16_t)(isel | pipe | mbw);
+            USB200.CFIFOSEL = buffer;
+
+            for (loop = 0; loop < 4; loop++)
+            {
+                if ((USB200.CFIFOSEL & (USB_FUNCTION_BITISEL | USB_FUNCTION_BITCURPIPE)) ==
+                        (buffer & (USB_FUNCTION_BITISEL | USB_FUNCTION_BITCURPIPE)))
+                {
+                    break;
+                }
+
+                loop2 = 100;
+
+                while (loop2-- > 0)
+                {
+                    /* wait */
+                }
+            }
+        break;
+
+        case USB_FUNCTION_D0DMA:
+        case USB_FUNCTION_D0USE:
+            buffer  = USB200.D0FIFOSEL;
+#ifdef  __USB_FUNCTION_DF_ACC_ENABLE__
+            buffer &= (uint16_t)~(USB_FUNCTION_BITCURPIPE | USB_FUNCTION_BITMBW);
+
+            if (dfacc != 0)
+            {
+                buffer |= (uint16_t)(USB_FUNCTION_BITMBW_32);
+            }
+#else
+            buffer &= (uint16_t)~(USB_FUNCTION_BITCURPIPE);
+#endif
+            USB200.D0FIFOSEL = buffer;
+
+            for (loop = 0; loop < 4; loop++)
+            {
+                if ((USB200.D0FIFOSEL & USB_FUNCTION_BITCURPIPE) == (buffer & USB_FUNCTION_BITCURPIPE))
+                {
+                    break;
+                }
+
+                loop2 = 100;
+
+                while (loop2-- > 0)
+                {
+                    /* wait */
+                }
+            }
+
+#ifdef  __USB_FUNCTION_DF_ACC_ENABLE__
+            if (dfacc != 0)
+            {
+                dummy = USB200.D0FIFO.UINT32;
+            }
+#endif
+            buffer &= (uint16_t)~(USB_FUNCTION_BITCURPIPE | USB_FUNCTION_BITMBW);
+            buffer |= (uint16_t)(pipe | mbw);
+            USB200.D0FIFOSEL = buffer;
+
+            for (loop = 0; loop < 4; loop++)
+            {
+                if ((USB200.D0FIFOSEL & USB_FUNCTION_BITCURPIPE) == (buffer & USB_FUNCTION_BITCURPIPE))
+                {
+                    break;
+                }
+
+                loop2 = 100;
+
+                while (loop2-- > 0)
+                {
+                    /* wait */
+                }
+            }
+        break;
+
+        case USB_FUNCTION_D1DMA:
+        case USB_FUNCTION_D1USE:
+            buffer  = USB200.D1FIFOSEL;
+#ifdef  __USB_FUNCTION_DF_ACC_ENABLE__
+            buffer &= (uint16_t)~(USB_FUNCTION_BITCURPIPE | USB_FUNCTION_BITMBW);
+
+            if (dfacc != 0)
+            {
+                buffer |= (uint16_t)(USB_FUNCTION_BITMBW_32);
+            }
+#else
+            buffer &= (uint16_t)~(USB_FUNCTION_BITCURPIPE);
+#endif
+            USB200.D1FIFOSEL = buffer;
+
+            for (loop = 0; loop < 4; loop++)
+            {
+                if ((USB200.D1FIFOSEL & USB_FUNCTION_BITCURPIPE) == (buffer & USB_FUNCTION_BITCURPIPE))
+                {
+                    break;
+                }
+
+                loop2 = 100;
+
+                while (loop2-- > 0)
+                {
+                    /* wait */
+                }
+            }
+#ifdef  __USB_FUNCTION_DF_ACC_ENABLE__
+            if (dfacc != 0)
+            {
+                dummy = USB200.D1FIFO.UINT32;
+                loop = dummy;                   // avoid warning.
+            }
+#endif
+            buffer &= (uint16_t)~(USB_FUNCTION_BITCURPIPE | USB_FUNCTION_BITMBW);
+            buffer |= (uint16_t)(pipe | mbw);
+            USB200.D1FIFOSEL = buffer;
+
+            for (loop = 0; loop < 4; loop++)
+            {
+                if ((USB200.D1FIFOSEL & USB_FUNCTION_BITCURPIPE) == (buffer & USB_FUNCTION_BITCURPIPE))
+                {
+                    break;
+                }
+
+                loop2 = 100;
+
+                while (loop2-- > 0)
+                {
+                    /* wait */
+                }
+            }
+        break;
+
+        default:
+        break;
+    }
+
+    /* Cautions !!!
+     * Depending on the external bus speed of CPU, you may need to wait for 450ns here.
+     * For details, please look at the data sheet.   */
+    loop2 = 100;
+
+    while (loop2-- > 0)
+    {
+        /* wait */
+    }
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_write_c_fifo
+* Description  : Writes data in CFIFO.
+*              : Writes data by BYTE/WORD/LONG according to access size
+*              : to the pipe specified by the arguments.
+*              : Before executing this function, allocating CFIF0 in the specified pipe
+*              : should be completed.
+*              : Before executing this function, access size to the specified pipe
+*              : should be fixed and set in g_usb0_function_mbw[].
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint16_t count     ; Data Size(Byte)
+* Return Value : none
+*******************************************************************************/
+static void usb0_function_write_c_fifo (uint16_t pipe, uint16_t count)
+{
+    uint16_t even;
+
+    if (g_usb0_function_mbw[pipe] == USB_FUNCTION_BITMBW_8)
+    {
+        for (even = count; even; --even)
+        {
+            USB200.CFIFO.UINT8[HH] = *g_usb0_function_data_pointer[pipe];
+            g_usb0_function_data_pointer[pipe] += 1;
+        }
+    }
+    else if (g_usb0_function_mbw[pipe] == USB_FUNCTION_BITMBW_16)
+    {
+        for (even = (uint16_t)(count / 2); even; --even)
+        {
+            USB200.CFIFO.UINT16[H] = *((uint16_t *)g_usb0_function_data_pointer[pipe]);
+            g_usb0_function_data_pointer[pipe] += 2;
+        }
+    }
+    else
+    {
+        for (even = (uint16_t)(count / 4); even; --even)
+        {
+            USB200.CFIFO.UINT32 = *((uint32_t *)g_usb0_function_data_pointer[pipe]);
+            g_usb0_function_data_pointer[pipe] += 4;
+        }
+    }
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_read_c_fifo
+* Description  : Reads data from CFIFO.
+*              : Reads data by BYTE/WORD/LONG according to access size
+*              : to the pipe specified by the arguments.
+*              : Before executing this function, allocating CFIF0 in the specified pipe
+*              : should be completed.
+*              : Before executing this function, access size to the specified pipe
+*              : should be fixed and set in g_usb0_function_mbw[].
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint16_t count     ; Data Size(Byte)
+* Return Value : none
+*******************************************************************************/
+static void usb0_function_read_c_fifo (uint16_t pipe, uint16_t count)
+{
+    uint16_t even;
+
+    if (g_usb0_function_mbw[pipe] == USB_FUNCTION_BITMBW_8)
+    {
+        for (even = count; even; --even)
+        {
+            *g_usb0_function_data_pointer[pipe] = USB200.CFIFO.UINT8[HH];
+            g_usb0_function_data_pointer[pipe] += 1;
+        }
+    }
+    else if (g_usb0_function_mbw[pipe] == USB_FUNCTION_BITMBW_16)
+    {
+        for (even = (uint16_t)((count + 1) / 2); even; --even)
+        {
+            *((uint16_t *)g_usb0_function_data_pointer[pipe]) = USB200.CFIFO.UINT16[H];
+            g_usb0_function_data_pointer[pipe] += 2;
+        }
+    }
+    else
+    {
+        for (even = (uint16_t)((count + 3) / 4); even; --even)
+        {
+            *((uint32_t *)g_usb0_function_data_pointer[pipe]) = USB200.CFIFO.UINT32;
+            g_usb0_function_data_pointer[pipe] += 4;
+        }
+    }
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_write_d0_fifo
+* Description  : Writes data in D0FIFO.
+*              : Writes data by BYTE/WORD/LONG according to access size
+*              : to the pipe specified by the arguments.
+*              : Before executing this function, allocating CFIF0 in the specified pipe
+*              : should be completed.
+*              : Before executing this function, access size to the specified pipe
+*              : should be fixed and set in g_usb0_function_mbw[].
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint16_t count     ; Data Size(Byte)
+* Return Value : none
+*******************************************************************************/
+static void usb0_function_write_d0_fifo (uint16_t pipe, uint16_t count)
+{
+    uint16_t even;
+
+    if (g_usb0_function_mbw[pipe] == USB_FUNCTION_BITMBW_8)
+    {
+        for (even = count; even; --even)
+        {
+            USB200.D0FIFO.UINT8[HH] = *g_usb0_function_data_pointer[pipe];
+            g_usb0_function_data_pointer[pipe] += 1;
+        }
+    }
+    else if (g_usb0_function_mbw[pipe] == USB_FUNCTION_BITMBW_16)
+    {
+        for (even = (uint16_t)(count / 2); even; --even)
+        {
+            USB200.D0FIFO.UINT16[H] = *((uint16_t *)g_usb0_function_data_pointer[pipe]);
+            g_usb0_function_data_pointer[pipe] += 2;
+        }
+    }
+    else
+    {
+        for (even = (uint16_t)(count / 4); even; --even)
+        {
+            USB200.D0FIFO.UINT32 = *((uint32_t *)g_usb0_function_data_pointer[pipe]);
+            g_usb0_function_data_pointer[pipe] += 4;
+        }
+    }
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_read_d0_fifo
+* Description  : Reads data from D0FIFO.
+*              : Reads data by BYTE/WORD/LONG according to access size
+*              : to the pipe specified by the arguments.
+*              : Before executing this function, allocating DOFIF0 in the specified pipe
+*              : should be completed.
+*              : Before executing this function, access size to the specified pipe
+*              : should be fixed and set in g_usb0_function_mbw[].
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint16_t count     ; Data Size(Byte)
+* Return Value : none
+*******************************************************************************/
+static void usb0_function_read_d0_fifo (uint16_t pipe, uint16_t count)
+{
+    uint16_t even;
+
+    if (g_usb0_function_mbw[pipe] == USB_FUNCTION_BITMBW_8)
+    {
+        for (even = count; even; --even)
+        {
+            *g_usb0_function_data_pointer[pipe] = USB200.D0FIFO.UINT8[HH];
+            g_usb0_function_data_pointer[pipe] += 1;
+        }
+    }
+    else if (g_usb0_function_mbw[pipe] == USB_FUNCTION_BITMBW_16)
+    {
+        for (even = (uint16_t)((count + 1) / 2); even; --even)
+        {
+            *((uint16_t *)g_usb0_function_data_pointer[pipe]) = USB200.D0FIFO.UINT16[H];
+            g_usb0_function_data_pointer[pipe] += 2;
+        }
+    }
+    else
+    {
+        for (even = (uint16_t)((count + 3) / 4); even; --even)
+        {
+            *((uint32_t *)g_usb0_function_data_pointer[pipe]) = USB200.D0FIFO.UINT32;
+            g_usb0_function_data_pointer[pipe] += 4;
+        }
+    }
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_write_d1_fifo
+* Description  : Writes data in D1FIFO.
+*              : Writes data by BYTE/WORD/LONG according to access size
+*              : to the pipe specified by the arguments.
+*              : Before executing this function, allocating D1FIF0 in the specified pipe
+*              : should be completed.
+*              : Before executing this function, access size to the specified pipe
+*              : should be fixed and set in g_usb0_function_mbw[].
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint16_t count     ; Data Size(Byte)
+* Return Value : none
+*******************************************************************************/
+static void usb0_function_write_d1_fifo (uint16_t pipe, uint16_t count)
+{
+    uint16_t even;
+
+    if (g_usb0_function_mbw[pipe] == USB_FUNCTION_BITMBW_8)
+    {
+        for (even = count; even; --even)
+        {
+            USB200.D1FIFO.UINT8[HH] = *g_usb0_function_data_pointer[pipe];
+            g_usb0_function_data_pointer[pipe] += 1;
+        }
+    }
+    else if (g_usb0_function_mbw[pipe] == USB_FUNCTION_BITMBW_16)
+    {
+        for (even = (uint16_t)(count / 2); even; --even)
+        {
+            USB200.D1FIFO.UINT16[H] = *((uint16_t *)g_usb0_function_data_pointer[pipe]);
+            g_usb0_function_data_pointer[pipe] += 2;
+        }
+    }
+    else
+    {
+        for (even = (uint16_t)(count / 4); even; --even)
+        {
+            USB200.D1FIFO.UINT32 = *((uint32_t *)g_usb0_function_data_pointer[pipe]);
+            g_usb0_function_data_pointer[pipe] += 4;
+        }
+    }
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_read_d1_fifo
+* Description  : Reads data from D1FIFO.
+*              : Reads data by BYTE/WORD/LONG according to access size
+*              : to the pipe specified by the arguments.
+*              : Before executing this function, allocating D1FIF0 in the specified pipe
+*              : should be completed.
+*              : Before executing this function, access size to the specified pipe
+*              : should be fixed and set in g_usb0_function_mbw[].
+* Arguments    : uint16_t pipe      ; Pipe Number
+*              : uint16_t count     ; Data Size(Byte)
+* Return Value : none
+*******************************************************************************/
+static void usb0_function_read_d1_fifo (uint16_t pipe, uint16_t count)
+{
+    uint16_t even;
+
+    if (g_usb0_function_mbw[pipe] == USB_FUNCTION_BITMBW_8)
+    {
+        for (even = count; even; --even)
+        {
+            *g_usb0_function_data_pointer[pipe] = USB200.D1FIFO.UINT8[HH];
+            g_usb0_function_data_pointer[pipe] += 1;
+        }
+    }
+    else if (g_usb0_function_mbw[pipe] == USB_FUNCTION_BITMBW_16)
+    {
+        for (even = (uint16_t)((count + 1) / 2); even; --even)
+        {
+            *((uint16_t *)g_usb0_function_data_pointer[pipe]) = USB200.D1FIFO.UINT16[H];
+            g_usb0_function_data_pointer[pipe] += 2;
+        }
+    }
+    else
+    {
+        for (even = (uint16_t)((count + 3) / 4); even; --even)
+        {
+            *((uint32_t *)g_usb0_function_data_pointer[pipe]) = USB200.D1FIFO.UINT32;
+            g_usb0_function_data_pointer[pipe] += 4;
+        }
+    }
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_com_get_dmasize
+* Description  : Calculates access width of DMA transfer by the argument to
+*              : return as the Return Value.
+* Arguments    : uint32_t trncount   : transfer byte
+*              : uint32_t dtptr      : transfer data pointer
+* Return Value : DMA transfer size    : 0   8bit
+*              :                      : 1  16bit
+*              :                      : 2  32bit
+*******************************************************************************/
+static uint32_t usb0_function_com_get_dmasize (uint32_t trncount, uint32_t dtptr)
+{
+    uint32_t size;
+
+    if (((trncount & 0x0001) != 0) || ((dtptr & 0x00000001) != 0))
+    {
+        /*  When transfer byte count is odd         */
+        /* or transfer data area is 8-bit alignment */
+        size = 0;           /* 8bit */
+    }
+    else if (((trncount & 0x0003) != 0) || ((dtptr & 0x00000003) != 0))
+    {
+        /* When the transfer byte count is multiples of 2 */
+        /* or the transfer data area is 16-bit alignment */
+        size = 1;           /* 16bit */
+    }
+    else
+    {
+        /* When the transfer byte count is multiples of 4 */
+        /* or the transfer data area is 32-bit alignment */
+        size = 2;           /* 32bit */
+    }
+
+    return size;
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_get_mbw
+* Description  : Calculates access width of DMA to return the value set in MBW.
+* Arguments    : uint32_t trncount   : transfer byte
+*              : uint32_t dtptr      : transfer data pointer
+* Return Value : FIFO transfer size   : USB_FUNCTION_BITMBW_8    8bit
+*              :                      : USB_FUNCTION_BITMBW_16  16bit
+*              :                      : USB_FUNCTION_BITMBW_32  32bit
+*******************************************************************************/
+uint16_t usb0_function_get_mbw (uint32_t trncount, uint32_t dtptr)
+{
+    uint32_t size;
+    uint16_t mbw;
+
+    size = usb0_function_com_get_dmasize(trncount, dtptr);
+
+    if (size == 0)
+    {
+        /* 8bit */
+        mbw = USB_FUNCTION_BITMBW_8;
+    }
+    else if (size == 1)
+    {
+        /* 16bit */
+        mbw = USB_FUNCTION_BITMBW_16;
+    }
+    else
+    {
+        /* 32bit */
+        mbw = USB_FUNCTION_BITMBW_32;
+    }
+
+    return mbw;
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_set_transaction_counter
+* Description  : Sets transaction counter by the argument(PIPEnTRN).
+*              : Clears transaction before setting to enable transaction counter setting.
+* Arguments    : uint16_t pipe     ; Pipe number
+*              : uint32_t bsize    : Data transfer size
+* Return Value : none
+*******************************************************************************/
+static void usb0_function_set_transaction_counter (uint16_t pipe, uint32_t bsize)
+{
+    uint16_t mxps;
+    uint16_t cnt;
+
+    if (bsize  == 0)
+    {
+        return;
+    }
+
+    mxps = usb0_function_get_mxps(pipe);            /* Max Packet Size */
+
+    if ((bsize % mxps) == 0)
+    {
+        cnt = (uint16_t)(bsize / mxps);
+    }
+    else
+    {
+        cnt = (uint16_t)((bsize / mxps) + 1);
+    }
+
+    switch (pipe)
+    {
+        case USB_FUNCTION_PIPE1:
+            RZA_IO_RegWrite_16(&USB200.PIPE1TRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+            USB200.PIPE1TRN             = cnt;
+            RZA_IO_RegWrite_16(&USB200.PIPE1TRE,
+                                1,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+        break;
+
+        case USB_FUNCTION_PIPE2:
+            RZA_IO_RegWrite_16(&USB200.PIPE2TRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+            USB200.PIPE2TRN             = cnt;
+            RZA_IO_RegWrite_16(&USB200.PIPE2TRE,
+                                1,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+        break;
+
+        case USB_FUNCTION_PIPE3:
+            RZA_IO_RegWrite_16(&USB200.PIPE3TRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+            USB200.PIPE3TRN             = cnt;
+            RZA_IO_RegWrite_16(&USB200.PIPE3TRE,
+                                1,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+        break;
+
+        case USB_FUNCTION_PIPE4:
+            RZA_IO_RegWrite_16(&USB200.PIPE4TRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+            USB200.PIPE4TRN             = cnt;
+            RZA_IO_RegWrite_16(&USB200.PIPE4TRE,
+                                1,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+        break;
+
+        case USB_FUNCTION_PIPE5:
+            RZA_IO_RegWrite_16(&USB200.PIPE5TRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+            USB200.PIPE5TRN             = cnt;
+            RZA_IO_RegWrite_16(&USB200.PIPE5TRE,
+                                1,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+        break;
+
+        case USB_FUNCTION_PIPE9:
+            RZA_IO_RegWrite_16(&USB200.PIPE9TRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+            USB200.PIPE9TRN             = cnt;
+            RZA_IO_RegWrite_16(&USB200.PIPE9TRE,
+                                1,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+        break;
+
+        case USB_FUNCTION_PIPEA:
+            RZA_IO_RegWrite_16(&USB200.PIPEATRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+            USB200.PIPEATRN             = cnt;
+            RZA_IO_RegWrite_16(&USB200.PIPEATRE,
+                                1,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+        break;
+
+        case USB_FUNCTION_PIPEB:
+            RZA_IO_RegWrite_16(&USB200.PIPEBTRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+            USB200.PIPEBTRN             = cnt;
+            RZA_IO_RegWrite_16(&USB200.PIPEBTRE,
+                                1,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+        break;
+
+        case USB_FUNCTION_PIPEC:
+            RZA_IO_RegWrite_16(&USB200.PIPECTRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+            USB200.PIPECTRN             = cnt;
+            RZA_IO_RegWrite_16(&USB200.PIPECTRE,
+                                1,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+        break;
+
+        case USB_FUNCTION_PIPED:
+            RZA_IO_RegWrite_16(&USB200.PIPEDTRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+            USB200.PIPEDTRN             = cnt;
+            RZA_IO_RegWrite_16(&USB200.PIPEDTRE,
+                                1,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+        break;
+
+        case USB_FUNCTION_PIPEE:
+            RZA_IO_RegWrite_16(&USB200.PIPEETRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+            USB200.PIPEETRN             = cnt;
+            RZA_IO_RegWrite_16(&USB200.PIPEETRE,
+                                1,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+        break;
+
+        case USB_FUNCTION_PIPEF:
+            RZA_IO_RegWrite_16(&USB200.PIPEFTRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+            USB200.PIPEFTRN             = cnt;
+            RZA_IO_RegWrite_16(&USB200.PIPEFTRE,
+                                1,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+        break;
+
+        default:
+        break;
+    }
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_clear_transaction_counter
+* Description  : Clears the transaction counter by the argument.
+*              : After executing this function, the transaction counter is invalid.
+* Arguments    : uint16_t pipe     ; Pipe number
+* Return Value : none
+*******************************************************************************/
+void usb0_function_clear_transaction_counter (uint16_t pipe)
+{
+    switch (pipe)
+    {
+        case USB_FUNCTION_PIPE1:
+            RZA_IO_RegWrite_16(&USB200.PIPE1TRE,
+                                0,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+            RZA_IO_RegWrite_16(&USB200.PIPE1TRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+        break;
+
+        case USB_FUNCTION_PIPE2:
+            RZA_IO_RegWrite_16(&USB200.PIPE2TRE,
+                                0,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+            RZA_IO_RegWrite_16(&USB200.PIPE2TRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+        break;
+
+        case USB_FUNCTION_PIPE3:
+            RZA_IO_RegWrite_16(&USB200.PIPE3TRE,
+                                0,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+            RZA_IO_RegWrite_16(&USB200.PIPE3TRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+        break;
+
+        case USB_FUNCTION_PIPE4:
+            RZA_IO_RegWrite_16(&USB200.PIPE4TRE,
+                                0,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+            RZA_IO_RegWrite_16(&USB200.PIPE4TRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+        break;
+
+        case USB_FUNCTION_PIPE5:
+            RZA_IO_RegWrite_16(&USB200.PIPE5TRE,
+                                0,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+            RZA_IO_RegWrite_16(&USB200.PIPE5TRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+        break;
+
+        case USB_FUNCTION_PIPE9:
+            RZA_IO_RegWrite_16(&USB200.PIPE9TRE,
+                                0,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+            RZA_IO_RegWrite_16(&USB200.PIPE9TRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+        break;
+
+        case USB_FUNCTION_PIPEA:
+            RZA_IO_RegWrite_16(&USB200.PIPEATRE,
+                                0,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+            RZA_IO_RegWrite_16(&USB200.PIPEATRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+        break;
+
+        case USB_FUNCTION_PIPEB:
+            RZA_IO_RegWrite_16(&USB200.PIPEBTRE,
+                                0,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+            RZA_IO_RegWrite_16(&USB200.PIPEBTRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+        break;
+
+        case USB_FUNCTION_PIPEC:
+            RZA_IO_RegWrite_16(&USB200.PIPECTRE,
+                                0,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+            RZA_IO_RegWrite_16(&USB200.PIPECTRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+        break;
+
+        case USB_FUNCTION_PIPED:
+            RZA_IO_RegWrite_16(&USB200.PIPEDTRE,
+                                0,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+            RZA_IO_RegWrite_16(&USB200.PIPEDTRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+        break;
+
+        case USB_FUNCTION_PIPEE:
+            RZA_IO_RegWrite_16(&USB200.PIPEETRE,
+                                0,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+            RZA_IO_RegWrite_16(&USB200.PIPEETRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+        break;
+
+        case USB_FUNCTION_PIPEF:
+            RZA_IO_RegWrite_16(&USB200.PIPEFTRE,
+                                0,
+                                USB_PIPEnTRE_TRENB_SHIFT,
+                                USB_PIPEnTRE_TRENB);
+            RZA_IO_RegWrite_16(&USB200.PIPEFTRE,
+                                1,
+                                USB_PIPEnTRE_TRCLR_SHIFT,
+                                USB_PIPEnTRE_TRCLR);
+        break;
+
+        default:
+        break;
+    }
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_stop_transfer
+* Description  : Stops the USB transfer in the pipe specified by the argument.
+*              : After stopping the USB transfer, clears the buffer allocated in
+*              : the pipe.
+*              : After executing this function, allocation in FIF0 becomes USB_FUNCTION_PIPE0;
+*              : invalid. After executing this function, BRDY/NRDY/BEMP interrupt
+*              : in the corresponding pipe becomes invalid. Sequence bit is also
+*              : cleared.
+* Arguments    : uint16_t  pipe     ; Pipe Number
+* Return Value : none
+*******************************************************************************/
+void usb0_function_stop_transfer (uint16_t pipe)
+{
+    uint16_t usefifo;
+    uint32_t remain;
+    uint16_t fifo;
+
+    usb0_function_set_pid_nak(pipe);
+
+    usefifo = (uint16_t)(g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE);
+    switch (usefifo)
+    {
+        case USB_FUNCTION_D0FIFO_USE:
+            usb0_function_clear_transaction_counter(pipe);
+            USB200.D0FIFOCTR = USB_FUNCTION_BITBCLR;        /* Buffer Clear */
+            fifo = USB_FUNCTION_D0USE;
+        break;
+
+        case USB_FUNCTION_D1FIFO_USE:
+            usb0_function_clear_transaction_counter(pipe);
+            USB200.D1FIFOCTR = USB_FUNCTION_BITBCLR;        /* Buffer Clear */
+            fifo = USB_FUNCTION_D1USE;
+        break;
+
+        case USB_FUNCTION_D0FIFO_DMA:
+            remain = Userdef_USB_usb0_function_stop_dma0();
+            usb0_function_dma_stop_d0(pipe, remain);
+            usb0_function_clear_transaction_counter(pipe);
+            USB200.D0FIFOCTR = USB_FUNCTION_BITBCLR;        /* Buffer Clear */
+            fifo = USB_FUNCTION_D0DMA;
+        break;
+
+        case USB_FUNCTION_D1FIFO_DMA:
+            remain = Userdef_USB_usb0_function_stop_dma1();
+            usb0_function_dma_stop_d1(pipe, remain);
+            usb0_function_clear_transaction_counter(pipe);
+            USB200.D1FIFOCTR = USB_FUNCTION_BITBCLR;        /* Buffer Clear */
+            fifo = USB_FUNCTION_D1DMA;
+        break;
+
+        default:
+            usb0_function_clear_transaction_counter(pipe);
+            USB200.CFIFOCTR =  USB_FUNCTION_BITBCLR;        /* Buffer Clear */
+            fifo = USB_FUNCTION_CUSE;
+        break;
+    }
+
+    usb0_function_set_curpipe(USB_FUNCTION_PIPE0, fifo, DEVDRV_USBF_NO, USB_FUNCTION_BITMBW_16);
+
+    /* Interrupt of pipe set is disabled */
+    usb0_function_disable_brdy_int(pipe);
+    usb0_function_disable_nrdy_int(pipe);
+    usb0_function_disable_bemp_int(pipe);
+
+    usb0_function_aclrm(pipe);
+    usb0_function_set_csclr(pipe);
+
+    if ( g_usb0_function_pipe_status[pipe] == DEVDRV_USBF_PIPE_WAIT )
+    {
+        g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_NORES;
+    }
+
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_set_dfacc_d0
+* Description  : Sets the DFACC setting value in D0FIFO using the transfer size.
+* Arguments    : uint16_t mbw     ; MBW
+*              : uint16_t count   ; data count
+* Return Value : DFACC Access mode
+*******************************************************************************/
+static uint16_t usb0_function_set_dfacc_d0 (uint16_t mbw, uint32_t count)
+{
+    uint16_t dfacc = 0;
+
+#ifndef __USB_FUNCTION_DF_ACC_ENABLE__
+    RZA_IO_RegWrite_16(&USB200.D0FBCFG,
+                        0,
+                        USB_DnFBCFG_DFACC_SHIFT,
+                        USB_DnFBCFG_DFACC);
+    RZA_IO_RegWrite_16(&USB200.D0FBCFG,
+                        0,
+                        USB_DnFBCFG_TENDE_SHIFT,
+                        USB_DnFBCFG_TENDE);
+    dfacc = 0;
+#else
+    if (mbw == USB_FUNCTION_BITMBW_32)
+    {
+        if ((count % 32) == 0)
+        {
+            /* 32byte transfer */
+            RZA_IO_RegWrite_16(&USB200.D0FBCFG,
+                                2,
+                                USB_DnFBCFG_DFACC_SHIFT,
+                                USB_DnFBCFG_DFACC);
+            RZA_IO_RegWrite_16(&USB200.D0FBCFG,
+                                0,
+                                USB_DnFBCFG_TENDE_SHIFT,
+                                USB_DnFBCFG_TENDE);
+            dfacc = 2;
+        }
+        else if ((count % 16) == 0)
+        {
+            /* 16byte transfer */
+            RZA_IO_RegWrite_16(&USB200.D0FBCFG,
+                                1,
+                                USB_DnFBCFG_DFACC_SHIFT,
+                                USB_DnFBCFG_DFACC);
+            RZA_IO_RegWrite_16(&USB200.D0FBCFG,
+                                0,
+                                USB_DnFBCFG_TENDE_SHIFT,
+                                USB_DnFBCFG_TENDE);
+            dfacc = 1;
+        }
+        else
+        {
+            RZA_IO_RegWrite_16(&USB200.D0FBCFG,
+                                0,
+                                USB_DnFBCFG_DFACC_SHIFT,
+                                USB_DnFBCFG_DFACC);
+            RZA_IO_RegWrite_16(&USB200.D0FBCFG,
+                                0,
+                                USB_DnFBCFG_TENDE_SHIFT,
+                                USB_DnFBCFG_TENDE);
+            dfacc = 0;
+        }
+    }
+    else if (mbw == USB_FUNCTION_BITMBW_16)
+    {
+        RZA_IO_RegWrite_16(&USB200.D0FBCFG,
+                            0,
+                            USB_DnFBCFG_DFACC_SHIFT,
+                            USB_DnFBCFG_DFACC);
+        RZA_IO_RegWrite_16(&USB200.D0FBCFG,
+                            0,
+                            USB_DnFBCFG_TENDE_SHIFT,
+                            USB_DnFBCFG_TENDE);
+        dfacc = 0;
+    }
+    else
+    {
+        RZA_IO_RegWrite_16(&USB200.D0FBCFG,
+                            0,
+                            USB_DnFBCFG_DFACC_SHIFT,
+                            USB_DnFBCFG_DFACC);
+        RZA_IO_RegWrite_16(&USB200.D0FBCFG,
+                            0,
+                            USB_DnFBCFG_TENDE_SHIFT,
+                            USB_DnFBCFG_TENDE);
+        dfacc = 0;
+    }
+#endif
+    return dfacc;
+}
+
+/*******************************************************************************
+* Function Name: usb0_function_set_dfacc_d1
+* Description  : Set the DFACC setting value in D1FIFO using the transfer size.
+* Arguments    : uint16_t mbw     ; MBW
+*              : uint16_t count   ; data count
+* Return Value : DFACC Access mode
+*******************************************************************************/
+static uint16_t usb0_function_set_dfacc_d1 (uint16_t mbw, uint32_t count)
+{
+    uint16_t dfacc = 0;
+
+#ifndef __USB_FUNCTION_DF_ACC_ENABLE__
+    RZA_IO_RegWrite_16(&USB200.D1FBCFG,
+                        0,
+                        USB_DnFBCFG_DFACC_SHIFT,
+                        USB_DnFBCFG_DFACC);
+    RZA_IO_RegWrite_16(&USB200.D1FBCFG,
+                        0,
+                        USB_DnFBCFG_TENDE_SHIFT,
+                        USB_DnFBCFG_TENDE);
+    dfacc = 0;
+#else
+    if (mbw == USB_FUNCTION_BITMBW_32)
+    {
+        if ((count % 32) == 0)
+        {
+            /* 32byte transfer */
+            RZA_IO_RegWrite_16(&USB200.D1FBCFG,
+                                2,
+                                USB_DnFBCFG_DFACC_SHIFT,
+                                USB_DnFBCFG_DFACC);
+            RZA_IO_RegWrite_16(&USB200.D1FBCFG,
+                                0,
+                                USB_DnFBCFG_TENDE_SHIFT,
+                                USB_DnFBCFG_TENDE);
+            dfacc = 2;
+        }
+        else if ((count % 16) == 0)
+        {
+            /* 16byte transfer */
+            RZA_IO_RegWrite_16(&USB200.D1FBCFG,
+                                1,
+                                USB_DnFBCFG_DFACC_SHIFT,
+                                USB_DnFBCFG_DFACC);
+            RZA_IO_RegWrite_16(&USB200.D1FBCFG,
+                                0,
+                                USB_DnFBCFG_TENDE_SHIFT,
+                                USB_DnFBCFG_TENDE);
+            dfacc = 1;
+        }
+        else
+        {
+            RZA_IO_RegWrite_16(&USB200.D1FBCFG,
+                                0,
+                                USB_DnFBCFG_DFACC_SHIFT,
+                                USB_DnFBCFG_DFACC);
+            RZA_IO_RegWrite_16(&USB200.D1FBCFG,
+                                0,
+                                USB_DnFBCFG_TENDE_SHIFT,
+                                USB_DnFBCFG_TENDE);
+            dfacc = 0;
+        }
+    }
+    else if (mbw == USB_FUNCTION_BITMBW_16)
+    {
+        RZA_IO_RegWrite_16(&USB200.D1FBCFG,
+                            0,
+                            USB_DnFBCFG_DFACC_SHIFT,
+                            USB_DnFBCFG_DFACC);
+        RZA_IO_RegWrite_16(&USB200.D1FBCFG,
+                            0,
+                            USB_DnFBCFG_TENDE_SHIFT,
+                            USB_DnFBCFG_TENDE);
+        dfacc = 0;
+    }
+    else
+    {
+        RZA_IO_RegWrite_16(&USB200.D1FBCFG,
+                            0,
+                            USB_DnFBCFG_DFACC_SHIFT,
+                            USB_DnFBCFG_DFACC);
+        RZA_IO_RegWrite_16(&USB200.D1FBCFG,
+                            0,
+                            USB_DnFBCFG_TENDE_SHIFT,
+                            USB_DnFBCFG_TENDE);
+        dfacc = 0;
+    }
+#endif
+
+    return dfacc;
+}
+
+/* End of File */