This program operates a pH meter and requires an Excel spreadsheet template available at www.kissinstrments.com

Dependencies:   mbed

Committer:
KISScientific
Date:
Fri Jul 22 00:03:25 2016 +0000
Revision:
0:f6b418db17d2
pH-V12 version 1

Who changed what in which revision?

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