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

« Back to documentation index

Show/hide line numbers usbd_ATSAM3U2C.c Source File

usbd_ATSAM3U2C.c

Go to the documentation of this file.
00001 /**
00002  * @file    usbd_ATSAM3U2C.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 "sam3u.h"
00024 #include "util.h"
00025 
00026 #define __NO_USB_LIB_C
00027 #include "usb_config.c"
00028 
00029 #define UDPHS_EPTFIFO_BASE (0x20180000) /* (UDPHS_EPTFIFO) Base Address       */
00030 uint32_t eptsta_copy[USBD_EP_NUM + 1];
00031 
00032 /*
00033  *  Calculate EP size code Function
00034  *   Called during EndPoint configuration
00035  *    Return Value:    EP size code for given EP size
00036  */
00037 
00038 static int USBD_CalcSizeEP(uint32_t size)
00039 {
00040     if (size <=    8) {
00041         return (0);
00042     } else if (size <=   16) {
00043         return (1);
00044     } else if (size <=   32) {
00045         return (2);
00046     } else if (size <=   64) {
00047         return (3);
00048     } else if (size <=  128) {
00049         return (4);
00050     } else if (size <=  256) {
00051         return (5);
00052     } else if (size <=  512)  {
00053         return (6);
00054     } else if (size <= 1024) {
00055         return (7);
00056     }
00057 
00058     return (0);
00059 }
00060 
00061 
00062 /*
00063  *  Retrieve maximum EP size Function
00064  *   Called during EndPoint configuration
00065  *    Return Value:    maximum size for given EP
00066  */
00067 
00068 static int USBD_GetSizeEP(uint32_t EPNum)
00069 {
00070     switch (EPNum & 0x0F) {
00071         case 0:
00072             return (64);                      /* Maximum size is 64 bytes           */
00073 
00074         case 1:
00075         case 2:
00076             return (512);                     /* Maximum size is 512 bytes          */
00077 
00078         case 3:
00079         case 4:
00080             return (64);                      /* Maximum size is 64 bytes           */
00081 
00082         case 5:
00083         case 6:
00084             return (1024);                    /* Maximum size is 1024 bytes         */
00085 
00086         default:
00087             return (0);                       /* Non existant endpoint              */
00088     }
00089 }
00090 
00091 
00092 /*
00093  *  USB Device Interrupt enable
00094  *   Called by USBD_Init to enable the USB Interrupt
00095  *    Return Value:    None
00096  */
00097 
00098 void USBD_IntrEna(void)
00099 {
00100     NVIC_EnableIRQ(UDPHS_IRQn);           /* Enable USB interrupt               */
00101 }
00102 
00103 
00104 /*
00105  *  USB Device Initialize Function
00106  *   Called by the User to initialize USB Device
00107  *    Return Value:    None
00108  */
00109 
00110 void USBD_Init(void)
00111 {
00112     uint32_t n;
00113     /* Enables the 48MHz USB Clock UDPCK and System Peripheral USB Clock        */
00114     PMC->PMC_WPMR = 0x504D4300;                              /* Disable write protect  */
00115     PMC->PMC_PCER0  = (1 << ID_UDPHS);                       /* enable clock for UPDHS */
00116     PMC->CKGR_UCKR  = (CKGR_UCKR_UPLLCOUNT(15) | CKGR_UCKR_UPLLEN);
00117 
00118     while (!(PMC->PMC_SR & PMC_SR_LOCKU));                   /* wait until PLL is locked */
00119 
00120     PMC->PMC_WPMR = 0x504D4301;                              /* Enable write protect */
00121     /* Configure the pull-up on D+ and disconnect it                            */
00122     UDPHS->UDPHS_CTRL |= UDPHS_CTRL_DETACH;         /* Detach                   */
00123     UDPHS->UDPHS_CTRL |= UDPHS_CTRL_PULLD_DIS;      /* Disable Pull Down        */
00124     /* Reset IP UDPHS                                                           */
00125     UDPHS->UDPHS_CTRL &= ~UDPHS_CTRL_EN_UDPHS;
00126     UDPHS->UDPHS_CTRL |=  UDPHS_CTRL_EN_UDPHS;
00127 #if (!USBD_HS_ENABLE)                             /* If HS disabled           */
00128     UDPHS->UDPHS_TST  |= (3 & UDPHS_TST_SPEED_CFG_Msk);
00129 #endif
00130 
00131     /* Disable DMA for UDPHS                                                    */
00132     for (n = 1; n < (UDPHSDMA_NUMBER); n++) {
00133         /* RESET endpoint canal DMA:                                              */
00134         UDPHS->UDPHS_DMA[n].UDPHS_DMACONTROL = 0;     /* STOP command             */
00135         /* Disable endpoint                                                       */
00136         UDPHS->UDPHS_EPT[n].UDPHS_EPTCTLDIS  = 0xFFFFFFFF;
00137         /* Clear status endpoint                                                  */
00138         UDPHS->UDPHS_EPT[n].UDPHS_EPTCLRSTA  = 0xFFFFFFFF;
00139         /* Reset endpoint config                                                  */
00140         UDPHS->UDPHS_EPT[n].UDPHS_EPTCTLENB  = 0;
00141         /* Reset DMA channel (Buff count and Control field)                       */
00142         UDPHS->UDPHS_DMA[n].UDPHS_DMACONTROL = (0x1 << 1);    /* NON STOP command */
00143         /* Reset DMA channel 0 (STOP)                                             */
00144         UDPHS->UDPHS_DMA[n].UDPHS_DMACONTROL = 0;             /* STOP command     */
00145         /* Clear DMA channel status (read the register for clear it)              */
00146         UDPHS->UDPHS_DMA[n].UDPHS_DMASTATUS =  UDPHS->UDPHS_DMA[n].UDPHS_DMASTATUS;
00147     }
00148 
00149     UDPHS->UDPHS_IEN     = 0;
00150     UDPHS->UDPHS_CLRINT  = UDPHS_CLRINT_UPSTR_RES |
00151                            UDPHS_CLRINT_ENDOFRSM  |
00152                            UDPHS_CLRINT_WAKE_UP   |
00153                            UDPHS_CLRINT_ENDRESET  |
00154                            UDPHS_CLRINT_INT_SOF   |
00155                            UDPHS_CLRINT_MICRO_SOF |
00156                            UDPHS_CLRINT_DET_SUSPD;
00157     USBD_IntrEna();                       /* Enable USB interrupt               */
00158 }
00159 
00160 
00161 /*
00162  *  USB Device Connect Function
00163  *   Called by the User to Connect/Disconnect USB Device
00164  *    Parameters:      con:   Connect/Disconnect
00165  *    Return Value:    None
00166  */
00167 
00168 void USBD_Connect(BOOL con)
00169 {
00170     if (con) {
00171         UDPHS->UDPHS_CTRL &= ~UDPHS_CTRL_DETACH;          /* Pull Up on DP        */
00172         UDPHS->UDPHS_CTRL |=  UDPHS_CTRL_PULLD_DIS;       /* Disable Pull Down    */
00173     } else {
00174         UDPHS->UDPHS_CTRL |=  UDPHS_CTRL_DETACH;          /* Detach               */
00175         UDPHS->UDPHS_CTRL &= ~UDPHS_CTRL_PULLD_DIS;       /* Enable Pull Down     */
00176     }
00177 }
00178 
00179 /*
00180  *  USB Device Reset Function
00181  *   Called automatically on USB Device Reset
00182  *    Return Value:    None
00183  */
00184 extern U8 USBD_ConfigDescriptor_HS[];
00185 extern U8 USBD_ConfigDescriptor[];
00186 void USBD_Reset(void)
00187 {
00188     uint32_t ep, EPMask;
00189     EPMask = ((1 << (USBD_EP_NUM + 1)) - 1);
00190 
00191     /* Reset & Disable USB Endpoints                                            */
00192     for (ep = 0; ep <= USBD_EP_NUM; ep++) {
00193         UDPHS->UDPHS_EPT[ep].UDPHS_EPTCFG    =  0;
00194         UDPHS->UDPHS_EPT[ep].UDPHS_EPTCTLDIS = (0x1 <<  0);     /* Disable EP     */
00195         eptsta_copy[ep] = 0;
00196     }
00197 
00198     UDPHS->UDPHS_EPTRST = EPMask;                             /* Reset   EPs    */
00199     UDPHS->UDPHS_EPTRST = 0;
00200     /* Setup USB Interrupts */               /* note: Micro_SOF not yet handled */
00201 #ifdef __RTX
00202     UDPHS->UDPHS_IEN = ((USBD_RTX_DevTask     != 0) ? UDPHS_IEN_DET_SUSPD : 0) |
00203                        ((USBD_RTX_DevTask     != 0) ? UDPHS_IEN_MICRO_SOF : 0) |
00204                        ((USBD_RTX_DevTask     != 0) ? UDPHS_IEN_INT_SOF   : 0) |
00205                        ((USBD_RTX_DevTask     != 0) ? UDPHS_IEN_ENDRESET  : 0) |
00206 //                   ((USBD_RTX_DevTask     != 0) ? UDPHS_IEN_WAKE_UP   : 0) |
00207 //                   ((USBD_RTX_DevTask     != 0) ? UDPHS_IEN_UPSTR_RES : 0) |
00208 #else
00209     UDPHS->UDPHS_IEN = ((USBD_P_Suspend_Event != 0) ? UDPHS_IEN_DET_SUSPD : 0) |
00210                        ((USBD_P_SOF_Event     != 0) ? UDPHS_IEN_MICRO_SOF : 0) |
00211                        ((USBD_P_SOF_Event     != 0) ? UDPHS_IEN_INT_SOF   : 0) |
00212                        ((USBD_P_Reset_Event   != 0) ? UDPHS_IEN_ENDRESET  : 0) |
00213 //                   ((USBD_P_WakeUp_Event  != 0) ? UDPHS_IEN_WAKE_UP   : 0) |
00214 //                   ((USBD_P_Resume_Event  != 0) ? UDPHS_IEN_UPSTR_RES : 0) |
00215 #endif
00216                        (EPMask << 8);
00217     /* Setup Control Endpoint 0                                                 */
00218     UDPHS->UDPHS_EPT[0].UDPHS_EPTCFG     = UDPHS_EPTCFG_BK_NUMBER_1            |
00219                                            UDPHS_EPTCFG_EPT_TYPE_CTRL8         |
00220                                            USBD_CalcSizeEP(USBD_MAX_PACKET0)   ;
00221     UDPHS->UDPHS_EPT[0].UDPHS_EPTCTLENB  = UDPHS_EPTCTLENB_RXRDY_TXKL          |
00222                                            UDPHS_EPTCTLENB_TX_COMPLT           |
00223                                            UDPHS_EPTCTLENB_RX_SETUP            |
00224                                            UDPHS_EPTCTLENB_STALL_SNT           |
00225                                            UDPHS_EPTCTLENB_NYET_DIS            |
00226                                            UDPHS_EPTCTLENB_EPT_ENABL;
00227                                            
00228     
00229 #if (USBD_HS_ENABLE == 1)
00230     U8 * config_desc = USBD_ConfigDescriptor_HS;
00231 #else
00232     U8 * config_desc = USBD_ConfigDescriptor;
00233 #endif
00234 
00235     while (((USB_ENDPOINT_DESCRIPTOR *)config_desc)->bLength > 0) {
00236         if (((USB_ENDPOINT_DESCRIPTOR *)config_desc)->bDescriptorType == USB_ENDPOINT_DESCRIPTOR_TYPE) {
00237             uint32_t num, type, dir, size, banks, interval;
00238             USB_ENDPOINT_DESCRIPTOR *pEPD =  (USB_ENDPOINT_DESCRIPTOR *)config_desc;
00239             num      = pEPD->bEndpointAddress & 0x0F;
00240             type     = pEPD->bmAttributes & USB_ENDPOINT_TYPE_MASK;
00241             dir      = pEPD->bEndpointAddress >> 7;
00242             interval = pEPD->bInterval;
00243             size     = USBD_CalcSizeEP(pEPD->wMaxPacketSize);
00244             banks    = 1;
00245             UDPHS->UDPHS_EPT[num].UDPHS_EPTCFG    = (interval << 8) |
00246                                                     (banks    << 6) |
00247                                                     (type     << 4) |
00248                                                     (dir      << 3) |
00249                                                     (size     << 0) ;
00250         }
00251         config_desc += ((USB_ENDPOINT_DESCRIPTOR *)config_desc)->bLength;
00252     }
00253 }
00254 
00255 
00256 /*
00257  *  USB Device Suspend Function
00258  *   Called automatically on USB Device Suspend
00259  *    Return Value:    None
00260  */
00261 
00262 void USBD_Suspend(void)
00263 {
00264     UDPHS->UDPHS_IEN  &= ~UDPHS_IEN_DET_SUSPD;
00265     UDPHS->UDPHS_IEN  |=  UDPHS_IEN_WAKE_UP;
00266 }
00267 
00268 
00269 /*
00270  *  USB Device Resume Function
00271  *   Called automatically on USB Device Resume
00272  *    Return Value:    None
00273  */
00274 
00275 void USBD_Resume(void)
00276 {
00277     UDPHS->UDPHS_IEN  &= ~UDPHS_IEN_WAKE_UP;
00278     UDPHS->UDPHS_IEN  |=  UDPHS_IEN_DET_SUSPD;
00279 }
00280 
00281 
00282 /*
00283  *  USB Device Remote Wakeup Function
00284  *   Called automatically on USB Device Remote Wakeup
00285  *    Return Value:    None
00286  */
00287 
00288 void USBD_WakeUp(void)
00289 {
00290     UDPHS->UDPHS_IEN  |=  UDPHS_IEN_UPSTR_RES;
00291     UDPHS->UDPHS_CTRL |=  UDPHS_CTRL_REWAKEUP;
00292 }
00293 
00294 
00295 /*
00296  *  USB Device Remote Wakeup Configuration Function
00297  *    Parameters:      cfg:   Device Enable/Disable
00298  *    Return Value:    None
00299  */
00300 
00301 void USBD_WakeUpCfg(BOOL cfg)
00302 {
00303     if (cfg) {
00304         /* Enable wakeup mechanism */
00305     } else {
00306         UDPHS->UDPHS_CTRL &= ~UDPHS_CTRL_REWAKEUP;
00307         UDPHS->UDPHS_IEN  &= ~UDPHS_IEN_UPSTR_RES;
00308     }
00309 }
00310 
00311 
00312 /*
00313  *  USB Device Set Address Function
00314  *    Parameters:      adr:   USB Device Address
00315  *                     setup: Called in setup stage (!=0), else after status stage
00316  *    Return Value:    None
00317  */
00318 
00319 void USBD_SetAddress(uint32_t adr, uint32_t setup)
00320 {
00321     if (setup) {
00322         return;
00323     }
00324 
00325     if (adr) {
00326         UDPHS->UDPHS_CTRL |= (UDPHS_CTRL_FADDR_EN | adr);
00327     } else {
00328         UDPHS->UDPHS_CTRL &= ~(UDPHS_CTRL_FADDR_EN | UDPHS_CTRL_DEV_ADDR_Msk);
00329     }
00330 }
00331 
00332 
00333 /*
00334  *  USB Device Configure Function
00335  *    Parameters:      cfg:   Device Configure/Deconfigure
00336  *    Return Value:    None
00337  */
00338 
00339 void USBD_Configure(BOOL cfg)
00340 {
00341     /* Performed by Hardware */
00342 }
00343 
00344 
00345 /*
00346  *  Configure USB Device Endpoint according to Descriptor
00347  *    Parameters:      pEPD:  Pointer to Device Endpoint Descriptor
00348  *    Return Value:    None
00349  */
00350 
00351 void USBD_ConfigEP(USB_ENDPOINT_DESCRIPTOR *pEPD)
00352 {
00353     uint32_t num;//, type, dir, size, banks, interval;
00354     num      = pEPD->bEndpointAddress & 0x0F;
00355     /*type     = pEPD->bmAttributes & USB_ENDPOINT_TYPE_MASK;
00356     dir      = pEPD->bEndpointAddress >> 7;
00357     interval = pEPD->bInterval;
00358     size     = USBD_CalcSizeEP(pEPD->wMaxPacketSize);
00359     banks    = 1;
00360     */
00361     /* Check if MaxPacketSize fits for EndPoint                                 */
00362     if (pEPD->wMaxPacketSize <= USBD_GetSizeEP(num)) {
00363         /*UDPHS->UDPHS_EPT[num].UDPHS_EPTCFG    = (interval << 8) |
00364                                                 (banks    << 6) |
00365                                                 (type     << 4) |
00366                                                 (dir      << 3) |
00367                                                 //(size     << 0) ;
00368                                                  6;*/
00369         UDPHS->UDPHS_EPT[num].UDPHS_EPTCTLENB =
00370             (0x1 <<  9) |  /* Received OUT Data Interrupt Enable                    */
00371             (0x1 << 10) |  /* Transmitted IN Data Complete Interrupt Enable         */
00372             (0x0 <<  4) |  /* NYET Disable (Only for High Speed Bulk OUT endpoints) */
00373             (0x1 << 13) ;  /* Stall Sent /ISO CRC Error/Number of Transaction Error */
00374     }
00375 }
00376 
00377 
00378 /*
00379  *  Set Direction for USB Device Control Endpoint
00380  *    Parameters:      dir:   Out (dir == 0), In (dir <> 0)
00381  *    Return Value:    None
00382  */
00383 
00384 void USBD_DirCtrlEP(uint32_t dir)
00385 {
00386     /* Performed by Hardware */
00387 }
00388 
00389 
00390 /*
00391  *  Enable USB Device Endpoint
00392  *    Parameters:      EPNum: Device Endpoint Number
00393  *                       EPNum.0..3: Address
00394  *                       EPNum.7:    Dir
00395  *    Return Value:    None
00396  */
00397 
00398 void USBD_EnableEP(uint32_t EPNum)
00399 {
00400     UDPHS->UDPHS_EPT[EPNum & 0x0F].UDPHS_EPTCTLENB = (0x1 << 0);  /* EP Enable  */
00401     eptsta_copy[EPNum & 0x0F] = UDPHS->UDPHS_EPT[EPNum].UDPHS_EPTSETSTA;
00402 }
00403 
00404 
00405 /*
00406  *  Disable USB Device Endpoint
00407  *    Parameters:      EPNum: Device Endpoint Number
00408  *                       EPNum.0..3: Address
00409  *                       EPNum.7:    Dir
00410  *    Return Value:    None
00411  */
00412 
00413 void USBD_DisableEP(uint32_t EPNum)
00414 {
00415     UDPHS->UDPHS_EPT[EPNum & 0x0F].UDPHS_EPTCTLDIS = (0x1 << 0);  /* EP Disable */
00416     eptsta_copy[EPNum & 0x0F] = UDPHS->UDPHS_EPT[EPNum].UDPHS_EPTSETSTA;
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     EPNum &= 0x0F;
00431     UDPHS->UDPHS_EPT[EPNum].UDPHS_EPTCLRSTA = (0x1 << 6) |  /* Data Toggle Clear*/
00432             (0x1 << 5);   /* Stall Req Set    */
00433     UDPHS->UDPHS_EPTRST |= (1 << EPNum);                    /* Reset endpoint   */
00434     UDPHS->UDPHS_EPTRST &= ~(1 << EPNum);
00435     eptsta_copy[EPNum] = UDPHS->UDPHS_EPT[EPNum].UDPHS_EPTSETSTA;
00436 }
00437 
00438 
00439 /*
00440  *  Set Stall for USB Device Endpoint
00441  *    Parameters:      EPNum: Device Endpoint Number
00442  *                       EPNum.0..3: Address
00443  *                       EPNum.7:    Dir
00444  *    Return Value:    None
00445  */
00446 
00447 void USBD_SetStallEP(uint32_t EPNum)
00448 {
00449     UDPHS->UDPHS_EPT[EPNum & 0x0F].UDPHS_EPTSETSTA = (0x1 << 5);  /* Stall Set  */
00450     eptsta_copy[EPNum & 0x0F] |= 0x1 << 5;
00451 }
00452 
00453 
00454 /*
00455  *  Clear Stall for USB Device Endpoint
00456  *    Parameters:      EPNum: Device Endpoint Number
00457  *                       EPNum.0..3: Address
00458  *                       EPNum.7:    Dir
00459  *    Return Value:    None
00460  */
00461 
00462 void USBD_ClrStallEP(uint32_t EPNum)
00463 {
00464     UDPHS->UDPHS_EPT[EPNum & 0x0F].UDPHS_EPTCLRSTA = (0x1 << 6) | /* Clr Toggle */
00465             (0x1 << 5);  /* Stall Clear*/
00466     eptsta_copy[EPNum & 0x0F] &= ~(0x1 << 5);
00467 }
00468 
00469 
00470 /*
00471  *  Read USB Device Endpoint Data
00472  *    Parameters:      EPNum: Device Endpoint Number
00473  *                       EPNum.0..3: Address
00474  *                       EPNum.7:    Dir
00475  *                     pData: Pointer to Data Buffer
00476  *    Return Value:    Number of bytes read
00477  */
00478 
00479 uint32_t USBD_ReadEP(uint32_t EPNum, uint8_t *pData, uint32_t size)
00480 {
00481     uint32_t cnt, n, copy_sz;
00482     uint8_t *pEPFIFO;                                /* Pointer to EP FIFO           */
00483     uint32_t eptsta;
00484     EPNum  &= 0x0F;
00485     eptsta = eptsta_copy[EPNum];
00486     pEPFIFO = (uint8_t *)((uint32_t *)UDPHS_EPTFIFO_BASE + (16384 * EPNum));
00487     cnt     = (eptsta >> 20) & 0x07FF;  /* Get by */
00488     copy_sz = cnt > size ? size : cnt;
00489 
00490     for (n = 0; n < copy_sz; n++) {
00491         *pData++ = *pEPFIFO++;
00492     }
00493 
00494     util_assert(cnt == copy_sz);
00495 
00496     if ((cnt == copy_sz) && (eptsta & (0x1 << 9))) {
00497         UDPHS->UDPHS_EPT[EPNum].UDPHS_EPTCLRSTA = (0x1 << 9);   /* Rece OUT Clear   */
00498     }
00499 
00500     /* RX_Setup must be cleared after Setup packet is read                      */
00501     if (eptsta & (0x1 << 12)) {
00502         UDPHS->UDPHS_EPT[EPNum].UDPHS_EPTCLRSTA = (0x1 << 12);  /* Rece SETUP Clear */
00503     }
00504     UDPHS->UDPHS_IEN |= (1 << (EPNum + 8));     /* Enable EP int after data read*/
00505     return (cnt);
00506 }
00507 
00508 
00509 /*
00510  *  Write USB Device Endpoint Data
00511  *    Parameters:      EPNum: Device Endpoint Number
00512  *                       EPNum.0..3: Address
00513  *                       EPNum.7:    Dir
00514  *                     pData: Pointer to Data Buffer
00515  *                     cnt:   Number of bytes to write
00516  *    Return Value:    Number of bytes written
00517  */
00518 
00519 uint32_t USBD_WriteEP(uint32_t EPNum, uint8_t *pData, uint32_t cnt)
00520 {
00521     uint32_t n;
00522     uint8_t *pEPFIFO;                          /* Pointer to the endpoint FIFO       */
00523     uint32_t eptsta;
00524     EPNum &= 0x0F;
00525     eptsta = eptsta_copy[EPNum];
00526 
00527     // Cached value should match the real value
00528     util_assert((UDPHS->UDPHS_EPT[EPNum].UDPHS_EPTSTA & (0x1 << 5)) == (eptsta & (0x1 << 5)));
00529     if (eptsta & (0x1 << 5)) {  /* If EP is stall */
00530         return (cnt);
00531     }
00532 
00533     // Both register and cached value should indicate that the bank is ready (bit 11 clear)
00534     util_assert(!(UDPHS->UDPHS_EPT[EPNum].UDPHS_EPTSTA & (0x1 << 11)));
00535     util_assert(!(eptsta & (0x1 << 11)));
00536 
00537     pEPFIFO = (uint8_t *)((uint32_t *)UDPHS_EPTFIFO_BASE + (16384 * EPNum));
00538 
00539     for (n = 0; n < cnt; n++) {
00540         *pEPFIFO++ = *pData++;              /* Write data to FIFO                 */
00541     }
00542 
00543     UDPHS->UDPHS_EPT[EPNum].UDPHS_EPTSETSTA = (0x1 << 11);  /* Set packet ready */
00544     return (cnt);
00545 }
00546 
00547 
00548 /*
00549  *  Get USB Device Last Frame Number
00550  *    Parameters:      None
00551  *    Return Value:    Frame Number
00552  */
00553 
00554 uint32_t USBD_GetFrame(void)
00555 {
00556     uint32_t val;
00557 
00558     if ((UDPHS->UDPHS_FNUM & (1UL << 31)) == 0) {
00559         if (USBD_HighSpeed) {
00560             val = UDPHS->UDPHS_FNUM & 0x7FFFFFFF;
00561         } else {
00562             val = (UDPHS->UDPHS_FNUM & UDPHS_FNUM_FRAME_NUMBER_Msk) >> 3;
00563         }
00564     } else {
00565         val = 0xFFFFFFFF;
00566     }
00567 
00568     return (val);
00569 }
00570 
00571 
00572 #ifdef __RTX
00573 uint32_t LastError;                          /* Last Error                         */
00574 
00575 /*
00576  *  Get USB Device Last Error Code
00577  *    Parameters:      None
00578  *    Return Value:    Error Code
00579  */
00580 
00581 uint32_t USBD_GetError(void)
00582 {
00583     return (LastError);
00584 }
00585 #endif
00586 
00587 
00588 /*
00589  *  USB Device Interrupt Service Routine
00590  */
00591 
00592 void UDPHS_IRQHandler(void)
00593 {
00594     NVIC_DisableIRQ(UDPHS_IRQn);
00595     USBD_SignalHandler();
00596 }
00597 
00598 /*
00599  *  USB Device Service Routine
00600  */
00601 
00602 void USBD_Handler(void)
00603 {
00604     uint32_t intsta, eptsta, n;
00605     intsta = UDPHS->UDPHS_INTSTA & UDPHS->UDPHS_IEN;
00606 
00607     /* End of Bus Reset Interrupt                                               */
00608     if (intsta & UDPHS_INTSTA_ENDRESET) {
00609         /* Get used speed (HighSpeed or FullSpeed)                                */
00610         USBD_HighSpeed = (UDPHS->UDPHS_INTSTA & UDPHS_INTSTA_SPEED) ? 1 : 0;
00611         USBD_Reset();
00612         usbd_reset_core();
00613 #ifdef __RTX
00614         UDPHS->UDPHS_CLRINT = UDPHS_CLRINT_ENDRESET;
00615 
00616         if (USBD_RTX_DevTask) {
00617             isr_evt_set(USBD_EVT_RESET, USBD_RTX_DevTask);
00618         }
00619 
00620 #else
00621 
00622         if (USBD_P_Reset_Event) {
00623             USBD_P_Reset_Event();
00624         }
00625 
00626         UDPHS->UDPHS_CLRINT = UDPHS_CLRINT_ENDRESET;
00627 #endif
00628     }
00629 
00630     /* USB Suspend Interrupt                                                    */
00631     if (intsta & UDPHS_INTSTA_DET_SUSPD) {
00632         USBD_Suspend();
00633 #ifdef __RTX
00634         UDPHS->UDPHS_CLRINT = UDPHS_CLRINT_DET_SUSPD;
00635 
00636         if (USBD_RTX_DevTask) {
00637             isr_evt_set(USBD_EVT_SUSPEND, USBD_RTX_DevTask);
00638         }
00639 
00640 #else
00641 
00642         if (USBD_P_Suspend_Event) {
00643             USBD_P_Suspend_Event();
00644         }
00645 
00646         UDPHS->UDPHS_CLRINT = UDPHS_CLRINT_DET_SUSPD;
00647 #endif
00648     }
00649 
00650     /* USB Resume Interrupt                                                     */
00651     if (intsta & UDPHS_INTSTA_WAKE_UP) {
00652         USBD_Resume();
00653 #ifdef __RTX
00654         UDPHS->UDPHS_CLRINT = UDPHS_INTSTA_WAKE_UP;
00655 
00656         if (USBD_RTX_DevTask) {
00657             isr_evt_set(USBD_EVT_RESUME,  USBD_RTX_DevTask);
00658         }
00659 
00660 #else
00661 
00662         if (USBD_P_Resume_Event) {
00663             USBD_P_Resume_Event();
00664         }
00665 
00666         UDPHS->UDPHS_CLRINT = UDPHS_INTSTA_WAKE_UP;
00667 #endif
00668     }
00669 
00670     /* USB Remote Wakeup Interrupt                                              */
00671     if (intsta & UDPHS_INTSTA_UPSTR_RES) {
00672         UDPHS->UDPHS_CLRINT = UDPHS_INTSTA_UPSTR_RES;
00673     }
00674 
00675     /* Start of Frame Interrupt                                                 */
00676     if (intsta & UDPHS_INTSTA_INT_SOF) {
00677         /* Process the SOF interrupt even in high speed mode.
00678         The SOF and MICRO_SOF interrupt are never generated at the same
00679         time. Instead, when in high speed mode there is 1 SOF
00680         interrupt and 7 MICRO_SOF interrupts every 1ms. */
00681 
00682 #ifdef __RTX
00683         UDPHS->UDPHS_CLRINT = UDPHS_CLRINT_INT_SOF;
00684 
00685         if (USBD_RTX_DevTask) {
00686             isr_evt_set(USBD_EVT_SOF, USBD_RTX_DevTask);
00687         }
00688 
00689 #else
00690 
00691         if (USBD_P_SOF_Event) {
00692             USBD_P_SOF_Event();
00693         }
00694 
00695         UDPHS->UDPHS_CLRINT = UDPHS_CLRINT_INT_SOF;
00696 #endif
00697     }
00698 
00699     /* Micro Frame Interrupt                                                    */
00700     if (intsta & UDPHS_INTSTA_MICRO_SOF) {
00701         if (USBD_HighSpeed == 1) {
00702 #ifdef __RTX
00703             UDPHS->UDPHS_CLRINT = UDPHS_CLRINT_MICRO_SOF;
00704 
00705             if (USBD_RTX_DevTask) {
00706                 isr_evt_set(USBD_EVT_SOF, USBD_RTX_DevTask);
00707             }
00708 
00709 #else
00710 
00711             if (USBD_P_SOF_Event) {
00712                 USBD_P_SOF_Event();
00713             }
00714 
00715             UDPHS->UDPHS_CLRINT = UDPHS_CLRINT_MICRO_SOF;
00716 #endif
00717 
00718         } else {
00719             UDPHS->UDPHS_CLRINT = UDPHS_CLRINT_MICRO_SOF;
00720         }
00721     }
00722 
00723     /* Endpoint Interrupts                                                      */
00724     for (n = 0; n <= USBD_EP_NUM; n++) {
00725         if (intsta & (1 << (n + 8))) {
00726             eptsta = UDPHS->UDPHS_EPT[n].UDPHS_EPTSTA;  /* Read EP status           */
00727             eptsta_copy[n] = eptsta;
00728 
00729             /* Data Packet Sent Interrupt                                           */
00730             if (eptsta & (1 << 10)) {         /* Transmitted IN Data Complete Int   */
00731                 UDPHS->UDPHS_EPT[n].UDPHS_EPTCLRSTA = (1 << 10);    /* Tx IN Clear    */
00732 #ifdef __RTX
00733 
00734                 if (USBD_RTX_EPTask[n]) {       /* IN Packet                          */
00735                     isr_evt_set(USBD_EVT_IN,  USBD_RTX_EPTask[n]);
00736                 }
00737 
00738 #else
00739 
00740                 if (USBD_P_EP[n]) {
00741                     USBD_P_EP[n](USBD_EVT_IN);
00742                 }
00743 
00744 #endif
00745             }
00746 
00747             /* Data Packet Received Interrupt                                       */
00748             if (eptsta & (1 << 9)) {          /* Received OUT Data Interrupt        */
00749                 UDPHS->UDPHS_IEN &= ~(1 << (n + 8));      /* Disable EP int until read*/
00750 #ifdef __RTX
00751 
00752                 if (USBD_RTX_EPTask[n]) {       /* OUT Packet                         */
00753                     isr_evt_set(USBD_EVT_OUT, USBD_RTX_EPTask[n]);
00754                 }
00755 
00756 #else
00757 
00758                 if (USBD_P_EP[n]) {
00759                     USBD_P_EP[n](USBD_EVT_OUT);
00760                 }
00761 
00762 #endif
00763             }
00764 
00765             /* STALL Packet Sent Interrupt                                          */
00766             if (eptsta & (0x1 << 13)) {       /* Stall Sent                         */
00767                 if ((UDPHS->UDPHS_EPT[n].UDPHS_EPTCFG & UDPHS_EPTCFG_EPT_TYPE_Msk) == UDPHS_EPTCFG_EPT_TYPE_CTRL8) {
00768 #ifdef __RTX
00769 
00770                     if (USBD_RTX_EPTask[n]) {
00771                         isr_evt_set(USBD_EVT_IN_STALL, USBD_RTX_EPTask[n]);
00772                     }
00773 
00774 #else
00775 
00776                     if (USBD_P_EP[n]) {
00777                         USBD_P_EP[n](USBD_EVT_IN_STALL);
00778                     }
00779 
00780 #endif
00781                 }
00782 
00783                 UDPHS->UDPHS_EPT[n].UDPHS_EPTCLRSTA = UDPHS_EPTCLRSTA_STALL_SNT;
00784             }
00785 
00786             /* Setup Packet Received Interrupt                                      */
00787             if (eptsta & (0x1 << 12)) {       /* Received SETUP Interrupt           */
00788                 UDPHS->UDPHS_IEN &= ~(1 << (n + 8));      /* Disable EP int until read*/
00789 #ifdef __RTX
00790 
00791                 if (USBD_RTX_EPTask[n]) {       /* SETUP Packet                       */
00792                     isr_evt_set(USBD_EVT_SETUP, USBD_RTX_EPTask[n]);
00793                 }
00794 
00795 #else
00796 
00797                 if (USBD_P_EP[n]) {
00798                     USBD_P_EP[n](USBD_EVT_SETUP);
00799                 }
00800 
00801 #endif
00802             }
00803         }
00804     }
00805 
00806     NVIC_EnableIRQ(UDPHS_IRQn);
00807 }