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.
usbd_kinetis.c
00001 /** 00002 * @file usbd_kinetis.c 00003 * @brief 00004 * 00005 * DAPLink Interface Firmware 00006 * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved 00007 * SPDX-License-Identifier: Apache-2.0 00008 * 00009 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00010 * not use this file except in compliance with the License. 00011 * You may obtain a copy of the License at 00012 * 00013 * http://www.apache.org/licenses/LICENSE-2.0 00014 * 00015 * Unless required by applicable law or agreed to in writing, software 00016 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00017 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00018 * See the License for the specific language governing permissions and 00019 * limitations under the License. 00020 */ 00021 00022 #include "rl_usb.h" 00023 #include "fsl_device_registers.h" 00024 #include "cortex_m.h" 00025 #include "util.h" 00026 #include "string.h" 00027 00028 #define __NO_USB_LIB_C 00029 #include "usb_config.c" 00030 00031 typedef struct __BUF_DESC { 00032 uint8_t stat; 00033 uint8_t reserved; 00034 uint16_t bc; 00035 uint32_t buf_addr; 00036 } BUF_DESC; 00037 00038 BUF_DESC __align(512) BD[(USBD_EP_NUM + 1) * 2 * 2]; 00039 uint8_t EPBuf[(USBD_EP_NUM + 1) * 2 * 2][64]; 00040 uint8_t OutEpSize[USBD_EP_NUM + 1]; 00041 uint8_t StatQueue[(USBD_EP_NUM + 1) * 2 * 2 + 1]; 00042 uint32_t StatQueueHead = 0; 00043 uint32_t StatQueueTail = 0; 00044 uint32_t LastIstat = 0; 00045 uint8_t UsbSuspended = 0; 00046 uint8_t Ep0ZlpOut = 0; 00047 00048 uint32_t Data1 = 0x55555555; 00049 00050 #define BD_OWN_MASK 0x80 00051 #define BD_DATA01_MASK 0x40 00052 #define BD_KEEP_MASK 0x20 00053 #define BD_NINC_MASK 0x10 00054 #define BD_DTS_MASK 0x08 00055 #define BD_STALL_MASK 0x04 00056 00057 #define TX 1 00058 #define RX 0 00059 #define ODD 0 00060 #define EVEN 1 00061 #define IDX(Ep, dir, Ev_Odd) ((((Ep & 0x0F) * 4) + (2 * dir) + (1 * Ev_Odd))) 00062 00063 #define SETUP_TOKEN 0x0D 00064 #define IN_TOKEN 0x09 00065 #define OUT_TOKEN 0x01 00066 #define TOK_PID(idx) ((BD[idx].stat >> 2) & 0x0F) 00067 00068 inline static void protected_and(uint32_t *addr, uint32_t val) 00069 { 00070 cortex_int_state_t state; 00071 state = cortex_int_get_and_disable(); 00072 *addr = *addr & val; 00073 cortex_int_restore(state); 00074 } 00075 inline static void protected_or(uint32_t *addr, uint32_t val) 00076 { 00077 cortex_int_state_t state; 00078 state = cortex_int_get_and_disable(); 00079 *addr = *addr | val; 00080 cortex_int_restore(state); 00081 } 00082 inline static void protected_xor(uint32_t *addr, uint32_t val) 00083 { 00084 cortex_int_state_t state; 00085 state = cortex_int_get_and_disable(); 00086 *addr = *addr ^ val; 00087 cortex_int_restore(state); 00088 } 00089 00090 inline static void stat_enque(uint32_t stat) 00091 { 00092 cortex_int_state_t state; 00093 state = cortex_int_get_and_disable(); 00094 StatQueue[StatQueueTail] = stat; 00095 StatQueueTail = (StatQueueTail + 1) % sizeof(StatQueue); 00096 cortex_int_restore(state); 00097 } 00098 00099 inline static uint32_t stat_deque() 00100 { 00101 cortex_int_state_t state; 00102 uint32_t stat; 00103 state = cortex_int_get_and_disable(); 00104 stat = StatQueue[StatQueueHead]; 00105 StatQueueHead = (StatQueueHead + 1) % sizeof(StatQueue); 00106 cortex_int_restore(state); 00107 00108 return stat; 00109 } 00110 00111 inline static uint32_t stat_is_empty() 00112 { 00113 cortex_int_state_t state; 00114 uint32_t empty; 00115 state = cortex_int_get_and_disable(); 00116 empty = StatQueueHead == StatQueueTail; 00117 cortex_int_restore(state); 00118 return empty; 00119 } 00120 00121 /* 00122 * USB Device Interrupt enable 00123 * Called by USBD_Init to enable the USB Interrupt 00124 * Return Value: None 00125 */ 00126 00127 void USBD_IntrEna(void) 00128 { 00129 NVIC_EnableIRQ(USB0_IRQn); /* Enable OTG interrupt */ 00130 } 00131 00132 00133 /* 00134 * USB Device Initialize Function 00135 * Called by the User to initialize USB 00136 * Return Value: None 00137 */ 00138 00139 void USBD_Init(void) 00140 { 00141 OutEpSize[0] = USBD_MAX_PACKET0; 00142 /* Enable all clocks needed for USB to function */ 00143 /* Set USB clock to 48 MHz */ 00144 SIM->SOPT2 |= SIM_SOPT2_USBSRC_MASK | /* MCGPLLCLK used as src */ 00145 SIM_SOPT2_PLLFLLSEL_MASK ; /* Select MCGPLLCLK as clock */ 00146 #if defined(TARGET_MK20D5) 00147 SIM->CLKDIV2 &= ~(SIM_CLKDIV2_USBFRAC_MASK | /* Clear CLKDIV2 FS values */ 00148 SIM_CLKDIV2_USBDIV_MASK); 00149 SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(0) ; /* USB clk = (PLL*1/2) */ 00150 /* = ( 48*1/1)=48 */ 00151 #endif // TARGET_MK20D5 00152 SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK; /* Enable USBOTG clock */ 00153 USBD_IntrEna(); 00154 USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; 00155 00156 while (USB0->USBTRC0 & USB_USBTRC0_USBRESET_MASK); 00157 00158 USB0->BDTPAGE1 = (uint8_t)((uint32_t) BD >> 8); 00159 USB0->BDTPAGE2 = (uint8_t)((uint32_t) BD >> 16); 00160 USB0->BDTPAGE3 = (uint8_t)((uint32_t) BD >> 24); 00161 USB0->ISTAT = 0xFF; /* clear interrupt flags */ 00162 /* enable interrupts */ 00163 USB0->INTEN = USB_INTEN_USBRSTEN_MASK | 00164 USB_INTEN_TOKDNEEN_MASK | 00165 USB_INTEN_SLEEPEN_MASK | 00166 #ifdef __RTX 00167 ((USBD_RTX_DevTask != 0) ? USB_INTEN_SOFTOKEN_MASK : 0) | 00168 ((USBD_RTX_DevTask != 0) ? USB_INTEN_ERROREN_MASK : 0) ; 00169 #else 00170 ((USBD_P_SOF_Event != 0) ? USB_INTEN_SOFTOKEN_MASK : 0) | 00171 ((USBD_P_Error_Event != 0) ? USB_INTEN_ERROREN_MASK : 0) ; 00172 #endif 00173 USB0->USBCTRL = USB_USBCTRL_PDE_MASK;/* pull dawn on D+ and D- */ 00174 USB0->USBTRC0 |= (1 << 6); /* bit 6 must be set to 1 */ 00175 } 00176 00177 00178 /* 00179 * USB Device Connect Function 00180 * Called by the User to Connect/Disconnect USB Device 00181 * Parameters: con: Connect/Disconnect 00182 * Return Value: None 00183 */ 00184 00185 void USBD_Connect(uint32_t con) 00186 { 00187 if (con) { 00188 USB0->CTL |= USB_CTL_USBENSOFEN_MASK; /* enable USB */ 00189 USB0->CONTROL = USB_CONTROL_DPPULLUPNONOTG_MASK; /* pull up on D+ */ 00190 } else { 00191 USB0->CTL &= ~USB_CTL_USBENSOFEN_MASK; /* disable USB */ 00192 USB0->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;/* pull down on D+ */ 00193 } 00194 } 00195 00196 00197 /* 00198 * USB Device Reset Function 00199 * Called automatically on USB Device Reset 00200 * Return Value: None 00201 */ 00202 00203 void USBD_Reset(void) 00204 { 00205 uint32_t i; 00206 00207 NVIC_DisableIRQ(USB0_IRQn); 00208 00209 for (i = 1; i < 16; i++) { 00210 USB0->ENDPOINT[i].ENDPT = 0x00; 00211 } 00212 00213 memset(StatQueue, 0, sizeof(StatQueue)); 00214 StatQueueHead = 0; 00215 StatQueueTail = 0; 00216 LastIstat = 0; 00217 UsbSuspended = 0; 00218 Ep0ZlpOut = 0; 00219 00220 /* EP0 control endpoint */ 00221 BD[IDX(0, RX, ODD)].bc = USBD_MAX_PACKET0; 00222 BD[IDX(0, RX, ODD)].buf_addr = (uint32_t) & (EPBuf[IDX(0, RX, ODD)][0]); 00223 BD[IDX(0, RX, ODD)].stat = BD_OWN_MASK | BD_DTS_MASK | BD_DATA01_MASK; 00224 BD[IDX(0, RX, EVEN)].stat = 0; 00225 BD[IDX(0, TX, ODD)].buf_addr = (uint32_t) & (EPBuf[IDX(0, TX, ODD)][0]); 00226 BD[IDX(0, TX, EVEN)].buf_addr = 0; 00227 USB0->ENDPOINT[0].ENDPT = USB_ENDPT_EPHSHK_MASK | /* enable ep handshaking */ 00228 USB_ENDPT_EPTXEN_MASK | /* enable TX (IN) tran. */ 00229 USB_ENDPT_EPRXEN_MASK; /* enable RX (OUT) tran. */ 00230 Data1 = 0x55555555; 00231 USB0->CTL |= USB_CTL_ODDRST_MASK; 00232 USB0->ISTAT = 0xFF; /* clear all interrupt status flags */ 00233 USB0->ERRSTAT = 0xFF; /* clear all error flags */ 00234 USB0->ERREN = 0xFF; /* enable error interrupt sources */ 00235 USB0->ADDR = 0x00; /* set default address */ 00236 00237 NVIC_EnableIRQ(USB0_IRQn); 00238 } 00239 00240 00241 /* 00242 * USB Device Suspend Function 00243 * Called automatically on USB Device Suspend 00244 * Return Value: None 00245 */ 00246 00247 void USBD_Suspend(void) 00248 { 00249 USB0->INTEN |= USB_INTEN_RESUMEEN_MASK; 00250 } 00251 00252 00253 /* 00254 * USB Device Resume Function 00255 * Called automatically on USB Device Resume 00256 * Return Value: None 00257 */ 00258 00259 void USBD_Resume(void) 00260 { 00261 USB0->INTEN &= ~USB_INTEN_RESUMEEN_MASK; 00262 } 00263 00264 00265 /* 00266 * USB Device Remote Wakeup Function 00267 * Called automatically on USB Device Remote Wakeup 00268 * Return Value: None 00269 */ 00270 00271 void USBD_WakeUp(void) 00272 { 00273 uint32_t i = 50000; 00274 00275 if (USBD_DeviceStatus & USB_GETSTATUS_REMOTE_WAKEUP) { 00276 USB0->CTL |= USB_CTL_RESUME_MASK; 00277 00278 while (i--) { 00279 __nop(); 00280 } 00281 00282 USB0->CTL &= ~USB_CTL_RESUME_MASK; 00283 } 00284 } 00285 00286 00287 /* 00288 * USB Device Remote Wakeup Configuration Function 00289 * Parameters: cfg: Device Enable/Disable 00290 * Return Value: None 00291 */ 00292 00293 void USBD_WakeUpCfg(uint32_t cfg) 00294 { 00295 /* Not needed */ 00296 } 00297 00298 00299 /* 00300 * USB Device Set Address Function 00301 * Parameters: adr: USB Device Address 00302 * Return Value: None 00303 */ 00304 00305 void USBD_SetAddress(uint32_t adr, uint32_t setup) 00306 { 00307 if (!setup) { 00308 USB0->ADDR = adr & 0x7F; 00309 } 00310 } 00311 00312 00313 /* 00314 * USB Device Configure Function 00315 * Parameters: cfg: Device Configure/Deconfigure 00316 * Return Value: None 00317 */ 00318 00319 void USBD_Configure(uint32_t cfg) 00320 { 00321 } 00322 00323 00324 /* 00325 * Configure USB Device Endpoint according to Descriptor 00326 * Parameters: pEPD: Pointer to Device Endpoint Descriptor 00327 * Return Value: None 00328 */ 00329 00330 void USBD_ConfigEP(USB_ENDPOINT_DESCRIPTOR *pEPD) 00331 { 00332 uint32_t num, val; 00333 num = pEPD->bEndpointAddress; 00334 val = pEPD->wMaxPacketSize; 00335 00336 if (!(pEPD->bEndpointAddress & 0x80)) { 00337 OutEpSize[num] = val; 00338 } 00339 00340 USBD_ResetEP(num); 00341 } 00342 00343 00344 /* 00345 * Set Direction for USB Device Control Endpoint 00346 * Parameters: dir: Out (dir == 0), In (dir <> 0) 00347 * Return Value: None 00348 */ 00349 00350 void USBD_DirCtrlEP(uint32_t dir) 00351 { 00352 /* Not needed */ 00353 } 00354 00355 00356 /* 00357 * Enable USB Device Endpoint 00358 * Parameters: EPNum: Device Endpoint Number 00359 * EPNum.0..3: Address 00360 * EPNum.7: Dir 00361 * Return Value: None 00362 */ 00363 00364 void USBD_EnableEP(uint32_t EPNum) 00365 { 00366 if (EPNum & 0x80) { 00367 EPNum &= 0x0F; 00368 USB0->ENDPOINT[EPNum].ENDPT |= USB_ENDPT_EPHSHK_MASK | /*en ep handshaking*/ 00369 USB_ENDPT_EPTXEN_MASK; /*en TX (IN) tran */ 00370 } else { 00371 USB0->ENDPOINT[EPNum].ENDPT |= USB_ENDPT_EPHSHK_MASK | /*en ep handshaking*/ 00372 USB_ENDPT_EPRXEN_MASK; /*en RX (OUT) tran.*/ 00373 } 00374 } 00375 00376 00377 /* 00378 * Disable USB Endpoint 00379 * Parameters: EPNum: Endpoint Number 00380 * EPNum.0..3: Address 00381 * EPNum.7: Dir 00382 * Return Value: None 00383 */ 00384 00385 void USBD_DisableEP(uint32_t EPNum) 00386 { 00387 if (EPNum & 0x80) { 00388 EPNum &= 0x0F; 00389 USB0->ENDPOINT[EPNum].ENDPT &= ~(USB_ENDPT_EPHSHK_MASK |/*dis handshaking */ 00390 USB_ENDPT_EPTXEN_MASK);/*dis TX(IN) tran */ 00391 } else { 00392 USB0->ENDPOINT[EPNum].ENDPT &= ~(USB_ENDPT_EPHSHK_MASK |/*dis handshaking */ 00393 USB_ENDPT_EPRXEN_MASK);/*dis RX(OUT) tran*/ 00394 } 00395 } 00396 00397 00398 /* 00399 * Reset USB Device Endpoint 00400 * Parameters: EPNum: Device Endpoint Number 00401 * EPNum.0..3: Address 00402 * EPNum.7: Dir 00403 * Return Value: None 00404 */ 00405 00406 void USBD_ResetEP(uint32_t EPNum) 00407 { 00408 if (EPNum & 0x80) { 00409 EPNum &= 0x0F; 00410 protected_or(&Data1, (1 << ((EPNum * 2) + 1))); 00411 BD[IDX(EPNum, TX, ODD)].buf_addr = (uint32_t) & (EPBuf[IDX(EPNum, TX, ODD)][0]); 00412 BD[IDX(EPNum, TX, EVEN)].buf_addr = 0; 00413 } else { 00414 protected_and(&Data1, ~(1 << (EPNum * 2))); 00415 BD[IDX(EPNum, RX, ODD)].bc = OutEpSize[EPNum]; 00416 BD[IDX(EPNum, RX, ODD)].buf_addr = (uint32_t) & (EPBuf[IDX(EPNum, RX, ODD)][0]); 00417 BD[IDX(EPNum, RX, ODD)].stat = BD_OWN_MASK | BD_DTS_MASK; 00418 BD[IDX(EPNum, RX, EVEN)].stat = 0; 00419 } 00420 } 00421 00422 /* 00423 * Set Stall for USB Device Endpoint 00424 * Parameters: EPNum: Device Endpoint Number 00425 * EPNum.0..3: Address 00426 * EPNum.7: Dir 00427 * Return Value: None 00428 */ 00429 00430 void USBD_SetStallEP(uint32_t EPNum) 00431 { 00432 EPNum &= 0x0F; 00433 USB0->ENDPOINT[EPNum].ENDPT |= USB_ENDPT_EPSTALL_MASK; 00434 } 00435 00436 00437 /* 00438 * Clear Stall for USB Device Endpoint 00439 * Parameters: EPNum: Device Endpoint Number 00440 * EPNum.0..3: Address 00441 * EPNum.7: Dir 00442 * Return Value: None 00443 */ 00444 00445 void USBD_ClrStallEP(uint32_t EPNum) 00446 { 00447 USB0->ENDPOINT[EPNum & 0x0F].ENDPT &= ~USB_ENDPT_EPSTALL_MASK; 00448 USBD_ResetEP(EPNum); 00449 } 00450 00451 00452 /* 00453 * Clear USB Device Endpoint Buffer 00454 * Parameters: EPNum: Device Endpoint Number 00455 * EPNum.0..3: Address 00456 * EPNum.7: Dir 00457 * Return Value: None 00458 */ 00459 00460 void USBD_ClearEPBuf(uint32_t EPNum) 00461 { 00462 } 00463 00464 00465 /* 00466 * Read USB Device Endpoint Data 00467 * Parameters: EPNum: Device Endpoint Number 00468 * EPNum.0..3: Address 00469 * EPNum.7: Dir 00470 * pData: Pointer to Data Buffer 00471 * Return Value: Number of bytes read 00472 */ 00473 00474 uint32_t USBD_ReadEP(uint32_t EPNum, uint8_t *pData, uint32_t size) 00475 { 00476 uint32_t n, sz, idx, setup = 0; 00477 idx = IDX(EPNum, RX, 0); 00478 sz = BD[idx].bc; 00479 00480 if ((EPNum == 0) && Ep0ZlpOut) { 00481 // This packet was a zero length data out packet. It has already 00482 // been processed by USB0_IRQHandler. Only toggle the DATAx bit 00483 // and return a size of 0. 00484 protected_xor(&Data1, (1 << (idx / 2))); 00485 return 0; 00486 } 00487 00488 if ((EPNum == 0) && (TOK_PID(idx) == SETUP_TOKEN)) { 00489 setup = 1; 00490 } 00491 00492 if (size < sz) { 00493 util_assert(0); 00494 sz = size; 00495 } 00496 00497 for (n = 0; n < sz; n++) { 00498 pData[n] = EPBuf[idx][n]; 00499 } 00500 00501 BD[idx].bc = OutEpSize[EPNum]; 00502 00503 if ((Data1 >> (idx / 2) & 1) == ((BD[idx].stat >> 6) & 1)) { 00504 uint32_t xfer_size = (pData[7] << 8) | (pData[6] << 0); 00505 if (setup && (0 == xfer_size)) { /* if no setup data stage, */ 00506 protected_and(&Data1, ~1); /* set DATA0 */ 00507 } else { 00508 protected_xor(&Data1, (1 << (idx / 2))); 00509 } 00510 } 00511 00512 if ((Data1 >> (idx / 2)) & 1) { 00513 BD[idx].stat = BD_DTS_MASK | BD_DATA01_MASK; 00514 BD[idx].stat |= BD_OWN_MASK; 00515 } else { 00516 BD[idx].stat = BD_DTS_MASK; 00517 BD[idx].stat |= BD_OWN_MASK; 00518 } 00519 00520 return (sz); 00521 } 00522 00523 00524 /* 00525 * Write USB Device Endpoint Data 00526 * Parameters: EPNum: Device Endpoint Number 00527 * EPNum.0..3: Address 00528 * EPNum.7: Dir 00529 * pData: Pointer to Data Buffer 00530 * cnt: Number of bytes to write 00531 * Return Value: Number of bytes written 00532 */ 00533 00534 uint32_t USBD_WriteEP(uint32_t EPNum, uint8_t *pData, uint32_t cnt) 00535 { 00536 uint32_t idx, n; 00537 EPNum &= 0x0F; 00538 idx = IDX(EPNum, TX, 0); 00539 BD[idx].bc = cnt; 00540 00541 for (n = 0; n < cnt; n++) { 00542 EPBuf[idx][n] = pData[n]; 00543 } 00544 00545 if ((Data1 >> (idx / 2)) & 1) { 00546 BD[idx].stat = BD_OWN_MASK | BD_DTS_MASK; 00547 } else { 00548 BD[idx].stat = BD_OWN_MASK | BD_DTS_MASK | BD_DATA01_MASK; 00549 } 00550 00551 protected_xor(&Data1, (1 << (idx / 2))); 00552 return (cnt); 00553 } 00554 00555 /* 00556 * Get USB Device Last Frame Number 00557 * Parameters: None 00558 * Return Value: Frame Number 00559 */ 00560 00561 uint32_t USBD_GetFrame(void) 00562 { 00563 return ((USB0->FRMNUML | (USB0->FRMNUMH << 8) & 0x07FF)); 00564 } 00565 00566 #ifdef __RTX 00567 U32 LastError; /* Last Error */ 00568 00569 /* 00570 * Get USB Device Last Error Code 00571 * Parameters: None 00572 * Return Value: Error Code 00573 */ 00574 00575 U32 USBD_GetError(void) 00576 { 00577 return (LastError); 00578 } 00579 #endif 00580 00581 00582 /* 00583 * USB Device Interrupt Service Routine 00584 */ 00585 void USB0_IRQHandler(void) 00586 { 00587 uint32_t istat, num, dir, ev_odd; 00588 uint32_t new_istat; 00589 uint8_t suspended = 0; 00590 00591 new_istat = istat = USB0->ISTAT; 00592 00593 // Read all tokens 00594 if (istat & USB_ISTAT_TOKDNE_MASK) { 00595 while (istat & USB_ISTAT_TOKDNE_MASK) { 00596 uint8_t stat = USB0->STAT; 00597 num = (stat >> 4) & 0x0F; 00598 dir = (stat >> 3) & 0x01; 00599 ev_odd = (stat >> 2) & 0x01; 00600 00601 // Consume all zero length OUT packets on endpoint 0 to prevent 00602 // a subsequent SETUP packet from being dropped 00603 if ((0 == num) && (RX == dir)) { 00604 uint32_t idx; 00605 idx = IDX(num, dir, ev_odd); 00606 if ((TOK_PID(idx) == OUT_TOKEN) && (BD[idx].bc == 0)) { 00607 BD[idx].bc = OutEpSize[num]; 00608 if (BD[idx].stat & BD_DATA01_MASK) { 00609 BD[idx].stat = BD_OWN_MASK | BD_DTS_MASK; 00610 } else { 00611 BD[idx].stat = BD_OWN_MASK | BD_DTS_MASK | BD_DATA01_MASK; 00612 } 00613 stat |= 1 << 0; 00614 } 00615 } 00616 00617 stat_enque(stat); 00618 USB0->ISTAT = USB_ISTAT_TOKDNE_MASK; 00619 00620 // Check if USB is suspending before checking istat 00621 suspended = suspended || USB0->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK; 00622 istat = USB0->ISTAT; 00623 } 00624 } 00625 00626 // Set global istat and suspended flags 00627 new_istat |= istat; 00628 protected_or(&LastIstat, new_istat); 00629 UsbSuspended |= suspended ? 1 : 0; 00630 USB0->ISTAT = istat; 00631 00632 USBD_SignalHandler(); 00633 } 00634 00635 /* 00636 * USB Device Service Routine 00637 */ 00638 00639 void USBD_Handler(void) 00640 { 00641 uint32_t istr, num, dir, ev_odd; 00642 cortex_int_state_t state; 00643 uint8_t suspended = 0; 00644 00645 // Get ISTAT 00646 state = cortex_int_get_and_disable(); 00647 istr = LastIstat; 00648 LastIstat = 0; 00649 suspended = UsbSuspended; 00650 UsbSuspended = 0; 00651 cortex_int_restore(state); 00652 00653 00654 /* reset interrupt */ 00655 if (istr & USB_ISTAT_USBRST_MASK) { 00656 USBD_Reset(); 00657 usbd_reset_core(); 00658 #ifdef __RTX 00659 00660 if (USBD_RTX_DevTask) { 00661 isr_evt_set(USBD_EVT_RESET, USBD_RTX_DevTask); 00662 } 00663 00664 #else 00665 00666 if (USBD_P_Reset_Event) { 00667 USBD_P_Reset_Event(); 00668 } 00669 00670 #endif 00671 } 00672 00673 /* suspend interrupt */ 00674 if (istr & USB_ISTAT_SLEEP_MASK) { 00675 USBD_Suspend(); 00676 #ifdef __RTX 00677 00678 if (USBD_RTX_DevTask) { 00679 isr_evt_set(USBD_EVT_SUSPEND, USBD_RTX_DevTask); 00680 } 00681 00682 #else 00683 00684 if (USBD_P_Suspend_Event) { 00685 USBD_P_Suspend_Event(); 00686 } 00687 00688 #endif 00689 } 00690 00691 /* resume interrupt */ 00692 if (istr & USB_ISTAT_RESUME_MASK) { 00693 USBD_Resume(); 00694 #ifdef __RTX 00695 00696 if (USBD_RTX_DevTask) { 00697 isr_evt_set(USBD_EVT_RESUME, USBD_RTX_DevTask); 00698 } 00699 00700 #else 00701 00702 if (USBD_P_Resume_Event) { 00703 USBD_P_Resume_Event(); 00704 } 00705 00706 #endif 00707 } 00708 00709 /* Start Of Frame */ 00710 if (istr & USB_ISTAT_SOFTOK_MASK) { 00711 #ifdef __RTX 00712 00713 if (USBD_RTX_DevTask) { 00714 isr_evt_set(USBD_EVT_SOF, USBD_RTX_DevTask); 00715 } 00716 00717 #else 00718 00719 if (USBD_P_SOF_Event) { 00720 USBD_P_SOF_Event(); 00721 } 00722 00723 #endif 00724 } 00725 00726 /* Error interrupt */ 00727 if (istr == USB_ISTAT_ERROR_MASK) { 00728 #ifdef __RTX 00729 LastError = USB0->ERRSTAT; 00730 00731 if (USBD_RTX_DevTask) { 00732 isr_evt_set(USBD_EVT_ERROR, USBD_RTX_DevTask); 00733 } 00734 00735 #else 00736 00737 if (USBD_P_Error_Event) { 00738 USBD_P_Error_Event(USB0->ERRSTAT); 00739 } 00740 00741 #endif 00742 USB0->ERRSTAT = 0xFF; 00743 } 00744 00745 /* token interrupt */ 00746 if (istr & USB_ISTAT_TOKDNE_MASK) { 00747 while (!stat_is_empty()) { 00748 uint32_t stat; 00749 00750 stat = stat_deque(); 00751 num = (stat >> 4) & 0x0F; 00752 dir = (stat >> 3) & 0x01; 00753 ev_odd = (stat >> 2) & 0x01; 00754 00755 /* setup packet */ 00756 if ((num == 0) && (TOK_PID((IDX(num, dir, ev_odd))) == SETUP_TOKEN)) { 00757 Data1 &= ~0x02; 00758 BD[IDX(0, TX, EVEN)].stat &= ~BD_OWN_MASK; 00759 BD[IDX(0, TX, ODD)].stat &= ~BD_OWN_MASK; 00760 Ep0ZlpOut = 0; 00761 #ifdef __RTX 00762 00763 if (USBD_RTX_EPTask[num]) { 00764 isr_evt_set(USBD_EVT_SETUP, USBD_RTX_EPTask[num]); 00765 } 00766 00767 #else 00768 00769 if (USBD_P_EP[num]) { 00770 USBD_P_EP[num](USBD_EVT_SETUP); 00771 } 00772 00773 #endif 00774 00775 } else { 00776 /* OUT packet */ 00777 if (TOK_PID((IDX(num, dir, ev_odd))) == OUT_TOKEN) { 00778 if (0 == num) { 00779 Ep0ZlpOut = stat & (1 << 0); 00780 } 00781 #ifdef __RTX 00782 00783 if (USBD_RTX_EPTask[num]) { 00784 isr_evt_set(USBD_EVT_OUT, USBD_RTX_EPTask[num]); 00785 } 00786 00787 #else 00788 00789 if (USBD_P_EP[num]) { 00790 USBD_P_EP[num](USBD_EVT_OUT); 00791 } 00792 00793 #endif 00794 } 00795 00796 /* IN packet */ 00797 if (TOK_PID((IDX(num, dir, ev_odd))) == IN_TOKEN) { 00798 #ifdef __RTX 00799 00800 if (USBD_RTX_EPTask[num]) { 00801 isr_evt_set(USBD_EVT_IN, USBD_RTX_EPTask[num]); 00802 } 00803 00804 #else 00805 00806 if (USBD_P_EP[num]) { 00807 USBD_P_EP[num](USBD_EVT_IN); 00808 } 00809 00810 #endif 00811 } 00812 } 00813 } 00814 } 00815 00816 if (suspended) { 00817 USB0->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; 00818 } 00819 }
Generated on Tue Jul 12 2022 15:37:26 by
1.7.2