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

Committer:
ceri
Date:
Sat Nov 19 22:54:22 2011 +0000
Revision:
0:cbe01b678bd4
just enough to work

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ceri 0:cbe01b678bd4 1 // USBBusInterface_LPC11U.c
ceri 0:cbe01b678bd4 2 // USB Bus Interface for NXP LPC11Uxx
ceri 0:cbe01b678bd4 3 // Copyright (c) 2011 ARM Limited. All rights reserved.
ceri 0:cbe01b678bd4 4
ceri 0:cbe01b678bd4 5 // Reference:
ceri 0:cbe01b678bd4 6 // NXP UM10462 LPC11U1x User manual Rev. 1 � 14 April 2011
ceri 0:cbe01b678bd4 7
ceri 0:cbe01b678bd4 8 #ifdef TARGET_LPC11U24
ceri 0:cbe01b678bd4 9
ceri 0:cbe01b678bd4 10 #include "USBBusInterface.h"
ceri 0:cbe01b678bd4 11
ceri 0:cbe01b678bd4 12 USBHAL * USBHAL::instance;
ceri 0:cbe01b678bd4 13
ceri 0:cbe01b678bd4 14
ceri 0:cbe01b678bd4 15 // Valid physical endpoint numbers are 0 to (NUMBER_OF_PHYSICAL_ENDPOINTS-1)
ceri 0:cbe01b678bd4 16 #define LAST_PHYSICAL_ENDPOINT (NUMBER_OF_PHYSICAL_ENDPOINTS-1)
ceri 0:cbe01b678bd4 17
ceri 0:cbe01b678bd4 18 // Convert physical endpoint number to register bit
ceri 0:cbe01b678bd4 19 #define EP(endpoint) (1UL<<endpoint)
ceri 0:cbe01b678bd4 20
ceri 0:cbe01b678bd4 21 // Convert physical to logical
ceri 0:cbe01b678bd4 22 #define PHY_TO_LOG(endpoint) ((endpoint)>>1)
ceri 0:cbe01b678bd4 23
ceri 0:cbe01b678bd4 24 // Get endpoint direction
ceri 0:cbe01b678bd4 25 #define IN_EP(endpoint) ((endpoint) & 1U ? true : false)
ceri 0:cbe01b678bd4 26 #define OUT_EP(endpoint) ((endpoint) & 1U ? false : true)
ceri 0:cbe01b678bd4 27
ceri 0:cbe01b678bd4 28 // USB RAM
ceri 0:cbe01b678bd4 29 #define USB_RAM_START (0x20004000)
ceri 0:cbe01b678bd4 30 #define USB_RAM_SIZE (0x00000800)
ceri 0:cbe01b678bd4 31
ceri 0:cbe01b678bd4 32 // SYSAHBCLKCTRL
ceri 0:cbe01b678bd4 33 #define CLK_USB (1UL<<14)
ceri 0:cbe01b678bd4 34 #define CLK_USBRAM (1UL<<27)
ceri 0:cbe01b678bd4 35
ceri 0:cbe01b678bd4 36 // USB Information register
ceri 0:cbe01b678bd4 37 #define FRAME_NR(a) ((a) & 0x7ff) // Frame number
ceri 0:cbe01b678bd4 38
ceri 0:cbe01b678bd4 39 // USB Device Command/Status register
ceri 0:cbe01b678bd4 40 #define DEV_ADDR_MASK (0x7f) // Device address
ceri 0:cbe01b678bd4 41 #define DEV_ADDR(a) ((a) & DEV_ADDR_MASK)
ceri 0:cbe01b678bd4 42 #define DEV_EN (1UL<<7) // Device enable
ceri 0:cbe01b678bd4 43 #define SETUP (1UL<<8) // SETUP token received
ceri 0:cbe01b678bd4 44 #define PLL_ON (1UL<<9) // PLL enabled in suspend
ceri 0:cbe01b678bd4 45 #define DCON (1UL<<16) // Device status - connect
ceri 0:cbe01b678bd4 46 #define DSUS (1UL<<17) // Device status - suspend
ceri 0:cbe01b678bd4 47 #define DCON_C (1UL<<24) // Connect change
ceri 0:cbe01b678bd4 48 #define DSUS_C (1UL<<25) // Suspend change
ceri 0:cbe01b678bd4 49 #define DRES_C (1UL<<26) // Reset change
ceri 0:cbe01b678bd4 50 #define VBUSDEBOUNCED (1UL<<28) // Vbus detected
ceri 0:cbe01b678bd4 51
ceri 0:cbe01b678bd4 52 // Endpoint Command/Status list
ceri 0:cbe01b678bd4 53 #define CMDSTS_A (1UL<<31) // Active
ceri 0:cbe01b678bd4 54 #define CMDSTS_D (1UL<<30) // Disable
ceri 0:cbe01b678bd4 55 #define CMDSTS_S (1UL<<29) // Stall
ceri 0:cbe01b678bd4 56 #define CMDSTS_TR (1UL<<28) // Toggle Reset
ceri 0:cbe01b678bd4 57 #define CMDSTS_RF (1UL<<27) // Rate Feedback mode
ceri 0:cbe01b678bd4 58 #define CMDSTS_TV (1UL<<27) // Toggle Value
ceri 0:cbe01b678bd4 59 #define CMDSTS_T (1UL<<26) // Endpoint Type
ceri 0:cbe01b678bd4 60 #define CMDSTS_NBYTES(n) (((n)&0x3ff)<<16) // Number of bytes
ceri 0:cbe01b678bd4 61 #define CMDSTS_ADDRESS_OFFSET(a) (((a)>>6)&0xffff) // Buffer start address
ceri 0:cbe01b678bd4 62
ceri 0:cbe01b678bd4 63 #define BYTES_REMAINING(s) (((s)>>16)&0x3ff) // Bytes remaining after transfer
ceri 0:cbe01b678bd4 64
ceri 0:cbe01b678bd4 65 // USB Non-endpoint interrupt sources
ceri 0:cbe01b678bd4 66 #define FRAME_INT (1UL<<30)
ceri 0:cbe01b678bd4 67 #define DEV_INT (1UL<<31)
ceri 0:cbe01b678bd4 68
ceri 0:cbe01b678bd4 69 static int epComplete = 0;
ceri 0:cbe01b678bd4 70
ceri 0:cbe01b678bd4 71 // One entry for a double-buffered logical endpoint in the endpoint
ceri 0:cbe01b678bd4 72 // command/status list. Endpoint 0 is single buffered, out[1] is used
ceri 0:cbe01b678bd4 73 // for the SETUP packet and in[1] is not used
ceri 0:cbe01b678bd4 74 typedef __packed struct {
ceri 0:cbe01b678bd4 75 uint32_t out[2];
ceri 0:cbe01b678bd4 76 uint32_t in[2];
ceri 0:cbe01b678bd4 77 } EP_COMMAND_STATUS;
ceri 0:cbe01b678bd4 78
ceri 0:cbe01b678bd4 79 typedef __packed struct {
ceri 0:cbe01b678bd4 80 uint8_t out[MAX_PACKET_SIZE_EP0];
ceri 0:cbe01b678bd4 81 uint8_t in[MAX_PACKET_SIZE_EP0];
ceri 0:cbe01b678bd4 82 uint8_t setup[SETUP_PACKET_SIZE];
ceri 0:cbe01b678bd4 83 } CONTROL_TRANSFER;
ceri 0:cbe01b678bd4 84
ceri 0:cbe01b678bd4 85 typedef __packed struct {
ceri 0:cbe01b678bd4 86 uint32_t maxPacket;
ceri 0:cbe01b678bd4 87 uint32_t buffer[2];
ceri 0:cbe01b678bd4 88 uint32_t options;
ceri 0:cbe01b678bd4 89 } EP_STATE;
ceri 0:cbe01b678bd4 90
ceri 0:cbe01b678bd4 91 static volatile EP_STATE endpointState[NUMBER_OF_PHYSICAL_ENDPOINTS];
ceri 0:cbe01b678bd4 92
ceri 0:cbe01b678bd4 93 // Pointer to the endpoint command/status list
ceri 0:cbe01b678bd4 94 static EP_COMMAND_STATUS *ep = NULL;
ceri 0:cbe01b678bd4 95
ceri 0:cbe01b678bd4 96 // Pointer to endpoint 0 data (IN/OUT and SETUP)
ceri 0:cbe01b678bd4 97 static CONTROL_TRANSFER *ct = NULL;
ceri 0:cbe01b678bd4 98
ceri 0:cbe01b678bd4 99 // Shadow DEVCMDSTAT register to avoid accidentally clearing flags or
ceri 0:cbe01b678bd4 100 // initiating a remote wakeup event.
ceri 0:cbe01b678bd4 101 static volatile uint32_t devCmdStat;
ceri 0:cbe01b678bd4 102
ceri 0:cbe01b678bd4 103 // Pointers used to allocate USB RAM
ceri 0:cbe01b678bd4 104 static uint32_t usbRamPtr = USB_RAM_START;
ceri 0:cbe01b678bd4 105 static uint32_t epRamPtr = 0; // Buffers for endpoints > 0 start here
ceri 0:cbe01b678bd4 106
ceri 0:cbe01b678bd4 107 #define ROUND_UP_TO_MULTIPLE(x, m) ((((x)+((m)-1))/(m))*(m))
ceri 0:cbe01b678bd4 108
ceri 0:cbe01b678bd4 109 void USBMemCopy(uint8_t *dst, uint8_t *src, uint32_t size);
ceri 0:cbe01b678bd4 110 void USBMemCopy(uint8_t *dst, uint8_t *src, uint32_t size) {
ceri 0:cbe01b678bd4 111 if (size > 0) {
ceri 0:cbe01b678bd4 112 do {
ceri 0:cbe01b678bd4 113 *dst++ = *src++;
ceri 0:cbe01b678bd4 114 } while (--size > 0);
ceri 0:cbe01b678bd4 115 }
ceri 0:cbe01b678bd4 116 }
ceri 0:cbe01b678bd4 117
ceri 0:cbe01b678bd4 118
ceri 0:cbe01b678bd4 119 USBHAL::USBHAL(void) {
ceri 0:cbe01b678bd4 120 NVIC_DisableIRQ(USB_IRQn);
ceri 0:cbe01b678bd4 121
ceri 0:cbe01b678bd4 122 // USB_VBUS input, Pull down, Hysteresis enabled
ceri 0:cbe01b678bd4 123 //LPC_IOCON->PIO0_3 = 0x00000029;
ceri 0:cbe01b678bd4 124 // nUSB_CONNECT output
ceri 0:cbe01b678bd4 125 LPC_IOCON->PIO0_6 = 0x00000001;
ceri 0:cbe01b678bd4 126
ceri 0:cbe01b678bd4 127 // Enable clocks (USB registers, USB RAM)
ceri 0:cbe01b678bd4 128 LPC_SYSCON->SYSAHBCLKCTRL |= CLK_USB | CLK_USBRAM;
ceri 0:cbe01b678bd4 129
ceri 0:cbe01b678bd4 130 // Ensure device disconnected (DCON not set)
ceri 0:cbe01b678bd4 131 LPC_USB->DEVCMDSTAT = 0;
ceri 0:cbe01b678bd4 132
ceri 0:cbe01b678bd4 133 // Device must be disconnected for at least 2.5uS
ceri 0:cbe01b678bd4 134 // to ensure that the USB host sees the device as
ceri 0:cbe01b678bd4 135 // disconnected if the target CPU is reset.
ceri 0:cbe01b678bd4 136 wait(0.3);
ceri 0:cbe01b678bd4 137
ceri 0:cbe01b678bd4 138
ceri 0:cbe01b678bd4 139 // Reserve space in USB RAM for endpoint command/status list
ceri 0:cbe01b678bd4 140 // Must be 256 byte aligned
ceri 0:cbe01b678bd4 141 usbRamPtr = ROUND_UP_TO_MULTIPLE(usbRamPtr, 256);
ceri 0:cbe01b678bd4 142 ep = (EP_COMMAND_STATUS *)usbRamPtr;
ceri 0:cbe01b678bd4 143 usbRamPtr += (sizeof(EP_COMMAND_STATUS) * NUMBER_OF_LOGICAL_ENDPOINTS);
ceri 0:cbe01b678bd4 144 LPC_USB->EPLISTSTART = (uint32_t)(ep) & 0xffffff00;
ceri 0:cbe01b678bd4 145
ceri 0:cbe01b678bd4 146 // Reserve space in USB RAM for Endpoint 0
ceri 0:cbe01b678bd4 147 // Must be 64 byte aligned
ceri 0:cbe01b678bd4 148 usbRamPtr = ROUND_UP_TO_MULTIPLE(usbRamPtr, 64);
ceri 0:cbe01b678bd4 149 ct = (CONTROL_TRANSFER *)usbRamPtr;
ceri 0:cbe01b678bd4 150 usbRamPtr += sizeof(CONTROL_TRANSFER);
ceri 0:cbe01b678bd4 151 LPC_USB->DATABUFSTART =(uint32_t)(ct) & 0xffc00000;
ceri 0:cbe01b678bd4 152
ceri 0:cbe01b678bd4 153 // Setup command/status list for EP0
ceri 0:cbe01b678bd4 154 ep[0].out[0] = 0;
ceri 0:cbe01b678bd4 155 ep[0].in[0] = 0;
ceri 0:cbe01b678bd4 156 ep[0].out[1] = CMDSTS_ADDRESS_OFFSET((uint32_t)ct->setup);
ceri 0:cbe01b678bd4 157
ceri 0:cbe01b678bd4 158 // Route all interrupts to IRQ, some can be routed to
ceri 0:cbe01b678bd4 159 // USB_FIQ if you wish.
ceri 0:cbe01b678bd4 160 LPC_USB->INTROUTING = 0;
ceri 0:cbe01b678bd4 161
ceri 0:cbe01b678bd4 162 // Set device address 0, enable USB device, no remote wakeup
ceri 0:cbe01b678bd4 163 devCmdStat = DEV_ADDR(0) | DEV_EN | DSUS;
ceri 0:cbe01b678bd4 164 LPC_USB->DEVCMDSTAT = devCmdStat;
ceri 0:cbe01b678bd4 165
ceri 0:cbe01b678bd4 166 // Enable interrupts for device events and EP0
ceri 0:cbe01b678bd4 167 LPC_USB->INTEN = DEV_INT | EP(EP0IN) | EP(EP0OUT);
ceri 0:cbe01b678bd4 168 instance = this;
ceri 0:cbe01b678bd4 169 NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr);
ceri 0:cbe01b678bd4 170 NVIC_EnableIRQ(USB_IRQn);
ceri 0:cbe01b678bd4 171 }
ceri 0:cbe01b678bd4 172
ceri 0:cbe01b678bd4 173 USBHAL::~USBHAL(void) {
ceri 0:cbe01b678bd4 174 // Ensure device disconnected (DCON not set)
ceri 0:cbe01b678bd4 175 LPC_USB->DEVCMDSTAT = 0;
ceri 0:cbe01b678bd4 176
ceri 0:cbe01b678bd4 177 // Disable USB interrupts
ceri 0:cbe01b678bd4 178 NVIC_DisableIRQ(USB_IRQn);
ceri 0:cbe01b678bd4 179 }
ceri 0:cbe01b678bd4 180
ceri 0:cbe01b678bd4 181 void USBHAL::connect(void) {
ceri 0:cbe01b678bd4 182 devCmdStat |= DCON;
ceri 0:cbe01b678bd4 183 LPC_USB->DEVCMDSTAT = devCmdStat;
ceri 0:cbe01b678bd4 184 }
ceri 0:cbe01b678bd4 185
ceri 0:cbe01b678bd4 186 void USBHAL::disconnect(void) {
ceri 0:cbe01b678bd4 187 devCmdStat &= ~DCON;
ceri 0:cbe01b678bd4 188 LPC_USB->DEVCMDSTAT = devCmdStat;
ceri 0:cbe01b678bd4 189 }
ceri 0:cbe01b678bd4 190
ceri 0:cbe01b678bd4 191 void USBHAL::configureDevice(void) {
ceri 0:cbe01b678bd4 192 }
ceri 0:cbe01b678bd4 193
ceri 0:cbe01b678bd4 194 void USBHAL::unconfigureDevice(void) {
ceri 0:cbe01b678bd4 195 }
ceri 0:cbe01b678bd4 196
ceri 0:cbe01b678bd4 197 void USBHAL::EP0setup(uint8_t *buffer) {
ceri 0:cbe01b678bd4 198 // Copy setup packet data
ceri 0:cbe01b678bd4 199 USBMemCopy(buffer, ct->setup, SETUP_PACKET_SIZE);
ceri 0:cbe01b678bd4 200 }
ceri 0:cbe01b678bd4 201
ceri 0:cbe01b678bd4 202 void USBHAL::EP0read(void) {
ceri 0:cbe01b678bd4 203 // Start an endpoint 0 read
ceri 0:cbe01b678bd4 204
ceri 0:cbe01b678bd4 205 // The USB ISR will call USBDevice_EP0out() when a packet has been read,
ceri 0:cbe01b678bd4 206 // the USBDevice layer then calls USBBusInterface_EP0getReadResult() to
ceri 0:cbe01b678bd4 207 // read the data.
ceri 0:cbe01b678bd4 208
ceri 0:cbe01b678bd4 209 ep[0].out[0] = CMDSTS_A |CMDSTS_NBYTES(MAX_PACKET_SIZE_EP0) \
ceri 0:cbe01b678bd4 210 | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->out);
ceri 0:cbe01b678bd4 211 }
ceri 0:cbe01b678bd4 212
ceri 0:cbe01b678bd4 213 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
ceri 0:cbe01b678bd4 214 // Complete an endpoint 0 read
ceri 0:cbe01b678bd4 215 uint32_t bytesRead;
ceri 0:cbe01b678bd4 216
ceri 0:cbe01b678bd4 217 // Find how many bytes were read
ceri 0:cbe01b678bd4 218 bytesRead = MAX_PACKET_SIZE_EP0 - BYTES_REMAINING(ep[0].out[0]);
ceri 0:cbe01b678bd4 219
ceri 0:cbe01b678bd4 220 // Copy data
ceri 0:cbe01b678bd4 221 USBMemCopy(buffer, ct->out, bytesRead);
ceri 0:cbe01b678bd4 222 return bytesRead;
ceri 0:cbe01b678bd4 223 }
ceri 0:cbe01b678bd4 224
ceri 0:cbe01b678bd4 225 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
ceri 0:cbe01b678bd4 226 // Start and endpoint 0 write
ceri 0:cbe01b678bd4 227
ceri 0:cbe01b678bd4 228 // The USB ISR will call USBDevice_EP0in() when the data has
ceri 0:cbe01b678bd4 229 // been written, the USBDevice layer then calls
ceri 0:cbe01b678bd4 230 // USBBusInterface_EP0getWriteResult() to complete the transaction.
ceri 0:cbe01b678bd4 231
ceri 0:cbe01b678bd4 232 // Copy data
ceri 0:cbe01b678bd4 233 USBMemCopy(ct->in, buffer, size);
ceri 0:cbe01b678bd4 234
ceri 0:cbe01b678bd4 235 // Start transfer
ceri 0:cbe01b678bd4 236 ep[0].in[0] = CMDSTS_A | CMDSTS_NBYTES(size) \
ceri 0:cbe01b678bd4 237 | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->in);
ceri 0:cbe01b678bd4 238 }
ceri 0:cbe01b678bd4 239
ceri 0:cbe01b678bd4 240
ceri 0:cbe01b678bd4 241 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
ceri 0:cbe01b678bd4 242 ep[PHY_TO_LOG(endpoint)].out[0] = CMDSTS_A | CMDSTS_NBYTES(maximumSize) \
ceri 0:cbe01b678bd4 243 | CMDSTS_ADDRESS_OFFSET((uint32_t)ct->out);
ceri 0:cbe01b678bd4 244 return EP_PENDING;
ceri 0:cbe01b678bd4 245 }
ceri 0:cbe01b678bd4 246
ceri 0:cbe01b678bd4 247 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t *data, uint32_t *bytesRead) {
ceri 0:cbe01b678bd4 248 if (!(epComplete & EP(endpoint)))
ceri 0:cbe01b678bd4 249 return EP_PENDING;
ceri 0:cbe01b678bd4 250 else {
ceri 0:cbe01b678bd4 251 epComplete &= ~EP(endpoint);
ceri 0:cbe01b678bd4 252 // Find how many bytes were read
ceri 0:cbe01b678bd4 253 *bytesRead = (uint32_t) (endpointState[endpoint].maxPacket - BYTES_REMAINING(ep[PHY_TO_LOG(endpoint)].out[0]));
ceri 0:cbe01b678bd4 254 // Copy data
ceri 0:cbe01b678bd4 255 USBMemCopy(data, ct->out, *bytesRead);
ceri 0:cbe01b678bd4 256 return EP_COMPLETED;
ceri 0:cbe01b678bd4 257 }
ceri 0:cbe01b678bd4 258 }
ceri 0:cbe01b678bd4 259
ceri 0:cbe01b678bd4 260 void USBHAL::EP0getWriteResult(void) {
ceri 0:cbe01b678bd4 261 // Complete an endpoint 0 write
ceri 0:cbe01b678bd4 262
ceri 0:cbe01b678bd4 263 // Nothing required for this target
ceri 0:cbe01b678bd4 264 return;
ceri 0:cbe01b678bd4 265 }
ceri 0:cbe01b678bd4 266
ceri 0:cbe01b678bd4 267 void USBHAL::EP0stall(void) {
ceri 0:cbe01b678bd4 268 ep[0].in[0] = CMDSTS_S;
ceri 0:cbe01b678bd4 269 ep[0].out[0] = CMDSTS_S;
ceri 0:cbe01b678bd4 270 }
ceri 0:cbe01b678bd4 271
ceri 0:cbe01b678bd4 272 void USBHAL::setAddress(uint8_t address) {
ceri 0:cbe01b678bd4 273 devCmdStat &= ~DEV_ADDR_MASK;
ceri 0:cbe01b678bd4 274 devCmdStat |= DEV_ADDR(address);
ceri 0:cbe01b678bd4 275 LPC_USB->DEVCMDSTAT = devCmdStat;
ceri 0:cbe01b678bd4 276 }
ceri 0:cbe01b678bd4 277
ceri 0:cbe01b678bd4 278 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
ceri 0:cbe01b678bd4 279 uint32_t flags = 0;
ceri 0:cbe01b678bd4 280 uint32_t bf;
ceri 0:cbe01b678bd4 281
ceri 0:cbe01b678bd4 282 // Validate parameters
ceri 0:cbe01b678bd4 283 if (data == NULL) {
ceri 0:cbe01b678bd4 284 return EP_INVALID;
ceri 0:cbe01b678bd4 285 }
ceri 0:cbe01b678bd4 286
ceri 0:cbe01b678bd4 287 if (endpoint > LAST_PHYSICAL_ENDPOINT) {
ceri 0:cbe01b678bd4 288 return EP_INVALID;
ceri 0:cbe01b678bd4 289 }
ceri 0:cbe01b678bd4 290
ceri 0:cbe01b678bd4 291 if ((endpoint==EP0IN) || (endpoint==EP0OUT)) {
ceri 0:cbe01b678bd4 292 return EP_INVALID;
ceri 0:cbe01b678bd4 293 }
ceri 0:cbe01b678bd4 294
ceri 0:cbe01b678bd4 295 if (size > endpointState[endpoint].maxPacket) {
ceri 0:cbe01b678bd4 296 return EP_INVALID;
ceri 0:cbe01b678bd4 297 }
ceri 0:cbe01b678bd4 298
ceri 0:cbe01b678bd4 299 if (LPC_USB->EPBUFCFG & EP(endpoint)) {
ceri 0:cbe01b678bd4 300 // Double buffered // TODO: FIX THIS
ceri 0:cbe01b678bd4 301 if (LPC_USB->EPINUSE & EP(endpoint)) {
ceri 0:cbe01b678bd4 302 bf = 1;
ceri 0:cbe01b678bd4 303 } else {
ceri 0:cbe01b678bd4 304 bf = 0;
ceri 0:cbe01b678bd4 305 }
ceri 0:cbe01b678bd4 306 } else {
ceri 0:cbe01b678bd4 307 // Single buffered
ceri 0:cbe01b678bd4 308 bf = 0;
ceri 0:cbe01b678bd4 309 }
ceri 0:cbe01b678bd4 310
ceri 0:cbe01b678bd4 311 // Check if already active
ceri 0:cbe01b678bd4 312 if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_A) {
ceri 0:cbe01b678bd4 313 return EP_INVALID;
ceri 0:cbe01b678bd4 314 }
ceri 0:cbe01b678bd4 315
ceri 0:cbe01b678bd4 316 // Check if stalled
ceri 0:cbe01b678bd4 317 if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_S) {
ceri 0:cbe01b678bd4 318 return EP_STALLED;
ceri 0:cbe01b678bd4 319 }
ceri 0:cbe01b678bd4 320
ceri 0:cbe01b678bd4 321 // Copy data to USB RAM
ceri 0:cbe01b678bd4 322 USBMemCopy((uint8_t *)endpointState[endpoint].buffer[bf], data, size);
ceri 0:cbe01b678bd4 323
ceri 0:cbe01b678bd4 324 // Add options
ceri 0:cbe01b678bd4 325 if (endpointState[endpoint].options & RATE_FEEDBACK_MODE) {
ceri 0:cbe01b678bd4 326 flags |= CMDSTS_RF;
ceri 0:cbe01b678bd4 327 }
ceri 0:cbe01b678bd4 328
ceri 0:cbe01b678bd4 329 if (endpointState[endpoint].options & ISOCHRONOUS) {
ceri 0:cbe01b678bd4 330 flags |= CMDSTS_T;
ceri 0:cbe01b678bd4 331 }
ceri 0:cbe01b678bd4 332
ceri 0:cbe01b678bd4 333 // Add transfer
ceri 0:cbe01b678bd4 334 ep[PHY_TO_LOG(endpoint)].in[bf] = CMDSTS_ADDRESS_OFFSET( \
ceri 0:cbe01b678bd4 335 endpointState[endpoint].buffer[bf]) \
ceri 0:cbe01b678bd4 336 | CMDSTS_NBYTES(size) | CMDSTS_A | flags;
ceri 0:cbe01b678bd4 337
ceri 0:cbe01b678bd4 338 return EP_PENDING;
ceri 0:cbe01b678bd4 339 }
ceri 0:cbe01b678bd4 340
ceri 0:cbe01b678bd4 341 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
ceri 0:cbe01b678bd4 342 uint32_t bf;
ceri 0:cbe01b678bd4 343 // Validate parameters
ceri 0:cbe01b678bd4 344
ceri 0:cbe01b678bd4 345 if (endpoint > LAST_PHYSICAL_ENDPOINT) {
ceri 0:cbe01b678bd4 346 return EP_INVALID;
ceri 0:cbe01b678bd4 347 }
ceri 0:cbe01b678bd4 348
ceri 0:cbe01b678bd4 349 if (OUT_EP(endpoint)) {
ceri 0:cbe01b678bd4 350 return EP_INVALID;
ceri 0:cbe01b678bd4 351 }
ceri 0:cbe01b678bd4 352
ceri 0:cbe01b678bd4 353 if (LPC_USB->EPBUFCFG & EP(endpoint)) {
ceri 0:cbe01b678bd4 354 // Double buffered // TODO: FIX THIS
ceri 0:cbe01b678bd4 355 if (LPC_USB->EPINUSE & EP(endpoint)) {
ceri 0:cbe01b678bd4 356 bf = 1;
ceri 0:cbe01b678bd4 357 } else {
ceri 0:cbe01b678bd4 358 bf = 0;
ceri 0:cbe01b678bd4 359 }
ceri 0:cbe01b678bd4 360 } else {
ceri 0:cbe01b678bd4 361 // Single buffered
ceri 0:cbe01b678bd4 362 bf = 0;
ceri 0:cbe01b678bd4 363 }
ceri 0:cbe01b678bd4 364
ceri 0:cbe01b678bd4 365 // Check if endpoint still active
ceri 0:cbe01b678bd4 366 if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_A) {
ceri 0:cbe01b678bd4 367 return EP_PENDING;
ceri 0:cbe01b678bd4 368 }
ceri 0:cbe01b678bd4 369
ceri 0:cbe01b678bd4 370 // Check if stalled
ceri 0:cbe01b678bd4 371 if (ep[PHY_TO_LOG(endpoint)].in[bf] & CMDSTS_S) {
ceri 0:cbe01b678bd4 372 return EP_STALLED;
ceri 0:cbe01b678bd4 373 }
ceri 0:cbe01b678bd4 374
ceri 0:cbe01b678bd4 375 return EP_COMPLETED;
ceri 0:cbe01b678bd4 376 }
ceri 0:cbe01b678bd4 377
ceri 0:cbe01b678bd4 378 void USBHAL::stallEndpoint(uint8_t endpoint) {
ceri 0:cbe01b678bd4 379
ceri 0:cbe01b678bd4 380 // TODO: should this clear active bit?
ceri 0:cbe01b678bd4 381
ceri 0:cbe01b678bd4 382 if (IN_EP(endpoint)) {
ceri 0:cbe01b678bd4 383 ep[PHY_TO_LOG(endpoint)].in[0] |= CMDSTS_S;
ceri 0:cbe01b678bd4 384 ep[PHY_TO_LOG(endpoint)].in[1] |= CMDSTS_S;
ceri 0:cbe01b678bd4 385 } else {
ceri 0:cbe01b678bd4 386 ep[PHY_TO_LOG(endpoint)].out[0] |= CMDSTS_S;
ceri 0:cbe01b678bd4 387 ep[PHY_TO_LOG(endpoint)].out[1] |= CMDSTS_S;
ceri 0:cbe01b678bd4 388 }
ceri 0:cbe01b678bd4 389 }
ceri 0:cbe01b678bd4 390
ceri 0:cbe01b678bd4 391 void USBHAL::unstallEndpoint(uint8_t endpoint) {
ceri 0:cbe01b678bd4 392 if (LPC_USB->EPBUFCFG & EP(endpoint)) {
ceri 0:cbe01b678bd4 393 // Double buffered
ceri 0:cbe01b678bd4 394 if (IN_EP(endpoint)) {
ceri 0:cbe01b678bd4 395 ep[PHY_TO_LOG(endpoint)].in[0] = 0; // S = 0
ceri 0:cbe01b678bd4 396 ep[PHY_TO_LOG(endpoint)].in[1] = 0; // S = 0
ceri 0:cbe01b678bd4 397
ceri 0:cbe01b678bd4 398 if (LPC_USB->EPINUSE & EP(endpoint)) {
ceri 0:cbe01b678bd4 399 ep[PHY_TO_LOG(endpoint)].in[1] = CMDSTS_TR; // S =0, TR=1, TV = 0
ceri 0:cbe01b678bd4 400 } else {
ceri 0:cbe01b678bd4 401 ep[PHY_TO_LOG(endpoint)].in[0] = CMDSTS_TR; // S =0, TR=1, TV = 0
ceri 0:cbe01b678bd4 402 }
ceri 0:cbe01b678bd4 403 } else {
ceri 0:cbe01b678bd4 404 ep[PHY_TO_LOG(endpoint)].out[0] = 0; // S = 0
ceri 0:cbe01b678bd4 405 ep[PHY_TO_LOG(endpoint)].out[1] = 0; // S = 0
ceri 0:cbe01b678bd4 406
ceri 0:cbe01b678bd4 407 if (LPC_USB->EPINUSE & EP(endpoint)) {
ceri 0:cbe01b678bd4 408 ep[PHY_TO_LOG(endpoint)].out[1] = CMDSTS_TR; // S =0, TR=1, TV = 0
ceri 0:cbe01b678bd4 409 } else {
ceri 0:cbe01b678bd4 410 ep[PHY_TO_LOG(endpoint)].out[0] = CMDSTS_TR; // S =0, TR=1, TV = 0
ceri 0:cbe01b678bd4 411 }
ceri 0:cbe01b678bd4 412 }
ceri 0:cbe01b678bd4 413 } else {
ceri 0:cbe01b678bd4 414 // Single buffered
ceri 0:cbe01b678bd4 415 if (IN_EP(endpoint)) {
ceri 0:cbe01b678bd4 416 ep[PHY_TO_LOG(endpoint)].in[0] = CMDSTS_TR; // S=0, TR=1, TV = 0
ceri 0:cbe01b678bd4 417 } else {
ceri 0:cbe01b678bd4 418 ep[PHY_TO_LOG(endpoint)].out[0] = CMDSTS_TR; // S=0, TR=1, TV = 0
ceri 0:cbe01b678bd4 419 }
ceri 0:cbe01b678bd4 420 }
ceri 0:cbe01b678bd4 421 }
ceri 0:cbe01b678bd4 422
ceri 0:cbe01b678bd4 423 bool USBHAL::getEndpointStallState(unsigned char endpoint) {
ceri 0:cbe01b678bd4 424 if (IN_EP(endpoint)) {
ceri 0:cbe01b678bd4 425 if (LPC_USB->EPINUSE & EP(endpoint)) {
ceri 0:cbe01b678bd4 426 if (ep[PHY_TO_LOG(endpoint)].in[1] & CMDSTS_S) {
ceri 0:cbe01b678bd4 427 return true;
ceri 0:cbe01b678bd4 428 }
ceri 0:cbe01b678bd4 429 } else {
ceri 0:cbe01b678bd4 430 if (ep[PHY_TO_LOG(endpoint)].in[0] & CMDSTS_S) {
ceri 0:cbe01b678bd4 431 return true;
ceri 0:cbe01b678bd4 432 }
ceri 0:cbe01b678bd4 433 }
ceri 0:cbe01b678bd4 434 } else {
ceri 0:cbe01b678bd4 435 if (LPC_USB->EPINUSE & EP(endpoint)) {
ceri 0:cbe01b678bd4 436 if (ep[PHY_TO_LOG(endpoint)].out[1] & CMDSTS_S) {
ceri 0:cbe01b678bd4 437 return true;
ceri 0:cbe01b678bd4 438 }
ceri 0:cbe01b678bd4 439 } else {
ceri 0:cbe01b678bd4 440 if (ep[PHY_TO_LOG(endpoint)].out[0] & CMDSTS_S) {
ceri 0:cbe01b678bd4 441 return true;
ceri 0:cbe01b678bd4 442 }
ceri 0:cbe01b678bd4 443 }
ceri 0:cbe01b678bd4 444 }
ceri 0:cbe01b678bd4 445
ceri 0:cbe01b678bd4 446 return false;
ceri 0:cbe01b678bd4 447 }
ceri 0:cbe01b678bd4 448
ceri 0:cbe01b678bd4 449 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t options) {
ceri 0:cbe01b678bd4 450 uint32_t tmpEpRamPtr;
ceri 0:cbe01b678bd4 451
ceri 0:cbe01b678bd4 452 // Support for double buffered endpoints needs to be fixed/finished in this
ceri 0:cbe01b678bd4 453 // software - force single buffered for now.
ceri 0:cbe01b678bd4 454
ceri 0:cbe01b678bd4 455
ceri 0:cbe01b678bd4 456 options |= SINGLE_BUFFERED; // TODO - FIX THIS
ceri 0:cbe01b678bd4 457
ceri 0:cbe01b678bd4 458 if (endpoint > LAST_PHYSICAL_ENDPOINT) {
ceri 0:cbe01b678bd4 459 return false;
ceri 0:cbe01b678bd4 460 }
ceri 0:cbe01b678bd4 461
ceri 0:cbe01b678bd4 462 // Not applicable to the control endpoints
ceri 0:cbe01b678bd4 463 if ((endpoint==EP0IN) || (endpoint==EP0OUT)) {
ceri 0:cbe01b678bd4 464 return false;
ceri 0:cbe01b678bd4 465 }
ceri 0:cbe01b678bd4 466
ceri 0:cbe01b678bd4 467 // Allocate buffers in USB RAM
ceri 0:cbe01b678bd4 468 tmpEpRamPtr = epRamPtr;
ceri 0:cbe01b678bd4 469
ceri 0:cbe01b678bd4 470 // Must be 64 byte aligned
ceri 0:cbe01b678bd4 471 tmpEpRamPtr = ROUND_UP_TO_MULTIPLE(tmpEpRamPtr, 64);
ceri 0:cbe01b678bd4 472
ceri 0:cbe01b678bd4 473 if ((tmpEpRamPtr + maxPacket) > (USB_RAM_START + USB_RAM_SIZE)) {
ceri 0:cbe01b678bd4 474 // Out of memory
ceri 0:cbe01b678bd4 475 return false;
ceri 0:cbe01b678bd4 476 }
ceri 0:cbe01b678bd4 477
ceri 0:cbe01b678bd4 478 // Allocate first buffer
ceri 0:cbe01b678bd4 479 endpointState[endpoint].buffer[0] = tmpEpRamPtr;
ceri 0:cbe01b678bd4 480 tmpEpRamPtr += maxPacket;
ceri 0:cbe01b678bd4 481
ceri 0:cbe01b678bd4 482 if (!(options & SINGLE_BUFFERED)) {
ceri 0:cbe01b678bd4 483 // Must be 64 byte aligned
ceri 0:cbe01b678bd4 484 tmpEpRamPtr = ROUND_UP_TO_MULTIPLE(tmpEpRamPtr, 64);
ceri 0:cbe01b678bd4 485
ceri 0:cbe01b678bd4 486 if ((tmpEpRamPtr + maxPacket) > (USB_RAM_START + USB_RAM_SIZE)) {
ceri 0:cbe01b678bd4 487 // Out of memory
ceri 0:cbe01b678bd4 488 return false;
ceri 0:cbe01b678bd4 489 }
ceri 0:cbe01b678bd4 490
ceri 0:cbe01b678bd4 491 // Allocate second buffer
ceri 0:cbe01b678bd4 492 endpointState[endpoint].buffer[1] = tmpEpRamPtr;
ceri 0:cbe01b678bd4 493 tmpEpRamPtr += maxPacket;
ceri 0:cbe01b678bd4 494 }
ceri 0:cbe01b678bd4 495
ceri 0:cbe01b678bd4 496 // Commit to this USB RAM allocation
ceri 0:cbe01b678bd4 497 epRamPtr = tmpEpRamPtr;
ceri 0:cbe01b678bd4 498
ceri 0:cbe01b678bd4 499 // Remaining endpoint state values
ceri 0:cbe01b678bd4 500 endpointState[endpoint].maxPacket = maxPacket;
ceri 0:cbe01b678bd4 501 endpointState[endpoint].options = options;
ceri 0:cbe01b678bd4 502
ceri 0:cbe01b678bd4 503 // Enable double buffering if required
ceri 0:cbe01b678bd4 504 if (options & SINGLE_BUFFERED) {
ceri 0:cbe01b678bd4 505 LPC_USB->EPBUFCFG &= ~EP(endpoint);
ceri 0:cbe01b678bd4 506 } else {
ceri 0:cbe01b678bd4 507 // Double buffered
ceri 0:cbe01b678bd4 508 LPC_USB->EPBUFCFG |= EP(endpoint);
ceri 0:cbe01b678bd4 509 }
ceri 0:cbe01b678bd4 510
ceri 0:cbe01b678bd4 511 // Enable interrupt for OUT endpoint
ceri 0:cbe01b678bd4 512 LPC_USB->INTEN |= EP(endpoint);
ceri 0:cbe01b678bd4 513
ceri 0:cbe01b678bd4 514 // Enable endpoint
ceri 0:cbe01b678bd4 515 unstallEndpoint(endpoint);
ceri 0:cbe01b678bd4 516 return true;
ceri 0:cbe01b678bd4 517 }
ceri 0:cbe01b678bd4 518
ceri 0:cbe01b678bd4 519 void USBHAL::remoteWakeup(void) {
ceri 0:cbe01b678bd4 520 // Clearing DSUS bit initiates a remote wakeup if the
ceri 0:cbe01b678bd4 521 // device is currently enabled and suspended - otherwise
ceri 0:cbe01b678bd4 522 // it has no effect.
ceri 0:cbe01b678bd4 523 LPC_USB->DEVCMDSTAT = devCmdStat & ~DSUS;
ceri 0:cbe01b678bd4 524 }
ceri 0:cbe01b678bd4 525
ceri 0:cbe01b678bd4 526
ceri 0:cbe01b678bd4 527 static void disableEndpoints(void) {
ceri 0:cbe01b678bd4 528 uint32_t logEp;
ceri 0:cbe01b678bd4 529
ceri 0:cbe01b678bd4 530 // Ref. Table 158 "When a bus reset is received, software
ceri 0:cbe01b678bd4 531 // must set the disable bit of all endpoints to 1".
ceri 0:cbe01b678bd4 532
ceri 0:cbe01b678bd4 533 for (logEp = 1; logEp < NUMBER_OF_LOGICAL_ENDPOINTS; logEp++) {
ceri 0:cbe01b678bd4 534 ep[logEp].out[0] = CMDSTS_D;
ceri 0:cbe01b678bd4 535 ep[logEp].out[1] = CMDSTS_D;
ceri 0:cbe01b678bd4 536 ep[logEp].in[0] = CMDSTS_D;
ceri 0:cbe01b678bd4 537 ep[logEp].in[1] = CMDSTS_D;
ceri 0:cbe01b678bd4 538 }
ceri 0:cbe01b678bd4 539
ceri 0:cbe01b678bd4 540 // Start of USB RAM for endpoints > 0
ceri 0:cbe01b678bd4 541 epRamPtr = usbRamPtr;
ceri 0:cbe01b678bd4 542 }
ceri 0:cbe01b678bd4 543
ceri 0:cbe01b678bd4 544
ceri 0:cbe01b678bd4 545
ceri 0:cbe01b678bd4 546 void USBHAL::_usbisr(void)
ceri 0:cbe01b678bd4 547 {
ceri 0:cbe01b678bd4 548 instance->usbisr();
ceri 0:cbe01b678bd4 549 }
ceri 0:cbe01b678bd4 550
ceri 0:cbe01b678bd4 551
ceri 0:cbe01b678bd4 552 void USBHAL::usbisr(void) {
ceri 0:cbe01b678bd4 553 // Start of frame
ceri 0:cbe01b678bd4 554 if (LPC_USB->INTSTAT & FRAME_INT) {
ceri 0:cbe01b678bd4 555 // Clear SOF interrupt
ceri 0:cbe01b678bd4 556 LPC_USB->INTSTAT = FRAME_INT;
ceri 0:cbe01b678bd4 557
ceri 0:cbe01b678bd4 558 // SOF event, read frame number
ceri 0:cbe01b678bd4 559 SOF(FRAME_NR(LPC_USB->INFO));
ceri 0:cbe01b678bd4 560 }
ceri 0:cbe01b678bd4 561
ceri 0:cbe01b678bd4 562 // Device state
ceri 0:cbe01b678bd4 563 if (LPC_USB->INTSTAT & DEV_INT) {
ceri 0:cbe01b678bd4 564 LPC_USB->INTSTAT = DEV_INT;
ceri 0:cbe01b678bd4 565
ceri 0:cbe01b678bd4 566 if (LPC_USB->DEVCMDSTAT & DCON_C) {
ceri 0:cbe01b678bd4 567 // Connect status changed
ceri 0:cbe01b678bd4 568 LPC_USB->DEVCMDSTAT = devCmdStat | DCON_C;
ceri 0:cbe01b678bd4 569
ceri 0:cbe01b678bd4 570 connectStateChanged((LPC_USB->DEVCMDSTAT & DCON) != 0);
ceri 0:cbe01b678bd4 571 }
ceri 0:cbe01b678bd4 572
ceri 0:cbe01b678bd4 573 if (LPC_USB->DEVCMDSTAT & DSUS_C) {
ceri 0:cbe01b678bd4 574 // Suspend status changed
ceri 0:cbe01b678bd4 575 LPC_USB->DEVCMDSTAT = devCmdStat | DSUS_C;
ceri 0:cbe01b678bd4 576
ceri 0:cbe01b678bd4 577 suspendStateChanged((LPC_USB->DEVCMDSTAT & DSUS) != 0);
ceri 0:cbe01b678bd4 578 }
ceri 0:cbe01b678bd4 579
ceri 0:cbe01b678bd4 580 if (LPC_USB->DEVCMDSTAT & DRES_C) {
ceri 0:cbe01b678bd4 581 // Bus reset
ceri 0:cbe01b678bd4 582 LPC_USB->DEVCMDSTAT = devCmdStat | DRES_C;
ceri 0:cbe01b678bd4 583
ceri 0:cbe01b678bd4 584 // Disable endpoints > 0
ceri 0:cbe01b678bd4 585 disableEndpoints();
ceri 0:cbe01b678bd4 586
ceri 0:cbe01b678bd4 587 // Bus reset event
ceri 0:cbe01b678bd4 588 busReset();
ceri 0:cbe01b678bd4 589 }
ceri 0:cbe01b678bd4 590 }
ceri 0:cbe01b678bd4 591
ceri 0:cbe01b678bd4 592 // Endpoint 0
ceri 0:cbe01b678bd4 593 if (LPC_USB->INTSTAT & EP(EP0OUT)) {
ceri 0:cbe01b678bd4 594 // Clear EP0OUT/SETUP interrupt
ceri 0:cbe01b678bd4 595 LPC_USB->INTSTAT = EP(EP0OUT);
ceri 0:cbe01b678bd4 596
ceri 0:cbe01b678bd4 597 // Check if SETUP
ceri 0:cbe01b678bd4 598 if (LPC_USB->DEVCMDSTAT & SETUP) {
ceri 0:cbe01b678bd4 599 // Clear Active and Stall bits for EP0
ceri 0:cbe01b678bd4 600 // Documentation does not make it clear if we must use the
ceri 0:cbe01b678bd4 601 // EPSKIP register to achieve this, Fig. 16 and NXP reference
ceri 0:cbe01b678bd4 602 // code suggests we can just clear the Active bits - check with
ceri 0:cbe01b678bd4 603 // NXP to be sure.
ceri 0:cbe01b678bd4 604 ep[0].in[0] = 0;
ceri 0:cbe01b678bd4 605 ep[0].out[0] = 0;
ceri 0:cbe01b678bd4 606
ceri 0:cbe01b678bd4 607 // Clear EP0IN interrupt
ceri 0:cbe01b678bd4 608 LPC_USB->INTSTAT = EP(EP0IN);
ceri 0:cbe01b678bd4 609
ceri 0:cbe01b678bd4 610 // Clear SETUP (and INTONNAK_CI/O) in device status register
ceri 0:cbe01b678bd4 611 LPC_USB->DEVCMDSTAT = devCmdStat | SETUP;
ceri 0:cbe01b678bd4 612
ceri 0:cbe01b678bd4 613 // EP0 SETUP event (SETUP data received)
ceri 0:cbe01b678bd4 614 EP0setupCallback();
ceri 0:cbe01b678bd4 615 } else {
ceri 0:cbe01b678bd4 616 // EP0OUT ACK event (OUT data received)
ceri 0:cbe01b678bd4 617 EP0out();
ceri 0:cbe01b678bd4 618 }
ceri 0:cbe01b678bd4 619 }
ceri 0:cbe01b678bd4 620
ceri 0:cbe01b678bd4 621 if (LPC_USB->INTSTAT & EP(EP0IN)) {
ceri 0:cbe01b678bd4 622 // Clear EP0IN interrupt
ceri 0:cbe01b678bd4 623 LPC_USB->INTSTAT = EP(EP0IN);
ceri 0:cbe01b678bd4 624
ceri 0:cbe01b678bd4 625 // EP0IN ACK event (IN data sent)
ceri 0:cbe01b678bd4 626 EP0in();
ceri 0:cbe01b678bd4 627 }
ceri 0:cbe01b678bd4 628
ceri 0:cbe01b678bd4 629 if (LPC_USB->INTSTAT & EP(EP1IN)) {
ceri 0:cbe01b678bd4 630 // Clear EP1IN interrupt
ceri 0:cbe01b678bd4 631 LPC_USB->INTSTAT = EP(EP1IN);
ceri 0:cbe01b678bd4 632 epComplete |= EP(EP1IN);
ceri 0:cbe01b678bd4 633 }
ceri 0:cbe01b678bd4 634
ceri 0:cbe01b678bd4 635 if (LPC_USB->INTSTAT & EP(EP1OUT)) {
ceri 0:cbe01b678bd4 636 // Clear EP1OUT interrupt
ceri 0:cbe01b678bd4 637 LPC_USB->INTSTAT = EP(EP1OUT);
ceri 0:cbe01b678bd4 638 epComplete |= EP(EP1OUT);
ceri 0:cbe01b678bd4 639 }
ceri 0:cbe01b678bd4 640
ceri 0:cbe01b678bd4 641 if (LPC_USB->INTSTAT & EP(EPBULK_IN)) {
ceri 0:cbe01b678bd4 642 // Clear EPBULK_OUT interrupt
ceri 0:cbe01b678bd4 643 LPC_USB->INTSTAT = EP(EPBULK_IN);
ceri 0:cbe01b678bd4 644 epComplete |= EP(EPBULK_IN);
ceri 0:cbe01b678bd4 645 if(EPBULK_IN_callback())
ceri 0:cbe01b678bd4 646 epComplete &= ~EP(EPBULK_IN);
ceri 0:cbe01b678bd4 647 }
ceri 0:cbe01b678bd4 648
ceri 0:cbe01b678bd4 649 if (LPC_USB->INTSTAT & EP(EPBULK_OUT)) {
ceri 0:cbe01b678bd4 650 // Clear EPBULK_OUT interrupt
ceri 0:cbe01b678bd4 651 LPC_USB->INTSTAT = EP(EPBULK_OUT);
ceri 0:cbe01b678bd4 652 epComplete |= EP(EPBULK_OUT);
ceri 0:cbe01b678bd4 653 //Call callback function. If true, clear epComplete
ceri 0:cbe01b678bd4 654 if(EPBULK_OUT_callback())
ceri 0:cbe01b678bd4 655 epComplete &= ~EP(EPBULK_OUT);
ceri 0:cbe01b678bd4 656 }
ceri 0:cbe01b678bd4 657
ceri 0:cbe01b678bd4 658 }
ceri 0:cbe01b678bd4 659
ceri 0:cbe01b678bd4 660 #endif