]> git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/USBDevice/USBDevice/USBHAL_RZ_A1H.cpp
remove experimental return, cleanup slash_question key
[tmk_keyboard.git] / tmk_core / 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*/
Imprint / Impressum