Hossein Rahmani / USBDevice
Committer:
Kojto
Date:
Thu Jul 27 12:14:04 2017 +0100
Revision:
72:53949e6131f6
Update libraries

Fixes the previous commmit, as some devices were not copied. USBDevice contains
now targets directory with all targets implementations

Who changed what in which revision?

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