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