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_LPC43xx_USB0.c
00001 /** 00002 * @file usbd_LPC43xx_USBD0.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 "usb.h" 00024 #include "LPC43xx.h" 00025 #include "compiler.h" 00026 00027 #define __NO_USB_LIB_C 00028 #include "usb_config.c" 00029 00030 /* Endpoint queue head */ 00031 typedef struct __EPQH { 00032 uint32_t cap; 00033 uint32_t curr_dTD; 00034 uint32_t next_dTD; 00035 uint32_t dTD_token; 00036 uint32_t buf[5]; 00037 uint32_t reserved; 00038 uint32_t setup[2]; 00039 uint32_t reserved1[4]; 00040 } EPQH; 00041 00042 /* Endpoint transfer descriptor */ 00043 typedef struct __dTD { 00044 uint32_t next_dTD; 00045 uint32_t dTD_token; 00046 uint32_t buf[5]; 00047 uint32_t reserved; 00048 } dTD; 00049 00050 /* Endpoint */ 00051 typedef struct __EP { 00052 uint8_t *buf; 00053 uint32_t maxPacket; 00054 } EP; 00055 00056 EPQH __align(2048) EPQHx[(USBD_EP_NUM + 1) * 2]; 00057 dTD __align(32) dTDx[(USBD_EP_NUM + 1) * 2]; 00058 00059 EP Ep[(USBD_EP_NUM + 1) * 2]; 00060 uint32_t BufUsed; 00061 uint32_t IsoEp; 00062 uint32_t cmpl_pnd; 00063 00064 #define LPC_USBx LPC_USB0 00065 #define ENDPTCTRL(EPNum) *(volatile uint32_t *)((uint32_t)(&LPC_USBx->ENDPTCTRL0) + 4 * EPNum) 00066 #define EP_OUT_IDX(EPNum) (EPNum * 2 ) 00067 #define EP_IN_IDX(EPNum) (EPNum * 2 + 1) 00068 #define HS(en) (USBD_HS_ENABLE * en) 00069 00070 /* reserve RAM for endpoint buffers */ 00071 #if USBD_VENDOR_ENABLE 00072 /* custom class: user defined buffer size */ 00073 #define EP_BUF_POOL_SIZE 0x1000 00074 uint8_t __align(4096) EPBufPool[EP_BUF_POOL_SIZE] 00075 #else 00076 /* supported classes are used */ 00077 uint8_t __align(4096) EPBufPool[ 00078 USBD_MAX_PACKET0 * 2 + 00079 USBD_HID_ENABLE * (HS(USBD_HID_HS_ENABLE) ? USBD_HID_HS_WMAXPACKETSIZE : USBD_HID_WMAXPACKETSIZE) * 2 + 00080 USBD_MSC_ENABLE * (HS(USBD_MSC_HS_ENABLE) ? USBD_MSC_HS_WMAXPACKETSIZE : USBD_MSC_WMAXPACKETSIZE) * 2 + 00081 USBD_ADC_ENABLE * (HS(USBD_ADC_HS_ENABLE) ? USBD_ADC_HS_WMAXPACKETSIZE : USBD_ADC_WMAXPACKETSIZE) + 00082 USBD_CDC_ACM_ENABLE * ((HS(USBD_CDC_ACM_HS_ENABLE) ? USBD_CDC_ACM_HS_WMAXPACKETSIZE : USBD_CDC_ACM_WMAXPACKETSIZE) + 00083 (HS(USBD_CDC_ACM_HS_ENABLE) ? USBD_CDC_ACM_HS_WMAXPACKETSIZE1 : USBD_CDC_ACM_WMAXPACKETSIZE1) * 2) + 00084 USBD_BULK_ENABLE * (HS(USBD_BULK_HS_ENABLE) ? USBD_BULK_HS_WMAXPACKETSIZE : USBD_BULK_WMAXPACKETSIZE) * 2 00085 ]; 00086 #endif 00087 00088 void USBD_PrimeEp(uint32_t EPNum, uint32_t cnt); 00089 00090 /* 00091 * Usb interrupt enable/disable 00092 * Parameters: ena: enable/disable 00093 * 0: disable interrupt 00094 * 1: enable interrupt 00095 */ 00096 00097 #ifdef __RTX 00098 void __svc(1) USBD_Intr(int ena); 00099 void __SVC_1(int ena) 00100 { 00101 #else 00102 void USBD_Intr(int ena) 00103 { 00104 #endif 00105 00106 if (ena) { 00107 NVIC_EnableIRQ(USB0_IRQn); /* Enable USB interrupt */ 00108 } else { 00109 NVIC_DisableIRQ(USB0_IRQn); /* Disable USB interrupt */ 00110 } 00111 } 00112 00113 00114 /* 00115 * USB Device Initialize Function 00116 * Called by the User to initialize USB Device 00117 * Return Value: None 00118 */ 00119 00120 void USBD_Init(void) 00121 { 00122 USBD_Intr(0); 00123 /* BASE_USB0_CLK */ 00124 LPC_CGU->BASE_USB0_CLK = (0x01 << 11) | /* Autoblock En */ 00125 (0x07 << 24) ; /* Clock source: PLL0 */ 00126 LPC_CCU1->CLK_M4_USB0_CFG |= 1; 00127 00128 while (!(LPC_CCU1->CLK_M4_USB0_STAT & 1)); 00129 00130 LPC_SCU->SFSP6_3 = 1; /* pwr en */ 00131 LPC_SCU->SFSP6_6 = 3; /* pwr fault */ 00132 LPC_SCU->SFSP8_1 = 1; /* port indicator LED control out 1 */ 00133 LPC_SCU->SFSP8_2 = 1; /* port indicator LED control out 0 */ 00134 LPC_USBx->USBCMD_D |= (1UL << 1); /* usb reset */ 00135 00136 while (LPC_USBx->USBCMD_D & (1UL << 1)); 00137 00138 LPC_CREG->CREG0 &= ~(1 << 5); 00139 LPC_USBx->USBMODE_D = 2 | (1UL << 3);/* device mode */ 00140 #if USBD_HS_ENABLE 00141 LPC_USBx->PORTSC1_D &= ~(1UL << 24); 00142 #else 00143 LPC_USBx->PORTSC1_D |= (1UL << 24); 00144 #endif 00145 LPC_USBx->OTGSC = 1 | (1UL << 3); 00146 Ep[EP_OUT_IDX(0)].maxPacket = USBD_MAX_PACKET0; 00147 LPC_USBx->USBINTR_D = (1UL << 0) | /* usb int enable */ 00148 (1UL << 2) | /* port change detect int enable */ 00149 (1UL << 8) | /* suspend int enable */ 00150 (1UL << 16) | /* nak int enable */ 00151 (1UL << 6) | /* reset int enable */ 00152 #ifdef __RTX 00153 ((USBD_RTX_DevTask != 0) ? (1UL << 7) : 0) | /* SOF */ 00154 ((USBD_RTX_DevTask != 0) ? (1UL << 1) : 0) ; /* Error */ 00155 #else 00156 ((USBD_P_SOF_Event != 0) ? (1UL << 7) : 0) | /* SOF */ 00157 ((USBD_P_Error_Event != 0) ? (1UL << 1) : 0) ; /* Error */ 00158 #endif 00159 USBD_Reset(); 00160 USBD_Intr(1); 00161 } 00162 00163 00164 /* 00165 * USB Device Connect Function 00166 * Called by the User to Connect/Disconnect USB Device 00167 * Parameters: con: Connect/Disconnect 00168 * Return Value: None 00169 */ 00170 00171 void USBD_Connect(uint32_t con) 00172 { 00173 if (con) { 00174 LPC_USBx->USBCMD_D |= 1; /* run */ 00175 } else { 00176 LPC_USBx->USBCMD_D &= ~1; /* stop */ 00177 } 00178 } 00179 00180 00181 /* 00182 * USB Device Reset Function 00183 * Called automatically on USB Device Reset 00184 * Return Value: None 00185 */ 00186 00187 void USBD_Reset(void) 00188 { 00189 uint32_t i; 00190 uint8_t *ptr; 00191 cmpl_pnd = 0; 00192 00193 for (i = 1; i < USBD_EP_NUM + 1; i++) { 00194 ENDPTCTRL(i) &= ~((1UL << 7) | (1UL << 23)); 00195 } 00196 00197 /* clear interrupts */ 00198 LPC_USBx->ENDPTNAK = 0xFFFFFFFF; 00199 LPC_USBx->ENDPTNAKEN = 0; 00200 LPC_USBx->USBSTS_D = 0xFFFFFFFF; 00201 LPC_USBx->ENDPTSETUPSTAT = LPC_USBx->ENDPTSETUPSTAT; 00202 LPC_USBx->ENDPTCOMPLETE = LPC_USBx->ENDPTCOMPLETE; 00203 00204 while (LPC_USBx->ENDPTPRIME); 00205 00206 LPC_USBx->ENDPTFLUSH = 0xFFFFFFFF; 00207 00208 while (LPC_USBx->ENDPTFLUSH); 00209 00210 LPC_USBx->USBCMD_D &= ~0x00FF0000; /* immediate intrrupt treshold */ 00211 /* clear endpoint queue heads */ 00212 ptr = (uint8_t *)EPQHx; 00213 00214 for (i = 0; i < sizeof(EPQHx); i++) { 00215 ptr[i] = 0; 00216 } 00217 00218 /* clear endpoint transfer descriptors */ 00219 ptr = (uint8_t *)dTDx; 00220 00221 for (i = 0; i < sizeof(dTDx); i++) { 00222 ptr[i] = 0; 00223 } 00224 00225 Ep[EP_OUT_IDX(0)].maxPacket = USBD_MAX_PACKET0; 00226 Ep[EP_OUT_IDX(0)].buf = EPBufPool; 00227 BufUsed = USBD_MAX_PACKET0; 00228 Ep[EP_IN_IDX(0)].maxPacket = USBD_MAX_PACKET0; 00229 Ep[EP_IN_IDX(0)].buf = &(EPBufPool[BufUsed]); 00230 BufUsed += USBD_MAX_PACKET0; 00231 dTDx[EP_OUT_IDX(0)].next_dTD = 1; 00232 dTDx[EP_IN_IDX(0)].next_dTD = 1; 00233 dTDx[EP_OUT_IDX(0)].dTD_token = (USBD_MAX_PACKET0 << 16) | /* total bytes */ 00234 (1UL << 15); /* int on compl */ 00235 dTDx[EP_IN_IDX(0)].dTD_token = (USBD_MAX_PACKET0 << 16) | /* total bytes */ 00236 (1UL << 15); /* int on compl */ 00237 EPQHx[EP_OUT_IDX(0)].next_dTD = (uint32_t) &dTDx[EP_OUT_IDX(0)]; 00238 EPQHx[EP_IN_IDX(0)].next_dTD = (uint32_t) &dTDx[EP_IN_IDX(0)]; 00239 EPQHx[EP_OUT_IDX(0)].cap = ((USBD_MAX_PACKET0 & 0x0EFF) << 16) | 00240 (1UL << 29) | 00241 (1UL << 15); /* int on setup */ 00242 EPQHx[EP_IN_IDX(0)].cap = (USBD_MAX_PACKET0 << 16) | 00243 (1UL << 29) | 00244 (1UL << 15); /* int on setup */ 00245 LPC_USBx->ENDPOINTLISTADDR = (uint32_t)EPQHx; 00246 LPC_USBx->USBMODE_D |= (1UL << 3); /* Setup lockouts off */ 00247 LPC_USBx->ENDPTCTRL0 = 0x00C000C0; 00248 USBD_PrimeEp(0, Ep[EP_OUT_IDX(0)].maxPacket); 00249 } 00250 00251 00252 /* 00253 * USB Device Suspend Function 00254 * Called automatically on USB Device Suspend 00255 * Return Value: None 00256 */ 00257 00258 void USBD_Suspend(void) 00259 { 00260 /* Performed by Hardware */ 00261 } 00262 00263 00264 /* 00265 * USB Device Resume Function 00266 * Called automatically on USB Device Resume 00267 * Return Value: None 00268 */ 00269 00270 void USBD_Resume(void) 00271 { 00272 /* Performed by Hardware */ 00273 } 00274 00275 00276 /* 00277 * USB Device Remote Wakeup Function 00278 * Called automatically on USB Device Remote Wakeup 00279 * Return Value: None 00280 */ 00281 00282 void USBD_WakeUp(void) 00283 { 00284 LPC_USBx->PORTSC1_D |= (1UL << 6); 00285 } 00286 00287 00288 /* 00289 * USB Device Remote Wakeup Configuration Function 00290 * Parameters: cfg: Device Enable/Disable 00291 * Return Value: None 00292 */ 00293 00294 void USBD_WakeUpCfg(uint32_t cfg) 00295 { 00296 /* Not needed */ 00297 } 00298 00299 00300 /* 00301 * USB Device Set Address Function 00302 * Parameters: adr: USB Device Address 00303 * Return Value: None 00304 */ 00305 00306 void USBD_SetAddress(uint32_t adr, uint32_t setup) 00307 { 00308 if (setup == 0) { 00309 LPC_USBx->DEVICEADDR = (adr << 25); 00310 LPC_USBx->DEVICEADDR |= (1UL << 24); 00311 } 00312 } 00313 00314 00315 /* 00316 * USB Device Configure Function 00317 * Parameters: cfg: Device Configure/Deconfigure 00318 * Return Value: None 00319 */ 00320 00321 void USBD_Configure(uint32_t cfg) 00322 { 00323 uint32_t i; 00324 00325 if (!cfg) { 00326 for (i = 2; i < (2 * (USBD_EP_NUM + 1)); i++) { 00327 Ep[i].buf = 0; 00328 Ep[i].maxPacket = 0; 00329 } 00330 00331 BufUsed = 2 * USBD_MAX_PACKET0; 00332 } 00333 } 00334 00335 00336 /* 00337 * Configure USB Device Endpoint according to Descriptor 00338 * Parameters: pEPD: Pointer to Device Endpoint Descriptor 00339 * Return Value: None 00340 */ 00341 00342 void USBD_ConfigEP(USB_ENDPOINT_DESCRIPTOR *pEPD) 00343 { 00344 uint32_t num, val, type, idx; 00345 00346 if ((pEPD->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK)) { 00347 val = 16; 00348 num = pEPD->bEndpointAddress & ~0x80; 00349 idx = EP_IN_IDX(num); 00350 00351 } else { 00352 val = 0; 00353 num = pEPD->bEndpointAddress; 00354 idx = EP_OUT_IDX(num); 00355 } 00356 00357 type = pEPD->bmAttributes & USB_ENDPOINT_TYPE_MASK; 00358 00359 if (!(Ep[idx].buf)) { 00360 Ep[idx].buf = &(EPBufPool[BufUsed]); 00361 Ep[idx].maxPacket = pEPD->wMaxPacketSize; 00362 BufUsed += pEPD->wMaxPacketSize; 00363 00364 /* Isochronous endpoint */ 00365 if (type == USB_ENDPOINT_TYPE_ISOCHRONOUS) { 00366 IsoEp |= (1UL << (num + val)); 00367 } 00368 } 00369 00370 dTDx[idx].buf[0] = (uint32_t)(Ep[idx].buf); 00371 dTDx[idx].next_dTD = 1; 00372 EPQHx[idx].cap = (Ep[idx].maxPacket << 16) | 00373 (1UL << 29); 00374 ENDPTCTRL(num) &= ~(0xFFFF << val); 00375 ENDPTCTRL(num) |= ((type << 2) << val) | 00376 ((1UL << 6) << val); /* Data toogle reset */ 00377 } 00378 00379 00380 /* 00381 * Set Direction for USB Device Control Endpoint 00382 * Parameters: dir: Out (dir == 0), In (dir <> 0) 00383 * Return Value: None 00384 */ 00385 00386 void USBD_DirCtrlEP(uint32_t dir) 00387 { 00388 /* Not needed */ 00389 } 00390 00391 00392 /* 00393 * Enable USB Device Endpoint 00394 * Parameters: EPNum: Device Endpoint Number 00395 * EPNum.0..3: Address 00396 * EPNum.7: Dir 00397 * Return Value: None 00398 */ 00399 00400 void USBD_EnableEP(uint32_t EPNum) 00401 { 00402 if (EPNum & 0x80) { 00403 EPNum &= 0x7F; 00404 ENDPTCTRL(EPNum) |= (1UL << 23); /* EP enabled */ 00405 } else { 00406 ENDPTCTRL(EPNum) |= (1UL << 7); /* EP enabled */ 00407 } 00408 } 00409 00410 00411 /* 00412 * Disable USB Device Endpoint 00413 * Parameters: EPNum: Device Endpoint Number 00414 * EPNum.0..3: Address 00415 * EPNum.7: Dir 00416 * Return Value: None 00417 */ 00418 00419 void USBD_DisableEP(uint32_t EPNum) 00420 { 00421 if (EPNum & 0x80) { 00422 EPNum &= 0x7F; 00423 ENDPTCTRL(EPNum) &= ~(1UL << 23); /* EP disabled */ 00424 } else { 00425 ENDPTCTRL(EPNum) &= ~(1UL << 7); /* EP disabled */ 00426 } 00427 } 00428 00429 00430 /* 00431 * Reset USB Device Endpoint 00432 * Parameters: EPNum: Device Endpoint Number 00433 * EPNum.0..3: Address 00434 * EPNum.7: Dir 00435 * Return Value: None 00436 */ 00437 00438 void USBD_ResetEP(uint32_t EPNum) 00439 { 00440 if (EPNum & 0x80) { 00441 EPNum &= 0x7F; 00442 EPQHx[EP_IN_IDX(EPNum)].dTD_token &= 0xC0; 00443 LPC_USBx->ENDPTFLUSH = (1UL << (EPNum + 16)); /* flush endpoint */ 00444 00445 while (LPC_USBx->ENDPTFLUSH & (1UL << (EPNum + 16))); 00446 00447 ENDPTCTRL(EPNum) |= (1UL << 22); /* data toggle reset */ 00448 00449 } else { 00450 EPQHx[EP_OUT_IDX(EPNum)].dTD_token &= 0xC0; 00451 LPC_USBx->ENDPTFLUSH = (1UL << EPNum); /* flush endpoint */ 00452 00453 while (LPC_USBx->ENDPTFLUSH & (1UL << EPNum)); 00454 00455 ENDPTCTRL(EPNum) |= (1UL << 6); /* data toggle reset */ 00456 USBD_PrimeEp(EPNum, Ep[EP_OUT_IDX(EPNum)].maxPacket); 00457 } 00458 } 00459 00460 00461 /* 00462 * Set Stall for USB Device Endpoint 00463 * Parameters: EPNum: Device Endpoint Number 00464 * EPNum.0..3: Address 00465 * EPNum.7: Dir 00466 * Return Value: None 00467 */ 00468 00469 void USBD_SetStallEP(uint32_t EPNum) 00470 { 00471 if (EPNum & 0x80) { 00472 EPNum &= 0x7F; 00473 ENDPTCTRL(EPNum) |= (1UL << 16); /* IN endpoint stall */ 00474 } else { 00475 ENDPTCTRL(EPNum) |= (1UL << 0); /* OUT endpoint stall */ 00476 } 00477 } 00478 00479 00480 /* 00481 * Clear Stall for USB Device Endpoint 00482 * Parameters: EPNum: Device Endpoint Number 00483 * EPNum.0..3: Address 00484 * EPNum.7: Dir 00485 * Return Value: None 00486 */ 00487 00488 void USBD_ClrStallEP(uint32_t EPNum) 00489 { 00490 if (EPNum & 0x80) { 00491 EPNum &= 0x7F; 00492 ENDPTCTRL(EPNum) &= ~(1UL << 16); /* clear stall */ 00493 ENDPTCTRL(EPNum) |= (1UL << 22); /* data toggle reset */ 00494 00495 while (ENDPTCTRL(EPNum) & (1UL << 16)); 00496 00497 USBD_ResetEP(EPNum | 0x80); 00498 00499 } else { 00500 ENDPTCTRL(EPNum) &= ~(1UL << 0); /* clear stall */ 00501 ENDPTCTRL(EPNum) |= (1UL << 6); /* data toggle reset */ 00502 } 00503 } 00504 00505 00506 /* 00507 * Clear USB Device Endpoint Buffer 00508 * Parameters: EPNum: Device Endpoint Number 00509 * EPNum.0..3: Address 00510 * EPNum.7: Dir 00511 * Return Value: None 00512 */ 00513 00514 void USBD_ClearEPBuf(uint32_t EPNum) 00515 { 00516 } 00517 00518 00519 /* 00520 * USB Device Prime endpoint function 00521 * Parameters: EPNum: Device Endpoint Number 00522 * EPNum.0..3: Address 00523 * EPNum.7: Dir 00524 * cnt: Bytes to transfer/receive 00525 * Return Value: None 00526 */ 00527 00528 void USBD_PrimeEp(uint32_t EPNum, uint32_t cnt) 00529 { 00530 uint32_t idx, val; 00531 00532 /* IN endpoint */ 00533 if (EPNum & 0x80) { 00534 EPNum &= 0x7F; 00535 idx = EP_IN_IDX(EPNum); 00536 val = (1UL << (EPNum + 16)); 00537 } 00538 00539 /* OUT endpoint */ 00540 else { 00541 val = (1UL << EPNum); 00542 idx = EP_OUT_IDX(EPNum); 00543 } 00544 00545 dTDx[idx].buf[0] = (uint32_t)(Ep[idx].buf); 00546 dTDx[idx].next_dTD = 1; 00547 00548 if (IsoEp & val) { 00549 if (Ep[idx].maxPacket <= cnt) { 00550 dTDx[idx].dTD_token = (1 << 10); /* MultO = 1 */ 00551 00552 } else if ((Ep[idx].maxPacket * 2) <= cnt) { 00553 dTDx[idx].dTD_token = (2 << 10); /* MultO = 2 */ 00554 00555 } else { 00556 dTDx[idx].dTD_token = (3 << 10); /* MultO = 3 */ 00557 } 00558 00559 } else { 00560 dTDx[idx].dTD_token = 0; 00561 } 00562 00563 dTDx[idx].dTD_token |= (cnt << 16) | /* bytes to transfer */ 00564 (1UL << 15) | /* int on complete */ 00565 0x80; /* status - active */ 00566 EPQHx[idx].next_dTD = (uint32_t)(&dTDx[idx]); 00567 EPQHx[idx].dTD_token &= ~0xC0; 00568 LPC_USBx->ENDPTPRIME = (val); 00569 00570 while ((LPC_USBx->ENDPTPRIME & val)); 00571 } 00572 00573 00574 /* 00575 * Read USB Device Endpoint Data 00576 * Parameters: EPNum: Device Endpoint Number 00577 * EPNum.0..3: Address 00578 * EPNum.7: Dir 00579 * pData: Pointer to Data Buffer 00580 * Return Value: Number of bytes read 00581 */ 00582 00583 uint32_t USBD_ReadEP(uint32_t EPNum, uint8_t *pData, U32 size) 00584 { 00585 uint32_t cnt = 0; 00586 uint32_t i; 00587 00588 /* Setup packet */ 00589 if ((LPC_USBx->ENDPTSETUPSTAT & 1) && (!EPNum)) { 00590 LPC_USBx->ENDPTSETUPSTAT = 1; 00591 00592 while (LPC_USBx->ENDPTSETUPSTAT & 1); 00593 00594 do { 00595 *((__packed uint32_t *) pData) = EPQHx[EP_OUT_IDX(0)].setup[0]; 00596 *((__packed uint32_t *)(pData + 4)) = EPQHx[EP_OUT_IDX(0)].setup[1]; 00597 cnt = 8; 00598 LPC_USBx->USBCMD_D |= (1UL << 13); 00599 } while (!(LPC_USBx->USBCMD_D & (1UL << 13))); 00600 00601 LPC_USBx->USBCMD_D &= (~(1UL << 13)); 00602 LPC_USBx->ENDPTFLUSH = (1UL << EPNum) | (1UL << (EPNum + 16)); 00603 00604 while (LPC_USBx->ENDPTFLUSH & ((1UL << (EPNum + 16)) | (1UL << EPNum))); 00605 00606 while (LPC_USBx->ENDPTSETUPSTAT & 1); 00607 00608 USBD_PrimeEp(EPNum, Ep[EP_OUT_IDX(EPNum)].maxPacket); 00609 } 00610 00611 /* OUT Packet */ 00612 else { 00613 if (Ep[EP_OUT_IDX(EPNum)].buf) { 00614 cnt = Ep[EP_OUT_IDX(EPNum)].maxPacket - 00615 ((dTDx[EP_OUT_IDX(EPNum)].dTD_token >> 16) & 0x7FFF); 00616 00617 cnt = cnt < size ? cnt : size; 00618 00619 for (i = 0; i < cnt; i++) { 00620 pData[i] = Ep[EP_OUT_IDX(EPNum)].buf[i]; 00621 } 00622 } 00623 00624 LPC_USBx->ENDPTCOMPLETE = (1UL << EPNum); 00625 cmpl_pnd &= ~(1UL << EPNum); 00626 USBD_PrimeEp(EPNum, Ep[EP_OUT_IDX(EPNum)].maxPacket); 00627 } 00628 00629 return (cnt); 00630 } 00631 00632 00633 /* 00634 * Write USB Device Endpoint Data 00635 * Parameters: EPNum: Endpoint Number 00636 * EPNum.0..3: Address 00637 * EPNum.7: Dir 00638 * pData: Pointer to Data Buffer 00639 * cnt: Number of bytes to write 00640 * Return Value: Number of bytes written 00641 */ 00642 00643 uint32_t USBD_WriteEP(uint32_t EPNum, uint8_t *pData, uint32_t cnt) 00644 { 00645 uint32_t i; 00646 EPNum &= 0x7f; 00647 00648 for (i = 0; i < cnt; i++) { 00649 Ep[EP_IN_IDX(EPNum)].buf[i] = pData[i]; 00650 } 00651 00652 USBD_PrimeEp(EPNum | 0x80, cnt); 00653 return (cnt); 00654 } 00655 00656 00657 /* 00658 * Get USB Device Last Frame Number 00659 * Parameters: None 00660 * Return Value: Frame Number 00661 */ 00662 00663 uint32_t USBD_GetFrame(void) 00664 { 00665 return ((LPC_USBx->FRINDEX_D >> 3) & 0x0FFF); 00666 } 00667 00668 00669 #ifdef __RTX 00670 uint32_t LastError; /* Last Error */ 00671 00672 /* 00673 * Get USB Device Last Error Code 00674 * Parameters: None 00675 * Return Value: Error Code 00676 */ 00677 00678 uint32_t USBD_GetError(void) 00679 { 00680 return (LastError); 00681 } 00682 #endif 00683 00684 00685 /* 00686 * USB Device Interrupt Service Routine 00687 */ 00688 00689 void USB0_IRQHandler(void) 00690 { 00691 NVIC_DisableIRQ(USB0_IRQn); 00692 USBD_SignalHandler(); 00693 } 00694 00695 void USBD_Handler(void) 00696 { 00697 uint32_t sts, cmpl, num; 00698 sts = LPC_USBx->USBSTS_D & LPC_USBx->USBINTR_D; 00699 cmpl = LPC_USBx->ENDPTCOMPLETE; 00700 LPC_USBx->USBSTS_D = sts; /* clear interupt flags */ 00701 00702 /* reset interrupt */ 00703 if (sts & (1UL << 6)) { 00704 USBD_Reset(); 00705 usbd_reset_core(); 00706 #ifdef __RTX 00707 00708 if (USBD_RTX_DevTask) { 00709 isr_evt_set(USBD_EVT_RESET, USBD_RTX_DevTask); 00710 } 00711 00712 #else 00713 00714 if (USBD_P_Reset_Event) { 00715 USBD_P_Reset_Event(); 00716 } 00717 00718 #endif 00719 } 00720 00721 /* suspend interrupt */ 00722 if (sts & (1UL << 8)) { 00723 USBD_Suspend(); 00724 #ifdef __RTX 00725 00726 if (USBD_RTX_DevTask) { 00727 isr_evt_set(USBD_EVT_SUSPEND, USBD_RTX_DevTask); 00728 } 00729 00730 #else 00731 00732 if (USBD_P_Suspend_Event) { 00733 USBD_P_Suspend_Event(); 00734 } 00735 00736 #endif 00737 } 00738 00739 /* SOF interrupt */ 00740 if (sts & (1UL << 7)) { 00741 if (IsoEp) { 00742 for (num = 0; num < USBD_EP_NUM + 1; num++) { 00743 if (IsoEp & (1UL << num)) { 00744 USBD_PrimeEp(num, Ep[EP_OUT_IDX(num)].maxPacket); 00745 } 00746 } 00747 00748 } else { 00749 #ifdef __RTX 00750 00751 if (USBD_RTX_DevTask) { 00752 isr_evt_set(USBD_EVT_SOF, USBD_RTX_DevTask); 00753 } 00754 00755 #else 00756 00757 if (USBD_P_SOF_Event) { 00758 USBD_P_SOF_Event(); 00759 } 00760 00761 #endif 00762 } 00763 } 00764 00765 /* port change detect interrupt */ 00766 if (sts & (1UL << 2)) { 00767 if (((LPC_USBx->PORTSC1_D >> 26) & 0x03) == 2) { 00768 USBD_HighSpeed = __TRUE; 00769 } 00770 00771 USBD_Resume(); 00772 #ifdef __RTX 00773 00774 if (USBD_RTX_DevTask) { 00775 isr_evt_set(USBD_EVT_RESUME, USBD_RTX_DevTask); 00776 } 00777 00778 #else 00779 00780 if (USBD_P_Resume_Event) { 00781 USBD_P_Resume_Event(); 00782 } 00783 00784 #endif 00785 } 00786 00787 /* USB interrupt - completed transfer */ 00788 if (sts & 1) { 00789 /* Setup Packet */ 00790 if (LPC_USBx->ENDPTSETUPSTAT) { 00791 #ifdef __RTX 00792 00793 if (USBD_RTX_EPTask[0]) { 00794 isr_evt_set(USBD_EVT_SETUP, USBD_RTX_EPTask[0]); 00795 } 00796 00797 #else 00798 00799 if (USBD_P_EP[0]) { 00800 USBD_P_EP[0](USBD_EVT_SETUP); 00801 } 00802 00803 #endif 00804 } 00805 00806 /* IN Packet */ 00807 if (cmpl & (0x3F << 16)) { 00808 for (num = 0; num < USBD_EP_NUM + 1; num++) { 00809 if (((cmpl >> 16) & 0x3F) & (1UL << num)) { 00810 LPC_USBx->ENDPTCOMPLETE = (1UL << (num + 16)); /* Clear completed */ 00811 #ifdef __RTX 00812 00813 if (USBD_RTX_EPTask[num]) { 00814 isr_evt_set(USBD_EVT_IN, USBD_RTX_EPTask[num]); 00815 } 00816 00817 #else 00818 00819 if (USBD_P_EP[num]) { 00820 USBD_P_EP[num](USBD_EVT_IN); 00821 } 00822 00823 #endif 00824 } 00825 } 00826 } 00827 00828 /* OUT Packet */ 00829 if (cmpl & 0x3F) { 00830 for (num = 0; num < USBD_EP_NUM + 1; num++) { 00831 if ((cmpl ^ cmpl_pnd) & cmpl & (1UL << num)) { 00832 cmpl_pnd |= 1UL << num; 00833 #ifdef __RTX 00834 00835 if (USBD_RTX_EPTask[num]) { 00836 isr_evt_set(USBD_EVT_OUT, USBD_RTX_EPTask[num]); 00837 00838 } else if (IsoEp & (1UL << num)) { 00839 if (USBD_RTX_DevTask) { 00840 isr_evt_set(USBD_EVT_SOF, USBD_RTX_DevTask); 00841 } 00842 } 00843 00844 #else 00845 00846 if (USBD_P_EP[num]) { 00847 USBD_P_EP[num](USBD_EVT_OUT); 00848 00849 } else if (IsoEp & (1UL << num)) { 00850 if (USBD_P_SOF_Event) { 00851 USBD_P_SOF_Event(); 00852 } 00853 } 00854 00855 #endif 00856 } 00857 } 00858 } 00859 } 00860 00861 /* error interrupt */ 00862 if (sts & (1UL << 1)) { 00863 for (num = 0; num < USBD_EP_NUM + 1; num++) { 00864 if (cmpl & (1UL << num)) { 00865 #ifdef __RTX 00866 00867 if (USBD_RTX_DevTask) { 00868 LastError = dTDx[EP_OUT_IDX(num)].dTD_token & 0xE8; 00869 isr_evt_set(USBD_EVT_ERROR, USBD_RTX_DevTask); 00870 } 00871 00872 #else 00873 00874 if (USBD_P_Error_Event) { 00875 USBD_P_Error_Event(dTDx[EP_OUT_IDX(num)].dTD_token & 0xE8); 00876 } 00877 00878 #endif 00879 } 00880 00881 if (cmpl & (1UL << (num + 16))) { 00882 #ifdef __RTX 00883 00884 if (USBD_RTX_DevTask) { 00885 LastError = dTDx[EP_IN_IDX(num)].dTD_token & 0xE8; 00886 isr_evt_set(USBD_EVT_ERROR, USBD_RTX_DevTask); 00887 } 00888 00889 #else 00890 00891 if (USBD_P_Error_Event) { 00892 USBD_P_Error_Event(dTDx[EP_IN_IDX(num)].dTD_token & 0xE8); 00893 } 00894 00895 #endif 00896 } 00897 } 00898 } 00899 00900 NVIC_EnableIRQ(USB0_IRQn); 00901 }
Generated on Tue Jul 12 2022 15:37:26 by
1.7.2