Modified for PS3 Joystick

Dependents:   NiseKabuto

Fork of USBDevice by Samuel Mokrani

Committer:
sankichi
Date:
Sat Jul 27 14:05:26 2013 +0000
Revision:
1:ac5cca60029a
Parent:
0:140cdf8e2d60
First Release

Who changed what in which revision?

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