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_LPC11U.cpp Source File

USBBusInterface_LPC11U.cpp

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