1
0
Fork 0

Squashed 'tmk_core/' changes from 7967731..b9e0ea0

b9e0ea0 Merge commit '7fa9d8bdea3773d1195b04d98fcf27cf48ddd81d' as 'tool/mbed/mbed-sdk'
7fa9d8b Squashed 'tool/mbed/mbed-sdk/' content from commit 7c21ce5

git-subtree-dir: tmk_core
git-subtree-split: b9e0ea08cb940de20b3610ecdda18e9d8cd7c552
This commit is contained in:
Jun Wako 2015-04-24 16:26:14 +09:00
parent a20ef7052c
commit 1fe4406f37
4198 changed files with 2016457 additions and 0 deletions

View file

@ -0,0 +1,276 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "stdint.h"
#include "USBHAL.h"
#include "USBHID.h"
USBHID::USBHID(uint8_t output_report_length, uint8_t input_report_length, uint16_t vendor_id, uint16_t product_id, uint16_t product_release, bool connect): USBDevice(vendor_id, product_id, product_release)
{
output_length = output_report_length;
input_length = input_report_length;
if(connect) {
USBDevice::connect();
}
}
bool USBHID::send(HID_REPORT *report)
{
return write(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
}
bool USBHID::sendNB(HID_REPORT *report)
{
return writeNB(EPINT_IN, report->data, report->length, MAX_HID_REPORT_SIZE);
}
bool USBHID::read(HID_REPORT *report)
{
uint32_t bytesRead = 0;
bool result;
result = USBDevice::readEP(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
return false;
report->length = bytesRead;
return result;
}
bool USBHID::readNB(HID_REPORT *report)
{
uint32_t bytesRead = 0;
bool result;
result = USBDevice::readEP_NB(EPINT_OUT, report->data, &bytesRead, MAX_HID_REPORT_SIZE);
// if readEP_NB did not succeed, does not issue a readStart
if (!result)
return false;
report->length = bytesRead;
if(!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
return false;
return result;
}
uint16_t USBHID::reportDescLength() {
reportDesc();
return reportLength;
}
//
// Route callbacks from lower layers to class(es)
//
// Called in ISR context
// Called by USBDevice on Endpoint0 request
// This is used to handle extensions to standard requests
// and class specific requests
// Return true if class handles this request
bool USBHID::USBCallback_request() {
bool success = false;
CONTROL_TRANSFER * transfer = getTransferPtr();
uint8_t *hidDescriptor;
// Process additional standard requests
if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
{
switch (transfer->setup.bRequest)
{
case GET_DESCRIPTOR:
switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
{
case REPORT_DESCRIPTOR:
if ((reportDesc() != NULL) \
&& (reportDescLength() != 0))
{
transfer->remaining = reportDescLength();
transfer->ptr = reportDesc();
transfer->direction = DEVICE_TO_HOST;
success = true;
}
break;
case HID_DESCRIPTOR:
// Find the HID descriptor, after the configuration descriptor
hidDescriptor = findDescriptor(HID_DESCRIPTOR);
if (hidDescriptor != NULL)
{
transfer->remaining = HID_DESCRIPTOR_LENGTH;
transfer->ptr = hidDescriptor;
transfer->direction = DEVICE_TO_HOST;
success = true;
}
break;
default:
break;
}
break;
default:
break;
}
}
// Process class-specific requests
if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
{
switch (transfer->setup.bRequest)
{
case SET_REPORT:
// First byte will be used for report ID
outputReport.data[0] = transfer->setup.wValue & 0xff;
outputReport.length = transfer->setup.wLength + 1;
transfer->remaining = sizeof(outputReport.data) - 1;
transfer->ptr = &outputReport.data[1];
transfer->direction = HOST_TO_DEVICE;
transfer->notify = true;
success = true;
default:
break;
}
}
return success;
}
#define DEFAULT_CONFIGURATION (1)
// Called in ISR context
// Set configuration. Return false if the
// configuration is not supported
bool USBHID::USBCallback_setConfiguration(uint8_t configuration) {
if (configuration != DEFAULT_CONFIGURATION) {
return false;
}
// Configure endpoints > 0
addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
// We activate the endpoint to be able to recceive data
readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
return true;
}
uint8_t * USBHID::stringIinterfaceDesc() {
static uint8_t stringIinterfaceDescriptor[] = {
0x08, //bLength
STRING_DESCRIPTOR, //bDescriptorType 0x03
'H',0,'I',0,'D',0, //bString iInterface - HID
};
return stringIinterfaceDescriptor;
}
uint8_t * USBHID::stringIproductDesc() {
static uint8_t stringIproductDescriptor[] = {
0x16, //bLength
STRING_DESCRIPTOR, //bDescriptorType 0x03
'H',0,'I',0,'D',0,' ',0,'D',0,'E',0,'V',0,'I',0,'C',0,'E',0 //bString iProduct - HID device
};
return stringIproductDescriptor;
}
uint8_t * USBHID::reportDesc() {
static uint8_t reportDescriptor[] = {
0x06, LSB(0xFFAB), MSB(0xFFAB),
0x0A, LSB(0x0200), MSB(0x0200),
0xA1, 0x01, // Collection 0x01
0x75, 0x08, // report size = 8 bits
0x15, 0x00, // logical minimum = 0
0x26, 0xFF, 0x00, // logical maximum = 255
0x95, input_length, // report count
0x09, 0x01, // usage
0x81, 0x02, // Input (array)
0x95, output_length,// report count
0x09, 0x02, // usage
0x91, 0x02, // Output (array)
0xC0 // end collection
};
reportLength = sizeof(reportDescriptor);
return reportDescriptor;
}
#define DEFAULT_CONFIGURATION (1)
#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+ (1 * INTERFACE_DESCRIPTOR_LENGTH) \
+ (1 * HID_DESCRIPTOR_LENGTH) \
+ (2 * ENDPOINT_DESCRIPTOR_LENGTH))
uint8_t * USBHID::configurationDesc() {
static uint8_t configurationDescriptor[] = {
CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
CONFIGURATION_DESCRIPTOR, // bDescriptorType
LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
0x01, // bNumInterfaces
DEFAULT_CONFIGURATION, // bConfigurationValue
0x00, // iConfiguration
C_RESERVED | C_SELF_POWERED, // bmAttributes
C_POWER(0), // bMaxPower
INTERFACE_DESCRIPTOR_LENGTH, // bLength
INTERFACE_DESCRIPTOR, // bDescriptorType
0x00, // bInterfaceNumber
0x00, // bAlternateSetting
0x02, // bNumEndpoints
HID_CLASS, // bInterfaceClass
HID_SUBCLASS_NONE, // bInterfaceSubClass
HID_PROTOCOL_NONE, // bInterfaceProtocol
0x00, // iInterface
HID_DESCRIPTOR_LENGTH, // bLength
HID_DESCRIPTOR, // bDescriptorType
LSB(HID_VERSION_1_11), // bcdHID (LSB)
MSB(HID_VERSION_1_11), // bcdHID (MSB)
0x00, // bCountryCode
0x01, // bNumDescriptors
REPORT_DESCRIPTOR, // bDescriptorType
(uint8_t)(LSB(this->reportDescLength())), // wDescriptorLength (LSB)
(uint8_t)(MSB(this->reportDescLength())), // wDescriptorLength (MSB)
ENDPOINT_DESCRIPTOR_LENGTH, // bLength
ENDPOINT_DESCRIPTOR, // bDescriptorType
PHY_TO_DESC(EPINT_IN), // bEndpointAddress
E_INTERRUPT, // bmAttributes
LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
1, // bInterval (milliseconds)
ENDPOINT_DESCRIPTOR_LENGTH, // bLength
ENDPOINT_DESCRIPTOR, // bDescriptorType
PHY_TO_DESC(EPINT_OUT), // bEndpointAddress
E_INTERRUPT, // bmAttributes
LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
1, // bInterval (milliseconds)
};
return configurationDescriptor;
}

View file

@ -0,0 +1,172 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef USB_HID_H
#define USB_HID_H
/* These headers are included for child class. */
#include "USBEndpoints.h"
#include "USBDescriptor.h"
#include "USBDevice_Types.h"
#include "USBHID_Types.h"
#include "USBDevice.h"
/**
* USBHID example
* @code
* #include "mbed.h"
* #include "USBHID.h"
*
* USBHID hid;
* HID_REPORT recv;
* BusOut leds(LED1,LED2,LED3,LED4);
*
* int main(void) {
* while (1) {
* hid.read(&recv);
* leds = recv.data[0];
* }
* }
* @endcode
*/
class USBHID: public USBDevice {
public:
/**
* Constructor
*
* @param output_report_length Maximum length of a sent report (up to 64 bytes) (default: 64 bytes)
* @param input_report_length Maximum length of a received report (up to 64 bytes) (default: 64 bytes)
* @param vendor_id Your vendor_id
* @param product_id Your product_id
* @param product_release Your preoduct_release
* @param connect Connect the device
*/
USBHID(uint8_t output_report_length = 64, uint8_t input_report_length = 64, uint16_t vendor_id = 0x1234, uint16_t product_id = 0x0006, uint16_t product_release = 0x0001, bool connect = true);
/**
* Send a Report. warning: blocking
*
* @param report Report which will be sent (a report is defined by all data and the length)
* @returns true if successful
*/
bool send(HID_REPORT *report);
/**
* Send a Report. warning: non blocking
*
* @param report Report which will be sent (a report is defined by all data and the length)
* @returns true if successful
*/
bool sendNB(HID_REPORT *report);
/**
* Read a report: blocking
*
* @param report pointer to the report to fill
* @returns true if successful
*/
bool read(HID_REPORT * report);
/**
* Read a report: non blocking
*
* @param report pointer to the report to fill
* @returns true if successful
*/
bool readNB(HID_REPORT * report);
protected:
uint16_t reportLength;
/*
* Get the Report descriptor
*
* @returns pointer to the report descriptor
*/
virtual uint8_t * reportDesc();
/*
* Get the length of the report descriptor
*
* @returns the length of the report descriptor
*/
virtual uint16_t reportDescLength();
/*
* Get string product descriptor
*
* @returns pointer to the string product descriptor
*/
virtual uint8_t * stringIproductDesc();
/*
* Get string interface descriptor
*
* @returns pointer to the string interface descriptor
*/
virtual uint8_t * stringIinterfaceDesc();
/*
* Get configuration descriptor
*
* @returns pointer to the configuration descriptor
*/
virtual uint8_t * configurationDesc();
/*
* HID Report received by SET_REPORT request. Warning: Called in ISR context
* First byte of data will be the report ID
*
* @param report Data and length received
*/
virtual void HID_callbackSetReport(HID_REPORT *report){};
/*
* Called by USBDevice on Endpoint0 request. Warning: Called in ISR context
* This is used to handle extensions to standard requests
* and class specific requests
*
* @returns true if class handles this request
*/
virtual bool USBCallback_request();
/*
* Called by USBDevice layer. Set configuration of the device.
* For instance, you can add all endpoints that you need on this function.
*
* @param configuration Number of the configuration
* @returns true if class handles this request
*/
virtual bool USBCallback_setConfiguration(uint8_t configuration);
private:
HID_REPORT outputReport;
uint8_t output_length;
uint8_t input_length;
};
#endif

View file

@ -0,0 +1,91 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef USBCLASS_HID_TYPES
#define USBCLASS_HID_TYPES
#include <stdint.h>
/* */
#define HID_VERSION_1_11 (0x0111)
/* HID Class */
#define HID_CLASS (3)
#define HID_SUBCLASS_NONE (0)
#define HID_PROTOCOL_NONE (0)
/* Descriptors */
#define HID_DESCRIPTOR (33)
#define HID_DESCRIPTOR_LENGTH (0x09)
#define REPORT_DESCRIPTOR (34)
/* Class requests */
#define GET_REPORT (0x1)
#define GET_IDLE (0x2)
#define SET_REPORT (0x9)
#define SET_IDLE (0xa)
/* 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_MINIMUM(size) (0x14 | size)
#define LOGICAL_MAXIMUM(size) (0x24 | size)
#define PHYSICAL_MINIMUM(size) (0x34 | size)
#define PHYSICAL_MAXIMUM(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_MINIMUM(size) (0x18 | size)
#define USAGE_MAXIMUM(size) (0x28 | size)
#define DESIGNATOR_INDEX(size) (0x38 | size)
#define DESIGNATOR_MINIMUM(size) (0x48 | size)
#define DESIGNATOR_MAXIMUM(size) (0x58 | size)
#define STRING_INDEX(size) (0x78 | size)
#define STRING_MINIMUM(size) (0x88 | size)
#define STRING_MAXIMUM(size) (0x98 | size)
#define DELIMITER(size) (0xa8 | size)
/* HID Report */
/* Where report IDs are used the first byte of 'data' will be the */
/* report ID and 'length' will include this report ID byte. */
#define MAX_HID_REPORT_SIZE (64)
typedef struct {
uint32_t length;
uint8_t data[MAX_HID_REPORT_SIZE];
} HID_REPORT;
#endif

View file

@ -0,0 +1,553 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "stdint.h"
#include "USBKeyboard.h"
#define REPORT_ID_KEYBOARD 1
#define REPORT_ID_VOLUME 3
typedef struct {
unsigned char usage;
unsigned char modifier;
} KEYMAP;
#ifdef US_KEYBOARD
/* US keyboard (as HID standard) */
#define KEYMAP_SIZE (152)
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, KEY_SHIFT}, /* ! */
{0x34, KEY_SHIFT}, /* " */
{0x20, KEY_SHIFT}, /* # */
{0x21, KEY_SHIFT}, /* $ */
{0x22, KEY_SHIFT}, /* % */
{0x24, KEY_SHIFT}, /* & */
{0x34, 0}, /* ' */
{0x26, KEY_SHIFT}, /* ( */
{0x27, KEY_SHIFT}, /* ) */
{0x25, KEY_SHIFT}, /* * */
{0x2e, KEY_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, KEY_SHIFT}, /* : */
{0x33, 0}, /* ; */
{0x36, KEY_SHIFT}, /* < */
{0x2e, 0}, /* = */
{0x37, KEY_SHIFT}, /* > */
{0x38, KEY_SHIFT}, /* ? */
{0x1f, KEY_SHIFT}, /* @ */
{0x04, KEY_SHIFT}, /* A */
{0x05, KEY_SHIFT}, /* B */
{0x06, KEY_SHIFT}, /* C */
{0x07, KEY_SHIFT}, /* D */
{0x08, KEY_SHIFT}, /* E */
{0x09, KEY_SHIFT}, /* F */
{0x0a, KEY_SHIFT}, /* G */
{0x0b, KEY_SHIFT}, /* H */
{0x0c, KEY_SHIFT}, /* I */
{0x0d, KEY_SHIFT}, /* J */
{0x0e, KEY_SHIFT}, /* K */
{0x0f, KEY_SHIFT}, /* L */
{0x10, KEY_SHIFT}, /* M */
{0x11, KEY_SHIFT}, /* N */
{0x12, KEY_SHIFT}, /* O */
{0x13, KEY_SHIFT}, /* P */
{0x14, KEY_SHIFT}, /* Q */
{0x15, KEY_SHIFT}, /* R */
{0x16, KEY_SHIFT}, /* S */
{0x17, KEY_SHIFT}, /* T */
{0x18, KEY_SHIFT}, /* U */
{0x19, KEY_SHIFT}, /* V */
{0x1a, KEY_SHIFT}, /* W */
{0x1b, KEY_SHIFT}, /* X */
{0x1c, KEY_SHIFT}, /* Y */
{0x1d, KEY_SHIFT}, /* Z */
{0x2f, 0}, /* [ */
{0x31, 0}, /* \ */
{0x30, 0}, /* ] */
{0x23, KEY_SHIFT}, /* ^ */
{0x2d, KEY_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, KEY_SHIFT}, /* { */
{0x31, KEY_SHIFT}, /* | */
{0x30, KEY_SHIFT}, /* } */
{0x35, KEY_SHIFT}, /* ~ */
{0,0}, /* DEL */
{0x3a, 0}, /* F1 */
{0x3b, 0}, /* F2 */
{0x3c, 0}, /* F3 */
{0x3d, 0}, /* F4 */
{0x3e, 0}, /* F5 */
{0x3f, 0}, /* F6 */
{0x40, 0}, /* F7 */
{0x41, 0}, /* F8 */
{0x42, 0}, /* F9 */
{0x43, 0}, /* F10 */
{0x44, 0}, /* F11 */
{0x45, 0}, /* F12 */
{0x46, 0}, /* PRINT_SCREEN */
{0x47, 0}, /* SCROLL_LOCK */
{0x39, 0}, /* CAPS_LOCK */
{0x53, 0}, /* NUM_LOCK */
{0x49, 0}, /* INSERT */
{0x4a, 0}, /* HOME */
{0x4b, 0}, /* PAGE_UP */
{0x4e, 0}, /* PAGE_DOWN */
{0x4f, 0}, /* RIGHT_ARROW */
{0x50, 0}, /* LEFT_ARROW */
{0x51, 0}, /* DOWN_ARROW */
{0x52, 0}, /* UP_ARROW */
};
#else
/* UK keyboard */
#define KEYMAP_SIZE (152)
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, KEY_SHIFT}, /* ! */
{0x1f, KEY_SHIFT}, /* " */
{0x32, 0}, /* # */
{0x21, KEY_SHIFT}, /* $ */
{0x22, KEY_SHIFT}, /* % */
{0x24, KEY_SHIFT}, /* & */
{0x34, 0}, /* ' */
{0x26, KEY_SHIFT}, /* ( */
{0x27, KEY_SHIFT}, /* ) */
{0x25, KEY_SHIFT}, /* * */
{0x2e, KEY_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, KEY_SHIFT}, /* : */
{0x33, 0}, /* ; */
{0x36, KEY_SHIFT}, /* < */
{0x2e, 0}, /* = */
{0x37, KEY_SHIFT}, /* > */
{0x38, KEY_SHIFT}, /* ? */
{0x34, KEY_SHIFT}, /* @ */
{0x04, KEY_SHIFT}, /* A */
{0x05, KEY_SHIFT}, /* B */
{0x06, KEY_SHIFT}, /* C */
{0x07, KEY_SHIFT}, /* D */
{0x08, KEY_SHIFT}, /* E */
{0x09, KEY_SHIFT}, /* F */
{0x0a, KEY_SHIFT}, /* G */
{0x0b, KEY_SHIFT}, /* H */
{0x0c, KEY_SHIFT}, /* I */
{0x0d, KEY_SHIFT}, /* J */
{0x0e, KEY_SHIFT}, /* K */
{0x0f, KEY_SHIFT}, /* L */
{0x10, KEY_SHIFT}, /* M */
{0x11, KEY_SHIFT}, /* N */
{0x12, KEY_SHIFT}, /* O */
{0x13, KEY_SHIFT}, /* P */
{0x14, KEY_SHIFT}, /* Q */
{0x15, KEY_SHIFT}, /* R */
{0x16, KEY_SHIFT}, /* S */
{0x17, KEY_SHIFT}, /* T */
{0x18, KEY_SHIFT}, /* U */
{0x19, KEY_SHIFT}, /* V */
{0x1a, KEY_SHIFT}, /* W */
{0x1b, KEY_SHIFT}, /* X */
{0x1c, KEY_SHIFT}, /* Y */
{0x1d, KEY_SHIFT}, /* Z */
{0x2f, 0}, /* [ */
{0x64, 0}, /* \ */
{0x30, 0}, /* ] */
{0x23, KEY_SHIFT}, /* ^ */
{0x2d, KEY_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, KEY_SHIFT}, /* { */
{0x64, KEY_SHIFT}, /* | */
{0x30, KEY_SHIFT}, /* } */
{0x32, KEY_SHIFT}, /* ~ */
{0,0}, /* DEL */
{0x3a, 0}, /* F1 */
{0x3b, 0}, /* F2 */
{0x3c, 0}, /* F3 */
{0x3d, 0}, /* F4 */
{0x3e, 0}, /* F5 */
{0x3f, 0}, /* F6 */
{0x40, 0}, /* F7 */
{0x41, 0}, /* F8 */
{0x42, 0}, /* F9 */
{0x43, 0}, /* F10 */
{0x44, 0}, /* F11 */
{0x45, 0}, /* F12 */
{0x46, 0}, /* PRINT_SCREEN */
{0x47, 0}, /* SCROLL_LOCK */
{0x39, 0}, /* CAPS_LOCK */
{0x53, 0}, /* NUM_LOCK */
{0x49, 0}, /* INSERT */
{0x4a, 0}, /* HOME */
{0x4b, 0}, /* PAGE_UP */
{0x4e, 0}, /* PAGE_DOWN */
{0x4f, 0}, /* RIGHT_ARROW */
{0x50, 0}, /* LEFT_ARROW */
{0x51, 0}, /* DOWN_ARROW */
{0x52, 0}, /* UP_ARROW */
};
#endif
uint8_t * USBKeyboard::reportDesc() {
static uint8_t reportDescriptor[] = {
USAGE_PAGE(1), 0x01, // Generic Desktop
USAGE(1), 0x06, // Keyboard
COLLECTION(1), 0x01, // Application
REPORT_ID(1), REPORT_ID_KEYBOARD,
USAGE_PAGE(1), 0x07, // Key Codes
USAGE_MINIMUM(1), 0xE0,
USAGE_MAXIMUM(1), 0xE7,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0x01,
REPORT_SIZE(1), 0x01,
REPORT_COUNT(1), 0x08,
INPUT(1), 0x02, // Data, Variable, Absolute
REPORT_COUNT(1), 0x01,
REPORT_SIZE(1), 0x08,
INPUT(1), 0x01, // Constant
REPORT_COUNT(1), 0x05,
REPORT_SIZE(1), 0x01,
USAGE_PAGE(1), 0x08, // LEDs
USAGE_MINIMUM(1), 0x01,
USAGE_MAXIMUM(1), 0x05,
OUTPUT(1), 0x02, // Data, Variable, Absolute
REPORT_COUNT(1), 0x01,
REPORT_SIZE(1), 0x03,
OUTPUT(1), 0x01, // Constant
REPORT_COUNT(1), 0x06,
REPORT_SIZE(1), 0x08,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0x65,
USAGE_PAGE(1), 0x07, // Key Codes
USAGE_MINIMUM(1), 0x00,
USAGE_MAXIMUM(1), 0x65,
INPUT(1), 0x00, // Data, Array
END_COLLECTION(0),
// Media Control
USAGE_PAGE(1), 0x0C,
USAGE(1), 0x01,
COLLECTION(1), 0x01,
REPORT_ID(1), REPORT_ID_VOLUME,
USAGE_PAGE(1), 0x0C,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0x01,
REPORT_SIZE(1), 0x01,
REPORT_COUNT(1), 0x07,
USAGE(1), 0xB5, // Next Track
USAGE(1), 0xB6, // Previous Track
USAGE(1), 0xB7, // Stop
USAGE(1), 0xCD, // Play / Pause
USAGE(1), 0xE2, // Mute
USAGE(1), 0xE9, // Volume Up
USAGE(1), 0xEA, // Volume Down
INPUT(1), 0x02, // Input (Data, Variable, Absolute)
REPORT_COUNT(1), 0x01,
INPUT(1), 0x01,
END_COLLECTION(0),
};
reportLength = sizeof(reportDescriptor);
return reportDescriptor;
}
bool USBKeyboard::EPINT_OUT_callback() {
uint32_t bytesRead = 0;
uint8_t led[65];
USBDevice::readEP(EPINT_OUT, led, &bytesRead, MAX_HID_REPORT_SIZE);
// we take led[1] because led[0] is the report ID
lock_status = led[1] & 0x07;
// We activate the endpoint to be able to recceive data
if (!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
return false;
return true;
}
uint8_t USBKeyboard::lockStatus() {
return lock_status;
}
int USBKeyboard::_putc(int c) {
return keyCode(c, keymap[c].modifier);
}
bool USBKeyboard::keyCode(uint8_t key, uint8_t modifier) {
// Send a simulated keyboard keypress. Returns true if successful.
HID_REPORT report;
report.data[0] = REPORT_ID_KEYBOARD;
report.data[1] = modifier;
report.data[2] = 0;
report.data[3] = keymap[key].usage;
report.data[4] = 0;
report.data[5] = 0;
report.data[6] = 0;
report.data[7] = 0;
report.data[8] = 0;
report.length = 9;
if (!send(&report)) {
return false;
}
report.data[1] = 0;
report.data[3] = 0;
if (!send(&report)) {
return false;
}
return true;
}
bool USBKeyboard::mediaControl(MEDIA_KEY key) {
HID_REPORT report;
report.data[0] = REPORT_ID_VOLUME;
report.data[1] = (1 << key) & 0x7f;
report.length = 2;
if (!send(&report)) {
return false;
}
report.data[0] = REPORT_ID_VOLUME;
report.data[1] = 0;
report.length = 2;
return send(&report);
}
#define DEFAULT_CONFIGURATION (1)
#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+ (1 * INTERFACE_DESCRIPTOR_LENGTH) \
+ (1 * HID_DESCRIPTOR_LENGTH) \
+ (2 * ENDPOINT_DESCRIPTOR_LENGTH))
uint8_t * USBKeyboard::configurationDesc() {
static uint8_t configurationDescriptor[] = {
CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
CONFIGURATION_DESCRIPTOR, // bDescriptorType
LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
0x01, // bNumInterfaces
DEFAULT_CONFIGURATION, // bConfigurationValue
0x00, // iConfiguration
C_RESERVED | C_SELF_POWERED, // bmAttributes
C_POWER(0), // bMaxPowerHello World from Mbed
INTERFACE_DESCRIPTOR_LENGTH, // bLength
INTERFACE_DESCRIPTOR, // bDescriptorType
0x00, // bInterfaceNumber
0x00, // bAlternateSetting
0x02, // bNumEndpoints
HID_CLASS, // bInterfaceClass
1, // bInterfaceSubClass
1, // bInterfaceProtocol (keyboard)
0x00, // iInterface
HID_DESCRIPTOR_LENGTH, // bLength
HID_DESCRIPTOR, // bDescriptorType
LSB(HID_VERSION_1_11), // bcdHID (LSB)
MSB(HID_VERSION_1_11), // bcdHID (MSB)
0x00, // bCountryCode
0x01, // bNumDescriptors
REPORT_DESCRIPTOR, // bDescriptorType
(uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
(uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB)
ENDPOINT_DESCRIPTOR_LENGTH, // bLength
ENDPOINT_DESCRIPTOR, // bDescriptorType
PHY_TO_DESC(EPINT_IN), // bEndpointAddress
E_INTERRUPT, // bmAttributes
LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
1, // bInterval (milliseconds)
ENDPOINT_DESCRIPTOR_LENGTH, // bLength
ENDPOINT_DESCRIPTOR, // bDescriptorType
PHY_TO_DESC(EPINT_OUT), // bEndpointAddress
E_INTERRUPT, // bmAttributes
LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
1, // bInterval (milliseconds)
};
return configurationDescriptor;
}

View file

@ -0,0 +1,183 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef USBKEYBOARD_H
#define USBKEYBOARD_H
#include "USBHID.h"
#include "Stream.h"
/* Modifiers */
enum MODIFIER_KEY {
KEY_CTRL = 1,
KEY_SHIFT = 2,
KEY_ALT = 4,
};
enum MEDIA_KEY {
KEY_NEXT_TRACK, /*!< next Track Button */
KEY_PREVIOUS_TRACK, /*!< Previous track Button */
KEY_STOP, /*!< Stop Button */
KEY_PLAY_PAUSE, /*!< Play/Pause Button */
KEY_MUTE, /*!< Mute Button */
KEY_VOLUME_UP, /*!< Volume Up Button */
KEY_VOLUME_DOWN, /*!< Volume Down Button */
};
enum FUNCTION_KEY {
KEY_F1 = 128, /* F1 key */
KEY_F2, /* F2 key */
KEY_F3, /* F3 key */
KEY_F4, /* F4 key */
KEY_F5, /* F5 key */
KEY_F6, /* F6 key */
KEY_F7, /* F7 key */
KEY_F8, /* F8 key */
KEY_F9, /* F9 key */
KEY_F10, /* F10 key */
KEY_F11, /* F11 key */
KEY_F12, /* F12 key */
KEY_PRINT_SCREEN, /* Print Screen key */
KEY_SCROLL_LOCK, /* Scroll lock */
KEY_CAPS_LOCK, /* caps lock */
KEY_NUM_LOCK, /* num lock */
KEY_INSERT, /* Insert key */
KEY_HOME, /* Home key */
KEY_PAGE_UP, /* Page Up key */
KEY_PAGE_DOWN, /* Page Down key */
RIGHT_ARROW, /* Right arrow */
LEFT_ARROW, /* Left arrow */
DOWN_ARROW, /* Down arrow */
UP_ARROW, /* Up arrow */
};
/**
* USBKeyboard example
* @code
*
* #include "mbed.h"
* #include "USBKeyboard.h"
*
* USBKeyboard key;
*
* int main(void)
* {
* while (1)
* {
* key.printf("Hello World\r\n");
* wait(1);
* }
* }
*
* @endcode
*/
class USBKeyboard: public USBHID, public Stream {
public:
/**
* Constructor
*
*
* @param leds Leds bus: first: NUM_LOCK, second: CAPS_LOCK, third: SCROLL_LOCK
* @param vendor_id Your vendor_id (default: 0x1235)
* @param product_id Your product_id (default: 0x0050)
* @param product_release Your preoduct_release (default: 0x0001)
*
*/
USBKeyboard(uint16_t vendor_id = 0x1235, uint16_t product_id = 0x0050, uint16_t product_release = 0x0001):
USBHID(0, 0, vendor_id, product_id, product_release, false) {
lock_status = 0;
connect();
};
/**
* To send a character defined by a modifier(CTRL, SHIFT, ALT) and the key
*
* @code
* //To send CTRL + s (save)
* keyboard.keyCode('s', KEY_CTRL);
* @endcode
*
* @param modifier bit 0: KEY_CTRL, bit 1: KEY_SHIFT, bit 2: KEY_ALT (default: 0)
* @param key character to send
* @returns true if there is no error, false otherwise
*/
bool keyCode(uint8_t key, uint8_t modifier = 0);
/**
* Send a character
*
* @param c character to be sent
* @returns true if there is no error, false otherwise
*/
virtual int _putc(int c);
/**
* Control media keys
*
* @param key media key pressed (KEY_NEXT_TRACK, KEY_PREVIOUS_TRACK, KEY_STOP, KEY_PLAY_PAUSE, KEY_MUTE, KEY_VOLUME_UP, KEY_VOLUME_DOWN)
* @returns true if there is no error, false otherwise
*/
bool mediaControl(MEDIA_KEY key);
/*
* To define the report descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
*
* @returns pointer to the report descriptor
*/
virtual uint8_t * reportDesc();
/*
* Called when a data is received on the OUT endpoint. Useful to switch on LED of LOCK keys
*
* @returns if handle by subclass, return true
*/
virtual bool EPINT_OUT_callback();
/**
* Read status of lock keys. Useful to switch-on/off leds according to key pressed. Only the first three bits of the result is important:
* - First bit: NUM_LOCK
* - Second bit: CAPS_LOCK
* - Third bit: SCROLL_LOCK
*
* @returns status of lock keys
*/
uint8_t lockStatus();
protected:
/*
* Get configuration descriptor
*
* @returns pointer to the configuration descriptor
*/
virtual uint8_t * configurationDesc();
private:
//dummy otherwise it doesn,t compile (we must define all methods of an abstract class)
virtual int _getc() {
return -1;
};
uint8_t lock_status;
};
#endif

View file

@ -0,0 +1,245 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "stdint.h"
#include "USBMouse.h"
bool USBMouse::update(int16_t x, int16_t y, uint8_t button, int8_t z) {
switch (mouse_type) {
case REL_MOUSE:
while (x > 127) {
if (!mouseSend(127, 0, button, z)) return false;
x = x - 127;
}
while (x < -128) {
if (!mouseSend(-128, 0, button, z)) return false;
x = x + 128;
}
while (y > 127) {
if (!mouseSend(0, 127, button, z)) return false;
y = y - 127;
}
while (y < -128) {
if (!mouseSend(0, -128, button, z)) return false;
y = y + 128;
}
return mouseSend(x, y, button, z);
case ABS_MOUSE:
HID_REPORT report;
report.data[0] = x & 0xff;
report.data[1] = (x >> 8) & 0xff;
report.data[2] = y & 0xff;
report.data[3] = (y >> 8) & 0xff;
report.data[4] = -z;
report.data[5] = button & 0x07;
report.length = 6;
return send(&report);
default:
return false;
}
}
bool USBMouse::mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z) {
HID_REPORT report;
report.data[0] = buttons & 0x07;
report.data[1] = x;
report.data[2] = y;
report.data[3] = -z; // >0 to scroll down, <0 to scroll up
report.length = 4;
return send(&report);
}
bool USBMouse::move(int16_t x, int16_t y) {
return update(x, y, button, 0);
}
bool USBMouse::scroll(int8_t z) {
return update(0, 0, button, z);
}
bool USBMouse::doubleClick() {
if (!click(MOUSE_LEFT))
return false;
wait(0.1);
return click(MOUSE_LEFT);
}
bool USBMouse::click(uint8_t button) {
if (!update(0, 0, button, 0))
return false;
wait(0.01);
return update(0, 0, 0, 0);
}
bool USBMouse::press(uint8_t button_) {
button = button_ & 0x07;
return update(0, 0, button, 0);
}
bool USBMouse::release(uint8_t button_) {
button = (button & (~button_)) & 0x07;
return update(0, 0, button, 0);
}
uint8_t * USBMouse::reportDesc() {
if (mouse_type == REL_MOUSE) {
static uint8_t reportDescriptor[] = {
USAGE_PAGE(1), 0x01, // Genric Desktop
USAGE(1), 0x02, // Mouse
COLLECTION(1), 0x01, // Application
USAGE(1), 0x01, // Pointer
COLLECTION(1), 0x00, // Physical
REPORT_COUNT(1), 0x03,
REPORT_SIZE(1), 0x01,
USAGE_PAGE(1), 0x09, // Buttons
USAGE_MINIMUM(1), 0x1,
USAGE_MAXIMUM(1), 0x3,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(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, // X
USAGE(1), 0x31, // Y
USAGE(1), 0x38, // scroll
LOGICAL_MINIMUM(1), 0x81,
LOGICAL_MAXIMUM(1), 0x7f,
INPUT(1), 0x06, // Relative data
END_COLLECTION(0),
END_COLLECTION(0),
};
reportLength = sizeof(reportDescriptor);
return reportDescriptor;
} else if (mouse_type == ABS_MOUSE) {
static uint8_t reportDescriptor[] = {
USAGE_PAGE(1), 0x01, // Generic Desktop
USAGE(1), 0x02, // Mouse
COLLECTION(1), 0x01, // Application
USAGE(1), 0x01, // Pointer
COLLECTION(1), 0x00, // Physical
USAGE_PAGE(1), 0x01, // Generic Desktop
USAGE(1), 0x30, // X
USAGE(1), 0x31, // Y
LOGICAL_MINIMUM(1), 0x00, // 0
LOGICAL_MAXIMUM(2), 0xff, 0x7f, // 32767
REPORT_SIZE(1), 0x10,
REPORT_COUNT(1), 0x02,
INPUT(1), 0x02, // Data, Variable, Absolute
USAGE_PAGE(1), 0x01, // Generic Desktop
USAGE(1), 0x38, // scroll
LOGICAL_MINIMUM(1), 0x81, // -127
LOGICAL_MAXIMUM(1), 0x7f, // 127
REPORT_SIZE(1), 0x08,
REPORT_COUNT(1), 0x01,
INPUT(1), 0x06, // Data, Variable, Relative
USAGE_PAGE(1), 0x09, // Buttons
USAGE_MINIMUM(1), 0x01,
USAGE_MAXIMUM(1), 0x03,
LOGICAL_MINIMUM(1), 0x00, // 0
LOGICAL_MAXIMUM(1), 0x01, // 1
REPORT_COUNT(1), 0x03,
REPORT_SIZE(1), 0x01,
INPUT(1), 0x02, // Data, Variable, Absolute
REPORT_COUNT(1), 0x01,
REPORT_SIZE(1), 0x05,
INPUT(1), 0x01, // Constant
END_COLLECTION(0),
END_COLLECTION(0)
};
reportLength = sizeof(reportDescriptor);
return reportDescriptor;
}
return NULL;
}
#define DEFAULT_CONFIGURATION (1)
#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+ (1 * INTERFACE_DESCRIPTOR_LENGTH) \
+ (1 * HID_DESCRIPTOR_LENGTH) \
+ (2 * ENDPOINT_DESCRIPTOR_LENGTH))
uint8_t * USBMouse::configurationDesc() {
static uint8_t configurationDescriptor[] = {
CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
CONFIGURATION_DESCRIPTOR, // bDescriptorType
LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
0x01, // bNumInterfaces
DEFAULT_CONFIGURATION, // bConfigurationValue
0x00, // iConfiguration
C_RESERVED | C_SELF_POWERED, // bmAttributes
C_POWER(0), // bMaxPowerHello World from Mbed
INTERFACE_DESCRIPTOR_LENGTH, // bLength
INTERFACE_DESCRIPTOR, // bDescriptorType
0x00, // bInterfaceNumber
0x00, // bAlternateSetting
0x02, // bNumEndpoints
HID_CLASS, // bInterfaceClass
1, // bInterfaceSubClass
2, // bInterfaceProtocol (mouse)
0x00, // iInterface
HID_DESCRIPTOR_LENGTH, // bLength
HID_DESCRIPTOR, // bDescriptorType
LSB(HID_VERSION_1_11), // bcdHID (LSB)
MSB(HID_VERSION_1_11), // bcdHID (MSB)
0x00, // bCountryCode
0x01, // bNumDescriptors
REPORT_DESCRIPTOR, // bDescriptorType
(uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
(uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB)
ENDPOINT_DESCRIPTOR_LENGTH, // bLength
ENDPOINT_DESCRIPTOR, // bDescriptorType
PHY_TO_DESC(EPINT_IN), // bEndpointAddress
E_INTERRUPT, // bmAttributes
LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
1, // bInterval (milliseconds)
ENDPOINT_DESCRIPTOR_LENGTH, // bLength
ENDPOINT_DESCRIPTOR, // bDescriptorType
PHY_TO_DESC(EPINT_OUT), // bEndpointAddress
E_INTERRUPT, // bmAttributes
LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
1, // bInterval (milliseconds)
};
return configurationDescriptor;
}

View file

@ -0,0 +1,209 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef USBMOUSE_H
#define USBMOUSE_H
#include "USBHID.h"
#define REPORT_ID_MOUSE 2
/* Common usage */
enum MOUSE_BUTTON
{
MOUSE_LEFT = 1,
MOUSE_RIGHT = 2,
MOUSE_MIDDLE = 4,
};
/* X and Y limits */
/* These values do not directly map to screen pixels */
/* Zero may be interpreted as meaning 'no movement' */
#define X_MIN_ABS (1) /*!< Minimum value on x-axis */
#define Y_MIN_ABS (1) /*!< Minimum value on y-axis */
#define X_MAX_ABS (0x7fff) /*!< Maximum value on x-axis */
#define Y_MAX_ABS (0x7fff) /*!< Maximum value on y-axis */
#define X_MIN_REL (-127) /*!< The maximum value that we can move to the left on the x-axis */
#define Y_MIN_REL (-127) /*!< The maximum value that we can move up on the y-axis */
#define X_MAX_REL (127) /*!< The maximum value that we can move to the right on the x-axis */
#define Y_MAX_REL (127) /*!< The maximum value that we can move down on the y-axis */
enum MOUSE_TYPE
{
ABS_MOUSE,
REL_MOUSE,
};
/**
*
* USBMouse example
* @code
* #include "mbed.h"
* #include "USBMouse.h"
*
* USBMouse mouse;
*
* int main(void)
* {
* while (1)
* {
* mouse.move(20, 0);
* wait(0.5);
* }
* }
*
* @endcode
*
*
* @code
* #include "mbed.h"
* #include "USBMouse.h"
* #include <math.h>
*
* USBMouse mouse(ABS_MOUSE);
*
* int main(void)
* {
* uint16_t x_center = (X_MAX_ABS - X_MIN_ABS)/2;
* uint16_t y_center = (Y_MAX_ABS - Y_MIN_ABS)/2;
* uint16_t x_screen = 0;
* uint16_t y_screen = 0;
*
* uint32_t x_origin = x_center;
* uint32_t y_origin = y_center;
* uint32_t radius = 5000;
* uint32_t angle = 0;
*
* while (1)
* {
* x_screen = x_origin + cos((double)angle*3.14/180.0)*radius;
* y_screen = y_origin + sin((double)angle*3.14/180.0)*radius;
*
* mouse.move(x_screen, y_screen);
* angle += 3;
* wait(0.01);
* }
* }
*
* @endcode
*/
class USBMouse: public USBHID
{
public:
/**
* Constructor
*
* @param mouse_type Mouse type: ABS_MOUSE (absolute mouse) or REL_MOUSE (relative mouse) (default: REL_MOUSE)
* @param vendor_id Your vendor_id (default: 0x1234)
* @param product_id Your product_id (default: 0x0001)
* @param product_release Your preoduct_release (default: 0x0001)
*
*/
USBMouse(MOUSE_TYPE mouse_type = REL_MOUSE, uint16_t vendor_id = 0x1234, uint16_t product_id = 0x0001, uint16_t product_release = 0x0001):
USBHID(0, 0, vendor_id, product_id, product_release, false)
{
button = 0;
this->mouse_type = mouse_type;
connect();
};
/**
* Write a state of the mouse
*
* @param x x-axis position
* @param y y-axis position
* @param buttons buttons state (first bit represents MOUSE_LEFT, second bit MOUSE_RIGHT and third bit MOUSE_MIDDLE)
* @param z wheel state (>0 to scroll down, <0 to scroll up)
* @returns true if there is no error, false otherwise
*/
bool update(int16_t x, int16_t y, uint8_t buttons, int8_t z);
/**
* Move the cursor to (x, y)
*
* @param x-axis position
* @param y-axis position
* @returns true if there is no error, false otherwise
*/
bool move(int16_t x, int16_t y);
/**
* Press one or several buttons
*
* @param button button state (ex: press(MOUSE_LEFT))
* @returns true if there is no error, false otherwise
*/
bool press(uint8_t button);
/**
* Release one or several buttons
*
* @param button button state (ex: release(MOUSE_LEFT))
* @returns true if there is no error, false otherwise
*/
bool release(uint8_t button);
/**
* Double click (MOUSE_LEFT)
*
* @returns true if there is no error, false otherwise
*/
bool doubleClick();
/**
* Click
*
* @param button state of the buttons ( ex: clic(MOUSE_LEFT))
* @returns true if there is no error, false otherwise
*/
bool click(uint8_t button);
/**
* Scrolling
*
* @param z value of the wheel (>0 to go down, <0 to go up)
* @returns true if there is no error, false otherwise
*/
bool scroll(int8_t z);
/*
* To define the report descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
*
* @returns pointer to the report descriptor
*/
virtual uint8_t * reportDesc();
protected:
/*
* Get configuration descriptor
*
* @returns pointer to the configuration descriptor
*/
virtual uint8_t * configurationDesc();
private:
MOUSE_TYPE mouse_type;
uint8_t button;
bool mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z);
};
#endif

View file

@ -0,0 +1,706 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "stdint.h"
#include "USBMouseKeyboard.h"
typedef struct {
unsigned char usage;
unsigned char modifier;
} KEYMAP;
#ifdef US_KEYBOARD
/* US keyboard (as HID standard) */
#define KEYMAP_SIZE (152)
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, KEY_SHIFT}, /* ! */
{0x34, KEY_SHIFT}, /* " */
{0x20, KEY_SHIFT}, /* # */
{0x21, KEY_SHIFT}, /* $ */
{0x22, KEY_SHIFT}, /* % */
{0x24, KEY_SHIFT}, /* & */
{0x34, 0}, /* ' */
{0x26, KEY_SHIFT}, /* ( */
{0x27, KEY_SHIFT}, /* ) */
{0x25, KEY_SHIFT}, /* * */
{0x2e, KEY_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, KEY_SHIFT}, /* : */
{0x33, 0}, /* ; */
{0x36, KEY_SHIFT}, /* < */
{0x2e, 0}, /* = */
{0x37, KEY_SHIFT}, /* > */
{0x38, KEY_SHIFT}, /* ? */
{0x1f, KEY_SHIFT}, /* @ */
{0x04, KEY_SHIFT}, /* A */
{0x05, KEY_SHIFT}, /* B */
{0x06, KEY_SHIFT}, /* C */
{0x07, KEY_SHIFT}, /* D */
{0x08, KEY_SHIFT}, /* E */
{0x09, KEY_SHIFT}, /* F */
{0x0a, KEY_SHIFT}, /* G */
{0x0b, KEY_SHIFT}, /* H */
{0x0c, KEY_SHIFT}, /* I */
{0x0d, KEY_SHIFT}, /* J */
{0x0e, KEY_SHIFT}, /* K */
{0x0f, KEY_SHIFT}, /* L */
{0x10, KEY_SHIFT}, /* M */
{0x11, KEY_SHIFT}, /* N */
{0x12, KEY_SHIFT}, /* O */
{0x13, KEY_SHIFT}, /* P */
{0x14, KEY_SHIFT}, /* Q */
{0x15, KEY_SHIFT}, /* R */
{0x16, KEY_SHIFT}, /* S */
{0x17, KEY_SHIFT}, /* T */
{0x18, KEY_SHIFT}, /* U */
{0x19, KEY_SHIFT}, /* V */
{0x1a, KEY_SHIFT}, /* W */
{0x1b, KEY_SHIFT}, /* X */
{0x1c, KEY_SHIFT}, /* Y */
{0x1d, KEY_SHIFT}, /* Z */
{0x2f, 0}, /* [ */
{0x31, 0}, /* \ */
{0x30, 0}, /* ] */
{0x23, KEY_SHIFT}, /* ^ */
{0x2d, KEY_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, KEY_SHIFT}, /* { */
{0x31, KEY_SHIFT}, /* | */
{0x30, KEY_SHIFT}, /* } */
{0x35, KEY_SHIFT}, /* ~ */
{0,0}, /* DEL */
{0x3a, 0}, /* F1 */
{0x3b, 0}, /* F2 */
{0x3c, 0}, /* F3 */
{0x3d, 0}, /* F4 */
{0x3e, 0}, /* F5 */
{0x3f, 0}, /* F6 */
{0x40, 0}, /* F7 */
{0x41, 0}, /* F8 */
{0x42, 0}, /* F9 */
{0x43, 0}, /* F10 */
{0x44, 0}, /* F11 */
{0x45, 0}, /* F12 */
{0x46, 0}, /* PRINT_SCREEN */
{0x47, 0}, /* SCROLL_LOCK */
{0x39, 0}, /* CAPS_LOCK */
{0x53, 0}, /* NUM_LOCK */
{0x49, 0}, /* INSERT */
{0x4a, 0}, /* HOME */
{0x4b, 0}, /* PAGE_UP */
{0x4e, 0}, /* PAGE_DOWN */
{0x4f, 0}, /* RIGHT_ARROW */
{0x50, 0}, /* LEFT_ARROW */
{0x51, 0}, /* DOWN_ARROW */
{0x52, 0}, /* UP_ARROW */
};
#else
/* UK keyboard */
#define KEYMAP_SIZE (152)
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, KEY_SHIFT}, /* ! */
{0x1f, KEY_SHIFT}, /* " */
{0x32, 0}, /* # */
{0x21, KEY_SHIFT}, /* $ */
{0x22, KEY_SHIFT}, /* % */
{0x24, KEY_SHIFT}, /* & */
{0x34, 0}, /* ' */
{0x26, KEY_SHIFT}, /* ( */
{0x27, KEY_SHIFT}, /* ) */
{0x25, KEY_SHIFT}, /* * */
{0x2e, KEY_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, KEY_SHIFT}, /* : */
{0x33, 0}, /* ; */
{0x36, KEY_SHIFT}, /* < */
{0x2e, 0}, /* = */
{0x37, KEY_SHIFT}, /* > */
{0x38, KEY_SHIFT}, /* ? */
{0x34, KEY_SHIFT}, /* @ */
{0x04, KEY_SHIFT}, /* A */
{0x05, KEY_SHIFT}, /* B */
{0x06, KEY_SHIFT}, /* C */
{0x07, KEY_SHIFT}, /* D */
{0x08, KEY_SHIFT}, /* E */
{0x09, KEY_SHIFT}, /* F */
{0x0a, KEY_SHIFT}, /* G */
{0x0b, KEY_SHIFT}, /* H */
{0x0c, KEY_SHIFT}, /* I */
{0x0d, KEY_SHIFT}, /* J */
{0x0e, KEY_SHIFT}, /* K */
{0x0f, KEY_SHIFT}, /* L */
{0x10, KEY_SHIFT}, /* M */
{0x11, KEY_SHIFT}, /* N */
{0x12, KEY_SHIFT}, /* O */
{0x13, KEY_SHIFT}, /* P */
{0x14, KEY_SHIFT}, /* Q */
{0x15, KEY_SHIFT}, /* R */
{0x16, KEY_SHIFT}, /* S */
{0x17, KEY_SHIFT}, /* T */
{0x18, KEY_SHIFT}, /* U */
{0x19, KEY_SHIFT}, /* V */
{0x1a, KEY_SHIFT}, /* W */
{0x1b, KEY_SHIFT}, /* X */
{0x1c, KEY_SHIFT}, /* Y */
{0x1d, KEY_SHIFT}, /* Z */
{0x2f, 0}, /* [ */
{0x64, 0}, /* \ */
{0x30, 0}, /* ] */
{0x23, KEY_SHIFT}, /* ^ */
{0x2d, KEY_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, KEY_SHIFT}, /* { */
{0x64, KEY_SHIFT}, /* | */
{0x30, KEY_SHIFT}, /* } */
{0x32, KEY_SHIFT}, /* ~ */
{0,0}, /* DEL */
{0x3a, 0}, /* F1 */
{0x3b, 0}, /* F2 */
{0x3c, 0}, /* F3 */
{0x3d, 0}, /* F4 */
{0x3e, 0}, /* F5 */
{0x3f, 0}, /* F6 */
{0x40, 0}, /* F7 */
{0x41, 0}, /* F8 */
{0x42, 0}, /* F9 */
{0x43, 0}, /* F10 */
{0x44, 0}, /* F11 */
{0x45, 0}, /* F12 */
{0x46, 0}, /* PRINT_SCREEN */
{0x47, 0}, /* SCROLL_LOCK */
{0x39, 0}, /* CAPS_LOCK */
{0x53, 0}, /* NUM_LOCK */
{0x49, 0}, /* INSERT */
{0x4a, 0}, /* HOME */
{0x4b, 0}, /* PAGE_UP */
{0x4e, 0}, /* PAGE_DOWN */
{0x4f, 0}, /* RIGHT_ARROW */
{0x50, 0}, /* LEFT_ARROW */
{0x51, 0}, /* DOWN_ARROW */
{0x52, 0}, /* UP_ARROW */
};
#endif
uint8_t * USBMouseKeyboard::reportDesc() {
if (mouse_type == REL_MOUSE) {
static uint8_t reportDescriptor[] = {
// Keyboard
USAGE_PAGE(1), 0x01,
USAGE(1), 0x06,
COLLECTION(1), 0x01,
REPORT_ID(1), REPORT_ID_KEYBOARD,
USAGE_PAGE(1), 0x07,
USAGE_MINIMUM(1), 0xE0,
USAGE_MAXIMUM(1), 0xE7,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(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_MINIMUM(1), 0x01,
USAGE_MAXIMUM(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_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(2), 0xff, 0x00,
USAGE_PAGE(1), 0x07,
USAGE_MINIMUM(1), 0x00,
USAGE_MAXIMUM(2), 0xff, 0x00,
INPUT(1), 0x00,
END_COLLECTION(0),
// Mouse
USAGE_PAGE(1), 0x01, // Generic Desktop
USAGE(1), 0x02, // Mouse
COLLECTION(1), 0x01, // Application
USAGE(1), 0x01, // Pointer
COLLECTION(1), 0x00, // Physical
REPORT_ID(1), REPORT_ID_MOUSE,
REPORT_COUNT(1), 0x03,
REPORT_SIZE(1), 0x01,
USAGE_PAGE(1), 0x09, // Buttons
USAGE_MINIMUM(1), 0x1,
USAGE_MAXIMUM(1), 0x3,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(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, // X
USAGE(1), 0x31, // Y
USAGE(1), 0x38, // scroll
LOGICAL_MINIMUM(1), 0x81,
LOGICAL_MAXIMUM(1), 0x7f,
INPUT(1), 0x06,
END_COLLECTION(0),
END_COLLECTION(0),
// Media Control
USAGE_PAGE(1), 0x0C,
USAGE(1), 0x01,
COLLECTION(1), 0x01,
REPORT_ID(1), REPORT_ID_VOLUME,
USAGE_PAGE(1), 0x0C,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0x01,
REPORT_SIZE(1), 0x01,
REPORT_COUNT(1), 0x07,
USAGE(1), 0xB5, // Next Track
USAGE(1), 0xB6, // Previous Track
USAGE(1), 0xB7, // Stop
USAGE(1), 0xCD, // Play / Pause
USAGE(1), 0xE2, // Mute
USAGE(1), 0xE9, // Volume Up
USAGE(1), 0xEA, // Volume Down
INPUT(1), 0x02, // Input (Data, Variable, Absolute)
REPORT_COUNT(1), 0x01,
INPUT(1), 0x01,
END_COLLECTION(0),
};
reportLength = sizeof(reportDescriptor);
return reportDescriptor;
} else if (mouse_type == ABS_MOUSE) {
static uint8_t reportDescriptor[] = {
// Keyboard
USAGE_PAGE(1), 0x01,
USAGE(1), 0x06,
COLLECTION(1), 0x01,
REPORT_ID(1), REPORT_ID_KEYBOARD,
USAGE_PAGE(1), 0x07,
USAGE_MINIMUM(1), 0xE0,
USAGE_MAXIMUM(1), 0xE7,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(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_MINIMUM(1), 0x01,
USAGE_MAXIMUM(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_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(2), 0xff, 0x00,
USAGE_PAGE(1), 0x07,
USAGE_MINIMUM(1), 0x00,
USAGE_MAXIMUM(2), 0xff, 0x00,
INPUT(1), 0x00,
END_COLLECTION(0),
// Mouse
USAGE_PAGE(1), 0x01, // Generic Desktop
USAGE(1), 0x02, // Mouse
COLLECTION(1), 0x01, // Application
USAGE(1), 0x01, // Pointer
COLLECTION(1), 0x00, // Physical
REPORT_ID(1), REPORT_ID_MOUSE,
USAGE_PAGE(1), 0x01, // Generic Desktop
USAGE(1), 0x30, // X
USAGE(1), 0x31, // Y
LOGICAL_MINIMUM(1), 0x00, // 0
LOGICAL_MAXIMUM(2), 0xff, 0x7f, // 32767
REPORT_SIZE(1), 0x10,
REPORT_COUNT(1), 0x02,
INPUT(1), 0x02, // Data, Variable, Absolute
USAGE_PAGE(1), 0x01, // Generic Desktop
USAGE(1), 0x38, // scroll
LOGICAL_MINIMUM(1), 0x81, // -127
LOGICAL_MAXIMUM(1), 0x7f, // 127
REPORT_SIZE(1), 0x08,
REPORT_COUNT(1), 0x01,
INPUT(1), 0x06, // Data, Variable, Relative
USAGE_PAGE(1), 0x09, // Buttons
USAGE_MINIMUM(1), 0x01,
USAGE_MAXIMUM(1), 0x03,
LOGICAL_MINIMUM(1), 0x00, // 0
LOGICAL_MAXIMUM(1), 0x01, // 1
REPORT_COUNT(1), 0x03,
REPORT_SIZE(1), 0x01,
INPUT(1), 0x02, // Data, Variable, Absolute
REPORT_COUNT(1), 0x01,
REPORT_SIZE(1), 0x05,
INPUT(1), 0x01, // Constant
END_COLLECTION(0),
END_COLLECTION(0),
// Media Control
USAGE_PAGE(1), 0x0C,
USAGE(1), 0x01,
COLLECTION(1), 0x01,
REPORT_ID(1), REPORT_ID_VOLUME,
USAGE_PAGE(1), 0x0C,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0x01,
REPORT_SIZE(1), 0x01,
REPORT_COUNT(1), 0x07,
USAGE(1), 0xB5, // Next Track
USAGE(1), 0xB6, // Previous Track
USAGE(1), 0xB7, // Stop
USAGE(1), 0xCD, // Play / Pause
USAGE(1), 0xE2, // Mute
USAGE(1), 0xE9, // Volume Up
USAGE(1), 0xEA, // Volume Down
INPUT(1), 0x02, // Input (Data, Variable, Absolute)
REPORT_COUNT(1), 0x01,
INPUT(1), 0x01,
END_COLLECTION(0),
};
reportLength = sizeof(reportDescriptor);
return reportDescriptor;
}
return NULL;
}
bool USBMouseKeyboard::EPINT_OUT_callback() {
uint32_t bytesRead = 0;
uint8_t led[65];
USBDevice::readEP(EPINT_OUT, led, &bytesRead, MAX_HID_REPORT_SIZE);
// we take led[1] because led[0] is the report ID
lock_status = led[1] & 0x07;
// We activate the endpoint to be able to recceive data
if (!readStart(EPINT_OUT, MAX_HID_REPORT_SIZE))
return false;
return true;
}
uint8_t USBMouseKeyboard::lockStatus() {
return lock_status;
}
bool USBMouseKeyboard::update(int16_t x, int16_t y, uint8_t button, int8_t z) {
switch (mouse_type) {
case REL_MOUSE:
while (x > 127) {
if (!mouseSend(127, 0, button, z)) return false;
x = x - 127;
}
while (x < -128) {
if (!mouseSend(-128, 0, button, z)) return false;
x = x + 128;
}
while (y > 127) {
if (!mouseSend(0, 127, button, z)) return false;
y = y - 127;
}
while (y < -128) {
if (!mouseSend(0, -128, button, z)) return false;
y = y + 128;
}
return mouseSend(x, y, button, z);
case ABS_MOUSE:
HID_REPORT report;
report.data[0] = REPORT_ID_MOUSE;
report.data[1] = x & 0xff;
report.data[2] = (x >> 8) & 0xff;
report.data[3] = y & 0xff;
report.data[4] = (y >> 8) & 0xff;
report.data[5] = -z;
report.data[6] = button & 0x07;
report.length = 7;
return send(&report);
default:
return false;
}
}
bool USBMouseKeyboard::mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z) {
HID_REPORT report;
report.data[0] = REPORT_ID_MOUSE;
report.data[1] = buttons & 0x07;
report.data[2] = x;
report.data[3] = y;
report.data[4] = -z; // >0 to scroll down, <0 to scroll up
report.length = 5;
return send(&report);
}
bool USBMouseKeyboard::move(int16_t x, int16_t y) {
return update(x, y, button, 0);
}
bool USBMouseKeyboard::scroll(int8_t z) {
return update(0, 0, button, z);
}
bool USBMouseKeyboard::doubleClick() {
if (!click(MOUSE_LEFT))
return false;
wait(0.1);
return click(MOUSE_LEFT);
}
bool USBMouseKeyboard::click(uint8_t button) {
if (!update(0, 0, button, 0))
return false;
wait(0.01);
return update(0, 0, 0, 0);
}
bool USBMouseKeyboard::press(uint8_t button_) {
button = button_ & 0x07;
return update(0, 0, button, 0);
}
bool USBMouseKeyboard::release(uint8_t button_) {
button = (button & (~button_)) & 0x07;
return update(0, 0, button, 0);
}
int USBMouseKeyboard::_putc(int c) {
return keyCode(c, keymap[c].modifier);
}
bool USBMouseKeyboard::keyCode(uint8_t key, uint8_t modifier) {
// Send a simulated keyboard keypress. Returns true if successful.
HID_REPORT report;
report.data[0] = REPORT_ID_KEYBOARD;
report.data[1] = modifier;
report.data[2] = 0;
report.data[3] = keymap[key].usage;
report.data[4] = 0;
report.data[5] = 0;
report.data[6] = 0;
report.data[7] = 0;
report.data[8] = 0;
report.length = 9;
if (!send(&report)) {
return false;
}
report.data[1] = 0;
report.data[3] = 0;
if (!send(&report)) {
return false;
}
return true;
}
bool USBMouseKeyboard::mediaControl(MEDIA_KEY key) {
HID_REPORT report;
report.data[0] = REPORT_ID_VOLUME;
report.data[1] = (1 << key) & 0x7f;
report.length = 2;
send(&report);
report.data[0] = REPORT_ID_VOLUME;
report.data[1] = 0;
report.length = 2;
return send(&report);
}

View file

@ -0,0 +1,220 @@
/* Copyright (c) 2010-2011 mbed.org, MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
* and associated documentation files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef USBMOUSEKEYBOARD_H
#define USBMOUSEKEYBOARD_H
#define REPORT_ID_KEYBOARD 1
#define REPORT_ID_MOUSE 2
#define REPORT_ID_VOLUME 3
#include "USBMouse.h"
#include "USBKeyboard.h"
#include "Stream.h"
#include "USBHID.h"
/**
* USBMouseKeyboard example
* @code
*
* #include "mbed.h"
* #include "USBMouseKeyboard.h"
*
* USBMouseKeyboard key_mouse;
*
* int main(void)
* {
* while(1)
* {
* key_mouse.move(20, 0);
* key_mouse.printf("Hello From MBED\r\n");
* wait(1);
* }
* }
* @endcode
*
*
* @code
*
* #include "mbed.h"
* #include "USBMouseKeyboard.h"
*
* USBMouseKeyboard key_mouse(ABS_MOUSE);
*
* int main(void)
* {
* while(1)
* {
* key_mouse.move(X_MAX_ABS/2, Y_MAX_ABS/2);
* key_mouse.printf("Hello from MBED\r\n");
* wait(1);
* }
* }
* @endcode
*/
class USBMouseKeyboard: public USBHID, public Stream
{
public:
/**
* Constructor
*
* @param mouse_type Mouse type: ABS_MOUSE (absolute mouse) or REL_MOUSE (relative mouse) (default: REL_MOUSE)
* @param leds Leds bus: first: NUM_LOCK, second: CAPS_LOCK, third: SCROLL_LOCK
* @param vendor_id Your vendor_id (default: 0x1234)
* @param product_id Your product_id (default: 0x0001)
* @param product_release Your preoduct_release (default: 0x0001)
*
*/
USBMouseKeyboard(MOUSE_TYPE mouse_type = REL_MOUSE, uint16_t vendor_id = 0x0021, uint16_t product_id = 0x0011, uint16_t product_release = 0x0001):
USBHID(0, 0, vendor_id, product_id, product_release, false)
{
lock_status = 0;
button = 0;
this->mouse_type = mouse_type;
connect();
};
/**
* Write a state of the mouse
*
* @param x x-axis position
* @param y y-axis position
* @param buttons buttons state (first bit represents MOUSE_LEFT, second bit MOUSE_RIGHT and third bit MOUSE_MIDDLE)
* @param z wheel state (>0 to scroll down, <0 to scroll up)
* @returns true if there is no error, false otherwise
*/
bool update(int16_t x, int16_t y, uint8_t buttons, int8_t z);
/**
* Move the cursor to (x, y)
*
* @param x x-axis position
* @param y y-axis position
* @returns true if there is no error, false otherwise
*/
bool move(int16_t x, int16_t y);
/**
* Press one or several buttons
*
* @param button button state (ex: press(MOUSE_LEFT))
* @returns true if there is no error, false otherwise
*/
bool press(uint8_t button);
/**
* Release one or several buttons
*
* @param button button state (ex: release(MOUSE_LEFT))
* @returns true if there is no error, false otherwise
*/
bool release(uint8_t button);
/**
* Double click (MOUSE_LEFT)
*
* @returns true if there is no error, false otherwise
*/
bool doubleClick();
/**
* Click
*
* @param button state of the buttons ( ex: clic(MOUSE_LEFT))
* @returns true if there is no error, false otherwise
*/
bool click(uint8_t button);
/**
* Scrolling
*
* @param z value of the wheel (>0 to go down, <0 to go up)
* @returns true if there is no error, false otherwise
*/
bool scroll(int8_t z);
/**
* To send a character defined by a modifier(CTRL, SHIFT, ALT) and the key
*
* @code
* //To send CTRL + s (save)
* keyboard.keyCode('s', KEY_CTRL);
* @endcode
*
* @param modifier bit 0: KEY_CTRL, bit 1: KEY_SHIFT, bit 2: KEY_ALT (default: 0)
* @param key character to send
* @returns true if there is no error, false otherwise
*/
bool keyCode(uint8_t key, uint8_t modifier = 0);
/**
* Send a character
*
* @param c character to be sent
* @returns true if there is no error, false otherwise
*/
virtual int _putc(int c);
/**
* Control media keys
*
* @param key media key pressed (KEY_NEXT_TRACK, KEY_PREVIOUS_TRACK, KEY_STOP, KEY_PLAY_PAUSE, KEY_MUTE, KEY_VOLUME_UP, KEY_VOLUME_DOWN)
* @returns true if there is no error, false otherwise
*/
bool mediaControl(MEDIA_KEY key);
/**
* Read status of lock keys. Useful to switch-on/off leds according to key pressed. Only the first three bits of the result is important:
* - First bit: NUM_LOCK
* - Second bit: CAPS_LOCK
* - Third bit: SCROLL_LOCK
*
* @returns status of lock keys
*/
uint8_t lockStatus();
/*
* To define the report descriptor. Warning: this method has to store the length of the report descriptor in reportLength.
*
* @returns pointer to the report descriptor
*/
virtual uint8_t * reportDesc();
/*
* Called when a data is received on the OUT endpoint. Useful to switch on LED of LOCK keys
*
* @returns if handle by subclass, return true
*/
virtual bool EPINT_OUT_callback();
private:
bool mouseWrite(int8_t x, int8_t y, uint8_t buttons, int8_t z);
MOUSE_TYPE mouse_type;
uint8_t button;
bool mouseSend(int8_t x, int8_t y, uint8_t buttons, int8_t z);
uint8_t lock_status;
//dummy otherwise it doesn't compile (we must define all methods of an abstract class)
virtual int _getc() { return -1;}
};
#endif