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_ATSAM3U2C.c
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 }
Generated on Tue Jul 12 2022 15:37:26 by
1.7.2