Embed:
(wiki syntax)
Show/hide line numbers
USBBusInterface_LPC11U.c
00001 /* USBBusInterface_LPC11U.c */ 00002 /* USB Bus Interface for NXP LPC11Uxx */ 00003 /* Copyright (c) 2011 ARM Limited. All rights reserved. */ 00004 00005 /* Reference: */ 00006 /* NXP UM10462 LPC11U1x User manual Rev. 1 � 14 April 2011 */ 00007 00008 #ifdef TARGET_LPC11U24 00009 00010 #include "USBBusInterface.h" 00011 #include "USBUtils.h" 00012 #include "USBEvents.h" 00013 00014 00015 /* Valid physical endpoint numbers are 0 to (NUMBER_OF_PHYSICAL_ENDPOINTS-1) */ 00016 #define LAST_PHYSICAL_ENDPOINT (NUMBER_OF_PHYSICAL_ENDPOINTS-1) 00017 /* Convert physical endpoint number to register bit */ 00018 #define EP(endpoint) (1UL<<endpoint) 00019 /* Convert physical to logical */ 00020 #define PHY_TO_LOG(endpoint) ((endpoint)>>1) 00021 /* Get endpoint direction */ 00022 #define IN_EP(endpoint) ((endpoint) & 1U ? true : false) 00023 #define OUT_EP(endpoint) ((endpoint) & 1U ? false : true) 00024 00025 /* USB RAM */ 00026 #define USB_RAM_START (0x20004000) 00027 #define USB_RAM_SIZE (0x00000800) 00028 00029 /* SYSAHBCLKCTRL */ 00030 #define CLK_USB (1UL<<14) 00031 #define CLK_USBRAM (1UL<<27) 00032 00033 /* USB Information register */ 00034 #define FRAME_NR(a) ((a) & 0x7ff) /* Frame number */ 00035 00036 /* USB Device Command/Status register */ 00037 #define DEV_ADDR_MASK (0x7f) /* Device address */ 00038 #define DEV_ADDR(a) ((a) & DEV_ADDR_MASK) 00039 #define DEV_EN (1UL<<7) /* Device enable */ 00040 #define SETUP (1UL<<8) /* SETUP token received */ 00041 #define PLL_ON (1UL<<9) /* PLL enabled in suspend */ 00042 #define DCON (1UL<<16) /* Device status - connect */ 00043 #define DSUS (1UL<<17) /* Device status - suspend */ 00044 #define DCON_C (1UL<<24) /* Connect change */ 00045 #define DSUS_C (1UL<<25) /* Suspend change */ 00046 #define DRES_C (1UL<<26) /* Reset change */ 00047 #define VBUSDEBOUNCED (1UL<<28) /* Vbus detected */ 00048 00049 /* Endpoint Command/Status list */ 00050 #define CMDSTS_A (1UL<<31) /* Active */ 00051 #define CMDSTS_D (1UL<<30) /* Disable */ 00052 #define CMDSTS_S (1UL<<29) /* Stall */ 00053 #define CMDSTS_TR (1UL<<28) /* Toggle Reset */ 00054 #define CMDSTS_RF (1UL<<27) /* Rate Feedback mode */ 00055 #define CMDSTS_TV (1UL<<27) /* Toggle Value */ 00056 #define CMDSTS_T (1UL<<26) /* Endpoint Type */ 00057 #define CMDSTS_NBYTES(n) (((n)&0x3ff)<<16) /* Number of bytes */ 00058 #define CMDSTS_ADDRESS_OFFSET(a) (((a)>>6)&0xffff) /* Buffer start address */ 00059 00060 #define BYTES_REMAINING(s) (((s)>>16)&0x3ff) /* Bytes remaining after transfer */ 00061 00062 /* USB Non-endpoint interrupt sources */ 00063 #define FRAME_INT (1UL<<30) 00064 #define DEV_INT (1UL<<31) 00065 00066 /* One entry for a double-buffered logical endpoint in the endpoint */ 00067 /* command/status list. Endpoint 0 is single buffered, out[1] is used */ 00068 /* for the SETUP packet and in[1] is not used */ 00069 typedef __packed struct { 00070 uint32_t out[2]; 00071 uint32_t in[2]; 00072 } EP_COMMAND_STATUS; 00073 00074 typedef __packed struct { 00075 uint8_t out[MAX_PACKET_SIZE_EP0]; 00076 uint8_t in[MAX_PACKET_SIZE_EP0]; 00077 uint8_t setup[SETUP_PACKET_SIZE]; 00078 } CONTROL_TRANSFER; 00079 00080 typedef __packed struct { 00081 uint32_t maxPacket; 00082 uint32_t buffer[2]; 00083 uint32_t options; 00084 } EP_STATE; 00085 00086 static volatile EP_STATE endpointState[NUMBER_OF_PHYSICAL_ENDPOINTS]; 00087 00088 /* Pointer to the endpoint command/status list */ 00089 static EP_COMMAND_STATUS *ep = NULL; 00090 00091 /* Pointer to endpoint 0 data (IN/OUT and SETUP) */ 00092 static CONTROL_TRANSFER *ct = NULL; 00093 00094 /* Shadow DEVCMDSTAT register to avoid accidentally clearing flags or */ 00095 /* initiating a remote wakeup event. */ 00096 static volatile uint32_t devCmdStat; 00097 00098 /* Pointers used to allocate USB RAM */ 00099 static uint32_t usbRamPtr = USB_RAM_START; 00100 static uint32_t epRamPtr = 0; /* Buffers for endpoints > 0 start here */ 00101 00102 /* 00103 * USBBusInterface API 00104 */ 00105 00106 bool USBBusInterface_init(void) 00107 { 00108 NVIC_DisableIRQ(USB_IRQn); 00109 00110 /* USB_VBUS input, Pull down, Hysteresis enabled */ 00111 //LPC_IOCON->PIO0_3 = 0x00000029; 00112 /* nUSB_CONNECT output */ 00113 LPC_IOCON->PIO0_6 = 0x00000001; 00114 00115 /* Enable clocks (USB registers, USB RAM) */ 00116 LPC_SYSCON->SYSAHBCLKCTRL |= CLK_USB | CLK_USBRAM; 00117 00118 /* Ensure device disconnected (DCON not set) */ 00119 LPC_USB->DEVCMDSTAT = 0; 00120 /* Device must be disconnected for at least 2.5uS */ 00121 /* to ensure that the USB host sees the device as */ 00122 /* disconnected if the target CPU is reset. */ 00123 wait(0.3); 00124 00125 00126 /* Reserve space in USB RAM for endpoint command/status list */ 00127 /* Must be 256 byte aligned */ 00128 usbRamPtr = ROUND_UP_TO_MULTIPLE(usbRamPtr, 256); 00129 ep = (EP_COMMAND_STATUS *)usbRamPtr; 00130 usbRamPtr += (sizeof(EP_COMMAND_STATUS) * NUMBER_OF_LOGICAL_ENDPOINTS); 00131 LPC_USB->EPLISTSTART = (uint32_t)(ep) & 0xffffff00; 00132 00133 /* Reserve space in USB RAM for Endpoint 0 */ 00134 /* Must be 64 byte aligned */ 00135 usbRamPtr = ROUND_UP_TO_MULTIPLE(usbRamPtr, 64); 00136 ct = (CONTROL_TRANSFER *)usbRamPtr; 00137 usbRamPtr += sizeof(CONTROL_TRANSFER); 00138 LPC_USB->DATABUFSTART =(uint32_t)(ct) & 0xffc00000; 00139 00140 /* Setup command/status list for EP0 */ 00141 ep[0].out[0] = 0; 00142 ep[0].in[0] = 0; 00143 ep[0].out[1] = CMDSTS_ADDRESS_OFFSET((uint32_t)ct->setup); 00144 00145 /* Route all interrupts to IRQ, some can be routed to */ 00146 /* USB_FIQ if you wish. */ 00147 LPC_USB->INTROUTING = 0; 00148 00149 /* Set device address 0, enable USB device, no remote wakeup */ 00150 devCmdStat = DEV_ADDR(0) | DEV_EN | DSUS; 00151 LPC_USB->DEVCMDSTAT = devCmdStat; 00152 00153 /* Enable interrupts for device events and EP0 */ 00154 LPC_USB->INTEN = DEV_INT | EP(EP0IN) | EP(EP0OUT); 00155 NVIC_EnableIRQ(USB_IRQn); 00156 00157 00158 /* Successful */ 00159 return true; 00160 } 00161 00162 void USBBusInterface_uninit(void) 00163 { 00164 /* Ensure device disconnected (DCON not set) */ 00165 LPC_USB->DEVCMDSTAT = 0; 00166 00167 /* Disable USB interrupts */ 00168 NVIC_DisableIRQ(USB_IRQn); 00169 } 00170 00171 void USBBusInterface_connect(void) 00172 { 00173 devCmdStat |= DCON; 00174 LPC_USB->DEVCMDSTAT = devCmdStat; 00175 } 00176 00177 void USBBusInterface_disconnect(void) 00178 { 00179 devCmdStat &= ~DCON; 00180 LPC_USB->DEVCMDSTAT = devCmdStat; 00181 } 00182 00183 void USBBusInterface_configureDevice(void) 00184 { 00185 } 00186 00187 void USBBusInterface_unconfigureDevice(void) 00188 { 00189 } 00190 00191 void USBBusInterface_EP0setup(uint8_t *buffer) 00192 { 00193 /* Copy setup packet data */ 00194 USBMemCopy(buffer, ct->setup, SETUP_PACKET_SIZE); 00195 } 00196 00197 void USBBusInterface_EP0read(void) 00198 { 00199 /* Start an endpoint 0 read */ 00200 00201 /* The USB ISR will call USBDevice_EP0out() when a packet has been read, */ 00202 /* the USBDevice layer then calls USBBusInterface_EP0getReadResult() to */ 00203 /* read the data. */ 00204 00205 ep[0].out[0] = CMDSTS_A |CMDSTS_NBYTES(MAX_PACKET_SIZE_EP0) \ 00206 | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->out); 00207 } 00208 00209 uint32_t USBBusInterface_EP0getReadResult(uint8_t *buffer) 00210 { 00211 /* Complete an endpoint 0 read */ 00212 uint32_t bytesRead; 00213 00214 /* Find how many bytes were read */ 00215 bytesRead = MAX_PACKET_SIZE_EP0 - BYTES_REMAINING(ep[0].out[0]); 00216 00217 /* Copy data */ 00218 USBMemCopy(buffer, ct->out, bytesRead); 00219 return bytesRead; 00220 } 00221 00222 void USBBusInterface_EP0write(uint8_t *buffer, uint32_t size) 00223 { 00224 /* Start and endpoint 0 write */ 00225 00226 /* The USB ISR will call USBDevice_EP0in() when the data has */ 00227 /* been written, the USBDevice layer then calls */ 00228 /* USBBusInterface_EP0getWriteResult() to complete the transaction. */ 00229 00230 /* Copy data */ 00231 USBMemCopy(ct->in, buffer, size); 00232 00233 /* Start transfer */ 00234 ep[0].in[0] = CMDSTS_A | CMDSTS_NBYTES(size) \ 00235 | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->in); 00236 } 00237 00238 void USBBusInterface_EP0getWriteResult(void) 00239 { 00240 /* Complete an endpoint 0 write */ 00241 00242 /* Nothing required for this target */ 00243 return; 00244 } 00245 00246 void USBBusInterface_EP0stall(void) 00247 { 00248 ep[0].in[0] = CMDSTS_S; 00249 ep[0].out[0] = CMDSTS_S; 00250 } 00251 00252 void USBBusInterface_setAddress(uint8_t address) 00253 { 00254 devCmdStat &= ~DEV_ADDR_MASK; 00255 devCmdStat |= DEV_ADDR(address); 00256 LPC_USB->DEVCMDSTAT = devCmdStat; 00257 } 00258 00259 EP_STATUS USBBusInterface_endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) 00260 { 00261 uint32_t flags = 0; 00262 uint32_t bf; 00263 00264 /* Validate parameters */ 00265 if (data == NULL) 00266 { 00267 return EP_INVALID; 00268 } 00269 00270 if (endpoint > LAST_PHYSICAL_ENDPOINT) 00271 { 00272 return EP_INVALID; 00273 } 00274 00275 if ((endpoint==EP0IN) || (endpoint==EP0OUT)) 00276 { 00277 return EP_INVALID; 00278 } 00279 00280 if (size > endpointState[endpoint].maxPacket) 00281 { 00282 return EP_INVALID; 00283 } 00284 00285 if (LPC_USB->EPBUFCFG & EP(endpoint)) 00286 { 00287 /* Double buffered */ /* TODO: FIX THIS */ 00288 if (LPC_USB->EPINUSE & EP(endpoint)) 00289 { 00290 bf = 1; 00291 } 00292 else 00293 { 00294 bf = 0; 00295 } 00296 } 00297 else 00298 { 00299 /* Single buffered */ 00300 bf = 0; 00301 } 00302 00303 /* Check if already active */ 00304 if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_A) 00305 { 00306 return EP_INVALID; 00307 } 00308 00309 /* Check if stalled */ 00310 if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_S) 00311 { 00312 return EP_STALLED; 00313 } 00314 00315 /* Copy data to USB RAM */ 00316 USBMemCopy((uint8_t *)endpointState[endpoint].buffer[bf], data, size); 00317 00318 /* Add options */ 00319 if (endpointState[endpoint].options & RATE_FEEDBACK_MODE) 00320 { 00321 flags |= CMDSTS_RF; 00322 } 00323 00324 if (endpointState[endpoint].options & ISOCHRONOUS) 00325 { 00326 flags |= CMDSTS_T; 00327 } 00328 00329 /* Add transfer */ 00330 ep[PHY_TO_LOG(endpoint)].in[bf] = CMDSTS_ADDRESS_OFFSET( \ 00331 endpointState[endpoint].buffer[bf]) \ 00332 | CMDSTS_NBYTES(size) | CMDSTS_A | flags; 00333 00334 return EP_PENDING; 00335 } 00336 00337 EP_STATUS USBBusInterface_endpointWriteResult(uint8_t endpoint) 00338 { 00339 uint32_t bf; 00340 /* Validate parameters */ 00341 00342 if (endpoint > LAST_PHYSICAL_ENDPOINT) 00343 { 00344 return EP_INVALID; 00345 } 00346 00347 if (OUT_EP(endpoint)) 00348 { 00349 return EP_INVALID; 00350 } 00351 00352 if (LPC_USB->EPBUFCFG & EP(endpoint)) 00353 { 00354 /* Double buffered */ /* TODO: FIX THIS */ 00355 if (LPC_USB->EPINUSE & EP(endpoint)) 00356 { 00357 bf = 1; 00358 } 00359 else 00360 { 00361 bf = 0; 00362 } 00363 } 00364 else 00365 { 00366 /* Single buffered */ 00367 bf = 0; 00368 } 00369 00370 /* Check if endpoint still active */ 00371 if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_A) 00372 { 00373 return EP_PENDING; 00374 } 00375 00376 /* Check if stalled */ 00377 if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_S) 00378 { 00379 return EP_STALLED; 00380 } 00381 00382 return EP_COMPLETED; 00383 } 00384 00385 void USBBusInterface_stallEndpoint(uint8_t endpoint) 00386 { 00387 00388 // TODO: should this clear active bit? 00389 00390 if (IN_EP(endpoint)) 00391 { 00392 ep[PHY_TO_LOG(endpoint)].in[0] |= CMDSTS_S; 00393 ep[PHY_TO_LOG(endpoint)].in[1] |= CMDSTS_S; 00394 } 00395 else 00396 { 00397 ep[PHY_TO_LOG(endpoint)].out[0] |= CMDSTS_S; 00398 ep[PHY_TO_LOG(endpoint)].out[1] |= CMDSTS_S; 00399 } 00400 } 00401 00402 void USBBusInterface_unstallEndpoint(uint8_t endpoint) 00403 { 00404 if (LPC_USB->EPBUFCFG & EP(endpoint)) 00405 { 00406 /* Double buffered */ 00407 if (IN_EP(endpoint)) 00408 { 00409 ep[PHY_TO_LOG(endpoint)].in[0] = 0; /* S = 0 */ 00410 ep[PHY_TO_LOG(endpoint)].in[1] = 0; /* S = 0 */ 00411 00412 if (LPC_USB->EPINUSE & EP(endpoint)) 00413 { 00414 ep[PHY_TO_LOG(endpoint)].in[1] = CMDSTS_TR; /* S =0, TR=1, TV = 0 */ 00415 } 00416 else 00417 { 00418 ep[PHY_TO_LOG(endpoint)].in[0] = CMDSTS_TR; /* S =0, TR=1, TV = 0 */ 00419 } 00420 } 00421 else 00422 { 00423 ep[PHY_TO_LOG(endpoint)].out[0] = 0; /* S = 0 */ 00424 ep[PHY_TO_LOG(endpoint)].out[1] = 0; /* S = 0 */ 00425 00426 if (LPC_USB->EPINUSE & EP(endpoint)) 00427 { 00428 ep[PHY_TO_LOG(endpoint)].out[1] = CMDSTS_TR; /* S =0, TR=1, TV = 0 */ 00429 } 00430 else 00431 { 00432 ep[PHY_TO_LOG(endpoint)].out[0] = CMDSTS_TR; /* S =0, TR=1, TV = 0 */ 00433 } 00434 } 00435 } 00436 else 00437 { 00438 /* Single buffered */ 00439 if (IN_EP(endpoint)) 00440 { 00441 ep[PHY_TO_LOG(endpoint)].in[0] = CMDSTS_TR; /* S=0, TR=1, TV = 0 */ 00442 } 00443 else 00444 { 00445 ep[PHY_TO_LOG(endpoint)].out[0] = CMDSTS_TR; /* S=0, TR=1, TV = 0 */ 00446 } 00447 } 00448 } 00449 00450 bool USBBusInterface_getEndpointStallState(unsigned char endpoint) 00451 { 00452 if (IN_EP(endpoint)) 00453 { 00454 if (LPC_USB->EPINUSE & EP(endpoint)) 00455 { 00456 if (ep[PHY_TO_LOG(endpoint)].in[1] & CMDSTS_S) 00457 { 00458 return true; 00459 } 00460 } 00461 else 00462 { 00463 if (ep[PHY_TO_LOG(endpoint)].in[0] & CMDSTS_S) 00464 { 00465 return true; 00466 } 00467 } 00468 } 00469 else 00470 { 00471 if (LPC_USB->EPINUSE & EP(endpoint)) 00472 { 00473 if (ep[PHY_TO_LOG(endpoint)].out[1] & CMDSTS_S) 00474 { 00475 return true; 00476 } 00477 } 00478 else 00479 { 00480 if (ep[PHY_TO_LOG(endpoint)].out[0] & CMDSTS_S) 00481 { 00482 return true; 00483 } 00484 } 00485 } 00486 00487 return false; 00488 } 00489 00490 bool USBBusInterface_realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options) 00491 { 00492 uint32_t tmpEpRamPtr; 00493 00494 /* 00495 * 00496 * Support for double buffered endpoints needs to be fixed/finished in this 00497 * software - force single buffered for now. 00498 * 00499 */ 00500 options |= SINGLE_BUFFERED; /* TODO - FIX THIS */ 00501 00502 if (endpoint > LAST_PHYSICAL_ENDPOINT) 00503 { 00504 return false; 00505 } 00506 00507 /* Not applicable to the control endpoints */ 00508 if ((endpoint==EP0IN) || (endpoint==EP0OUT)) 00509 { 00510 return false; 00511 } 00512 00513 /* Allocate buffers in USB RAM */ 00514 tmpEpRamPtr = epRamPtr; 00515 00516 /* Must be 64 byte aligned */ 00517 tmpEpRamPtr = ROUND_UP_TO_MULTIPLE(tmpEpRamPtr, 64); 00518 00519 if ((tmpEpRamPtr + maxPacket) > (USB_RAM_START + USB_RAM_SIZE)) 00520 { 00521 /* Out of memory */ 00522 return false; 00523 } 00524 00525 /* Allocate first buffer */ 00526 endpointState[endpoint].buffer[0] = tmpEpRamPtr; 00527 tmpEpRamPtr += maxPacket; 00528 00529 if (!(options & SINGLE_BUFFERED)) 00530 { 00531 /* Must be 64 byte aligned */ 00532 tmpEpRamPtr = ROUND_UP_TO_MULTIPLE(tmpEpRamPtr, 64); 00533 00534 if ((tmpEpRamPtr + maxPacket) > (USB_RAM_START + USB_RAM_SIZE)) 00535 { 00536 /* Out of memory */ 00537 return false; 00538 } 00539 00540 /* Allocate second buffer */ 00541 endpointState[endpoint].buffer[1] = tmpEpRamPtr; 00542 tmpEpRamPtr += maxPacket; 00543 } 00544 00545 /* Commit to this USB RAM allocation */ 00546 epRamPtr = tmpEpRamPtr; 00547 00548 /* Remaining endpoint state values */ 00549 endpointState[endpoint].maxPacket = maxPacket; 00550 endpointState[endpoint].options = options; 00551 00552 /* Enable double buffering if required */ 00553 if (options & SINGLE_BUFFERED) 00554 { 00555 LPC_USB->EPBUFCFG &= ~EP(endpoint); 00556 } 00557 else 00558 { 00559 /* Double buffered */ 00560 LPC_USB->EPBUFCFG |= EP(endpoint); 00561 } 00562 00563 /* Enable endpoint */ 00564 USBBusInterface_unstallEndpoint(endpoint); 00565 return true; 00566 } 00567 00568 void USBBusInterface_remoteWakeup(void) 00569 { 00570 /* Clearing DSUS bit initiates a remote wakeup if the */ 00571 /* device is currently enabled and suspended - otherwise */ 00572 /* it has no effect. */ 00573 LPC_USB->DEVCMDSTAT = devCmdStat & ~DSUS; 00574 } 00575 00576 /* 00577 * Configuration helper functions 00578 */ 00579 00580 static void disableEndpoints(void) 00581 { 00582 uint32_t logEp; 00583 00584 /* Ref. Table 158 "When a bus reset is received, software */ 00585 /* must set the disable bit of all endpoints to 1".*/ 00586 00587 for (logEp = 1; logEp < NUMBER_OF_LOGICAL_ENDPOINTS; logEp++) 00588 { 00589 ep[logEp].out[0] = CMDSTS_D; 00590 ep[logEp].out[1] = CMDSTS_D; 00591 ep[logEp].in[0] = CMDSTS_D; 00592 ep[logEp].in[1] = CMDSTS_D; 00593 } 00594 00595 /* Start of USB RAM for endpoints > 0 */ 00596 epRamPtr = usbRamPtr; 00597 } 00598 00599 /* 00600 * USB interrupt handler 00601 */ 00602 00603 extern "C" 00604 { 00605 void USB_IRQHandler(void) 00606 { 00607 /* Start of frame */ 00608 if (LPC_USB->INTSTAT & FRAME_INT) 00609 { 00610 /* Clear SOF interrupt */ 00611 LPC_USB->INTSTAT = FRAME_INT; 00612 00613 /* SOF event, read frame number */ 00614 USBDevice_SOF(FRAME_NR(LPC_USB->INFO)); 00615 } 00616 00617 /* Device state */ 00618 if (LPC_USB->INTSTAT & DEV_INT) 00619 { 00620 LPC_USB->INTSTAT = DEV_INT; 00621 00622 if (LPC_USB->DEVCMDSTAT & DCON_C) 00623 { 00624 /* Connect status changed */ 00625 LPC_USB->DEVCMDSTAT = devCmdStat | DCON_C; 00626 00627 USBDevice_connectStateChanged((LPC_USB->DEVCMDSTAT & DCON) != 0); 00628 } 00629 00630 if (LPC_USB->DEVCMDSTAT & DSUS_C) 00631 { 00632 /* Suspend status changed */ 00633 LPC_USB->DEVCMDSTAT = devCmdStat | DSUS_C; 00634 00635 USBDevice_suspendStateChanged((LPC_USB->DEVCMDSTAT & DSUS) != 0); 00636 } 00637 00638 if (LPC_USB->DEVCMDSTAT & DRES_C) 00639 { 00640 /* Bus reset */ 00641 LPC_USB->DEVCMDSTAT = devCmdStat | DRES_C; 00642 00643 /* Disable endpoints > 0 */ 00644 disableEndpoints(); 00645 00646 /* Bus reset event */ 00647 USBDevice_busReset(); 00648 } 00649 } 00650 00651 /* Endpoint 0 */ 00652 if (LPC_USB->INTSTAT & EP(EP0OUT)) 00653 { 00654 /* Clear EP0OUT/SETUP interrupt */ 00655 LPC_USB->INTSTAT = EP(EP0OUT); 00656 00657 /* Check if SETUP */ 00658 if (LPC_USB->DEVCMDSTAT & SETUP) 00659 { 00660 /* Clear Active and Stall bits for EP0 */ 00661 /* Documentation does not make it clear if we must use the */ 00662 /* EPSKIP register to achieve this, Fig. 16 and NXP reference */ 00663 /* code suggests we can just clear the Active bits - check with */ 00664 /* NXP to be sure. */ 00665 ep[0].in[0] = 0; 00666 ep[0].out[0] = 0; 00667 00668 /* Clear EP0IN interrupt */ 00669 LPC_USB->INTSTAT = EP(EP0IN); 00670 00671 /* Clear SETUP (and INTONNAK_CI/O) in device status register */ 00672 LPC_USB->DEVCMDSTAT = devCmdStat | SETUP; 00673 00674 /* EP0 SETUP event (SETUP data received) */ 00675 USBDevice_EP0setup(); 00676 } 00677 else 00678 { 00679 /* EP0OUT ACK event (OUT data received) */ 00680 USBDevice_EP0out(); 00681 } 00682 } 00683 00684 if (LPC_USB->INTSTAT & EP(EP0IN)) 00685 { 00686 /* Clear EP0IN interrupt */ 00687 LPC_USB->INTSTAT = EP(EP0IN); 00688 00689 /* EP0IN ACK event (IN data sent) */ 00690 USBDevice_EP0in(); 00691 } 00692 } 00693 } 00694 00695 #endif
Generated on Fri Jul 15 2022 02:22:27 by 1.7.2