]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/USBDevice/USBDevice/USBHAL_RZ_A1H.cpp
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / USBDevice / USBDevice / USBHAL_RZ_A1H.cpp
1 /* Copyright (c) 2010-2011 mbed.org, MIT License
2 *
3 * Permission is hereby granted, free of charge, to any person
4 * obtaining a copy of this software and associated documentation
5 * files (the "Software"), to deal in the Software without
6 * restriction, including without limitation the rights to use,
7 * copy, modify, merge, publish, distribute, sublicense, and/or
8 * sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following
10 * conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17 * KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
19 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 #if defined(TARGET_RZ_A1H)
27
28 /*
29   This class can use the pipe1, pipe3 and pipe6 only. You should
30   re-program this class if you wanted to use other pipe.
31  */
32
33 /*************************************************************************/
34 extern "C"
35 {
36 #include "r_typedefs.h"
37 #include "iodefine.h"
38 }
39 #include "USBHAL.h"
40 #include "devdrv_usb_function_api.h"
41 #include "usb_iobitmask.h"
42 #include "rza_io_regrw.h"
43 #include "USBDevice_Types.h"
44 #include "usb_function_setting.h"
45
46
47 /*************************************************************************/
48 /* constants */
49 const struct PIPECFGREC {
50     uint16_t    endpoint;
51     uint16_t    pipesel;
52     uint16_t    pipecfg;
53     uint16_t    pipebuf;
54     uint16_t    pipemaxp;
55     uint16_t    pipeperi;
56 } def_pipecfg[] = {
57     /*EP0OUT and EP0IN are configured by USB IP*/
58     {
59         EP1OUT, /*EP1: Host -> Func, INT*/
60         6 | USB_FUNCTION_D0FIFO_USE,
61         USB_FUNCTION_INTERRUPT |
62         USB_FUNCTION_BFREOFF   |
63         USB_FUNCTION_DBLBOFF   |
64         USB_FUNCTION_CNTMDON   |
65         USB_FUNCTION_SHTNAKOFF |
66         USB_FUNCTION_DIR_P_OUT |
67         USB_FUNCTION_EP1,
68         ( ( (  64) / 64 - 1 ) << 10 ) | 0x04u,
69         MAX_PACKET_SIZE_EP1,
70         DEVDRV_USBF_OFF |
71         ( 3 << USB_PIPEPERI_IITV_SHIFT ),
72     },
73     {
74         EP1IN,  /*EP1: Host <- Func, INT*/
75         7 | USB_FUNCTION_D1FIFO_USE,
76         USB_FUNCTION_INTERRUPT |
77         USB_FUNCTION_BFREOFF   |
78         USB_FUNCTION_DBLBOFF   |
79         USB_FUNCTION_CNTMDOFF  |
80         USB_FUNCTION_SHTNAKOFF |
81         USB_FUNCTION_DIR_P_IN  |
82         USB_FUNCTION_EP1,
83         ( ( (  64) / 64 - 1 ) << 10 ) | 0x05u,
84         MAX_PACKET_SIZE_EP1,
85         DEVDRV_USBF_OFF |
86         ( 3 << USB_PIPEPERI_IITV_SHIFT ),
87     },
88     {
89         EP2OUT, /*EP2: Host -> Func, BULK*/
90         3 | USB_FUNCTION_D0FIFO_USE,
91         USB_FUNCTION_BULK      |
92         USB_FUNCTION_BFREOFF   |
93         USB_FUNCTION_DBLBON    |
94         USB_FUNCTION_CNTMDON   |
95         USB_FUNCTION_SHTNAKON  |
96         USB_FUNCTION_DIR_P_OUT |
97         USB_FUNCTION_EP2,
98         ( ( (2048) / 64 - 1 ) << 10 ) | 0x30u,
99         MAX_PACKET_SIZE_EP2,
100         DEVDRV_USBF_OFF |
101         ( 0 << USB_PIPEPERI_IITV_SHIFT ),
102     },
103     {
104         EP2IN,  /*EP2: Host <- Func, BULK*/
105         4 | USB_FUNCTION_D1FIFO_USE,
106         USB_FUNCTION_BULK      |
107         USB_FUNCTION_BFREOFF   |
108         USB_FUNCTION_DBLBOFF   |
109         USB_FUNCTION_CNTMDON   |
110         USB_FUNCTION_SHTNAKOFF |
111         USB_FUNCTION_DIR_P_IN  |
112         USB_FUNCTION_EP2,
113         ( ( (2048) / 64 - 1 ) << 10 ) | 0x50u,
114         MAX_PACKET_SIZE_EP2,
115         DEVDRV_USBF_OFF |
116         ( 0 << USB_PIPEPERI_IITV_SHIFT ),
117     },
118     {
119         EP3OUT, /*EP3: Host -> Func, ISO*/
120         1 | USB_FUNCTION_D0FIFO_USE,
121         USB_FUNCTION_ISO       |
122         USB_FUNCTION_BFREOFF   |
123         USB_FUNCTION_DBLBON    |
124         USB_FUNCTION_CNTMDOFF  |
125         USB_FUNCTION_SHTNAKON  |
126         USB_FUNCTION_DIR_P_OUT |
127         USB_FUNCTION_EP3,
128         ( ( ( 512) / 64 - 1 ) << 10 ) | 0x10u,
129         MAX_PACKET_SIZE_EP3,
130         DEVDRV_USBF_OFF |
131         ( 0 << USB_PIPEPERI_IITV_SHIFT ),
132     },
133     {
134         EP3IN,  /*EP3: Host <- Func, ISO*/
135         2 | USB_FUNCTION_D1FIFO_USE,
136         USB_FUNCTION_ISO       |
137         USB_FUNCTION_BFREOFF   |
138         USB_FUNCTION_DBLBON    |
139         USB_FUNCTION_CNTMDOFF  |
140         USB_FUNCTION_SHTNAKOFF |
141         USB_FUNCTION_DIR_P_IN  |
142         USB_FUNCTION_EP3,
143         ( ( ( 512) / 64 - 1 ) << 10 ) | 0x20u,
144         MAX_PACKET_SIZE_EP3,
145         DEVDRV_USBF_OFF |
146         ( 0 << USB_PIPEPERI_IITV_SHIFT ),
147     },
148     { /*terminator*/
149         0, 0, 0, 0, 0,
150     },
151 };
152
153
154 /*************************************************************************/
155 /* workareas */
156 USBHAL * USBHAL::instance;
157
158 static IRQn_Type    int_id;         /* interrupt ID          */
159 static uint16_t     int_level;      /* initerrupt level      */
160 static uint16_t     clock_mode;     /* input clock selector  */
161 static uint16_t     mode;           /* USB speed (HIGH/FULL) */
162
163 //static DigitalOut *usbx_en;
164
165 static uint16_t     EP0_read_status;
166 static uint16_t     EPx_read_status;
167
168 static uint16_t setup_buffer[MAX_PACKET_SIZE_EP0 / 2];
169
170 /* 0: not used / other: a pipe number to use recv_buffer*/
171 static uint8_t  recv_buffer[MAX_PACKET_SIZE_EPBULK];
172 volatile static uint16_t    recv_error;
173
174
175 /*************************************************************************/
176 /* prototypes for C */
177 extern "C" {
178     void usbx_function_BRDYInterruptPIPE0 (uint16_t status, uint16_t intenb,
179         USBHAL *object, void (USBHAL::*EP0func)(void));
180
181     void usbx_function_BRDYInterrupt (uint16_t status, uint16_t intenb,
182         USBHAL *object, bool (USBHAL::*epCallback[])(void));
183
184     void usbx_function_NRDYInterruptPIPE0(uint16_t status, uint16_t intenb,
185         USBHAL *object, void (USBHAL::*EP0func)(void));
186
187     void usbx_function_NRDYInterrupt (uint16_t status, uint16_t intenb,
188         USBHAL *object, bool (USBHAL::*epCallback[])(void));
189
190     void usbx_function_BEMPInterruptPIPE0(uint16_t status, uint16_t intenb,
191         USBHAL *object, void (USBHAL::*EP0func)(void));
192
193     void usbx_function_BEMPInterrupt (uint16_t status, uint16_t intenb,
194         USBHAL *object, bool (USBHAL::*epCallback[])(void));
195 }
196
197
198 /*************************************************************************/
199 /* macros */
200
201 /******************************************************************************
202  * Function Name: usbx_function_BRDYInterruptPIPE0
203  * Description  : Executes BRDY interrupt for pipe0.
204  * Arguments    : uint16_t status       ; BRDYSTS Register Value
205  *              : uint16_t intenb       ; BRDYENB Register Value
206  * Return Value : none
207  *****************************************************************************/
208 extern "C" {
209     void usbx_function_BRDYInterruptPIPE0 (
210         uint16_t status,
211         uint16_t intenb,
212         USBHAL *object,
213         void (USBHAL::*EP0func)(void)
214     )
215     {
216         volatile uint16_t dumy_sts;
217         uint16_t read_status;
218
219         USB20X.BRDYSTS =
220             (uint16_t)~g_usbx_function_bit_set[USB_FUNCTION_PIPE0];
221         RZA_IO_RegWrite_16(
222             &USB20X.CFIFOSEL, USB_FUNCTION_PIPE0,
223             USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE);
224
225         g_usbx_function_PipeDataSize[USB_FUNCTION_PIPE0] =
226             g_usbx_function_data_count[USB_FUNCTION_PIPE0];
227
228         read_status = usbx_function_read_buffer_c(USB_FUNCTION_PIPE0);
229
230         g_usbx_function_PipeDataSize[USB_FUNCTION_PIPE0] -=
231             g_usbx_function_data_count[USB_FUNCTION_PIPE0];
232
233         switch (read_status) {
234             case USB_FUNCTION_READING:      /* Continue of data read */
235             case USB_FUNCTION_READEND:      /* End of data read */
236                 /* PID = BUF */
237                 usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);
238
239                 /*callback*/
240                 (object->*EP0func)();
241                 break;
242
243             case USB_FUNCTION_READSHRT:     /* End of data read */
244                 usbx_function_disable_brdy_int(USB_FUNCTION_PIPE0);
245                 /* PID = BUF */
246                 usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);
247
248                 /*callback*/
249                 (object->*EP0func)();
250                 break;
251
252             case USB_FUNCTION_READOVER:     /* FIFO access error */
253                 /* Buffer Clear */
254                 USB20X.CFIFOCTR = USB_FUNCTION_BITBCLR;
255                 usbx_function_disable_brdy_int(USB_FUNCTION_PIPE0);
256                 /* Req Error */
257                 usbx_function_set_pid_stall(USB_FUNCTION_PIPE0);
258
259                 /*callback*/
260                 (object->*EP0func)();
261                 break;
262
263             case DEVDRV_USBF_FIFOERROR:     /* FIFO access error */
264             default:
265                 usbx_function_disable_brdy_int(USB_FUNCTION_PIPE0);
266                 /* Req Error */
267                 usbx_function_set_pid_stall(USB_FUNCTION_PIPE0);
268                 break;
269         }
270         /* Three dummy reads for clearing interrupt requests */
271         dumy_sts = USB20X.BRDYSTS;
272     }
273 }
274
275
276 /******************************************************************************
277  * Function Name: usbx_function_BRDYInterrupt
278  * Description  : Executes BRDY interrupt uxclude pipe0.
279  * Arguments    : uint16_t status       ; BRDYSTS Register Value
280  *              : uint16_t intenb       ; BRDYENB Register Value
281  * Return Value : none
282  *****************************************************************************/
283 extern "C" {
284     void usbx_function_BRDYInterrupt(
285         uint16_t status,
286         uint16_t intenb,
287         USBHAL *object,
288         bool (USBHAL::*epCallback[])(void)
289     )
290     {
291         volatile uint16_t dumy_sts;
292
293         /**************************************************************
294          * Function Name: usbx_function_brdy_int
295          * Description  : Executes BRDY interrupt(USB_FUNCTION_PIPE1-9).
296          *              : According to the pipe that interrupt is generated in,
297          *              : reads/writes buffer allocated in the pipe.
298          *              : This function is executed in the BRDY
299          *              : interrupt handler.  This function
300          *              : clears BRDY interrupt status and BEMP
301          *              : interrupt status.
302          * Arguments    : uint16_t Status    ; BRDYSTS Register Value
303          *              : uint16_t Int_enbl  ; BRDYENB Register Value
304          * Return Value : none
305          *************************************************************/
306         /* copied from usbx_function_intrn.c */
307         uint32_t int_sense = 0;
308         uint16_t pipe;
309         uint16_t pipebit;
310         uint16_t ep;
311
312         for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) {
313             pipebit = g_usbx_function_bit_set[pipe];
314
315             if ((status & pipebit) && (intenb & pipebit)) {
316                 USB20X.BRDYSTS = (uint16_t)~pipebit;
317                 USB20X.BEMPSTS = (uint16_t)~pipebit;
318
319                 switch (g_usbx_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) {
320                     case USB_FUNCTION_D0FIFO_DMA:
321                         if (g_usbx_function_DmaStatus[USB_FUNCTION_D0FIFO] != USB_FUNCTION_DMA_READY) {
322                             /*now, DMA is not supported*/
323                             usbx_function_dma_interrupt_d0fifo(int_sense);
324                         }
325
326                         if (RZA_IO_RegRead_16(
327                                 &g_usbx_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) {
328                             /*now, DMA is not supported*/
329                             usbx_function_read_dma(pipe);
330                             usbx_function_disable_brdy_int(pipe);
331                         } else {
332                             USB20X.D0FIFOCTR = USB_FUNCTION_BITBCLR;
333                             g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE;
334                         }
335                         break;
336
337                     case USB_FUNCTION_D1FIFO_DMA:
338                         if (g_usbx_function_DmaStatus[USB_FUNCTION_D1FIFO] != USB_FUNCTION_DMA_READY) {
339                             /*now, DMA is not supported*/
340                             usbx_function_dma_interrupt_d1fifo(int_sense);
341                         }
342
343                         if (RZA_IO_RegRead_16(
344                                 &g_usbx_function_pipecfg[pipe], USB_PIPECFG_BFRE_SHIFT, USB_PIPECFG_BFRE) == 0) {
345                             /*now, DMA is not supported*/
346                             usbx_function_read_dma(pipe);
347                             usbx_function_disable_brdy_int(pipe);
348                         } else {
349                             USB20X.D1FIFOCTR = USB_FUNCTION_BITBCLR;
350                             g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE;
351                         }
352                         break;
353
354                     default:
355                         ep = (g_usbx_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT;
356                         ep <<= 1;
357                         if (RZA_IO_RegRead_16(
358                                 &g_usbx_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0) {
359                             /* read */
360                             EPx_read_status = DEVDRV_USBF_PIPE_WAIT;
361                             (object->*(epCallback[ep - 2])) ();
362                             EPx_read_status = DEVDRV_USBF_PIPE_DONE;
363                         } else {
364                             /* write */
365                             EPx_read_status = DEVDRV_USBF_PIPE_WAIT;
366                             (object->*(epCallback[ep - 2 + 1])) ();
367                             EPx_read_status = DEVDRV_USBF_PIPE_DONE;
368                             usbx_function_write_buffer(pipe);
369                         }
370                 }
371             }
372         }
373         /* Three dummy reads for clearing interrupt requests */
374         dumy_sts = USB20X.BRDYSTS;
375     }
376 }
377
378
379 /******************************************************************************
380  * Function Name: usbx_function_NRDYInterruptPIPE0
381  * Description  : Executes NRDY interrupt for pipe0.
382  * Arguments    : uint16_t status       ; NRDYSTS Register Value
383  *              : uint16_t intenb       ; NRDYENB Register Value
384  * Return Value : none
385  *****************************************************************************/
386 extern "C" {
387     void usbx_function_NRDYInterruptPIPE0(
388         uint16_t status,
389         uint16_t intenb,
390         USBHAL *object,
391         void (USBHAL::*EP0func)(void)
392     )
393     {
394         volatile uint16_t dumy_sts;
395
396         USB20X.NRDYSTS =
397             (uint16_t)~g_usbx_function_bit_set[USB_FUNCTION_PIPE0];
398
399         /* Three dummy reads for clearing interrupt requests */
400         dumy_sts = USB20X.NRDYSTS;
401     }
402 }
403
404
405 /******************************************************************************
406  * Function Name: usbx_function_NRDYInterrupt
407  * Description  : Executes NRDY interrupt exclude pipe0.
408  * Arguments    : uint16_t status       ; NRDYSTS Register Value
409  *              : uint16_t intenb       ; NRDYENB Register Value
410  * Return Value : none
411  *****************************************************************************/
412 extern "C" {
413     void usbx_function_NRDYInterrupt(
414         uint16_t status,
415         uint16_t intenb,
416         USBHAL *object,
417         bool (USBHAL::*epCallback[])(void)
418     )
419     {
420         volatile uint16_t dumy_sts;
421
422         /**************************************************************
423          * Function Name: usbx_function_nrdy_int
424          * Description  : Executes NRDY interrupt(USB_FUNCTION_PIPE1-9).
425          *              : Checks NRDY interrupt cause by PID. When the cause if STALL,
426          *              : regards the pipe state as STALL and ends the processing.
427          *              : Then the cause is not STALL, increments the error count to
428          *              : communicate again. When the error count is 3, determines
429          *              : the pipe state as DEVDRV_USBF_PIPE_NORES and ends the processing.
430          *              : This function is executed in the NRDY interrupt handler.
431          *              : This function clears NRDY interrupt status.
432          * Arguments    : uint16_t status       ; NRDYSTS Register Value
433          *              : uint16_t int_enb      ; NRDYENB Register Value
434          * Return Value : none
435          *************************************************************/
436         /* copied from usbx_function_intrn.c */
437 #if 0
438         uint16_t usefifo;
439 #endif
440         uint16_t pid;
441         uint16_t pipe;
442         uint16_t bitcheck;
443 #if 0
444         uint16_t mbw;
445         uint32_t size;
446 #endif
447         uint16_t ep;
448
449         bitcheck = (uint16_t)(status & intenb);
450
451         USB20X.NRDYSTS = (uint16_t)~status;
452
453
454         if (RZA_IO_RegRead_16(&USB20X.SYSCFG0, USB_SYSCFG_DCFM_SHIFT, USB_SYSCFG_DCFM) == 1) {
455             /* USB HOST */
456             /* not support */
457
458         } else {
459             /* USB Function */
460             for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) {
461                 if ((bitcheck&g_usbx_function_bit_set[pipe]) != g_usbx_function_bit_set[pipe]) {
462                     continue;
463                 }
464
465                 if (g_usbx_function_pipe_status[pipe] != DEVDRV_USBF_PIPE_WAIT) {
466                     continue;
467                 }
468
469 #if 0
470                 usbx_function_set_pid_nak(pipe);
471
472                 size = (uint32_t)g_usbx_function_data_count[pipe];
473                 mbw = usbx_function_get_mbw(
474                     size, (uint32_t)g_usbx_function_data_pointer[pipe]);
475
476                 usefifo = (uint16_t)(g_usbx_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE);
477                 switch (usefifo) {
478
479                     case USB_FUNCTION_D0FIFO_USE:
480                         usbx_function_set_curpipe(
481                             pipe, USB_FUNCTION_D0USE, DEVDRV_USBF_NO, mbw);
482                         USB20X.D0FIFOCTR = USB_FUNCTION_BITBCLR;
483                         break;
484
485                     case USB_FUNCTION_D1FIFO_USE:
486                         usbx_function_set_curpipe(
487                             pipe, USB_FUNCTION_D1USE, DEVDRV_USBF_NO, mbw);
488                         USB20X.D1FIFOCTR = USB_FUNCTION_BITBCLR;
489                         break;
490
491                     default:
492                         usbx_function_set_curpipe(
493                             pipe, USB_FUNCTION_CUSE, USB_FUNCTION_CFIFO_READ, mbw);
494                         USB20X.CFIFOCTR = USB_FUNCTION_BITBCLR;
495                         break;
496                 }
497
498                 usbx_function_aclrm(pipe);
499
500                 usbx_function_enable_nrdy_int(pipe);
501                 usbx_function_enable_brdy_int(pipe);
502
503                 usbx_function_set_pid_buf(pipe);
504 #endif
505
506                 pid = usbx_function_get_pid(pipe);
507                 if ((pid == DEVDRV_USBF_PID_STALL) || (pid == DEVDRV_USBF_PID_STALL2)) {
508                     g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_STALL;
509                 } else {
510                     usbx_function_set_pid_buf(pipe);
511                 }
512
513                 ep = (g_usbx_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT;
514                 ep <<= 1;
515                 if (RZA_IO_RegRead_16(
516                         &g_usbx_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0) {
517                     /* read */
518                     __NOP();
519                 } else {
520                     /* write */
521                     __NOP();
522                 }
523             }
524         }
525
526         /* Three dummy reads for clearing interrupt requests */
527         dumy_sts = USB20X.NRDYSTS;
528     }
529 }
530
531 /******************************************************************************
532  * Function Name: usbx_function_BEMPInterruptPIPE0
533  * Description  : Executes BEMP interrupt for pipe0.
534  * Arguments    : uint16_t status       ; BEMPSTS Register Value
535  *              : uint16_t intenb       ; BEMPENB Register Value
536  * Return Value : none
537  *****************************************************************************/
538 extern "C" {
539     void usbx_function_BEMPInterruptPIPE0(
540         uint16_t status,
541         uint16_t intenb,
542         USBHAL *object,
543         void (USBHAL::*EP0func)(void)
544     )
545     {
546         volatile uint16_t dumy_sts;
547
548         USB20X.BEMPSTS =
549             (uint16_t)~g_usbx_function_bit_set[USB_FUNCTION_PIPE0];
550         RZA_IO_RegWrite_16(
551             &USB20X.CFIFOSEL, USB_FUNCTION_PIPE0,
552             USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE);
553
554         /*usbx_function_write_buffer_c(USB_FUNCTION_PIPE0);*/
555         (object->*EP0func)();
556
557         /* Three dummy reads for clearing interrupt requests */
558         dumy_sts = USB20X.BEMPSTS;
559     }
560 }
561
562
563 /******************************************************************************
564  * Function Name: usbx_function_BEMPInterrupt
565  * Description  : Executes BEMP interrupt exclude pipe0.
566  * Arguments    : uint16_t status       ; BEMPSTS Register Value
567  *              : uint16_t intenb       ; BEMPENB Register Value
568  * Return Value : none
569  *****************************************************************************/
570 extern "C" {
571     void usbx_function_BEMPInterrupt(
572         uint16_t status,
573         uint16_t intenb,
574         USBHAL *object,
575         bool (USBHAL::*epCallback[])(void)
576     )
577     {
578         volatile uint16_t dumy_sts;
579
580         /**************************************************************
581          * Function Name: usbx_function_bemp_int
582          * Description  : Executes BEMP interrupt(USB_FUNCTION_PIPE1-9).
583          * Arguments    : uint16_t status       ; BEMPSTS Register Value
584          *              : uint16_t intenb      ; BEMPENB Register Value
585          * Return Value : none
586          *************************************************************/
587         /* copied from usbx_function_intrn.c */
588         uint16_t pid;
589         uint16_t pipe;
590         uint16_t bitcheck;
591         uint16_t inbuf;
592         uint16_t ep;
593
594         bitcheck = (uint16_t)(status & intenb);
595
596         USB20X.BEMPSTS = (uint16_t)~status;
597
598         for (pipe = USB_FUNCTION_PIPE1; pipe <= USB_FUNCTION_MAX_PIPE_NO; pipe++) {
599             if ((bitcheck&g_usbx_function_bit_set[pipe]) != g_usbx_function_bit_set[pipe]) {
600                 continue;
601             }
602
603             pid = usbx_function_get_pid(pipe);
604
605             if ((pid == DEVDRV_USBF_PID_STALL) ||
606                 (pid == DEVDRV_USBF_PID_STALL2)) {
607                 g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_STALL;
608
609             } else {
610                 inbuf = usbx_function_get_inbuf(pipe);
611
612                 if (inbuf == 0) {
613                     usbx_function_disable_bemp_int(pipe);
614                     usbx_function_set_pid_nak(pipe);
615                     g_usbx_function_pipe_status[pipe] = DEVDRV_USBF_PIPE_DONE;
616
617                     switch (g_usbx_function_PipeTbl[pipe] & USB_FUNCTION_FIFO_USE) {
618                         case USB_FUNCTION_D0FIFO_DMA:
619                             /*now, DMA is not supported*/
620                             break;
621
622                         case USB_FUNCTION_D1FIFO_DMA:
623                             /*now, DMA is not supported*/
624                             break;
625
626                         default:
627                             ep = (g_usbx_function_pipecfg[pipe] & USB_PIPECFG_EPNUM) >> USB_PIPECFG_EPNUM_SHIFT;
628                             ep <<= 1;
629                             if (RZA_IO_RegRead_16(
630                                     &g_usbx_function_pipecfg[pipe], USB_PIPECFG_DIR_SHIFT, USB_PIPECFG_DIR) == 0) {
631                                 /* read */
632                                 __NOP();
633                             } else {
634                                 /* write */
635                                 EPx_read_status = DEVDRV_USBF_PIPE_WAIT;
636                                 (object->*(epCallback[ep - 2 + 1])) ();
637                                 EPx_read_status = DEVDRV_USBF_PIPE_DONE;
638                             }
639                     }
640                 }
641             }
642         }
643
644         /* Three dummy reads for clearing interrupt requests */
645         dumy_sts = USB20X.BEMPSTS;
646     }
647 }
648
649 /******************************************************************************
650  * Function Name: EP2PIPE
651  * Description  : Converts from endpoint to pipe
652  * Arguments    : number of endpoint
653  * Return Value : number of pipe
654  *****************************************************************************/
655 /*EP2PIPE converter is for pipe1, pipe3 and pipe6 only.*/
656 #define EP2PIPE(endpoint)   ((uint32_t)usbx_function_EpToPipe(endpoint))
657
658
659 /******************************************************************************
660  * Function Name: usbx_function_save_request
661  * Description  : Retains the USB request information in variables.
662  * Arguments    : none
663  * Return Value : none
664  *****************************************************************************/
665 #define  usbx_function_save_request()                       \
666     {                                                       \
667         uint16_t *bufO = &setup_buffer[0];                  \
668                                                             \
669         USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITVALID;  \
670         /*data[0] <= bmRequest, data[1] <= bmRequestType */ \
671         *bufO++ = USB20X.USBREQ;                            \
672         /*data[2] data[3] <= wValue*/                       \
673         *bufO++ = USB20X.USBVAL;                            \
674         /*data[4] data[5] <= wIndex*/                       \
675         *bufO++ = USB20X.USBINDX;                           \
676         /*data[6] data[6] <= wIndex*/                       \
677         *bufO++ = USB20X.USBLENG;                           \
678     }
679
680
681 /*************************************************************************/
682 /*************************************************************************/
683 /*************************************************************************/
684
685 /*************************************************************************/
686 /* constructor */
687 USBHAL::USBHAL(void)
688 {
689     /* ---- P4_1 : P4_1 (USB0_EN for GR-PEACH) ---- */
690     //usbx_en = new DigitalOut(P4_1, 1);
691
692     /* some constants */
693     int_id          = USBIX_IRQn;
694     int_level       = ( 2 << 3 );
695     clock_mode      = USBFCLOCK_X1_48MHZ;
696 #if (USB_FUNCTION_HISPEED == 0)
697     mode            = USB_FUNCTION_FULL_SPEED;
698 #else
699     mode            = USB_FUNCTION_HIGH_SPEED;
700 #endif
701     EP0_read_status = DEVDRV_USBF_WRITEEND;
702     EPx_read_status = DEVDRV_USBF_PIPE_DONE;
703
704     /* Disables interrupt for usb */
705     GIC_DisableIRQ(int_id);
706
707     /* Setup the end point */
708     epCallback[ 0] = &USBHAL::EP1_OUT_callback;
709     epCallback[ 1] = &USBHAL::EP1_IN_callback;
710     epCallback[ 2] = &USBHAL::EP2_OUT_callback;
711     epCallback[ 3] = &USBHAL::EP2_IN_callback;
712     epCallback[ 4] = &USBHAL::EP3_OUT_callback;
713     epCallback[ 5] = &USBHAL::EP3_IN_callback;
714     epCallback[ 6] = &USBHAL::EP4_OUT_callback;
715     epCallback[ 7] = &USBHAL::EP4_IN_callback;
716     epCallback[ 8] = &USBHAL::EP5_OUT_callback;
717     epCallback[ 9] = &USBHAL::EP5_IN_callback;
718     epCallback[10] = &USBHAL::EP6_OUT_callback;
719     epCallback[11] = &USBHAL::EP6_IN_callback;
720     epCallback[12] = &USBHAL::EP7_OUT_callback;
721     epCallback[13] = &USBHAL::EP7_IN_callback;
722     epCallback[14] = &USBHAL::EP8_OUT_callback;
723     epCallback[15] = &USBHAL::EP8_IN_callback;
724     epCallback[16] = &USBHAL::EP9_OUT_callback;
725     epCallback[17] = &USBHAL::EP9_IN_callback;
726     epCallback[18] = &USBHAL::EP10_OUT_callback;
727     epCallback[19] = &USBHAL::EP10_IN_callback;
728     epCallback[20] = &USBHAL::EP11_OUT_callback;
729     epCallback[21] = &USBHAL::EP11_IN_callback;
730     epCallback[22] = &USBHAL::EP12_OUT_callback;
731     epCallback[23] = &USBHAL::EP12_IN_callback;
732     epCallback[24] = &USBHAL::EP13_OUT_callback;
733     epCallback[25] = &USBHAL::EP13_IN_callback;
734     epCallback[26] = &USBHAL::EP14_OUT_callback;
735     epCallback[27] = &USBHAL::EP14_IN_callback;
736     epCallback[28] = &USBHAL::EP15_OUT_callback;
737     epCallback[29] = &USBHAL::EP15_IN_callback;
738
739     /* registers me */
740     instance = this;
741
742     /* Clear pipe table */
743     usbx_function_clear_pipe_tbl();
744
745 /******************************************************************************
746  * Function Name: usbx_api_function_init
747  * Description  : Initializes the USB module in the USB function mode.
748  *****************************************************************************/
749     /* The clock of USB0 modules is permitted */
750 #if (USB_FUNCTION_CH == 0)
751     CPG.STBCR7 &= ~(CPG_STBCR7_MSTP71);
752 #else
753     CPG.STBCR7 &= ~(CPG_STBCR7_MSTP71 | CPG_STBCR7_MSTP70);
754 #endif
755     volatile uint8_t    dummy8;
756     dummy8 = CPG.STBCR7;
757
758     {
759 /******************************************************************************
760  * Function Name: usbx_function_setting_interrupt
761  * Description  : Sets the USB module interrupt level.
762  *****************************************************************************/
763 #if 0   /*DMA is not supported*/
764         IRQn_Type d0fifo_dmaintid;
765         IRQn_Type d1fifo_dmaintid;
766 #endif
767
768         InterruptHandlerRegister(int_id, &_usbisr);
769         GIC_SetPriority(int_id, int_level);
770         GIC_EnableIRQ(int_id);
771
772 #if 0   /*DMA is not supported*/
773         d0fifo_dmaintid = Userdef_USB_usbx_function_d0fifo_dmaintid();
774         if (d0fifo_dmaintid != 0xFFFF) {
775             InterruptHandlerRegister(d0fifo_dmaintid, usbx_function_dma_interrupt_d0fifo);
776             GIC_SetPriority(d0fifo_dmaintid, int_level);
777             GIC_EnableIRQ(d0fifo_dmaintid);
778         }
779 #endif
780
781 #if 0   /*DMA is not supported*/
782         d1fifo_dmaintid = Userdef_USB_usbx_function_d1fifo_dmaintid();
783         if (d1fifo_dmaintid != 0xFFFF) {
784             InterruptHandlerRegister(d1fifo_dmaintid, usbx_function_dma_interrupt_d1fifo);
785             GIC_SetPriority(d1fifo_dmaintid, int_level);
786             GIC_EnableIRQ(d1fifo_dmaintid);
787         }
788 #endif
789 /*****************************************************************************/
790     }
791
792     /* reset USB module with setting tranciever and HSE=1 */
793     usbx_function_reset_module(clock_mode);
794
795     /* clear variables */
796     usbx_function_init_status();
797
798     /* select USB Function and Interrupt Enable */
799     /* Detect USB Device to attach or detach    */
800     usbx_function_InitModule(mode);
801
802     {
803         uint16_t buf;
804         buf  = USB20X.INTENB0;
805         buf |= USB_INTENB0_SOFE;
806         USB20X.INTENB0 = buf;
807     }
808 }
809
810 /*************************************************************************/
811 USBHAL::~USBHAL(void)
812 {
813     /* Disables interrupt for usb */
814     GIC_DisableIRQ( int_id );
815     /* Unregisters interrupt function and priority */
816     InterruptHandlerRegister( int_id, (uint32_t)NULL );
817
818     //usbx_en  = NULL;
819     instance = NULL;
820 }
821
822 /*************************************************************************/
823 void USBHAL::connect(void)
824 {
825     /* Activates USB0_EN */
826     //(*usbx_en) = 0;
827 }
828
829
830 /*************************************************************************/
831 void USBHAL::disconnect(void)
832 {
833     /* Deactivates USB0_EN */
834     //(*usbx_en) = 1;
835 }
836
837
838 /*************************************************************************/
839 void USBHAL::configureDevice(void)
840 {
841     /*The pipes set up in USBHAL::realiseEndpoint*/
842     /*usbx_function_clear_alt();*/      /* Alternate setting clear */
843     /*usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);*/
844 }
845
846
847 /*************************************************************************/
848 void USBHAL::unconfigureDevice(void)
849 {
850     /* The Interface would be managed by USBDevice */
851     /*usbx_function_clear_alt();*/      /* Alternate setting clear */
852     /*usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);*/
853 }
854
855
856 /*************************************************************************/
857 void USBHAL::setAddress(uint8_t address)
858 {
859     if (address <= 127) {
860         usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);      /* OK */
861     } else {
862         usbx_function_set_pid_stall(USB_FUNCTION_PIPE0);    /* Not Spec */
863     }
864 }
865
866
867 /*************************************************************************/
868 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags)
869 {
870     const struct PIPECFGREC *cfg;
871     uint16_t pipe;
872     uint16_t buf;
873
874     if ( (EP0OUT == endpoint) || (EP0IN  == endpoint) ) {
875         return true;
876     }
877
878     for (cfg = &def_pipecfg[0]; cfg->pipesel != 0; cfg++) {
879         if (cfg->endpoint == endpoint) {
880             break;
881         }
882     }
883     if (cfg->pipesel == 0) {
884         return false;
885     }
886
887     pipe = ((cfg->pipesel & USB_PIPESEL_PIPESEL) >> USB_PIPESEL_PIPESEL_SHIFT);
888
889     g_usbx_function_PipeTbl[ pipe ] = (uint16_t)(endpoint | ((cfg->pipesel & USB_FUNCTION_FIFO_USE) << 0));
890
891     /* There are maintenance routine of SHTNAK and BFRE bits
892      * in original sample program. This sample is not
893      * programmed. Do maintenance the "def_pipecfg" array if
894      * you want it. */
895
896     /* Interrupt Disable */
897     buf  = USB20X.BRDYENB;
898     buf &= (uint16_t)~g_usbx_function_bit_set[pipe];
899     USB20X.BRDYENB = buf;
900     buf  = USB20X.NRDYENB;
901     buf &= (uint16_t)~g_usbx_function_bit_set[pipe];
902     USB20X.NRDYENB = buf;
903     buf  = USB20X.BEMPENB;
904     buf &= (uint16_t)~g_usbx_function_bit_set[pipe];
905     USB20X.BEMPENB = buf;
906
907     usbx_function_set_pid_nak(pipe);
908
909     /* CurrentPIPE Clear */
910     if (RZA_IO_RegRead_16(&USB20X.CFIFOSEL, USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE) == pipe) {
911         RZA_IO_RegWrite_16(&USB20X.CFIFOSEL, 0, USB_CFIFOSEL_CURPIPE_SHIFT, USB_CFIFOSEL_CURPIPE);
912     }
913
914     if (RZA_IO_RegRead_16(&USB20X.D0FIFOSEL, USB_DnFIFOSEL_CURPIPE_SHIFT, USB_DnFIFOSEL_CURPIPE) == pipe) {
915         RZA_IO_RegWrite_16(&USB20X.D0FIFOSEL, 0, USB_DnFIFOSEL_CURPIPE_SHIFT, USB_DnFIFOSEL_CURPIPE);
916     }
917
918     if (RZA_IO_RegRead_16(&USB20X.D1FIFOSEL, USB_DnFIFOSEL_CURPIPE_SHIFT, USB_DnFIFOSEL_CURPIPE) == pipe) {
919         RZA_IO_RegWrite_16(&USB20X.D1FIFOSEL, 0, USB_DnFIFOSEL_CURPIPE_SHIFT, USB_DnFIFOSEL_CURPIPE);
920     }
921
922     /* PIPE Configuration */
923     USB20X.PIPESEL  = pipe;
924     USB20X.PIPECFG  = cfg->pipecfg;
925     USB20X.PIPEBUF  = cfg->pipebuf;
926     USB20X.PIPEMAXP = cfg->pipemaxp;
927     USB20X.PIPEPERI = cfg->pipeperi;
928
929     g_usbx_function_pipecfg[pipe]  = cfg->pipecfg;
930     g_usbx_function_pipebuf[pipe]  = cfg->pipebuf;
931     g_usbx_function_pipemaxp[pipe] = cfg->pipemaxp;
932     g_usbx_function_pipeperi[pipe] = cfg->pipeperi;
933
934     /* Buffer Clear */
935     usbx_function_set_sqclr(pipe);
936     usbx_function_aclrm(pipe);
937
938     /* init Global */
939     g_usbx_function_pipe_status[pipe]  = DEVDRV_USBF_PIPE_IDLE;
940     g_usbx_function_PipeDataSize[pipe] = 0;
941
942     return true;
943 }
944
945
946 /*************************************************************************/
947 // read setup packet
948 void USBHAL::EP0setup(uint8_t *buffer)
949 {
950     memcpy(buffer, setup_buffer, MAX_PACKET_SIZE_EP0);
951 }
952
953
954 /*************************************************************************/
955 void USBHAL::EP0readStage(void)
956 {
957     // No implements
958 }
959
960
961 /*************************************************************************/
962 void USBHAL::EP0read(void)
963 {
964     uint8_t *buffer;
965     uint32_t size;
966
967     /* remain of last writing */
968     while (EP0_read_status != DEVDRV_USBF_WRITEEND) {
969         static uint8_t bbb[2] = { 255, 255 };
970         EP0write(&bbb[0], 0);
971     }
972
973     buffer = (uint8_t*)(&setup_buffer[4]);
974     size   = (MAX_PACKET_SIZE_EP0 / 2) - 8;
975     usbx_api_function_CtrlWriteStart(size, buffer);
976 }
977
978
979 /*************************************************************************/
980 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer)
981 {
982     memcpy(buffer, (uint8_t*)(&setup_buffer[4]), g_usbx_function_PipeDataSize[USB_FUNCTION_PIPE0]);
983
984     return g_usbx_function_PipeDataSize[USB_FUNCTION_PIPE0];
985 }
986
987
988 /*************************************************************************/
989 void USBHAL::EP0write(uint8_t *buffer, uint32_t size)
990 {
991     /* zero byte writing */
992     if ( (size == 0) && (EP0_read_status == DEVDRV_USBF_WRITEEND) ) {
993         return;
994     }
995
996     if (EP0_read_status == DEVDRV_USBF_WRITEEND) {
997         /*1st block*/
998         EP0_read_status = usbx_api_function_CtrlReadStart(size, buffer);
999     } else {
1000         /* waits the last transmission */
1001         /*other blocks*/
1002         g_usbx_function_data_count[ USB_FUNCTION_PIPE0 ]    = size;
1003         g_usbx_function_data_pointer [ USB_FUNCTION_PIPE0 ] = buffer;
1004         EP0_read_status = usbx_function_write_buffer_c(USB_FUNCTION_PIPE0);
1005     }
1006     /*max size may be deblocking outside*/
1007     if (size == MAX_PACKET_SIZE_EP0) {
1008         EP0_read_status = DEVDRV_USBF_WRITING;
1009     }
1010 }
1011
1012
1013 /*************************************************************************/
1014 #if 0   // No implements
1015 void USBHAL::EP0getWriteResult(void)
1016 {
1017 }
1018 #endif
1019
1020 /*************************************************************************/
1021 void USBHAL::EP0stall(void)
1022 {
1023     stallEndpoint( 0 );
1024 }
1025
1026
1027 /*************************************************************************/
1028 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t max_size)
1029 {
1030     uint32_t    pipe = EP2PIPE(endpoint);
1031     uint32_t    pipe_size;
1032     uint16_t    pipe_status;
1033     EP_STATUS status = EP_COMPLETED;
1034
1035     pipe_status = usbx_api_function_check_pipe_status(pipe, &pipe_size);
1036
1037     switch (pipe_status) {
1038         case DEVDRV_USBF_PIPE_IDLE:
1039         case DEVDRV_USBF_PIPE_WAIT:
1040             usbx_api_function_set_pid_nak(pipe);
1041             usbx_api_function_clear_pipe_status(pipe);
1042
1043             usbx_api_function_start_receive_transfer(pipe, max_size, recv_buffer);
1044             break;
1045
1046         default:
1047             status = EP_PENDING;
1048             break;
1049     }
1050
1051     return status;
1052 }
1053
1054
1055 /*************************************************************************/
1056 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t *buffer, uint32_t *bytes_read )
1057 {
1058     uint32_t pipe = EP2PIPE(endpoint);
1059     uint16_t pipe_status;
1060     uint16_t err;
1061     EP_STATUS status = EP_PENDING;
1062
1063
1064     if (EPx_read_status != DEVDRV_USBF_PIPE_WAIT) {
1065         return status;
1066     }
1067
1068     pipe_status = usbx_api_function_check_pipe_status(pipe, bytes_read);
1069     switch (pipe_status) {
1070         case DEVDRV_USBF_PIPE_IDLE:
1071             return EP_COMPLETED;
1072
1073         case DEVDRV_USBF_PIPE_DONE:
1074             return EP_COMPLETED;
1075
1076         case DEVDRV_USBF_PIPE_WAIT:
1077             break;
1078
1079         default:
1080             return status;
1081     }
1082
1083     /* sets the output buffer and size */
1084     g_usbx_function_data_pointer[pipe] = buffer;
1085
1086     /* receives data from pipe */
1087     err = usbx_function_read_buffer(pipe);
1088     recv_error = err;
1089     switch (err) {
1090         case USB_FUNCTION_READEND:
1091         case USB_FUNCTION_READSHRT:
1092         case USB_FUNCTION_READOVER:
1093             *bytes_read = g_usbx_function_PipeDataSize[pipe];
1094             break;
1095
1096         case USB_FUNCTION_READING:
1097         case DEVDRV_USBF_FIFOERROR:
1098             break;
1099     }
1100
1101     pipe_status = usbx_api_function_check_pipe_status(pipe, bytes_read);
1102     switch (pipe_status) {
1103         case DEVDRV_USBF_PIPE_DONE:
1104             status = EP_COMPLETED;
1105             break;
1106
1107         case DEVDRV_USBF_PIPE_IDLE:
1108         case DEVDRV_USBF_PIPE_NORES:
1109         case DEVDRV_USBF_PIPE_STALL:
1110         case DEVDRV_USBF_FIFOERROR:
1111         default:
1112             break;
1113     }
1114
1115     return status;
1116 }
1117
1118
1119 /*************************************************************************/
1120 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
1121 {
1122     uint32_t pipe = EP2PIPE(endpoint);
1123     uint32_t pipe_size;
1124     uint16_t pipe_status;
1125     uint16_t err;
1126     uint16_t count;
1127     EP_STATUS status = EP_PENDING;
1128
1129     pipe_status = usbx_api_function_check_pipe_status(pipe, &pipe_size);
1130
1131     /* waits the last transmission */
1132     count = 30000;
1133     while ((pipe_status == DEVDRV_USBF_PIPE_WAIT) || (pipe_status == DEVDRV_USBF_PIPE_DONE)) {
1134         pipe_status = usbx_api_function_check_pipe_status(pipe, &pipe_size);
1135         if( --count == 0 ) {
1136             pipe_status = DEVDRV_USBF_PIPE_STALL;
1137             break;
1138         }
1139     }
1140
1141     switch (pipe_status) {
1142         case DEVDRV_USBF_PIPE_IDLE:
1143             err = usbx_api_function_start_send_transfer(pipe, size, data);
1144
1145             switch (err) {
1146                     /* finish to write */
1147                 case DEVDRV_USBF_WRITEEND:
1148                     /* finish to write, but data is short */
1149                 case DEVDRV_USBF_WRITESHRT:
1150                     /* continue to write */
1151                 case DEVDRV_USBF_WRITING:
1152                     /* use DMA */
1153                 case DEVDRV_USBF_WRITEDMA:
1154                     /* error */
1155                 case DEVDRV_USBF_FIFOERROR:
1156                     status = EP_PENDING;
1157                     break;
1158             }
1159             break;
1160
1161         case DEVDRV_USBF_PIPE_WAIT:
1162         case DEVDRV_USBF_PIPE_DONE:
1163             status = EP_PENDING;
1164             break;
1165
1166         case DEVDRV_USBF_PIPE_NORES:
1167         case DEVDRV_USBF_PIPE_STALL:
1168         default:
1169             status = EP_STALLED;
1170             break;
1171     }
1172
1173     return status;
1174 }
1175
1176
1177 /*************************************************************************/
1178 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint)
1179 {
1180     uint32_t    pipe = EP2PIPE(endpoint);
1181     uint32_t    pipe_size;
1182     uint16_t    pipe_status;
1183     EP_STATUS status = EP_PENDING;
1184
1185     pipe_status = usbx_api_function_check_pipe_status(pipe, &pipe_size);
1186
1187     switch (pipe_status) {
1188         case DEVDRV_USBF_PIPE_IDLE:
1189             status = EP_COMPLETED;
1190             break;
1191
1192         case DEVDRV_USBF_PIPE_WAIT:
1193             status = EP_PENDING;
1194             break;
1195
1196         case DEVDRV_USBF_PIPE_DONE:
1197             usbx_function_stop_transfer(pipe);
1198             status = EP_COMPLETED;
1199             break;
1200
1201         case DEVDRV_USBF_PIPE_NORES:
1202             status = EP_STALLED;
1203             break;
1204
1205         case DEVDRV_USBF_PIPE_STALL:
1206             status = EP_STALLED;
1207             break;
1208
1209         default:
1210             status = EP_PENDING;
1211     }
1212
1213     return status;
1214 }
1215
1216
1217 /*************************************************************************/
1218 void USBHAL::stallEndpoint(uint8_t endpoint)
1219 {
1220     uint32_t pipe = EP2PIPE(endpoint);
1221
1222     usbx_function_clear_pid_stall(pipe);
1223 }
1224
1225
1226 /*************************************************************************/
1227 void USBHAL::unstallEndpoint(uint8_t endpoint)
1228 {
1229     uint32_t pipe = EP2PIPE(endpoint);
1230
1231     usbx_function_set_pid_stall( pipe );
1232 }
1233
1234
1235 /*************************************************************************/
1236 bool USBHAL::getEndpointStallState(uint8_t endpoint)
1237 {
1238     // No implemens
1239     return false;
1240 }
1241
1242
1243 /*************************************************************************/
1244 #if 0   // No implements
1245 void USBHAL::remoteWakeup(void)
1246 {
1247 }
1248 #endif
1249
1250 /*************************************************************************/
1251 void USBHAL::_usbisr(void)
1252 {
1253     instance->usbisr();
1254 }
1255
1256
1257 /*************************************************************************/
1258 void USBHAL::usbisr(void)
1259 {
1260     uint16_t            int_sts0;
1261     uint16_t            int_sts1;
1262     uint16_t            int_sts2;
1263     uint16_t            int_sts3;
1264     uint16_t            int_enb0;
1265     uint16_t            int_enb2;
1266     uint16_t            int_enb3;
1267     uint16_t            int_enb4;
1268     volatile uint16_t   dumy_sts;
1269
1270
1271     int_sts0 = USB20X.INTSTS0;
1272
1273     if (!(int_sts0 & (
1274                 USB_FUNCTION_BITVBINT |
1275                 USB_FUNCTION_BITRESM  |
1276                 USB_FUNCTION_BITSOFR  |
1277                 USB_FUNCTION_BITDVST  |
1278                 USB_FUNCTION_BITCTRT  |
1279                 USB_FUNCTION_BITBEMP  |
1280                 USB_FUNCTION_BITNRDY  |
1281                 USB_FUNCTION_BITBRDY ))) {
1282         return;
1283     }
1284
1285     int_sts1 = USB20X.BRDYSTS;
1286     int_sts2 = USB20X.NRDYSTS;
1287     int_sts3 = USB20X.BEMPSTS;
1288     int_enb0 = USB20X.INTENB0;
1289     int_enb2 = USB20X.BRDYENB;
1290     int_enb3 = USB20X.NRDYENB;
1291     int_enb4 = USB20X.BEMPENB;
1292
1293     if ((int_sts0 & USB_FUNCTION_BITRESM) &&
1294             (int_enb0 & USB_FUNCTION_BITRSME)) {
1295         USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITRESM;
1296         RZA_IO_RegWrite_16(&USB20X.INTENB0, 0, USB_INTENB0_RSME_SHIFT, USB_INTENB0_RSME);
1297         /*usbx_function_USB_FUNCTION_Resume();*/
1298         suspendStateChanged(1);
1299     } else if (
1300         (int_sts0 & USB_FUNCTION_BITVBINT) &&
1301         (int_enb0 & USB_FUNCTION_BITVBSE)) {
1302         USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITVBINT;
1303
1304         if (usbx_function_CheckVBUStaus() == DEVDRV_USBF_ON) {
1305             usbx_function_USB_FUNCTION_Attach();
1306         } else {
1307             usbx_function_USB_FUNCTION_Detach();
1308         }
1309     } else if (
1310         (int_sts0 & USB_FUNCTION_BITSOFR) &&
1311         (int_enb0 & USB_FUNCTION_BITSOFE)) {
1312         USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITSOFR;
1313         SOF((USB20X.FRMNUM & USB_FRMNUM_FRNM) >> USB_FRMNUM_FRNM_SHIFT);
1314     } else if (
1315         (int_sts0 & USB_FUNCTION_BITDVST) &&
1316         (int_enb0 & USB_FUNCTION_BITDVSE)) {
1317         USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITDVST;
1318         switch (int_sts0 & USB_FUNCTION_BITDVSQ) {
1319             case USB_FUNCTION_DS_POWR:
1320                 break;
1321
1322             case USB_FUNCTION_DS_DFLT:
1323                 /*****************************************************************************
1324                  * Function Name: usbx_function_USB_FUNCTION_BusReset
1325                  * Description  : This function is executed when the USB device is transitioned
1326                  *              : to POWERD_STATE. Sets the device descriptor according to the
1327                  *              : connection speed determined by the USB reset hand shake.
1328                  * Arguments    : none
1329                  * Return Value : none
1330                  *****************************************************************************/
1331                 usbx_function_init_status();            /* memory clear */
1332
1333 #if 0
1334                 /* You would program those steps in USBCallback_busReset
1335                  * if the system need the comment out steps.
1336                  */
1337
1338                 if (usbx_function_is_hispeed() == USB_FUNCTION_HIGH_SPEED) {
1339                     /* Device Descriptor reset */
1340                     usbx_function_ResetDescriptor(USB_FUNCTION_HIGH_SPEED);
1341                 } else {
1342                     /* Device Descriptor reset */
1343                     usbx_function_ResetDescriptor(USB_FUNCTION_FULL_SPEED);
1344                 }
1345 #endif
1346                 /* Default Control PIPE reset */
1347                 /*****************************************************************************
1348                  * Function Name: usbx_function_ResetDCP
1349                  * Description  : Initializes the default control pipe(DCP).
1350                  * Outline      : Reset default control pipe
1351                  * Arguments    : none
1352                  * Return Value : none
1353                  *****************************************************************************/
1354                 USB20X.DCPCFG  = 0;
1355                 USB20X.DCPMAXP = 64;    /*TODO: This value is copied from sample*/
1356
1357                 USB20X.CFIFOSEL  = (uint16_t)(USB_FUNCTION_BITMBW_8 | USB_FUNCTION_BITBYTE_LITTLE);
1358                 USB20X.D0FIFOSEL = (uint16_t)(USB_FUNCTION_BITMBW_8 | USB_FUNCTION_BITBYTE_LITTLE);
1359                 USB20X.D1FIFOSEL = (uint16_t)(USB_FUNCTION_BITMBW_8 | USB_FUNCTION_BITBYTE_LITTLE);
1360
1361                 busReset();
1362                 break;
1363
1364             case USB_FUNCTION_DS_ADDS:
1365                 break;
1366
1367             case USB_FUNCTION_DS_CNFG:
1368                 break;
1369
1370             case USB_FUNCTION_DS_SPD_POWR:
1371             case USB_FUNCTION_DS_SPD_DFLT:
1372             case USB_FUNCTION_DS_SPD_ADDR:
1373             case USB_FUNCTION_DS_SPD_CNFG:
1374                 suspendStateChanged(0);
1375                 /*usbx_function_USB_FUNCTION_Suspend();*/
1376                 break;
1377
1378             default:
1379                 break;
1380         }
1381     } else if (
1382         (int_sts0 & USB_FUNCTION_BITBEMP) &&
1383         (int_enb0 & USB_FUNCTION_BITBEMP) &&
1384         ((int_sts3 & int_enb4) & g_usbx_function_bit_set[USB_FUNCTION_PIPE0])) {
1385         /* ==== BEMP PIPE0 ==== */
1386         usbx_function_BEMPInterruptPIPE0(int_sts3, int_enb4, this, &USBHAL::EP0in);
1387     } else if (
1388         (int_sts0 & USB_FUNCTION_BITBRDY) &&
1389         (int_enb0 & USB_FUNCTION_BITBRDY) &&
1390         ((int_sts1 & int_enb2) & g_usbx_function_bit_set[USB_FUNCTION_PIPE0])) {
1391         /* ==== BRDY PIPE0 ==== */
1392         usbx_function_BRDYInterruptPIPE0(int_sts1, int_enb2, this, &USBHAL::EP0out);
1393     } else if (
1394         (int_sts0 & USB_FUNCTION_BITNRDY) &&
1395         (int_enb0 & USB_FUNCTION_BITNRDY) &&
1396         ((int_sts2 & int_enb3) & g_usbx_function_bit_set[USB_FUNCTION_PIPE0])) {
1397         /* ==== NRDY PIPE0 ==== */
1398         usbx_function_NRDYInterruptPIPE0(int_sts2, int_enb3, this, NULL);
1399     } else if (
1400         (int_sts0 & USB_FUNCTION_BITCTRT) && (int_enb0 & USB_FUNCTION_BITCTRE)) {
1401         int_sts0 = USB20X.INTSTS0;
1402         USB20X.INTSTS0 = (uint16_t)~USB_FUNCTION_BITCTRT;
1403
1404         if (((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_RDDS) ||
1405                 ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_WRDS) ||
1406                 ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_WRND)) {
1407
1408             /* remake EP0 into buffer */
1409             usbx_function_save_request();
1410             if ((USB20X.INTSTS0 & USB_FUNCTION_BITVALID) && (
1411                         ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_RDDS) ||
1412                         ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_WRDS) ||
1413                         ((int_sts0 & USB_FUNCTION_BITCTSQ) == USB_FUNCTION_CS_WRND))) {
1414                 /* New SETUP token received */
1415                 /* Three dummy reads for cleearing interrupt requests */
1416                 dumy_sts = USB20X.INTSTS0;
1417                 dumy_sts = USB20X.INTSTS0;
1418                 dumy_sts = USB20X.INTSTS0;
1419                 return;
1420             }
1421         }
1422
1423         switch (int_sts0 & USB_FUNCTION_BITCTSQ) {
1424             case USB_FUNCTION_CS_IDST:
1425                 if (g_usbx_function_TestModeFlag == DEVDRV_USBF_YES) {
1426                     /* ==== Test Mode ==== */
1427                     usbx_function_USB_FUNCTION_TestMode();
1428                 }
1429                 /* Needs not procedure in this state */
1430                 break;
1431
1432             case USB_FUNCTION_CS_RDDS:
1433                 /* Reads a setup packet */
1434                 EP0setupCallback();
1435                 break;
1436
1437             case USB_FUNCTION_CS_WRDS:
1438                 /* Original code was the SetDescriptor was called */
1439                 EP0setupCallback();
1440                 break;
1441
1442             case USB_FUNCTION_CS_WRND:
1443                 EP0setupCallback();
1444
1445                 /*The EP0setupCallback should finish in successful */
1446                 usbx_function_set_pid_buf(USB_FUNCTION_PIPE0);
1447
1448                 RZA_IO_RegWrite_16(&USB20X.DCPCTR, 1, USB_DCPCTR_CCPL_SHIFT, USB_DCPCTR_CCPL);
1449                 break;
1450
1451             case USB_FUNCTION_CS_RDSS:
1452                 RZA_IO_RegWrite_16(&USB20X.DCPCTR, 1, USB_DCPCTR_CCPL_SHIFT, USB_DCPCTR_CCPL);
1453                 break;
1454
1455             case USB_FUNCTION_CS_WRSS:
1456                 RZA_IO_RegWrite_16(&USB20X.DCPCTR, 1, USB_DCPCTR_CCPL_SHIFT, USB_DCPCTR_CCPL);
1457                 break;
1458
1459             case USB_FUNCTION_CS_SQER:
1460                 usbx_function_set_pid_stall(USB_FUNCTION_PIPE0);
1461                 break;
1462
1463             default:
1464                 usbx_function_set_pid_stall(USB_FUNCTION_PIPE0);
1465                 break;
1466         }
1467     } else if (
1468         (int_sts0 & USB_FUNCTION_BITBEMP) &&
1469         (int_enb0 & USB_FUNCTION_BITBEMP) &&
1470         (int_sts3 & int_enb4) ) {
1471         /* ==== BEMP PIPEx ==== */
1472         usbx_function_BEMPInterrupt(int_sts3, int_enb4, this, epCallback);
1473     } else if (
1474         (int_sts0 & USB_FUNCTION_BITBRDY) &&
1475         (int_enb0 & USB_FUNCTION_BITBRDY) &&
1476         (int_sts1 & int_enb2) ) {
1477         /* ==== BRDY PIPEx ==== */
1478         usbx_function_BRDYInterrupt(int_sts1, int_enb2, this, epCallback);
1479     } else if (
1480         (int_sts0 & USB_FUNCTION_BITNRDY) &&
1481         (int_enb0 & USB_FUNCTION_BITNRDY) &&
1482         (int_sts2 & int_enb3)) {
1483         /* ==== NRDY PIPEx ==== */
1484         usbx_function_NRDYInterrupt(int_sts2, int_enb3, this, epCallback);
1485     } else {
1486         /* Do Nothing */
1487     }
1488
1489     /* Three dummy reads for cleearing interrupt requests */
1490     dumy_sts = USB20X.INTSTS0;
1491     dumy_sts = USB20X.INTSTS1;
1492 }
1493
1494 /*************************************************************************/
1495 #endif
1496 /*************************************************************************/
1497 /*EOF*/