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