USB device stack for NUCLEO-F042K6, NUCLEO-L152RE and NUCLEO-F103RB.

Dependents:   LPE-SEM01

Fork of L152RE_USBDevice by Norimasa Okamoto

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHAL_RZ_A1H.cpp Source File

USBHAL_RZ_A1H.cpp

00001 /* Copyright (c) 2010-2011 mbed.org, MIT License
00002 *
00003 * Permission is hereby granted, free of charge, to any person
00004 * obtaining a copy of this software and associated documentation
00005 * files (the "Software"), to deal in the Software without
00006 * restriction, including without limitation the rights to use,
00007 * copy, modify, merge, publish, distribute, sublicense, and/or
00008 * sell copies of the Software, and to permit persons to whom the
00009 * Software is furnished to do so, subject to the following
00010 * conditions:
00011 *
00012 * The above copyright notice and this permission notice shall be
00013 * included in all copies or substantial portions of the
00014 * Software.
00015 *
00016 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
00017 * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
00018 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
00019 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
00020 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
00022 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00023 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00024 */
00025 
00026 #if defined(TARGET_RZ_A1H)
00027 
00028 /*
00029   This class can use the pipe1, pipe3 and pipe6 only. You should
00030   re-program this class if you wanted to use other pipe.
00031  */
00032 
00033 /*************************************************************************/
00034 extern "C"
00035 {
00036 #include "r_typedefs.h"
00037 #include "iodefine.h"
00038 }
00039 #include "USBHAL.h"
00040 #include "devdrv_usb_function_api.h"
00041 #include "usb_iobitmask.h"
00042 #include "rza_io_regrw.h"
00043 #include "USBDevice_Types.h"
00044 #include "usb_function_setting.h"
00045 
00046 
00047 /*************************************************************************/
00048 /* constants */
00049 const struct PIPECFGREC {
00050     uint16_t    endpoint;
00051     uint16_t    pipesel;
00052     uint16_t    pipecfg;
00053     uint16_t    pipebuf;
00054     uint16_t    pipemaxp;
00055     uint16_t    pipeperi;
00056 } def_pipecfg[] = {
00057     /*EP0OUT and EP0IN are configured by USB IP*/
00058     {
00059         EP1OUT, /*EP1: Host -> Func, INT*/
00060         6 | USB_FUNCTION_D0FIFO_USE,
00061         USB_FUNCTION_INTERRUPT |
00062         USB_FUNCTION_BFREOFF   |
00063         USB_FUNCTION_DBLBOFF   |
00064         USB_FUNCTION_CNTMDON   |
00065         USB_FUNCTION_SHTNAKOFF |
00066         USB_FUNCTION_DIR_P_OUT |
00067         USB_FUNCTION_EP1,
00068         ( ( (  64) / 64 - 1 ) << 10 ) | 0x04u,
00069         MAX_PACKET_SIZE_EP1,
00070         DEVDRV_USBF_OFF |
00071         ( 3 << USB_PIPEPERI_IITV_SHIFT ),
00072     },
00073     {
00074         EP1IN,  /*EP1: Host <- Func, INT*/
00075         7 | USB_FUNCTION_D1FIFO_USE,
00076         USB_FUNCTION_INTERRUPT |
00077         USB_FUNCTION_BFREOFF   |
00078         USB_FUNCTION_DBLBOFF   |
00079         USB_FUNCTION_CNTMDOFF  |
00080         USB_FUNCTION_SHTNAKOFF |
00081         USB_FUNCTION_DIR_P_IN  |
00082         USB_FUNCTION_EP1,
00083         ( ( (  64) / 64 - 1 ) << 10 ) | 0x05u,
00084         MAX_PACKET_SIZE_EP1,
00085         DEVDRV_USBF_OFF |
00086         ( 3 << USB_PIPEPERI_IITV_SHIFT ),
00087     },
00088     {
00089         EP2OUT, /*EP2: Host -> Func, BULK*/
00090         3 | USB_FUNCTION_D0FIFO_USE,
00091         USB_FUNCTION_BULK      |
00092         USB_FUNCTION_BFREOFF   |
00093         USB_FUNCTION_DBLBON    |
00094         USB_FUNCTION_CNTMDON   |
00095         USB_FUNCTION_SHTNAKON  |
00096         USB_FUNCTION_DIR_P_OUT |
00097         USB_FUNCTION_EP2,
00098         ( ( (2048) / 64 - 1 ) << 10 ) | 0x30u,
00099         MAX_PACKET_SIZE_EP2,
00100         DEVDRV_USBF_OFF |
00101         ( 0 << USB_PIPEPERI_IITV_SHIFT ),
00102     },
00103     {
00104         EP2IN,  /*EP2: Host <- Func, BULK*/
00105         4 | USB_FUNCTION_D1FIFO_USE,
00106         USB_FUNCTION_BULK      |
00107         USB_FUNCTION_BFREOFF   |
00108         USB_FUNCTION_DBLBOFF   |
00109         USB_FUNCTION_CNTMDON   |
00110         USB_FUNCTION_SHTNAKOFF |
00111         USB_FUNCTION_DIR_P_IN  |
00112         USB_FUNCTION_EP2,
00113         ( ( (2048) / 64 - 1 ) << 10 ) | 0x50u,
00114         MAX_PACKET_SIZE_EP2,
00115         DEVDRV_USBF_OFF |
00116         ( 0 << USB_PIPEPERI_IITV_SHIFT ),
00117     },
00118     {
00119         EP3OUT, /*EP3: Host -> Func, ISO*/
00120         1 | USB_FUNCTION_D0FIFO_USE,
00121         USB_FUNCTION_ISO       |
00122         USB_FUNCTION_BFREOFF   |
00123         USB_FUNCTION_DBLBON    |
00124         USB_FUNCTION_CNTMDOFF  |
00125         USB_FUNCTION_SHTNAKON  |
00126         USB_FUNCTION_DIR_P_OUT |
00127         USB_FUNCTION_EP3,
00128         ( ( ( 512) / 64 - 1 ) << 10 ) | 0x10u,
00129         MAX_PACKET_SIZE_EP3,
00130         DEVDRV_USBF_OFF |
00131         ( 0 << USB_PIPEPERI_IITV_SHIFT ),
00132     },
00133     {
00134         EP3IN,  /*EP3: Host <- Func, ISO*/
00135         2 | USB_FUNCTION_D1FIFO_USE,
00136         USB_FUNCTION_ISO       |
00137         USB_FUNCTION_BFREOFF   |
00138         USB_FUNCTION_DBLBON    |
00139         USB_FUNCTION_CNTMDOFF  |
00140         USB_FUNCTION_SHTNAKOFF |
00141         USB_FUNCTION_DIR_P_IN  |
00142         USB_FUNCTION_EP3,
00143         ( ( ( 512) / 64 - 1 ) << 10 ) | 0x20u,
00144         MAX_PACKET_SIZE_EP3,
00145         DEVDRV_USBF_OFF |
00146         ( 0 << USB_PIPEPERI_IITV_SHIFT ),
00147     },
00148     { /*terminator*/
00149         0, 0, 0, 0, 0,
00150     },
00151 };
00152 
00153 
00154 /*************************************************************************/
00155 /* workareas */
00156 USBHAL * USBHAL::instance;
00157 
00158 static IRQn_Type    int_id;         /* interrupt ID          */
00159 static uint16_t     int_level;      /* initerrupt level      */
00160 static uint16_t     clock_mode;     /* input clock selector  */
00161 static uint16_t     mode;           /* USB speed (HIGH/FULL) */
00162 
00163 //static DigitalOut *usbx_en;
00164 
00165 static uint16_t     EP0_read_status;
00166 static uint16_t     EPx_read_status;
00167 
00168 static uint16_t setup_buffer[MAX_PACKET_SIZE_EP0 / 2];
00169 
00170 /* 0: not used / other: a pipe number to use recv_buffer*/
00171 static uint8_t  recv_buffer[MAX_PACKET_SIZE_EPBULK];
00172 volatile static uint16_t    recv_error;
00173 
00174 
00175 /*************************************************************************/
00176 /* prototypes for C */
00177 extern "C" {
00178     void usbx_function_BRDYInterruptPIPE0 (uint16_t status, uint16_t intenb,
00179         USBHAL *object, void (USBHAL::*EP0func)(void));
00180 
00181     void usbx_function_BRDYInterrupt (uint16_t status, uint16_t intenb,
00182         USBHAL *object, bool (USBHAL::*epCallback[])(void));
00183 
00184     void usbx_function_NRDYInterruptPIPE0(uint16_t status, uint16_t intenb,
00185         USBHAL *object, void (USBHAL::*EP0func)(void));
00186 
00187     void usbx_function_NRDYInterrupt (uint16_t status, uint16_t intenb,
00188         USBHAL *object, bool (USBHAL::*epCallback[])(void));
00189 
00190     void usbx_function_BEMPInterruptPIPE0(uint16_t status, uint16_t intenb,
00191         USBHAL *object, void (USBHAL::*EP0func)(void));
00192 
00193     void usbx_function_BEMPInterrupt (uint16_t status, uint16_t intenb,
00194         USBHAL *object, bool (USBHAL::*epCallback[])(void));
00195 }
00196 
00197 
00198 /*************************************************************************/
00199 /* macros */
00200 
00201 /******************************************************************************
00202  * Function Name: usbx_function_BRDYInterruptPIPE0
00203  * Description  : Executes BRDY interrupt for pipe0.
00204  * Arguments    : uint16_t status       ; BRDYSTS Register Value
00205  *              : uint16_t intenb       ; BRDYENB Register Value
00206  * Return Value : none
00207  *****************************************************************************/
00208 extern "C" {
00209     void usbx_function_BRDYInterruptPIPE0 (
00210         uint16_t status,
00211         uint16_t intenb,
00212         USBHAL *object,
00213         void (USBHAL::*EP0func)(void)
00214     )
00215     {
00216         volatile uint16_t dumy_sts;
00217         uint16_t read_status;
00218 
00219         USB20X.BRDYSTS =
00220             (uint16_t)~g_usbx_function_bit_set[USB_FUNCTION_PIPE0];
00221         RZA_IO_RegWrite_16(
00222             &USB20X.CFIFOSEL, USB_FUNCTION_PIPE0,
00223             USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE);
00224 
00225         g_usbx_function_PipeDataSize[USB_FUNCTION_PIPE0] =
00226             g_usbx_function_data_count[USB_FUNCTION_PIPE0];
00227 
00228         read_status = usbx_function_read_buffer_c(USB_FUNCTION_PIPE0);
00229 
00230         g_usbx_function_PipeDataSize[USB_FUNCTION_PIPE0] -=
00231             g_usbx_function_data_count[USB_FUNCTION_PIPE0];
00232 
00233         switch (read_status) {
00234             case USB_FUNCTION_READING:      /* Continue of data read */
00235             case USB_FUNCTION_READEND:      /* End of data read */
00236                 /* PID = BUF */
00237                 usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);
00238 
00239                 /*callback*/
00240                 (object->*EP0func)();
00241                 break;
00242 
00243             case USB_FUNCTION_READSHRT:     /* End of data read */
00244                 usbx_function_disable_brdy_int(USB_FUNCTION_PIPE0);
00245                 /* PID = BUF */
00246                 usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);
00247 
00248                 /*callback*/
00249                 (object->*EP0func)();
00250                 break;
00251 
00252             case USB_FUNCTION_READOVER:     /* FIFO access error */
00253                 /* Buffer Clear */
00254                 USB20X.CFIFOCTR = USB_FUNCTION_BITBCLR;
00255                 usbx_function_disable_brdy_int(USB_FUNCTION_PIPE0);
00256                 /* Req Error */
00257                 usbx_function_set_pid_stall(USB_FUNCTION_PIPE0);
00258 
00259                 /*callback*/
00260                 (object->*EP0func)();
00261                 break;
00262 
00263             case DEVDRV_USBF_FIFOERROR:     /* FIFO access error */
00264             default:
00265                 usbx_function_disable_brdy_int(USB_FUNCTION_PIPE0);
00266                 /* Req Error */
00267                 usbx_function_set_pid_stall(USB_FUNCTION_PIPE0);
00268                 break;
00269         }
00270         /* Three dummy reads for clearing interrupt requests */
00271         dumy_sts = USB20X.BRDYSTS;
00272     }
00273 }
00274 
00275 
00276 /******************************************************************************
00277  * Function Name: usbx_function_BRDYInterrupt
00278  * Description  : Executes BRDY interrupt uxclude pipe0.
00279  * Arguments    : uint16_t status       ; BRDYSTS Register Value
00280  *              : uint16_t intenb       ; BRDYENB Register Value
00281  * Return Value : none
00282  *****************************************************************************/
00283 extern "C" {
00284     void usbx_function_BRDYInterrupt(
00285         uint16_t status,
00286         uint16_t intenb,
00287         USBHAL *object,
00288         bool (USBHAL::*epCallback[])(void)
00289     )
00290     {
00291         volatile uint16_t dumy_sts;
00292 
00293         /**************************************************************
00294          * Function Name: usbx_function_brdy_int
00295          * Description  : Executes BRDY interrupt(USB_FUNCTION_PIPE1-9).
00296          *              : According to the pipe that interrupt is generated in,
00297          *              : reads/writes buffer allocated in the pipe.
00298          *              : This function is executed in the BRDY
00299          *              : interrupt handler.  This function
00300          *              : clears BRDY interrupt status and BEMP
00301          *              : interrupt status.
00302          * Arguments    : uint16_t Status    ; BRDYSTS Register Value
00303          *              : uint16_t Int_enbl  ; BRDYENB Register Value
00304          * Return Value : none
00305          *************************************************************/
00306         /* copied from usbx_function_intrn.c */
00307         uint32_t int_sense = 0;
00308         uint16_t pipe;
00309         uint16_t pipebit;
00310         uint16_t ep;
00311 
00312         for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) {
00313             pipebit = g_usbx_function_bit_set[pipe];
00314 
00315             if ((status & pipebit) && (intenb & pipebit)) {
00316                 USB20X.BRDYSTS = (uint16_t)~pipebit;
00317                 USB20X.BEMPSTS = (uint16_t)~pipebit;
00318 
00319                 switch (g_usbx_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) {
00320                     case USB_FUNCTION_D0FIFO_DMA:
00321                         if (g_usbx_function_DmaStatus[USB_FUNCTION_D0FIFO] != USB_FUNCTION_DMA_READY) {
00322                             /*now, DMA is not supported*/
00323                             usbx_function_dma_interrupt_d0fifo(int_sense);
00324                         }
00325 
00326                         if (RZA_IO_RegRead_16(
00327                                 &g_usbx_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) {
00328                             /*now, DMA is not supported*/
00329                             usbx_function_read_dma(pipe);
00330                             usbx_function_disable_brdy_int(pipe);
00331                         } else {
00332                             USB20X.D0FIFOCTR = USB_FUNCTION_BITBCLR;
00333                             g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE;
00334                         }
00335                         break;
00336 
00337                     case USB_FUNCTION_D1FIFO_DMA:
00338                         if (g_usbx_function_DmaStatus[USB_FUNCTION_D1FIFO] != USB_FUNCTION_DMA_READY) {
00339                             /*now, DMA is not supported*/
00340                             usbx_function_dma_interrupt_d1fifo(int_sense);
00341                         }
00342 
00343                         if (RZA_IO_RegRead_16(
00344                                 &g_usbx_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) {
00345                             /*now, DMA is not supported*/
00346                             usbx_function_read_dma(pipe);
00347                             usbx_function_disable_brdy_int(pipe);
00348                         } else {
00349                             USB20X.D1FIFOCTR = USB_FUNCTION_BITBCLR;
00350                             g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE;
00351                         }
00352                         break;
00353 
00354                     default:
00355                         ep = (g_usbx_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT;
00356                         ep <<= 1;
00357                         if (RZA_IO_RegRead_16(
00358                                 &g_usbx_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0) {
00359                             /* read */
00360                             EPx_read_status = DEVDRV_USBF_PIPE_WAIT;
00361                             (object->*(epCallback[ep - 2])) ();
00362                             EPx_read_status = DEVDRV_USBF_PIPE_DONE;
00363                         } else {
00364                             /* write */
00365                             EPx_read_status = DEVDRV_USBF_PIPE_WAIT;
00366                             (object->*(epCallback[ep - 2 + 1])) ();
00367                             EPx_read_status = DEVDRV_USBF_PIPE_DONE;
00368                             usbx_function_write_buffer(pipe);
00369                         }
00370                 }
00371             }
00372         }
00373         /* Three dummy reads for clearing interrupt requests */
00374         dumy_sts = USB20X.BRDYSTS;
00375     }
00376 }
00377 
00378 
00379 /******************************************************************************
00380  * Function Name: usbx_function_NRDYInterruptPIPE0
00381  * Description  : Executes NRDY interrupt for pipe0.
00382  * Arguments    : uint16_t status       ; NRDYSTS Register Value
00383  *              : uint16_t intenb       ; NRDYENB Register Value
00384  * Return Value : none
00385  *****************************************************************************/
00386 extern "C" {
00387     void usbx_function_NRDYInterruptPIPE0(
00388         uint16_t status,
00389         uint16_t intenb,
00390         USBHAL *object,
00391         void (USBHAL::*EP0func)(void)
00392     )
00393     {
00394         volatile uint16_t dumy_sts;
00395 
00396         USB20X.NRDYSTS =
00397             (uint16_t)~g_usbx_function_bit_set[USB_FUNCTION_PIPE0];
00398 
00399         /* Three dummy reads for clearing interrupt requests */
00400         dumy_sts = USB20X.NRDYSTS;
00401     }
00402 }
00403 
00404 
00405 /******************************************************************************
00406  * Function Name: usbx_function_NRDYInterrupt
00407  * Description  : Executes NRDY interrupt exclude pipe0.
00408  * Arguments    : uint16_t status       ; NRDYSTS Register Value
00409  *              : uint16_t intenb       ; NRDYENB Register Value
00410  * Return Value : none
00411  *****************************************************************************/
00412 extern "C" {
00413     void usbx_function_NRDYInterrupt(
00414         uint16_t status,
00415         uint16_t intenb,
00416         USBHAL *object,
00417         bool (USBHAL::*epCallback[])(void)
00418     )
00419     {
00420         volatile uint16_t dumy_sts;
00421 
00422         /**************************************************************
00423          * Function Name: usbx_function_nrdy_int
00424          * Description  : Executes NRDY interrupt(USB_FUNCTION_PIPE1-9).
00425          *              : Checks NRDY interrupt cause by PID. When the cause if STALL,
00426          *              : regards the pipe state as STALL and ends the processing.
00427          *              : Then the cause is not STALL, increments the error count to
00428          *              : communicate again. When the error count is 3, determines
00429          *              : the pipe state as DEVDRV_USBF_PIPE_NORES and ends the processing.
00430          *              : This function is executed in the NRDY interrupt handler.
00431          *              : This function clears NRDY interrupt status.
00432          * Arguments    : uint16_t status       ; NRDYSTS Register Value
00433          *              : uint16_t int_enb      ; NRDYENB Register Value
00434          * Return Value : none
00435          *************************************************************/
00436         /* copied from usbx_function_intrn.c */
00437 #if 0
00438         uint16_t usefifo;
00439 #endif
00440         uint16_t pid;
00441         uint16_t pipe;
00442         uint16_t bitcheck;
00443 #if 0
00444         uint16_t mbw;
00445         uint32_t size;
00446 #endif
00447         uint16_t ep;
00448 
00449         bitcheck = (uint16_t)(status & intenb);
00450 
00451         USB20X.NRDYSTS = (uint16_t)~status;
00452 
00453 
00454         if (RZA_IO_RegRead_16(&USB20X.SYSCFG0, USB_SYSCFG_DCFM_SHIFT, USB_SYSCFG_DCFM) == 1) {
00455             /* USB HOST */
00456             /* not support */
00457 
00458         } else {
00459             /* USB Function */
00460             for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) {
00461                 if ((bitcheck&g_usbx_function_bit_set[pipe]) != g_usbx_function_bit_set[pipe]) {
00462                     continue;
00463                 }
00464 
00465                 if (g_usbx_function_pipe_status[pipe] != DEVDRV_USBF_PIPE_WAIT) {
00466                     continue;
00467                 }
00468 
00469 #if 0
00470                 usbx_function_set_pid_nak(pipe);
00471 
00472                 size = (uint32_t)g_usbx_function_data_count[pipe];
00473                 mbw = usbx_function_get_mbw(
00474                     size, (uint32_t)g_usbx_function_data_pointer[pipe]);
00475 
00476                 usefifo = (uint16_t)(g_usbx_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE);
00477                 switch (usefifo) {
00478 
00479                     case USB_FUNCTION_D0FIFO_USE:
00480                         usbx_function_set_curpipe(
00481                             pipe, USB_FUNCTION_D0USE, DEVDRV_USBF_NO, mbw);
00482                         USB20X.D0FIFOCTR = USB_FUNCTION_BITBCLR;
00483                         break;
00484 
00485                     case USB_FUNCTION_D1FIFO_USE:
00486                         usbx_function_set_curpipe(
00487                             pipe, USB_FUNCTION_D1USE, DEVDRV_USBF_NO, mbw);
00488                         USB20X.D1FIFOCTR = USB_FUNCTION_BITBCLR;
00489                         break;
00490 
00491                     default:
00492                         usbx_function_set_curpipe(
00493                             pipe, USB_FUNCTION_CUSE, USB_FUNCTION_CFIFO_READ, mbw);
00494                         USB20X.CFIFOCTR = USB_FUNCTION_BITBCLR;
00495                         break;
00496                 }
00497 
00498                 usbx_function_aclrm(pipe);
00499 
00500                 usbx_function_enable_nrdy_int(pipe);
00501                 usbx_function_enable_brdy_int(pipe);
00502 
00503                 usbx_function_set_pid_buf(pipe);
00504 #endif
00505 
00506                 pid = usbx_function_get_pid(pipe);
00507                 if ((pid == DEVDRV_USBF_PID_STALL) || (pid == DEVDRV_USBF_PID_STALL2)) {
00508                     g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_STALL;
00509                 } else {
00510                     usbx_function_set_pid_buf(pipe);
00511                 }
00512 
00513                 ep = (g_usbx_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT;
00514                 ep <<= 1;
00515                 if (RZA_IO_RegRead_16(
00516                         &g_usbx_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0) {
00517                     /* read */
00518                     __NOP();
00519                 } else {
00520                     /* write */
00521                     __NOP();
00522                 }
00523             }
00524         }
00525 
00526         /* Three dummy reads for clearing interrupt requests */
00527         dumy_sts = USB20X.NRDYSTS;
00528     }
00529 }
00530 
00531 /******************************************************************************
00532  * Function Name: usbx_function_BEMPInterruptPIPE0
00533  * Description  : Executes BEMP interrupt for pipe0.
00534  * Arguments    : uint16_t status       ; BEMPSTS Register Value
00535  *              : uint16_t intenb       ; BEMPENB Register Value
00536  * Return Value : none
00537  *****************************************************************************/
00538 extern "C" {
00539     void usbx_function_BEMPInterruptPIPE0(
00540         uint16_t status,
00541         uint16_t intenb,
00542         USBHAL *object,
00543         void (USBHAL::*EP0func)(void)
00544     )
00545     {
00546         volatile uint16_t dumy_sts;
00547 
00548         USB20X.BEMPSTS =
00549             (uint16_t)~g_usbx_function_bit_set[USB_FUNCTION_PIPE0];
00550         RZA_IO_RegWrite_16(
00551             &USB20X.CFIFOSEL, USB_FUNCTION_PIPE0,
00552             USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE);
00553 
00554         /*usbx_function_write_buffer_c(USB_FUNCTION_PIPE0);*/
00555         (object->*EP0func)();
00556 
00557         /* Three dummy reads for clearing interrupt requests */
00558         dumy_sts = USB20X.BEMPSTS;
00559     }
00560 }
00561 
00562 
00563 /******************************************************************************
00564  * Function Name: usbx_function_BEMPInterrupt
00565  * Description  : Executes BEMP interrupt exclude pipe0.
00566  * Arguments    : uint16_t status       ; BEMPSTS Register Value
00567  *              : uint16_t intenb       ; BEMPENB Register Value
00568  * Return Value : none
00569  *****************************************************************************/
00570 extern "C" {
00571     void usbx_function_BEMPInterrupt(
00572         uint16_t status,
00573         uint16_t intenb,
00574         USBHAL *object,
00575         bool (USBHAL::*epCallback[])(void)
00576     )
00577     {
00578         volatile uint16_t dumy_sts;
00579 
00580         /**************************************************************
00581          * Function Name: usbx_function_bemp_int
00582          * Description  : Executes BEMP interrupt(USB_FUNCTION_PIPE1-9).
00583          * Arguments    : uint16_t status       ; BEMPSTS Register Value
00584          *              : uint16_t intenb      ; BEMPENB Register Value
00585          * Return Value : none
00586          *************************************************************/
00587         /* copied from usbx_function_intrn.c */
00588         uint16_t pid;
00589         uint16_t pipe;
00590         uint16_t bitcheck;
00591         uint16_t inbuf;
00592         uint16_t ep;
00593 
00594         bitcheck = (uint16_t)(status & intenb);
00595 
00596         USB20X.BEMPSTS = (uint16_t)~status;
00597 
00598         for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) {
00599             if ((bitcheck&g_usbx_function_bit_set[pipe]) != g_usbx_function_bit_set[pipe]) {
00600                 continue;
00601             }
00602 
00603             pid = usbx_function_get_pid(pipe);
00604 
00605             if ((pid == DEVDRV_USBF_PID_STALL) ||
00606                 (pid == DEVDRV_USBF_PID_STALL2)) {
00607                 g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_STALL;
00608 
00609             } else {
00610                 inbuf = usbx_function_get_inbuf(pipe);
00611 
00612                 if (inbuf == 0) {
00613                     usbx_function_disable_bemp_int(pipe);
00614                     usbx_function_set_pid_nak(pipe);
00615                     g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE;
00616 
00617                     switch (g_usbx_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) {
00618                         case USB_FUNCTION_D0FIFO_DMA:
00619                             /*now, DMA is not supported*/
00620                             break;
00621 
00622                         case USB_FUNCTION_D1FIFO_DMA:
00623                             /*now, DMA is not supported*/
00624                             break;
00625 
00626                         default:
00627                             ep = (g_usbx_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT;
00628                             ep <<= 1;
00629                             if (RZA_IO_RegRead_16(
00630                                     &g_usbx_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0) {
00631                                 /* read */
00632                                 __NOP();
00633                             } else {
00634                                 /* write */
00635                                 EPx_read_status = DEVDRV_USBF_PIPE_WAIT;
00636                                 (object->*(epCallback[ep - 2 + 1])) ();
00637                                 EPx_read_status = DEVDRV_USBF_PIPE_DONE;
00638                             }
00639                     }
00640                 }
00641             }
00642         }
00643 
00644         /* Three dummy reads for clearing interrupt requests */
00645         dumy_sts = USB20X.BEMPSTS;
00646     }
00647 }
00648 
00649 /******************************************************************************
00650  * Function Name: EP2PIPE
00651  * Description  : Converts from endpoint to pipe
00652  * Arguments    : number of endpoint
00653  * Return Value : number of pipe
00654  *****************************************************************************/
00655 /*EP2PIPE converter is for pipe1, pipe3 and pipe6 only.*/
00656 #define EP2PIPE(endpoint)   ((uint32_t)usbx_function_EpToPipe(endpoint))
00657 
00658 
00659 /******************************************************************************
00660  * Function Name: usbx_function_save_request
00661  * Description  : Retains the USB request information in variables.
00662  * Arguments    : none
00663  * Return Value : none
00664  *****************************************************************************/
00665 #define  usbx_function_save_request()                       \
00666     {                                                       \
00667         uint16_t *bufO = &setup_buffer[0];                  \
00668                                                             \
00669         USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITVALID;  \
00670         /*data[0] <= bmRequest, data[1] <= bmRequestType */ \
00671         *bufO++ = USB20X.USBREQ;                            \
00672         /*data[2] data[3] <= wValue*/                       \
00673         *bufO++ = USB20X.USBVAL;                            \
00674         /*data[4] data[5] <= wIndex*/                       \
00675         *bufO++ = USB20X.USBINDX;                           \
00676         /*data[6] data[6] <= wIndex*/                       \
00677         *bufO++ = USB20X.USBLENG;                           \
00678     }
00679 
00680 
00681 /*************************************************************************/
00682 /*************************************************************************/
00683 /*************************************************************************/
00684 
00685 /*************************************************************************/
00686 /* constructor */
00687 USBHAL::USBHAL(void)
00688 {
00689     /* ---- P4_1 : P4_1 (USB0_EN for GR-PEACH) ---- */
00690     //usbx_en = new DigitalOut(P4_1, 1);
00691 
00692     /* some constants */
00693     int_id          = USBIX_IRQn;
00694     int_level       = ( 2 << 3 );
00695     clock_mode      = USBFCLOCK_X1_48MHZ;
00696 #if (USB_FUNCTION_HISPEED == 0)
00697     mode            = USB_FUNCTION_FULL_SPEED;
00698 #else
00699     mode            = USB_FUNCTION_HIGH_SPEED;
00700 #endif
00701     EP0_read_status = DEVDRV_USBF_WRITEEND;
00702     EPx_read_status = DEVDRV_USBF_PIPE_DONE;
00703 
00704     /* Disables interrupt for usb */
00705     GIC_DisableIRQ(int_id);
00706 
00707     /* Setup the end point */
00708     epCallback[ 0] = &USBHAL::EP1_OUT_callback;
00709     epCallback[ 1] = &USBHAL::EP1_IN_callback;
00710     epCallback[ 2] = &USBHAL::EP2_OUT_callback;
00711     epCallback[ 3] = &USBHAL::EP2_IN_callback;
00712     epCallback[ 4] = &USBHAL::EP3_OUT_callback;
00713     epCallback[ 5] = &USBHAL::EP3_IN_callback;
00714     epCallback[ 6] = &USBHAL::EP4_OUT_callback;
00715     epCallback[ 7] = &USBHAL::EP4_IN_callback;
00716     epCallback[ 8] = &USBHAL::EP5_OUT_callback;
00717     epCallback[ 9] = &USBHAL::EP5_IN_callback;
00718     epCallback[10] = &USBHAL::EP6_OUT_callback;
00719     epCallback[11] = &USBHAL::EP6_IN_callback;
00720     epCallback[12] = &USBHAL::EP7_OUT_callback;
00721     epCallback[13] = &USBHAL::EP7_IN_callback;
00722     epCallback[14] = &USBHAL::EP8_OUT_callback;
00723     epCallback[15] = &USBHAL::EP8_IN_callback;
00724     epCallback[16] = &USBHAL::EP9_OUT_callback;
00725     epCallback[17] = &USBHAL::EP9_IN_callback;
00726     epCallback[18] = &USBHAL::EP10_OUT_callback;
00727     epCallback[19] = &USBHAL::EP10_IN_callback;
00728     epCallback[20] = &USBHAL::EP11_OUT_callback;
00729     epCallback[21] = &USBHAL::EP11_IN_callback;
00730     epCallback[22] = &USBHAL::EP12_OUT_callback;
00731     epCallback[23] = &USBHAL::EP12_IN_callback;
00732     epCallback[24] = &USBHAL::EP13_OUT_callback;
00733     epCallback[25] = &USBHAL::EP13_IN_callback;
00734     epCallback[26] = &USBHAL::EP14_OUT_callback;
00735     epCallback[27] = &USBHAL::EP14_IN_callback;
00736     epCallback[28] = &USBHAL::EP15_OUT_callback;
00737     epCallback[29] = &USBHAL::EP15_IN_callback;
00738 
00739     /* registers me */
00740     instance = this;
00741 
00742     /* Clear pipe table */
00743     usbx_function_clear_pipe_tbl();
00744 
00745 /******************************************************************************
00746  * Function Name: usbx_api_function_init
00747  * Description  : Initializes the USB module in the USB function mode.
00748  *****************************************************************************/
00749     /* The clock of USB0 modules is permitted */
00750 #if (USB_FUNCTION_CH == 0)
00751     CPG.STBCR7 &= ~(CPG_STBCR7_MSTP71);
00752 #else
00753     CPG.STBCR7 &= ~(CPG_STBCR7_MSTP71 | CPG_STBCR7_MSTP70);
00754 #endif
00755     volatile uint8_t    dummy8;
00756     dummy8 = CPG.STBCR7;
00757 
00758     {
00759 /******************************************************************************
00760  * Function Name: usbx_function_setting_interrupt
00761  * Description  : Sets the USB module interrupt level.
00762  *****************************************************************************/
00763 #if 0   /*DMA is not supported*/
00764         IRQn_Type d0fifo_dmaintid;
00765         IRQn_Type d1fifo_dmaintid;
00766 #endif
00767 
00768         InterruptHandlerRegister(int_id, &_usbisr);
00769         GIC_SetPriority(int_id, int_level);
00770         GIC_EnableIRQ(int_id);
00771 
00772 #if 0   /*DMA is not supported*/
00773         d0fifo_dmaintid = Userdef_USB_usbx_function_d0fifo_dmaintid();
00774         if (d0fifo_dmaintid != 0xFFFF) {
00775             InterruptHandlerRegister(d0fifo_dmaintid, usbx_function_dma_interrupt_d0fifo);
00776             GIC_SetPriority(d0fifo_dmaintid, int_level);
00777             GIC_EnableIRQ(d0fifo_dmaintid);
00778         }
00779 #endif
00780 
00781 #if 0   /*DMA is not supported*/
00782         d1fifo_dmaintid = Userdef_USB_usbx_function_d1fifo_dmaintid();
00783         if (d1fifo_dmaintid != 0xFFFF) {
00784             InterruptHandlerRegister(d1fifo_dmaintid, usbx_function_dma_interrupt_d1fifo);
00785             GIC_SetPriority(d1fifo_dmaintid, int_level);
00786             GIC_EnableIRQ(d1fifo_dmaintid);
00787         }
00788 #endif
00789 /*****************************************************************************/
00790     }
00791 
00792     /* reset USB module with setting tranciever and HSE=1 */
00793     usbx_function_reset_module(clock_mode);
00794 
00795     /* clear variables */
00796     usbx_function_init_status();
00797 
00798     /* select USB Function and Interrupt Enable */
00799     /* Detect USB Device to attach or detach    */
00800     usbx_function_InitModule(mode);
00801 
00802     {
00803         uint16_t buf;
00804         buf  = USB20X.INTENB0;
00805         buf |= USB_INTENB0_SOFE;
00806         USB20X.INTENB0 = buf;
00807     }
00808 }
00809 
00810 /*************************************************************************/
00811 USBHAL::~USBHAL(void)
00812 {
00813     /* Disables interrupt for usb */
00814     GIC_DisableIRQ( int_id );
00815     /* Unregisters interrupt function and priority */
00816     InterruptHandlerRegister( int_id, (uint32_t)NULL );
00817 
00818     //usbx_en  = NULL;
00819     instance = NULL;
00820 }
00821 
00822 /*************************************************************************/
00823 void USBHAL::connect(void)
00824 {
00825     /* Activates USB0_EN */
00826     //(*usbx_en) = 0;
00827 }
00828 
00829 
00830 /*************************************************************************/
00831 void USBHAL::disconnect(void)
00832 {
00833     /* Deactivates USB0_EN */
00834     //(*usbx_en) = 1;
00835 }
00836 
00837 
00838 /*************************************************************************/
00839 void USBHAL::configureDevice(void)
00840 {
00841     /*The pipes set up in USBHAL::realiseEndpoint*/
00842     /*usbx_function_clear_alt();*/      /* Alternate setting clear */
00843     /*usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);*/
00844 }
00845 
00846 
00847 /*************************************************************************/
00848 void USBHAL::unconfigureDevice(void)
00849 {
00850     /* The Interface would be managed by USBDevice */
00851     /*usbx_function_clear_alt();*/      /* Alternate setting clear */
00852     /*usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);*/
00853 }
00854 
00855 
00856 /*************************************************************************/
00857 void USBHAL::setAddress(uint8_t address)
00858 {
00859     if (address <= 127) {
00860         usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);      /* OK */
00861     } else {
00862         usbx_function_set_pid_stall(USB_FUNCTION_PIPE0);    /* Not Spec */
00863     }
00864 }
00865 
00866 
00867 /*************************************************************************/
00868 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags)
00869 {
00870     const struct PIPECFGREC *cfg;
00871     uint16_t pipe;
00872     uint16_t buf;
00873 
00874     if ( (EP0OUT == endpoint) || (EP0IN  == endpoint) ) {
00875         return true;
00876     }
00877 
00878     for (cfg = &def_pipecfg[0]; cfg->pipesel != 0; cfg++) {
00879         if (cfg->endpoint == endpoint) {
00880             break;
00881         }
00882     }
00883     if (cfg->pipesel == 0) {
00884         return false;
00885     }
00886 
00887     pipe = ((cfg->pipesel & USB_PIPESEL_PIPESEL) >> USB_PIPESEL_PIPESEL_SHIFT);
00888 
00889     g_usbx_function_PipeTbl[ pipe ] = (uint16_t)(endpoint | ((cfg->pipesel & USB_FUNCTION_FIFO_USE) << 0));
00890 
00891     /* There are maintenance routine of SHTNAK and BFRE bits
00892      * in original sample program. This sample is not
00893      * programmed. Do maintenance the "def_pipecfg" array if
00894      * you want it. */
00895 
00896     /* Interrupt Disable */
00897     buf  = USB20X.BRDYENB;
00898     buf &= (uint16_t)~g_usbx_function_bit_set[pipe];
00899     USB20X.BRDYENB = buf;
00900     buf  = USB20X.NRDYENB;
00901     buf &= (uint16_t)~g_usbx_function_bit_set[pipe];
00902     USB20X.NRDYENB = buf;
00903     buf  = USB20X.BEMPENB;
00904     buf &= (uint16_t)~g_usbx_function_bit_set[pipe];
00905     USB20X.BEMPENB = buf;
00906 
00907     usbx_function_set_pid_nak(pipe);
00908 
00909     /* CurrentPIPE Clear */
00910     if (RZA_IO_RegRead_16(&USB20X.CFIFOSEL, USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE) == pipe) {
00911         RZA_IO_RegWrite_16(&USB20X.CFIFOSEL, 0, USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE);
00912     }
00913 
00914     if (RZA_IO_RegRead_16(&USB20X.D0FIFOSEL, USB_DnFIFOSEL_CURPIPE_SHIFT, USB_DnFIFOSEL_CURPIPE) == pipe) {
00915         RZA_IO_RegWrite_16(&USB20X.D0FIFOSEL, 0, USB_DnFIFOSEL_CURPIPE_SHIFT, USB_DnFIFOSEL_CURPIPE);
00916     }
00917 
00918     if (RZA_IO_RegRead_16(&USB20X.D1FIFOSEL, USB_DnFIFOSEL_CURPIPE_SHIFT, USB_DnFIFOSEL_CURPIPE) == pipe) {
00919         RZA_IO_RegWrite_16(&USB20X.D1FIFOSEL, 0, USB_DnFIFOSEL_CURPIPE_SHIFT, USB_DnFIFOSEL_CURPIPE);
00920     }
00921 
00922     /* PIPE Configuration */
00923     USB20X.PIPESEL  = pipe;
00924     USB20X.PIPECFG  = cfg->pipecfg;
00925     USB20X.PIPEBUF  = cfg->pipebuf;
00926     USB20X.PIPEMAXP = cfg->pipemaxp;
00927     USB20X.PIPEPERI = cfg->pipeperi;
00928 
00929     g_usbx_function_pipecfg[pipe]  = cfg->pipecfg;
00930     g_usbx_function_pipebuf[pipe]  = cfg->pipebuf;
00931     g_usbx_function_pipemaxp[pipe] = cfg->pipemaxp;
00932     g_usbx_function_pipeperi[pipe] = cfg->pipeperi;
00933 
00934     /* Buffer Clear */
00935     usbx_function_set_sqclr(pipe);
00936     usbx_function_aclrm(pipe);
00937 
00938     /* init Global */
00939     g_usbx_function_pipe_status[pipe]  = DEVDRV_USBF_PIPE_IDLE;
00940     g_usbx_function_PipeDataSize[pipe] = 0;
00941 
00942     return true;
00943 }
00944 
00945 
00946 /*************************************************************************/
00947 // read setup packet
00948 void USBHAL::EP0setup(uint8_t *buffer)
00949 {
00950     memcpy(buffer, setup_buffer, MAX_PACKET_SIZE_EP0);
00951 }
00952 
00953 
00954 /*************************************************************************/
00955 void USBHAL::EP0readStage(void)
00956 {
00957     // No implements
00958 }
00959 
00960 
00961 /*************************************************************************/
00962 void USBHAL::EP0read(void)
00963 {
00964     uint8_t *buffer;
00965     uint32_t size;
00966 
00967     /* remain of last writing */
00968     while (EP0_read_status != DEVDRV_USBF_WRITEEND) {
00969         static uint8_t bbb[2] = { 255, 255 };
00970         EP0write(&bbb[0], 0);
00971     }
00972 
00973     buffer = (uint8_t*)(&setup_buffer[4]);
00974     size   = (MAX_PACKET_SIZE_EP0 / 2) - 8;
00975     usbx_api_function_CtrlWriteStart(size, buffer);
00976 }
00977 
00978 
00979 /*************************************************************************/
00980 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer)
00981 {
00982     memcpy(buffer, (uint8_t*)(&setup_buffer[4]), g_usbx_function_PipeDataSize[USB_FUNCTION_PIPE0]);
00983 
00984     return g_usbx_function_PipeDataSize[USB_FUNCTION_PIPE0];
00985 }
00986 
00987 
00988 /*************************************************************************/
00989 void USBHAL::EP0write(uint8_t *buffer, uint32_t size)
00990 {
00991     /* zero byte writing */
00992     if ( (size == 0) && (EP0_read_status == DEVDRV_USBF_WRITEEND) ) {
00993         return;
00994     }
00995 
00996     if (EP0_read_status == DEVDRV_USBF_WRITEEND) {
00997         /*1st block*/
00998         EP0_read_status = usbx_api_function_CtrlReadStart(size, buffer);
00999     } else {
01000         /* waits the last transmission */
01001         /*other blocks*/
01002         g_usbx_function_data_count[ USB_FUNCTION_PIPE0 ]    = size;
01003         g_usbx_function_data_pointer [ USB_FUNCTION_PIPE0 ] = buffer;
01004         EP0_read_status = usbx_function_write_buffer_c(USB_FUNCTION_PIPE0);
01005     }
01006     /*max size may be deblocking outside*/
01007     if (size == MAX_PACKET_SIZE_EP0) {
01008         EP0_read_status = DEVDRV_USBF_WRITING;
01009     }
01010 }
01011 
01012 
01013 /*************************************************************************/
01014 #if 0   // No implements
01015 void USBHAL::EP0getWriteResult(void)
01016 {
01017 }
01018 #endif
01019 
01020 /*************************************************************************/
01021 void USBHAL::EP0stall(void)
01022 {
01023     stallEndpoint( 0 );
01024 }
01025 
01026 
01027 /*************************************************************************/
01028 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t max_size)
01029 {
01030     uint32_t    pipe = EP2PIPE(endpoint);
01031     uint32_t    pipe_size;
01032     uint16_t    pipe_status;
01033     EP_STATUS status = EP_COMPLETED;
01034 
01035     pipe_status = usbx_api_function_check_pipe_status(pipe, &pipe_size);
01036 
01037     switch (pipe_status) {
01038         case DEVDRV_USBF_PIPE_IDLE:
01039         case DEVDRV_USBF_PIPE_WAIT:
01040             usbx_api_function_set_pid_nak(pipe);
01041             usbx_api_function_clear_pipe_status(pipe);
01042 
01043             usbx_api_function_start_receive_transfer(pipe, max_size, recv_buffer);
01044             break;
01045 
01046         default:
01047             status = EP_PENDING;
01048             break;
01049     }
01050 
01051     return status;
01052 }
01053 
01054 
01055 /*************************************************************************/
01056 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t *buffer, uint32_t *bytes_read )
01057 {
01058     uint32_t pipe = EP2PIPE(endpoint);
01059     uint16_t pipe_status;
01060     uint16_t err;
01061     EP_STATUS status = EP_PENDING;
01062 
01063 
01064     if (EPx_read_status != DEVDRV_USBF_PIPE_WAIT) {
01065         return status;
01066     }
01067 
01068     pipe_status = usbx_api_function_check_pipe_status(pipe, bytes_read);
01069     switch (pipe_status) {
01070         case DEVDRV_USBF_PIPE_IDLE:
01071             return EP_COMPLETED;
01072 
01073         case DEVDRV_USBF_PIPE_DONE:
01074             return EP_COMPLETED;
01075 
01076         case DEVDRV_USBF_PIPE_WAIT:
01077             break;
01078 
01079         default:
01080             return status;
01081     }
01082 
01083     /* sets the output buffer and size */
01084     g_usbx_function_data_pointer[pipe] = buffer;
01085 
01086     /* receives data from pipe */
01087     err = usbx_function_read_buffer(pipe);
01088     recv_error = err;
01089     switch (err) {
01090         case USB_FUNCTION_READEND:
01091         case USB_FUNCTION_READSHRT:
01092         case USB_FUNCTION_READOVER:
01093             *bytes_read = g_usbx_function_PipeDataSize[pipe];
01094             break;
01095 
01096         case USB_FUNCTION_READING:
01097         case DEVDRV_USBF_FIFOERROR:
01098             break;
01099     }
01100 
01101     pipe_status = usbx_api_function_check_pipe_status(pipe, bytes_read);
01102     switch (pipe_status) {
01103         case DEVDRV_USBF_PIPE_DONE:
01104             status = EP_COMPLETED;
01105             break;
01106 
01107         case DEVDRV_USBF_PIPE_IDLE:
01108         case DEVDRV_USBF_PIPE_NORES:
01109         case DEVDRV_USBF_PIPE_STALL:
01110         case DEVDRV_USBF_FIFOERROR:
01111         default:
01112             break;
01113     }
01114 
01115     return status;
01116 }
01117 
01118 
01119 /*************************************************************************/
01120 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
01121 {
01122     uint32_t pipe = EP2PIPE(endpoint);
01123     uint32_t pipe_size;
01124     uint16_t pipe_status;
01125     uint16_t err;
01126     uint16_t count;
01127     EP_STATUS status = EP_PENDING;
01128 
01129     pipe_status = usbx_api_function_check_pipe_status(pipe, &pipe_size);
01130 
01131     /* waits the last transmission */
01132     count = 30000;
01133     while ((pipe_status == DEVDRV_USBF_PIPE_WAIT) || (pipe_status == DEVDRV_USBF_PIPE_DONE)) {
01134         pipe_status = usbx_api_function_check_pipe_status(pipe, &pipe_size);
01135         if( --count == 0 ) {
01136             pipe_status = DEVDRV_USBF_PIPE_STALL;
01137             break;
01138         }
01139     }
01140 
01141     switch (pipe_status) {
01142         case DEVDRV_USBF_PIPE_IDLE:
01143             err = usbx_api_function_start_send_transfer(pipe, size, data);
01144 
01145             switch (err) {
01146                     /* finish to write */
01147                 case DEVDRV_USBF_WRITEEND:
01148                     /* finish to write, but data is short */
01149                 case DEVDRV_USBF_WRITESHRT:
01150                     /* continue to write */
01151                 case DEVDRV_USBF_WRITING:
01152                     /* use DMA */
01153                 case DEVDRV_USBF_WRITEDMA:
01154                     /* error */
01155                 case DEVDRV_USBF_FIFOERROR:
01156                     status = EP_PENDING;
01157                     break;
01158             }
01159             break;
01160 
01161         case DEVDRV_USBF_PIPE_WAIT:
01162         case DEVDRV_USBF_PIPE_DONE:
01163             status = EP_PENDING;
01164             break;
01165 
01166         case DEVDRV_USBF_PIPE_NORES:
01167         case DEVDRV_USBF_PIPE_STALL:
01168         default:
01169             status = EP_STALLED;
01170             break;
01171     }
01172 
01173     return status;
01174 }
01175 
01176 
01177 /*************************************************************************/
01178 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint)
01179 {
01180     uint32_t    pipe = EP2PIPE(endpoint);
01181     uint32_t    pipe_size;
01182     uint16_t    pipe_status;
01183     EP_STATUS status = EP_PENDING;
01184 
01185     pipe_status = usbx_api_function_check_pipe_status(pipe, &pipe_size);
01186 
01187     switch (pipe_status) {
01188         case DEVDRV_USBF_PIPE_IDLE:
01189             status = EP_COMPLETED;
01190             break;
01191 
01192         case DEVDRV_USBF_PIPE_WAIT:
01193             status = EP_PENDING;
01194             break;
01195 
01196         case DEVDRV_USBF_PIPE_DONE:
01197             usbx_function_stop_transfer(pipe);
01198             status = EP_COMPLETED;
01199             break;
01200 
01201         case DEVDRV_USBF_PIPE_NORES:
01202             status = EP_STALLED;
01203             break;
01204 
01205         case DEVDRV_USBF_PIPE_STALL:
01206             status = EP_STALLED;
01207             break;
01208 
01209         default:
01210             status = EP_PENDING;
01211     }
01212 
01213     return status;
01214 }
01215 
01216 
01217 /*************************************************************************/
01218 void USBHAL::stallEndpoint(uint8_t endpoint)
01219 {
01220     uint32_t pipe = EP2PIPE(endpoint);
01221 
01222     usbx_function_clear_pid_stall(pipe);
01223 }
01224 
01225 
01226 /*************************************************************************/
01227 void USBHAL::unstallEndpoint(uint8_t endpoint)
01228 {
01229     uint32_t pipe = EP2PIPE(endpoint);
01230 
01231     usbx_function_set_pid_stall( pipe );
01232 }
01233 
01234 
01235 /*************************************************************************/
01236 bool USBHAL::getEndpointStallState(uint8_t endpoint)
01237 {
01238     // No implemens
01239     return false;
01240 }
01241 
01242 
01243 /*************************************************************************/
01244 #if 0   // No implements
01245 void USBHAL::remoteWakeup(void)
01246 {
01247 }
01248 #endif
01249 
01250 /*************************************************************************/
01251 void USBHAL::_usbisr(void)
01252 {
01253     instance->usbisr();
01254 }
01255 
01256 
01257 /*************************************************************************/
01258 void USBHAL::usbisr(void)
01259 {
01260     uint16_t            int_sts0;
01261     uint16_t            int_sts1;
01262     uint16_t            int_sts2;
01263     uint16_t            int_sts3;
01264     uint16_t            int_enb0;
01265     uint16_t            int_enb2;
01266     uint16_t            int_enb3;
01267     uint16_t            int_enb4;
01268     volatile uint16_t   dumy_sts;
01269 
01270 
01271     int_sts0 = USB20X.INTSTS0;
01272 
01273     if (!(int_sts0 & (
01274                 USB_FUNCTION_BITVBINT |
01275                 USB_FUNCTION_BITRESM  |
01276                 USB_FUNCTION_BITSOFR  |
01277                 USB_FUNCTION_BITDVST  |
01278                 USB_FUNCTION_BITCTRT  |
01279                 USB_FUNCTION_BITBEMP  |
01280                 USB_FUNCTION_BITNRDY  |
01281                 USB_FUNCTION_BITBRDY ))) {
01282         return;
01283     }
01284 
01285     int_sts1 = USB20X.BRDYSTS;
01286     int_sts2 = USB20X.NRDYSTS;
01287     int_sts3 = USB20X.BEMPSTS;
01288     int_enb0 = USB20X.INTENB0;
01289     int_enb2 = USB20X.BRDYENB;
01290     int_enb3 = USB20X.NRDYENB;
01291     int_enb4 = USB20X.BEMPENB;
01292 
01293     if ((int_sts0 & USB_FUNCTION_BITRESM) &&
01294             (int_enb0 & USB_FUNCTION_BITRSME)) {
01295         USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITRESM;
01296         RZA_IO_RegWrite_16(&USB20X.INTENB0, 0, USB_INTENB0_RSME_SHIFT, USB_INTENB0_RSME);
01297         /*usbx_function_USB_FUNCTION_Resume();*/
01298         suspendStateChanged(1);
01299     } else if (
01300         (int_sts0 & USB_FUNCTION_BITVBINT) &&
01301         (int_enb0 & USB_FUNCTION_BITVBSE)) {
01302         USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITVBINT;
01303 
01304         if (usbx_function_CheckVBUStaus() == DEVDRV_USBF_ON) {
01305             usbx_function_USB_FUNCTION_Attach();
01306         } else {
01307             usbx_function_USB_FUNCTION_Detach();
01308         }
01309     } else if (
01310         (int_sts0 & USB_FUNCTION_BITSOFR) &&
01311         (int_enb0 & USB_FUNCTION_BITSOFE)) {
01312         USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITSOFR;
01313         SOF((USB20X.FRMNUM & USB_FRMNUM_FRNM) >> USB_FRMNUM_FRNM_SHIFT);
01314     } else if (
01315         (int_sts0 & USB_FUNCTION_BITDVST) &&
01316         (int_enb0 & USB_FUNCTION_BITDVSE)) {
01317         USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITDVST;
01318         switch (int_sts0 & USB_FUNCTION_BITDVSQ) {
01319             case USB_FUNCTION_DS_POWR:
01320                 break;
01321 
01322             case USB_FUNCTION_DS_DFLT:
01323                 /*****************************************************************************
01324                  * Function Name: usbx_function_USB_FUNCTION_BusReset
01325                  * Description  : This function is executed when the USB device is transitioned
01326                  *              : to POWERD_STATE. Sets the device descriptor according to the
01327                  *              : connection speed determined by the USB reset hand shake.
01328                  * Arguments    : none
01329                  * Return Value : none
01330                  *****************************************************************************/
01331                 usbx_function_init_status();            /* memory clear */
01332 
01333 #if 0
01334                 /* You would program those steps in USBCallback_busReset
01335                  * if the system need the comment out steps.
01336                  */
01337 
01338                 if (usbx_function_is_hispeed() == USB_FUNCTION_HIGH_SPEED) {
01339                     /* Device Descriptor reset */
01340                     usbx_function_ResetDescriptor(USB_FUNCTION_HIGH_SPEED);
01341                 } else {
01342                     /* Device Descriptor reset */
01343                     usbx_function_ResetDescriptor(USB_FUNCTION_FULL_SPEED);
01344                 }
01345 #endif
01346                 /* Default Control PIPE reset */
01347                 /*****************************************************************************
01348                  * Function Name: usbx_function_ResetDCP
01349                  * Description  : Initializes the default control pipe(DCP).
01350                  * Outline      : Reset default control pipe
01351                  * Arguments    : none
01352                  * Return Value : none
01353                  *****************************************************************************/
01354                 USB20X.DCPCFG  = 0;
01355                 USB20X.DCPMAXP = 64;    /*TODO: This value is copied from sample*/
01356 
01357                 USB20X.CFIFOSEL  = (uint16_t)(USB_FUNCTION_BITMBW_8 | USB_FUNCTION_BITBYTE_LITTLE);
01358                 USB20X.D0FIFOSEL = (uint16_t)(USB_FUNCTION_BITMBW_8 | USB_FUNCTION_BITBYTE_LITTLE);
01359                 USB20X.D1FIFOSEL = (uint16_t)(USB_FUNCTION_BITMBW_8 | USB_FUNCTION_BITBYTE_LITTLE);
01360 
01361                 busReset();
01362                 break;
01363 
01364             case USB_FUNCTION_DS_ADDS:
01365                 break;
01366 
01367             case USB_FUNCTION_DS_CNFG:
01368                 break;
01369 
01370             case USB_FUNCTION_DS_SPD_POWR:
01371             case USB_FUNCTION_DS_SPD_DFLT:
01372             case USB_FUNCTION_DS_SPD_ADDR:
01373             case USB_FUNCTION_DS_SPD_CNFG:
01374                 suspendStateChanged(0);
01375                 /*usbx_function_USB_FUNCTION_Suspend();*/
01376                 break;
01377 
01378             default:
01379                 break;
01380         }
01381     } else if (
01382         (int_sts0 & USB_FUNCTION_BITBEMP) &&
01383         (int_enb0 & USB_FUNCTION_BITBEMP) &&
01384         ((int_sts3 & int_enb4) & g_usbx_function_bit_set[USB_FUNCTION_PIPE0])) {
01385         /* ==== BEMP PIPE0 ==== */
01386         usbx_function_BEMPInterruptPIPE0(int_sts3, int_enb4, this, &USBHAL::EP0in);
01387     } else if (
01388         (int_sts0 & USB_FUNCTION_BITBRDY) &&
01389         (int_enb0 & USB_FUNCTION_BITBRDY) &&
01390         ((int_sts1 & int_enb2) & g_usbx_function_bit_set[USB_FUNCTION_PIPE0])) {
01391         /* ==== BRDY PIPE0 ==== */
01392         usbx_function_BRDYInterruptPIPE0(int_sts1, int_enb2, this, &USBHAL::EP0out);
01393     } else if (
01394         (int_sts0 & USB_FUNCTION_BITNRDY) &&
01395         (int_enb0 & USB_FUNCTION_BITNRDY) &&
01396         ((int_sts2 & int_enb3) & g_usbx_function_bit_set[USB_FUNCTION_PIPE0])) {
01397         /* ==== NRDY PIPE0 ==== */
01398         usbx_function_NRDYInterruptPIPE0(int_sts2, int_enb3, this, NULL);
01399     } else if (
01400         (int_sts0 & USB_FUNCTION_BITCTRT) && (int_enb0 & USB_FUNCTION_BITCTRE)) {
01401         int_sts0 = USB20X.INTSTS0;
01402         USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITCTRT;
01403 
01404         if (((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_RDDS) ||
01405                 ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_WRDS) ||
01406                 ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_WRND)) {
01407 
01408             /* remake EP0 into buffer */
01409             usbx_function_save_request();
01410             if ((USB20X.INTSTS0 & USB_FUNCTION_BITVALID) && (
01411                         ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_RDDS) ||
01412                         ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_WRDS) ||
01413                         ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_WRND))) {
01414                 /* New SETUP token received */
01415                 /* Three dummy reads for cleearing interrupt requests */
01416                 dumy_sts = USB20X.INTSTS0;
01417                 dumy_sts = USB20X.INTSTS0;
01418                 dumy_sts = USB20X.INTSTS0;
01419                 return;
01420             }
01421         }
01422 
01423         switch (int_sts0 & USB_FUNCTION_BITCTSQ) {
01424             case USB_FUNCTION_CS_IDST:
01425                 if (g_usbx_function_TestModeFlag == DEVDRV_USBF_YES) {
01426                     /* ==== Test Mode ==== */
01427                     usbx_function_USB_FUNCTION_TestMode();
01428                 }
01429                 /* Needs not procedure in this state */
01430                 break;
01431 
01432             case USB_FUNCTION_CS_RDDS:
01433                 /* Reads a setup packet */
01434                 EP0setupCallback();
01435                 break;
01436 
01437             case USB_FUNCTION_CS_WRDS:
01438                 /* Original code was the SetDescriptor was called */
01439                 EP0setupCallback();
01440                 break;
01441 
01442             case USB_FUNCTION_CS_WRND:
01443                 EP0setupCallback();
01444 
01445                 /*The EP0setupCallback should finish in successful */
01446                 usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);
01447 
01448                 RZA_IO_RegWrite_16(&USB20X.DCPCTR, 1, USB_DCPCTR_CCPL_SHIFT, USB_DCPCTR_CCPL);
01449                 break;
01450 
01451             case USB_FUNCTION_CS_RDSS:
01452                 RZA_IO_RegWrite_16(&USB20X.DCPCTR, 1, USB_DCPCTR_CCPL_SHIFT, USB_DCPCTR_CCPL);
01453                 break;
01454 
01455             case USB_FUNCTION_CS_WRSS:
01456                 RZA_IO_RegWrite_16(&USB20X.DCPCTR, 1, USB_DCPCTR_CCPL_SHIFT, USB_DCPCTR_CCPL);
01457                 break;
01458 
01459             case USB_FUNCTION_CS_SQER:
01460                 usbx_function_set_pid_stall(USB_FUNCTION_PIPE0);
01461                 break;
01462 
01463             default:
01464                 usbx_function_set_pid_stall(USB_FUNCTION_PIPE0);
01465                 break;
01466         }
01467     } else if (
01468         (int_sts0 & USB_FUNCTION_BITBEMP) &&
01469         (int_enb0 & USB_FUNCTION_BITBEMP) &&
01470         (int_sts3 & int_enb4) ) {
01471         /* ==== BEMP PIPEx ==== */
01472         usbx_function_BEMPInterrupt(int_sts3, int_enb4, this, epCallback);
01473     } else if (
01474         (int_sts0 & USB_FUNCTION_BITBRDY) &&
01475         (int_enb0 & USB_FUNCTION_BITBRDY) &&
01476         (int_sts1 & int_enb2) ) {
01477         /* ==== BRDY PIPEx ==== */
01478         usbx_function_BRDYInterrupt(int_sts1, int_enb2, this, epCallback);
01479     } else if (
01480         (int_sts0 & USB_FUNCTION_BITNRDY) &&
01481         (int_enb0 & USB_FUNCTION_BITNRDY) &&
01482         (int_sts2 & int_enb3)) {
01483         /* ==== NRDY PIPEx ==== */
01484         usbx_function_NRDYInterrupt(int_sts2, int_enb3, this, epCallback);
01485     } else {
01486         /* Do Nothing */
01487     }
01488 
01489     /* Three dummy reads for cleearing interrupt requests */
01490     dumy_sts = USB20X.INTSTS0;
01491     dumy_sts = USB20X.INTSTS1;
01492 }
01493 
01494 /*************************************************************************/
01495 #endif
01496 /*************************************************************************/
01497 /*EOF*/