ADC Niose test Connect four analog signals to your MBED. and then run the Windows app. The four traces are displayed on an oscilloscope like display. I have used a USB HID DEVICE link, so connections to D+, D- are required. The MBED code is otherwise quite basic, So you can modify it to your own test needs. Additionaly, there is a 16 bit count value, in my MBED code Mainly to test if MSB & LSB are correct.

Dependencies:   mbed

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 {
00110     // The command phase of a SIE transaction
00111     LPC_USB->USBDevIntClr = CCEMPTY;
00112     LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_COMMAND, command);
00113     while (!(LPC_USB->USBDevIntSt & CCEMPTY));
00114 }
00115 
00116 static void SIEWriteData(uint8_t data)
00117 {
00118     // The data write phase of a SIE transaction
00119     LPC_USB->USBDevIntClr = CCEMPTY;
00120     LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_WRITE, data);
00121     while (!(LPC_USB->USBDevIntSt & CCEMPTY));
00122 }
00123 
00124 static uint8_t SIEReadData(uint32_t command)
00125 {
00126     // The data read phase of a SIE transaction
00127     LPC_USB->USBDevIntClr = CDFULL;
00128     LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_READ, command);
00129     while (!(LPC_USB->USBDevIntSt & CDFULL));
00130     return (uint8_t)LPC_USB->USBCmdData;
00131 }
00132 
00133 static void SIEsetDeviceStatus(uint8_t status)
00134 {
00135     // Write SIE device status register
00136     SIECommand(SIE_CMD_SET_DEVICE_STATUS);
00137     SIEWriteData(status);
00138 }
00139 
00140 static uint8_t SIEgetDeviceStatus(void)
00141 {
00142     // Read SIE device status register
00143     SIECommand(SIE_CMD_GET_DEVICE_STATUS);
00144     return SIEReadData(SIE_CMD_GET_DEVICE_STATUS);
00145 }
00146 
00147 void SIEsetAddress(uint8_t address)
00148 {
00149     // Write SIE device address register
00150     SIECommand(SIE_CMD_SET_ADDRESS);
00151     SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN);
00152 }
00153 
00154 static uint8_t SIEselectEndpoint(uint8_t endpoint)
00155 {
00156     // SIE select endpoint command
00157     SIECommand(SIE_CMD_SELECT_ENDPOINT(endpoint));
00158     return SIEReadData(SIE_CMD_SELECT_ENDPOINT(endpoint));
00159 }
00160 
00161 static uint8_t SIEclearBuffer(void)
00162 {
00163     // SIE clear buffer command
00164     SIECommand(SIE_CMD_CLEAR_BUFFER);
00165     return SIEReadData(SIE_CMD_CLEAR_BUFFER);
00166 }
00167 
00168 static void SIEvalidateBuffer(void)
00169 {
00170     // SIE validate buffer command
00171     SIECommand(SIE_CMD_VALIDATE_BUFFER);
00172 }
00173 
00174 static void SIEsetEndpointStatus(uint8_t endpoint, uint8_t status)
00175 {
00176     // SIE set endpoint status command
00177     SIECommand(SIE_CMD_SET_ENDPOINT_STATUS(endpoint));
00178     SIEWriteData(status);
00179 }
00180 
00181 static uint16_t SIEgetFrameNumber(void) __attribute__ ((unused));
00182 static uint16_t SIEgetFrameNumber(void)
00183 {
00184     // Read current frame number
00185     uint16_t lowByte;
00186     uint16_t highByte;
00187 
00188     SIECommand(SIE_CMD_READ_FRAME_NUMBER);
00189     lowByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER);
00190     highByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER);
00191 
00192     return (highByte << 8) | lowByte;
00193 }
00194 
00195 static void SIEconfigureDevice(void)
00196 {
00197     // SIE Configure device command
00198     SIECommand(SIE_CMD_CONFIGURE_DEVICE);
00199     SIEWriteData(SIE_CONF_DEVICE);
00200 }
00201 
00202 static void SIEunconfigureDevice(void)
00203 {
00204     // SIE Configure device command
00205     SIECommand(SIE_CMD_CONFIGURE_DEVICE);
00206     SIEWriteData(0);
00207 }
00208 
00209 static void SIEconnect(void)
00210 {
00211     // Connect USB device
00212     uint8_t status;
00213 
00214     status = SIEgetDeviceStatus();
00215     SIEsetDeviceStatus(status | SIE_DS_CON);
00216 }
00217 
00218 
00219 static void SIEdisconnect(void)
00220 {
00221     // Disconnect USB device
00222     uint8_t status;
00223 
00224     status = SIEgetDeviceStatus();
00225     SIEsetDeviceStatus(status & ~SIE_DS_CON);
00226 }
00227 
00228 
00229 static uint8_t selectEndpointClearInterrupt(uint8_t endpoint)
00230 {
00231     // Implemented using using EP_INT_CLR.
00232     LPC_USB->USBEpIntClr = EP(endpoint);
00233     while (!(LPC_USB->USBDevIntSt & CDFULL));
00234     return (uint8_t)LPC_USB->USBCmdData;
00235 }
00236 
00237 
00238 
00239 
00240 
00241 static void enableEndpointEvent(uint8_t endpoint)
00242 {
00243     // Enable an endpoint interrupt
00244     LPC_USB->USBEpIntEn |= EP(endpoint);
00245 }
00246 
00247 static void disableEndpointEvent(uint8_t endpoint) __attribute__ ((unused));
00248 static void disableEndpointEvent(uint8_t endpoint)
00249 {
00250     // Disable an endpoint interrupt
00251     LPC_USB->USBEpIntEn &= ~EP(endpoint);
00252 }
00253 
00254 static volatile uint32_t __attribute__((used)) dummyRead;
00255 
00256 
00257 static uint32_t endpointReadcore(uint8_t endpoint, uint8_t *buffer)
00258 {
00259     // Read from an OUT endpoint
00260     uint32_t size;
00261     uint32_t i;
00262     uint32_t data = 0;
00263     uint8_t offset;
00264 
00265     LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | RD_EN;
00266     while (!(LPC_USB->USBRxPLen & PKT_RDY));
00267 
00268     size = LPC_USB->USBRxPLen & PKT_LNGTH_MASK;
00269 
00270     offset = 0;
00271 
00272     if (size > 0)
00273     {
00274         for (i=0; i<size; i++)
00275         {
00276             if (offset==0)
00277             {
00278                 // Fetch up to four bytes of data as a word
00279                 data = LPC_USB->USBRxData;
00280             }
00281 
00282             // extract a byte
00283             *buffer = (data>>offset) & 0xff;
00284             buffer++;
00285 
00286             // move on to the next byte
00287             offset = (offset + 8) % 32;
00288         }
00289     }
00290     else
00291     {
00292         dummyRead = LPC_USB->USBRxData;
00293     }
00294 
00295     SIEselectEndpoint(endpoint);
00296     SIEclearBuffer();
00297     return size;
00298 }
00299 
00300 static void endpointWritecore(uint8_t endpoint, uint8_t *buffer, uint32_t size)
00301 {
00302     // Write to an IN endpoint
00303     uint32_t temp, data;
00304     uint8_t offset;
00305 
00306     LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | WR_EN;
00307 
00308     LPC_USB->USBTxPLen = size;
00309     offset = 0;
00310     data = 0;
00311 
00312     if (size>0)
00313     {
00314         do {
00315             // Fetch next data byte into a word-sized temporary variable
00316             temp = *buffer++;
00317 
00318             // Add to current data word
00319             temp = temp << offset;
00320             data = data | temp;
00321 
00322             // move on to the next byte
00323             offset = (offset + 8) % 32;
00324             size--;
00325 
00326             if ((offset==0) || (size==0))
00327             {
00328                 // Write the word to the endpoint
00329                 LPC_USB->USBTxData = data;
00330                 data = 0;
00331             }
00332         } while (size>0);
00333     }
00334     else
00335     {
00336         LPC_USB->USBTxData = 0;
00337     }
00338 
00339     // Clear WR_EN to cover zero length packet case
00340     LPC_USB->USBCtrl=0;
00341 
00342     SIEselectEndpoint(endpoint);
00343     SIEvalidateBuffer();
00344 }
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 USBHAL::USBHAL(void)
00353 {
00354     // Disable IRQ
00355     NVIC_DisableIRQ(USB_IRQn);
00356 
00357     // Enable power to USB device controller
00358     LPC_SC->PCONP |= PCUSB;
00359 
00360     // Enable USB clocks
00361     LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
00362     while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON));
00363 
00364     // Configure pins P0.29 and P0.30 to be USB D+ and USB D-
00365     LPC_PINCON->PINSEL1 &= 0xc3ffffff;
00366     LPC_PINCON->PINSEL1 |= 0x14000000;
00367 
00368     // Disconnect USB device
00369     SIEdisconnect();
00370 
00371     // Configure pin P2.9 to be Connect
00372     LPC_PINCON->PINSEL4 &= 0xfffcffff;
00373     LPC_PINCON->PINSEL4 |= 0x00040000;
00374 
00375     // Connect must be low for at least 2.5uS
00376     wait(0.3);
00377 
00378     // Set the maximum packet size for the control endpoints
00379     realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0);
00380     realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0);
00381 
00382     // Attach IRQ
00383     instance = this;
00384     NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr);
00385     NVIC_EnableIRQ(USB_IRQn);
00386 
00387     // Enable interrupts for device events and EP0
00388     LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT;
00389     enableEndpointEvent(EP0IN);
00390     enableEndpointEvent(EP0OUT);
00391 }
00392 
00393 USBHAL::~USBHAL(void)
00394 {
00395     // Ensure device disconnected
00396     SIEdisconnect();
00397 
00398     // Disable USB interrupts
00399     NVIC_DisableIRQ(USB_IRQn);
00400 }
00401 
00402 void USBHAL::connect(void)
00403 {
00404     // Connect USB device
00405     SIEconnect();
00406 }
00407 
00408 void USBHAL::disconnect(void)
00409 {
00410     // Disconnect USB device
00411     SIEdisconnect();
00412 }
00413 
00414 void USBHAL::configureDevice(void)
00415 {
00416     SIEconfigureDevice();
00417 }
00418 
00419 void USBHAL::unconfigureDevice(void)
00420 {
00421     SIEunconfigureDevice();
00422 }
00423 
00424 void USBHAL::setAddress(uint8_t address)
00425 {
00426     SIEsetAddress(address);
00427 }
00428 
00429 void USBHAL::EP0setup(uint8_t *buffer)
00430 {
00431     endpointReadcore(EP0OUT, buffer);
00432 }
00433 
00434 void USBHAL::EP0read(void)
00435 {
00436     // Not required
00437 }
00438 
00439 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer)
00440 {
00441     return endpointReadcore(EP0OUT, buffer);
00442 }
00443 
00444 void USBHAL::EP0write(uint8_t *buffer, uint32_t size)
00445 {
00446     endpointWritecore(EP0IN, buffer, size);
00447 }
00448 
00449 void USBHAL::EP0getWriteResult(void)
00450 {
00451     // Not required
00452 }
00453 
00454 void USBHAL::EP0stall(void)
00455 {
00456     // This will stall both control endpoints
00457     stallEndpoint(EP0OUT);
00458 }
00459 
00460 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize)
00461 {
00462     return EP_PENDING;
00463 }
00464 
00465 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead)
00466 {
00467     if(!(epComplete & EP(endpoint)))
00468         return EP_PENDING;
00469     *bytesRead = endpointReadcore(endpoint, buffer);
00470     epComplete &= ~EP(endpoint);
00471     return EP_COMPLETED;
00472 }
00473 
00474 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size)
00475 {
00476     if (getEndpointStallState(endpoint))
00477     {
00478         return EP_STALLED;
00479     }
00480 
00481     epComplete &= ~EP(endpoint);
00482 
00483     endpointWritecore(endpoint, data, size);
00484     return EP_PENDING;
00485 }
00486 
00487 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint)
00488 {
00489     if (epComplete & EP(endpoint))
00490     {
00491         epComplete &= ~EP(endpoint);
00492         return EP_COMPLETED;
00493     }
00494 
00495     return EP_PENDING;
00496 }
00497 
00498 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags)
00499 {
00500     // Realise an endpoint
00501     LPC_USB->USBDevIntClr = EP_RLZED;
00502     LPC_USB->USBReEp |= EP(endpoint);
00503     LPC_USB->USBEpInd = endpoint;
00504     LPC_USB->USBMaxPSize = maxPacket;
00505 
00506     while (!(LPC_USB->USBDevIntSt & EP_RLZED));
00507     LPC_USB->USBDevIntClr = EP_RLZED;
00508 
00509     // Clear stall state
00510     endpointStallState &= ~EP(endpoint);
00511 
00512     enableEndpointEvent(endpoint);
00513     return true;
00514 }
00515 
00516 void USBHAL::stallEndpoint(uint8_t endpoint)
00517 {
00518     // Stall an endpoint
00519     if ( (endpoint==EP0IN) || (endpoint==EP0OUT) )
00520     {
00521         // Conditionally stall both control endpoints
00522         SIEsetEndpointStatus(EP0OUT, SIE_SES_CND_ST);
00523     }
00524     else
00525     {
00526         SIEsetEndpointStatus(endpoint, SIE_SES_ST);
00527 
00528         // Update stall state
00529         endpointStallState |= EP(endpoint);
00530     }
00531 }
00532 
00533 void USBHAL::unstallEndpoint(uint8_t endpoint)
00534 {
00535     // Unstall an endpoint. The endpoint will also be reinitialised
00536     SIEsetEndpointStatus(endpoint, 0);
00537 
00538     // Update stall state
00539     endpointStallState &= ~EP(endpoint);
00540 }
00541 
00542 bool USBHAL::getEndpointStallState(uint8_t endpoint)
00543 {
00544     // Returns true if endpoint stalled
00545     return endpointStallState & EP(endpoint);
00546 }
00547 
00548 void USBHAL::remoteWakeup(void)
00549 {
00550     // Remote wakeup
00551     uint8_t status;
00552 
00553     // Enable USB clocks
00554     LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
00555     while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON));
00556 
00557     status = SIEgetDeviceStatus();
00558     SIEsetDeviceStatus(status & ~SIE_DS_SUS);
00559 }
00560 
00561 
00562 
00563 
00564 
00565 void USBHAL::_usbisr(void)
00566 {
00567     instance->usbisr();
00568 } 
00569 
00570 DigitalOut ledd(LED1);
00571 void USBHAL::usbisr(void)
00572 { 
00573     uint8_t devStat;
00574 
00575     if (LPC_USB->USBDevIntSt & FRAME)
00576     {
00577         // Start of frame event
00578         SOF(SIEgetFrameNumber());
00579         // Clear interrupt status flag
00580         LPC_USB->USBDevIntClr = FRAME;
00581     }
00582 
00583     if (LPC_USB->USBDevIntSt & DEV_STAT)
00584     {
00585         // Device Status interrupt
00586         // Must clear the interrupt status flag before reading the device status from the SIE
00587         LPC_USB->USBDevIntClr = DEV_STAT;
00588 
00589         // Read device status from SIE
00590         devStat = SIEgetDeviceStatus();
00591 
00592         if (devStat & SIE_DS_RST)
00593         {
00594             // Bus reset
00595             busReset();
00596         }
00597     }
00598 
00599     if (LPC_USB->USBDevIntSt & EP_SLOW)
00600     {
00601         // (Slow) Endpoint Interrupt
00602 
00603         // Process each endpoint interrupt
00604         if (LPC_USB->USBEpIntSt & EP(EP0OUT))
00605         {
00606             if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP)
00607             {
00608                 // this is a setup packet
00609                 EP0setupCallback();
00610             }
00611             else
00612             {
00613                 EP0out();
00614             }
00615             LPC_USB->USBDevIntClr = EP_SLOW;
00616         }
00617 
00618         if (LPC_USB->USBEpIntSt & EP(EP0IN))
00619         {
00620             selectEndpointClearInterrupt(EP0IN);
00621             LPC_USB->USBDevIntClr = EP_SLOW;
00622             EP0in();
00623         }
00624 
00625         // TODO: This should cover all endpoints, not just EP1,2,3:
00626         if (LPC_USB->USBEpIntSt & EP(EP1IN))
00627         {
00628             selectEndpointClearInterrupt(EP1IN);
00629             epComplete |= EP(EP1IN);
00630             LPC_USB->USBDevIntClr = EP_SLOW;
00631         }
00632 
00633         if (LPC_USB->USBEpIntSt & EP(EP1OUT))
00634         {
00635             selectEndpointClearInterrupt(EP1OUT);
00636             epComplete |= EP(EP1OUT);
00637             LPC_USB->USBDevIntClr = EP_SLOW;
00638         }
00639 
00640         if (LPC_USB->USBEpIntSt & EP(EP2IN))
00641         {
00642             ledd = 1;
00643             selectEndpointClearInterrupt(EP2IN);
00644             epComplete |= EP(EP2IN);
00645             LPC_USB->USBDevIntClr = EP_SLOW;
00646             if(EPBULK_IN_callback())
00647                 epComplete &= ~EP(EPBULK_OUT);
00648         }
00649 
00650         if (LPC_USB->USBEpIntSt & EP(EP2OUT))
00651         {
00652             selectEndpointClearInterrupt(EP2OUT);
00653             epComplete |= EP(EP2OUT);
00654             LPC_USB->USBDevIntClr = EP_SLOW;
00655             if(EPBULK_OUT_callback())
00656                 epComplete &= ~EP(EPBULK_OUT);
00657         }
00658 
00659         if (LPC_USB->USBEpIntSt & EP(EP3IN))
00660         {
00661             selectEndpointClearInterrupt(EP3IN);
00662             epComplete |= EP(EP3IN);
00663             LPC_USB->USBDevIntClr = EP_SLOW;
00664         }
00665 
00666         if (LPC_USB->USBEpIntSt & EP(EP3OUT))
00667         {
00668             selectEndpointClearInterrupt(EP3OUT);
00669             epComplete |= EP(EP3OUT);
00670             LPC_USB->USBDevIntClr = EP_SLOW;
00671         }
00672     }
00673 }
00674 
00675 #endif