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