Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of USBMIDI by
usbcore.cpp@3:1c9f95100210, 2016-04-29 (annotated)
- Committer:
- KrissyHam
- Date:
- Fri Apr 29 01:46:03 2016 +0000
- Revision:
- 3:1c9f95100210
- Parent:
- usbcore.c@2:10d694d6ccdc
Changed file extensions from .c to .cpp
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| simon | 2:10d694d6ccdc | 1 | /* @license The MIT License |
| simon | 1:ff74eabe02cd | 2 | * Copyright (c) 2011 mux, simon |
| simon | 1:ff74eabe02cd | 3 | * |
| simon | 1:ff74eabe02cd | 4 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
| simon | 1:ff74eabe02cd | 5 | * of this software and associated documentation files (the "Software"), to deal |
| simon | 1:ff74eabe02cd | 6 | * in the Software without restriction, including without limitation the rights |
| simon | 1:ff74eabe02cd | 7 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| simon | 1:ff74eabe02cd | 8 | * copies of the Software, and to permit persons to whom the Software is |
| simon | 1:ff74eabe02cd | 9 | * furnished to do so, subject to the following conditions: |
| simon | 1:ff74eabe02cd | 10 | * |
| simon | 1:ff74eabe02cd | 11 | * The above copyright notice and this permission notice shall be included in |
| simon | 1:ff74eabe02cd | 12 | * all copies or substantial portions of the Software. |
| simon | 1:ff74eabe02cd | 13 | * |
| simon | 1:ff74eabe02cd | 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| simon | 1:ff74eabe02cd | 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| simon | 1:ff74eabe02cd | 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| simon | 1:ff74eabe02cd | 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| simon | 1:ff74eabe02cd | 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| simon | 1:ff74eabe02cd | 19 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
| simon | 1:ff74eabe02cd | 20 | * THE SOFTWARE. |
| simon | 1:ff74eabe02cd | 21 | */ |
| simon | 1:ff74eabe02cd | 22 | |
| simon | 1:ff74eabe02cd | 23 | #include "usbcore.h" |
| simon | 1:ff74eabe02cd | 24 | |
| simon | 1:ff74eabe02cd | 25 | #include "mbed.h" |
| simon | 1:ff74eabe02cd | 26 | |
| simon | 1:ff74eabe02cd | 27 | // Serial Interface Engine |
| simon | 1:ff74eabe02cd | 28 | #define SIE_SET_ADDR (0xD0) |
| simon | 1:ff74eabe02cd | 29 | #define SIE_SET_STATUS (0xFE) |
| simon | 1:ff74eabe02cd | 30 | #define SIE_GET_STATUS (0xFE) |
| simon | 1:ff74eabe02cd | 31 | #define SIE_SET_MODE (0xF3) |
| simon | 1:ff74eabe02cd | 32 | #define SIE_CLR_BUFFER (0xF2) |
| simon | 1:ff74eabe02cd | 33 | #define SIE_VAL_BUFFER (0xFA) |
| simon | 1:ff74eabe02cd | 34 | #define SIE_SEL_EP (0x00) |
| simon | 1:ff74eabe02cd | 35 | #define SIE_SEL_CLR_EP (0x28) |
| simon | 1:ff74eabe02cd | 36 | #define SIE_SET_EP_STAT (0x40) |
| simon | 1:ff74eabe02cd | 37 | #define SIE_READ_ERROR (0xFB) |
| simon | 1:ff74eabe02cd | 38 | #define SIE_CONFIG_DEVICE (0xD8) |
| simon | 1:ff74eabe02cd | 39 | |
| simon | 1:ff74eabe02cd | 40 | // EP status |
| simon | 1:ff74eabe02cd | 41 | #define EP_FE (1<<0) // Full/Empty |
| simon | 1:ff74eabe02cd | 42 | #define EP_ST (1<<1) // Stalled endpoint |
| simon | 1:ff74eabe02cd | 43 | #define EP_STP (1<<2) // Setup packet |
| simon | 1:ff74eabe02cd | 44 | #define EP_PO (1<<3) // packet overwritten |
| simon | 1:ff74eabe02cd | 45 | #define EP_EPN (1<<4) // EP NAKed |
| simon | 1:ff74eabe02cd | 46 | #define B_1_FULL (1<<5) // buffer 1 status |
| simon | 1:ff74eabe02cd | 47 | #define B_2_FULL (1<<6) // buffer 2 status |
| simon | 1:ff74eabe02cd | 48 | |
| simon | 1:ff74eabe02cd | 49 | // USB device interrupts |
| simon | 1:ff74eabe02cd | 50 | #define DEV_FRAME (1<<0) |
| simon | 1:ff74eabe02cd | 51 | #define EP_FAST (1<<1) |
| simon | 1:ff74eabe02cd | 52 | #define EP_SLOW (1<<2) |
| simon | 1:ff74eabe02cd | 53 | #define DEV_STAT (1<<3) |
| simon | 1:ff74eabe02cd | 54 | #define RxENDPKT (1<<6) |
| simon | 1:ff74eabe02cd | 55 | #define TxENDPKT (1<<7) |
| simon | 1:ff74eabe02cd | 56 | #define EP_RLZED (1<<8) |
| simon | 1:ff74eabe02cd | 57 | #define CCEMPTY (0x10) |
| simon | 1:ff74eabe02cd | 58 | #define CDFULL (0x20) |
| simon | 1:ff74eabe02cd | 59 | |
| simon | 1:ff74eabe02cd | 60 | // USB device status bits |
| simon | 1:ff74eabe02cd | 61 | #define STAT_CON (1<<0) |
| simon | 1:ff74eabe02cd | 62 | #define STAT_CON_CH (1<<1) |
| simon | 1:ff74eabe02cd | 63 | #define STAT_SUS (1<<2) |
| simon | 1:ff74eabe02cd | 64 | #define STAT_SUS_CH (1<<3) |
| simon | 1:ff74eabe02cd | 65 | #define STAT_RST (1<<4) |
| simon | 1:ff74eabe02cd | 66 | |
| simon | 1:ff74eabe02cd | 67 | // end points interrupts |
| simon | 1:ff74eabe02cd | 68 | #define EP0RX_INT (1<<0) |
| simon | 1:ff74eabe02cd | 69 | #define EP0TX_INT (1<<1) |
| simon | 1:ff74eabe02cd | 70 | #define EP1RX_INT (1<<2) |
| simon | 1:ff74eabe02cd | 71 | #define EP1TX_INT (1<<3) |
| simon | 1:ff74eabe02cd | 72 | #define EP2RX_INT (1<<4) |
| simon | 1:ff74eabe02cd | 73 | #define EP2TX_INT (1<<5) |
| simon | 1:ff74eabe02cd | 74 | |
| simon | 1:ff74eabe02cd | 75 | // USB control register |
| simon | 1:ff74eabe02cd | 76 | #define RD_EN (1<<0) |
| simon | 1:ff74eabe02cd | 77 | #define WR_EN (1<<1) |
| simon | 1:ff74eabe02cd | 78 | #define PKT_RDY (1<<11) |
| simon | 1:ff74eabe02cd | 79 | #define LOG_ENDPOINT(ep) ((ep>>1)<<2) |
| simon | 1:ff74eabe02cd | 80 | |
| simon | 1:ff74eabe02cd | 81 | // configure state |
| simon | 1:ff74eabe02cd | 82 | static int configured = 0; |
| simon | 1:ff74eabe02cd | 83 | |
| simon | 1:ff74eabe02cd | 84 | // USB interrupt handler |
| simon | 1:ff74eabe02cd | 85 | void USB_IRQHandler(void); |
| simon | 1:ff74eabe02cd | 86 | |
| simon | 1:ff74eabe02cd | 87 | // Serial Interface Engine functions |
| simon | 1:ff74eabe02cd | 88 | void sie_command(uint32_t code) { |
| simon | 1:ff74eabe02cd | 89 | LPC_USB->USBDevIntClr = CCEMPTY; // clear CCEMPTY |
| simon | 1:ff74eabe02cd | 90 | LPC_USB->USBCmdCode = ((code<<16)|(0x05<<8)); // CMD_PHASE=Command |
| simon | 1:ff74eabe02cd | 91 | while (!(LPC_USB->USBDevIntSt & CCEMPTY)); // wait for CCEMPTY |
| simon | 1:ff74eabe02cd | 92 | } |
| simon | 1:ff74eabe02cd | 93 | |
| simon | 1:ff74eabe02cd | 94 | void sie_write(uint32_t data) { |
| simon | 1:ff74eabe02cd | 95 | LPC_USB->USBDevIntClr = CCEMPTY; // clear CCEMPTY |
| simon | 1:ff74eabe02cd | 96 | LPC_USB->USBCmdCode = ((data<<16)|(0x01<<8)); // CMD_PHASE=Write |
| simon | 1:ff74eabe02cd | 97 | while (!(LPC_USB->USBDevIntSt & CCEMPTY)); // wait for CCEMPTY |
| simon | 1:ff74eabe02cd | 98 | } |
| simon | 1:ff74eabe02cd | 99 | |
| simon | 1:ff74eabe02cd | 100 | uint8_t sie_read(uint32_t code) { |
| simon | 1:ff74eabe02cd | 101 | LPC_USB->USBDevIntClr = CDFULL; // clear CCEMPTY |
| simon | 1:ff74eabe02cd | 102 | LPC_USB->USBCmdCode = ((code<<16)|(0x02<<8)); // CMD_PHASE=Read |
| simon | 1:ff74eabe02cd | 103 | while (!(LPC_USB->USBDevIntSt & CDFULL)); // wait for CDFULL |
| simon | 1:ff74eabe02cd | 104 | return (uint8_t) LPC_USB->USBCmdData; |
| simon | 1:ff74eabe02cd | 105 | |
| simon | 1:ff74eabe02cd | 106 | } |
| simon | 1:ff74eabe02cd | 107 | |
| simon | 1:ff74eabe02cd | 108 | // end point functions |
| simon | 1:ff74eabe02cd | 109 | void ep_realize(uint8_t ep, uint32_t size) { |
| simon | 1:ff74eabe02cd | 110 | LPC_USB->USBDevIntClr = EP_RLZED; // clear EP_RLZED |
| simon | 1:ff74eabe02cd | 111 | LPC_USB->USBReEp |= (1<<ep); |
| simon | 1:ff74eabe02cd | 112 | LPC_USB->USBEpInd = ep; // set USBEpIn |
| simon | 1:ff74eabe02cd | 113 | LPC_USB->USBMaxPSize = size; // writing to EPn pointed to by USBEpInd |
| simon | 1:ff74eabe02cd | 114 | while (!(LPC_USB->USBDevIntSt & EP_RLZED)); // wait for EP_RLZED |
| simon | 1:ff74eabe02cd | 115 | LPC_USB->USBDevIntClr = EP_RLZED; // clear EP_RLZED |
| simon | 1:ff74eabe02cd | 116 | } |
| simon | 1:ff74eabe02cd | 117 | |
| simon | 1:ff74eabe02cd | 118 | void ep_stall(uint8_t ep) { |
| simon | 1:ff74eabe02cd | 119 | sie_command(SIE_SET_EP_STAT+ep); |
| simon | 1:ff74eabe02cd | 120 | sie_write(1); |
| simon | 1:ff74eabe02cd | 121 | } |
| simon | 1:ff74eabe02cd | 122 | |
| simon | 1:ff74eabe02cd | 123 | void ep_unstall(uint8_t ep) { |
| simon | 1:ff74eabe02cd | 124 | sie_command(SIE_SET_EP_STAT+ep); |
| simon | 1:ff74eabe02cd | 125 | sie_write(0); |
| simon | 1:ff74eabe02cd | 126 | } |
| simon | 1:ff74eabe02cd | 127 | |
| simon | 1:ff74eabe02cd | 128 | // initializes a pointer to the endpoint buffer |
| simon | 1:ff74eabe02cd | 129 | uint8_t ep_select(uint8_t ep) { |
| simon | 1:ff74eabe02cd | 130 | sie_command(SIE_SEL_EP+ep); |
| simon | 1:ff74eabe02cd | 131 | return sie_read(SIE_SEL_EP+ep); |
| simon | 1:ff74eabe02cd | 132 | } |
| simon | 1:ff74eabe02cd | 133 | |
| simon | 1:ff74eabe02cd | 134 | uint8_t ep_select_clear(uint8_t ep) { |
| simon | 1:ff74eabe02cd | 135 | LPC_USB->USBEpIntClr |= ep; // clear ep interrupt |
| simon | 1:ff74eabe02cd | 136 | while (!(LPC_USB->USBDevIntSt & CDFULL)); // wait for cmd finish |
| simon | 1:ff74eabe02cd | 137 | return LPC_USB->USBCmdData; |
| simon | 1:ff74eabe02cd | 138 | } |
| simon | 1:ff74eabe02cd | 139 | |
| simon | 1:ff74eabe02cd | 140 | int ep_readable(uint8_t ep) { |
| simon | 1:ff74eabe02cd | 141 | uint8_t st = ep_select(ep); |
| simon | 1:ff74eabe02cd | 142 | return (st & EP_FE); |
| simon | 1:ff74eabe02cd | 143 | } |
| simon | 1:ff74eabe02cd | 144 | |
| simon | 1:ff74eabe02cd | 145 | int ep_writable(uint8_t ep) { |
| simon | 1:ff74eabe02cd | 146 | uint8_t st = ep_select(ep); |
| simon | 1:ff74eabe02cd | 147 | return !(st & EP_FE); |
| simon | 1:ff74eabe02cd | 148 | } |
| simon | 1:ff74eabe02cd | 149 | |
| simon | 1:ff74eabe02cd | 150 | int ep_read(uint8_t ep, uint8_t *tbuf) { |
| simon | 1:ff74eabe02cd | 151 | uint32_t *buf = (uint32_t*) tbuf; |
| simon | 1:ff74eabe02cd | 152 | LPC_USB->USBCtrl = LOG_ENDPOINT(ep)|RD_EN; // RD_EN bit and LOG_ENDPOINT |
| simon | 1:ff74eabe02cd | 153 | while (!(LPC_USB->USBRxPLen & PKT_RDY)); // wait for packet to be fetched |
| simon | 1:ff74eabe02cd | 154 | int len = LPC_USB->USBRxPLen & 0x3FF; // read and mask packet length |
| simon | 1:ff74eabe02cd | 155 | while (!(LPC_USB->USBDevIntSt & RxENDPKT)) { |
| simon | 1:ff74eabe02cd | 156 | *buf++ = LPC_USB->USBRxData; |
| simon | 1:ff74eabe02cd | 157 | } |
| simon | 1:ff74eabe02cd | 158 | LPC_USB->USBCtrl = 0; |
| simon | 1:ff74eabe02cd | 159 | LPC_USB->USBDevIntClr |= RxENDPKT; |
| simon | 1:ff74eabe02cd | 160 | sie_command(SIE_SEL_EP+ep); // select endpoint |
| simon | 1:ff74eabe02cd | 161 | sie_command(SIE_CLR_BUFFER); // clear RX buffer |
| simon | 1:ff74eabe02cd | 162 | return len; |
| simon | 1:ff74eabe02cd | 163 | } |
| simon | 1:ff74eabe02cd | 164 | |
| simon | 1:ff74eabe02cd | 165 | void ep_write(uint8_t ep, uint8_t *tbuf, uint32_t len) { |
| simon | 1:ff74eabe02cd | 166 | uint32_t *buf = (uint32_t*) tbuf; |
| simon | 1:ff74eabe02cd | 167 | LPC_USB->USBCtrl = LOG_ENDPOINT(ep)|WR_EN; // RD_EN bit and LOG_ENDPOINT |
| simon | 1:ff74eabe02cd | 168 | LPC_USB->USBTxPLen |= (len & 0x3FF); // write and mask packet length |
| simon | 1:ff74eabe02cd | 169 | while (!(LPC_USB->USBDevIntSt & TxENDPKT)) { |
| simon | 1:ff74eabe02cd | 170 | LPC_USB->USBTxData = *buf++; |
| simon | 1:ff74eabe02cd | 171 | } |
| simon | 1:ff74eabe02cd | 172 | LPC_USB->USBCtrl = 0; |
| simon | 1:ff74eabe02cd | 173 | LPC_USB->USBDevIntClr |= TxENDPKT; |
| simon | 1:ff74eabe02cd | 174 | sie_command(SIE_SEL_EP+ep); // select endpoint |
| simon | 1:ff74eabe02cd | 175 | sie_command(SIE_VAL_BUFFER); // validate TX buffer |
| simon | 1:ff74eabe02cd | 176 | } |
| simon | 1:ff74eabe02cd | 177 | |
| simon | 1:ff74eabe02cd | 178 | // USB device controller initialization |
| simon | 1:ff74eabe02cd | 179 | void usb_init() { |
| simon | 1:ff74eabe02cd | 180 | // USB D+/D- pinsel functions |
| simon | 1:ff74eabe02cd | 181 | LPC_PINCON->PINSEL1 &= 0xC3FFFFFF; |
| simon | 1:ff74eabe02cd | 182 | LPC_PINCON->PINSEL1 |= 0x14000000; |
| simon | 1:ff74eabe02cd | 183 | |
| simon | 1:ff74eabe02cd | 184 | #if USB_UP_DEBUG |
| simon | 1:ff74eabe02cd | 185 | // USB_UP_LED pinsel function |
| simon | 1:ff74eabe02cd | 186 | LPC_PINCON->PINSEL3 &= 0xFFFFFFCF; |
| simon | 1:ff74eabe02cd | 187 | LPC_PINCON->PINSEL3 |= 0x00000010; |
| simon | 1:ff74eabe02cd | 188 | #endif |
| simon | 1:ff74eabe02cd | 189 | |
| simon | 1:ff74eabe02cd | 190 | // USB connect pinsel function |
| simon | 1:ff74eabe02cd | 191 | LPC_PINCON->PINSEL4 &= 0xFFFCFFFF; |
| simon | 1:ff74eabe02cd | 192 | LPC_PINCON->PINSEL4 |= 0x00040000; |
| simon | 1:ff74eabe02cd | 193 | LPC_SC->PCONP |= (1UL<<31); // enable the USB controller |
| simon | 1:ff74eabe02cd | 194 | LPC_USB->USBClkCtrl |= ((1<<1)|(1<<4)); // enable the AHB and DEV clocks |
| simon | 1:ff74eabe02cd | 195 | while ((LPC_USB->USBClkSt & 0x12) != 0x12); // wait for the clocks to init |
| simon | 1:ff74eabe02cd | 196 | |
| simon | 1:ff74eabe02cd | 197 | NVIC_SetVector(USB_IRQn, (uint32_t)&USB_IRQHandler); |
| simon | 1:ff74eabe02cd | 198 | NVIC_EnableIRQ(USB_IRQn); // enable USB interrupts |
| simon | 1:ff74eabe02cd | 199 | |
| simon | 1:ff74eabe02cd | 200 | usb_reset(); |
| simon | 1:ff74eabe02cd | 201 | usb_set_address(0); // default address |
| simon | 1:ff74eabe02cd | 202 | } |
| simon | 1:ff74eabe02cd | 203 | |
| simon | 1:ff74eabe02cd | 204 | void usb_reset() { |
| simon | 1:ff74eabe02cd | 205 | ep_realize(EP0, MAX_EP0_PSIZE); |
| simon | 1:ff74eabe02cd | 206 | ep_realize(EP1, MAX_EP0_PSIZE); |
| simon | 1:ff74eabe02cd | 207 | LPC_USB->USBEpIntClr = 0xFFFFFFFF; // clear end points interrupts |
| simon | 1:ff74eabe02cd | 208 | LPC_USB->USBEpIntEn = 0xFFFFFFFF; // enable end points interrupts |
| simon | 1:ff74eabe02cd | 209 | LPC_USB->USBEpIntPri = 0x0; // route to EP_SLOW |
| simon | 1:ff74eabe02cd | 210 | LPC_USB->USBDevIntClr = 0xFFFFFFFF; // clear USB device interrupts |
| simon | 1:ff74eabe02cd | 211 | LPC_USB->USBDevIntEn = (EP_SLOW|DEV_STAT); // enable USB device interrupts |
| simon | 1:ff74eabe02cd | 212 | } |
| simon | 1:ff74eabe02cd | 213 | |
| simon | 1:ff74eabe02cd | 214 | void usb_configure(uint8_t conf) { |
| simon | 1:ff74eabe02cd | 215 | sie_command(SIE_CONFIG_DEVICE); |
| simon | 1:ff74eabe02cd | 216 | sie_write(conf); |
| simon | 1:ff74eabe02cd | 217 | configured = 1; |
| simon | 1:ff74eabe02cd | 218 | } |
| simon | 1:ff74eabe02cd | 219 | |
| simon | 1:ff74eabe02cd | 220 | int usb_configured() { |
| simon | 1:ff74eabe02cd | 221 | return configured; |
| simon | 1:ff74eabe02cd | 222 | } |
| simon | 1:ff74eabe02cd | 223 | |
| simon | 1:ff74eabe02cd | 224 | void usb_set_address(uint8_t addr) { |
| simon | 1:ff74eabe02cd | 225 | sie_command(SIE_SET_ADDR); |
| simon | 1:ff74eabe02cd | 226 | sie_write(addr|0x80); // DEV_EN = 1 |
| simon | 1:ff74eabe02cd | 227 | } |
| simon | 1:ff74eabe02cd | 228 | |
| simon | 1:ff74eabe02cd | 229 | uint8_t usb_get_status() { |
| simon | 1:ff74eabe02cd | 230 | sie_command(SIE_GET_STATUS); |
| simon | 1:ff74eabe02cd | 231 | return sie_read(SIE_GET_STATUS); |
| simon | 1:ff74eabe02cd | 232 | } |
| simon | 1:ff74eabe02cd | 233 | |
| simon | 1:ff74eabe02cd | 234 | void usb_connect() { |
| simon | 1:ff74eabe02cd | 235 | sie_command(SIE_GET_STATUS); // read current status |
| simon | 1:ff74eabe02cd | 236 | uint8_t st = sie_read(SIE_GET_STATUS); |
| simon | 1:ff74eabe02cd | 237 | |
| simon | 1:ff74eabe02cd | 238 | sie_command(SIE_SET_STATUS); // set STAT_CON bit |
| simon | 1:ff74eabe02cd | 239 | sie_write(st|STAT_CON); |
| simon | 1:ff74eabe02cd | 240 | } |
| simon | 1:ff74eabe02cd | 241 | |
| simon | 1:ff74eabe02cd | 242 | void USB_IRQHandler(void) { |
| simon | 1:ff74eabe02cd | 243 | if (LPC_USB->USBDevIntSt & DEV_STAT) { // DEV_STAT interrupt |
| simon | 1:ff74eabe02cd | 244 | LPC_USB->USBDevIntClr |= DEV_STAT; |
| simon | 1:ff74eabe02cd | 245 | if (usb_get_status() & STAT_RST) { // bus reset |
| simon | 1:ff74eabe02cd | 246 | usb_reset(); |
| simon | 1:ff74eabe02cd | 247 | } |
| simon | 1:ff74eabe02cd | 248 | return; |
| simon | 1:ff74eabe02cd | 249 | } |
| simon | 1:ff74eabe02cd | 250 | |
| simon | 1:ff74eabe02cd | 251 | if (LPC_USB->USBDevIntSt & EP_SLOW) { // EP_SLOW interrupt |
| simon | 1:ff74eabe02cd | 252 | if (LPC_USB->USBEpIntSt & EP0RX_INT) { |
| simon | 1:ff74eabe02cd | 253 | if (ep_select_clear(EP0RX_INT) & EP_STP) { // setup transfer |
| simon | 1:ff74eabe02cd | 254 | ep0_setup(); |
| simon | 1:ff74eabe02cd | 255 | } else { |
| simon | 1:ff74eabe02cd | 256 | ep0_out(); |
| simon | 1:ff74eabe02cd | 257 | } |
| simon | 1:ff74eabe02cd | 258 | } |
| simon | 1:ff74eabe02cd | 259 | |
| simon | 1:ff74eabe02cd | 260 | if (LPC_USB->USBEpIntSt & EP0TX_INT) { |
| simon | 1:ff74eabe02cd | 261 | ep_select_clear(EP0TX_INT); |
| simon | 1:ff74eabe02cd | 262 | ep0_in(); |
| simon | 1:ff74eabe02cd | 263 | } |
| simon | 1:ff74eabe02cd | 264 | |
| simon | 1:ff74eabe02cd | 265 | if (LPC_USB->USBEpIntSt & EP2RX_INT) { |
| simon | 1:ff74eabe02cd | 266 | ep_select_clear(EP2TX_INT); |
| simon | 1:ff74eabe02cd | 267 | ep2_out(); |
| simon | 1:ff74eabe02cd | 268 | } |
| simon | 1:ff74eabe02cd | 269 | |
| simon | 1:ff74eabe02cd | 270 | if (LPC_USB->USBEpIntSt & EP2TX_INT) { |
| simon | 1:ff74eabe02cd | 271 | ep_select_clear(EP2TX_INT); |
| simon | 1:ff74eabe02cd | 272 | ep2_in(); |
| simon | 1:ff74eabe02cd | 273 | } |
| simon | 1:ff74eabe02cd | 274 | |
| simon | 1:ff74eabe02cd | 275 | // EP_SLOW should be cleared after clearing EPs interrupts |
| simon | 1:ff74eabe02cd | 276 | LPC_USB->USBDevIntClr |= EP_SLOW; |
| simon | 1:ff74eabe02cd | 277 | } |
| simon | 1:ff74eabe02cd | 278 | } |
