library

Dependents:   USB_CDC_MSD_Hello

Committer:
sherckuith
Date:
Fri Aug 24 02:01:51 2012 +0000
Revision:
0:d5bb9a9c3e24
[mbed] converted /USB_CDC_MSD_Hello/USBDevice

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sherckuith 0:d5bb9a9c3e24 1 // USBBusInterface_LPC17_LPC23.c
sherckuith 0:d5bb9a9c3e24 2 // USB Bus Interface for NXP LPC1768 and LPC2368
sherckuith 0:d5bb9a9c3e24 3 // Copyright (c) 2011 ARM Limited. All rights reserved.
sherckuith 0:d5bb9a9c3e24 4
sherckuith 0:d5bb9a9c3e24 5 #ifdef TARGET_LPC1768
sherckuith 0:d5bb9a9c3e24 6
sherckuith 0:d5bb9a9c3e24 7 #include "USBBusInterface.h"
sherckuith 0:d5bb9a9c3e24 8
sherckuith 0:d5bb9a9c3e24 9
sherckuith 0:d5bb9a9c3e24 10 // Get endpoint direction
sherckuith 0:d5bb9a9c3e24 11 #define IN_EP(endpoint) ((endpoint) & 1U ? true : false)
sherckuith 0:d5bb9a9c3e24 12 #define OUT_EP(endpoint) ((endpoint) & 1U ? false : true)
sherckuith 0:d5bb9a9c3e24 13
sherckuith 0:d5bb9a9c3e24 14 // Convert physical endpoint number to register bit
sherckuith 0:d5bb9a9c3e24 15 #define EP(endpoint) (1UL<<endpoint)
sherckuith 0:d5bb9a9c3e24 16
sherckuith 0:d5bb9a9c3e24 17 // Power Control for Peripherals register
sherckuith 0:d5bb9a9c3e24 18 #define PCUSB (1UL<<31)
sherckuith 0:d5bb9a9c3e24 19
sherckuith 0:d5bb9a9c3e24 20 // USB Clock Control register
sherckuith 0:d5bb9a9c3e24 21 #define DEV_CLK_EN (1UL<<1)
sherckuith 0:d5bb9a9c3e24 22 #define AHB_CLK_EN (1UL<<4)
sherckuith 0:d5bb9a9c3e24 23
sherckuith 0:d5bb9a9c3e24 24 // USB Clock Status register
sherckuith 0:d5bb9a9c3e24 25 #define DEV_CLK_ON (1UL<<1)
sherckuith 0:d5bb9a9c3e24 26 #define AHB_CLK_ON (1UL<<4)
sherckuith 0:d5bb9a9c3e24 27
sherckuith 0:d5bb9a9c3e24 28 // USB Device Interupt registers
sherckuith 0:d5bb9a9c3e24 29 #define FRAME (1UL<<0)
sherckuith 0:d5bb9a9c3e24 30 #define EP_FAST (1UL<<1)
sherckuith 0:d5bb9a9c3e24 31 #define EP_SLOW (1UL<<2)
sherckuith 0:d5bb9a9c3e24 32 #define DEV_STAT (1UL<<3)
sherckuith 0:d5bb9a9c3e24 33 #define CCEMPTY (1UL<<4)
sherckuith 0:d5bb9a9c3e24 34 #define CDFULL (1UL<<5)
sherckuith 0:d5bb9a9c3e24 35 #define RxENDPKT (1UL<<6)
sherckuith 0:d5bb9a9c3e24 36 #define TxENDPKT (1UL<<7)
sherckuith 0:d5bb9a9c3e24 37 #define EP_RLZED (1UL<<8)
sherckuith 0:d5bb9a9c3e24 38 #define ERR_INT (1UL<<9)
sherckuith 0:d5bb9a9c3e24 39
sherckuith 0:d5bb9a9c3e24 40 // USB Control register
sherckuith 0:d5bb9a9c3e24 41 #define RD_EN (1<<0)
sherckuith 0:d5bb9a9c3e24 42 #define WR_EN (1<<1)
sherckuith 0:d5bb9a9c3e24 43 #define LOG_ENDPOINT(endpoint) ((endpoint>>1)<<2)
sherckuith 0:d5bb9a9c3e24 44
sherckuith 0:d5bb9a9c3e24 45 // USB Receive Packet Length register
sherckuith 0:d5bb9a9c3e24 46 #define DV (1UL<<10)
sherckuith 0:d5bb9a9c3e24 47 #define PKT_RDY (1UL<<11)
sherckuith 0:d5bb9a9c3e24 48 #define PKT_LNGTH_MASK (0x3ff)
sherckuith 0:d5bb9a9c3e24 49
sherckuith 0:d5bb9a9c3e24 50 // Serial Interface Engine (SIE)
sherckuith 0:d5bb9a9c3e24 51 #define SIE_WRITE (0x01)
sherckuith 0:d5bb9a9c3e24 52 #define SIE_READ (0x02)
sherckuith 0:d5bb9a9c3e24 53 #define SIE_COMMAND (0x05)
sherckuith 0:d5bb9a9c3e24 54 #define SIE_CMD_CODE(phase, data) ((phase<<8)|(data<<16))
sherckuith 0:d5bb9a9c3e24 55
sherckuith 0:d5bb9a9c3e24 56 // SIE Command codes
sherckuith 0:d5bb9a9c3e24 57 #define SIE_CMD_SET_ADDRESS (0xD0)
sherckuith 0:d5bb9a9c3e24 58 #define SIE_CMD_CONFIGURE_DEVICE (0xD8)
sherckuith 0:d5bb9a9c3e24 59 #define SIE_CMD_SET_MODE (0xF3)
sherckuith 0:d5bb9a9c3e24 60 #define SIE_CMD_READ_FRAME_NUMBER (0xF5)
sherckuith 0:d5bb9a9c3e24 61 #define SIE_CMD_READ_TEST_REGISTER (0xFD)
sherckuith 0:d5bb9a9c3e24 62 #define SIE_CMD_SET_DEVICE_STATUS (0xFE)
sherckuith 0:d5bb9a9c3e24 63 #define SIE_CMD_GET_DEVICE_STATUS (0xFE)
sherckuith 0:d5bb9a9c3e24 64 #define SIE_CMD_GET_ERROR_CODE (0xFF)
sherckuith 0:d5bb9a9c3e24 65 #define SIE_CMD_READ_ERROR_STATUS (0xFB)
sherckuith 0:d5bb9a9c3e24 66
sherckuith 0:d5bb9a9c3e24 67 #define SIE_CMD_SELECT_ENDPOINT(endpoint) (0x00+endpoint)
sherckuith 0:d5bb9a9c3e24 68 #define SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint) (0x40+endpoint)
sherckuith 0:d5bb9a9c3e24 69 #define SIE_CMD_SET_ENDPOINT_STATUS(endpoint) (0x40+endpoint)
sherckuith 0:d5bb9a9c3e24 70
sherckuith 0:d5bb9a9c3e24 71 #define SIE_CMD_CLEAR_BUFFER (0xF2)
sherckuith 0:d5bb9a9c3e24 72 #define SIE_CMD_VALIDATE_BUFFER (0xFA)
sherckuith 0:d5bb9a9c3e24 73
sherckuith 0:d5bb9a9c3e24 74 // SIE Device Status register
sherckuith 0:d5bb9a9c3e24 75 #define SIE_DS_CON (1<<0)
sherckuith 0:d5bb9a9c3e24 76 #define SIE_DS_CON_CH (1<<1)
sherckuith 0:d5bb9a9c3e24 77 #define SIE_DS_SUS (1<<2)
sherckuith 0:d5bb9a9c3e24 78 #define SIE_DS_SUS_CH (1<<3)
sherckuith 0:d5bb9a9c3e24 79 #define SIE_DS_RST (1<<4)
sherckuith 0:d5bb9a9c3e24 80
sherckuith 0:d5bb9a9c3e24 81 // SIE Device Set Address register
sherckuith 0:d5bb9a9c3e24 82 #define SIE_DSA_DEV_EN (1<<7)
sherckuith 0:d5bb9a9c3e24 83
sherckuith 0:d5bb9a9c3e24 84 // SIE Configue Device register
sherckuith 0:d5bb9a9c3e24 85 #define SIE_CONF_DEVICE (1<<0)
sherckuith 0:d5bb9a9c3e24 86
sherckuith 0:d5bb9a9c3e24 87 // Select Endpoint register
sherckuith 0:d5bb9a9c3e24 88 #define SIE_SE_FE (1<<0)
sherckuith 0:d5bb9a9c3e24 89 #define SIE_SE_ST (1<<1)
sherckuith 0:d5bb9a9c3e24 90 #define SIE_SE_STP (1<<2)
sherckuith 0:d5bb9a9c3e24 91 #define SIE_SE_PO (1<<3)
sherckuith 0:d5bb9a9c3e24 92 #define SIE_SE_EPN (1<<4)
sherckuith 0:d5bb9a9c3e24 93 #define SIE_SE_B_1_FULL (1<<5)
sherckuith 0:d5bb9a9c3e24 94 #define SIE_SE_B_2_FULL (1<<6)
sherckuith 0:d5bb9a9c3e24 95
sherckuith 0:d5bb9a9c3e24 96 // Set Endpoint Status command
sherckuith 0:d5bb9a9c3e24 97 #define SIE_SES_ST (1<<0)
sherckuith 0:d5bb9a9c3e24 98 #define SIE_SES_DA (1<<5)
sherckuith 0:d5bb9a9c3e24 99 #define SIE_SES_RF_MO (1<<6)
sherckuith 0:d5bb9a9c3e24 100 #define SIE_SES_CND_ST (1<<7)
sherckuith 0:d5bb9a9c3e24 101
sherckuith 0:d5bb9a9c3e24 102
sherckuith 0:d5bb9a9c3e24 103 USBHAL * USBHAL::instance;
sherckuith 0:d5bb9a9c3e24 104
sherckuith 0:d5bb9a9c3e24 105 volatile int epComplete;
sherckuith 0:d5bb9a9c3e24 106 uint32_t endpointStallState;
sherckuith 0:d5bb9a9c3e24 107
sherckuith 0:d5bb9a9c3e24 108 static void SIECommand(uint32_t command) {
sherckuith 0:d5bb9a9c3e24 109 // The command phase of a SIE transaction
sherckuith 0:d5bb9a9c3e24 110 LPC_USB->USBDevIntClr = CCEMPTY;
sherckuith 0:d5bb9a9c3e24 111 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_COMMAND, command);
sherckuith 0:d5bb9a9c3e24 112 while (!(LPC_USB->USBDevIntSt & CCEMPTY));
sherckuith 0:d5bb9a9c3e24 113 }
sherckuith 0:d5bb9a9c3e24 114
sherckuith 0:d5bb9a9c3e24 115 static void SIEWriteData(uint8_t data) {
sherckuith 0:d5bb9a9c3e24 116 // The data write phase of a SIE transaction
sherckuith 0:d5bb9a9c3e24 117 LPC_USB->USBDevIntClr = CCEMPTY;
sherckuith 0:d5bb9a9c3e24 118 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_WRITE, data);
sherckuith 0:d5bb9a9c3e24 119 while (!(LPC_USB->USBDevIntSt & CCEMPTY));
sherckuith 0:d5bb9a9c3e24 120 }
sherckuith 0:d5bb9a9c3e24 121
sherckuith 0:d5bb9a9c3e24 122 static uint8_t SIEReadData(uint32_t command) {
sherckuith 0:d5bb9a9c3e24 123 // The data read phase of a SIE transaction
sherckuith 0:d5bb9a9c3e24 124 LPC_USB->USBDevIntClr = CDFULL;
sherckuith 0:d5bb9a9c3e24 125 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_READ, command);
sherckuith 0:d5bb9a9c3e24 126 while (!(LPC_USB->USBDevIntSt & CDFULL));
sherckuith 0:d5bb9a9c3e24 127 return (uint8_t)LPC_USB->USBCmdData;
sherckuith 0:d5bb9a9c3e24 128 }
sherckuith 0:d5bb9a9c3e24 129
sherckuith 0:d5bb9a9c3e24 130 static void SIEsetDeviceStatus(uint8_t status) {
sherckuith 0:d5bb9a9c3e24 131 // Write SIE device status register
sherckuith 0:d5bb9a9c3e24 132 SIECommand(SIE_CMD_SET_DEVICE_STATUS);
sherckuith 0:d5bb9a9c3e24 133 SIEWriteData(status);
sherckuith 0:d5bb9a9c3e24 134 }
sherckuith 0:d5bb9a9c3e24 135
sherckuith 0:d5bb9a9c3e24 136 static uint8_t SIEgetDeviceStatus(void) {
sherckuith 0:d5bb9a9c3e24 137 // Read SIE device status register
sherckuith 0:d5bb9a9c3e24 138 SIECommand(SIE_CMD_GET_DEVICE_STATUS);
sherckuith 0:d5bb9a9c3e24 139 return SIEReadData(SIE_CMD_GET_DEVICE_STATUS);
sherckuith 0:d5bb9a9c3e24 140 }
sherckuith 0:d5bb9a9c3e24 141
sherckuith 0:d5bb9a9c3e24 142 void SIEsetAddress(uint8_t address) {
sherckuith 0:d5bb9a9c3e24 143 // Write SIE device address register
sherckuith 0:d5bb9a9c3e24 144 SIECommand(SIE_CMD_SET_ADDRESS);
sherckuith 0:d5bb9a9c3e24 145 SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN);
sherckuith 0:d5bb9a9c3e24 146 }
sherckuith 0:d5bb9a9c3e24 147
sherckuith 0:d5bb9a9c3e24 148 static uint8_t SIEselectEndpoint(uint8_t endpoint) {
sherckuith 0:d5bb9a9c3e24 149 // SIE select endpoint command
sherckuith 0:d5bb9a9c3e24 150 SIECommand(SIE_CMD_SELECT_ENDPOINT(endpoint));
sherckuith 0:d5bb9a9c3e24 151 return SIEReadData(SIE_CMD_SELECT_ENDPOINT(endpoint));
sherckuith 0:d5bb9a9c3e24 152 }
sherckuith 0:d5bb9a9c3e24 153
sherckuith 0:d5bb9a9c3e24 154 static uint8_t SIEclearBuffer(void) {
sherckuith 0:d5bb9a9c3e24 155 // SIE clear buffer command
sherckuith 0:d5bb9a9c3e24 156 SIECommand(SIE_CMD_CLEAR_BUFFER);
sherckuith 0:d5bb9a9c3e24 157 return SIEReadData(SIE_CMD_CLEAR_BUFFER);
sherckuith 0:d5bb9a9c3e24 158 }
sherckuith 0:d5bb9a9c3e24 159
sherckuith 0:d5bb9a9c3e24 160 static void SIEvalidateBuffer(void) {
sherckuith 0:d5bb9a9c3e24 161 // SIE validate buffer command
sherckuith 0:d5bb9a9c3e24 162 SIECommand(SIE_CMD_VALIDATE_BUFFER);
sherckuith 0:d5bb9a9c3e24 163 }
sherckuith 0:d5bb9a9c3e24 164
sherckuith 0:d5bb9a9c3e24 165 static void SIEsetEndpointStatus(uint8_t endpoint, uint8_t status) {
sherckuith 0:d5bb9a9c3e24 166 // SIE set endpoint status command
sherckuith 0:d5bb9a9c3e24 167 SIECommand(SIE_CMD_SET_ENDPOINT_STATUS(endpoint));
sherckuith 0:d5bb9a9c3e24 168 SIEWriteData(status);
sherckuith 0:d5bb9a9c3e24 169 }
sherckuith 0:d5bb9a9c3e24 170
sherckuith 0:d5bb9a9c3e24 171 static uint16_t SIEgetFrameNumber(void) __attribute__ ((unused));
sherckuith 0:d5bb9a9c3e24 172 static uint16_t SIEgetFrameNumber(void) {
sherckuith 0:d5bb9a9c3e24 173 // Read current frame number
sherckuith 0:d5bb9a9c3e24 174 uint16_t lowByte;
sherckuith 0:d5bb9a9c3e24 175 uint16_t highByte;
sherckuith 0:d5bb9a9c3e24 176
sherckuith 0:d5bb9a9c3e24 177 SIECommand(SIE_CMD_READ_FRAME_NUMBER);
sherckuith 0:d5bb9a9c3e24 178 lowByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER);
sherckuith 0:d5bb9a9c3e24 179 highByte = SIEReadData(SIE_CMD_READ_FRAME_NUMBER);
sherckuith 0:d5bb9a9c3e24 180
sherckuith 0:d5bb9a9c3e24 181 return (highByte << 8) | lowByte;
sherckuith 0:d5bb9a9c3e24 182 }
sherckuith 0:d5bb9a9c3e24 183
sherckuith 0:d5bb9a9c3e24 184 static void SIEconfigureDevice(void) {
sherckuith 0:d5bb9a9c3e24 185 // SIE Configure device command
sherckuith 0:d5bb9a9c3e24 186 SIECommand(SIE_CMD_CONFIGURE_DEVICE);
sherckuith 0:d5bb9a9c3e24 187 SIEWriteData(SIE_CONF_DEVICE);
sherckuith 0:d5bb9a9c3e24 188 }
sherckuith 0:d5bb9a9c3e24 189
sherckuith 0:d5bb9a9c3e24 190 static void SIEunconfigureDevice(void) {
sherckuith 0:d5bb9a9c3e24 191 // SIE Configure device command
sherckuith 0:d5bb9a9c3e24 192 SIECommand(SIE_CMD_CONFIGURE_DEVICE);
sherckuith 0:d5bb9a9c3e24 193 SIEWriteData(0);
sherckuith 0:d5bb9a9c3e24 194 }
sherckuith 0:d5bb9a9c3e24 195
sherckuith 0:d5bb9a9c3e24 196 static void SIEconnect(void) {
sherckuith 0:d5bb9a9c3e24 197 // Connect USB device
sherckuith 0:d5bb9a9c3e24 198 uint8_t status;
sherckuith 0:d5bb9a9c3e24 199
sherckuith 0:d5bb9a9c3e24 200 status = SIEgetDeviceStatus();
sherckuith 0:d5bb9a9c3e24 201 SIEsetDeviceStatus(status | SIE_DS_CON);
sherckuith 0:d5bb9a9c3e24 202 }
sherckuith 0:d5bb9a9c3e24 203
sherckuith 0:d5bb9a9c3e24 204
sherckuith 0:d5bb9a9c3e24 205 static void SIEdisconnect(void) {
sherckuith 0:d5bb9a9c3e24 206 // Disconnect USB device
sherckuith 0:d5bb9a9c3e24 207 uint8_t status;
sherckuith 0:d5bb9a9c3e24 208
sherckuith 0:d5bb9a9c3e24 209 status = SIEgetDeviceStatus();
sherckuith 0:d5bb9a9c3e24 210 SIEsetDeviceStatus(status & ~SIE_DS_CON);
sherckuith 0:d5bb9a9c3e24 211 }
sherckuith 0:d5bb9a9c3e24 212
sherckuith 0:d5bb9a9c3e24 213
sherckuith 0:d5bb9a9c3e24 214 static uint8_t selectEndpointClearInterrupt(uint8_t endpoint) {
sherckuith 0:d5bb9a9c3e24 215 // Implemented using using EP_INT_CLR.
sherckuith 0:d5bb9a9c3e24 216 LPC_USB->USBEpIntClr = EP(endpoint);
sherckuith 0:d5bb9a9c3e24 217 while (!(LPC_USB->USBDevIntSt & CDFULL));
sherckuith 0:d5bb9a9c3e24 218 return (uint8_t)LPC_USB->USBCmdData;
sherckuith 0:d5bb9a9c3e24 219 }
sherckuith 0:d5bb9a9c3e24 220
sherckuith 0:d5bb9a9c3e24 221
sherckuith 0:d5bb9a9c3e24 222
sherckuith 0:d5bb9a9c3e24 223
sherckuith 0:d5bb9a9c3e24 224
sherckuith 0:d5bb9a9c3e24 225 static void enableEndpointEvent(uint8_t endpoint) {
sherckuith 0:d5bb9a9c3e24 226 // Enable an endpoint interrupt
sherckuith 0:d5bb9a9c3e24 227 LPC_USB->USBEpIntEn |= EP(endpoint);
sherckuith 0:d5bb9a9c3e24 228 }
sherckuith 0:d5bb9a9c3e24 229
sherckuith 0:d5bb9a9c3e24 230 static void disableEndpointEvent(uint8_t endpoint) __attribute__ ((unused));
sherckuith 0:d5bb9a9c3e24 231 static void disableEndpointEvent(uint8_t endpoint) {
sherckuith 0:d5bb9a9c3e24 232 // Disable an endpoint interrupt
sherckuith 0:d5bb9a9c3e24 233 LPC_USB->USBEpIntEn &= ~EP(endpoint);
sherckuith 0:d5bb9a9c3e24 234 }
sherckuith 0:d5bb9a9c3e24 235
sherckuith 0:d5bb9a9c3e24 236 static volatile uint32_t __attribute__((used)) dummyRead;
sherckuith 0:d5bb9a9c3e24 237
sherckuith 0:d5bb9a9c3e24 238
sherckuith 0:d5bb9a9c3e24 239 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
sherckuith 0:d5bb9a9c3e24 240 // Read from an OUT endpoint
sherckuith 0:d5bb9a9c3e24 241 uint32_t size;
sherckuith 0:d5bb9a9c3e24 242 uint32_t i;
sherckuith 0:d5bb9a9c3e24 243 uint32_t data = 0;
sherckuith 0:d5bb9a9c3e24 244 uint8_t offset;
sherckuith 0:d5bb9a9c3e24 245
sherckuith 0:d5bb9a9c3e24 246 LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | RD_EN;
sherckuith 0:d5bb9a9c3e24 247 while (!(LPC_USB->USBRxPLen & PKT_RDY));
sherckuith 0:d5bb9a9c3e24 248
sherckuith 0:d5bb9a9c3e24 249 size = LPC_USB->USBRxPLen & PKT_LNGTH_MASK;
sherckuith 0:d5bb9a9c3e24 250
sherckuith 0:d5bb9a9c3e24 251 offset = 0;
sherckuith 0:d5bb9a9c3e24 252
sherckuith 0:d5bb9a9c3e24 253 if (size > 0) {
sherckuith 0:d5bb9a9c3e24 254 for (i=0; i<size; i++) {
sherckuith 0:d5bb9a9c3e24 255 if (offset==0) {
sherckuith 0:d5bb9a9c3e24 256 // Fetch up to four bytes of data as a word
sherckuith 0:d5bb9a9c3e24 257 data = LPC_USB->USBRxData;
sherckuith 0:d5bb9a9c3e24 258 }
sherckuith 0:d5bb9a9c3e24 259
sherckuith 0:d5bb9a9c3e24 260 // extract a byte
sherckuith 0:d5bb9a9c3e24 261 *buffer = (data>>offset) & 0xff;
sherckuith 0:d5bb9a9c3e24 262 buffer++;
sherckuith 0:d5bb9a9c3e24 263
sherckuith 0:d5bb9a9c3e24 264 // move on to the next byte
sherckuith 0:d5bb9a9c3e24 265 offset = (offset + 8) % 32;
sherckuith 0:d5bb9a9c3e24 266 }
sherckuith 0:d5bb9a9c3e24 267 } else {
sherckuith 0:d5bb9a9c3e24 268 dummyRead = LPC_USB->USBRxData;
sherckuith 0:d5bb9a9c3e24 269 }
sherckuith 0:d5bb9a9c3e24 270
sherckuith 0:d5bb9a9c3e24 271 LPC_USB->USBCtrl = 0;
sherckuith 0:d5bb9a9c3e24 272
sherckuith 0:d5bb9a9c3e24 273 if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
sherckuith 0:d5bb9a9c3e24 274 SIEselectEndpoint(endpoint);
sherckuith 0:d5bb9a9c3e24 275 SIEclearBuffer();
sherckuith 0:d5bb9a9c3e24 276 }
sherckuith 0:d5bb9a9c3e24 277
sherckuith 0:d5bb9a9c3e24 278 return size;
sherckuith 0:d5bb9a9c3e24 279 }
sherckuith 0:d5bb9a9c3e24 280
sherckuith 0:d5bb9a9c3e24 281 static void endpointWritecore(uint8_t endpoint, uint8_t *buffer, uint32_t size) {
sherckuith 0:d5bb9a9c3e24 282 // Write to an IN endpoint
sherckuith 0:d5bb9a9c3e24 283 uint32_t temp, data;
sherckuith 0:d5bb9a9c3e24 284 uint8_t offset;
sherckuith 0:d5bb9a9c3e24 285
sherckuith 0:d5bb9a9c3e24 286 LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | WR_EN;
sherckuith 0:d5bb9a9c3e24 287
sherckuith 0:d5bb9a9c3e24 288 LPC_USB->USBTxPLen = size;
sherckuith 0:d5bb9a9c3e24 289 offset = 0;
sherckuith 0:d5bb9a9c3e24 290 data = 0;
sherckuith 0:d5bb9a9c3e24 291
sherckuith 0:d5bb9a9c3e24 292 if (size>0) {
sherckuith 0:d5bb9a9c3e24 293 do {
sherckuith 0:d5bb9a9c3e24 294 // Fetch next data byte into a word-sized temporary variable
sherckuith 0:d5bb9a9c3e24 295 temp = *buffer++;
sherckuith 0:d5bb9a9c3e24 296
sherckuith 0:d5bb9a9c3e24 297 // Add to current data word
sherckuith 0:d5bb9a9c3e24 298 temp = temp << offset;
sherckuith 0:d5bb9a9c3e24 299 data = data | temp;
sherckuith 0:d5bb9a9c3e24 300
sherckuith 0:d5bb9a9c3e24 301 // move on to the next byte
sherckuith 0:d5bb9a9c3e24 302 offset = (offset + 8) % 32;
sherckuith 0:d5bb9a9c3e24 303 size--;
sherckuith 0:d5bb9a9c3e24 304
sherckuith 0:d5bb9a9c3e24 305 if ((offset==0) || (size==0)) {
sherckuith 0:d5bb9a9c3e24 306 // Write the word to the endpoint
sherckuith 0:d5bb9a9c3e24 307 LPC_USB->USBTxData = data;
sherckuith 0:d5bb9a9c3e24 308 data = 0;
sherckuith 0:d5bb9a9c3e24 309 }
sherckuith 0:d5bb9a9c3e24 310 } while (size>0);
sherckuith 0:d5bb9a9c3e24 311 } else {
sherckuith 0:d5bb9a9c3e24 312 LPC_USB->USBTxData = 0;
sherckuith 0:d5bb9a9c3e24 313 }
sherckuith 0:d5bb9a9c3e24 314
sherckuith 0:d5bb9a9c3e24 315 // Clear WR_EN to cover zero length packet case
sherckuith 0:d5bb9a9c3e24 316 LPC_USB->USBCtrl=0;
sherckuith 0:d5bb9a9c3e24 317
sherckuith 0:d5bb9a9c3e24 318 SIEselectEndpoint(endpoint);
sherckuith 0:d5bb9a9c3e24 319 SIEvalidateBuffer();
sherckuith 0:d5bb9a9c3e24 320 }
sherckuith 0:d5bb9a9c3e24 321
sherckuith 0:d5bb9a9c3e24 322
sherckuith 0:d5bb9a9c3e24 323
sherckuith 0:d5bb9a9c3e24 324
sherckuith 0:d5bb9a9c3e24 325
sherckuith 0:d5bb9a9c3e24 326
sherckuith 0:d5bb9a9c3e24 327
sherckuith 0:d5bb9a9c3e24 328 USBHAL::USBHAL(void) {
sherckuith 0:d5bb9a9c3e24 329 // Disable IRQ
sherckuith 0:d5bb9a9c3e24 330 NVIC_DisableIRQ(USB_IRQn);
sherckuith 0:d5bb9a9c3e24 331
sherckuith 0:d5bb9a9c3e24 332 // Enable power to USB device controller
sherckuith 0:d5bb9a9c3e24 333 LPC_SC->PCONP |= PCUSB;
sherckuith 0:d5bb9a9c3e24 334
sherckuith 0:d5bb9a9c3e24 335 // Enable USB clocks
sherckuith 0:d5bb9a9c3e24 336 LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
sherckuith 0:d5bb9a9c3e24 337 while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON));
sherckuith 0:d5bb9a9c3e24 338
sherckuith 0:d5bb9a9c3e24 339 // Configure pins P0.29 and P0.30 to be USB D+ and USB D-
sherckuith 0:d5bb9a9c3e24 340 LPC_PINCON->PINSEL1 &= 0xc3ffffff;
sherckuith 0:d5bb9a9c3e24 341 LPC_PINCON->PINSEL1 |= 0x14000000;
sherckuith 0:d5bb9a9c3e24 342
sherckuith 0:d5bb9a9c3e24 343 // Disconnect USB device
sherckuith 0:d5bb9a9c3e24 344 SIEdisconnect();
sherckuith 0:d5bb9a9c3e24 345
sherckuith 0:d5bb9a9c3e24 346 // Configure pin P2.9 to be Connect
sherckuith 0:d5bb9a9c3e24 347 LPC_PINCON->PINSEL4 &= 0xfffcffff;
sherckuith 0:d5bb9a9c3e24 348 LPC_PINCON->PINSEL4 |= 0x00040000;
sherckuith 0:d5bb9a9c3e24 349
sherckuith 0:d5bb9a9c3e24 350 // Connect must be low for at least 2.5uS
sherckuith 0:d5bb9a9c3e24 351 wait(0.3);
sherckuith 0:d5bb9a9c3e24 352
sherckuith 0:d5bb9a9c3e24 353 // Set the maximum packet size for the control endpoints
sherckuith 0:d5bb9a9c3e24 354 realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0);
sherckuith 0:d5bb9a9c3e24 355 realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0);
sherckuith 0:d5bb9a9c3e24 356
sherckuith 0:d5bb9a9c3e24 357 // Attach IRQ
sherckuith 0:d5bb9a9c3e24 358 instance = this;
sherckuith 0:d5bb9a9c3e24 359 NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr);
sherckuith 0:d5bb9a9c3e24 360 NVIC_EnableIRQ(USB_IRQn);
sherckuith 0:d5bb9a9c3e24 361
sherckuith 0:d5bb9a9c3e24 362 // Enable interrupts for device events and EP0
sherckuith 0:d5bb9a9c3e24 363 LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT | FRAME;
sherckuith 0:d5bb9a9c3e24 364 enableEndpointEvent(EP0IN);
sherckuith 0:d5bb9a9c3e24 365 enableEndpointEvent(EP0OUT);
sherckuith 0:d5bb9a9c3e24 366 }
sherckuith 0:d5bb9a9c3e24 367
sherckuith 0:d5bb9a9c3e24 368 USBHAL::~USBHAL(void) {
sherckuith 0:d5bb9a9c3e24 369 // Ensure device disconnected
sherckuith 0:d5bb9a9c3e24 370 SIEdisconnect();
sherckuith 0:d5bb9a9c3e24 371
sherckuith 0:d5bb9a9c3e24 372 // Disable USB interrupts
sherckuith 0:d5bb9a9c3e24 373 NVIC_DisableIRQ(USB_IRQn);
sherckuith 0:d5bb9a9c3e24 374 }
sherckuith 0:d5bb9a9c3e24 375
sherckuith 0:d5bb9a9c3e24 376 void USBHAL::connect(void) {
sherckuith 0:d5bb9a9c3e24 377 // Connect USB device
sherckuith 0:d5bb9a9c3e24 378 SIEconnect();
sherckuith 0:d5bb9a9c3e24 379 }
sherckuith 0:d5bb9a9c3e24 380
sherckuith 0:d5bb9a9c3e24 381 void USBHAL::disconnect(void) {
sherckuith 0:d5bb9a9c3e24 382 // Disconnect USB device
sherckuith 0:d5bb9a9c3e24 383 SIEdisconnect();
sherckuith 0:d5bb9a9c3e24 384 }
sherckuith 0:d5bb9a9c3e24 385
sherckuith 0:d5bb9a9c3e24 386 void USBHAL::configureDevice(void) {
sherckuith 0:d5bb9a9c3e24 387 SIEconfigureDevice();
sherckuith 0:d5bb9a9c3e24 388 }
sherckuith 0:d5bb9a9c3e24 389
sherckuith 0:d5bb9a9c3e24 390 void USBHAL::unconfigureDevice(void) {
sherckuith 0:d5bb9a9c3e24 391 SIEunconfigureDevice();
sherckuith 0:d5bb9a9c3e24 392 }
sherckuith 0:d5bb9a9c3e24 393
sherckuith 0:d5bb9a9c3e24 394 void USBHAL::setAddress(uint8_t address) {
sherckuith 0:d5bb9a9c3e24 395 SIEsetAddress(address);
sherckuith 0:d5bb9a9c3e24 396 }
sherckuith 0:d5bb9a9c3e24 397
sherckuith 0:d5bb9a9c3e24 398 void USBHAL::EP0setup(uint8_t *buffer) {
sherckuith 0:d5bb9a9c3e24 399 endpointReadcore(EP0OUT, buffer);
sherckuith 0:d5bb9a9c3e24 400 }
sherckuith 0:d5bb9a9c3e24 401
sherckuith 0:d5bb9a9c3e24 402 void USBHAL::EP0read(void) {
sherckuith 0:d5bb9a9c3e24 403 // Not required
sherckuith 0:d5bb9a9c3e24 404 }
sherckuith 0:d5bb9a9c3e24 405
sherckuith 0:d5bb9a9c3e24 406 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
sherckuith 0:d5bb9a9c3e24 407 return endpointReadcore(EP0OUT, buffer);
sherckuith 0:d5bb9a9c3e24 408 }
sherckuith 0:d5bb9a9c3e24 409
sherckuith 0:d5bb9a9c3e24 410 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
sherckuith 0:d5bb9a9c3e24 411 endpointWritecore(EP0IN, buffer, size);
sherckuith 0:d5bb9a9c3e24 412 }
sherckuith 0:d5bb9a9c3e24 413
sherckuith 0:d5bb9a9c3e24 414 void USBHAL::EP0getWriteResult(void) {
sherckuith 0:d5bb9a9c3e24 415 // Not required
sherckuith 0:d5bb9a9c3e24 416 }
sherckuith 0:d5bb9a9c3e24 417
sherckuith 0:d5bb9a9c3e24 418 void USBHAL::EP0stall(void) {
sherckuith 0:d5bb9a9c3e24 419 // This will stall both control endpoints
sherckuith 0:d5bb9a9c3e24 420 stallEndpoint(EP0OUT);
sherckuith 0:d5bb9a9c3e24 421 }
sherckuith 0:d5bb9a9c3e24 422
sherckuith 0:d5bb9a9c3e24 423 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
sherckuith 0:d5bb9a9c3e24 424 return EP_PENDING;
sherckuith 0:d5bb9a9c3e24 425 }
sherckuith 0:d5bb9a9c3e24 426
sherckuith 0:d5bb9a9c3e24 427 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) {
sherckuith 0:d5bb9a9c3e24 428
sherckuith 0:d5bb9a9c3e24 429 //for isochronous endpoint, we don't wait an interrupt
sherckuith 0:d5bb9a9c3e24 430 if ((endpoint >> 1) % 3 || (endpoint >> 1) == 0) {
sherckuith 0:d5bb9a9c3e24 431 if (!(epComplete & EP(endpoint)))
sherckuith 0:d5bb9a9c3e24 432 return EP_PENDING;
sherckuith 0:d5bb9a9c3e24 433 }
sherckuith 0:d5bb9a9c3e24 434
sherckuith 0:d5bb9a9c3e24 435 *bytesRead = endpointReadcore(endpoint, buffer);
sherckuith 0:d5bb9a9c3e24 436 epComplete &= ~EP(endpoint);
sherckuith 0:d5bb9a9c3e24 437 return EP_COMPLETED;
sherckuith 0:d5bb9a9c3e24 438 }
sherckuith 0:d5bb9a9c3e24 439
sherckuith 0:d5bb9a9c3e24 440 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
sherckuith 0:d5bb9a9c3e24 441 if (getEndpointStallState(endpoint)) {
sherckuith 0:d5bb9a9c3e24 442 return EP_STALLED;
sherckuith 0:d5bb9a9c3e24 443 }
sherckuith 0:d5bb9a9c3e24 444
sherckuith 0:d5bb9a9c3e24 445 epComplete &= ~EP(endpoint);
sherckuith 0:d5bb9a9c3e24 446
sherckuith 0:d5bb9a9c3e24 447 endpointWritecore(endpoint, data, size);
sherckuith 0:d5bb9a9c3e24 448 return EP_PENDING;
sherckuith 0:d5bb9a9c3e24 449 }
sherckuith 0:d5bb9a9c3e24 450
sherckuith 0:d5bb9a9c3e24 451 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
sherckuith 0:d5bb9a9c3e24 452 if (epComplete & EP(endpoint)) {
sherckuith 0:d5bb9a9c3e24 453 epComplete &= ~EP(endpoint);
sherckuith 0:d5bb9a9c3e24 454 return EP_COMPLETED;
sherckuith 0:d5bb9a9c3e24 455 }
sherckuith 0:d5bb9a9c3e24 456
sherckuith 0:d5bb9a9c3e24 457 return EP_PENDING;
sherckuith 0:d5bb9a9c3e24 458 }
sherckuith 0:d5bb9a9c3e24 459
sherckuith 0:d5bb9a9c3e24 460 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) {
sherckuith 0:d5bb9a9c3e24 461 // Realise an endpoint
sherckuith 0:d5bb9a9c3e24 462 LPC_USB->USBDevIntClr = EP_RLZED;
sherckuith 0:d5bb9a9c3e24 463 LPC_USB->USBReEp |= EP(endpoint);
sherckuith 0:d5bb9a9c3e24 464 LPC_USB->USBEpInd = endpoint;
sherckuith 0:d5bb9a9c3e24 465 LPC_USB->USBMaxPSize = maxPacket;
sherckuith 0:d5bb9a9c3e24 466
sherckuith 0:d5bb9a9c3e24 467 while (!(LPC_USB->USBDevIntSt & EP_RLZED));
sherckuith 0:d5bb9a9c3e24 468 LPC_USB->USBDevIntClr = EP_RLZED;
sherckuith 0:d5bb9a9c3e24 469
sherckuith 0:d5bb9a9c3e24 470 // Clear stall state
sherckuith 0:d5bb9a9c3e24 471 endpointStallState &= ~EP(endpoint);
sherckuith 0:d5bb9a9c3e24 472
sherckuith 0:d5bb9a9c3e24 473 enableEndpointEvent(endpoint);
sherckuith 0:d5bb9a9c3e24 474 return true;
sherckuith 0:d5bb9a9c3e24 475 }
sherckuith 0:d5bb9a9c3e24 476
sherckuith 0:d5bb9a9c3e24 477 void USBHAL::stallEndpoint(uint8_t endpoint) {
sherckuith 0:d5bb9a9c3e24 478 // Stall an endpoint
sherckuith 0:d5bb9a9c3e24 479 if ( (endpoint==EP0IN) || (endpoint==EP0OUT) ) {
sherckuith 0:d5bb9a9c3e24 480 // Conditionally stall both control endpoints
sherckuith 0:d5bb9a9c3e24 481 SIEsetEndpointStatus(EP0OUT, SIE_SES_CND_ST);
sherckuith 0:d5bb9a9c3e24 482 } else {
sherckuith 0:d5bb9a9c3e24 483 SIEsetEndpointStatus(endpoint, SIE_SES_ST);
sherckuith 0:d5bb9a9c3e24 484
sherckuith 0:d5bb9a9c3e24 485 // Update stall state
sherckuith 0:d5bb9a9c3e24 486 endpointStallState |= EP(endpoint);
sherckuith 0:d5bb9a9c3e24 487 }
sherckuith 0:d5bb9a9c3e24 488 }
sherckuith 0:d5bb9a9c3e24 489
sherckuith 0:d5bb9a9c3e24 490 void USBHAL::unstallEndpoint(uint8_t endpoint) {
sherckuith 0:d5bb9a9c3e24 491 // Unstall an endpoint. The endpoint will also be reinitialised
sherckuith 0:d5bb9a9c3e24 492 SIEsetEndpointStatus(endpoint, 0);
sherckuith 0:d5bb9a9c3e24 493
sherckuith 0:d5bb9a9c3e24 494 // Update stall state
sherckuith 0:d5bb9a9c3e24 495 endpointStallState &= ~EP(endpoint);
sherckuith 0:d5bb9a9c3e24 496 }
sherckuith 0:d5bb9a9c3e24 497
sherckuith 0:d5bb9a9c3e24 498 bool USBHAL::getEndpointStallState(uint8_t endpoint) {
sherckuith 0:d5bb9a9c3e24 499 // Returns true if endpoint stalled
sherckuith 0:d5bb9a9c3e24 500 return endpointStallState & EP(endpoint);
sherckuith 0:d5bb9a9c3e24 501 }
sherckuith 0:d5bb9a9c3e24 502
sherckuith 0:d5bb9a9c3e24 503 void USBHAL::remoteWakeup(void) {
sherckuith 0:d5bb9a9c3e24 504 // Remote wakeup
sherckuith 0:d5bb9a9c3e24 505 uint8_t status;
sherckuith 0:d5bb9a9c3e24 506
sherckuith 0:d5bb9a9c3e24 507 // Enable USB clocks
sherckuith 0:d5bb9a9c3e24 508 LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
sherckuith 0:d5bb9a9c3e24 509 while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON));
sherckuith 0:d5bb9a9c3e24 510
sherckuith 0:d5bb9a9c3e24 511 status = SIEgetDeviceStatus();
sherckuith 0:d5bb9a9c3e24 512 SIEsetDeviceStatus(status & ~SIE_DS_SUS);
sherckuith 0:d5bb9a9c3e24 513 }
sherckuith 0:d5bb9a9c3e24 514
sherckuith 0:d5bb9a9c3e24 515
sherckuith 0:d5bb9a9c3e24 516
sherckuith 0:d5bb9a9c3e24 517
sherckuith 0:d5bb9a9c3e24 518
sherckuith 0:d5bb9a9c3e24 519 void USBHAL::_usbisr(void) {
sherckuith 0:d5bb9a9c3e24 520 instance->usbisr();
sherckuith 0:d5bb9a9c3e24 521 }
sherckuith 0:d5bb9a9c3e24 522
sherckuith 0:d5bb9a9c3e24 523
sherckuith 0:d5bb9a9c3e24 524 void USBHAL::usbisr(void) {
sherckuith 0:d5bb9a9c3e24 525 uint8_t devStat;
sherckuith 0:d5bb9a9c3e24 526
sherckuith 0:d5bb9a9c3e24 527 if (LPC_USB->USBDevIntSt & FRAME) {
sherckuith 0:d5bb9a9c3e24 528 // Start of frame event
sherckuith 0:d5bb9a9c3e24 529 SOF(SIEgetFrameNumber());
sherckuith 0:d5bb9a9c3e24 530 // Clear interrupt status flag
sherckuith 0:d5bb9a9c3e24 531 LPC_USB->USBDevIntClr = FRAME;
sherckuith 0:d5bb9a9c3e24 532 }
sherckuith 0:d5bb9a9c3e24 533
sherckuith 0:d5bb9a9c3e24 534 if (LPC_USB->USBDevIntSt & DEV_STAT) {
sherckuith 0:d5bb9a9c3e24 535 // Device Status interrupt
sherckuith 0:d5bb9a9c3e24 536 // Must clear the interrupt status flag before reading the device status from the SIE
sherckuith 0:d5bb9a9c3e24 537 LPC_USB->USBDevIntClr = DEV_STAT;
sherckuith 0:d5bb9a9c3e24 538
sherckuith 0:d5bb9a9c3e24 539 // Read device status from SIE
sherckuith 0:d5bb9a9c3e24 540 devStat = SIEgetDeviceStatus();
sherckuith 0:d5bb9a9c3e24 541
sherckuith 0:d5bb9a9c3e24 542 if (devStat & SIE_DS_RST) {
sherckuith 0:d5bb9a9c3e24 543 // Bus reset
sherckuith 0:d5bb9a9c3e24 544 busReset();
sherckuith 0:d5bb9a9c3e24 545 }
sherckuith 0:d5bb9a9c3e24 546 }
sherckuith 0:d5bb9a9c3e24 547
sherckuith 0:d5bb9a9c3e24 548 if (LPC_USB->USBDevIntSt & EP_SLOW) {
sherckuith 0:d5bb9a9c3e24 549 // (Slow) Endpoint Interrupt
sherckuith 0:d5bb9a9c3e24 550
sherckuith 0:d5bb9a9c3e24 551 // Process each endpoint interrupt
sherckuith 0:d5bb9a9c3e24 552 if (LPC_USB->USBEpIntSt & EP(EP0OUT)) {
sherckuith 0:d5bb9a9c3e24 553 if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP) {
sherckuith 0:d5bb9a9c3e24 554 // this is a setup packet
sherckuith 0:d5bb9a9c3e24 555 EP0setupCallback();
sherckuith 0:d5bb9a9c3e24 556 } else {
sherckuith 0:d5bb9a9c3e24 557 EP0out();
sherckuith 0:d5bb9a9c3e24 558 }
sherckuith 0:d5bb9a9c3e24 559 LPC_USB->USBDevIntClr = EP_SLOW;
sherckuith 0:d5bb9a9c3e24 560 }
sherckuith 0:d5bb9a9c3e24 561
sherckuith 0:d5bb9a9c3e24 562 if (LPC_USB->USBEpIntSt & EP(EP0IN)) {
sherckuith 0:d5bb9a9c3e24 563 selectEndpointClearInterrupt(EP0IN);
sherckuith 0:d5bb9a9c3e24 564 LPC_USB->USBDevIntClr = EP_SLOW;
sherckuith 0:d5bb9a9c3e24 565 EP0in();
sherckuith 0:d5bb9a9c3e24 566 }
sherckuith 0:d5bb9a9c3e24 567
sherckuith 0:d5bb9a9c3e24 568 // TODO: This should cover all endpoints, not just EP1,2,3:
sherckuith 0:d5bb9a9c3e24 569 if (LPC_USB->USBEpIntSt & EP(EP1IN)) {
sherckuith 0:d5bb9a9c3e24 570 selectEndpointClearInterrupt(EP1IN);
sherckuith 0:d5bb9a9c3e24 571 epComplete |= EP(EP1IN);
sherckuith 0:d5bb9a9c3e24 572 LPC_USB->USBDevIntClr = EP_SLOW;
sherckuith 0:d5bb9a9c3e24 573 if (EP1_IN_callback())
sherckuith 0:d5bb9a9c3e24 574 epComplete &= ~EP(EP1IN);
sherckuith 0:d5bb9a9c3e24 575 }
sherckuith 0:d5bb9a9c3e24 576
sherckuith 0:d5bb9a9c3e24 577 if (LPC_USB->USBEpIntSt & EP(EP1OUT)) {
sherckuith 0:d5bb9a9c3e24 578 selectEndpointClearInterrupt(EP1OUT);
sherckuith 0:d5bb9a9c3e24 579 epComplete |= EP(EP1OUT);
sherckuith 0:d5bb9a9c3e24 580 LPC_USB->USBDevIntClr = EP_SLOW;
sherckuith 0:d5bb9a9c3e24 581 if (EP1_OUT_callback())
sherckuith 0:d5bb9a9c3e24 582 epComplete &= ~EP(EP1OUT);
sherckuith 0:d5bb9a9c3e24 583 }
sherckuith 0:d5bb9a9c3e24 584
sherckuith 0:d5bb9a9c3e24 585 if (LPC_USB->USBEpIntSt & EP(EP2IN)) {
sherckuith 0:d5bb9a9c3e24 586 selectEndpointClearInterrupt(EP2IN);
sherckuith 0:d5bb9a9c3e24 587 epComplete |= EP(EP2IN);
sherckuith 0:d5bb9a9c3e24 588 LPC_USB->USBDevIntClr = EP_SLOW;
sherckuith 0:d5bb9a9c3e24 589 if (EP2_IN_callback())
sherckuith 0:d5bb9a9c3e24 590 epComplete &= ~EP(EP2IN);
sherckuith 0:d5bb9a9c3e24 591 }
sherckuith 0:d5bb9a9c3e24 592
sherckuith 0:d5bb9a9c3e24 593 if (LPC_USB->USBEpIntSt & EP(EP2OUT)) {
sherckuith 0:d5bb9a9c3e24 594 selectEndpointClearInterrupt(EP2OUT);
sherckuith 0:d5bb9a9c3e24 595 epComplete |= EP(EP2OUT);
sherckuith 0:d5bb9a9c3e24 596 LPC_USB->USBDevIntClr = EP_SLOW;
sherckuith 0:d5bb9a9c3e24 597 if (EP2_OUT_callback())
sherckuith 0:d5bb9a9c3e24 598 epComplete &= ~EP(EP2OUT);
sherckuith 0:d5bb9a9c3e24 599 }
sherckuith 0:d5bb9a9c3e24 600
sherckuith 0:d5bb9a9c3e24 601 if (LPC_USB->USBEpIntSt & EP(EP3IN)) {
sherckuith 0:d5bb9a9c3e24 602 selectEndpointClearInterrupt(EP3IN);
sherckuith 0:d5bb9a9c3e24 603 epComplete |= EP(EP3IN);
sherckuith 0:d5bb9a9c3e24 604 LPC_USB->USBDevIntClr = EP_SLOW;
sherckuith 0:d5bb9a9c3e24 605 if (EP3_IN_callback())
sherckuith 0:d5bb9a9c3e24 606 epComplete &= ~EP(EP3IN);
sherckuith 0:d5bb9a9c3e24 607 }
sherckuith 0:d5bb9a9c3e24 608
sherckuith 0:d5bb9a9c3e24 609 if (LPC_USB->USBEpIntSt & EP(EP3OUT)) {
sherckuith 0:d5bb9a9c3e24 610 selectEndpointClearInterrupt(EP3OUT);
sherckuith 0:d5bb9a9c3e24 611 epComplete |= EP(EP3OUT);
sherckuith 0:d5bb9a9c3e24 612 LPC_USB->USBDevIntClr = EP_SLOW;
sherckuith 0:d5bb9a9c3e24 613 if (EP3_OUT_callback())
sherckuith 0:d5bb9a9c3e24 614 epComplete &= ~EP(EP3OUT);
sherckuith 0:d5bb9a9c3e24 615 }
sherckuith 0:d5bb9a9c3e24 616
sherckuith 0:d5bb9a9c3e24 617 if (LPC_USB->USBEpIntSt & EP(EP5IN)) {
sherckuith 0:d5bb9a9c3e24 618 selectEndpointClearInterrupt(EP5IN);
sherckuith 0:d5bb9a9c3e24 619 epComplete |= EP(EP5IN);
sherckuith 0:d5bb9a9c3e24 620 LPC_USB->USBDevIntClr = EP_SLOW;
sherckuith 0:d5bb9a9c3e24 621 if (EP5_IN_callback())
sherckuith 0:d5bb9a9c3e24 622 epComplete &= ~EP(EP5IN);
sherckuith 0:d5bb9a9c3e24 623 }
sherckuith 0:d5bb9a9c3e24 624
sherckuith 0:d5bb9a9c3e24 625 if (LPC_USB->USBEpIntSt & EP(EP5OUT)) {
sherckuith 0:d5bb9a9c3e24 626 selectEndpointClearInterrupt(EP5OUT);
sherckuith 0:d5bb9a9c3e24 627 epComplete |= EP(EP5OUT);
sherckuith 0:d5bb9a9c3e24 628 LPC_USB->USBDevIntClr = EP_SLOW;
sherckuith 0:d5bb9a9c3e24 629 if (EP5_OUT_callback())
sherckuith 0:d5bb9a9c3e24 630 epComplete &= ~EP(EP5OUT);
sherckuith 0:d5bb9a9c3e24 631 }
sherckuith 0:d5bb9a9c3e24 632 }
sherckuith 0:d5bb9a9c3e24 633 }
sherckuith 0:d5bb9a9c3e24 634
sherckuith 0:d5bb9a9c3e24 635 #endif