USBMSD SD card Hello World for Mbed platforms

Dependencies:   mbed USBMSD_SD USBDevice

Committer:
samux
Date:
Wed Nov 16 17:17:42 2011 +0000
Revision:
11:a26e7b7a1221
GOOD COMMIT: msd and hid work even on MAC...

Who changed what in which revision?

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