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.
Dependencies: ChaNFSSD mbed ChaNFS
USBBusInterface_LPC17_LPC23.cpp
00001 // USBBusInterface_LPC17_LPC23.c 00002 // USB Bus Interface for NXP LPC1768 and LPC2368 00003 // Copyright (c) 2011 ARM Limited. All rights reserved. 00004 00005 #ifdef TARGET_LPC1768 00006 00007 #include "USBBusInterface.h" 00008 00009 00010 // Get endpoint direction 00011 #define IN_EP(endpoint) ((endpoint) & 1U ? true : false) 00012 #define OUT_EP(endpoint) ((endpoint) & 1U ? false : true) 00013 00014 // Convert physical endpoint number to register bit 00015 #define EP(endpoint) (1UL<<endpoint) 00016 00017 // Power Control for Peripherals register 00018 #define PCUSB (1UL<<31) 00019 00020 // USB Clock Control register 00021 #define DEV_CLK_EN (1UL<<1) 00022 #define AHB_CLK_EN (1UL<<4) 00023 00024 // USB Clock Status register 00025 #define DEV_CLK_ON (1UL<<1) 00026 #define AHB_CLK_ON (1UL<<4) 00027 00028 // USB Device Interupt registers 00029 #define FRAME (1UL<<0) 00030 #define EP_FAST (1UL<<1) 00031 #define EP_SLOW (1UL<<2) 00032 #define DEV_STAT (1UL<<3) 00033 #define CCEMPTY (1UL<<4) 00034 #define CDFULL (1UL<<5) 00035 #define RxENDPKT (1UL<<6) 00036 #define TxENDPKT (1UL<<7) 00037 #define EP_RLZED (1UL<<8) 00038 #define ERR_INT (1UL<<9) 00039 00040 // USB Control register 00041 #define RD_EN (1<<0) 00042 #define WR_EN (1<<1) 00043 #define LOG_ENDPOINT(endpoint) ((endpoint>>1)<<2) 00044 00045 // USB Receive Packet Length register 00046 #define DV (1UL<<10) 00047 #define PKT_RDY (1UL<<11) 00048 #define PKT_LNGTH_MASK (0x3ff) 00049 00050 // Serial Interface Engine (SIE) 00051 #define SIE_WRITE (0x01) 00052 #define SIE_READ (0x02) 00053 #define SIE_COMMAND (0x05) 00054 #define SIE_CMD_CODE(phase, data) ((phase<<8)|(data<<16)) 00055 00056 // SIE Command codes 00057 #define SIE_CMD_SET_ADDRESS (0xD0) 00058 #define SIE_CMD_CONFIGURE_DEVICE (0xD8) 00059 #define SIE_CMD_SET_MODE (0xF3) 00060 #define SIE_CMD_READ_FRAME_NUMBER (0xF5) 00061 #define SIE_CMD_READ_TEST_REGISTER (0xFD) 00062 #define SIE_CMD_SET_DEVICE_STATUS (0xFE) 00063 #define SIE_CMD_GET_DEVICE_STATUS (0xFE) 00064 #define SIE_CMD_GET_ERROR_CODE (0xFF) 00065 #define SIE_CMD_READ_ERROR_STATUS (0xFB) 00066 00067 #define SIE_CMD_SELECT_ENDPOINT(endpoint) (0x00+endpoint) 00068 #define SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint) (0x40+endpoint) 00069 #define SIE_CMD_SET_ENDPOINT_STATUS(endpoint) (0x40+endpoint) 00070 00071 #define SIE_CMD_CLEAR_BUFFER (0xF2) 00072 #define SIE_CMD_VALIDATE_BUFFER (0xFA) 00073 00074 // SIE Device Status register 00075 #define SIE_DS_CON (1<<0) 00076 #define SIE_DS_CON_CH (1<<1) 00077 #define SIE_DS_SUS (1<<2) 00078 #define SIE_DS_SUS_CH (1<<3) 00079 #define SIE_DS_RST (1<<4) 00080 00081 // SIE Device Set Address register 00082 #define SIE_DSA_DEV_EN (1<<7) 00083 00084 // SIE Configue Device register 00085 #define SIE_CONF_DEVICE (1<<0) 00086 00087 // Select Endpoint register 00088 #define SIE_SE_FE (1<<0) 00089 #define SIE_SE_ST (1<<1) 00090 #define SIE_SE_STP (1<<2) 00091 #define SIE_SE_PO (1<<3) 00092 #define SIE_SE_EPN (1<<4) 00093 #define SIE_SE_B_1_FULL (1<<5) 00094 #define SIE_SE_B_2_FULL (1<<6) 00095 00096 // Set Endpoint Status command 00097 #define SIE_SES_ST (1<<0) 00098 #define SIE_SES_DA (1<<5) 00099 #define SIE_SES_RF_MO (1<<6) 00100 #define SIE_SES_CND_ST (1<<7) 00101 00102 00103 USBHAL * USBHAL::instance; 00104 00105 volatile int epComplete; 00106 uint32_t endpointStallState; 00107 00108 static void SIECommand(uint32_t command) { 00109 // The command phase of a SIE transaction 00110 LPC_USB->USBDevIntClr = CCEMPTY; 00111 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_COMMAND, command); 00112 while (!(LPC_USB->USBDevIntSt & CCEMPTY)); 00113 } 00114 00115 static void SIEWriteData(uint8_t data) { 00116 // The data write phase of a SIE transaction 00117 LPC_USB->USBDevIntClr = CCEMPTY; 00118 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_WRITE, data); 00119 while (!(LPC_USB->USBDevIntSt & CCEMPTY)); 00120 } 00121 00122 static uint8_t SIEReadData(uint32_t command) { 00123 // The data read phase of a SIE transaction 00124 LPC_USB->USBDevIntClr = CDFULL; 00125 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_READ, command); 00126 while (!(LPC_USB->USBDevIntSt & CDFULL)); 00127 return (uint8_t)LPC_USB->USBCmdData; 00128 } 00129 00130 static void SIEsetDeviceStatus(uint8_t status) { 00131 // Write SIE device status register 00132 SIECommand(SIE_CMD_SET_DEVICE_STATUS); 00133 SIEWriteData(status); 00134 } 00135 00136 static uint8_t SIEgetDeviceStatus(void) { 00137 // Read SIE device status register 00138 SIECommand(SIE_CMD_GET_DEVICE_STATUS); 00139 return SIEReadData(SIE_CMD_GET_DEVICE_STATUS); 00140 } 00141 00142 void SIEsetAddress(uint8_t address) { 00143 // Write SIE device address register 00144 SIECommand(SIE_CMD_SET_ADDRESS); 00145 SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN); 00146 } 00147 00148 static uint8_t SIEselectEndpoint(uint8_t endpoint) { 00149 // SIE select endpoint command 00150 SIECommand(SIE_CMD_SELECT_ENDPOINT(endpoint)); 00151 return SIEReadData(SIE_CMD_SELECT_ENDPOINT(endpoint)); 00152 } 00153 00154 static uint8_t SIEclearBuffer(void) { 00155 // SIE clear buffer command 00156 SIECommand(SIE_CMD_CLEAR_BUFFER); 00157 return SIEReadData(SIE_CMD_CLEAR_BUFFER); 00158 } 00159 00160 static void SIEvalidateBuffer(void) { 00161 // SIE validate buffer command 00162 SIECommand(SIE_CMD_VALIDATE_BUFFER); 00163 } 00164 00165 static void SIEsetEndpointStatus(uint8_t endpoint, uint8_t status) { 00166 // SIE set endpoint status command 00167 SIECommand(SIE_CMD_SET_ENDPOINT_STATUS(endpoint)); 00168 SIEWriteData(status); 00169 } 00170 00171 static uint16_t SIEgetFrameNumber(void) __attribute__ ((unused)); 00172 static uint16_t SIEgetFrameNumber(void) { 00173 // Read current frame number 00174 uint16_t lowByte; 00175 uint16_t highByte; 00176 00177 SIECommand(SIE_CMD_READ_FRAME_NUMBER); 00178 lowByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER); 00179 highByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER); 00180 00181 return (highByte << 8) | lowByte; 00182 } 00183 00184 static void SIEconfigureDevice(void) { 00185 // SIE Configure device command 00186 SIECommand(SIE_CMD_CONFIGURE_DEVICE); 00187 SIEWriteData(SIE_CONF_DEVICE); 00188 } 00189 00190 static void SIEunconfigureDevice(void) { 00191 // SIE Configure device command 00192 SIECommand(SIE_CMD_CONFIGURE_DEVICE); 00193 SIEWriteData(0); 00194 } 00195 00196 static void SIEconnect(void) { 00197 // Connect USB device 00198 uint8_t status; 00199 00200 status = SIEgetDeviceStatus(); 00201 SIEsetDeviceStatus(status | SIE_DS_CON); 00202 } 00203 00204 00205 static void SIEdisconnect(void) { 00206 // Disconnect USB device 00207 uint8_t status; 00208 00209 status = SIEgetDeviceStatus(); 00210 SIEsetDeviceStatus(status & ~SIE_DS_CON); 00211 } 00212 00213 00214 static uint8_t selectEndpointClearInterrupt(uint8_t endpoint) { 00215 // Implemented using using EP_INT_CLR. 00216 LPC_USB->USBEpIntClr = EP(endpoint); 00217 while (!(LPC_USB->USBDevIntSt & CDFULL)); 00218 return (uint8_t)LPC_USB->USBCmdData; 00219 } 00220 00221 00222 00223 00224 00225 static void enableEndpointEvent(uint8_t endpoint) { 00226 // Enable an endpoint interrupt 00227 LPC_USB->USBEpIntEn |= EP(endpoint); 00228 } 00229 00230 static void disableEndpointEvent(uint8_t endpoint) __attribute__ ((unused)); 00231 static void disableEndpointEvent(uint8_t endpoint) { 00232 // Disable an endpoint interrupt 00233 LPC_USB->USBEpIntEn &= ~EP(endpoint); 00234 } 00235 00236 static volatile uint32_t __attribute__((used)) dummyRead; 00237 00238 00239 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) { 00240 // Read from an OUT endpoint 00241 uint32_t size; 00242 uint32_t i; 00243 uint32_t data = 0; 00244 uint8_t offset; 00245 00246 LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | RD_EN; 00247 while (!(LPC_USB->USBRxPLen & PKT_RDY)); 00248 00249 size = LPC_USB->USBRxPLen & PKT_LNGTH_MASK; 00250 00251 offset = 0; 00252 00253 if (size > 0) { 00254 for (i=0; i<size; i++) { 00255 if (offset==0) { 00256 // Fetch up to four bytes of data as a word 00257 data = LPC_USB->USBRxData; 00258 } 00259 00260 // extract a byte 00261 *buffer = (data>>offset) & 0xff; 00262 buffer++; 00263 00264 // move on to the next byte 00265 offset = (offset + 8) % 32; 00266 } 00267 } else { 00268 dummyRead = LPC_USB->USBRxData; 00269 } 00270 00271 LPC_USB->USBCtrl = 0; 00272 00273 if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) { 00274 SIEselectEndpoint(endpoint); 00275 SIEclearBuffer(); 00276 } 00277 00278 return size; 00279 } 00280 00281 static void endpointWritecore(uint8_t endpoint, uint8_t *buffer, uint32_t size) { 00282 // Write to an IN endpoint 00283 uint32_t temp, data; 00284 uint8_t offset; 00285 00286 LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | WR_EN; 00287 00288 LPC_USB->USBTxPLen = size; 00289 offset = 0; 00290 data = 0; 00291 00292 if (size>0) { 00293 do { 00294 // Fetch next data byte into a word-sized temporary variable 00295 temp = *buffer++; 00296 00297 // Add to current data word 00298 temp = temp << offset; 00299 data = data | temp; 00300 00301 // move on to the next byte 00302 offset = (offset + 8) % 32; 00303 size--; 00304 00305 if ((offset==0) || (size==0)) { 00306 // Write the word to the endpoint 00307 LPC_USB->USBTxData = data; 00308 data = 0; 00309 } 00310 } while (size>0); 00311 } else { 00312 LPC_USB->USBTxData = 0; 00313 } 00314 00315 // Clear WR_EN to cover zero length packet case 00316 LPC_USB->USBCtrl=0; 00317 00318 SIEselectEndpoint(endpoint); 00319 SIEvalidateBuffer(); 00320 } 00321 00322 00323 00324 00325 00326 00327 00328 USBHAL::USBHAL(void) { 00329 // Disable IRQ 00330 NVIC_DisableIRQ(USB_IRQn); 00331 00332 // Enable power to USB device controller 00333 LPC_SC->PCONP |= PCUSB; 00334 00335 // Enable USB clocks 00336 LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN; 00337 while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON)); 00338 00339 // Configure pins P0.29 and P0.30 to be USB D+ and USB D- 00340 LPC_PINCON->PINSEL1 &= 0xc3ffffff; 00341 LPC_PINCON->PINSEL1 |= 0x14000000; 00342 00343 // Disconnect USB device 00344 SIEdisconnect(); 00345 00346 // Configure pin P2.9 to be Connect 00347 LPC_PINCON->PINSEL4 &= 0xfffcffff; 00348 LPC_PINCON->PINSEL4 |= 0x00040000; 00349 00350 // Connect must be low for at least 2.5uS 00351 wait(0.3); 00352 00353 // Set the maximum packet size for the control endpoints 00354 realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0); 00355 realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0); 00356 00357 // Attach IRQ 00358 instance = this; 00359 NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr); 00360 NVIC_EnableIRQ(USB_IRQn); 00361 00362 // Enable interrupts for device events and EP0 00363 LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT | FRAME; 00364 enableEndpointEvent(EP0IN); 00365 enableEndpointEvent(EP0OUT); 00366 } 00367 00368 USBHAL::~USBHAL(void) { 00369 // Ensure device disconnected 00370 SIEdisconnect(); 00371 00372 // Disable USB interrupts 00373 NVIC_DisableIRQ(USB_IRQn); 00374 } 00375 00376 void USBHAL::connect(void) { 00377 // Connect USB device 00378 SIEconnect(); 00379 } 00380 00381 void USBHAL::disconnect(void) { 00382 // Disconnect USB device 00383 SIEdisconnect(); 00384 } 00385 00386 void USBHAL::configureDevice(void) { 00387 SIEconfigureDevice(); 00388 } 00389 00390 void USBHAL::unconfigureDevice(void) { 00391 SIEunconfigureDevice(); 00392 } 00393 00394 void USBHAL::setAddress(uint8_t address) { 00395 SIEsetAddress(address); 00396 } 00397 00398 void USBHAL::EP0setup(uint8_t *buffer) { 00399 endpointReadcore(EP0OUT, buffer); 00400 } 00401 00402 void USBHAL::EP0read(void) { 00403 // Not required 00404 } 00405 00406 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) { 00407 return endpointReadcore(EP0OUT, buffer); 00408 } 00409 00410 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) { 00411 endpointWritecore(EP0IN, buffer, size); 00412 } 00413 00414 void USBHAL::EP0getWriteResult(void) { 00415 // Not required 00416 } 00417 00418 void USBHAL::EP0stall(void) { 00419 // This will stall both control endpoints 00420 stallEndpoint(EP0OUT); 00421 } 00422 00423 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) { 00424 return EP_PENDING; 00425 } 00426 00427 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) { 00428 00429 //for isochronous endpoint, we don't wait an interrupt 00430 if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) { 00431 if (!(epComplete & EP(endpoint))) 00432 return EP_PENDING; 00433 } 00434 00435 *bytesRead = endpointReadcore(endpoint, buffer); 00436 epComplete &= ~EP(endpoint); 00437 return EP_COMPLETED; 00438 } 00439 00440 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) { 00441 if (getEndpointStallState(endpoint)) { 00442 return EP_STALLED; 00443 } 00444 00445 epComplete &= ~EP(endpoint); 00446 00447 endpointWritecore(endpoint, data, size); 00448 return EP_PENDING; 00449 } 00450 00451 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) { 00452 if (epComplete & EP(endpoint)) { 00453 epComplete &= ~EP(endpoint); 00454 return EP_COMPLETED; 00455 } 00456 00457 return EP_PENDING; 00458 } 00459 00460 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) { 00461 // Realise an endpoint 00462 LPC_USB->USBDevIntClr = EP_RLZED; 00463 LPC_USB->USBReEp |= EP(endpoint); 00464 LPC_USB->USBEpInd = endpoint; 00465 LPC_USB->USBMaxPSize = maxPacket; 00466 00467 while (!(LPC_USB->USBDevIntSt & EP_RLZED)); 00468 LPC_USB->USBDevIntClr = EP_RLZED; 00469 00470 // Clear stall state 00471 endpointStallState &= ~EP(endpoint); 00472 00473 enableEndpointEvent(endpoint); 00474 return true; 00475 } 00476 00477 void USBHAL::stallEndpoint(uint8_t endpoint) { 00478 // Stall an endpoint 00479 if ( (endpoint==EP0IN) || (endpoint==EP0OUT) ) { 00480 // Conditionally stall both control endpoints 00481 SIEsetEndpointStatus(EP0OUT, SIE_SES_CND_ST); 00482 } else { 00483 SIEsetEndpointStatus(endpoint, SIE_SES_ST); 00484 00485 // Update stall state 00486 endpointStallState |= EP(endpoint); 00487 } 00488 } 00489 00490 void USBHAL::unstallEndpoint(uint8_t endpoint) { 00491 // Unstall an endpoint. The endpoint will also be reinitialised 00492 SIEsetEndpointStatus(endpoint, 0); 00493 00494 // Update stall state 00495 endpointStallState &= ~EP(endpoint); 00496 } 00497 00498 bool USBHAL::getEndpointStallState(uint8_t endpoint) { 00499 // Returns true if endpoint stalled 00500 return endpointStallState & EP(endpoint); 00501 } 00502 00503 void USBHAL::remoteWakeup(void) { 00504 // Remote wakeup 00505 uint8_t status; 00506 00507 // Enable USB clocks 00508 LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN; 00509 while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON)); 00510 00511 status = SIEgetDeviceStatus(); 00512 SIEsetDeviceStatus(status & ~SIE_DS_SUS); 00513 } 00514 00515 00516 00517 00518 00519 void USBHAL::_usbisr(void) { 00520 instance->usbisr(); 00521 } 00522 00523 00524 void USBHAL::usbisr(void) { 00525 uint8_t devStat; 00526 00527 if (LPC_USB->USBDevIntSt & FRAME) { 00528 // Start of frame event 00529 SOF(SIEgetFrameNumber()); 00530 // Clear interrupt status flag 00531 LPC_USB->USBDevIntClr = FRAME; 00532 } 00533 00534 if (LPC_USB->USBDevIntSt & DEV_STAT) { 00535 // Device Status interrupt 00536 // Must clear the interrupt status flag before reading the device status from the SIE 00537 LPC_USB->USBDevIntClr = DEV_STAT; 00538 00539 // Read device status from SIE 00540 devStat = SIEgetDeviceStatus(); 00541 00542 if (devStat & SIE_DS_RST) { 00543 // Bus reset 00544 busReset(); 00545 } 00546 } 00547 00548 if (LPC_USB->USBDevIntSt & EP_SLOW) { 00549 // (Slow) Endpoint Interrupt 00550 00551 // Process each endpoint interrupt 00552 if (LPC_USB->USBEpIntSt & EP(EP0OUT)) { 00553 if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP) { 00554 // this is a setup packet 00555 EP0setupCallback(); 00556 } else { 00557 EP0out(); 00558 } 00559 LPC_USB->USBDevIntClr = EP_SLOW; 00560 } 00561 00562 if (LPC_USB->USBEpIntSt & EP(EP0IN)) { 00563 selectEndpointClearInterrupt(EP0IN); 00564 LPC_USB->USBDevIntClr = EP_SLOW; 00565 EP0in(); 00566 } 00567 00568 // TODO: This should cover all endpoints, not just EP1,2,3: 00569 if (LPC_USB->USBEpIntSt & EP(EP1IN)) { 00570 selectEndpointClearInterrupt(EP1IN); 00571 epComplete |= EP(EP1IN); 00572 LPC_USB->USBDevIntClr = EP_SLOW; 00573 if (EP1_IN_callback()) 00574 epComplete &= ~EP(EP1IN); 00575 } 00576 00577 if (LPC_USB->USBEpIntSt & EP(EP1OUT)) { 00578 selectEndpointClearInterrupt(EP1OUT); 00579 epComplete |= EP(EP1OUT); 00580 LPC_USB->USBDevIntClr = EP_SLOW; 00581 if (EP1_OUT_callback()) 00582 epComplete &= ~EP(EP1OUT); 00583 } 00584 00585 if (LPC_USB->USBEpIntSt & EP(EP2IN)) { 00586 selectEndpointClearInterrupt(EP2IN); 00587 epComplete |= EP(EP2IN); 00588 LPC_USB->USBDevIntClr = EP_SLOW; 00589 if (EP2_IN_callback()) 00590 epComplete &= ~EP(EP2IN); 00591 } 00592 00593 if (LPC_USB->USBEpIntSt & EP(EP2OUT)) { 00594 selectEndpointClearInterrupt(EP2OUT); 00595 epComplete |= EP(EP2OUT); 00596 LPC_USB->USBDevIntClr = EP_SLOW; 00597 if (EP2_OUT_callback()) 00598 epComplete &= ~EP(EP2OUT); 00599 } 00600 00601 if (LPC_USB->USBEpIntSt & EP(EP3IN)) { 00602 selectEndpointClearInterrupt(EP3IN); 00603 epComplete |= EP(EP3IN); 00604 LPC_USB->USBDevIntClr = EP_SLOW; 00605 if (EP3_IN_callback()) 00606 epComplete &= ~EP(EP3IN); 00607 } 00608 00609 if (LPC_USB->USBEpIntSt & EP(EP3OUT)) { 00610 selectEndpointClearInterrupt(EP3OUT); 00611 epComplete |= EP(EP3OUT); 00612 LPC_USB->USBDevIntClr = EP_SLOW; 00613 if (EP3_OUT_callback()) 00614 epComplete &= ~EP(EP3OUT); 00615 } 00616 00617 if (LPC_USB->USBEpIntSt & EP(EP5IN)) { 00618 selectEndpointClearInterrupt(EP5IN); 00619 epComplete |= EP(EP5IN); 00620 LPC_USB->USBDevIntClr = EP_SLOW; 00621 if (EP5_IN_callback()) 00622 epComplete &= ~EP(EP5IN); 00623 } 00624 00625 if (LPC_USB->USBEpIntSt & EP(EP5OUT)) { 00626 selectEndpointClearInterrupt(EP5OUT); 00627 epComplete |= EP(EP5OUT); 00628 LPC_USB->USBDevIntClr = EP_SLOW; 00629 if (EP5_OUT_callback()) 00630 epComplete &= ~EP(EP5OUT); 00631 } 00632 } 00633 } 00634 00635 #endif
Generated on Wed Jul 13 2022 11:42:57 by
1.7.2