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.
usbhw.c
00001 /*---------------------------------------------------------------------------- 00002 * U S B - K e r n e l 00003 *---------------------------------------------------------------------------- 00004 * Name: usbhw.c 00005 * Purpose: USB Hardware Layer Module for NXP's LPC17xx MCU 00006 * Version: V1.20 00007 *---------------------------------------------------------------------------- 00008 * This software is supplied "AS IS" without any warranties, express, 00009 * implied or statutory, including but not limited to the implied 00010 * warranties of fitness for purpose, satisfactory quality and 00011 * noninfringement. Keil extends you a royalty-free right to reproduce 00012 * and distribute executable files created using this software for use 00013 * on NXP Semiconductors LPC family microcontroller devices only. Nothing 00014 * else gives you the right to use this software. 00015 * 00016 * Copyright (c) 2009 Keil - An ARM Company. All rights reserved. 00017 *---------------------------------------------------------------------------- 00018 * History: 00019 * V1.20 Added USB_ClearEPBuf 00020 * V1.00 Initial Version 00021 *----------------------------------------------------------------------------*/ 00022 #include "LPC17xx.h" /* LPC17xx definitions */ 00023 //#include "LPC23xx.h" 00024 #include "usb.h" 00025 #include "usbcfg.h" 00026 #include "usbreg.h" 00027 #include "usbhw.h" 00028 #include "usbcore.h" 00029 #include "usbuser.h" 00030 00031 00032 #pragma diag_suppress 1441 00033 00034 00035 #define EP_MSK_CTRL 0x0001 /* Control Endpoint Logical Address Mask */ 00036 #define EP_MSK_BULK 0xC924 /* Bulk Endpoint Logical Address Mask */ 00037 #define EP_MSK_INT 0x4492 /* Interrupt Endpoint Logical Address Mask */ 00038 #define EP_MSK_ISO 0x1248 /* Isochronous Endpoint Logical Address Mask */ 00039 00040 00041 #if USB_DMA 00042 00043 #pragma arm section zidata = "USB_RAM" 00044 uint32_t UDCA[USB_EP_NUM]; /* UDCA in USB RAM */ 00045 uint32_t DD_NISO_Mem[4*DD_NISO_CNT]; /* Non-Iso DMA Descriptor Memory */ 00046 uint32_t DD_ISO_Mem [5*DD_ISO_CNT]; /* Iso DMA Descriptor Memory */ 00047 #pragma arm section zidata 00048 uint32_t udca[USB_EP_NUM]; /* UDCA saved values */ 00049 00050 uint32_t DDMemMap[2]; /* DMA Descriptor Memory Usage */ 00051 00052 #endif 00053 00054 00055 /* 00056 * Get Endpoint Physical Address 00057 * Parameters: EPNum: Endpoint Number 00058 * EPNum.0..3: Address 00059 * EPNum.7: Dir 00060 * Return Value: Endpoint Physical Address 00061 */ 00062 00063 uint32_t EPAdr (uint32_t EPNum) { 00064 uint32_t val; 00065 00066 val = (EPNum & 0x0F) << 1; 00067 if (EPNum & 0x80) { 00068 val += 1; 00069 } 00070 return (val); 00071 } 00072 00073 00074 /* 00075 * Write Command 00076 * Parameters: cmd: Command 00077 * Return Value: None 00078 */ 00079 00080 void WrCmd (uint32_t cmd) { 00081 00082 LPC_USB->USBDevIntClr = CCEMTY_INT; 00083 LPC_USB->USBCmdCode = cmd; 00084 while ((LPC_USB->USBDevIntSt & CCEMTY_INT) == 0); 00085 } 00086 00087 00088 /* 00089 * Write Command Data 00090 * Parameters: cmd: Command 00091 * val: Data 00092 * Return Value: None 00093 */ 00094 00095 void WrCmdDat (uint32_t cmd, uint32_t val) { 00096 00097 LPC_USB->USBDevIntClr = CCEMTY_INT; 00098 LPC_USB->USBCmdCode = cmd; 00099 while ((LPC_USB->USBDevIntSt & CCEMTY_INT) == 0); 00100 LPC_USB->USBDevIntClr = CCEMTY_INT; 00101 LPC_USB->USBCmdCode = val; 00102 while ((LPC_USB->USBDevIntSt & CCEMTY_INT) == 0); 00103 } 00104 00105 00106 /* 00107 * Write Command to Endpoint 00108 * Parameters: cmd: Command 00109 * val: Data 00110 * Return Value: None 00111 */ 00112 00113 void WrCmdEP (uint32_t EPNum, uint32_t cmd){ 00114 00115 LPC_USB->USBDevIntClr = CCEMTY_INT; 00116 LPC_USB->USBCmdCode = CMD_SEL_EP(EPAdr(EPNum)); 00117 while ((LPC_USB->USBDevIntSt & CCEMTY_INT) == 0); 00118 LPC_USB->USBDevIntClr = CCEMTY_INT; 00119 LPC_USB->USBCmdCode = cmd; 00120 while ((LPC_USB->USBDevIntSt & CCEMTY_INT) == 0); 00121 } 00122 00123 00124 /* 00125 * Read Command Data 00126 * Parameters: cmd: Command 00127 * Return Value: Data Value 00128 */ 00129 00130 uint32_t RdCmdDat (uint32_t cmd) { 00131 00132 LPC_USB->USBDevIntClr = CCEMTY_INT | CDFULL_INT; 00133 LPC_USB->USBCmdCode = cmd; 00134 while ((LPC_USB->USBDevIntSt & CDFULL_INT) == 0); 00135 return (LPC_USB->USBCmdData); 00136 } 00137 00138 00139 /* 00140 * USB Initialize Function 00141 * Called by the User to initialize USB 00142 * Return Value: None 00143 */ 00144 00145 void USB_Init (void) { 00146 00147 LPC_PINCON->PINSEL1 &= ~((3<<26)|(3<<28)); /* P0.29 D+, P0.30 D- */ 00148 LPC_PINCON->PINSEL1 |= ((1<<26)|(1<<28)); /* PINSEL1 26.27, 28.29 = 01 */ 00149 00150 LPC_PINCON->PINSEL3 &= ~((3<< 4)|(3<<28)); /* P1.18 GoodLink, P1.30 VBUS */ 00151 LPC_PINCON->PINSEL3 |= ((1<< 4)|(2<<28)); /* PINSEL3 4.5 = 01, 28.29 = 10 */ 00152 00153 LPC_PINCON->PINSEL4 &= ~((3<<18) ); /* P2.9 SoftConnect */ 00154 LPC_PINCON->PINSEL4 |= ((1<<18) ); /* PINSEL4 18.19 = 01 */ 00155 00156 LPC_SC->PCONP |= (1UL<<31); /* USB PCLK -> enable USB Per. */ 00157 00158 LPC_USB->USBClkCtrl = 0x1A; /* Dev, PortSel, AHB clock enable */ 00159 while ((LPC_USB->USBClkSt & 0x1A) != 0x1A); 00160 00161 NVIC_EnableIRQ(USB_IRQn); /* enable USB interrupt */ 00162 00163 USB_Reset(); 00164 USB_SetAddress(0); 00165 } 00166 00167 00168 /* 00169 * USB Connect Function 00170 * Called by the User to Connect/Disconnect USB 00171 * Parameters: con: Connect/Disconnect 00172 * Return Value: None 00173 */ 00174 00175 void USB_Connect (uint32_t con) { 00176 WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(con ? DEV_CON : 0)); 00177 } 00178 00179 00180 /* 00181 * USB Reset Function 00182 * Called automatically on USB Reset 00183 * Return Value: None 00184 */ 00185 00186 void USB_Reset (void) { 00187 #if USB_DMA 00188 uint32_t n; 00189 #endif 00190 00191 LPC_USB->USBEpInd = 0; 00192 LPC_USB->USBMaxPSize = USB_MAX_PACKET0; 00193 LPC_USB->USBEpInd = 1; 00194 LPC_USB->USBMaxPSize = USB_MAX_PACKET0; 00195 while ((LPC_USB->USBDevIntSt & EP_RLZED_INT) == 0); 00196 00197 LPC_USB->USBEpIntClr = 0xFFFFFFFF; 00198 LPC_USB->USBEpIntEn = 0xFFFFFFFF ^ USB_DMA_EP; 00199 LPC_USB->USBDevIntClr = 0xFFFFFFFF; 00200 LPC_USB->USBDevIntEn = DEV_STAT_INT | EP_SLOW_INT | 00201 (USB_SOF_EVENT ? FRAME_INT : 0) | 00202 (USB_ERROR_EVENT ? ERR_INT : 0); 00203 00204 #if USB_DMA 00205 LPC_USB->USBUDCAH = USB_RAM_ADR; 00206 LPC_USB->USBDMARClr = 0xFFFFFFFF; 00207 LPC_USB->USBEpDMADis = 0xFFFFFFFF; 00208 LPC_USB->USBEpDMAEn = USB_DMA_EP; 00209 LPC_USB->USBEoTIntClr = 0xFFFFFFFF; 00210 LPC_USB->USBNDDRIntClr = 0xFFFFFFFF; 00211 LPC_USB->USBSysErrIntClr = 0xFFFFFFFF; 00212 LPC_USB->USBDMAIntEn = 0x00000007; 00213 DDMemMap[0] = 0x00000000; 00214 DDMemMap[1] = 0x00000000; 00215 for (n = 0; n < USB_EP_NUM; n++) { 00216 udca[n] = 0; 00217 UDCA[n] = 0; 00218 } 00219 #endif 00220 } 00221 00222 00223 /* 00224 * USB Suspend Function 00225 * Called automatically on USB Suspend 00226 * Return Value: None 00227 */ 00228 00229 void USB_Suspend (void) { 00230 /* Performed by Hardware */ 00231 } 00232 00233 00234 /* 00235 * USB Resume Function 00236 * Called automatically on USB Resume 00237 * Return Value: None 00238 */ 00239 00240 void USB_Resume (void) { 00241 /* Performed by Hardware */ 00242 } 00243 00244 00245 /* 00246 * USB Remote Wakeup Function 00247 * Called automatically on USB Remote Wakeup 00248 * Return Value: None 00249 */ 00250 00251 void USB_WakeUp (void) { 00252 00253 if (USB_DeviceStatus & USB_GETSTATUS_REMOTE_WAKEUP) { 00254 WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(DEV_CON)); 00255 } 00256 } 00257 00258 00259 /* 00260 * USB Remote Wakeup Configuration Function 00261 * Parameters: cfg: Enable/Disable 00262 * Return Value: None 00263 */ 00264 00265 void USB_WakeUpCfg (uint32_t cfg) { 00266 /* Not needed */ 00267 } 00268 00269 00270 /* 00271 * USB Set Address Function 00272 * Parameters: adr: USB Address 00273 * Return Value: None 00274 */ 00275 00276 void USB_SetAddress (uint32_t adr) { 00277 WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Don't wait for next */ 00278 WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Setup Status Phase */ 00279 } 00280 00281 00282 /* 00283 * USB Configure Function 00284 * Parameters: cfg: Configure/Deconfigure 00285 * Return Value: None 00286 */ 00287 00288 void USB_Configure (uint32_t cfg) { 00289 00290 WrCmdDat(CMD_CFG_DEV, DAT_WR_BYTE(cfg ? CONF_DVICE : 0)); 00291 00292 LPC_USB->USBReEp = 0x00000003; 00293 while ((LPC_USB->USBDevIntSt & EP_RLZED_INT) == 0); 00294 LPC_USB->USBDevIntClr = EP_RLZED_INT; 00295 } 00296 00297 00298 /* 00299 * Configure USB Endpoint according to Descriptor 00300 * Parameters: pEPD: Pointer to Endpoint Descriptor 00301 * Return Value: None 00302 */ 00303 00304 void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD) { 00305 uint32_t num; 00306 00307 num = EPAdr(pEPD->bEndpointAddress); 00308 LPC_USB->USBReEp |= (1 << num); 00309 LPC_USB->USBEpInd = num; 00310 LPC_USB->USBMaxPSize = pEPD->wMaxPacketSize; 00311 while ((LPC_USB->USBDevIntSt & EP_RLZED_INT) == 0); 00312 LPC_USB->USBDevIntClr = EP_RLZED_INT; 00313 } 00314 00315 00316 /* 00317 * Set Direction for USB Control Endpoint 00318 * Parameters: dir: Out (dir == 0), In (dir <> 0) 00319 * Return Value: None 00320 */ 00321 00322 void USB_DirCtrlEP (uint32_t dir) { 00323 /* Not needed */ 00324 } 00325 00326 00327 /* 00328 * Enable USB Endpoint 00329 * Parameters: EPNum: Endpoint Number 00330 * EPNum.0..3: Address 00331 * EPNum.7: Dir 00332 * Return Value: None 00333 */ 00334 00335 void USB_EnableEP (uint32_t EPNum) { 00336 WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); 00337 } 00338 00339 00340 /* 00341 * Disable USB Endpoint 00342 * Parameters: EPNum: Endpoint Number 00343 * EPNum.0..3: Address 00344 * EPNum.7: Dir 00345 * Return Value: None 00346 */ 00347 00348 void USB_DisableEP (uint32_t EPNum) { 00349 WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_DA)); 00350 } 00351 00352 00353 /* 00354 * Reset USB Endpoint 00355 * Parameters: EPNum: Endpoint Number 00356 * EPNum.0..3: Address 00357 * EPNum.7: Dir 00358 * Return Value: None 00359 */ 00360 00361 void USB_ResetEP (uint32_t EPNum) { 00362 WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); 00363 } 00364 00365 00366 /* 00367 * Set Stall for USB Endpoint 00368 * Parameters: EPNum: Endpoint Number 00369 * EPNum.0..3: Address 00370 * EPNum.7: Dir 00371 * Return Value: None 00372 */ 00373 00374 void USB_SetStallEP (uint32_t EPNum) { 00375 WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_ST)); 00376 } 00377 00378 00379 /* 00380 * Clear Stall for USB Endpoint 00381 * Parameters: EPNum: Endpoint Number 00382 * EPNum.0..3: Address 00383 * EPNum.7: Dir 00384 * Return Value: None 00385 */ 00386 00387 void USB_ClrStallEP (uint32_t EPNum) { 00388 WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0)); 00389 } 00390 00391 00392 /* 00393 * Clear USB Endpoint Buffer 00394 * Parameters: EPNum: Endpoint Number 00395 * EPNum.0..3: Address 00396 * EPNum.7: Dir 00397 * Return Value: None 00398 */ 00399 00400 void USB_ClearEPBuf (uint32_t EPNum) { 00401 WrCmdEP(EPNum, CMD_CLR_BUF); 00402 } 00403 00404 00405 /* 00406 * Read USB Endpoint Data 00407 * Parameters: EPNum: Endpoint Number 00408 * EPNum.0..3: Address 00409 * EPNum.7: Dir 00410 * pData: Pointer to Data Buffer 00411 * Return Value: Number of bytes read 00412 */ 00413 00414 uint32_t USB_ReadEP (uint32_t EPNum, uint8_t *pData) { 00415 uint32_t cnt, n; 00416 00417 LPC_USB->USBCtrl = ((EPNum & 0x0F) << 2) | CTRL_RD_EN; 00418 00419 do { 00420 cnt = LPC_USB->USBRxPLen; 00421 } while ((cnt & PKT_RDY) == 0); 00422 cnt &= PKT_LNGTH_MASK; 00423 00424 for (n = 0; n < (cnt + 3) / 4; n++) { 00425 *((__packed uint32_t *)pData) = LPC_USB->USBRxData; 00426 pData += 4; 00427 } 00428 LPC_USB->USBCtrl = 0; 00429 00430 if (((EP_MSK_ISO >> EPNum) & 1) == 0) { /* Non-Isochronous Endpoint */ 00431 WrCmdEP(EPNum, CMD_CLR_BUF); 00432 } 00433 00434 return (cnt); 00435 } 00436 00437 00438 /* 00439 * Write USB Endpoint Data 00440 * Parameters: EPNum: Endpoint Number 00441 * EPNum.0..3: Address 00442 * EPNum.7: Dir 00443 * pData: Pointer to Data Buffer 00444 * cnt: Number of bytes to write 00445 * Return Value: Number of bytes written 00446 */ 00447 00448 uint32_t USB_WriteEP (uint32_t EPNum, uint8_t *pData, uint32_t cnt) { 00449 uint32_t n; 00450 00451 LPC_USB->USBCtrl = ((EPNum & 0x0F) << 2) | CTRL_WR_EN; 00452 00453 LPC_USB->USBTxPLen = cnt; 00454 00455 for (n = 0; n < (cnt + 3) / 4; n++) { 00456 LPC_USB->USBTxData = *((__packed uint32_t *)pData); 00457 pData += 4; 00458 } 00459 LPC_USB->USBCtrl = 0; 00460 WrCmdEP(EPNum, CMD_VALID_BUF); 00461 return (cnt); 00462 } 00463 00464 #if USB_DMA 00465 00466 /* DMA Descriptor Memory Layout */ 00467 const uint32_t DDAdr[2] = { DD_NISO_ADR, DD_ISO_ADR }; 00468 const uint32_t DDSz [2] = { 16, 20 }; 00469 00470 00471 /* 00472 * Setup USB DMA Transfer for selected Endpoint 00473 * Parameters: EPNum: Endpoint Number 00474 * pDD: Pointer to DMA Descriptor 00475 * Return Value: TRUE - Success, FALSE - Error 00476 */ 00477 00478 uint32_t USB_DMA_Setup(uint32_t EPNum, USB_DMA_DESCRIPTOR *pDD) { 00479 uint32_t num, ptr, nxt, iso, n; 00480 00481 iso = pDD->Cfg.Type.IsoEP; /* Iso or Non-Iso Descriptor */ 00482 num = EPAdr(EPNum); /* Endpoint's Physical Address */ 00483 00484 ptr = 0; /* Current Descriptor */ 00485 nxt = udca[num]; /* Initial Descriptor */ 00486 while (nxt) { /* Go through Descriptor List */ 00487 ptr = nxt; /* Current Descriptor */ 00488 if (!pDD->Cfg.Type.Link) { /* Check for Linked Descriptors */ 00489 n = (ptr - DDAdr[iso]) / DDSz[iso]; /* Descriptor Index */ 00490 DDMemMap[iso] &= ~(1 << n); /* Unmark Memory Usage */ 00491 } 00492 nxt = *((uint32_t *)ptr); /* Next Descriptor */ 00493 } 00494 00495 for (n = 0; n < 32; n++) { /* Search for available Memory */ 00496 if ((DDMemMap[iso] & (1 << n)) == 0) { 00497 break; /* Memory found */ 00498 } 00499 } 00500 if (n == 32) return (FALSE); /* Memory not available */ 00501 00502 DDMemMap[iso] |= 1 << n; /* Mark Memory Usage */ 00503 nxt = DDAdr[iso] + n * DDSz[iso]; /* Next Descriptor */ 00504 00505 if (ptr && pDD->Cfg.Type.Link) { 00506 *((uint32_t *)(ptr + 0)) = nxt; /* Link in new Descriptor */ 00507 *((uint32_t *)(ptr + 4)) |= 0x00000004; /* Next DD is Valid */ 00508 } else { 00509 udca[num] = nxt; /* Save new Descriptor */ 00510 UDCA[num] = nxt; /* Update UDCA in USB */ 00511 } 00512 00513 /* Fill in DMA Descriptor */ 00514 *(((uint32_t *)nxt)++) = 0; /* Next DD Pointer */ 00515 *(((uint32_t *)nxt)++) = pDD->Cfg.Type.ATLE | 00516 (pDD->Cfg.Type.IsoEP << 4) | 00517 (pDD->MaxSize << 5) | 00518 (pDD->BufLen << 16); 00519 *(((uint32_t *)nxt)++) = pDD->BufAdr; 00520 *(((uint32_t *)nxt)++) = pDD->Cfg.Type.LenPos << 8; 00521 if (iso) { 00522 *((uint32_t *)nxt) = pDD->InfoAdr; 00523 } 00524 00525 return (TRUE); /* Success */ 00526 } 00527 00528 00529 /* 00530 * Enable USB DMA Endpoint 00531 * Parameters: EPNum: Endpoint Number 00532 * EPNum.0..3: Address 00533 * EPNum.7: Dir 00534 * Return Value: None 00535 */ 00536 00537 void USB_DMA_Enable (uint32_t EPNum) { 00538 LPC_USB->USBEpDMAEn = 1 << EPAdr(EPNum); 00539 } 00540 00541 00542 /* 00543 * Disable USB DMA Endpoint 00544 * Parameters: EPNum: Endpoint Number 00545 * EPNum.0..3: Address 00546 * EPNum.7: Dir 00547 * Return Value: None 00548 */ 00549 00550 void USB_DMA_Disable (uint32_t EPNum) { 00551 LPC_USB->USBEpDMADis = 1 << EPAdr(EPNum); 00552 } 00553 00554 00555 /* 00556 * Get USB DMA Endpoint Status 00557 * Parameters: EPNum: Endpoint Number 00558 * EPNum.0..3: Address 00559 * EPNum.7: Dir 00560 * Return Value: DMA Status 00561 */ 00562 00563 uint32_t USB_DMA_Status (uint32_t EPNum) { 00564 uint32_t ptr, val; 00565 00566 ptr = UDCA[EPAdr(EPNum)]; /* Current Descriptor */ 00567 if (ptr == 0) 00568 return (USB_DMA_INVALID); 00569 00570 val = *((uint32_t *)(ptr + 3*4)); /* Status Information */ 00571 switch ((val >> 1) & 0x0F) { 00572 case 0x00: /* Not serviced */ 00573 return (USB_DMA_IDLE); 00574 case 0x01: /* Being serviced */ 00575 return (USB_DMA_BUSY); 00576 case 0x02: /* Normal Completition */ 00577 return (USB_DMA_DONE); 00578 case 0x03: /* Data Under Run */ 00579 return (USB_DMA_UNDER_RUN); 00580 case 0x08: /* Data Over Run */ 00581 return (USB_DMA_OVER_RUN); 00582 case 0x09: /* System Error */ 00583 return (USB_DMA_ERROR); 00584 } 00585 00586 return (USB_DMA_UNKNOWN); 00587 } 00588 00589 00590 /* 00591 * Get USB DMA Endpoint Current Buffer Address 00592 * Parameters: EPNum: Endpoint Number 00593 * EPNum.0..3: Address 00594 * EPNum.7: Dir 00595 * Return Value: DMA Address (or -1 when DMA is Invalid) 00596 */ 00597 00598 uint32_t USB_DMA_BufAdr (uint32_t EPNum) { 00599 uint32_t ptr, val; 00600 00601 ptr = UDCA[EPAdr(EPNum)]; /* Current Descriptor */ 00602 if (ptr == 0) 00603 { 00604 return ((uint32_t)(-1)); /* DMA Invalid */ 00605 } 00606 00607 val = *((uint32_t *)(ptr + 2*4)); /* Buffer Address */ 00608 return (val); /* Current Address */ 00609 } 00610 00611 00612 /* 00613 * Get USB DMA Endpoint Current Buffer Count 00614 * Number of transfered Bytes or Iso Packets 00615 * Parameters: EPNum: Endpoint Number 00616 * EPNum.0..3: Address 00617 * EPNum.7: Dir 00618 * Return Value: DMA Count (or -1 when DMA is Invalid) 00619 */ 00620 00621 uint32_t USB_DMA_BufCnt (uint32_t EPNum) { 00622 uint32_t ptr, val; 00623 00624 ptr = UDCA[EPAdr(EPNum)]; /* Current Descriptor */ 00625 if (ptr == 0) 00626 { 00627 return ((uint32_t)(-1)); /* DMA Invalid */ 00628 } 00629 val = *((uint32_t *)(ptr + 3*4)); /* Status Information */ 00630 return (val >> 16); /* Current Count */ 00631 } 00632 00633 00634 #endif /* USB_DMA */ 00635 00636 00637 /* 00638 * Get USB Last Frame Number 00639 * Parameters: None 00640 * Return Value: Frame Number 00641 */ 00642 00643 uint32_t USB_GetFrame (void) { 00644 uint32_t val; 00645 00646 WrCmd(CMD_RD_FRAME); 00647 val = RdCmdDat(DAT_RD_FRAME); 00648 val = val | (RdCmdDat(DAT_RD_FRAME) << 8); 00649 00650 return (val); 00651 } 00652 00653 00654 /* 00655 * USB Interrupt Service Routine 00656 */ 00657 00658 void USB_IRQHandler (void) { 00659 uint32_t disr, val, n, m; 00660 uint32_t episr, episrCur; 00661 00662 disr = LPC_USB->USBDevIntSt; /* Device Interrupt Status */ 00663 00664 /* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */ 00665 if (disr & DEV_STAT_INT) { 00666 LPC_USB->USBDevIntClr = DEV_STAT_INT; 00667 WrCmd(CMD_GET_DEV_STAT); 00668 val = RdCmdDat(DAT_GET_DEV_STAT); /* Device Status */ 00669 if (val & DEV_RST) { /* Reset */ 00670 USB_Reset(); 00671 #if USB_RESET_EVENT 00672 USB_Reset_Event(); 00673 #endif 00674 } 00675 if (val & DEV_CON_CH) { /* Connect change */ 00676 #if USB_POWER_EVENT 00677 USB_Power_Event(val & DEV_CON); 00678 #endif 00679 } 00680 if (val & DEV_SUS_CH) { /* Suspend/Resume */ 00681 if (val & DEV_SUS) { /* Suspend */ 00682 USB_Suspend(); 00683 #if USB_SUSPEND_EVENT 00684 USB_Suspend_Event(); 00685 #endif 00686 } else { /* Resume */ 00687 USB_Resume(); 00688 #if USB_RESUME_EVENT 00689 USB_Resume_Event(); 00690 #endif 00691 } 00692 } 00693 goto isr_end; 00694 } 00695 00696 #if USB_SOF_EVENT 00697 /* Start of Frame Interrupt */ 00698 if (disr & FRAME_INT) { 00699 USB_SOF_Event(); 00700 } 00701 #endif 00702 00703 #if USB_ERROR_EVENT 00704 /* Error Interrupt */ 00705 if (disr & ERR_INT) { 00706 WrCmd(CMD_RD_ERR_STAT); 00707 val = RdCmdDat(DAT_RD_ERR_STAT); 00708 USB_Error_Event(val); 00709 } 00710 #endif 00711 00712 /* Endpoint's Slow Interrupt */ 00713 if (disr & EP_SLOW_INT) { 00714 episrCur = 0; 00715 episr = LPC_USB->USBEpIntSt; 00716 for (n = 0; n < USB_EP_NUM; n++) { /* Check All Endpoints */ 00717 if (episr == episrCur) break; /* break if all EP interrupts handled */ 00718 if (episr & (1 << n)) { 00719 episrCur |= (1 << n); 00720 m = n >> 1; 00721 00722 LPC_USB->USBEpIntClr = (1 << n); 00723 while ((LPC_USB->USBDevIntSt & CDFULL_INT) == 0); 00724 val = LPC_USB->USBCmdData; 00725 00726 if ((n & 1) == 0) { /* OUT Endpoint */ 00727 if (n == 0) { /* Control OUT Endpoint */ 00728 if (val & EP_SEL_STP) { /* Setup Packet */ 00729 if (USB_P_EP[0]) { 00730 USB_P_EP[0](USB_EVT_SETUP); 00731 continue; 00732 } 00733 } 00734 } 00735 if (USB_P_EP[m]) { 00736 USB_P_EP[m](USB_EVT_OUT); 00737 } 00738 } else { /* IN Endpoint */ 00739 if (USB_P_EP[m]) { 00740 USB_P_EP[m](USB_EVT_IN); 00741 } 00742 } 00743 } 00744 } 00745 LPC_USB->USBDevIntClr = EP_SLOW_INT; 00746 } 00747 00748 #if USB_DMA 00749 00750 if (LPC_USB->USBDMAIntSt & 0x00000001) { /* End of Transfer Interrupt */ 00751 val = LPC_USB->USBEoTIntSt; 00752 for (n = 2; n < USB_EP_NUM; n++) { /* Check All Endpoints */ 00753 if (val & (1 << n)) { 00754 m = n >> 1; 00755 if ((n & 1) == 0) { /* OUT Endpoint */ 00756 if (USB_P_EP[m]) { 00757 USB_P_EP[m](USB_EVT_OUT_DMA_EOT); 00758 } 00759 } else { /* IN Endpoint */ 00760 if (USB_P_EP[m]) { 00761 USB_P_EP[m](USB_EVT_IN_DMA_EOT); 00762 } 00763 } 00764 } 00765 } 00766 LPC_USB->USBEoTIntClr = val; 00767 } 00768 00769 if (LPC_USB->USBDMAIntSt & 0x00000002) { /* New DD Request Interrupt */ 00770 val = LPC_USB->USBNDDRIntSt; 00771 for (n = 2; n < USB_EP_NUM; n++) { /* Check All Endpoints */ 00772 if (val & (1 << n)) { 00773 m = n >> 1; 00774 if ((n & 1) == 0) { /* OUT Endpoint */ 00775 if (USB_P_EP[m]) { 00776 USB_P_EP[m](USB_EVT_OUT_DMA_NDR); 00777 } 00778 } else { /* IN Endpoint */ 00779 if (USB_P_EP[m]) { 00780 USB_P_EP[m](USB_EVT_IN_DMA_NDR); 00781 } 00782 } 00783 } 00784 } 00785 LPC_USB->USBNDDRIntClr = val; 00786 } 00787 00788 if (LPC_USB->USBDMAIntSt & 0x00000004) { /* System Error Interrupt */ 00789 val = LPC_USB->USBSysErrIntSt; 00790 for (n = 2; n < USB_EP_NUM; n++) { /* Check All Endpoints */ 00791 if (val & (1 << n)) { 00792 m = n >> 1; 00793 if ((n & 1) == 0) { /* OUT Endpoint */ 00794 if (USB_P_EP[m]) { 00795 USB_P_EP[m](USB_EVT_OUT_DMA_ERR); 00796 } 00797 } else { /* IN Endpoint */ 00798 if (USB_P_EP[m]) { 00799 USB_P_EP[m](USB_EVT_IN_DMA_ERR); 00800 } 00801 } 00802 } 00803 } 00804 LPC_USB->USBSysErrIntClr = val; 00805 } 00806 00807 #endif /* USB_DMA */ 00808 00809 isr_end: 00810 return; 00811 }
Generated on Thu Jul 14 2022 04:45:41 by
1.7.2