mX mbed BaseBoard USB HID

Dependencies:   mbed

Committer:
ashwin_athani
Date:
Wed Dec 08 06:30:25 2010 +0000
Revision:
0:093612081f64

        

Who changed what in which revision?

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