Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:f97b1f255167, committed 2011-09-08
- Comitter:
- llumpu
- Date:
- Thu Sep 08 15:01:33 2011 +0000
- Commit message:
- Added USB String Descriptor
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBKeyboardMouse/USBKeyboard.cpp Thu Sep 08 15:01:33 2011 +0000
@@ -0,0 +1,13 @@
+#include "USBKeyboard.h"
+
+USBKeyboard::USBKeyboard() {
+// _buttons = 0;
+}
+
+void USBKeyboard::sendKeys(char *szString) {
+ keyboard(szString);
+}
+
+void USBKeyboard::sendKey(char c) {
+ keyboard(c);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBKeyboardMouse/USBKeyboard.h Thu Sep 08 15:01:33 2011 +0000
@@ -0,0 +1,37 @@
+#include "usbhid.h"
+
+#ifndef MBED_USBKEYBOARD_H
+#define MBED_USBKEYBOARD_H
+
+/* Class: USBKeyboard
+ * Emulate a USB Keyboard HID device
+ *
+ * Example:
+ * > #include "mbed.h"
+ * > #include "USBKeyboard.h"
+ * >
+ * > USBKeyboard kb;
+ * >
+ * > int main() {
+ * > while(1) {
+ * > kb.sendKeys("Foo goes here!");
+ * > wait(2);
+ * > }
+ * > }
+ */
+class USBKeyboard : private usbhid {
+public:
+ /* Constructor: USBKeyboard
+ * Create a USB Keyboard using the mbed USB Device interface
+ */
+ USBKeyboard();
+
+ void sendKeys(char *szString);
+ void sendKey(char c);
+
+
+private:
+
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBKeyboardMouse/USBMouse.cpp Thu Sep 08 15:01:33 2011 +0000
@@ -0,0 +1,51 @@
+#include "USBMouse.h"
+
+USBMouse::USBMouse() {
+ _buttons = 0;
+}
+
+void USBMouse::move(int x, int y) {
+ while(x > 127) {
+ mouse(127, 0, _buttons, 0);
+ x = x - 127;
+ }
+ while(x < -128) {
+ mouse(-128, 0, _buttons, 0);
+ x = x + 128;
+ }
+ while(y > 127) {
+ mouse(0, 127, _buttons, 0);
+ y = y - 127;
+ }
+ while(y < -128) {
+ mouse(0, -128, _buttons, 0);
+ y = y + 128;
+ }
+ mouse(x, y, _buttons, 0);
+}
+
+void USBMouse::scroll(int z) {
+ while(z > 127) {
+ mouse(0, 0, _buttons, 127);
+ z = z - 127;
+ }
+ while(z < -128) {
+ mouse(0, 0, _buttons, -128);
+ z = z + 128;
+ }
+ mouse(0, 0, _buttons, z);
+}
+
+void USBMouse::buttons(int left, int middle, int right) {
+ int _buttons = 0;
+ if(left) {
+ _buttons |= MOUSE_L;
+ }
+ if(middle) {
+ _buttons |= MOUSE_M;
+ }
+ if(right) {
+ _buttons |= MOUSE_R;
+ }
+ mouse(0,0, _buttons, 0);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBKeyboardMouse/USBMouse.h Thu Sep 08 15:01:33 2011 +0000
@@ -0,0 +1,60 @@
+#include "usbhid.h"
+
+#ifndef MBED_USBMOUSE_H
+#define MBED_USBMOUSE_H
+
+/* Class: USBMouse
+ * Emulate a USB Mouse HID device
+ *
+ * Example:
+ * > #include "mbed.h"
+ * > #include "USBMouse.h"
+ * >
+ * > USBMouse mouse;
+ * >
+ * > int main() {
+ * > while(1) {
+ * > mouse.move(10, 0);
+ * > wait(2);
+ * > }
+ * > }
+ */
+class USBMouse : private usbhid {
+public:
+ /* Constructor: USBMouse
+ * Create a USB Mouse using the mbed USB Device interface
+ */
+ USBMouse();
+
+ /* Function: move
+ * Move the mouse
+ *
+ * Variables:
+ * x - Distance to move in x-axis
+ * y - Distance to move in y-axis
+ */
+ void move(int x, int y);
+
+ /* Function: scroll
+ * Scroll the scroll wheel
+ *
+ * Variables:
+ * z - Distance to scroll scroll wheel
+ */
+ void scroll(int z);
+
+ /* Function: buttons
+ * Set the state of the buttons
+ *
+ * Variables:
+ * left - set the left button as down (1) or up (0)
+ * middle - set the middle button as down (1) or up (0)
+ * right - set the right button as down (1) or up (0)
+ */
+ void buttons(int left, int middle, int right);
+
+private:
+ int _buttons;
+};
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBKeyboardMouse/asciihid.h Thu Sep 08 15:01:33 2011 +0000
@@ -0,0 +1,289 @@
+/* asciihid.h */
+/* ASCII to HID Keyboard lookup table */
+/* Copyright (c) Phil Wright 2008 */
+
+#ifndef HIDTABLE_H
+#define HIDTABLE_H
+
+/* Default is UK keyboard layout */
+/* #define US_KEYBOARD */
+
+/* Modifiers */
+#define SHIFT (1<<1)
+
+typedef struct {
+ unsigned char usage;
+ unsigned char modifier;
+} KEYMAP;
+
+#ifdef US_KEYBOARD
+/* US keyboard (as HID standard) */
+#define KEYMAP_SIZE (128)
+const KEYMAP keymap[KEYMAP_SIZE] = {
+{0, 0}, /* NUL */
+{0, 0}, /* SOH */
+{0, 0}, /* STX */
+{0, 0}, /* ETX */
+{0, 0}, /* EOT */
+{0, 0}, /* ENQ */
+{0, 0}, /* ACK */
+{0, 0}, /* BEL */
+{0x2a, 0}, /* BS */ /* Keyboard Delete (Backspace) */
+{0x2b, 0}, /* TAB */ /* Keyboard Tab */
+{0x28, 0}, /* LF */ /* Keyboard Return (Enter) */
+{0, 0}, /* VT */
+{0, 0}, /* FF */
+{0, 0}, /* CR */
+{0, 0}, /* SO */
+{0, 0}, /* SI */
+{0, 0}, /* DEL */
+{0, 0}, /* DC1 */
+{0, 0}, /* DC2 */
+{0, 0}, /* DC3 */
+{0, 0}, /* DC4 */
+{0, 0}, /* NAK */
+{0, 0}, /* SYN */
+{0, 0}, /* ETB */
+{0, 0}, /* CAN */
+{0, 0}, /* EM */
+{0, 0}, /* SUB */
+{0, 0}, /* ESC */
+{0, 0}, /* FS */
+{0, 0}, /* GS */
+{0, 0}, /* RS */
+{0, 0}, /* US */
+{0x2c, 0}, /* */
+{0x1e, SHIFT}, /* ! */
+{0x34, SHIFT}, /* " */
+{0x20, SHIFT}, /* # */
+{0x21, SHIFT}, /* $ */
+{0x22, SHIFT}, /* % */
+{0x24, SHIFT}, /* & */
+{0x34, 0}, /* ' */
+{0x26, SHIFT}, /* ( */
+{0x27, SHIFT}, /* ) */
+{0x25, SHIFT}, /* * */
+{0x2e, SHIFT}, /* + */
+{0x36, 0}, /* , */
+{0x2d, 0}, /* - */
+{0x37, 0}, /* . */
+{0x38, 0}, /* / */
+{0x27, 0}, /* 0 */
+{0x1e, 0}, /* 1 */
+{0x1f, 0}, /* 2 */
+{0x20, 0}, /* 3 */
+{0x21, 0}, /* 4 */
+{0x22, 0}, /* 5 */
+{0x23, 0}, /* 6 */
+{0x24, 0}, /* 7 */
+{0x25, 0}, /* 8 */
+{0x26, 0}, /* 9 */
+{0x33, SHIFT}, /* : */
+{0x33, 0}, /* ; */
+{0x36, SHIFT}, /* < */
+{0x2e, 0}, /* = */
+{0x37, SHIFT}, /* > */
+{0x38, SHIFT}, /* ? */
+{0x1f, SHIFT}, /* @ */
+{0x04, SHIFT}, /* A */
+{0x05, SHIFT}, /* B */
+{0x06, SHIFT}, /* C */
+{0x07, SHIFT}, /* D */
+{0x08, SHIFT}, /* E */
+{0x09, SHIFT}, /* F */
+{0x0a, SHIFT}, /* G */
+{0x0b, SHIFT}, /* H */
+{0x0c, SHIFT}, /* I */
+{0x0d, SHIFT}, /* J */
+{0x0e, SHIFT}, /* K */
+{0x0f, SHIFT}, /* L */
+{0x10, SHIFT}, /* M */
+{0x11, SHIFT}, /* N */
+{0x12, SHIFT}, /* O */
+{0x13, SHIFT}, /* P */
+{0x14, SHIFT}, /* Q */
+{0x15, SHIFT}, /* R */
+{0x16, SHIFT}, /* S */
+{0x17, SHIFT}, /* T */
+{0x18, SHIFT}, /* U */
+{0x19, SHIFT}, /* V */
+{0x1a, SHIFT}, /* W */
+{0x1b, SHIFT}, /* X */
+{0x1c, SHIFT}, /* Y */
+{0x1d, SHIFT}, /* Z */
+{0x2f, 0}, /* [ */
+{0x31, 0}, /* \ */
+{0x30, 0}, /* ] */
+{0x23, SHIFT}, /* ^ */
+{0x2d, SHIFT}, /* _ */
+{0x35, 0}, /* ` */
+{0x04, 0}, /* a */
+{0x05, 0}, /* b */
+{0x06, 0}, /* c */
+{0x07, 0}, /* d */
+{0x08, 0}, /* e */
+{0x09, 0}, /* f */
+{0x0a, 0}, /* g */
+{0x0b, 0}, /* h */
+{0x0c, 0}, /* i */
+{0x0d, 0}, /* j */
+{0x0e, 0}, /* k */
+{0x0f, 0}, /* l */
+{0x10, 0}, /* m */
+{0x11, 0}, /* n */
+{0x12, 0}, /* o */
+{0x13, 0}, /* p */
+{0x14, 0}, /* q */
+{0x15, 0}, /* r */
+{0x16, 0}, /* s */
+{0x17, 0}, /* t */
+{0x18, 0}, /* u */
+{0x19, 0}, /* v */
+{0x1a, 0}, /* w */
+{0x1b, 0}, /* x */
+{0x1c, 0}, /* y */
+{0x1d, 0}, /* z */
+{0x2f, SHIFT}, /* { */
+{0x31, SHIFT}, /* | */
+{0x30, SHIFT}, /* } */
+{0x35, SHIFT}, /* ~ */
+{0,0}, /* DEL */
+};
+
+#else
+/* UK keyboard */
+#define KEYMAP_SIZE (128)
+const KEYMAP keymap[KEYMAP_SIZE] = {
+{0, 0}, /* NUL */
+{0, 0}, /* SOH */
+{0, 0}, /* STX */
+{0, 0}, /* ETX */
+{0, 0}, /* EOT */
+{0, 0}, /* ENQ */
+{0, 0}, /* ACK */
+{0, 0}, /* BEL */
+{0x2a, 0}, /* BS */ /* Keyboard Delete (Backspace) */
+{0x2b, 0}, /* TAB */ /* Keyboard Tab */
+{0x28, 0}, /* LF */ /* Keyboard Return (Enter) */
+{0, 0}, /* VT */
+{0, 0}, /* FF */
+{0, 0}, /* CR */
+{0, 0}, /* SO */
+{0, 0}, /* SI */
+{0, 0}, /* DEL */
+{0, 0}, /* DC1 */
+{0, 0}, /* DC2 */
+{0, 0}, /* DC3 */
+{0, 0}, /* DC4 */
+{0, 0}, /* NAK */
+{0, 0}, /* SYN */
+{0, 0}, /* ETB */
+{0, 0}, /* CAN */
+{0, 0}, /* EM */
+{0, 0}, /* SUB */
+{0, 0}, /* ESC */
+{0, 0}, /* FS */
+{0, 0}, /* GS */
+{0, 0}, /* RS */
+{0, 0}, /* US */
+{0x2c, 0}, /* */
+{0x1e, SHIFT}, /* ! */
+{0x1f, SHIFT}, /* " */
+{0x32, 0}, /* # */
+{0x21, SHIFT}, /* $ */
+{0x22, SHIFT}, /* % */
+{0x24, SHIFT}, /* & */
+{0x34, 0}, /* ' */
+{0x26, SHIFT}, /* ( */
+{0x27, SHIFT}, /* ) */
+{0x25, SHIFT}, /* * */
+{0x2e, SHIFT}, /* + */
+{0x36, 0}, /* , */
+{0x2d, 0}, /* - */
+{0x37, 0}, /* . */
+{0x38, 0}, /* / */
+{0x27, 0}, /* 0 */
+{0x1e, 0}, /* 1 */
+{0x1f, 0}, /* 2 */
+{0x20, 0}, /* 3 */
+{0x21, 0}, /* 4 */
+{0x22, 0}, /* 5 */
+{0x23, 0}, /* 6 */
+{0x24, 0}, /* 7 */
+{0x25, 0}, /* 8 */
+{0x26, 0}, /* 9 */
+{0x33, SHIFT}, /* : */
+{0x33, 0}, /* ; */
+{0x36, SHIFT}, /* < */
+{0x2e, 0}, /* = */
+{0x37, SHIFT}, /* > */
+{0x38, SHIFT}, /* ? */
+{0x34, SHIFT}, /* @ */
+{0x04, SHIFT}, /* A */
+{0x05, SHIFT}, /* B */
+{0x06, SHIFT}, /* C */
+{0x07, SHIFT}, /* D */
+{0x08, SHIFT}, /* E */
+{0x09, SHIFT}, /* F */
+{0x0a, SHIFT}, /* G */
+{0x0b, SHIFT}, /* H */
+{0x0c, SHIFT}, /* I */
+{0x0d, SHIFT}, /* J */
+{0x0e, SHIFT}, /* K */
+{0x0f, SHIFT}, /* L */
+{0x10, SHIFT}, /* M */
+{0x11, SHIFT}, /* N */
+{0x12, SHIFT}, /* O */
+{0x13, SHIFT}, /* P */
+{0x14, SHIFT}, /* Q */
+{0x15, SHIFT}, /* R */
+{0x16, SHIFT}, /* S */
+{0x17, SHIFT}, /* T */
+{0x18, SHIFT}, /* U */
+{0x19, SHIFT}, /* V */
+{0x1a, SHIFT}, /* W */
+{0x1b, SHIFT}, /* X */
+{0x1c, SHIFT}, /* Y */
+{0x1d, SHIFT}, /* Z */
+{0x2f, 0}, /* [ */
+{0x64, 0}, /* \ */
+{0x30, 0}, /* ] */
+{0x23, SHIFT}, /* ^ */
+{0x2d, SHIFT}, /* _ */
+{0x35, 0}, /* ` */
+{0x04, 0}, /* a */
+{0x05, 0}, /* b */
+{0x06, 0}, /* c */
+{0x07, 0}, /* d */
+{0x08, 0}, /* e */
+{0x09, 0}, /* f */
+{0x0a, 0}, /* g */
+{0x0b, 0}, /* h */
+{0x0c, 0}, /* i */
+{0x0d, 0}, /* j */
+{0x0e, 0}, /* k */
+{0x0f, 0}, /* l */
+{0x10, 0}, /* m */
+{0x11, 0}, /* n */
+{0x12, 0}, /* o */
+{0x13, 0}, /* p */
+{0x14, 0}, /* q */
+{0x15, 0}, /* r */
+{0x16, 0}, /* s */
+{0x17, 0}, /* t */
+{0x18, 0}, /* u */
+{0x19, 0}, /* v */
+{0x1a, 0}, /* w */
+{0x1b, 0}, /* x */
+{0x1c, 0}, /* y */
+{0x1d, 0}, /* z */
+{0x2f, SHIFT}, /* { */
+{0x64, SHIFT}, /* | */
+{0x30, SHIFT}, /* } */
+{0x32, SHIFT}, /* ~ */
+{0,0}, /* DEL */
+};
+#endif
+
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBKeyboardMouse/usbdc.cpp Thu Sep 08 15:01:33 2011 +0000
@@ -0,0 +1,544 @@
+/* usbdc.cpp */
+/* USB device controller */
+/* Copyright (c) Phil Wright 2008 */
+
+#include "mbed.h"
+#include "usbdc.h"
+#include "cmsis.h"
+
+#ifdef TARGET_LPC2368
+#undef LPC_USB_BASE
+#define LPC_USB_BASE (0xFFE0C000) /* TODO */
+#endif
+
+/* Power Control for Peripherals register */
+#define PCUSB ((unsigned long)1<<31)
+
+/* USB Clock Control register */
+#define DEV_CLK_EN ((unsigned long)1<<1)
+#define AHB_CLK_EN ((unsigned long)1<<4)
+
+/* USB Clock Status register */
+#define DEV_CLK_ON ((unsigned long)1<<1)
+#define AHB_CLK_ON ((unsigned long)1<<4)
+
+/* USB Device Interupt registers */
+#define FRAME ((unsigned long)1<<0)
+#define EP_FAST ((unsigned long)1<<1)
+#define EP_SLOW ((unsigned long)1<<2)
+#define DEV_STAT ((unsigned long)1<<3)
+#define CCEMPTY ((unsigned long)1<<4)
+#define CDFULL ((unsigned long)1<<5)
+#define RxENDPKT ((unsigned long)1<<6)
+#define TxENDPKT ((unsigned long)1<<7)
+#define EP_RLZED ((unsigned long)1<<8)
+#define ERR_INT ((unsigned long)1<<9)
+
+/* Endpoint Interrupt Registers */
+#define EP(endpoint) (1<<endpoint)
+
+/* USB Control register */
+#define RD_EN (1<<0)
+#define WR_EN (1<<1)
+#define LOG_ENDPOINT(endpoint) ((endpoint>>1)<<2)
+
+/* USB Receive Packet Length register */
+#define DV ((unsigned long)1<<10)
+#define PKT_RDY ((unsigned long)1<<11)
+#define PKT_LNGTH_MASK (0x3ff)
+
+/* Serial Interface Engine (SIE) */
+#define SIE_WRITE (0x01)
+#define SIE_READ (0x02)
+#define SIE_COMMAND (0x05)
+#define SIE_CMD_CODE(phase, data) ((phase<<8)|(data<<16))
+
+/* SIE Command codes */
+#define SIE_CMD_SET_ADDRESS (0xD0)
+#define SIE_CMD_CONFIGURE_DEVICE (0xD8)
+#define SIE_CMD_SET_MODE (0xF3)
+#define SIE_CMD_READ_FRAME_NUMBER (0xF5)
+#define SIE_CMD_READ_TEST_REGISTER (0xFD)
+#define SIE_CMD_SET_DEVICE_STATUS (0xFE)
+#define SIE_CMD_GET_DEVICE_STATUS (0xFE)
+#define SIE_CMD_GET_ERROR_CODE (0xFF)
+#define SIE_CMD_READ_ERROR_STATUS (0xFB)
+
+#define SIE_CMD_SELECT_ENDPOINT(endpoint) (0x00+endpoint)
+#define SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint) (0x40+endpoint)
+#define SIE_CMD_SET_ENDPOINT_STATUS(endpoint) (0x40+endpoint)
+
+#define SIE_CMD_CLEAR_BUFFER (0xF2)
+#define SIE_CMD_VALIDATE_BUFFER (0xFA)
+
+/* SIE Device Status register */
+#define SIE_DS_CON (1<<0)
+#define SIE_DS_CON_CH (1<<1)
+#define SIE_DS_SUS (1<<2)
+#define SIE_DS_SUS_CH (1<<3)
+#define SIE_DS_RST (1<<4)
+
+/* SIE Device Set Address register */
+#define SIE_DSA_DEV_EN (1<<7)
+
+/* SIE Configue Device register */
+#define SIE_CONF_DEVICE (1<<0)
+
+/* Select Endpoint register */
+#define SIE_SE_FE (1<<0)
+#define SIE_SE_ST (1<<1)
+#define SIE_SE_STP (1<<2)
+#define SIE_SE_PO (1<<3)
+#define SIE_SE_EPN (1<<4)
+#define SIE_SE_B_1_FULL (1<<5)
+#define SIE_SE_B_2_FULL (1<<6)
+
+/* Set Endpoint Status command */
+#define SIE_SES_ST (1<<0)
+#define SIE_SES_DA (1<<5)
+#define SIE_SES_RF_MO (1<<6)
+#define SIE_SES_CND_ST (1<<7)
+
+usbdc *usbdc::instance;
+
+usbdc::usbdc()
+{
+#ifdef TARGET_LPC1768
+ LPC_SC->USBCLKCFG=5; /* TODO */
+#endif
+
+ /* Enable power to USB device controller */
+ LPC_SC->PCONP |= PCUSB;
+
+ /* Enable USB clocks */
+ LPC_USB->USBClkCtrl |= DEV_CLK_EN | AHB_CLK_EN;
+ while (LPC_USB->USBClkSt != (DEV_CLK_ON | AHB_CLK_ON));
+
+ /* Configure pins P0.29 and P0.30 to be USB D+ and USB D- */
+ LPC_PINCON->PINSEL1 &= 0xc3ffffff;
+ LPC_PINCON->PINSEL1 |= 0x14000000;
+
+#ifdef ENABLE_VBUS
+ /* Configure pin P1.30 to be VBUS */
+ LPC_PINCON->PINSEL3 &= 0xcfffffff;
+ LPC_PINCON->PINSEL3 |= 0x20000000;
+
+ /* Configure pin P1.30 to have pull-down */
+ LPC_PINCON->PINMODE3 |= 0x30000000;
+#endif
+
+ /* Configure pin P2.9 to be Connect */
+ LPC_PINCON->PINSEL4 &= 0xfffcffff;
+ LPC_PINCON->PINSEL4 |= 0x00040000;
+
+ /* Connect must be low for at least 2.5uS */
+ wait_ms(1);
+
+ /* Attach IRQ */
+ instance = this;
+ NVIC_SetVector(USB_IRQn, (uint32_t)&_usbisr);
+ NVIC_EnableIRQ(USB_IRQn);
+
+ /* Enable device interrupts */
+ enableEvents();
+}
+
+void usbdc::connect(void)
+{
+ /* Connect USB device */
+ unsigned char status;
+
+ status = getDeviceStatus();
+ setDeviceStatus(status | SIE_DS_CON);
+}
+
+void usbdc::disconnect(void)
+{
+ /* Disconnect USB device */
+ unsigned char status;
+
+ status = getDeviceStatus();
+ setDeviceStatus(status & ~SIE_DS_CON);
+}
+
+void usbdc::SIECommand(unsigned long command)
+{
+ /* The command phase of a SIE transaction */
+ LPC_USB->USBDevIntClr = CCEMPTY;
+ LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_COMMAND, command);
+ while (!(LPC_USB->USBDevIntSt & CCEMPTY));
+}
+
+void usbdc::SIEWriteData(unsigned char data)
+{
+ /* The data write phase of a SIE transaction */
+ LPC_USB->USBDevIntClr = CCEMPTY;
+ LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_WRITE, data);
+ while (!(LPC_USB->USBDevIntSt & CCEMPTY));
+}
+
+unsigned char usbdc::SIEReadData(unsigned long command)
+{
+ /* The data read phase of a SIE transaction */
+ LPC_USB->USBDevIntClr = CDFULL;
+ LPC_USB->USBCmdCode = SIE_CMD_CODE(SIE_READ, command);
+ while (!(LPC_USB->USBDevIntSt & CDFULL));
+ return (unsigned char)LPC_USB->USBCmdData;
+}
+
+void usbdc::setDeviceStatus(unsigned char status)
+{
+ /* Write SIE device status register */
+ SIECommand(SIE_CMD_SET_DEVICE_STATUS);
+ SIEWriteData(status);
+}
+
+unsigned char usbdc::getDeviceStatus(void)
+{
+ /* Read SIE device status register */
+ SIECommand(SIE_CMD_GET_DEVICE_STATUS);
+ return SIEReadData(SIE_CMD_GET_DEVICE_STATUS);
+}
+
+void usbdc::setAddress(unsigned char address)
+{
+ /* Write SIE device address register */
+ SIECommand(SIE_CMD_SET_ADDRESS);
+ SIEWriteData((address & 0x7f) | SIE_DSA_DEV_EN);
+}
+
+unsigned char usbdc::selectEndpoint(unsigned char endpoint)
+{
+ /* SIE select endpoint command */
+ SIECommand(SIE_CMD_SELECT_ENDPOINT(endpoint));
+ return SIEReadData(SIE_CMD_SELECT_ENDPOINT(endpoint));
+}
+
+#if 1
+unsigned char usbdc::selectEndpointClearInterrupt(unsigned char endpoint)
+{
+ /* SIE select endpoint and clear interrupt command */
+ /* Using the Select Endpoint / Clear Interrupt SIE command does not seem */
+ /* to clear the appropriate bit in EP_INT_STAT? - using EP_INT_CLR instead */
+ LPC_USB->USBEpIntClr = EP(endpoint);
+ while (!(LPC_USB->USBDevIntSt & CDFULL));
+ return (unsigned char)LPC_USB->USBCmdData;
+}
+#else
+unsigned char usbdc::selectEndpointClearInterrupt(unsigned char endpoint)
+{
+ /* SIE select endpoint and clear interrupt command */
+ SIECommand(SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint));
+ return SIEReadData(SIE_CMD_SELECT_ENDPOINT_CLEAR_INTERRUPT(endpoint));
+}
+#endif
+
+unsigned char usbdc::clearBuffer(void)
+{
+ /* SIE clear buffer command */
+ SIECommand(SIE_CMD_CLEAR_BUFFER);
+ return SIEReadData(SIE_CMD_CLEAR_BUFFER);
+}
+
+void usbdc::validateBuffer(void)
+{
+ /* SIE validate buffer command */
+ SIECommand(SIE_CMD_VALIDATE_BUFFER);
+}
+
+void usbdc::setEndpointStatus(unsigned char endpoint, unsigned char status)
+{
+ /* SIE set endpoint status command */
+ SIECommand(SIE_CMD_SET_ENDPOINT_STATUS(endpoint));
+ SIEWriteData(status);
+}
+
+void usbdc::realiseEndpoint(unsigned char endpoint, unsigned long maxPacket)
+{
+ /* Realise an endpoint */
+ LPC_USB->USBDevIntClr = EP_RLZED;
+ LPC_USB->USBReEp |= EP(endpoint);
+ LPC_USB->USBEpInd = endpoint;
+ LPC_USB->USBMaxPSize = maxPacket;
+
+ while (!(LPC_USB->USBDevIntSt & EP_RLZED));
+ LPC_USB->USBDevIntClr = EP_RLZED;
+
+ /* Clear stall state */
+ endpointStallState &= ~EP(endpoint);
+}
+
+void usbdc::enableEndpointEvent(unsigned char endpoint)
+{
+ /* Enable an endpoint interrupt */
+ LPC_USB->USBEpIntEn |= EP(endpoint);
+}
+
+void usbdc::disableEndpointEvent(unsigned char endpoint)
+{
+ /* Disable an endpoint interrupt */
+ LPC_USB->USBEpIntEn &= ~EP(endpoint);
+}
+
+void usbdc::stallEndpoint(unsigned char endpoint)
+{
+ /* Stall an endpoint */
+ if ( (endpoint==EP0IN) || (endpoint==EP0OUT) )
+ {
+ /* Conditionally stall both control endpoints */
+ setEndpointStatus(EP0OUT, SIE_SES_CND_ST);
+ }
+ else
+ {
+ setEndpointStatus(endpoint, SIE_SES_ST);
+
+ /* Update stall state */
+ endpointStallState |= EP(endpoint);
+ }
+}
+
+void usbdc::unstallEndpoint(unsigned char endpoint)
+{
+ /* Unstall an endpoint. The endpoint will also be reinitialised */
+ setEndpointStatus(endpoint, 0);
+
+ /* Update stall state */
+ endpointStallState &= ~EP(endpoint);
+}
+
+bool usbdc::getEndpointStallState(unsigned char endpoint)
+{
+ /* Returns true if endpoint stalled */
+ return endpointStallState & EP(endpoint);
+}
+
+void usbdc::configureDevice(void)
+{
+ /* SIE Configure device command */
+ SIECommand(SIE_CMD_CONFIGURE_DEVICE);
+ SIEWriteData(SIE_CONF_DEVICE);
+}
+
+void usbdc::unconfigureDevice(void)
+{
+ /* SIE Configure device command */
+ SIECommand(SIE_CMD_CONFIGURE_DEVICE);
+ SIEWriteData(0);
+}
+
+unsigned long usbdc::endpointRead(unsigned char endpoint, unsigned char *buffer)
+{
+ /* Read from an OUT endpoint */
+ unsigned long size;
+ unsigned long i;
+ unsigned long data;
+ unsigned char offset;
+
+ LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | RD_EN;
+ while (!(LPC_USB->USBRxPLen & PKT_RDY));
+
+ size = LPC_USB->USBRxPLen & PKT_LNGTH_MASK;
+
+ offset = 0;
+
+ for (i=0; i<size; i++)
+ {
+ if (offset==0)
+ {
+ /* Fetch up to four bytes of data as a word */
+ data = LPC_USB->USBRxData;
+ }
+
+ /* extract a byte */
+ *buffer++ = data>>offset;
+
+ /* move on to the next byte */
+ offset = (offset + 8) % 32;
+ }
+
+ /* Clear RD_EN to cover zero length packet case */
+ LPC_USB->USBCtrl=0;
+
+ selectEndpoint(endpoint);
+ clearBuffer();
+
+ return size;
+}
+
+void usbdc::endpointWrite(unsigned char endpoint, unsigned char *buffer, unsigned long size)
+{
+ /* Write to an IN endpoint */
+ unsigned long temp, data;
+ unsigned char offset;
+
+ LPC_USB->USBCtrl = LOG_ENDPOINT(endpoint) | WR_EN;
+
+ LPC_USB->USBTxPLen = size;
+ offset = 0;
+ data = 0;
+
+ if (size>0)
+ {
+ do {
+ /* Fetch next data byte into a word-sized temporary variable */
+ temp = *buffer++;
+
+ /* Add to current data word */
+ temp = temp << offset;
+ data = data | temp;
+
+ /* move on to the next byte */
+ offset = (offset + 8) % 32;
+ size--;
+
+ if ((offset==0) || (size==0))
+ {
+ /* Write the word to the endpoint */
+ LPC_USB->USBTxData = data;
+ data = 0;
+ }
+ } while (size>0);
+ }
+
+ /* Clear WR_EN to cover zero length packet case */
+ LPC_USB->USBCtrl=0;
+
+ selectEndpoint(endpoint);
+ validateBuffer();
+}
+
+void usbdc::enableEvents(void)
+{
+ /* Enable interrupt sources */
+ LPC_USB->USBDevIntEn = EP_SLOW | DEV_STAT;
+}
+
+void usbdc::disableEvents(void)
+{
+ /* Disable interrupt sources */
+ LPC_USB->USBDevIntClr = EP_SLOW | DEV_STAT;
+}
+
+void usbdc::usbisr(void)
+{
+ unsigned char devStat;
+
+ if (LPC_USB->USBDevIntSt & FRAME)
+ {
+ /* Frame event */
+ deviceEventFrame();
+ /* Clear interrupt status flag */
+ LPC_USB->USBDevIntClr = FRAME;
+ }
+
+ if (LPC_USB->USBDevIntSt & DEV_STAT)
+ {
+ /* Device Status interrupt */
+ /* Must clear the interrupt status flag before reading the device status from the SIE */
+ LPC_USB->USBDevIntClr = DEV_STAT;
+
+ /* Read device status from SIE */
+ devStat = getDeviceStatus();
+
+ if (devStat & SIE_DS_RST)
+ {
+ /* Bus reset */
+ deviceEventReset();
+ }
+ }
+
+ if (LPC_USB->USBDevIntSt & EP_SLOW)
+ {
+ /* (Slow) Endpoint Interrupt */
+
+ /* Process each endpoint interrupt */
+ if (LPC_USB->USBEpIntSt & EP(EP0OUT))
+ {
+ if (selectEndpointClearInterrupt(EP0OUT) & SIE_SE_STP)
+ {
+ /* this is a setup packet */
+ endpointEventEP0Setup();
+ }
+ else
+ {
+ endpointEventEP0Out();
+ }
+ }
+
+ if (LPC_USB->USBEpIntSt & EP(EP0IN))
+ {
+ selectEndpointClearInterrupt(EP0IN);
+ endpointEventEP0In();
+ }
+
+ if (LPC_USB->USBEpIntSt & EP(EP1OUT))
+ {
+ selectEndpointClearInterrupt(EP1OUT);
+ endpointEventEP1Out();
+ }
+
+ if (LPC_USB->USBEpIntSt & EP(EP1IN))
+ {
+ selectEndpointClearInterrupt(EP1IN);
+ endpointEventEP1In();
+ }
+
+ if (LPC_USB->USBEpIntSt & EP(EP2OUT))
+ {
+ selectEndpointClearInterrupt(EP2OUT);
+ endpointEventEP2Out();
+ }
+
+ if (LPC_USB->USBEpIntSt & EP(EP2IN))
+ {
+ selectEndpointClearInterrupt(EP2IN);
+ endpointEventEP2In();
+ }
+
+ /* Clear interrupt status flag */
+ /* EP_SLOW and EP_FAST interrupt bits should be cleared after the corresponding endpoint interrupts are cleared. */
+ LPC_USB->USBDevIntClr = EP_SLOW;
+ }
+}
+
+
+void usbdc::_usbisr(void)
+{
+ instance->usbisr();
+}
+
+void usbdc::deviceEventReset(void)
+{
+}
+
+void usbdc::deviceEventFrame(void)
+{
+}
+
+void usbdc::endpointEventEP0Setup(void)
+{
+}
+
+void usbdc::endpointEventEP0In(void)
+{
+}
+
+void usbdc::endpointEventEP0Out(void)
+{
+}
+
+void usbdc::endpointEventEP1In(void)
+{
+}
+
+void usbdc::endpointEventEP1Out(void)
+{
+}
+
+void usbdc::endpointEventEP2In(void)
+{
+}
+
+void usbdc::endpointEventEP2Out(void)
+{
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBKeyboardMouse/usbdc.h Thu Sep 08 15:01:33 2011 +0000
@@ -0,0 +1,65 @@
+/* usbdc.h */
+/* USB device controller */
+/* Copyright (c) Phil Wright 2008 */
+
+#ifndef USBDC_H
+#define USBDC_H
+
+/* Endpoints */
+#define EP0OUT (0) /* Control */
+#define EP0IN (1) /* Control */
+#define EP1OUT (2) /* Interrupt */
+#define EP1IN (3) /* Interrupt */
+#define EP2OUT (4) /* Bulk */
+#define EP2IN (5) /* Bulk */
+
+#include "mbed.h"
+
+class usbdc : public Base
+{
+public:
+ usbdc();
+ void connect(void);
+ void disconnect(void);
+protected:
+ void setAddress(unsigned char address);
+ void realiseEndpoint(unsigned char endpoint, unsigned long maxPacket);
+ void enableEndpointEvent(unsigned char endpoint);
+ void disableEndpointEvent(unsigned char endpoint);
+ void stallEndpoint(unsigned char endpoint);
+ void unstallEndpoint(unsigned char endpoint);
+ bool getEndpointStallState(unsigned char endpoint);
+ void configureDevice(void);
+ void unconfigureDevice(void);
+ unsigned long endpointRead(unsigned char endpoint, unsigned char *buffer);
+ void endpointWrite(unsigned char endpoint, unsigned char *buffer, unsigned long size);
+ void enableEvents(void);
+ void disableEvents(void);
+ virtual void deviceEventReset(void);
+ virtual void deviceEventFrame(void);
+ virtual void endpointEventEP0Setup(void);
+ virtual void endpointEventEP0In(void);
+ virtual void endpointEventEP0Out(void);
+ virtual void endpointEventEP1In(void);
+ virtual void endpointEventEP1Out(void);
+ virtual void endpointEventEP2In(void);
+ virtual void endpointEventEP2Out(void);
+private:
+ void SIECommand(unsigned long command);
+ void SIEWriteData(unsigned char data);
+ unsigned char SIEReadData(unsigned long command);
+ void setDeviceStatus(unsigned char status);
+ void setEndpointStatus(unsigned char endpoint, unsigned char status);
+ unsigned char getDeviceStatus(void);
+ unsigned char selectEndpoint(unsigned char endpoint);
+ unsigned char selectEndpointClearInterrupt(unsigned char endpoint);
+ unsigned char clearBuffer(void);
+ void validateBuffer(void);
+ void usbisr(void);
+ unsigned long endpointStallState;
+ static void _usbisr(void);
+ static usbdc *instance;
+};
+
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBKeyboardMouse/usbdevice.cpp Thu Sep 08 15:01:33 2011 +0000
@@ -0,0 +1,532 @@
+/* usbdevice.cpp */
+/* Generic USB device */
+/* Copyright (c) Phil Wright 2008 */
+
+#include "mbed.h"
+#include "usbdevice.h"
+
+/* Standard requests */
+#define GET_STATUS (0)
+#define CLEAR_FEATURE (1)
+#define SET_FEATURE (3)
+#define SET_ADDRESS (5)
+#define GET_DESCRIPTOR (6)
+#define SET_DESCRIPTOR (7)
+#define GET_CONFIGURATION (8)
+#define SET_CONFIGURATION (9)
+#define GET_INTERFACE (10)
+#define SET_INTERFACE (11)
+
+/* Device status */
+#define DEVICE_STATUS_SELF_POWERED (1<<0)
+#define DEVICE_STATUS_REMOTE_WAKEUP (1<<1)
+
+/* Endpoint status */
+#define ENDPOINT_STATUS_HALT (1<<0)
+
+/* Standard feature selectors */
+#define DEVICE_REMOTE_WAKEUP (1)
+#define ENDPOINT_HALT (0)
+
+/* Macro to convert wIndex endpoint number to physical endpoint number */
+#define WINDEX_TO_PHYSICAL(endpoint) (((endpoint & 0x0f) << 1) + ((endpoint & 0x80) ? 1 : 0))
+
+CONTROL_TRANSFER transfer;
+USB_DEVICE device;
+
+usbdevice::usbdevice()
+{
+ /* Set initial device state */
+ device.state = POWERED;
+ device.configuration = 0;
+ device.suspended = false;
+
+ /* Set the maximum packet size for the control endpoints */
+ realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0);
+ realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0);
+
+ /* Enable endpoint events for EP0 */
+ enableEndpointEvent(EP0IN);
+ enableEndpointEvent(EP0OUT);
+}
+
+void usbdevice::endpointEventEP0Setup(void)
+{
+ /* Endpoint 0 setup event */
+ if (!controlSetup())
+ {
+ /* Protocol stall; this will stall both endpoints */
+ stallEndpoint(EP0OUT);
+ }
+}
+
+void usbdevice::endpointEventEP0Out(void)
+{
+ /* Endpoint 0 OUT data event */
+ if (!controlOut())
+ {
+ /* Protocol stall; this will stall both endpoints */
+ stallEndpoint(EP0OUT);
+ }
+}
+
+void usbdevice::endpointEventEP0In(void)
+{
+ /* Endpoint 0 IN data event */
+ if (!controlIn())
+ {
+ /* Protocol stall; this will stall both endpoints */
+ stallEndpoint(EP0OUT);
+ }
+}
+
+void usbdevice::deviceEventReset(void)
+{
+ device.state = DEFAULT;
+ device.configuration = 0;
+ device.suspended = false;
+}
+
+void usbdevice::decodeSetupPacket(unsigned char *data, SETUP_PACKET *packet)
+{
+ /* Fill in the elements of a SETUP_PACKET structure from raw data */
+ packet->bmRequestType.dataTransferDirection = (data[0] & 0x80) >> 7;
+ packet->bmRequestType.Type = (data[0] & 0x60) >> 5;
+ packet->bmRequestType.Recipient = data[0] & 0x1f;
+ packet->bRequest = data[1];
+ packet->wValue = (data[2] | (unsigned short)data[3] << 8);
+ packet->wIndex = (data[4] | (unsigned short)data[5] << 8);
+ packet->wLength = (data[6] | (unsigned short)data[7] << 8);
+}
+
+bool usbdevice::controlSetup(void)
+{
+ /* Control transfer setup stage */
+ unsigned char buffer[MAX_PACKET_SIZE_EP0];
+ unsigned long count;
+
+ count = endpointRead(EP0OUT, buffer);
+
+ /* Must be 8 bytes of data */
+ if (count != 8)
+ {
+ return false;
+ }
+
+ /* Initialise control transfer state */
+ decodeSetupPacket(buffer, &transfer.setup);
+ transfer.ptr = NULL;
+ transfer.remaining = 0;
+ transfer.direction = 0;
+ transfer.zlp = false;
+
+ /* Process request */
+ if (!requestSetup())
+ {
+ return false;
+ }
+
+ /* Check transfer size and direction */
+ if (transfer.setup.wLength>0)
+ {
+ if (transfer.setup.bmRequestType.dataTransferDirection==DEVICE_TO_HOST)
+ {
+ /* IN data stage is required */
+ if (transfer.direction != DEVICE_TO_HOST)
+ {
+ return false;
+ }
+
+ /* Transfer must be less than or equal to the size requested by the host */
+ if (transfer.remaining > transfer.setup.wLength)
+ {
+ transfer.remaining = transfer.setup.wLength;
+ }
+ }
+ else
+ {
+ /* OUT data stage is required */
+ if (transfer.direction != HOST_TO_DEVICE)
+ {
+ return false;
+ }
+
+ /* Transfer must be equal to the size requested by the host */
+ if (transfer.remaining != transfer.setup.wLength)
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ /* No data stage; transfer size must be zero */
+ if (transfer.remaining != 0)
+ {
+ return false;
+ }
+ }
+
+ /* Data or status stage if applicable */
+ if (transfer.setup.wLength>0)
+ {
+ if (transfer.setup.bmRequestType.dataTransferDirection==DEVICE_TO_HOST)
+ {
+ /* Check if we'll need to send a zero length packet at the end of this transfer */
+ if (transfer.setup.wLength > transfer.remaining)
+ {
+ /* Device wishes to transfer less than host requested */
+ if ((transfer.remaining % MAX_PACKET_SIZE_EP0) == 0)
+ {
+ /* Transfer is a multiple of EP0 max packet size */
+ transfer.zlp = true;
+ }
+ }
+
+ /* IN stage */
+ controlIn();
+ }
+ }
+ else
+ {
+ /* Status stage */
+ endpointWrite(EP0IN, NULL, 0);
+ }
+
+ return true;
+}
+
+bool usbdevice::controlOut(void)
+{
+ /* Control transfer data OUT stage */
+ unsigned char buffer[MAX_PACKET_SIZE_EP0];
+ unsigned long packetSize;
+
+ /* Check we should be transferring data OUT */
+ if (transfer.direction != HOST_TO_DEVICE)
+ {
+ return false;
+ }
+
+ /* Read from endpoint */
+ packetSize = endpointRead(EP0OUT, buffer);
+
+ /* Check if transfer size is valid */
+ if (packetSize > transfer.remaining)
+ {
+ /* Too big */
+ return false;
+ }
+
+ /* Update transfer */
+ transfer.ptr += packetSize;
+ transfer.remaining -= packetSize;
+
+ /* Check if transfer has completed */
+ if (transfer.remaining == 0)
+ {
+ /* Process request */
+ if (!requestOut())
+ {
+ return false;
+ }
+
+ /* Status stage */
+ endpointWrite(EP0IN, NULL, 0);
+ }
+
+ return true;
+}
+
+bool usbdevice::controlIn(void)
+{
+ /* Control transfer data IN stage */
+ unsigned packetSize;
+
+ /* Check if transfer has completed (status stage transactions also have transfer.remaining == 0) */
+ if (transfer.remaining == 0)
+ {
+ if (transfer.zlp)
+ {
+ /* Send zero length packet */
+ endpointWrite(EP0IN, NULL, 0);
+ transfer.zlp = false;
+ }
+
+ /* Completed */
+ return true;
+ }
+
+ /* Check we should be transferring data IN */
+ if (transfer.direction != DEVICE_TO_HOST)
+ {
+ return false;
+ }
+
+ packetSize = transfer.remaining;
+
+ if (packetSize > MAX_PACKET_SIZE_EP0)
+ {
+ packetSize = MAX_PACKET_SIZE_EP0;
+ }
+
+ /* Write to endpoint */
+ endpointWrite(EP0IN, transfer.ptr, packetSize);
+
+ /* Update transfer */
+ transfer.ptr += packetSize;
+ transfer.remaining -= packetSize;
+
+ return true;
+}
+
+bool usbdevice::requestSetup(void)
+{
+ bool success = false;
+
+ /* Process standard requests */
+ if ((transfer.setup.bmRequestType.Type == STANDARD_TYPE))
+ {
+ switch (transfer.setup.bRequest)
+ {
+ case GET_STATUS:
+ success = requestGetStatus();
+ break;
+ case CLEAR_FEATURE:
+ success = requestClearFeature();
+ break;
+ case SET_FEATURE:
+ success = requestSetFeature();
+ break;
+ case SET_ADDRESS:
+ success = requestSetAddress();
+ break;
+ case GET_DESCRIPTOR:
+ success = requestGetDescriptor();
+ break;
+ case SET_DESCRIPTOR:
+ /* TODO: Support is optional, not implemented here */
+ success = false;
+ break;
+ case GET_CONFIGURATION:
+ success = requestGetConfiguration();
+ break;
+ case SET_CONFIGURATION:
+ success = requestSetConfiguration();
+ break;
+ case GET_INTERFACE:
+ success = requestGetInterface();
+ break;
+ case SET_INTERFACE:
+ success = requestSetInterface();
+ break;
+ default:
+ break;
+ }
+ }
+
+ return success;
+}
+
+bool usbdevice::requestOut(void)
+{
+ return true;
+}
+
+bool usbdevice::requestSetAddress(void)
+{
+ /* Set the device address */
+ setAddress(transfer.setup.wValue);
+
+ if (transfer.setup.wValue == 0)
+ {
+ device.state = DEFAULT;
+ }
+ else
+ {
+ device.state = ADDRESS;
+ }
+
+ return true;
+}
+
+bool usbdevice::requestSetConfiguration(void)
+{
+ /* Set the device configuration */
+ if (transfer.setup.wValue == 0)
+ {
+ /* Not configured */
+ unconfigureDevice();
+ device.state = ADDRESS;
+ }
+ else
+ {
+ configureDevice();
+ device.state = CONFIGURED;
+ }
+
+ /* TODO: We do not currently support multiple configurations, just keep a record of the configuration value */
+ device.configuration = transfer.setup.wValue;
+
+ return true;
+}
+
+bool usbdevice::requestGetConfiguration(void)
+{
+ /* Send the device configuration */
+ transfer.ptr = &device.configuration;
+ transfer.remaining = sizeof(device.configuration);
+ transfer.direction = DEVICE_TO_HOST;
+ return true;
+}
+
+bool usbdevice::requestGetInterface(void)
+{
+ static unsigned char alternateSetting;
+
+ /* Return the selected alternate setting for an interface */
+
+ if (device.state != CONFIGURED)
+ {
+ return false;
+ }
+
+ /* TODO: We currently do not support alternate settings so always return zero */
+ /* TODO: Should check that the interface number is valid */
+ alternateSetting = 0;
+
+ /* Send the alternate setting */
+ transfer.ptr = &alternateSetting;
+ transfer.remaining = sizeof(alternateSetting);
+ transfer.direction = DEVICE_TO_HOST;
+ return true;
+}
+
+bool usbdevice::requestSetInterface(void)
+{
+ /* TODO: We currently do not support alternate settings, return false */
+ return false;
+}
+
+bool usbdevice::requestSetFeature()
+{
+ bool success = false;
+
+ if (device.state != CONFIGURED)
+ {
+ /* Endpoint or interface must be zero */
+ if (transfer.setup.wIndex != 0)
+ {
+ return false;
+ }
+ }
+
+ switch (transfer.setup.bmRequestType.Recipient)
+ {
+ case DEVICE_RECIPIENT:
+ /* TODO: Remote wakeup feature not supported */
+ break;
+ case ENDPOINT_RECIPIENT:
+ if (transfer.setup.wValue == ENDPOINT_HALT)
+ {
+ /* TODO: We should check that the endpoint number is valid */
+ stallEndpoint(WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
+ success = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return success;
+}
+
+bool usbdevice::requestClearFeature()
+{
+ bool success = false;
+
+ if (device.state != CONFIGURED)
+ {
+ /* Endpoint or interface must be zero */
+ if (transfer.setup.wIndex != 0)
+ {
+ return false;
+ }
+ }
+
+ switch (transfer.setup.bmRequestType.Recipient)
+ {
+ case DEVICE_RECIPIENT:
+ /* TODO: Remote wakeup feature not supported */
+ break;
+ case ENDPOINT_RECIPIENT:
+ /* TODO: We should check that the endpoint number is valid */
+ if (transfer.setup.wValue == ENDPOINT_HALT)
+ {
+ unstallEndpoint(WINDEX_TO_PHYSICAL(transfer.setup.wIndex));
+ success = true;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return success;
+}
+
+bool usbdevice::requestGetStatus(void)
+{
+ static unsigned short status;
+ bool success = false;
+
+ if (device.state != CONFIGURED)
+ {
+ /* Endpoint or interface must be zero */
+ if (transfer.setup.wIndex != 0)
+ {
+ return false;
+ }
+ }
+
+ switch (transfer.setup.bmRequestType.Recipient)
+ {
+ case DEVICE_RECIPIENT:
+ /* TODO: Currently only supports self powered devices */
+ status = DEVICE_STATUS_SELF_POWERED;
+ success = true;
+ break;
+ case INTERFACE_RECIPIENT:
+ status = 0;
+ success = true;
+ break;
+ case ENDPOINT_RECIPIENT:
+ /* TODO: We should check that the endpoint number is valid */
+ if (getEndpointStallState(WINDEX_TO_PHYSICAL(transfer.setup.wIndex)))
+ {
+ status = ENDPOINT_STATUS_HALT;
+ }
+ else
+ {
+ status = 0;
+ }
+ success = true;
+ break;
+ default:
+ break;
+ }
+
+ if (success)
+ {
+ /* Send the status */
+ transfer.ptr = (unsigned char *)&status; /* Assumes little endian */
+ transfer.remaining = sizeof(status);
+ transfer.direction = DEVICE_TO_HOST;
+ }
+
+ return success;
+}
+
+bool usbdevice::requestGetDescriptor(void)
+{
+ return false;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBKeyboardMouse/usbdevice.h Thu Sep 08 15:01:33 2011 +0000
@@ -0,0 +1,105 @@
+/* usbdevice.h */
+/* Generic USB device */
+/* Copyright (c) Phil Wright 2008 */
+
+#ifndef USBDEVICE_H
+#define USBDEVICE_H
+
+#include "usbdc.h"
+
+/* Endpoint packet sizes */
+#define MAX_PACKET_SIZE_EP0 (64)
+
+/* bmRequestType.dataTransferDirection */
+#define HOST_TO_DEVICE (0)
+#define DEVICE_TO_HOST (1)
+
+/* bmRequestType.Type*/
+#define STANDARD_TYPE (0)
+#define CLASS_TYPE (1)
+#define VENDOR_TYPE (2)
+#define RESERVED_TYPE (3)
+
+/* bmRequestType.Recipient */
+#define DEVICE_RECIPIENT (0)
+#define INTERFACE_RECIPIENT (1)
+#define ENDPOINT_RECIPIENT (2)
+#define OTHER_RECIPIENT (3)
+
+/* Descriptors */
+#define DESCRIPTOR_TYPE(wValue) (wValue >> 8)
+#define DESCRIPTOR_INDEX(wValue) (wValue & 0xff)
+
+/* Descriptor type */
+#define DEVICE_DESCRIPTOR (1)
+#define CONFIGURATION_DESCRIPTOR (2)
+#define STRING_DESCRIPTOR (3)
+#define INTERFACE_DESCRIPTOR (4)
+#define ENDPOINT_DESCRIPTOR (5)
+
+/*string offset*/
+#define STRING_OFFSET_LANGID (0)
+#define STRING_OFFSET_IMANUFACTURER (1)
+#define STRING_OFFSET_IPRODUCT (2)
+#define STRING_OFFSET_ISERIAL (3)
+#define STRING_OFFSET_ICONFIGURATION (4)
+#define STRING_OFFSET_IINTERFACE (5)
+
+typedef struct {
+ struct {
+ unsigned char dataTransferDirection;
+ unsigned char Type;
+ unsigned char Recipient;
+ } bmRequestType;
+ unsigned char bRequest;
+ unsigned short wValue;
+ unsigned short wIndex;
+ unsigned short wLength;
+} SETUP_PACKET;
+
+typedef struct {
+ SETUP_PACKET setup;
+ unsigned char *ptr;
+ unsigned long remaining;
+ unsigned char direction;
+ bool zlp;
+} CONTROL_TRANSFER;
+
+typedef enum {ATTACHED, POWERED, DEFAULT, ADDRESS, CONFIGURED} DEVICE_STATE;
+
+typedef struct {
+ DEVICE_STATE state;
+ unsigned char configuration;
+ bool suspended;
+} USB_DEVICE;
+
+class usbdevice : public usbdc
+{
+public:
+ usbdevice();
+protected:
+ virtual void endpointEventEP0Setup(void);
+ virtual void endpointEventEP0In(void);
+ virtual void endpointEventEP0Out(void);
+ virtual bool requestSetup(void);
+ virtual bool requestOut(void);
+ virtual void deviceEventReset(void);
+ virtual bool requestGetDescriptor(void);
+ bool requestSetAddress(void);
+ virtual bool requestSetConfiguration(void);
+ virtual bool requestGetConfiguration(void);
+ bool requestGetStatus(void);
+ virtual bool requestSetInterface(void);
+ virtual bool requestGetInterface(void);
+ bool requestSetFeature(void);
+ bool requestClearFeature(void);
+ CONTROL_TRANSFER transfer;
+ USB_DEVICE device;
+private:
+ bool controlIn(void);
+ bool controlOut(void);
+ bool controlSetup(void);
+ void decodeSetupPacket(unsigned char *data, SETUP_PACKET *packet);
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBKeyboardMouse/usbhid.cpp Thu Sep 08 15:01:33 2011 +0000
@@ -0,0 +1,491 @@
+/* usbhid.cpp */
+/* USB HID class device */
+/* Copyright (c) Phil Wright 2008 */
+/* USB String Descriptor by llumpu 2011*/
+
+#include "mbed.h"
+#include "usbhid.h"
+#include "asciihid.h"
+
+/* Endpoint packet sizes */
+#define MAX_PACKET_SIZE_EP1 (64)
+
+/* HID Class */
+#define HID_CLASS (3)
+#define HID_SUBCLASS_NONE (0)
+#define HID_PROTOCOL_NONE (0)
+#define HID_DESCRIPTOR (33)
+#define REPORT_DESCRIPTOR (34)
+
+/* Class requests */
+#define GET_REPORT (0x1)
+#define GET_IDLE (0x2)
+#define SET_REPORT (0x9)
+#define SET_IDLE (0xa)
+
+/* Descriptors */
+unsigned char deviceDescriptor[] = {
+ 0x12, /* bLength */
+ DEVICE_DESCRIPTOR, /* bDescriptorType */
+ 0x00, /* bcdUSB (LSB) */
+ 0x02, /* bcdUSB (MSB) */
+ 0x00, /* bDeviceClass */
+ 0x00, /* bDeviceSubClass */
+ 0x00, /* bDeviceprotocol */
+ MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
+ 0x28, /* idVendor (LSB) */
+ 0x0d, /* idVendor (MSB) */
+ 0x05, /* idProduct (LSB) */
+ 0x02, /* idProduct (MSB) */
+ 0x00, /* bcdDevice (LSB) */
+ 0x00, /* bcdDevice (MSB) */
+ STRING_OFFSET_IMANUFACTURER, /* iManufacturer */
+ STRING_OFFSET_IPRODUCT, /* iProduct */
+ STRING_OFFSET_ISERIAL, /* iSerialNumber */
+ 0x01 /* bNumConfigurations */
+ };
+
+unsigned char configurationDescriptor[] = {
+ 0x09, /* bLength */
+ CONFIGURATION_DESCRIPTOR, /* bDescriptorType */
+ 0x09+0x09+0x09+0x07, /* wTotalLength (LSB) */
+ 0x00, /* wTotalLength (MSB) */
+ 0x01, /* bNumInterfaces */
+ 0x01, /* bConfigurationValue */
+ STRING_OFFSET_ICONFIGURATION,/* iConfiguration */
+ 0xc0, /* bmAttributes */
+ 0x00, /* bMaxPower */
+
+ 0x09, /* bLength */
+ INTERFACE_DESCRIPTOR, /* bDescriptorType */
+ 0x00, /* bInterfaceNumber */
+ 0x00, /* bAlternateSetting */
+ 0x01, /* bNumEndpoints */
+ HID_CLASS, /* bInterfaceClass */
+ HID_SUBCLASS_NONE, /* bInterfaceSubClass */
+ HID_PROTOCOL_NONE, /* bInterfaceProtocol */
+ STRING_OFFSET_IINTERFACE, /* iInterface */
+
+ 0x09, /* bLength */
+ HID_DESCRIPTOR, /* bDescriptorType */
+ 0x11, /* bcdHID (LSB) */
+ 0x01, /* bcdHID (MSB) */
+ 0x00, /* bCountryCode */
+ 0x01, /* bNumDescriptors */
+ REPORT_DESCRIPTOR, /* bDescriptorType */
+ 0x79, /* wDescriptorLength (LSB) */
+ 0x00, /* wDescriptorLength (MSB) */
+
+ 0x07, /* bLength */
+ ENDPOINT_DESCRIPTOR, /* bDescriptorType */
+ 0x81, /* bEndpointAddress */
+ 0x03, /* bmAttributes */
+ MAX_PACKET_SIZE_EP1, /* wMaxPacketSize (LSB) */
+ 0x00, /* wMaxPacketSize (MSB) */
+ 0x0a, /* bInterval */
+ };
+
+ unsigned char stringLangidDescriptor[] = {
+ 0x04, /*bLength - must match size of stringLangidDescriptor array (always 4 bytes - hex 0x04) */
+ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
+ 0x09,0x00, /*bString Lang ID - 0x009 - English*/
+ };
+
+ unsigned char stringImanufacturerDescriptor[] = {
+ 0x12, /*bLength must match size of stringImanufacturerDescriptor array (here 18 bytes - hex 0x12) */
+ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
+ 'm',0,'b',0,'e',0,'d',0,'.',0,'o',0,'r',0,'g',0, /*bString iManufacturer - mbed.org*/
+ };
+
+ unsigned char stringIproductDescriptor[] = {
+ 0x12, /*bLength must match size of stringIproductDescriptor array (here 18 bytes - hex 0x12) */
+ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
+ 'm',0,'b',0,'e',0,'d',0,' ',0,'H',0,'I',0,'D',0, /*bString iProduct - mbed HID*/
+ };
+
+ unsigned char stringIserialDescriptor[] = {
+ 0x16, /*bLength must match size of stringIserialDescriptor array (here 22 bytes - hex 0x16) */
+ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
+ '0',0,'1',0,'2',0,'3',0,'4',0,'5',0,'6',0,'7',0,'8',0,'9',0, /*bString iSerial - 0123456789*/
+ };
+
+ unsigned char stringIconfigurationDescriptor[] = {
+ 0x06, /*bLength must match size of stringIconfigurationDescriptor array (here 6 bytes - hex 0x06) */
+ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
+ '0',0,'1',0, /*bString iConfiguration - 01*/
+ };
+
+ unsigned char stringIinterfaceDescriptor[] = {
+ 0x08, /*bLength must match size of stringIinterfaceDescriptor array (here 8 bytes - hex 0x08) */
+ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
+ 'H',0,'I',0,'D',0, /*bString iInterface - HID*/
+ };
+
+/* HID Class Report Descriptor */
+/* Short items: size is 0, 1, 2 or 3 specifying 0, 1, 2 or 4 (four) bytes of data as per HID Class standard */
+
+/* Main items */
+#define INPUT(size) (0x80 | size)
+#define OUTPUT(size) (0x90 | size)
+#define FEATURE(size) (0xb0 | size)
+#define COLLECTION(size) (0xa0 | size)
+#define END_COLLECTION(size) (0xc0 | size)
+
+/* Global items */
+#define USAGE_PAGE(size) (0x04 | size)
+#define LOGICAL_MIN(size) (0x14 | size)
+#define LOGICAL_MAX(size) (0x24 | size)
+#define PHYSICAL_MIN(size) (0x34 | size)
+#define PHYSICAL_MAX(size) (0x44 | size)
+#define UNIT_EXPONENT(size) (0x54 | size)
+#define UNIT(size) (0x64 | size)
+#define REPORT_SIZE(size) (0x74 | size)
+#define REPORT_ID(size) (0x84 | size)
+#define REPORT_COUNT(size) (0x94 | size)
+#define PUSH(size) (0xa4 | size)
+#define POP(size) (0xb4 | size)
+
+/* Local items */
+#define USAGE(size) (0x08 | size)
+#define USAGE_MIN(size) (0x18 | size)
+#define USAGE_MAX(size) (0x28 | size)
+#define DESIGNATOR_INDEX(size) (0x38 | size)
+#define DESIGNATOR_MIN(size) (0x48 | size)
+#define DESIGNATOR_MAX(size) (0x58 | size)
+#define STRING_INDEX(size) (0x78 | size)
+#define STRING_MIN(size) (0x88 | size)
+#define STRING_MAX(size) (0x98 | size)
+#define DELIMITER(size) (0xa8 | size)
+
+#define REPORT_ID_KEYBOARD (1)
+#define REPORT_ID_MOUSE (2)
+
+#define MAX_REPORT_SIZE (8)
+
+unsigned char reportDescriptor[] = {
+/* Keyboard */
+USAGE_PAGE(1), 0x01,
+USAGE(1), 0x06,
+COLLECTION(1), 0x01,
+REPORT_ID(1), REPORT_ID_KEYBOARD,
+USAGE_PAGE(1), 0x07,
+USAGE_MIN(1), 0xE0,
+USAGE_MAX(1), 0xE7,
+LOGICAL_MIN(1), 0x00,
+LOGICAL_MAX(1), 0x01,
+REPORT_SIZE(1), 0x01,
+REPORT_COUNT(1), 0x08,
+INPUT(1), 0x02,
+REPORT_COUNT(1), 0x01,
+REPORT_SIZE(1), 0x08,
+INPUT(1), 0x01,
+REPORT_COUNT(1), 0x05,
+REPORT_SIZE(1), 0x01,
+USAGE_PAGE(1), 0x08,
+USAGE_MIN(1), 0x01,
+USAGE_MAX(1), 0x05,
+OUTPUT(1), 0x02,
+REPORT_COUNT(1), 0x01,
+REPORT_SIZE(1), 0x03,
+OUTPUT(1), 0x01,
+REPORT_COUNT(1), 0x06,
+REPORT_SIZE(1), 0x08,
+LOGICAL_MIN(1), 0x00,
+LOGICAL_MAX(2), 0xff, 0x00,
+USAGE_PAGE(1), 0x07,
+USAGE_MIN(1), 0x00,
+USAGE_MAX(2), 0xff, 0x00,
+INPUT(1), 0x00,
+END_COLLECTION(0),
+
+/* Mouse */
+USAGE_PAGE(1), 0x01,
+USAGE(1), 0x02,
+COLLECTION(1), 0x01,
+USAGE(1), 0x01,
+COLLECTION(1), 0x00,
+REPORT_ID(1), REPORT_ID_MOUSE,
+REPORT_COUNT(1), 0x03,
+REPORT_SIZE(1), 0x01,
+USAGE_PAGE(1), 0x09,
+USAGE_MIN(1), 0x1,
+USAGE_MAX(1), 0x3,
+LOGICAL_MIN(1), 0x00,
+LOGICAL_MAX(1), 0x01,
+INPUT(1), 0x02,
+REPORT_COUNT(1), 0x01,
+REPORT_SIZE(1), 0x05,
+INPUT(1), 0x01,
+REPORT_COUNT(1), 0x03,
+REPORT_SIZE(1), 0x08,
+USAGE_PAGE(1), 0x01,
+USAGE(1), 0x30,
+USAGE(1), 0x31,
+USAGE(1), 0x38,
+LOGICAL_MIN(1), 0x81,
+LOGICAL_MAX(1), 0x7f,
+INPUT(1), 0x06,
+END_COLLECTION(0),
+END_COLLECTION(0),
+};
+
+volatile bool complete;
+volatile bool configured;
+unsigned char outputReport[MAX_REPORT_SIZE];
+
+usbhid::usbhid()
+{
+ configured = false;
+ connect();
+}
+
+void usbhid::deviceEventReset()
+{
+ configured = false;
+
+ /* Must call base class */
+ usbdevice::deviceEventReset();
+}
+
+bool usbhid::requestSetConfiguration(void)
+{
+ bool result;
+
+ /* Configure IN interrupt endpoint */
+ realiseEndpoint(EP1IN, MAX_PACKET_SIZE_EP1);
+ enableEndpointEvent(EP1IN);
+
+ /* Must call base class */
+ result = usbdevice::requestSetConfiguration();
+
+ if (result)
+ {
+ /* Now configured */
+ configured = true;
+ }
+
+ return result;
+}
+
+bool usbhid::requestGetDescriptor(void)
+{
+ bool success = false;
+
+ switch (DESCRIPTOR_TYPE(transfer.setup.wValue))
+ {
+ case DEVICE_DESCRIPTOR:
+ transfer.remaining = sizeof(deviceDescriptor);
+ transfer.ptr = deviceDescriptor;
+ transfer.direction = DEVICE_TO_HOST;
+ success = true;
+ break;
+ case CONFIGURATION_DESCRIPTOR:
+ transfer.remaining = sizeof(configurationDescriptor);
+ transfer.ptr = configurationDescriptor;
+ transfer.direction = DEVICE_TO_HOST;
+ success = true;
+ break;
+ case STRING_DESCRIPTOR:
+ switch (DESCRIPTOR_INDEX(transfer.setup.wValue))
+ {
+ case STRING_OFFSET_LANGID:
+ transfer.remaining = sizeof(stringLangidDescriptor);
+ transfer.ptr = stringLangidDescriptor;
+ transfer.direction = DEVICE_TO_HOST;
+ success = true;
+ break;
+ case STRING_OFFSET_IMANUFACTURER:
+ transfer.remaining = sizeof(stringImanufacturerDescriptor);
+ transfer.ptr = stringImanufacturerDescriptor;
+ transfer.direction = DEVICE_TO_HOST;
+ success = true;
+ break;
+ case STRING_OFFSET_IPRODUCT:
+ transfer.remaining = sizeof(stringIproductDescriptor);
+ transfer.ptr = stringIproductDescriptor;
+ transfer.direction = DEVICE_TO_HOST;
+ success = true;
+ break;
+ case STRING_OFFSET_ISERIAL:
+ transfer.remaining = sizeof(stringIserialDescriptor);
+ transfer.ptr = stringIserialDescriptor;
+ transfer.direction = DEVICE_TO_HOST;
+ success = true;
+ break;
+ case STRING_OFFSET_ICONFIGURATION:
+ transfer.remaining = sizeof(stringIconfigurationDescriptor);
+ transfer.ptr = stringIconfigurationDescriptor;
+ transfer.direction = DEVICE_TO_HOST;
+ success = true;
+ break;
+ case STRING_OFFSET_IINTERFACE:
+ transfer.remaining = sizeof(stringIinterfaceDescriptor);
+ transfer.ptr = stringIinterfaceDescriptor;
+ transfer.direction = DEVICE_TO_HOST;
+ success = true;
+ break;
+ }
+ case INTERFACE_DESCRIPTOR:
+ case ENDPOINT_DESCRIPTOR:
+ /* TODO: Support is optional, not implemented here */
+ break;
+ case HID_DESCRIPTOR:
+ transfer.remaining = 0x09; /* TODO: Fix hard coded size/offset */
+ transfer.ptr = &configurationDescriptor[18];
+ transfer.direction = DEVICE_TO_HOST;
+ success = true;
+ break;
+ case REPORT_DESCRIPTOR:
+ transfer.remaining = sizeof(reportDescriptor);
+ transfer.ptr = reportDescriptor;
+ transfer.direction = DEVICE_TO_HOST;
+ success = true;
+ break;
+ default:
+ break;
+ }
+
+ return success;
+}
+
+bool usbhid::requestSetup(void)
+{
+ /* Process class requests */
+ bool success = false;
+
+ if (transfer.setup.bmRequestType.Type == CLASS_TYPE)
+ {
+ switch (transfer.setup.bRequest)
+ {
+ case SET_REPORT:
+ switch (transfer.setup.wValue & 0xff)
+ {
+ case REPORT_ID_KEYBOARD:
+ /* TODO: LED state */
+ transfer.remaining = sizeof(outputReport);
+ transfer.ptr = outputReport;
+ transfer.direction = HOST_TO_DEVICE;
+ success = true;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (success)
+ {
+ /* We've handled this request */
+ return true;
+ }
+
+ return usbdevice::requestSetup();
+}
+
+bool usbhid::sendInputReport(unsigned char id, unsigned char *data, unsigned char size)
+{
+ /* Send an Input Report */
+ /* If data is NULL an all zero report is sent */
+
+ static unsigned char report[MAX_REPORT_SIZE+1]; /* +1 for report ID */
+ unsigned char i;
+
+ if (size > MAX_REPORT_SIZE)
+ {
+ return false;
+ }
+
+ /* Add report ID */
+ report[0]=id;
+
+ /* Add report data */
+ if (data != NULL)
+ {
+ for (i=0; i<size; i++)
+ {
+ report[i+1] = *data++;
+ }
+ }
+ else
+ {
+ for (i=0; i<size; i++)
+ {
+ report[i+1] = 0;
+ }
+ }
+
+ /* Block if not configured */
+ while (!configured);
+
+ /* Send report */
+ complete = false;
+ disableEvents();
+ endpointWrite(EP1IN, report, size+1); /* +1 for report ID */
+ enableEvents();
+
+ /* Wait for completion */
+ while(!complete && configured);
+ return true;
+}
+
+void usbhid::endpointEventEP1In(void)
+{
+ complete = true;
+}
+
+bool usbhid::keyboard(char c)
+{
+ /* Send a simulated keyboard keypress. Returns true if successful. */
+ unsigned char report[8]={0,0,0,0,0,0,0,0};
+
+ report[0] = keymap[c].modifier;
+ report[2] = keymap[c].usage;
+
+ /* Key down */
+ if (!sendInputReport(REPORT_ID_KEYBOARD, report, 8))
+ {
+ return false;
+ }
+
+ /* Key up */
+ if (!sendInputReport(REPORT_ID_KEYBOARD, NULL, 8))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+bool usbhid::keyboard(char *string)
+{
+ /* Send a string of characters. Returns true if successful. */
+ do {
+ if (!keyboard(*string++))
+ {
+ return false;
+ }
+ } while (*string != '\0');
+
+ return true;
+}
+
+bool usbhid::mouse(signed char x, signed char y, unsigned char buttons, signed char wheel)
+{
+ /* Send a simulated mouse event. Returns true if successful. */
+ unsigned char report[4]={0,0,0,0};
+
+ report[0] = buttons;
+ report[1] = x;
+ report[2] = y;
+ report[3] = wheel;
+
+ if (!sendInputReport(REPORT_ID_MOUSE, report, 4))
+ {
+ return false;
+ }
+
+ return true;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/USBKeyboardMouse/usbhid.h Thu Sep 08 15:01:33 2011 +0000
@@ -0,0 +1,32 @@
+/* usbhid.h */
+/* USB HID class device */
+/* Copyright (c) Phil Wright 2008 */
+
+#ifndef USBHID_H
+#define USBHID_H
+
+#include "usbdevice.h"
+
+/* Mouse buttons */
+#define MOUSE_L (1<<0)
+#define MOUSE_M (1<<1)
+#define MOUSE_R (1<<2)
+
+class usbhid : public usbdevice
+{
+public:
+ usbhid();
+ bool keyboard(char c);
+ bool keyboard(char *string);
+ bool mouse(signed char x, signed char y, unsigned char buttons=0, signed char wheel=0);
+protected:
+ virtual bool requestSetConfiguration();
+ virtual void endpointEventEP1In(void);
+ virtual void deviceEventReset(void);
+ virtual bool requestGetDescriptor(void);
+ virtual bool requestSetup(void);
+private:
+ bool sendInputReport(unsigned char id, unsigned char *data, unsigned char size);
+};
+
+#endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Thu Sep 08 15:01:33 2011 +0000
@@ -0,0 +1,17 @@
+#include "mbed.h"
+#include "USBMouse.h"
+#include "USBKeyboard.h"
+
+DigitalOut led(LED1);
+USBMouse mouse;
+USBKeyboard keyboard;
+
+int main() {
+ while(1) {
+ mouse.move(18, 10); //moves the mouse down and to the left
+ keyboard.sendKeys("mbed"); //sends the word "foo" through the keyboard
+
+ led = !led; //cycles the LED on/off
+ wait(2); //waits 2 seconds, then repeats
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Sep 08 15:01:33 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0