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

Dependents:   randomSearch

Fork of USBDevice by mbed official

Revision:
40:3b1c43ac045c
Parent:
36:4d3e7f3d5211
Child:
42:4f589e246b9e
--- a/USBDevice/USBHAL_RZ_A1H.cpp	Tue Jan 06 16:16:27 2015 +0000
+++ b/USBDevice/USBHAL_RZ_A1H.cpp	Mon Jan 19 14:30:30 2015 +0000
@@ -1,19 +1,26 @@
 /* Copyright (c) 2010-2011 mbed.org, MIT License
 *
-* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
-* and associated documentation files (the "Software"), to deal in the Software without
-* restriction, including without limitation the rights to use, copy, modify, merge, publish,
-* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
-* Software is furnished to do so, subject to the following conditions:
+* Permission is hereby granted, free of charge, to any person
+* obtaining a copy of this software and associated documentation
+* files (the "Software"), to deal in the Software without
+* restriction, including without limitation the rights to use,
+* copy, modify, merge, publish, distribute, sublicense, and/or
+* sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following
+* conditions:
 *
-* The above copyright notice and this permission notice shall be included in all copies or
-* substantial portions of the Software.
+* The above copyright notice and this permission notice shall be
+* included in all copies or substantial portions of the
+* Software.
 *
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+* KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
 
 #if defined(TARGET_RZ_A1H)
@@ -59,8 +66,9 @@
         USB_FUNCTION_DIR_P_OUT |
         USB_FUNCTION_EP1,
         ( ( (  64) / 64 - 1 ) << 10 ) | 0x04u,
-        64,
-        DEVDRV_USBF_OFF | 0,
+        MAX_PACKET_SIZE_EP1,
+        DEVDRV_USBF_OFF |
+        ( 3 << USB_PIPEPERI_IITV_SHIFT ),
     },
     {
         EP1IN,  /*EP1: Host <- Func, INT*/
@@ -73,8 +81,9 @@
         USB_FUNCTION_DIR_P_IN  |
         USB_FUNCTION_EP1,
         ( ( (  64) / 64 - 1 ) << 10 ) | 0x05u,
-        64,
-        DEVDRV_USBF_OFF | 0,
+        MAX_PACKET_SIZE_EP1,
+        DEVDRV_USBF_OFF |
+        ( 3 << USB_PIPEPERI_IITV_SHIFT ),
     },
     {
         EP2OUT, /*EP2: Host -> Func, BULK*/
@@ -87,8 +96,9 @@
         USB_FUNCTION_DIR_P_OUT |
         USB_FUNCTION_EP2,
         ( ( (2048) / 64 - 1 ) << 10 ) | 0x30u,
-        512,
-        DEVDRV_USBF_OFF | 0,
+        MAX_PACKET_SIZE_EP2,
+        DEVDRV_USBF_OFF |
+        ( 0 << USB_PIPEPERI_IITV_SHIFT ),
     },
     {
         EP2IN,  /*EP2: Host <- Func, BULK*/
@@ -101,8 +111,9 @@
         USB_FUNCTION_DIR_P_IN  |
         USB_FUNCTION_EP2,
         ( ( (2048) / 64 - 1 ) << 10 ) | 0x50u,
-        512,
-        DEVDRV_USBF_OFF | 0,
+        MAX_PACKET_SIZE_EP2,
+        DEVDRV_USBF_OFF |
+        ( 0 << USB_PIPEPERI_IITV_SHIFT ),
     },
     {
         EP3OUT, /*EP3: Host -> Func, ISO*/
@@ -110,13 +121,14 @@
         USB_FUNCTION_ISO       |
         USB_FUNCTION_BFREOFF   |
         USB_FUNCTION_DBLBON    |
-        USB_FUNCTION_CNTMDON   |
+        USB_FUNCTION_CNTMDOFF  |
         USB_FUNCTION_SHTNAKON  |
         USB_FUNCTION_DIR_P_OUT |
         USB_FUNCTION_EP3,
-        ( ( (1024) / 64 - 1 ) << 10 ) | 0x10u,
-        192,
-        DEVDRV_USBF_OFF | 1,
+        ( ( ( 512) / 64 - 1 ) << 10 ) | 0x10u,
+        MAX_PACKET_SIZE_EP3,
+        DEVDRV_USBF_OFF |
+        ( 0 << USB_PIPEPERI_IITV_SHIFT ),
     },
     {
         EP3IN,  /*EP3: Host <- Func, ISO*/
@@ -124,13 +136,14 @@
         USB_FUNCTION_ISO       |
         USB_FUNCTION_BFREOFF   |
         USB_FUNCTION_DBLBON    |
-        USB_FUNCTION_CNTMDON   |
+        USB_FUNCTION_CNTMDOFF  |
         USB_FUNCTION_SHTNAKOFF |
         USB_FUNCTION_DIR_P_IN  |
         USB_FUNCTION_EP3,
-        ( ( (1024) / 64 - 1 ) << 10 ) | 0x20u,
-        192,
-        DEVDRV_USBF_OFF | 1,
+        ( ( ( 512) / 64 - 1 ) << 10 ) | 0x20u,
+        MAX_PACKET_SIZE_EP3,
+        DEVDRV_USBF_OFF |
+        ( 0 << USB_PIPEPERI_IITV_SHIFT ),
     },
     { /*terminator*/
         0, 0, 0, 0, 0,
@@ -142,13 +155,12 @@
 /* workareas */
 USBHAL * USBHAL::instance;
 
-
 static IRQn_Type    int_id;         /* interrupt ID          */
 static uint16_t     int_level;      /* initerrupt level      */
 static uint16_t     clock_mode;     /* input clock selector  */
 static uint16_t     mode;           /* USB speed (HIGH/FULL) */
 
-static DigitalOut *usb0_en;
+//static DigitalOut *usb0_en;
 
 static uint16_t     EP0_read_status;
 static uint16_t     EPx_read_status;
@@ -160,17 +172,28 @@
 volatile static uint16_t    recv_error;
 
 
-
 /*************************************************************************/
 /* prototypes for C */
+extern "C" {
+    void usb0_function_BRDYInterruptPIPE0 (uint16_t status, uint16_t intenb,
+        USBHAL *object, void (USBHAL::*EP0func)(void));
 
-/* This C++ functions changed to macro functions.
-   static uint32_t EP2PIPE(uint8_t endpoint);
-   static void usb0_function_save_request(void);
-   void usb0_function_BRDYInterrupt(uint16_t status, uint16_t intenb);
-   void usb0_function_NRDYInterrupt (uint16_t status, uint16_t intenb);
-   void usb0_function_BEMPInterrupt (uint16_t status, uint16_t intenb);
-*/
+    void usb0_function_BRDYInterrupt (uint16_t status, uint16_t intenb,
+        USBHAL *object, bool (USBHAL::*epCallback[])(void));
+
+    void usb0_function_NRDYInterruptPIPE0(uint16_t status, uint16_t intenb,
+        USBHAL *object, void (USBHAL::*EP0func)(void));
+
+    void usb0_function_NRDYInterrupt (uint16_t status, uint16_t intenb,
+        USBHAL *object, bool (USBHAL::*epCallback[])(void));
+
+    void usb0_function_BEMPInterruptPIPE0(uint16_t status, uint16_t intenb,
+        USBHAL *object, void (USBHAL::*EP0func)(void));
+
+    void usb0_function_BEMPInterrupt (uint16_t status, uint16_t intenb,
+        USBHAL *object, bool (USBHAL::*epCallback[])(void));
+}
+
 
 /*************************************************************************/
 /* macros */
@@ -182,66 +205,72 @@
  *              : uint16_t intenb       ; BRDYENB Register Value
  * Return Value : none
  *****************************************************************************/
-#define usb0_function_BRDYInterruptPIPE0(status, intenb)                \
-    {                                                                   \
-        volatile uint16_t dumy_sts;                                     \
-        uint16_t read_status;                                           \
-                                                                        \
-        USB200.BRDYSTS =                                                \
-            (uint16_t)~g_usb0_function_bit_set[USB_FUNCTION_PIPE0];     \
-        RZA_IO_RegWrite_16(                                             \
-            &USB200.CFIFOSEL, USB_FUNCTION_PIPE0,                       \
-            USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE);          \
-                                                                        \
-        g_usb0_function_PipeDataSize[USB_FUNCTION_PIPE0] =              \
-            g_usb0_function_data_count[USB_FUNCTION_PIPE0];             \
-                                                                        \
-        read_status = usb0_function_read_buffer_c(USB_FUNCTION_PIPE0);  \
-                                                                        \
-        g_usb0_function_PipeDataSize[USB_FUNCTION_PIPE0] -=             \
-            g_usb0_function_data_count[USB_FUNCTION_PIPE0];             \
-                                                                        \
-        switch (read_status) {                                          \
-            case USB_FUNCTION_READING:      /* Continue of data read */ \
-            case USB_FUNCTION_READEND:      /* End of data read */      \
-                /* PID = BUF */                                         \
-                usb0_function_set_pid_buf(USB_FUNCTION_PIPE0);          \
-                                                                        \
-                /*callback*/                                            \
-                EP0out();                                               \
-                break;                                                  \
-                                                                        \
-            case USB_FUNCTION_READSHRT:     /* End of data read */      \
-                usb0_function_disable_brdy_int(USB_FUNCTION_PIPE0);     \
-                /* PID = BUF */                                         \
-                usb0_function_set_pid_buf(USB_FUNCTION_PIPE0);          \
-                                                                        \
-                /*callback*/                                            \
-                EP0out();                                               \
-                break;                                                  \
-                                                                        \
-            case USB_FUNCTION_READOVER:     /* FIFO access error */     \
-                /* Buffer Clear */                                      \
-                USB200.CFIFOCTR = USB_FUNCTION_BITBCLR;                 \
-                usb0_function_disable_brdy_int(USB_FUNCTION_PIPE0);     \
-                /* Req Error */                                         \
-                usb0_function_set_pid_stall(USB_FUNCTION_PIPE0);        \
-                                                                        \
-                /*callback*/                                            \
-                EP0out();                                               \
-                break;                                                  \
-                                                                        \
-            case DEVDRV_USBF_FIFOERROR:     /* FIFO access error */     \
-            default:                                                    \
-                usb0_function_disable_brdy_int(USB_FUNCTION_PIPE0);     \
-                /* Req Error */                                         \
-                usb0_function_set_pid_stall(USB_FUNCTION_PIPE0);        \
-                break;                                                  \
-        }                                                               \
-        /* Three dummy reads for clearing interrupt requests */         \
-        dumy_sts = USB200.BRDYSTS;                                      \
+extern "C" {
+    void usb0_function_BRDYInterruptPIPE0 (
+        uint16_t status,
+        uint16_t intenb,
+        USBHAL *object,
+        void (USBHAL::*EP0func)(void)
+    )
+    {
+        volatile uint16_t dumy_sts;
+        uint16_t read_status;
+
+        USB200.BRDYSTS =
+            (uint16_t)~g_usb0_function_bit_set[USB_FUNCTION_PIPE0];
+        RZA_IO_RegWrite_16(
+            &USB200.CFIFOSEL, USB_FUNCTION_PIPE0,
+            USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE);
+
+        g_usb0_function_PipeDataSize[USB_FUNCTION_PIPE0] =
+            g_usb0_function_data_count[USB_FUNCTION_PIPE0];
+
+        read_status = usb0_function_read_buffer_c(USB_FUNCTION_PIPE0);
+
+        g_usb0_function_PipeDataSize[USB_FUNCTION_PIPE0] -=
+            g_usb0_function_data_count[USB_FUNCTION_PIPE0];
+
+        switch (read_status) {
+            case USB_FUNCTION_READING:      /* Continue of data read */
+            case USB_FUNCTION_READEND:      /* End of data read */
+                /* PID = BUF */
+                usb0_function_set_pid_buf(USB_FUNCTION_PIPE0);
+
+                /*callback*/
+                (object->*EP0func)();
+                break;
+
+            case USB_FUNCTION_READSHRT:     /* End of data read */
+                usb0_function_disable_brdy_int(USB_FUNCTION_PIPE0);
+                /* PID = BUF */
+                usb0_function_set_pid_buf(USB_FUNCTION_PIPE0);
+
+                /*callback*/
+                (object->*EP0func)();
+                break;
+
+            case USB_FUNCTION_READOVER:     /* FIFO access error */
+                /* Buffer Clear */
+                USB200.CFIFOCTR = USB_FUNCTION_BITBCLR;
+                usb0_function_disable_brdy_int(USB_FUNCTION_PIPE0);
+                /* Req Error */
+                usb0_function_set_pid_stall(USB_FUNCTION_PIPE0);
+
+                /*callback*/
+                (object->*EP0func)();
+                break;
+
+            case DEVDRV_USBF_FIFOERROR:     /* FIFO access error */
+            default:
+                usb0_function_disable_brdy_int(USB_FUNCTION_PIPE0);
+                /* Req Error */
+                usb0_function_set_pid_stall(USB_FUNCTION_PIPE0);
+                break;
+        }
+        /* Three dummy reads for clearing interrupt requests */
+        dumy_sts = USB200.BRDYSTS;
     }
-
+}
 
 
 /******************************************************************************
@@ -251,85 +280,100 @@
  *              : uint16_t intenb       ; BRDYENB Register Value
  * Return Value : none
  *****************************************************************************/
-#define usb0_function_BRDYInterrupt(status, intenb)                     \
-    {                                                                   \
-        volatile uint16_t dumy_sts;                                     \
-                                                                        \
-        /************************************************************** \
-         * Function Name: usb0_function_brdy_int                        \
-         * Description  : Executes BRDY interrupt(USB_FUNCTION_PIPE1-9). \
-         *              : According to the pipe that interrupt is generated in, \
-         *              : reads/writes buffer allocated in the pipe.    \
-         *              : This function is executed in the BRDY         \
-         *              : interrupt handler.  This function             \
-         *              : clears BRDY interrupt status and BEMP         \
-         *              : interrupt status.                             \
-         * Arguments    : uint16_t Status    ; BRDYSTS Register Value   \
-         *              : uint16_t Int_enbl  ; BRDYENB Register Value   \
-         * Return Value : none                                          \
-         *************************************************************/ \
-        /* copied from usb0_function_intrn.c */                         \
-        uint32_t int_sense = 0;                                         \
-        uint16_t pipe;                                                  \
-        uint16_t pipebit;                                               \
-        uint16_t ep;                                                    \
-                                                                        \
-        for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) { \
-            pipebit = g_usb0_function_bit_set[pipe];                    \
-                                                                        \
-            if ((status & pipebit) && (intenb & pipebit)) {             \
-                USB200.BRDYSTS = (uint16_t)~pipebit;                    \
-                USB200.BEMPSTS = (uint16_t)~pipebit;                    \
-                                                                        \
-                switch (g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) { \
-                    case USB_FUNCTION_D0FIFO_DMA:                       \
-                        if (g_usb0_function_DmaStatus[USB_FUNCTION_D0FIFO] != USB_FUNCTION_DMA_READY) { \
-                            /*now, DMA is not supported*/               \
-                            usb0_function_dma_interrupt_d0fifo(int_sense); \
-                        }                                               \
-                                                                        \
-                        if (RZA_IO_RegRead_16(                          \
-                                &g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) { \
-                            /*now, DMA is not supported*/               \
-                            usb0_function_read_dma(pipe);               \
-                            usb0_function_disable_brdy_int(pipe);       \
-                        } else {                                        \
-                            USB200.D0FIFOCTR = USB_FUNCTION_BITBCLR;    \
-                            g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE; \
-                        }                                               \
-                        break;                                          \
-                                                                        \
-                    case USB_FUNCTION_D1FIFO_DMA:                       \
-                        if (g_usb0_function_DmaStatus[USB_FUNCTION_D1FIFO] != USB_FUNCTION_DMA_READY) { \
-                            /*now, DMA is not supported*/               \
-                            usb0_function_dma_interrupt_d1fifo(int_sense); \
-                        }                                               \
-                                                                        \
-                        if (RZA_IO_RegRead_16(                          \
-                                &g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) { \
-                            /*now, DMA is not supported*/               \
-                            usb0_function_read_dma(pipe);               \
-                            usb0_function_disable_brdy_int(pipe);       \
-                        } else {                                        \
-                            USB200.D1FIFOCTR = USB_FUNCTION_BITBCLR;    \
-                            g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE; \
-                        }                                               \
-                        break;                                          \
-                                                                        \
-                    default:                                            \
-                        ep = (g_usb0_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT; \
-                        ep <<= 1;                                       \
-                        ep += (RZA_IO_RegRead_16(&g_usb0_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0)? \
-                            (0): (1);                                   \
-                        EPx_read_status = DEVDRV_USBF_PIPE_WAIT;        \
-                        (instance->*(epCallback[ep - 2])) ();           \
-                        EPx_read_status = DEVDRV_USBF_PIPE_DONE;        \
-                }                                                       \
-            }                                                           \
-        }                                                               \
-        /* Three dummy reads for clearing interrupt requests */         \
-        dumy_sts = USB200.BRDYSTS;                                      \
+extern "C" {
+    void usb0_function_BRDYInterrupt(
+        uint16_t status,
+        uint16_t intenb,
+        USBHAL *object,
+        bool (USBHAL::*epCallback[])(void)
+    )
+    {
+        volatile uint16_t dumy_sts;
+
+        /**************************************************************
+         * Function Name: usb0_function_brdy_int
+         * Description  : Executes BRDY interrupt(USB_FUNCTION_PIPE1-9).
+         *              : According to the pipe that interrupt is generated in,
+         *              : reads/writes buffer allocated in the pipe.
+         *              : This function is executed in the BRDY
+         *              : interrupt handler.  This function
+         *              : clears BRDY interrupt status and BEMP
+         *              : interrupt status.
+         * Arguments    : uint16_t Status    ; BRDYSTS Register Value
+         *              : uint16_t Int_enbl  ; BRDYENB Register Value
+         * Return Value : none
+         *************************************************************/
+        /* copied from usb0_function_intrn.c */
+        uint32_t int_sense = 0;
+        uint16_t pipe;
+        uint16_t pipebit;
+        uint16_t ep;
+
+        for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) {
+            pipebit = g_usb0_function_bit_set[pipe];
+
+            if ((status & pipebit) && (intenb & pipebit)) {
+                USB200.BRDYSTS = (uint16_t)~pipebit;
+                USB200.BEMPSTS = (uint16_t)~pipebit;
+
+                switch (g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) {
+                    case USB_FUNCTION_D0FIFO_DMA:
+                        if (g_usb0_function_DmaStatus[USB_FUNCTION_D0FIFO] != USB_FUNCTION_DMA_READY) {
+                            /*now, DMA is not supported*/
+                            usb0_function_dma_interrupt_d0fifo(int_sense);
+                        }
+
+                        if (RZA_IO_RegRead_16(
+                                &g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) {
+                            /*now, DMA is not supported*/
+                            usb0_function_read_dma(pipe);
+                            usb0_function_disable_brdy_int(pipe);
+                        } else {
+                            USB200.D0FIFOCTR = USB_FUNCTION_BITBCLR;
+                            g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE;
+                        }
+                        break;
+
+                    case USB_FUNCTION_D1FIFO_DMA:
+                        if (g_usb0_function_DmaStatus[USB_FUNCTION_D1FIFO] != USB_FUNCTION_DMA_READY) {
+                            /*now, DMA is not supported*/
+                            usb0_function_dma_interrupt_d1fifo(int_sense);
+                        }
+
+                        if (RZA_IO_RegRead_16(
+                                &g_usb0_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) {
+                            /*now, DMA is not supported*/
+                            usb0_function_read_dma(pipe);
+                            usb0_function_disable_brdy_int(pipe);
+                        } else {
+                            USB200.D1FIFOCTR = USB_FUNCTION_BITBCLR;
+                            g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE;
+                        }
+                        break;
+
+                    default:
+                        ep = (g_usb0_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT;
+                        ep <<= 1;
+                        if (RZA_IO_RegRead_16(
+                                &g_usb0_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0) {
+                            /* read */
+                            EPx_read_status = DEVDRV_USBF_PIPE_WAIT;
+                            (object->*(epCallback[ep - 2])) ();
+                            EPx_read_status = DEVDRV_USBF_PIPE_DONE;
+                        } else {
+                            /* write */
+                            EPx_read_status = DEVDRV_USBF_PIPE_WAIT;
+                            (object->*(epCallback[ep - 2 + 1])) ();
+                            EPx_read_status = DEVDRV_USBF_PIPE_DONE;
+                            usb0_function_write_buffer(pipe);
+                        }
+                }
+            }
+        }
+        /* Three dummy reads for clearing interrupt requests */
+        dumy_sts = USB200.BRDYSTS;
     }
+}
 
 
 /******************************************************************************
@@ -339,16 +383,24 @@
  *              : uint16_t intenb       ; NRDYENB Register Value
  * Return Value : none
  *****************************************************************************/
-#define usb0_function_NRDYInterruptPIPE0(status, intenb)                \
-    {                                                                   \
-        volatile uint16_t dumy_sts;                                     \
-                                                                        \
-        USB200.NRDYSTS =                                                \
-            (uint16_t)~g_usb0_function_bit_set[USB_FUNCTION_PIPE0];     \
-                                                                        \
-        /* Three dummy reads for clearing interrupt requests */         \
-        dumy_sts = USB200.NRDYSTS;                                      \
+extern "C" {
+    void usb0_function_NRDYInterruptPIPE0(
+        uint16_t status,
+        uint16_t intenb,
+        USBHAL *object,
+        void (USBHAL::*EP0func)(void)
+    )
+    {
+        volatile uint16_t dumy_sts;
+
+        USB200.NRDYSTS =
+            (uint16_t)~g_usb0_function_bit_set[USB_FUNCTION_PIPE0];
+
+        /* Three dummy reads for clearing interrupt requests */
+        dumy_sts = USB200.NRDYSTS;
     }
+}
+
 
 /******************************************************************************
  * Function Name: usb0_function_NRDYInterrupt
@@ -357,16 +409,124 @@
  *              : uint16_t intenb       ; NRDYENB Register Value
  * Return Value : none
  *****************************************************************************/
-#define usb0_function_NRDYInterrupt(status, intenb)                     \
-    {                                                                   \
-        volatile uint16_t dumy_sts;                                     \
-                                                                        \
-        usb0_function_nrdy_int(status, intenb);                         \
-                                                                        \
-        /* Three dummy reads for clearing interrupt requests */         \
-        dumy_sts = USB200.NRDYSTS;                                      \
+extern "C" {
+    void usb0_function_NRDYInterrupt(
+        uint16_t status,
+        uint16_t intenb,
+        USBHAL *object,
+        bool (USBHAL::*epCallback[])(void)
+    )
+    {
+        volatile uint16_t dumy_sts;
+
+        /**************************************************************
+         * Function Name: usb0_function_nrdy_int
+         * Description  : Executes NRDY interrupt(USB_FUNCTION_PIPE1-9).
+         *              : Checks NRDY interrupt cause by PID. When the cause if STALL,
+         *              : regards the pipe state as STALL and ends the processing.
+         *              : Then the cause is not STALL, increments the error count to
+         *              : communicate again. When the error count is 3, determines
+         *              : the pipe state as DEVDRV_USBF_PIPE_NORES and ends the processing.
+         *              : This function is executed in the NRDY interrupt handler.
+         *              : This function clears NRDY interrupt status.
+         * Arguments    : uint16_t status       ; NRDYSTS Register Value
+         *              : uint16_t int_enb      ; NRDYENB Register Value
+         * Return Value : none
+         *************************************************************/
+        /* copied from usb0_function_intrn.c */
+#if 0
+        uint16_t usefifo;
+#endif
+        uint16_t pid;
+        uint16_t pipe;
+        uint16_t bitcheck;
+#if 0
+        uint16_t mbw;
+        uint32_t size;
+#endif
+        uint16_t ep;
+
+        bitcheck = (uint16_t)(status & intenb);
+
+        USB200.NRDYSTS = (uint16_t)~status;
+
+
+        if (RZA_IO_RegRead_16(&USB200.SYSCFG0, USB_SYSCFG_DCFM_SHIFT, USB_SYSCFG_DCFM) == 1) {
+            /* USB HOST */
+            /* not support */
+
+        } else {
+            /* USB Function */
+            for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) {
+                if ((bitcheck&g_usb0_function_bit_set[pipe]) != g_usb0_function_bit_set[pipe]) {
+                    continue;
+                }
+
+                if (g_usb0_function_pipe_status[pipe] != DEVDRV_USBF_PIPE_WAIT) {
+                    continue;
+                }
+
+#if 0
+                usb0_function_set_pid_nak(pipe);
+
+                size = (uint32_t)g_usb0_function_data_count[pipe];
+                mbw = usb0_function_get_mbw(
+                    size, (uint32_t)g_usb0_function_data_pointer[pipe]);
+
+                usefifo = (uint16_t)(g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE);
+                switch (usefifo) {
+
+                    case USB_FUNCTION_D0FIFO_USE:
+                        usb0_function_set_curpipe(
+                            pipe, USB_FUNCTION_D0USE, DEVDRV_USBF_NO, mbw);
+                        USB200.D0FIFOCTR = USB_FUNCTION_BITBCLR;
+                        break;
+
+                    case USB_FUNCTION_D1FIFO_USE:
+                        usb0_function_set_curpipe(
+                            pipe, USB_FUNCTION_D1USE, DEVDRV_USBF_NO, mbw);
+                        USB200.D1FIFOCTR = USB_FUNCTION_BITBCLR;
+                        break;
+
+                    default:
+                        usb0_function_set_curpipe(
+                            pipe, USB_FUNCTION_CUSE, USB_FUNCTION_CFIFO_READ, mbw);
+                        USB200.CFIFOCTR = USB_FUNCTION_BITBCLR;
+                        break;
+                }
+
+                usb0_function_aclrm(pipe);
+
+                usb0_function_enable_nrdy_int(pipe);
+                usb0_function_enable_brdy_int(pipe);
+
+                usb0_function_set_pid_buf(pipe);
+#endif
+
+                pid = usb0_function_get_pid(pipe);
+                if ((pid == DEVDRV_USBF_PID_STALL) || (pid == DEVDRV_USBF_PID_STALL2)) {
+                    g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_STALL;
+                } else {
+                    usb0_function_set_pid_buf(pipe);
+                }
+
+                ep = (g_usb0_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT;
+                ep <<= 1;
+                if (RZA_IO_RegRead_16(
+                        &g_usb0_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0) {
+                    /* read */
+                    __nop();
+                } else {
+                    /* write */
+                    __nop();
+                }
+            }
+        }
+
+        /* Three dummy reads for clearing interrupt requests */
+        dumy_sts = USB200.NRDYSTS;
     }
-
+}
 
 /******************************************************************************
  * Function Name: usb0_function_BEMPInterruptPIPE0
@@ -375,22 +535,29 @@
  *              : uint16_t intenb       ; BEMPENB Register Value
  * Return Value : none
  *****************************************************************************/
-#define usb0_function_BEMPInterruptPIPE0(status, intenb)                \
-    {                                                                   \
-        volatile uint16_t dumy_sts;                                     \
-                                                                        \
-        USB200.BEMPSTS =                                                \
-            (uint16_t)~g_usb0_function_bit_set[USB_FUNCTION_PIPE0];     \
-        RZA_IO_RegWrite_16(                                             \
-            &USB200.CFIFOSEL, USB_FUNCTION_PIPE0,                       \
-            USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE);          \
-                                                                        \
-        /*usb0_function_write_buffer_c(USB_FUNCTION_PIPE0);*/           \
-        EP0in();                                                        \
-                                                                        \
-        /* Three dummy reads for clearing interrupt requests */         \
-        dumy_sts = USB200.BEMPSTS;                                      \
+extern "C" {
+    void usb0_function_BEMPInterruptPIPE0(
+        uint16_t status,
+        uint16_t intenb,
+        USBHAL *object,
+        void (USBHAL::*EP0func)(void)
+    )
+    {
+        volatile uint16_t dumy_sts;
+
+        USB200.BEMPSTS =
+            (uint16_t)~g_usb0_function_bit_set[USB_FUNCTION_PIPE0];
+        RZA_IO_RegWrite_16(
+            &USB200.CFIFOSEL, USB_FUNCTION_PIPE0,
+            USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE);
+
+        /*usb0_function_write_buffer_c(USB_FUNCTION_PIPE0);*/
+        (object->*EP0func)();
+
+        /* Three dummy reads for clearing interrupt requests */
+        dumy_sts = USB200.BEMPSTS;
     }
+}
 
 
 /******************************************************************************
@@ -400,17 +567,85 @@
  *              : uint16_t intenb       ; BEMPENB Register Value
  * Return Value : none
  *****************************************************************************/
-#define usb0_function_BEMPInterrupt(status, intenb)                     \
-    {                                                                   \
-        volatile uint16_t dumy_sts;                                     \
-                                                                        \
-        usb0_function_bemp_int(status, intenb);                         \
-                                                                        \
-        /* Three dummy reads for clearing interrupt requests */         \
-        dumy_sts = USB200.BEMPSTS;                                      \
+extern "C" {
+    void usb0_function_BEMPInterrupt(
+        uint16_t status,
+        uint16_t intenb,
+        USBHAL *object,
+        bool (USBHAL::*epCallback[])(void)
+    )
+    {
+        volatile uint16_t dumy_sts;
+
+        /**************************************************************
+         * Function Name: usb0_function_bemp_int
+         * Description  : Executes BEMP interrupt(USB_FUNCTION_PIPE1-9).
+         * Arguments    : uint16_t status       ; BEMPSTS Register Value
+         *              : uint16_t intenb      ; BEMPENB Register Value
+         * Return Value : none
+         *************************************************************/
+        /* copied from usb0_function_intrn.c */
+        uint16_t pid;
+        uint16_t pipe;
+        uint16_t bitcheck;
+        uint16_t inbuf;
+        uint16_t ep;
+
+        bitcheck = (uint16_t)(status & intenb);
+
+        USB200.BEMPSTS = (uint16_t)~status;
+
+        for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) {
+            if ((bitcheck&g_usb0_function_bit_set[pipe]) != g_usb0_function_bit_set[pipe]) {
+                continue;
+            }
+
+            pid = usb0_function_get_pid(pipe);
+
+            if ((pid == DEVDRV_USBF_PID_STALL) ||
+                (pid == DEVDRV_USBF_PID_STALL2)) {
+                g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_STALL;
+
+            } else {
+                inbuf = usb0_function_get_inbuf(pipe);
+
+                if (inbuf == 0) {
+                    usb0_function_disable_bemp_int(pipe);
+                    usb0_function_set_pid_nak(pipe);
+                    g_usb0_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE;
+
+                    switch (g_usb0_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) {
+                        case USB_FUNCTION_D0FIFO_DMA:
+                            /*now, DMA is not supported*/
+                            break;
+
+                        case USB_FUNCTION_D1FIFO_DMA:
+                            /*now, DMA is not supported*/
+                            break;
+
+                        default:
+                            ep = (g_usb0_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT;
+                            ep <<= 1;
+                            if (RZA_IO_RegRead_16(
+                                    &g_usb0_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0) {
+                                /* read */
+                                __nop();
+                            } else {
+                                /* write */
+                                EPx_read_status = DEVDRV_USBF_PIPE_WAIT;
+                                (object->*(epCallback[ep - 2 + 1])) ();
+                                EPx_read_status = DEVDRV_USBF_PIPE_DONE;
+                            }
+                    }
+                }
+            }
+        }
+
+        /* Three dummy reads for clearing interrupt requests */
+        dumy_sts = USB200.BEMPSTS;
+    }
 }
 
-
 /******************************************************************************
  * Function Name: EP2PIPE
  * Description  : Converts from endpoint to pipe
@@ -440,7 +675,7 @@
         *bufO++ = USB200.USBINDX;                           \
         /*data[6] data[6] <= wIndex*/                       \
         *bufO++ = USB200.USBLENG;                           \
-}
+    }
 
 
 /*************************************************************************/
@@ -452,13 +687,17 @@
 USBHAL::USBHAL(void)
 {
     /* ---- P4_1 : P4_1 (USB0_EN for GR-PEACH) ---- */
-    usb0_en = new DigitalOut(P4_1, 1);
+    //usb0_en = new DigitalOut(P4_1, 1);
 
     /* some constants */
     int_id          = USBI0_IRQn;
     int_level       = ( 2 << 3 );
     clock_mode      = USBFCLOCK_X1_48MHZ;
+#if 1
     mode            = USB_FUNCTION_HIGH_SPEED;
+#else
+    mode            = USB_FUNCTION_FULL_SPEED;
+#endif
     EP0_read_status = DEVDRV_USBF_WRITEEND;
     EPx_read_status = DEVDRV_USBF_PIPE_DONE;
 
@@ -572,7 +811,7 @@
     /* Unregisters interrupt function and priority */
     InterruptHandlerRegister( int_id, (uint32_t)NULL );
 
-    usb0_en  = NULL;
+    //usb0_en  = NULL;
     instance = NULL;
 }
 
@@ -580,7 +819,7 @@
 void USBHAL::connect(void)
 {
     /* Activates USB0_EN */
-    (*usb0_en) = 0;
+    //(*usb0_en) = 0;
 }
 
 
@@ -588,7 +827,7 @@
 void USBHAL::disconnect(void)
 {
     /* Deactivates USB0_EN */
-    (*usb0_en) = 1;
+    //(*usb0_en) = 1;
 }
 
 
@@ -790,15 +1029,19 @@
     EP_STATUS status = EP_COMPLETED;
 
     pipe_status = usb0_api_function_check_pipe_status(pipe, &pipe_size);
-    pipe_size = (max_size < pipe_size)? (max_size): (pipe_size);
+
+    switch (pipe_status) {
+        case DEVDRV_USBF_PIPE_IDLE:
+        case DEVDRV_USBF_PIPE_WAIT:
+            usb0_api_function_set_pid_nak(pipe);
+            usb0_api_function_clear_pipe_status(pipe);
 
-    if (pipe_status == DEVDRV_USBF_PIPE_IDLE) {
-        usb0_api_function_set_pid_nak(pipe);
-        usb0_api_function_clear_pipe_status(pipe);
+            usb0_api_function_start_receive_transfer(pipe, max_size, recv_buffer);
+            break;
 
-        usb0_api_function_start_receive_transfer(pipe, pipe_size, recv_buffer);
-    } else {
-        status = EP_PENDING;
+        default:
+            status = EP_PENDING;
+            break;
     }
 
     return status;
@@ -819,14 +1062,18 @@
     }
 
     pipe_status = usb0_api_function_check_pipe_status(pipe, bytes_read);
-    if (pipe_status == DEVDRV_USBF_PIPE_IDLE) {
-        return EP_COMPLETED;
-    }
-    if (pipe_status == DEVDRV_USBF_PIPE_DONE) {
-        return EP_COMPLETED;
-    }
-    if (pipe_status != DEVDRV_USBF_PIPE_WAIT) {
-        return status;
+    switch (pipe_status) {
+        case DEVDRV_USBF_PIPE_IDLE:
+            return EP_COMPLETED;
+
+        case DEVDRV_USBF_PIPE_DONE:
+            return EP_COMPLETED;
+
+        case DEVDRV_USBF_PIPE_WAIT:
+            break;
+
+        default:
+            return status;
     }
 
     /* sets the output buffer and size */
@@ -835,10 +1082,30 @@
     /* receives data from pipe */
     err = usb0_function_read_buffer(pipe);
     recv_error = err;
+    switch (err) {
+        case USB_FUNCTION_READEND:
+        case USB_FUNCTION_READSHRT:
+        case USB_FUNCTION_READOVER:
+            *bytes_read = g_usb0_function_PipeDataSize[pipe];
+            break;
+
+        case USB_FUNCTION_READING:
+        case DEVDRV_USBF_FIFOERROR:
+            break;
+    }
 
     pipe_status = usb0_api_function_check_pipe_status(pipe, bytes_read);
-    if (pipe_status == DEVDRV_USBF_PIPE_DONE) {
-        status = EP_COMPLETED;
+    switch (pipe_status) {
+        case DEVDRV_USBF_PIPE_DONE:
+            status = EP_COMPLETED;
+            break;
+
+        case DEVDRV_USBF_PIPE_IDLE:
+        case DEVDRV_USBF_PIPE_NORES:
+        case DEVDRV_USBF_PIPE_STALL:
+        case DEVDRV_USBF_FIFOERROR:
+        default:
+            break;
     }
 
     return status;
@@ -1112,19 +1379,19 @@
         (int_enb0 & USB_FUNCTION_BITBEMP) &&
         ((int_sts3 & int_enb4) & g_usb0_function_bit_set[USB_FUNCTION_PIPE0])) {
         /* ==== BEMP PIPE0 ==== */
-        usb0_function_BEMPInterruptPIPE0(int_sts3, int_enb4);
+        usb0_function_BEMPInterruptPIPE0(int_sts3, int_enb4, this, &USBHAL::EP0in);
     } else if (
         (int_sts0 & USB_FUNCTION_BITBRDY) &&
         (int_enb0 & USB_FUNCTION_BITBRDY) &&
         ((int_sts1 & int_enb2) & g_usb0_function_bit_set[USB_FUNCTION_PIPE0])) {
         /* ==== BRDY PIPE0 ==== */
-        usb0_function_BRDYInterruptPIPE0(int_sts1, int_enb2);
+        usb0_function_BRDYInterruptPIPE0(int_sts1, int_enb2, this, &USBHAL::EP0out);
     } else if (
         (int_sts0 & USB_FUNCTION_BITNRDY) &&
         (int_enb0 & USB_FUNCTION_BITNRDY) &&
         ((int_sts2 & int_enb3) & g_usb0_function_bit_set[USB_FUNCTION_PIPE0])) {
         /* ==== NRDY PIPE0 ==== */
-        usb0_function_NRDYInterruptPIPE0(int_sts2, int_enb3);
+        usb0_function_NRDYInterruptPIPE0(int_sts2, int_enb3, this, NULL);
     } else if (
         (int_sts0 & USB_FUNCTION_BITCTRT) && (int_enb0 & USB_FUNCTION_BITCTRE)) {
         int_sts0 = USB200.INTSTS0;
@@ -1198,19 +1465,19 @@
         (int_enb0 & USB_FUNCTION_BITBEMP) &&
         (int_sts3 & int_enb4) ) {
         /* ==== BEMP PIPEx ==== */
-        usb0_function_BEMPInterrupt(int_sts3, int_enb4);
+        usb0_function_BEMPInterrupt(int_sts3, int_enb4, this, epCallback);
     } else if (
         (int_sts0 & USB_FUNCTION_BITBRDY) &&
         (int_enb0 & USB_FUNCTION_BITBRDY) &&
         (int_sts1 & int_enb2) ) {
         /* ==== BRDY PIPEx ==== */
-        usb0_function_BRDYInterrupt(int_sts1, int_enb2);
+        usb0_function_BRDYInterrupt(int_sts1, int_enb2, this, epCallback);
     } else if (
         (int_sts0 & USB_FUNCTION_BITNRDY) &&
         (int_enb0 & USB_FUNCTION_BITNRDY) &&
         (int_sts2 & int_enb3)) {
         /* ==== NRDY PIPEx ==== */
-        usb0_function_NRDYInterrupt(int_sts2, int_enb3);
+        usb0_function_NRDYInterrupt(int_sts2, int_enb3, this, epCallback);
     } else {
         /* Do Nothing */
     }