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