Based on USBKeyboardMouse example. I added USB String Descriptor so mbed reports itself to host not only with VID & PID but also with name of manufacturer, product name, serial number, configuration number and interface name. These can be changed to matching Yours in USBhid.cpp file on lines 88 - 122.

Dependencies:   mbed

Committer:
llumpu
Date:
Thu Sep 08 15:01:33 2011 +0000
Revision:
0:f97b1f255167
Added USB String Descriptor

Who changed what in which revision?

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