USB Keyboard and mouse Example. Based on USBMouse

Dependencies:   mbed

Fork of USBKeyboardMouse by Zack Clobes

Committer:
Wabouz
Date:
Wed May 08 09:33:27 2013 +0000
Revision:
1:9c83250ce43b
Parent:
0:86603687efec
Un petit programme.

Who changed what in which revision?

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