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

« Back to documentation index

Show/hide line numbers usbd_MK26F.c Source File

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 }