Arrow / Mbed OS DAPLink Reset
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbd_LPC43xx_USB0.c Source File

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 }