kekw

Dependencies:   mbed C12832_lcd MMA7660

Committer:
gri
Date:
Sun Jan 19 14:57:41 2020 +0000
Revision:
2:b07d155d316c
KEKw

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gri 2:b07d155d316c 1 /* usbdc.cpp */
gri 2:b07d155d316c 2 /* USB device controller */
gri 2:b07d155d316c 3 /* Copyright (c) Phil Wright 2008 */
gri 2:b07d155d316c 4
gri 2:b07d155d316c 5 #include "mbed.h"
gri 2:b07d155d316c 6 #include "usbdc.h"
gri 2:b07d155d316c 7 #include "cmsis.h"
gri 2:b07d155d316c 8
gri 2:b07d155d316c 9 #ifdef TARGET_LPC2368
gri 2:b07d155d316c 10 #undef LPC_USB_BASE
gri 2:b07d155d316c 11 #define LPC_USB_BASE (0xFFE0C000) /* TODO */
gri 2:b07d155d316c 12 #endif
gri 2:b07d155d316c 13
gri 2:b07d155d316c 14 /* Power Control for Peripherals register */
gri 2:b07d155d316c 15 #define PCUSB ((unsigned long)1<<31)
gri 2:b07d155d316c 16
gri 2:b07d155d316c 17 /* USB Clock Control register */
gri 2:b07d155d316c 18 #define DEV_CLK_EN ((unsigned long)1<<1)
gri 2:b07d155d316c 19 #define AHB_CLK_EN ((unsigned long)1<<4)
gri 2:b07d155d316c 20
gri 2:b07d155d316c 21 /* USB Clock Status register */
gri 2:b07d155d316c 22 #define DEV_CLK_ON ((unsigned long)1<<1)
gri 2:b07d155d316c 23 #define AHB_CLK_ON ((unsigned long)1<<4)
gri 2:b07d155d316c 24
gri 2:b07d155d316c 25 /* USB Device Interupt registers */
gri 2:b07d155d316c 26 #define FRAME ((unsigned long)1<<0)
gri 2:b07d155d316c 27 #define EP_FAST ((unsigned long)1<<1)
gri 2:b07d155d316c 28 #define EP_SLOW ((unsigned long)1<<2)
gri 2:b07d155d316c 29 #define DEV_STAT ((unsigned long)1<<3)
gri 2:b07d155d316c 30 #define CCEMPTY ((unsigned long)1<<4)
gri 2:b07d155d316c 31 #define CDFULL ((unsigned long)1<<5)
gri 2:b07d155d316c 32 #define RxENDPKT ((unsigned long)1<<6)
gri 2:b07d155d316c 33 #define TxENDPKT ((unsigned long)1<<7)
gri 2:b07d155d316c 34 #define EP_RLZED ((unsigned long)1<<8)
gri 2:b07d155d316c 35 #define ERR_INT ((unsigned long)1<<9)
gri 2:b07d155d316c 36
gri 2:b07d155d316c 37 /* Endpoint Interrupt Registers */
gri 2:b07d155d316c 38 #define EP(endpoint) (1<<endpoint)
gri 2:b07d155d316c 39
gri 2:b07d155d316c 40 /* USB Control register */
gri 2:b07d155d316c 41 #define RD_EN (1<<0)
gri 2:b07d155d316c 42 #define WR_EN (1<<1)
gri 2:b07d155d316c 43 #define LOG_ENDPOINT(endpoint) ((endpoint>>1)<<2)
gri 2:b07d155d316c 44
gri 2:b07d155d316c 45 /* USB Receive Packet Length register */
gri 2:b07d155d316c 46 #define DV ((unsigned long)1<<10)
gri 2:b07d155d316c 47 #define PKT_RDY ((unsigned long)1<<11)
gri 2:b07d155d316c 48 #define PKT_LNGTH_MASK (0x3ff)
gri 2:b07d155d316c 49
gri 2:b07d155d316c 50 /* Serial Interface Engine (SIE) */
gri 2:b07d155d316c 51 #define SIE_WRITE (0x01)
gri 2:b07d155d316c 52 #define SIE_READ (0x02)
gri 2:b07d155d316c 53 #define SIE_COMMAND (0x05)
gri 2:b07d155d316c 54 #define SIE_CMD_CODE(phase, data) ((phase<<8)|(data<<16))
gri 2:b07d155d316c 55
gri 2:b07d155d316c 56 /* SIE Command codes */
gri 2:b07d155d316c 57 #define SIE_CMD_SET_ADDRESS (0xD0)
gri 2:b07d155d316c 58 #define SIE_CMD_CONFIGURE_DEVICE (0xD8)
gri 2:b07d155d316c 59 #define SIE_CMD_SET_MODE (0xF3)
gri 2:b07d155d316c 60 #define SIE_CMD_READ_FRAME_NUMBER (0xF5)
gri 2:b07d155d316c 61 #define SIE_CMD_READ_TEST_REGISTER (0xFD)
gri 2:b07d155d316c 62 #define SIE_CMD_SET_DEVICE_STATUS (0xFE)
gri 2:b07d155d316c 63 #define SIE_CMD_GET_DEVICE_STATUS (0xFE)
gri 2:b07d155d316c 64 #define SIE_CMD_GET_ERROR_CODE (0xFF)
gri 2:b07d155d316c 65 #define SIE_CMD_READ_ERROR_STATUS (0xFB)
gri 2:b07d155d316c 66
gri 2:b07d155d316c 67 #define SIE_CMD_SELECT_ENDPOINT(endpoint) (0x00+endpoint)
gri 2:b07d155d316c 68 #define SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint) (0x40+endpoint)
gri 2:b07d155d316c 69 #define SIE_CMD_SET_ENDPOINT_STATUS(endpoint) (0x40+endpoint)
gri 2:b07d155d316c 70
gri 2:b07d155d316c 71 #define SIE_CMD_CLEAR_BUFFER (0xF2)
gri 2:b07d155d316c 72 #define SIE_CMD_VALIDATE_BUFFER (0xFA)
gri 2:b07d155d316c 73
gri 2:b07d155d316c 74 /* SIE Device Status register */
gri 2:b07d155d316c 75 #define SIE_DS_CON (1<<0)
gri 2:b07d155d316c 76 #define SIE_DS_CON_CH (1<<1)
gri 2:b07d155d316c 77 #define SIE_DS_SUS (1<<2)
gri 2:b07d155d316c 78 #define SIE_DS_SUS_CH (1<<3)
gri 2:b07d155d316c 79 #define SIE_DS_RST (1<<4)
gri 2:b07d155d316c 80
gri 2:b07d155d316c 81 /* SIE Device Set Address register */
gri 2:b07d155d316c 82 #define SIE_DSA_DEV_EN (1<<7)
gri 2:b07d155d316c 83
gri 2:b07d155d316c 84 /* SIE Configue Device register */
gri 2:b07d155d316c 85 #define SIE_CONF_DEVICE (1<<0)
gri 2:b07d155d316c 86
gri 2:b07d155d316c 87 /* Select Endpoint register */
gri 2:b07d155d316c 88 #define SIE_SE_FE (1<<0)
gri 2:b07d155d316c 89 #define SIE_SE_ST (1<<1)
gri 2:b07d155d316c 90 #define SIE_SE_STP (1<<2)
gri 2:b07d155d316c 91 #define SIE_SE_PO (1<<3)
gri 2:b07d155d316c 92 #define SIE_SE_EPN (1<<4)
gri 2:b07d155d316c 93 #define SIE_SE_B_1_FULL (1<<5)
gri 2:b07d155d316c 94 #define SIE_SE_B_2_FULL (1<<6)
gri 2:b07d155d316c 95
gri 2:b07d155d316c 96 /* Set Endpoint Status command */
gri 2:b07d155d316c 97 #define SIE_SES_ST (1<<0)
gri 2:b07d155d316c 98 #define SIE_SES_DA (1<<5)
gri 2:b07d155d316c 99 #define SIE_SES_RF_MO (1<<6)
gri 2:b07d155d316c 100 #define SIE_SES_CND_ST (1<<7)
gri 2:b07d155d316c 101
gri 2:b07d155d316c 102 usbdc *usbdc::instance;
gri 2:b07d155d316c 103
gri 2:b07d155d316c 104 usbdc::usbdc()
gri 2:b07d155d316c 105 {
gri 2:b07d155d316c 106 #ifdef TARGET_LPC1768
gri 2:b07d155d316c 107 LPC_SC->USBCLKCFG=5; /* TODO */
gri 2:b07d155d316c 108 #endif
gri 2:b07d155d316c 109
gri 2:b07d155d316c 110 /* Enable power to USB device controller */
gri 2:b07d155d316c 111 LPC_SC->PCONP |= PCUSB;
gri 2:b07d155d316c 112
gri 2:b07d155d316c 113 /* Enable USB clocks */
gri 2:b07d155d316c 114 LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
gri 2:b07d155d316c 115 while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON));
gri 2:b07d155d316c 116
gri 2:b07d155d316c 117 /* Configure pins P0.29 and P0.30 to be USB D+ and USB D- */
gri 2:b07d155d316c 118 LPC_PINCON->PINSEL1 &= 0xc3ffffff;
gri 2:b07d155d316c 119 LPC_PINCON->PINSEL1 |= 0x14000000;
gri 2:b07d155d316c 120
gri 2:b07d155d316c 121 #ifdef ENABLE_VBUS
gri 2:b07d155d316c 122 /* Configure pin P1.30 to be VBUS */
gri 2:b07d155d316c 123 LPC_PINCON->PINSEL3 &= 0xcfffffff;
gri 2:b07d155d316c 124 LPC_PINCON->PINSEL3 |= 0x20000000;
gri 2:b07d155d316c 125
gri 2:b07d155d316c 126 /* Configure pin P1.30 to have pull-down */
gri 2:b07d155d316c 127 LPC_PINCON->PINMODE3 |= 0x30000000;
gri 2:b07d155d316c 128 #endif
gri 2:b07d155d316c 129
gri 2:b07d155d316c 130 /* Configure pin P2.9 to be Connect */
gri 2:b07d155d316c 131 LPC_PINCON->PINSEL4 &= 0xfffcffff;
gri 2:b07d155d316c 132 LPC_PINCON->PINSEL4 |= 0x00040000;
gri 2:b07d155d316c 133
gri 2:b07d155d316c 134 /* Connect must be low for at least 2.5uS */
gri 2:b07d155d316c 135 wait_ms(1);
gri 2:b07d155d316c 136
gri 2:b07d155d316c 137 /* Attach IRQ */
gri 2:b07d155d316c 138 instance = this;
gri 2:b07d155d316c 139 NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr);
gri 2:b07d155d316c 140 NVIC_EnableIRQ(USB_IRQn);
gri 2:b07d155d316c 141
gri 2:b07d155d316c 142 /* Enable device interrupts */
gri 2:b07d155d316c 143 enableEvents();
gri 2:b07d155d316c 144 }
gri 2:b07d155d316c 145
gri 2:b07d155d316c 146 void usbdc::connect(void)
gri 2:b07d155d316c 147 {
gri 2:b07d155d316c 148 /* Connect USB device */
gri 2:b07d155d316c 149 unsigned char status;
gri 2:b07d155d316c 150
gri 2:b07d155d316c 151 status = getDeviceStatus();
gri 2:b07d155d316c 152 setDeviceStatus(status | SIE_DS_CON);
gri 2:b07d155d316c 153 }
gri 2:b07d155d316c 154
gri 2:b07d155d316c 155 void usbdc::disconnect(void)
gri 2:b07d155d316c 156 {
gri 2:b07d155d316c 157 /* Disconnect USB device */
gri 2:b07d155d316c 158 unsigned char status;
gri 2:b07d155d316c 159
gri 2:b07d155d316c 160 status = getDeviceStatus();
gri 2:b07d155d316c 161 setDeviceStatus(status & ~SIE_DS_CON);
gri 2:b07d155d316c 162 }
gri 2:b07d155d316c 163
gri 2:b07d155d316c 164 void usbdc::SIECommand(unsigned long command)
gri 2:b07d155d316c 165 {
gri 2:b07d155d316c 166 /* The command phase of a SIE transaction */
gri 2:b07d155d316c 167 LPC_USB->USBDevIntClr = CCEMPTY;
gri 2:b07d155d316c 168 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_COMMAND, command);
gri 2:b07d155d316c 169 while (!(LPC_USB->USBDevIntSt & CCEMPTY));
gri 2:b07d155d316c 170 }
gri 2:b07d155d316c 171
gri 2:b07d155d316c 172 void usbdc::SIEWriteData(unsigned char data)
gri 2:b07d155d316c 173 {
gri 2:b07d155d316c 174 /* The data write phase of a SIE transaction */
gri 2:b07d155d316c 175 LPC_USB->USBDevIntClr = CCEMPTY;
gri 2:b07d155d316c 176 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_WRITE, data);
gri 2:b07d155d316c 177 while (!(LPC_USB->USBDevIntSt & CCEMPTY));
gri 2:b07d155d316c 178 }
gri 2:b07d155d316c 179
gri 2:b07d155d316c 180 unsigned char usbdc::SIEReadData(unsigned long command)
gri 2:b07d155d316c 181 {
gri 2:b07d155d316c 182 /* The data read phase of a SIE transaction */
gri 2:b07d155d316c 183 LPC_USB->USBDevIntClr = CDFULL;
gri 2:b07d155d316c 184 LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_READ, command);
gri 2:b07d155d316c 185 while (!(LPC_USB->USBDevIntSt & CDFULL));
gri 2:b07d155d316c 186 return (unsigned char)LPC_USB->USBCmdData;
gri 2:b07d155d316c 187 }
gri 2:b07d155d316c 188
gri 2:b07d155d316c 189 void usbdc::setDeviceStatus(unsigned char status)
gri 2:b07d155d316c 190 {
gri 2:b07d155d316c 191 /* Write SIE device status register */
gri 2:b07d155d316c 192 SIECommand(SIE_CMD_SET_DEVICE_STATUS);
gri 2:b07d155d316c 193 SIEWriteData(status);
gri 2:b07d155d316c 194 }
gri 2:b07d155d316c 195
gri 2:b07d155d316c 196 unsigned char usbdc::getDeviceStatus(void)
gri 2:b07d155d316c 197 {
gri 2:b07d155d316c 198 /* Read SIE device status register */
gri 2:b07d155d316c 199 SIECommand(SIE_CMD_GET_DEVICE_STATUS);
gri 2:b07d155d316c 200 return SIEReadData(SIE_CMD_GET_DEVICE_STATUS);
gri 2:b07d155d316c 201 }
gri 2:b07d155d316c 202
gri 2:b07d155d316c 203 void usbdc::setAddress(unsigned char address)
gri 2:b07d155d316c 204 {
gri 2:b07d155d316c 205 /* Write SIE device address register */
gri 2:b07d155d316c 206 SIECommand(SIE_CMD_SET_ADDRESS);
gri 2:b07d155d316c 207 SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN);
gri 2:b07d155d316c 208 }
gri 2:b07d155d316c 209
gri 2:b07d155d316c 210 unsigned char usbdc::selectEndpoint(unsigned char endpoint)
gri 2:b07d155d316c 211 {
gri 2:b07d155d316c 212 /* SIE select endpoint command */
gri 2:b07d155d316c 213 SIECommand(SIE_CMD_SELECT_ENDPOINT(endpoint));
gri 2:b07d155d316c 214 return SIEReadData(SIE_CMD_SELECT_ENDPOINT(endpoint));
gri 2:b07d155d316c 215 }
gri 2:b07d155d316c 216
gri 2:b07d155d316c 217 #if 1
gri 2:b07d155d316c 218 unsigned char usbdc::selectEndpointClearInterrupt(unsigned char endpoint)
gri 2:b07d155d316c 219 {
gri 2:b07d155d316c 220 /* SIE select endpoint and clear interrupt command */
gri 2:b07d155d316c 221 /* Using the Select Endpoint / Clear Interrupt SIE command does not seem */
gri 2:b07d155d316c 222 /* to clear the appropriate bit in EP_INT_STAT? - using EP_INT_CLR instead */
gri 2:b07d155d316c 223 LPC_USB->USBEpIntClr = EP(endpoint);
gri 2:b07d155d316c 224 while (!(LPC_USB->USBDevIntSt & CDFULL));
gri 2:b07d155d316c 225 return (unsigned char)LPC_USB->USBCmdData;
gri 2:b07d155d316c 226 }
gri 2:b07d155d316c 227 #else
gri 2:b07d155d316c 228 unsigned char usbdc::selectEndpointClearInterrupt(unsigned char endpoint)
gri 2:b07d155d316c 229 {
gri 2:b07d155d316c 230 /* SIE select endpoint and clear interrupt command */
gri 2:b07d155d316c 231 SIECommand(SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint));
gri 2:b07d155d316c 232 return SIEReadData(SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint));
gri 2:b07d155d316c 233 }
gri 2:b07d155d316c 234 #endif
gri 2:b07d155d316c 235
gri 2:b07d155d316c 236 unsigned char usbdc::clearBuffer(void)
gri 2:b07d155d316c 237 {
gri 2:b07d155d316c 238 /* SIE clear buffer command */
gri 2:b07d155d316c 239 SIECommand(SIE_CMD_CLEAR_BUFFER);
gri 2:b07d155d316c 240 return SIEReadData(SIE_CMD_CLEAR_BUFFER);
gri 2:b07d155d316c 241 }
gri 2:b07d155d316c 242
gri 2:b07d155d316c 243 void usbdc::validateBuffer(void)
gri 2:b07d155d316c 244 {
gri 2:b07d155d316c 245 /* SIE validate buffer command */
gri 2:b07d155d316c 246 SIECommand(SIE_CMD_VALIDATE_BUFFER);
gri 2:b07d155d316c 247 }
gri 2:b07d155d316c 248
gri 2:b07d155d316c 249 void usbdc::setEndpointStatus(unsigned char endpoint, unsigned char status)
gri 2:b07d155d316c 250 {
gri 2:b07d155d316c 251 /* SIE set endpoint status command */
gri 2:b07d155d316c 252 SIECommand(SIE_CMD_SET_ENDPOINT_STATUS(endpoint));
gri 2:b07d155d316c 253 SIEWriteData(status);
gri 2:b07d155d316c 254 }
gri 2:b07d155d316c 255
gri 2:b07d155d316c 256 void usbdc::realiseEndpoint(unsigned char endpoint, unsigned long maxPacket)
gri 2:b07d155d316c 257 {
gri 2:b07d155d316c 258 /* Realise an endpoint */
gri 2:b07d155d316c 259 LPC_USB->USBDevIntClr = EP_RLZED;
gri 2:b07d155d316c 260 LPC_USB->USBReEp |= EP(endpoint);
gri 2:b07d155d316c 261 LPC_USB->USBEpInd = endpoint;
gri 2:b07d155d316c 262 LPC_USB->USBMaxPSize = maxPacket;
gri 2:b07d155d316c 263
gri 2:b07d155d316c 264 while (!(LPC_USB->USBDevIntSt & EP_RLZED));
gri 2:b07d155d316c 265 LPC_USB->USBDevIntClr = EP_RLZED;
gri 2:b07d155d316c 266
gri 2:b07d155d316c 267 /* Clear stall state */
gri 2:b07d155d316c 268 endpointStallState &= ~EP(endpoint);
gri 2:b07d155d316c 269 }
gri 2:b07d155d316c 270
gri 2:b07d155d316c 271 void usbdc::enableEndpointEvent(unsigned char endpoint)
gri 2:b07d155d316c 272 {
gri 2:b07d155d316c 273 /* Enable an endpoint interrupt */
gri 2:b07d155d316c 274 LPC_USB->USBEpIntEn |= EP(endpoint);
gri 2:b07d155d316c 275 }
gri 2:b07d155d316c 276
gri 2:b07d155d316c 277 void usbdc::disableEndpointEvent(unsigned char endpoint)
gri 2:b07d155d316c 278 {
gri 2:b07d155d316c 279 /* Disable an endpoint interrupt */
gri 2:b07d155d316c 280 LPC_USB->USBEpIntEn &= ~EP(endpoint);
gri 2:b07d155d316c 281 }
gri 2:b07d155d316c 282
gri 2:b07d155d316c 283 void usbdc::stallEndpoint(unsigned char endpoint)
gri 2:b07d155d316c 284 {
gri 2:b07d155d316c 285 /* Stall an endpoint */
gri 2:b07d155d316c 286 if ( (endpoint==EP0IN) || (endpoint==EP0OUT) )
gri 2:b07d155d316c 287 {
gri 2:b07d155d316c 288 /* Conditionally stall both control endpoints */
gri 2:b07d155d316c 289 setEndpointStatus(EP0OUT, SIE_SES_CND_ST);
gri 2:b07d155d316c 290 }
gri 2:b07d155d316c 291 else
gri 2:b07d155d316c 292 {
gri 2:b07d155d316c 293 setEndpointStatus(endpoint, SIE_SES_ST);
gri 2:b07d155d316c 294
gri 2:b07d155d316c 295 /* Update stall state */
gri 2:b07d155d316c 296 endpointStallState |= EP(endpoint);
gri 2:b07d155d316c 297 }
gri 2:b07d155d316c 298 }
gri 2:b07d155d316c 299
gri 2:b07d155d316c 300 void usbdc::unstallEndpoint(unsigned char endpoint)
gri 2:b07d155d316c 301 {
gri 2:b07d155d316c 302 /* Unstall an endpoint. The endpoint will also be reinitialised */
gri 2:b07d155d316c 303 setEndpointStatus(endpoint, 0);
gri 2:b07d155d316c 304
gri 2:b07d155d316c 305 /* Update stall state */
gri 2:b07d155d316c 306 endpointStallState &= ~EP(endpoint);
gri 2:b07d155d316c 307 }
gri 2:b07d155d316c 308
gri 2:b07d155d316c 309 bool usbdc::getEndpointStallState(unsigned char endpoint)
gri 2:b07d155d316c 310 {
gri 2:b07d155d316c 311 /* Returns true if endpoint stalled */
gri 2:b07d155d316c 312 return endpointStallState & EP(endpoint);
gri 2:b07d155d316c 313 }
gri 2:b07d155d316c 314
gri 2:b07d155d316c 315 void usbdc::configureDevice(void)
gri 2:b07d155d316c 316 {
gri 2:b07d155d316c 317 /* SIE Configure device command */
gri 2:b07d155d316c 318 SIECommand(SIE_CMD_CONFIGURE_DEVICE);
gri 2:b07d155d316c 319 SIEWriteData(SIE_CONF_DEVICE);
gri 2:b07d155d316c 320 }
gri 2:b07d155d316c 321
gri 2:b07d155d316c 322 void usbdc::unconfigureDevice(void)
gri 2:b07d155d316c 323 {
gri 2:b07d155d316c 324 /* SIE Configure device command */
gri 2:b07d155d316c 325 SIECommand(SIE_CMD_CONFIGURE_DEVICE);
gri 2:b07d155d316c 326 SIEWriteData(0);
gri 2:b07d155d316c 327 }
gri 2:b07d155d316c 328
gri 2:b07d155d316c 329 unsigned long usbdc::endpointRead(unsigned char endpoint, unsigned char *buffer)
gri 2:b07d155d316c 330 {
gri 2:b07d155d316c 331 /* Read from an OUT endpoint */
gri 2:b07d155d316c 332 unsigned long size;
gri 2:b07d155d316c 333 unsigned long i;
gri 2:b07d155d316c 334 unsigned long data;
gri 2:b07d155d316c 335 unsigned char offset;
gri 2:b07d155d316c 336
gri 2:b07d155d316c 337 LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | RD_EN;
gri 2:b07d155d316c 338 while (!(LPC_USB->USBRxPLen & PKT_RDY));
gri 2:b07d155d316c 339
gri 2:b07d155d316c 340 size = LPC_USB->USBRxPLen & PKT_LNGTH_MASK;
gri 2:b07d155d316c 341
gri 2:b07d155d316c 342 offset = 0;
gri 2:b07d155d316c 343
gri 2:b07d155d316c 344 for (i=0; i<size; i++)
gri 2:b07d155d316c 345 {
gri 2:b07d155d316c 346 if (offset==0)
gri 2:b07d155d316c 347 {
gri 2:b07d155d316c 348 /* Fetch up to four bytes of data as a word */
gri 2:b07d155d316c 349 data = LPC_USB->USBRxData;
gri 2:b07d155d316c 350 }
gri 2:b07d155d316c 351
gri 2:b07d155d316c 352 /* extract a byte */
gri 2:b07d155d316c 353 *buffer++ = data>>offset;
gri 2:b07d155d316c 354
gri 2:b07d155d316c 355 /* move on to the next byte */
gri 2:b07d155d316c 356 offset = (offset + 8) % 32;
gri 2:b07d155d316c 357 }
gri 2:b07d155d316c 358
gri 2:b07d155d316c 359 /* Clear RD_EN to cover zero length packet case */
gri 2:b07d155d316c 360 LPC_USB->USBCtrl=0;
gri 2:b07d155d316c 361
gri 2:b07d155d316c 362 selectEndpoint(endpoint);
gri 2:b07d155d316c 363 clearBuffer();
gri 2:b07d155d316c 364
gri 2:b07d155d316c 365 return size;
gri 2:b07d155d316c 366 }
gri 2:b07d155d316c 367
gri 2:b07d155d316c 368 void usbdc::endpointWrite(unsigned char endpoint, unsigned char *buffer, unsigned long size)
gri 2:b07d155d316c 369 {
gri 2:b07d155d316c 370 /* Write to an IN endpoint */
gri 2:b07d155d316c 371 unsigned long temp, data;
gri 2:b07d155d316c 372 unsigned char offset;
gri 2:b07d155d316c 373
gri 2:b07d155d316c 374 LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | WR_EN;
gri 2:b07d155d316c 375
gri 2:b07d155d316c 376 LPC_USB->USBTxPLen = size;
gri 2:b07d155d316c 377 offset = 0;
gri 2:b07d155d316c 378 data = 0;
gri 2:b07d155d316c 379
gri 2:b07d155d316c 380 if (size>0)
gri 2:b07d155d316c 381 {
gri 2:b07d155d316c 382 do {
gri 2:b07d155d316c 383 /* Fetch next data byte into a word-sized temporary variable */
gri 2:b07d155d316c 384 temp = *buffer++;
gri 2:b07d155d316c 385
gri 2:b07d155d316c 386 /* Add to current data word */
gri 2:b07d155d316c 387 temp = temp << offset;
gri 2:b07d155d316c 388 data = data | temp;
gri 2:b07d155d316c 389
gri 2:b07d155d316c 390 /* move on to the next byte */
gri 2:b07d155d316c 391 offset = (offset + 8) % 32;
gri 2:b07d155d316c 392 size--;
gri 2:b07d155d316c 393
gri 2:b07d155d316c 394 if ((offset==0) || (size==0))
gri 2:b07d155d316c 395 {
gri 2:b07d155d316c 396 /* Write the word to the endpoint */
gri 2:b07d155d316c 397 LPC_USB->USBTxData = data;
gri 2:b07d155d316c 398 data = 0;
gri 2:b07d155d316c 399 }
gri 2:b07d155d316c 400 } while (size>0);
gri 2:b07d155d316c 401 }
gri 2:b07d155d316c 402
gri 2:b07d155d316c 403 /* Clear WR_EN to cover zero length packet case */
gri 2:b07d155d316c 404 LPC_USB->USBCtrl=0;
gri 2:b07d155d316c 405
gri 2:b07d155d316c 406 selectEndpoint(endpoint);
gri 2:b07d155d316c 407 validateBuffer();
gri 2:b07d155d316c 408 }
gri 2:b07d155d316c 409
gri 2:b07d155d316c 410 void usbdc::enableEvents(void)
gri 2:b07d155d316c 411 {
gri 2:b07d155d316c 412 /* Enable interrupt sources */
gri 2:b07d155d316c 413 LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT;
gri 2:b07d155d316c 414 }
gri 2:b07d155d316c 415
gri 2:b07d155d316c 416 void usbdc::disableEvents(void)
gri 2:b07d155d316c 417 {
gri 2:b07d155d316c 418 /* Disable interrupt sources */
gri 2:b07d155d316c 419 LPC_USB->USBDevIntClr = EP_SLOW | DEV_STAT;
gri 2:b07d155d316c 420 }
gri 2:b07d155d316c 421
gri 2:b07d155d316c 422 void usbdc::usbisr(void)
gri 2:b07d155d316c 423 {
gri 2:b07d155d316c 424 unsigned char devStat;
gri 2:b07d155d316c 425
gri 2:b07d155d316c 426 if (LPC_USB->USBDevIntSt & FRAME)
gri 2:b07d155d316c 427 {
gri 2:b07d155d316c 428 /* Frame event */
gri 2:b07d155d316c 429 deviceEventFrame();
gri 2:b07d155d316c 430 /* Clear interrupt status flag */
gri 2:b07d155d316c 431 LPC_USB->USBDevIntClr = FRAME;
gri 2:b07d155d316c 432 }
gri 2:b07d155d316c 433
gri 2:b07d155d316c 434 if (LPC_USB->USBDevIntSt & DEV_STAT)
gri 2:b07d155d316c 435 {
gri 2:b07d155d316c 436 /* Device Status interrupt */
gri 2:b07d155d316c 437 /* Must clear the interrupt status flag before reading the device status from the SIE */
gri 2:b07d155d316c 438 LPC_USB->USBDevIntClr = DEV_STAT;
gri 2:b07d155d316c 439
gri 2:b07d155d316c 440 /* Read device status from SIE */
gri 2:b07d155d316c 441 devStat = getDeviceStatus();
gri 2:b07d155d316c 442
gri 2:b07d155d316c 443 if (devStat & SIE_DS_RST)
gri 2:b07d155d316c 444 {
gri 2:b07d155d316c 445 /* Bus reset */
gri 2:b07d155d316c 446 deviceEventReset();
gri 2:b07d155d316c 447 }
gri 2:b07d155d316c 448 }
gri 2:b07d155d316c 449
gri 2:b07d155d316c 450 if (LPC_USB->USBDevIntSt & EP_SLOW)
gri 2:b07d155d316c 451 {
gri 2:b07d155d316c 452 /* (Slow) Endpoint Interrupt */
gri 2:b07d155d316c 453
gri 2:b07d155d316c 454 /* Process each endpoint interrupt */
gri 2:b07d155d316c 455 if (LPC_USB->USBEpIntSt & EP(EP0OUT))
gri 2:b07d155d316c 456 {
gri 2:b07d155d316c 457 if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP)
gri 2:b07d155d316c 458 {
gri 2:b07d155d316c 459 /* this is a setup packet */
gri 2:b07d155d316c 460 endpointEventEP0Setup();
gri 2:b07d155d316c 461 }
gri 2:b07d155d316c 462 else
gri 2:b07d155d316c 463 {
gri 2:b07d155d316c 464 endpointEventEP0Out();
gri 2:b07d155d316c 465 }
gri 2:b07d155d316c 466 }
gri 2:b07d155d316c 467
gri 2:b07d155d316c 468 if (LPC_USB->USBEpIntSt & EP(EP0IN))
gri 2:b07d155d316c 469 {
gri 2:b07d155d316c 470 selectEndpointClearInterrupt(EP0IN);
gri 2:b07d155d316c 471 endpointEventEP0In();
gri 2:b07d155d316c 472 }
gri 2:b07d155d316c 473
gri 2:b07d155d316c 474 if (LPC_USB->USBEpIntSt & EP(EP1OUT))
gri 2:b07d155d316c 475 {
gri 2:b07d155d316c 476 selectEndpointClearInterrupt(EP1OUT);
gri 2:b07d155d316c 477 endpointEventEP1Out();
gri 2:b07d155d316c 478 }
gri 2:b07d155d316c 479
gri 2:b07d155d316c 480 if (LPC_USB->USBEpIntSt & EP(EP1IN))
gri 2:b07d155d316c 481 {
gri 2:b07d155d316c 482 selectEndpointClearInterrupt(EP1IN);
gri 2:b07d155d316c 483 endpointEventEP1In();
gri 2:b07d155d316c 484 }
gri 2:b07d155d316c 485
gri 2:b07d155d316c 486 if (LPC_USB->USBEpIntSt & EP(EP2OUT))
gri 2:b07d155d316c 487 {
gri 2:b07d155d316c 488 selectEndpointClearInterrupt(EP2OUT);
gri 2:b07d155d316c 489 endpointEventEP2Out();
gri 2:b07d155d316c 490 }
gri 2:b07d155d316c 491
gri 2:b07d155d316c 492 if (LPC_USB->USBEpIntSt & EP(EP2IN))
gri 2:b07d155d316c 493 {
gri 2:b07d155d316c 494 selectEndpointClearInterrupt(EP2IN);
gri 2:b07d155d316c 495 endpointEventEP2In();
gri 2:b07d155d316c 496 }
gri 2:b07d155d316c 497
gri 2:b07d155d316c 498 /* Clear interrupt status flag */
gri 2:b07d155d316c 499 /* EP_SLOW and EP_FAST interrupt bits should be cleared after the corresponding endpoint interrupts are cleared. */
gri 2:b07d155d316c 500 LPC_USB->USBDevIntClr = EP_SLOW;
gri 2:b07d155d316c 501 }
gri 2:b07d155d316c 502 }
gri 2:b07d155d316c 503
gri 2:b07d155d316c 504
gri 2:b07d155d316c 505 void usbdc::_usbisr(void)
gri 2:b07d155d316c 506 {
gri 2:b07d155d316c 507 instance->usbisr();
gri 2:b07d155d316c 508 }
gri 2:b07d155d316c 509
gri 2:b07d155d316c 510 void usbdc::deviceEventReset(void)
gri 2:b07d155d316c 511 {
gri 2:b07d155d316c 512 }
gri 2:b07d155d316c 513
gri 2:b07d155d316c 514 void usbdc::deviceEventFrame(void)
gri 2:b07d155d316c 515 {
gri 2:b07d155d316c 516 }
gri 2:b07d155d316c 517
gri 2:b07d155d316c 518 void usbdc::endpointEventEP0Setup(void)
gri 2:b07d155d316c 519 {
gri 2:b07d155d316c 520 }
gri 2:b07d155d316c 521
gri 2:b07d155d316c 522 void usbdc::endpointEventEP0In(void)
gri 2:b07d155d316c 523 {
gri 2:b07d155d316c 524 }
gri 2:b07d155d316c 525
gri 2:b07d155d316c 526 void usbdc::endpointEventEP0Out(void)
gri 2:b07d155d316c 527 {
gri 2:b07d155d316c 528 }
gri 2:b07d155d316c 529
gri 2:b07d155d316c 530 void usbdc::endpointEventEP1In(void)
gri 2:b07d155d316c 531 {
gri 2:b07d155d316c 532 }
gri 2:b07d155d316c 533
gri 2:b07d155d316c 534 void usbdc::endpointEventEP1Out(void)
gri 2:b07d155d316c 535 {
gri 2:b07d155d316c 536 }
gri 2:b07d155d316c 537
gri 2:b07d155d316c 538 void usbdc::endpointEventEP2In(void)
gri 2:b07d155d316c 539 {
gri 2:b07d155d316c 540 }
gri 2:b07d155d316c 541
gri 2:b07d155d316c 542 void usbdc::endpointEventEP2Out(void)
gri 2:b07d155d316c 543 {
gri 2:b07d155d316c 544 }