USBAudio example using a microphone

Dependencies:   USBDevice mbed

Committer:
samux
Date:
Mon Dec 19 15:46:17 2011 +0000
Revision:
3:e6a29c83ac52
Parent:
0:539ec61e1fbb
ok we can send a music from an sdcard but readings are time to time slow...

Who changed what in which revision?

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