Joystick enabled version of USBHID -library. Has full Playstation 3 functionality including button pressures and a working home-button implementation, while maintaining full PC/MAC/linux -compatibility. basic operation of the lib: #include "mbed.h" #include "usbhid.h" USBJoystick joystick; int main() { while(1) { char dpad = 0xf; /*only the rightmost 4 bits matter*/ short button = 0xff; /*only the rightmost 13 bits matter*/ /*buttons are square, cross, circle, triangle, l1, r1, l2, r2, l3, r3, home.*/ char stick1x = 0; char stick1y = 0; char stick2x = 0; char stick2y = 0; joystick.joystick(dpad, buttons, stick1x, stick1y, stick2x, stick2y); wait_ms(5); } }

Committer:
innocopter
Date:
Fri May 11 13:35:59 2012 +0000
Revision:
0:237d5ef643e9

        

Who changed what in which revision?

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