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_LPC11Uxx.c
00001 /** 00002 * @file usbd_LPC11Uxx.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 "LPC11Uxx.h" 00024 #include "compiler.h" 00025 #include "util.h" 00026 00027 #define __NO_USB_LIB_C 00028 #include "usb_config.c" 00029 00030 00031 #define BUF_ACTIVE (1UL << 31) 00032 #define EP_DISABLED (1UL << 30) 00033 #define EP_STALL (1UL << 29) 00034 #define TOOGLE_RESET (1UL << 28) 00035 #define EP_TYPE (1UL << 26) 00036 00037 #define N_BYTES(n) ((n & 0x3FF) << 16) 00038 #define BUF_ADDR(addr) (((addr) >> 6) & 0xFFFF) 00039 00040 #define EP_OUT_IDX(EPNum) (EPNum * 2 ) 00041 #define EP_IN_IDX(EPNum) (EPNum * 2 + 1) 00042 00043 #define EP_LIST_BASE 0x20004000 00044 #define EP_BUF_BASE (U32)(EP_LIST_BASE + 0x100) 00045 00046 typedef struct BUF_INFO { 00047 U32 buf_len; 00048 U32 buf_ptr; 00049 } EP_BUF_INFO; 00050 00051 EP_BUF_INFO EPBufInfo[(USBD_EP_NUM + 1) * 2]; 00052 volatile U32 EPList[(USBD_EP_NUM + 1) * 2] __at(EP_LIST_BASE); 00053 00054 static U32 addr = 3 * 64 + EP_BUF_BASE; 00055 static U32 ctrl_out_next = 0; 00056 00057 /* 00058 * Get EP CmdStat pointer 00059 * Parameters: EPNum: endpoint number 00060 * 00061 */ 00062 00063 U32 *GetEpCmdStatPtr(U32 EPNum) 00064 { 00065 U32 ptr = 0; 00066 00067 if (EPNum & 0x80) { 00068 EPNum &= ~0x80; 00069 ptr = 8; 00070 } 00071 00072 ptr += EP_LIST_BASE + EPNum * 16; 00073 return ((U32 *)ptr); 00074 } 00075 00076 00077 /* 00078 * Usb interrupt enable/disable 00079 * Parameters: ena: enable/disable 00080 * 0: disable interrupt 00081 * 1: enable interrupt 00082 */ 00083 00084 #ifdef __RTX 00085 void __svc(1) USBD_Intr(int ena); 00086 void __SVC_1(int ena) 00087 { 00088 if (ena) { 00089 NVIC_EnableIRQ(USB_IRQn ); /* Enable USB interrupt */ 00090 } else { 00091 NVIC_DisableIRQ(USB_IRQn ); /* Disable USB interrupt */ 00092 } 00093 } 00094 #endif 00095 00096 00097 00098 /* 00099 * USB Device Initialize Function 00100 * Called by the User to initialize USB Device 00101 * Return Value: None 00102 */ 00103 00104 void USBD_Init(void) 00105 { 00106 LPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 6); 00107 LPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 14) | 00108 (1UL << 27); 00109 LPC_USB->DEVCMDSTAT |= (1UL << 9); /* PLL ON */ 00110 LPC_IOCON->PIO0_3 &= ~(0x1F); 00111 LPC_IOCON->PIO0_3 |= (1UL << 0); /* Secondary function VBUS */ 00112 LPC_IOCON->PIO0_6 &= ~7; 00113 LPC_IOCON->PIO0_6 |= (1UL << 0); /* Secondary function USB CON */ 00114 LPC_SYSCON->PDRUNCFG &= ~((1UL << 8) | /* USB PLL powered */ 00115 (1UL << 10)); /* USB transceiver powered */ 00116 LPC_USB->DATABUFSTART = EP_BUF_BASE & 0xFFC00000; 00117 LPC_USB->EPLISTSTART = EP_LIST_BASE; 00118 NVIC_EnableIRQ(USB_IRQn ); 00119 USBD_Reset(); 00120 } 00121 00122 00123 /* 00124 * USB Device Connect Function 00125 * Called by the User to Connect/Disconnect USB Device 00126 * Parameters: con: Connect/Disconnect 00127 * Return Value: None 00128 */ 00129 00130 void USBD_Connect(BOOL con) 00131 { 00132 if (con) { 00133 LPC_USB->DEVCMDSTAT |= (1UL << 16); /* Set device connect status */ 00134 } else { 00135 LPC_USB->DEVCMDSTAT &= ~(1UL << 16); /* Clear device connect status */ 00136 } 00137 00138 return; 00139 } 00140 00141 00142 /* 00143 * USB Device Reset Function 00144 * Called automatically on USB Device Reset 00145 * Return Value: None 00146 */ 00147 00148 void USBD_Reset(void) 00149 { 00150 U32 i; 00151 U32 *ptr; 00152 addr = 3 * 64 + EP_BUF_BASE; 00153 00154 for (i = 2; i < (5 * 4); i++) { 00155 EPList[i] = (1UL << 30); /* EPs disabled */ 00156 } 00157 00158 ctrl_out_next = 0; 00159 EPBufInfo[0].buf_len = USBD_MAX_PACKET0; 00160 EPBufInfo[0].buf_ptr = EP_BUF_BASE; 00161 EPBufInfo[1].buf_len = USBD_MAX_PACKET0; 00162 EPBufInfo[1].buf_ptr = EP_BUF_BASE + 2 * 64; 00163 ptr = GetEpCmdStatPtr(0); 00164 *ptr = N_BYTES(EPBufInfo[0].buf_len) | /* EP0 OUT */ 00165 BUF_ADDR(EPBufInfo[0].buf_ptr) | 00166 BUF_ACTIVE; 00167 ptr++; 00168 *ptr = BUF_ADDR(EPBufInfo[0].buf_ptr + 64);/* SETUP */ 00169 LPC_USB->DEVCMDSTAT |= (1UL << 7); /*USB device enable */ 00170 LPC_USB->INTSTAT = 0x2FC; /* clear EP interrupt flags */ 00171 LPC_USB->INTEN = ((1UL << 30) | /* SOF intr enable */ 00172 (1UL << 0) | /* EP0 OUT intr enable */ 00173 (1UL << 1) | /* EP0 IN intr enable */ 00174 (1UL << 31)); /* stat change int en */ 00175 } 00176 00177 00178 /* 00179 * USB Device Suspend Function 00180 * Called automatically on USB Device Suspend 00181 * Return Value: None 00182 */ 00183 00184 void USBD_Suspend(void) 00185 { 00186 /* Performed by Hardware */ 00187 } 00188 00189 00190 /* 00191 * USB Device Resume Function 00192 * Called automatically on USB Device Resume 00193 * Return Value: None 00194 */ 00195 00196 void USBD_Resume(void) 00197 { 00198 /* Performed by Hardware */ 00199 } 00200 00201 00202 /* 00203 * USB Device Remote Wakeup Function 00204 * Called automatically on USB Device Remote Wakeup 00205 * Return Value: None 00206 */ 00207 00208 void USBD_WakeUp(void) 00209 { 00210 LPC_SYSCON->USBCLKCTRL = 1; 00211 LPC_USB->DEVCMDSTAT &= ~(1UL << 17); /*clear device suspend status */ 00212 00213 while (LPC_USB->DEVCMDSTAT & (1UL << 17)); 00214 00215 LPC_SYSCON->USBCLKCTRL = 0; 00216 } 00217 00218 00219 /* 00220 * USB Device Remote Wakeup Configuration Function 00221 * Parameters: cfg: Device Enable/Disable 00222 * Return Value: None 00223 */ 00224 00225 void USBD_WakeUpCfg(BOOL cfg) 00226 { 00227 if (cfg == __TRUE) { 00228 LPC_USB->DEVCMDSTAT &= ~(1UL << 9); /*PPL_ON=0, in suspend clk is stoped */ 00229 } else { 00230 LPC_USB->DEVCMDSTAT |= (1UL << 9); /*PPL_ON=1, in suspend clk isnt stoped */ 00231 LPC_SYSCON->USBCLKCTRL = 0; 00232 } 00233 } 00234 00235 00236 /* 00237 * USB Device Set Address Function 00238 * Parameters: adr: USB Device Address 00239 * Return Value: None 00240 */ 00241 00242 void USBD_SetAddress(U32 adr, U32 setup) 00243 { 00244 if (!setup) { 00245 LPC_USB->DEVCMDSTAT &= ~0x7F; 00246 LPC_USB->DEVCMDSTAT |= adr | (1UL << 7); 00247 } 00248 } 00249 00250 00251 00252 /* 00253 * USB Device Configure Function 00254 * Parameters: cfg: Device Configure/Deconfigure 00255 * Return Value: None 00256 */ 00257 00258 void USBD_Configure(BOOL cfg) 00259 { 00260 addr = 3 * 64 + EP_BUF_BASE; 00261 } 00262 00263 00264 /* 00265 * Configure USB Device Endpoint according to Descriptor 00266 * Parameters: pEPD: Pointer to Device Endpoint Descriptor 00267 * Return Value: None 00268 */ 00269 00270 void USBD_ConfigEP(USB_ENDPOINT_DESCRIPTOR *pEPD) 00271 { 00272 U32 num, val, type; 00273 U32 *ptr; 00274 num = pEPD->bEndpointAddress; 00275 val = pEPD->wMaxPacketSize; 00276 type = pEPD->bmAttributes & USB_ENDPOINT_TYPE_MASK; 00277 00278 /* IN EPs */ 00279 if (num & 0x80) { 00280 num &= ~0x80; 00281 EPBufInfo[EP_IN_IDX(num)].buf_len = val; 00282 EPBufInfo[EP_IN_IDX(num)].buf_ptr = addr; 00283 addr += ((val + 63) >> 6) * 64; /* calc new free buffer address */ 00284 ptr = GetEpCmdStatPtr(num | 0x80); 00285 *ptr = EP_DISABLED; 00286 00287 if (type == USB_ENDPOINT_TYPE_ISOCHRONOUS) { 00288 *ptr |= EP_TYPE; 00289 } 00290 } 00291 00292 /* OUT EPs */ 00293 else { 00294 EPBufInfo[EP_OUT_IDX(num)].buf_len = val; 00295 EPBufInfo[EP_OUT_IDX(num)].buf_ptr = addr; 00296 ptr = GetEpCmdStatPtr(num); 00297 *ptr = N_BYTES(EPBufInfo[EP_OUT_IDX(num)].buf_len) | 00298 BUF_ADDR(EPBufInfo[EP_OUT_IDX(num)].buf_ptr) | 00299 EP_DISABLED; 00300 00301 if (type == USB_ENDPOINT_TYPE_ISOCHRONOUS) { 00302 *ptr |= EP_TYPE; 00303 } 00304 00305 addr += ((val + 63) >> 6) * 64; /* calc new free buffer address */ 00306 } 00307 } 00308 00309 00310 /* 00311 * Set Direction for USB Device Control Endpoint 00312 * Parameters: dir: Out (dir == 0), In (dir <> 0) 00313 * Return Value: None 00314 */ 00315 00316 void USBD_DirCtrlEP(U32 dir) 00317 { 00318 /* Not needed */ 00319 } 00320 00321 00322 /* 00323 * Enable USB Device Endpoint 00324 * Parameters: EPNum: Device Endpoint Number 00325 * EPNum.0..3: Address 00326 * EPNum.7: Dir 00327 * Return Value: None 00328 */ 00329 00330 void USBD_EnableEP(U32 EPNum) 00331 { 00332 U32 *ptr;; 00333 ptr = GetEpCmdStatPtr(EPNum); 00334 00335 /* IN EP */ 00336 if (EPNum & 0x80) { 00337 EPNum &= ~0x80; 00338 *ptr &= ~EP_DISABLED; 00339 LPC_USB->INTSTAT = (1 << EP_IN_IDX(EPNum)); 00340 LPC_USB->INTEN |= (1 << EP_IN_IDX(EPNum)); 00341 } 00342 00343 /* OUT EP */ 00344 else { 00345 *ptr &= ~EP_DISABLED; 00346 *ptr |= BUF_ACTIVE; 00347 LPC_USB->INTSTAT = (1 << EP_OUT_IDX(EPNum)); 00348 LPC_USB->INTEN |= (1 << EP_OUT_IDX(EPNum)); 00349 } 00350 } 00351 00352 00353 /* 00354 * Disable USB Device Endpoint 00355 * Parameters: EPNum: Device Endpoint Number 00356 * EPNum.0..3: Address 00357 * EPNum.7: Dir 00358 * Return Value: None 00359 */ 00360 00361 void USBD_DisableEP(U32 EPNum) 00362 { 00363 U32 *ptr; 00364 ptr = GetEpCmdStatPtr(EPNum); 00365 *ptr = EP_DISABLED; 00366 00367 if (EPNum & 0x80) { 00368 EPNum &= ~0x80; 00369 LPC_USB->INTEN &= ~(1 << EP_IN_IDX(EPNum)); 00370 00371 } else { 00372 LPC_USB->INTEN &= ~(1 << EP_OUT_IDX(EPNum)); 00373 } 00374 } 00375 00376 00377 /* 00378 * Reset USB Device Endpoint 00379 * Parameters: EPNum: Device Endpoint Number 00380 * EPNum.0..3: Address 00381 * EPNum.7: Dir 00382 * Return Value: None 00383 */ 00384 00385 void USBD_ResetEP(U32 EPNum) 00386 { 00387 U32 *ptr; 00388 ptr = GetEpCmdStatPtr(EPNum); 00389 *ptr |= TOOGLE_RESET; 00390 } 00391 00392 00393 /* 00394 * Set Stall for USB Device Endpoint 00395 * Parameters: EPNum: Device Endpoint Number 00396 * EPNum.0..3: Address 00397 * EPNum.7: Dir 00398 * Return Value: None 00399 */ 00400 00401 void USBD_SetStallEP(U32 EPNum) 00402 { 00403 U32 *ptr; 00404 ptr = GetEpCmdStatPtr(EPNum); 00405 00406 if (EPNum & 0x7F) { 00407 if (*ptr & BUF_ACTIVE) { 00408 *ptr &= ~(BUF_ACTIVE); 00409 } 00410 00411 } else { 00412 if (EPNum & 0x80) { 00413 EPNum &= ~0x80; 00414 LPC_USB->EPSKIP |= (1 << EP_IN_IDX(EPNum)); 00415 00416 while (LPC_USB->EPSKIP & (1 << EP_IN_IDX(EPNum))); 00417 00418 } else { 00419 LPC_USB->EPSKIP |= (1 << EP_OUT_IDX(EPNum)); 00420 00421 while (LPC_USB->EPSKIP & (1 << EP_OUT_IDX(EPNum))); 00422 } 00423 } 00424 00425 if ((EPNum & 0x7F) == 0) { 00426 /* Endpoint is stalled so control out won't be next */ 00427 ctrl_out_next = 0; 00428 } 00429 00430 *ptr |= EP_STALL; 00431 } 00432 00433 00434 /* 00435 * Clear Stall for USB Device Endpoint 00436 * Parameters: EPNum: Device Endpoint Number 00437 * EPNum.0..3: Address 00438 * EPNum.7: Dir 00439 * Return Value: None 00440 */ 00441 00442 void USBD_ClrStallEP(U32 EPNum) 00443 { 00444 U32 *ptr; 00445 ptr = GetEpCmdStatPtr(EPNum); 00446 00447 if (EPNum & 0x80) { 00448 *ptr &= ~EP_STALL; 00449 00450 } else { 00451 *ptr &= ~EP_STALL; 00452 *ptr |= BUF_ACTIVE; 00453 } 00454 00455 USBD_ResetEP(EPNum); 00456 } 00457 00458 00459 /* 00460 * Clear USB Device Endpoint Buffer 00461 * Parameters: EPNum: Device Endpoint Number 00462 * EPNum.0..3: Address 00463 * EPNum.7: Dir 00464 * Return Value: None 00465 */ 00466 00467 void USBD_ClearEPBuf(U32 EPNum) 00468 { 00469 U32 cnt, i; 00470 U8 *dataptr; 00471 00472 if (EPNum & 0x80) { 00473 EPNum &= ~0x80; 00474 dataptr = (U8 *)EPBufInfo[EP_IN_IDX(EPNum)].buf_ptr; 00475 cnt = EPBufInfo[EP_IN_IDX(EPNum)].buf_len; 00476 00477 for (i = 0; i < cnt; i++) { 00478 dataptr[i] = 0; 00479 } 00480 00481 } else { 00482 dataptr = (U8 *)EPBufInfo[EP_OUT_IDX(EPNum)].buf_ptr; 00483 cnt = EPBufInfo[EP_OUT_IDX(EPNum)].buf_len; 00484 00485 for (i = 0; i < cnt; i++) { 00486 dataptr[i] = 0; 00487 } 00488 } 00489 } 00490 00491 00492 /* 00493 * Read USB Device Endpoint Data 00494 * Parameters: EPNum: Device Endpoint Number 00495 * EPNum.0..3: Address 00496 * EPNum.7: Dir 00497 * pData: Pointer to Data Buffer 00498 * Return Value: Number of bytes read 00499 */ 00500 00501 U32 USBD_ReadEP(U32 EPNum, U8 *pData, U32 size) 00502 { 00503 U32 cnt, i, xfer_size; 00504 volatile U32 *ptr; 00505 U8 *dataptr; 00506 ptr = GetEpCmdStatPtr(EPNum); 00507 int timeout = 256; 00508 00509 /* Setup packet */ 00510 if ((EPNum == 0) && !ctrl_out_next && (LPC_USB->DEVCMDSTAT & (1UL << 8))) { 00511 cnt = USBD_MAX_PACKET0; 00512 00513 if (size < cnt) { 00514 util_assert(0); 00515 cnt = size; 00516 } 00517 00518 dataptr = (U8 *)(EPBufInfo[EP_OUT_IDX(EPNum)].buf_ptr + 64); 00519 00520 for (i = 0; i < cnt; i++) { 00521 pData[i] = dataptr[i]; 00522 } 00523 00524 xfer_size = (pData[7] << 8) | (pData[6] << 0); 00525 if ((xfer_size > 0) && (pData[0] & (1 << 7))) { 00526 /* This control transfer has a data IN stage */ 00527 /* and ends with a zero length data OUT transfer. */ 00528 /* Ensure the data OUT token is not skipped even if */ 00529 /* a SETUP token arrives before USBD_ReadEP has */ 00530 /* been called. */ 00531 ctrl_out_next = 1; 00532 } 00533 00534 LPC_USB->EPSKIP |= (1 << EP_IN_IDX(EPNum)); 00535 00536 while (LPC_USB->EPSKIP & (1 << EP_IN_IDX(EPNum))); 00537 00538 if (*(ptr + 2) & EP_STALL) { 00539 *(ptr + 2) &= ~(EP_STALL); 00540 } 00541 00542 if (*ptr & EP_STALL) { 00543 *ptr &= ~(EP_STALL); 00544 } 00545 00546 LPC_USB->DEVCMDSTAT |= (1UL << 8); 00547 } 00548 00549 /* OUT packet */ 00550 else { 00551 ptr = GetEpCmdStatPtr(EPNum); 00552 cnt = EPBufInfo[EP_OUT_IDX(EPNum)].buf_len - ((*ptr >> 16) & 0x3FF); 00553 dataptr = (U8 *)EPBufInfo[EP_OUT_IDX(EPNum)].buf_ptr; 00554 00555 while ((timeout-- > 0) && (*ptr & BUF_ACTIVE)); //spin on the hardware until it's done 00556 util_assert(!(*ptr & BUF_ACTIVE)); //check for timeout 00557 00558 if (size < cnt) { 00559 util_assert(0); 00560 cnt = size; 00561 } 00562 00563 cnt = cnt < size ? cnt : size; 00564 00565 for (i = 0; i < cnt; i++) { 00566 pData[i] = dataptr[i]; 00567 } 00568 00569 *ptr = N_BYTES(EPBufInfo[EP_OUT_IDX(EPNum)].buf_len) | 00570 BUF_ADDR(EPBufInfo[EP_OUT_IDX(EPNum)].buf_ptr) | 00571 BUF_ACTIVE; 00572 00573 if (EPNum == 0) { 00574 /* If ctrl_out_next is set then this should be a zero length */ 00575 /* data OUT packet. */ 00576 util_assert(!ctrl_out_next || (cnt == 0)); 00577 ctrl_out_next = 0; 00578 if (LPC_USB->DEVCMDSTAT & (1UL << 8)) { 00579 // A setup packet is still pending so trigger another interrupt 00580 LPC_USB->INTSETSTAT |= (1 << 0); 00581 } 00582 } 00583 } 00584 00585 return (cnt); 00586 } 00587 00588 00589 /* 00590 * Write USB Device Endpoint Data 00591 * Parameters: EPNum: Endpoint Number 00592 * EPNum.0..3: Address 00593 * EPNum.7: Dir 00594 * pData: Pointer to Data Buffer 00595 * cnt: Number of bytes to write 00596 * Return Value: Number of bytes written 00597 */ 00598 00599 U32 USBD_WriteEP(U32 EPNum, U8 *pData, U32 cnt) 00600 { 00601 U32 i; 00602 volatile U32 *ptr; 00603 U32 *dataptr; 00604 ptr = GetEpCmdStatPtr(EPNum); 00605 EPNum &= ~0x80; 00606 00607 while (*ptr & BUF_ACTIVE); 00608 00609 *ptr &= ~(0x3FFFFFF); 00610 *ptr |= BUF_ADDR(EPBufInfo[EP_IN_IDX(EPNum)].buf_ptr) | 00611 N_BYTES(cnt); 00612 dataptr = (U32 *)EPBufInfo[EP_IN_IDX(EPNum)].buf_ptr; 00613 00614 for (i = 0; i < (cnt + 3) / 4; i++) { 00615 dataptr[i] = * ((__packed U32 *)pData); 00616 pData += 4; 00617 } 00618 00619 if (EPNum && (*ptr & EP_STALL)) { 00620 return (0); 00621 } 00622 00623 *ptr |= BUF_ACTIVE; 00624 return (cnt); 00625 } 00626 00627 00628 /* 00629 * Get USB Device Last Frame Number 00630 * Parameters: None 00631 * Return Value: Frame Number 00632 */ 00633 00634 U32 USBD_GetFrame(void) 00635 { 00636 return (LPC_USB->INFO & 0x7FF); 00637 } 00638 00639 00640 /* 00641 * USB Device Interrupt Service Routine 00642 */ 00643 00644 void USB_IRQHandler(void) 00645 { 00646 NVIC_DisableIRQ(USB_IRQn ); 00647 USBD_SignalHandler(); 00648 } 00649 00650 void USBD_Handler(void) 00651 { 00652 U32 sts, val, num, i; 00653 sts = LPC_USB->INTSTAT; 00654 LPC_USB->INTSTAT = sts; 00655 00656 /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */ 00657 if (sts & (1UL << 31)) { 00658 val = LPC_USB->DEVCMDSTAT; 00659 00660 /* reset interrupt */ 00661 if (val & (1UL << 26)) { 00662 LPC_USB->DEVCMDSTAT |= (1UL << 26); 00663 USBD_Reset(); 00664 usbd_reset_core(); 00665 #ifdef __RTX 00666 00667 if (USBD_RTX_DevTask) { 00668 isr_evt_set(USBD_EVT_RESET, USBD_RTX_DevTask); 00669 } 00670 00671 #else 00672 00673 if (USBD_P_Reset_Event) { 00674 USBD_P_Reset_Event(); 00675 } 00676 00677 #endif 00678 } 00679 00680 /* connect interrupt */ 00681 if (val & (1UL << 24)) { 00682 LPC_USB->DEVCMDSTAT |= (1UL << 24); 00683 #ifdef __RTX 00684 00685 if (USBD_RTX_DevTask) { 00686 if (val & (1UL << 16)) { 00687 isr_evt_set(USBD_EVT_POWER_ON, USBD_RTX_DevTask); 00688 } else { 00689 isr_evt_set(USBD_EVT_POWER_OFF, USBD_RTX_DevTask); 00690 } 00691 } 00692 00693 #else 00694 00695 if (USBD_P_Power_Event) { 00696 USBD_P_Power_Event((val >> 16) & 1); 00697 } 00698 00699 #endif 00700 } 00701 00702 /* suspend/resume interrupt */ 00703 if (val & (1 << 25)) { 00704 LPC_USB->DEVCMDSTAT |= (1UL << 25); 00705 00706 /* suspend interrupt */ 00707 if (val & (1UL << 17)) { 00708 USBD_Suspend(); 00709 #ifdef __RTX 00710 00711 if (USBD_RTX_DevTask) { 00712 isr_evt_set(USBD_EVT_SUSPEND, USBD_RTX_DevTask); 00713 } 00714 00715 #else 00716 00717 if (USBD_P_Suspend_Event) { 00718 USBD_P_Suspend_Event(); 00719 } 00720 00721 #endif 00722 } 00723 00724 /* resume interrupt */ 00725 else { 00726 #ifdef __RTX 00727 00728 if (USBD_RTX_DevTask) { 00729 isr_evt_set(USBD_EVT_RESUME, USBD_RTX_DevTask); 00730 } 00731 00732 #else 00733 00734 if (USBD_P_Resume_Event) { 00735 USBD_P_Resume_Event(); 00736 } 00737 00738 #endif 00739 } 00740 } 00741 } 00742 00743 /* Start of Frame */ 00744 if (sts & (1UL << 30)) { 00745 #ifdef __RTX 00746 00747 if (USBD_RTX_DevTask) { 00748 isr_evt_set(USBD_EVT_SOF, USBD_RTX_DevTask); 00749 } 00750 00751 #else 00752 00753 if (USBD_P_SOF_Event) { 00754 USBD_P_SOF_Event(); 00755 } 00756 00757 #endif 00758 } 00759 00760 /* EndPoint Interrupt */ 00761 if (sts & 0x3FF) { 00762 const uint32_t endpoint_count = ((USBD_EP_NUM + 1) * 2); 00763 00764 for (i = 0; i < endpoint_count; i++) { 00765 // Iterate through endpoints in the reverse order so IN endpoints 00766 // get processed before OUT endpoints if they are both pending. 00767 num = endpoint_count - i - 1; 00768 00769 if (sts & (1UL << num)) { 00770 /* Setup */ 00771 if ((num == 0) && !ctrl_out_next && (LPC_USB->DEVCMDSTAT & (1UL << 8))) { 00772 #ifdef __RTX 00773 00774 if (USBD_RTX_EPTask[num / 2]) { 00775 isr_evt_set(USBD_EVT_SETUP, USBD_RTX_EPTask[num / 2]); 00776 } 00777 00778 #else 00779 00780 if (USBD_P_EP[num / 2]) { 00781 USBD_P_EP[num / 2](USBD_EVT_SETUP); 00782 } 00783 00784 #endif 00785 } 00786 00787 /* OUT */ 00788 else if ((num % 2) == 0) { 00789 #ifdef __RTX 00790 00791 if (USBD_RTX_EPTask[num / 2]) { 00792 isr_evt_set(USBD_EVT_OUT, USBD_RTX_EPTask[num / 2]); 00793 } 00794 00795 #else 00796 00797 if (USBD_P_EP[num / 2]) { 00798 USBD_P_EP[num / 2](USBD_EVT_OUT); 00799 } 00800 00801 #endif 00802 } 00803 00804 /* IN */ 00805 else { 00806 #ifdef __RTX 00807 00808 if (USBD_RTX_EPTask[num / 2]) { 00809 isr_evt_set(USBD_EVT_IN, USBD_RTX_EPTask[num / 2]); 00810 } 00811 00812 #else 00813 00814 if (USBD_P_EP[num / 2]) { 00815 USBD_P_EP[num / 2](USBD_EVT_IN); 00816 } 00817 00818 #endif 00819 } 00820 } 00821 } 00822 } 00823 00824 NVIC_EnableIRQ(USB_IRQn ); 00825 }
Generated on Tue Jul 12 2022 15:37:26 by
1.7.2