Suga koubou / Mbed 2 deprecated USB_CDC_MSD_Hello

Dependencies:   ChaNFSSD mbed ChaNFS

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBBusInterface_LPC17_LPC23.cpp Source File

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