Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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) 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 Tue Jul 12 2022 14:14:02 by
