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 "usb.h" 00024 #include "usbcfg.h" 00025 #include "usbreg.h" 00026 #include "usbhw.h" 00027 #include "usbcore.h" 00028 #include "usbuser.h" 00029 00030 #if defined ( __CC_ARM__ ) 00031 #pragma diag_suppress 1441 00032 #endif 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 Tue Jul 12 2022 17:28:10 by 1.7.2