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