diff --git a/build/shared/examples/09.USB/Keyboard/KeyboardLogout/KeyboardLogout.ino b/build/shared/examples/09.USB/Keyboard/KeyboardLogout/KeyboardLogout.ino index 9358ae8ff3b..1e468085341 100644 --- a/build/shared/examples/09.USB/Keyboard/KeyboardLogout/KeyboardLogout.ino +++ b/build/shared/examples/09.USB/Keyboard/KeyboardLogout/KeyboardLogout.ino @@ -29,6 +29,9 @@ #define WINDOWS 1 #define UBUNTU 2 +#include "Keyboard.h" +#include "HID.h" + // change this to match your platform: int platform = OSX; diff --git a/build/shared/examples/09.USB/Keyboard/KeyboardMessage/KeyboardMessage.ino b/build/shared/examples/09.USB/Keyboard/KeyboardMessage/KeyboardMessage.ino index 40a91abbec9..b6405bb9967 100644 --- a/build/shared/examples/09.USB/Keyboard/KeyboardMessage/KeyboardMessage.ino +++ b/build/shared/examples/09.USB/Keyboard/KeyboardMessage/KeyboardMessage.ino @@ -20,6 +20,9 @@ http://www.arduino.cc/en/Tutorial/KeyboardMessage */ +#include "Keyboard.h" +#include "HID.h" + const int buttonPin = 4; // input pin for pushbutton int previousButtonState = HIGH; // for checking the state of a pushButton int counter = 0; // button push counter diff --git a/build/shared/examples/09.USB/Keyboard/KeyboardReprogram/KeyboardReprogram.ino b/build/shared/examples/09.USB/Keyboard/KeyboardReprogram/KeyboardReprogram.ino index bc486a044e8..807480489a0 100644 --- a/build/shared/examples/09.USB/Keyboard/KeyboardReprogram/KeyboardReprogram.ino +++ b/build/shared/examples/09.USB/Keyboard/KeyboardReprogram/KeyboardReprogram.ino @@ -27,6 +27,9 @@ http://www.arduino.cc/en/Tutorial/KeyboardReprogram */ +#include "Keyboard.h" +#include "HID.h" + // use this option for OSX. // Comment it out if using Windows or Linux: char ctrlKey = KEY_LEFT_GUI; diff --git a/build/shared/examples/09.USB/Keyboard/KeyboardSerial/KeyboardSerial.ino b/build/shared/examples/09.USB/Keyboard/KeyboardSerial/KeyboardSerial.ino index 2f98c9116a0..3c2a6838d90 100644 --- a/build/shared/examples/09.USB/Keyboard/KeyboardSerial/KeyboardSerial.ino +++ b/build/shared/examples/09.USB/Keyboard/KeyboardSerial/KeyboardSerial.ino @@ -19,6 +19,9 @@ http://www.arduino.cc/en/Tutorial/KeyboardSerial */ +#include "Keyboard.h" +#include "HID.h" + void setup() { // open the serial port: Serial.begin(9600); diff --git a/build/shared/examples/09.USB/KeyboardAndMouseControl/KeyboardAndMouseControl.ino b/build/shared/examples/09.USB/KeyboardAndMouseControl/KeyboardAndMouseControl.ino index b41512ac3bc..01f60fe88fc 100644 --- a/build/shared/examples/09.USB/KeyboardAndMouseControl/KeyboardAndMouseControl.ino +++ b/build/shared/examples/09.USB/KeyboardAndMouseControl/KeyboardAndMouseControl.ino @@ -21,6 +21,10 @@ */ +#include "Keyboard.h" +#include "Mouse.h" +#include "HID.h" + // set pin numbers for the five buttons: const int upButton = 2; const int downButton = 3; diff --git a/build/shared/examples/09.USB/Mouse/ButtonMouseControl/ButtonMouseControl.ino b/build/shared/examples/09.USB/Mouse/ButtonMouseControl/ButtonMouseControl.ino index 3a5629fb167..9b9aef0337c 100644 --- a/build/shared/examples/09.USB/Mouse/ButtonMouseControl/ButtonMouseControl.ino +++ b/build/shared/examples/09.USB/Mouse/ButtonMouseControl/ButtonMouseControl.ino @@ -24,6 +24,9 @@ */ +#include "Mouse.h" +#include "HID.h" + // set pin numbers for the five buttons: const int upButton = 2; const int downButton = 3; diff --git a/build/shared/examples/09.USB/Mouse/JoystickMouseControl/JoystickMouseControl.ino b/build/shared/examples/09.USB/Mouse/JoystickMouseControl/JoystickMouseControl.ino index 1fcf269cd7f..b59b2b76ab3 100644 --- a/build/shared/examples/09.USB/Mouse/JoystickMouseControl/JoystickMouseControl.ino +++ b/build/shared/examples/09.USB/Mouse/JoystickMouseControl/JoystickMouseControl.ino @@ -28,6 +28,9 @@ */ +#include "Mouse.h" +#include "HID.h" + // set pin numbers for switch, joystick axes, and LED: const int switchPin = 2; // switch to turn on and off mouse control const int mouseButton = 3; // input pin for the mouse pushButton diff --git a/hardware/arduino/avr/cores/arduino/CDC.cpp b/hardware/arduino/avr/cores/arduino/CDC.cpp index 5d4f2a08086..d694a2d2ca8 100644 --- a/hardware/arduino/avr/cores/arduino/CDC.cpp +++ b/hardware/arduino/avr/cores/arduino/CDC.cpp @@ -20,7 +20,6 @@ #include #if defined(USBCON) -#ifdef CDC_ENABLED typedef struct { @@ -54,13 +53,13 @@ const CDCDescriptor _cdcInterface = D_ENDPOINT(USB_ENDPOINT_IN (CDC_ENDPOINT_IN ),USB_ENDPOINT_TYPE_BULK,0x40,0) }; -int WEAK CDC_GetInterface(u8* interfaceNum) +int CDC_GetInterface(u8* interfaceNum) { interfaceNum[0] += 2; // uses 2 return USB_SendControl(TRANSFER_PGM,&_cdcInterface,sizeof(_cdcInterface)); } -bool WEAK CDC_Setup(Setup& setup) +bool CDC_Setup(USBSetup& setup) { u8 r = setup.bRequest; u8 requestType = setup.bmRequestType; @@ -96,6 +95,7 @@ bool WEAK CDC_Setup(Setup& setup) // We check DTR state to determine if host port is open (bit 0 of lineState). if (1200 == _usbLineInfo.dwDTERate && (_usbLineInfo.lineState & 0x01) == 0) { + *(uint16_t *)(RAMEND-1) = *(uint16_t *)0x0800; *(uint16_t *)0x0800 = 0x7777; wdt_enable(WDTO_120MS); } @@ -108,7 +108,7 @@ bool WEAK CDC_Setup(Setup& setup) wdt_disable(); wdt_reset(); - *(uint16_t *)0x0800 = 0x0; + *(uint16_t *)0x0800 = *(uint16_t *)(RAMEND-1); } } return true; @@ -207,5 +207,4 @@ Serial_::operator bool() { Serial_ Serial; -#endif #endif /* if defined(USBCON) */ diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp new file mode 100644 index 00000000000..857a27fe9d7 --- /dev/null +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.cpp @@ -0,0 +1,100 @@ +/* + PluggableUSB.cpp + Copyright (c) 2015 Arduino LLC + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "USBAPI.h" +#include "PluggableUSB.h" + +#if defined(USBCON) +#ifdef PLUGGABLE_USB_ENABLED + +#define MAX_MODULES 6 + +static u8 lastIf = CDC_ACM_INTERFACE + CDC_INTERFACE_COUNT; +static u8 lastEp = CDC_FIRST_ENDPOINT + CDC_ENPOINT_COUNT; + +extern u8 _initEndpoints[]; + +//PUSBCallbacks cbs[MAX_MODULES]; +static u8 modules_count = 0; + +static PUSBListNode* rootNode = NULL; + +int PUSB_GetInterface(u8* interfaceNum) +{ + int ret = 0; + PUSBListNode* node = rootNode; + for (u8 i=0; icb->getInterface(interfaceNum); + node = node->next; + } + return ret; +} + +int PUSB_GetDescriptor(int8_t t) +{ + int ret = 0; + PUSBListNode* node = rootNode; + for (u8 i=0; icb->getDescriptor(t); + node = node->next; + } + return ret; +} + +bool PUSB_Setup(USBSetup& setup, u8 j) +{ + bool ret = false; + PUSBListNode* node = rootNode; + for (u8 i=0; icb->setup(setup, j); + node = node->next; + } + return ret; +} + +int8_t PUSB_AddFunction(PUSBListNode *node, u8* interface) +{ + if (modules_count >= MAX_MODULES) { + return 0; + } + + if (modules_count == 0) { + rootNode = node; + } else { + PUSBListNode *current = rootNode; + while(current->next != NULL) { + current = current->next; + } + current->next = node; + } + + *interface = lastIf; + lastIf += node->cb->numInterfaces; + for ( u8 i = 0; i< node->cb->numEndpoints; i++) { + _initEndpoints[lastEp] = node->cb->endpointType[i]; + lastEp++; + } + modules_count++; + return lastEp - node->cb->numEndpoints; + // restart USB layer??? +} + +#endif + +#endif /* if defined(USBCON) */ \ No newline at end of file diff --git a/hardware/arduino/avr/cores/arduino/PluggableUSB.h b/hardware/arduino/avr/cores/arduino/PluggableUSB.h new file mode 100644 index 00000000000..d89040eb41d --- /dev/null +++ b/hardware/arduino/avr/cores/arduino/PluggableUSB.h @@ -0,0 +1,63 @@ +/* + PluggableUSB.h + Copyright (c) 2015 Arduino LLC + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef PUSB_h +#define PUSB_h + +#include "USBAPI.h" +#include + +#if defined(USBCON) + +typedef struct __attribute__((packed)) +{ + bool (*setup)(USBSetup& setup, u8 i); + int (*getInterface)(u8* interfaceNum); + int (*getDescriptor)(int8_t t); + int8_t numEndpoints; + int8_t numInterfaces; + uint8_t *endpointType; +} PUSBCallbacks; + +typedef struct +{ + u8 interface; + u8 firstEndpoint; +} PUSBReturn; + +class PUSBListNode { +public: + PUSBListNode *next = NULL; + PUSBCallbacks *cb; + PUSBListNode(PUSBCallbacks *ncb) {cb = ncb;} +}; + +int8_t PUSB_AddFunction(PUSBListNode *node, u8 *interface); + +int PUSB_GetInterface(u8* interfaceNum); + +int PUSB_GetDescriptor(int8_t t); + +bool PUSB_Setup(USBSetup& setup, u8 i); + +void PUSB_Begin(); + +#endif + +#endif diff --git a/hardware/arduino/avr/cores/arduino/USBAPI.h b/hardware/arduino/avr/cores/arduino/USBAPI.h index 5837b3e1130..4abd9616f33 100644 --- a/hardware/arduino/avr/cores/arduino/USBAPI.h +++ b/hardware/arduino/avr/cores/arduino/USBAPI.h @@ -41,6 +41,14 @@ typedef unsigned long u32; //================================================================================ // USB +#define EP_TYPE_CONTROL 0x00 +#define EP_TYPE_BULK_IN 0x81 +#define EP_TYPE_BULK_OUT 0x80 +#define EP_TYPE_INTERRUPT_IN 0xC1 +#define EP_TYPE_INTERRUPT_OUT 0xC0 +#define EP_TYPE_ISOCHRONOUS_IN 0x41 +#define EP_TYPE_ISOCHRONOUS_OUT 0x40 + class USBDevice_ { public: @@ -50,6 +58,7 @@ class USBDevice_ void attach(); void detach(); // Serial port goes down too... void poll(); + bool wakeupHost(); // returns false, when wakeup cannot be processed }; extern USBDevice_ USBDevice; @@ -99,98 +108,7 @@ extern Serial_ Serial; //================================================================================ //================================================================================ -// Mouse - -#define MOUSE_LEFT 1 -#define MOUSE_RIGHT 2 -#define MOUSE_MIDDLE 4 -#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) - -class Mouse_ -{ -private: - uint8_t _buttons; - void buttons(uint8_t b); -public: - Mouse_(void); - void begin(void); - void end(void); - void click(uint8_t b = MOUSE_LEFT); - void move(signed char x, signed char y, signed char wheel = 0); - void press(uint8_t b = MOUSE_LEFT); // press LEFT by default - void release(uint8_t b = MOUSE_LEFT); // release LEFT by default - bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default -}; -extern Mouse_ Mouse; - -//================================================================================ -//================================================================================ -// Keyboard - -#define KEY_LEFT_CTRL 0x80 -#define KEY_LEFT_SHIFT 0x81 -#define KEY_LEFT_ALT 0x82 -#define KEY_LEFT_GUI 0x83 -#define KEY_RIGHT_CTRL 0x84 -#define KEY_RIGHT_SHIFT 0x85 -#define KEY_RIGHT_ALT 0x86 -#define KEY_RIGHT_GUI 0x87 - -#define KEY_UP_ARROW 0xDA -#define KEY_DOWN_ARROW 0xD9 -#define KEY_LEFT_ARROW 0xD8 -#define KEY_RIGHT_ARROW 0xD7 -#define KEY_BACKSPACE 0xB2 -#define KEY_TAB 0xB3 -#define KEY_RETURN 0xB0 -#define KEY_ESC 0xB1 -#define KEY_INSERT 0xD1 -#define KEY_DELETE 0xD4 -#define KEY_PAGE_UP 0xD3 -#define KEY_PAGE_DOWN 0xD6 -#define KEY_HOME 0xD2 -#define KEY_END 0xD5 -#define KEY_CAPS_LOCK 0xC1 -#define KEY_F1 0xC2 -#define KEY_F2 0xC3 -#define KEY_F3 0xC4 -#define KEY_F4 0xC5 -#define KEY_F5 0xC6 -#define KEY_F6 0xC7 -#define KEY_F7 0xC8 -#define KEY_F8 0xC9 -#define KEY_F9 0xCA -#define KEY_F10 0xCB -#define KEY_F11 0xCC -#define KEY_F12 0xCD - -// Low level key report: up to 6 keys and shift, ctrl etc at once -typedef struct -{ - uint8_t modifiers; - uint8_t reserved; - uint8_t keys[6]; -} KeyReport; - -class Keyboard_ : public Print -{ -private: - KeyReport _keyReport; - void sendReport(KeyReport* keys); -public: - Keyboard_(void); - void begin(void); - void end(void); - virtual size_t write(uint8_t k); - virtual size_t press(uint8_t k); - virtual size_t release(uint8_t k); - virtual void releaseAll(void); -}; -extern Keyboard_ Keyboard; - -//================================================================================ -//================================================================================ -// Low level API +// Low level API typedef struct { @@ -200,16 +118,7 @@ typedef struct uint8_t wValueH; uint16_t wIndex; uint16_t wLength; -} Setup; - -//================================================================================ -//================================================================================ -// HID 'Driver' - -int HID_GetInterface(uint8_t* interfaceNum); -int HID_GetDescriptor(int i); -bool HID_Setup(Setup& setup); -void HID_SendReport(uint8_t id, const void* data, int len); +} USBSetup; //================================================================================ //================================================================================ @@ -217,7 +126,7 @@ void HID_SendReport(uint8_t id, const void* data, int len); int MSC_GetInterface(uint8_t* interfaceNum); int MSC_GetDescriptor(int i); -bool MSC_Setup(Setup& setup); +bool MSC_Setup(USBSetup& setup); bool MSC_Data(uint8_t rx,uint8_t tx); //================================================================================ @@ -226,7 +135,7 @@ bool MSC_Data(uint8_t rx,uint8_t tx); int CDC_GetInterface(uint8_t* interfaceNum); int CDC_GetDescriptor(int i); -bool CDC_Setup(Setup& setup); +bool CDC_Setup(USBSetup& setup); //================================================================================ //================================================================================ diff --git a/hardware/arduino/avr/cores/arduino/USBCore.cpp b/hardware/arduino/avr/cores/arduino/USBCore.cpp index b4f7bed7e86..8237ccb2c47 100644 --- a/hardware/arduino/avr/cores/arduino/USBCore.cpp +++ b/hardware/arduino/avr/cores/arduino/USBCore.cpp @@ -17,17 +17,10 @@ */ #include "USBAPI.h" +#include "PluggableUSB.h" #if defined(USBCON) -#define EP_TYPE_CONTROL 0x00 -#define EP_TYPE_BULK_IN 0x81 -#define EP_TYPE_BULK_OUT 0x80 -#define EP_TYPE_INTERRUPT_IN 0xC1 -#define EP_TYPE_INTERRUPT_OUT 0xC0 -#define EP_TYPE_ISOCHRONOUS_IN 0x41 -#define EP_TYPE_ISOCHRONOUS_OUT 0x40 - /** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */ #define TX_RX_LED_PULSE_MS 100 volatile u8 TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */ @@ -40,7 +33,7 @@ extern const u16 STRING_LANGUAGE[] PROGMEM; extern const u8 STRING_PRODUCT[] PROGMEM; extern const u8 STRING_MANUFACTURER[] PROGMEM; extern const DeviceDescriptor USB_DeviceDescriptor PROGMEM; -extern const DeviceDescriptor USB_DeviceDescriptorA PROGMEM; +extern const DeviceDescriptor USB_DeviceDescriptorB PROGMEM; const u16 STRING_LANGUAGE[2] = { (3<<8) | (2+2), @@ -72,23 +65,21 @@ const u8 STRING_PRODUCT[] PROGMEM = USB_PRODUCT; const u8 STRING_MANUFACTURER[] PROGMEM = USB_MANUFACTURER; -#ifdef CDC_ENABLED #define DEVICE_CLASS 0x02 -#else -#define DEVICE_CLASS 0x00 -#endif // DEVICE DESCRIPTOR const DeviceDescriptor USB_DeviceDescriptor = D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1); -const DeviceDescriptor USB_DeviceDescriptorA = - D_DEVICE(DEVICE_CLASS,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1); +const DeviceDescriptor USB_DeviceDescriptorB = + D_DEVICE(0xEF,0x02,0x01,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1); //================================================================== //================================================================== volatile u8 _usbConfiguration = 0; +volatile u8 _usbCurrentStatus = 0; // meaning of bits see usb_20.pdf, Figure 9-4. Information Returned by a GetStatus() Request to a Device +volatile u8 _usbSuspendState = 0; // copy of UDINT to check SUSPI and WAKEUPI bits static inline void WaitIN(void) { @@ -317,19 +308,19 @@ int USB_Send(u8 ep, const void* d, int len) return r; } -extern const u8 _initEndpoints[] PROGMEM; -const u8 _initEndpoints[] = +u8 _initEndpoints[] = { 0, -#ifdef CDC_ENABLED EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN -#endif -#ifdef HID_ENABLED - EP_TYPE_INTERRUPT_IN // HID_ENDPOINT_INT +#ifdef PLUGGABLE_USB_ENABLED + //allocate 3 endpoints and remove const so they can be changed by the user + 0, + 0, + 0, #endif }; @@ -340,7 +331,7 @@ static void InitEP(u8 index, u8 type, u8 size) { UENUM = index; - UECONX = 1; + UECONX = (1< 0 ? true : false); + } #endif const u8* desc_addr = 0; @@ -497,7 +485,7 @@ bool SendDescriptor(Setup& setup) { if (setup.wLength == 8) _cdcComposite = 1; - desc_addr = _cdcComposite ? (const u8*)&USB_DeviceDescriptorA : (const u8*)&USB_DeviceDescriptor; + desc_addr = _cdcComposite ? (const u8*)&USB_DeviceDescriptorB : (const u8*)&USB_DeviceDescriptor; } else if (USB_STRING_DESCRIPTOR_TYPE == t) { @@ -529,7 +517,7 @@ ISR(USB_COM_vect) if (!ReceivedSetupInt()) return; - Setup setup; + USBSetup setup; Recv((u8*)&setup,8); ClearSetupInt(); @@ -544,16 +532,37 @@ ISR(USB_COM_vect) { // Standard Requests u8 r = setup.bRequest; + u16 wValue = setup.wValueL | (setup.wValueH << 8); if (GET_STATUS == r) { - Send8(0); // TODO - Send8(0); + if (requestType == (REQUEST_DEVICETOHOST | REQUEST_STANDARD | REQUEST_DEVICE)) + { + Send8(_usbCurrentStatus); + Send8(0); + } + else + { + // TODO: handle the HALT state of an endpoint here + // see "Figure 9-6. Information Returned by a GetStatus() Request to an Endpoint" in usb_20.pdf for more information + Send8(0); + Send8(0); + } } else if (CLEAR_FEATURE == r) { + if((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE)) + && (wValue == DEVICE_REMOTE_WAKEUP)) + { + _usbCurrentStatus &= ~FEATURE_REMOTE_WAKEUP_ENABLED; + } } else if (SET_FEATURE == r) { + if((requestType == (REQUEST_HOSTTODEVICE | REQUEST_STANDARD | REQUEST_DEVICE)) + && (wValue == DEVICE_REMOTE_WAKEUP)) + { + _usbCurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED; + } } else if (SET_ADDRESS == r) { @@ -609,11 +618,73 @@ void USB_Flush(u8 ep) ReleaseTX(); } +static inline void USB_ClockDisable() +{ + USBCON = (USBCON & ~(1<> 8) + +#define RAWHID_USAGE_PAGE 0xFFC0 +#define RAWHID_USAGE 0x0C00 +#define RAWHID_TX_SIZE 64 +#define RAWHID_RX_SIZE 64 + +static u8 HID_INTERFACE; + +HIDDescriptor _hidInterface; + +static HIDDescriptorListNode* rootNode = NULL; +static uint8_t sizeof_hidReportDescriptor = 0; +static uint8_t modules_count = 0; +//================================================================================ +//================================================================================ +// Driver + +u8 _hid_protocol = 1; +u8 _hid_idle = 1; + +int HID_GetInterface(u8* interfaceNum) +{ + interfaceNum[0] += 1; // uses 1 + _hidInterface = + { + D_INTERFACE(HID_INTERFACE,1,3,0,0), + D_HIDREPORT(sizeof_hidReportDescriptor), + D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01) + }; + return USB_SendControl(0,&_hidInterface,sizeof(_hidInterface)); +} + +int HID_GetDescriptor(int8_t t) +{ + if (HID_REPORT_DESCRIPTOR_TYPE == t) { + HIDDescriptorListNode* current = rootNode; + int total = 0; + while(current != NULL) { + total += USB_SendControl(TRANSFER_PGM,current->cb->descriptor,current->cb->length); + current = current->next; + } + return total; + } else { + return 0; + } +} + +void HID_::AppendDescriptor(HIDDescriptorListNode *node) +{ + if (modules_count == 0) { + rootNode = node; + } else { + HIDDescriptorListNode *current = rootNode; + while(current->next != NULL) { + current = current->next; + } + current->next = node; + } + modules_count++; + sizeof_hidReportDescriptor += node->cb->length; +} + +void HID_::SendReport(u8 id, const void* data, int len) +{ + USB_Send(HID_TX, &id, 1); + USB_Send(HID_TX | TRANSFER_RELEASE,data,len); +} + +bool HID_Setup(USBSetup& setup, u8 i) +{ + if (HID_INTERFACE != i) { + return false; + } else { + u8 r = setup.bRequest; + u8 requestType = setup.bmRequestType; + if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) + { + if (HID_GET_REPORT == r) + { + //HID_GetReport(); + return true; + } + if (HID_GET_PROTOCOL == r) + { + //Send8(_hid_protocol); // TODO + return true; + } + } + + if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) + { + if (HID_SET_PROTOCOL == r) + { + _hid_protocol = setup.wValueL; + return true; + } + + if (HID_SET_IDLE == r) + { + _hid_idle = setup.wValueL; + return true; + } + } + return false; + } +} + +HID_::HID_(void) +{ + static uint8_t endpointType[1]; + + endpointType[0] = EP_TYPE_INTERRUPT_IN; + + static PUSBCallbacks cb = { + .setup = &HID_Setup, + .getInterface = &HID_GetInterface, + .getDescriptor = &HID_GetDescriptor, + .numEndpoints = 1, + .numInterfaces = 1, + .endpointType = endpointType, + }; + + static PUSBListNode node(&cb); + + HID_ENDPOINT_INT = PUSB_AddFunction(&node, &HID_INTERFACE); +} + +int HID_::begin(void) +{ +} + +#endif /* if defined(USBCON) */ diff --git a/hardware/arduino/avr/libraries/HID/HID.h b/hardware/arduino/avr/libraries/HID/HID.h new file mode 100644 index 00000000000..89832a9afef --- /dev/null +++ b/hardware/arduino/avr/libraries/HID/HID.h @@ -0,0 +1,97 @@ +/* + HID.h + + Copyright (c) 2015, Arduino LLC + Original code (pre-library): Copyright (c) 2011, Peter Barrett + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef HID_h +#define HID_h + +#include +#include + +#if defined(USBCON) + +#define _USING_HID + +//================================================================================ +//================================================================================ +// HID 'Driver' + +#define HID_GET_REPORT 0x01 +#define HID_GET_IDLE 0x02 +#define HID_GET_PROTOCOL 0x03 +#define HID_SET_REPORT 0x09 +#define HID_SET_IDLE 0x0A +#define HID_SET_PROTOCOL 0x0B + +#define HID_HID_DESCRIPTOR_TYPE 0x21 +#define HID_REPORT_DESCRIPTOR_TYPE 0x22 +#define HID_PHYSICAL_DESCRIPTOR_TYPE 0x23 + +typedef struct __attribute__((packed)) { + u8 length; + const void* descriptor; +} HID_Descriptor; + +class HIDDescriptorListNode { +public: + HIDDescriptorListNode *next = NULL; + const HID_Descriptor * cb; + HIDDescriptorListNode(const HID_Descriptor *ncb) {cb = ncb;} +}; + +class HID_ +{ +public: + HID_(void); + int begin(void); + void SendReport(uint8_t id, const void* data, int len); + void AppendDescriptor(HIDDescriptorListNode* node); +}; + +typedef struct +{ + u8 len; // 9 + u8 dtype; // 0x21 + u8 addr; + u8 versionL; // 0x101 + u8 versionH; // 0x101 + u8 country; + u8 desctype; // 0x22 report + u8 descLenL; + u8 descLenH; +} HIDDescDescriptor; + +typedef struct +{ + InterfaceDescriptor hid; + HIDDescDescriptor desc; + EndpointDescriptor in; +} HIDDescriptor; + +#define HID_TX HID_ENDPOINT_INT + +#define D_HIDREPORT(_descriptorLength) \ + { 9, 0x21, 0x1, 0x1, 0, 1, 0x22, _descriptorLength, 0 } + +#define WEAK __attribute__ ((weak)) + +#endif + +#endif \ No newline at end of file diff --git a/hardware/arduino/avr/libraries/HID/keywords.txt b/hardware/arduino/avr/libraries/HID/keywords.txt new file mode 100644 index 00000000000..32a9ba5f20c --- /dev/null +++ b/hardware/arduino/avr/libraries/HID/keywords.txt @@ -0,0 +1,21 @@ +####################################### +# Syntax Coloring Map HID +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +HID KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +begin KEYWORD2 +SendReport KEYWORD2 +AppendDescriptor KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### +HID_TX LITERAL1 \ No newline at end of file diff --git a/hardware/arduino/avr/libraries/HID/library.properties b/hardware/arduino/avr/libraries/HID/library.properties new file mode 100644 index 00000000000..20a1e7f331f --- /dev/null +++ b/hardware/arduino/avr/libraries/HID/library.properties @@ -0,0 +1,8 @@ +name=HID +version=1.0 +author=Arduino +maintainer=Arduino +sentence=Module for PluggableUSB infrastructure. Exposes an API for devices like Keyboards, Mice and Gamepads +paragraph= +url=http://www.arduino.cc/en/Reference/HID +architectures=avr \ No newline at end of file diff --git a/hardware/arduino/sam/libraries/HID/HID.h b/hardware/arduino/sam/libraries/HID/HID.h new file mode 100644 index 00000000000..47ad936fa2f --- /dev/null +++ b/hardware/arduino/sam/libraries/HID/HID.h @@ -0,0 +1,3 @@ +// HID.h + +// placeholder waiting for HID library to be DUE compatible \ No newline at end of file diff --git a/libraries/Keyboard/README.adoc b/libraries/Keyboard/README.adoc new file mode 100644 index 00000000000..0d77d9a83d4 --- /dev/null +++ b/libraries/Keyboard/README.adoc @@ -0,0 +1,25 @@ += Keyboard Library for Arduino = + +This library allows an Arduino board with USB capabilites to act as a Keyboard. +Being based on HID library you need to include "HID.h" in your sketch. + +For more information about this library please visit us at +http://www.arduino.cc/en/Reference/Keyboard + +== License == + +Copyright (c) Arduino LLC. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/libraries/Keyboard/keywords.txt b/libraries/Keyboard/keywords.txt new file mode 100644 index 00000000000..2078f032985 --- /dev/null +++ b/libraries/Keyboard/keywords.txt @@ -0,0 +1,24 @@ +####################################### +# Syntax Coloring Map For Keyboard +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +Keyboard KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +write KEYWORD2 +press KEYWORD2 +release KEYWORD2 +releaseAll KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/Keyboard/library.properties b/libraries/Keyboard/library.properties new file mode 100644 index 00000000000..7d1c20c59b3 --- /dev/null +++ b/libraries/Keyboard/library.properties @@ -0,0 +1,9 @@ +name=Keyboard +version=1.0.0 +author=Arduino +maintainer=Arduino +sentence=Allows an Arduino board with USB capabilites to act as a Keyboard. For Leonardo/Micro only +paragraph=This library plugs on the HID library. It can be used with or without other HID-based libraries (Mouse, Gamepad etc) +category=USB +url=http://www.arduino.cc/en/Reference/Keyboard +architectures=* diff --git a/hardware/arduino/avr/cores/arduino/HID.cpp b/libraries/Keyboard/src/Keyboard.cpp similarity index 53% rename from hardware/arduino/avr/cores/arduino/HID.cpp rename to libraries/Keyboard/src/Keyboard.cpp index 75c37b24b2f..73f4691193e 100644 --- a/hardware/arduino/avr/cores/arduino/HID.cpp +++ b/libraries/Keyboard/src/Keyboard.cpp @@ -1,279 +1,86 @@ +/* + Keyboard.cpp + Copyright (c) 2015, Arduino LLC + Original code (pre-library): Copyright (c) 2011, Peter Barrett -/* Copyright (c) 2011, Peter Barrett -** -** Permission to use, copy, modify, and/or distribute this software for -** any purpose with or without fee is hereby granted, provided that the -** above copyright notice and this permission notice appear in all copies. -** -** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL -** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR -** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES -** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -** SOFTWARE. -*/ - -#include "USBAPI.h" + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. -#if defined(USBCON) -#ifdef HID_ENABLED + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. -//#define RAWHID_ENABLED + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ -// Singletons for mouse and keyboard +#include "Keyboard.h" -Mouse_ Mouse; -Keyboard_ Keyboard; +#if defined(_USING_HID) //================================================================================ //================================================================================ +// Keyboard -// HID report descriptor - -#define LSB(_x) ((_x) & 0xFF) -#define MSB(_x) ((_x) >> 8) - -#define RAWHID_USAGE_PAGE 0xFFC0 -#define RAWHID_USAGE 0x0C00 -#define RAWHID_TX_SIZE 64 -#define RAWHID_RX_SIZE 64 - -extern const u8 _hidReportDescriptor[] PROGMEM; -const u8 _hidReportDescriptor[] = { - - // Mouse - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54 - 0x09, 0x02, // USAGE (Mouse) - 0xa1, 0x01, // COLLECTION (Application) - 0x09, 0x01, // USAGE (Pointer) - 0xa1, 0x00, // COLLECTION (Physical) - 0x85, 0x01, // REPORT_ID (1) - 0x05, 0x09, // USAGE_PAGE (Button) - 0x19, 0x01, // USAGE_MINIMUM (Button 1) - 0x29, 0x03, // USAGE_MAXIMUM (Button 3) - 0x15, 0x00, // LOGICAL_MINIMUM (0) - 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x95, 0x03, // REPORT_COUNT (3) - 0x75, 0x01, // REPORT_SIZE (1) - 0x81, 0x02, // INPUT (Data,Var,Abs) - 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x05, // REPORT_SIZE (5) - 0x81, 0x03, // INPUT (Cnst,Var,Abs) - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) - 0x09, 0x30, // USAGE (X) - 0x09, 0x31, // USAGE (Y) - 0x09, 0x38, // USAGE (Wheel) - 0x15, 0x81, // LOGICAL_MINIMUM (-127) - 0x25, 0x7f, // LOGICAL_MAXIMUM (127) - 0x75, 0x08, // REPORT_SIZE (8) - 0x95, 0x03, // REPORT_COUNT (3) - 0x81, 0x06, // INPUT (Data,Var,Rel) - 0xc0, // END_COLLECTION - 0xc0, // END_COLLECTION +static const u8 _hidReportDescriptor[] PROGMEM = { - // Keyboard - 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47 + // Keyboard + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47 0x09, 0x06, // USAGE (Keyboard) 0xa1, 0x01, // COLLECTION (Application) 0x85, 0x02, // REPORT_ID (2) 0x05, 0x07, // USAGE_PAGE (Keyboard) - 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) + 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) - 0x95, 0x08, // REPORT_COUNT (8) + 0x95, 0x08, // REPORT_COUNT (8) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) - 0x95, 0x06, // REPORT_COUNT (6) + 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x65, // LOGICAL_MAXIMUM (101) 0x05, 0x07, // USAGE_PAGE (Keyboard) - 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) + 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 0x81, 0x00, // INPUT (Data,Ary,Abs) 0xc0, // END_COLLECTION - -#ifdef RAWHID_ENABLED - // RAW HID - 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30 - 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE), - - 0xA1, 0x01, // Collection 0x01 - 0x85, 0x03, // REPORT_ID (3) - 0x75, 0x08, // report size = 8 bits - 0x15, 0x00, // logical minimum = 0 - 0x26, 0xFF, 0x00, // logical maximum = 255 - - 0x95, 64, // report count TX - 0x09, 0x01, // usage - 0x81, 0x02, // Input (array) - - 0x95, 64, // report count RX - 0x09, 0x02, // usage - 0x91, 0x02, // Output (array) - 0xC0 // end collection -#endif }; -extern const HIDDescriptor _hidInterface PROGMEM; -const HIDDescriptor _hidInterface = -{ - D_INTERFACE(HID_INTERFACE,1,3,0,0), - D_HIDREPORT(sizeof(_hidReportDescriptor)), - D_ENDPOINT(USB_ENDPOINT_IN (HID_ENDPOINT_INT),USB_ENDPOINT_TYPE_INTERRUPT,0x40,0x01) -}; - -//================================================================================ -//================================================================================ -// Driver - -u8 _hid_protocol = 1; -u8 _hid_idle = 1; - -#define WEAK __attribute__ ((weak)) - -int WEAK HID_GetInterface(u8* interfaceNum) -{ - interfaceNum[0] += 1; // uses 1 - return USB_SendControl(TRANSFER_PGM,&_hidInterface,sizeof(_hidInterface)); -} - -int WEAK HID_GetDescriptor(int /* i */) -{ - return USB_SendControl(TRANSFER_PGM,_hidReportDescriptor,sizeof(_hidReportDescriptor)); -} - -void WEAK HID_SendReport(u8 id, const void* data, int len) -{ - USB_Send(HID_TX, &id, 1); - USB_Send(HID_TX | TRANSFER_RELEASE,data,len); -} - -bool WEAK HID_Setup(Setup& setup) -{ - u8 r = setup.bRequest; - u8 requestType = setup.bmRequestType; - if (REQUEST_DEVICETOHOST_CLASS_INTERFACE == requestType) - { - if (HID_GET_REPORT == r) - { - //HID_GetReport(); - return true; - } - if (HID_GET_PROTOCOL == r) - { - //Send8(_hid_protocol); // TODO - return true; - } - } - - if (REQUEST_HOSTTODEVICE_CLASS_INTERFACE == requestType) - { - if (HID_SET_PROTOCOL == r) - { - _hid_protocol = setup.wValueL; - return true; - } - - if (HID_SET_IDLE == r) - { - _hid_idle = setup.wValueL; - return true; - } - } - return false; -} - -//================================================================================ -//================================================================================ -// Mouse - -Mouse_::Mouse_(void) : _buttons(0) -{ -} - -void Mouse_::begin(void) -{ -} - -void Mouse_::end(void) -{ -} - -void Mouse_::click(uint8_t b) -{ - _buttons = b; - move(0,0,0); - _buttons = 0; - move(0,0,0); -} - -void Mouse_::move(signed char x, signed char y, signed char wheel) -{ - u8 m[4]; - m[0] = _buttons; - m[1] = x; - m[2] = y; - m[3] = wheel; - HID_SendReport(1,m,4); -} - -void Mouse_::buttons(uint8_t b) -{ - if (b != _buttons) - { - _buttons = b; - move(0,0,0); - } -} - -void Mouse_::press(uint8_t b) -{ - buttons(_buttons | b); -} - -void Mouse_::release(uint8_t b) -{ - buttons(_buttons & ~b); -} - -bool Mouse_::isPressed(uint8_t b) -{ - if ((b & _buttons) > 0) - return true; - return false; -} - -//================================================================================ -//================================================================================ -// Keyboard - Keyboard_::Keyboard_(void) { + static HID_Descriptor cb = { + .length = sizeof(_hidReportDescriptor), + .descriptor = _hidReportDescriptor, + }; + static HIDDescriptorListNode node(&cb); + HID.AppendDescriptor(&node); } -void Keyboard_::begin(void) +void Keyboard_::begin(void) { } -void Keyboard_::end(void) +void Keyboard_::end(void) { } void Keyboard_::sendReport(KeyReport* keys) { - HID_SendReport(2,keys,sizeof(KeyReport)); + HID.SendReport(2,keys,sizeof(KeyReport)); } extern @@ -413,6 +220,7 @@ const uint8_t _asciimap[128] = 0 // DEL }; + uint8_t USBPutChar(uint8_t c); // press() adds the specified key (printing, non-printing, or modifier) @@ -513,6 +321,6 @@ size_t Keyboard_::write(uint8_t c) return p; // just return the result of press() since release() almost always returns 1 } -#endif +Keyboard_ Keyboard; -#endif /* if defined(USBCON) */ +#endif diff --git a/libraries/Keyboard/src/Keyboard.h b/libraries/Keyboard/src/Keyboard.h new file mode 100644 index 00000000000..761e8fa814a --- /dev/null +++ b/libraries/Keyboard/src/Keyboard.h @@ -0,0 +1,99 @@ +/* + Keyboard.h + + Copyright (c) 2015, Arduino LLC + Original code (pre-library): Copyright (c) 2011, Peter Barrett + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef KEYBOARD_h +#define KEYBOARD_h + +#include "HID.h" + +#if !defined(_USING_HID) + +#warning "Using legacy HID core (non pluggable)" + +#else + +//================================================================================ +//================================================================================ +// Keyboard + +#define KEY_LEFT_CTRL 0x80 +#define KEY_LEFT_SHIFT 0x81 +#define KEY_LEFT_ALT 0x82 +#define KEY_LEFT_GUI 0x83 +#define KEY_RIGHT_CTRL 0x84 +#define KEY_RIGHT_SHIFT 0x85 +#define KEY_RIGHT_ALT 0x86 +#define KEY_RIGHT_GUI 0x87 + +#define KEY_UP_ARROW 0xDA +#define KEY_DOWN_ARROW 0xD9 +#define KEY_LEFT_ARROW 0xD8 +#define KEY_RIGHT_ARROW 0xD7 +#define KEY_BACKSPACE 0xB2 +#define KEY_TAB 0xB3 +#define KEY_RETURN 0xB0 +#define KEY_ESC 0xB1 +#define KEY_INSERT 0xD1 +#define KEY_DELETE 0xD4 +#define KEY_PAGE_UP 0xD3 +#define KEY_PAGE_DOWN 0xD6 +#define KEY_HOME 0xD2 +#define KEY_END 0xD5 +#define KEY_CAPS_LOCK 0xC1 +#define KEY_F1 0xC2 +#define KEY_F2 0xC3 +#define KEY_F3 0xC4 +#define KEY_F4 0xC5 +#define KEY_F5 0xC6 +#define KEY_F6 0xC7 +#define KEY_F7 0xC8 +#define KEY_F8 0xC9 +#define KEY_F9 0xCA +#define KEY_F10 0xCB +#define KEY_F11 0xCC +#define KEY_F12 0xCD + +// Low level key report: up to 6 keys and shift, ctrl etc at once +typedef struct +{ + uint8_t modifiers; + uint8_t reserved; + uint8_t keys[6]; +} KeyReport; + +class Keyboard_ : public Print +{ +private: + KeyReport _keyReport; + void sendReport(KeyReport* keys); +public: + Keyboard_(void); + void begin(void); + void end(void); + size_t write(uint8_t k); + size_t press(uint8_t k); + size_t release(uint8_t k); + void releaseAll(void); +}; +extern Keyboard_ Keyboard; +extern HID_ HID; + +#endif diff --git a/libraries/Mouse/README.adoc b/libraries/Mouse/README.adoc new file mode 100644 index 00000000000..3e61306c65b --- /dev/null +++ b/libraries/Mouse/README.adoc @@ -0,0 +1,25 @@ += Mouse Library for Arduino = + +This library allows an Arduino board with USB capabilites to act as a Mouse. +Being based on HID library you need to include "HID.h" in your sketch + +For more information about this library please visit us at +http://www.arduino.cc/en/Reference/Mouse + +== License == + +Copyright (c) Arduino LLC. All right reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/libraries/Mouse/keywords.txt b/libraries/Mouse/keywords.txt new file mode 100644 index 00000000000..258c48eebaf --- /dev/null +++ b/libraries/Mouse/keywords.txt @@ -0,0 +1,24 @@ +####################################### +# Syntax Coloring Map For Keyboard +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +Mouse KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +click KEYWORD2 +move KEYWORD2 +press KEYWORD2 +release KEYWORD2 +isPressed KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/Mouse/library.properties b/libraries/Mouse/library.properties new file mode 100644 index 00000000000..fe8e2c0b001 --- /dev/null +++ b/libraries/Mouse/library.properties @@ -0,0 +1,9 @@ +name=Mouse +version=1.0.0 +author=Arduino +maintainer=Arduino +sentence=Allows an Arduino board with USB capabilites to act as a Mouse. For Leonardo/Micro only +paragraph=This library plugs on the HID library. Can be used with or without other HID-based libraries (Keyboard, Gamepad etc) +category=USB +url=http://www.arduino.cc/en/Reference/Mouse +architectures=* diff --git a/libraries/Mouse/src/Mouse.cpp b/libraries/Mouse/src/Mouse.cpp new file mode 100644 index 00000000000..a0566811c28 --- /dev/null +++ b/libraries/Mouse/src/Mouse.cpp @@ -0,0 +1,127 @@ +/* + Mouse.cpp + + Copyright (c) 2015, Arduino LLC + Original code (pre-library): Copyright (c) 2011, Peter Barrett + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Mouse.h" + +#if defined(_USING_HID) + +static const u8 _hidReportDescriptor[] PROGMEM = { + + // Mouse + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54 + 0x09, 0x02, // USAGE (Mouse) + 0xa1, 0x01, // COLLECTION (Application) + 0x09, 0x01, // USAGE (Pointer) + 0xa1, 0x00, // COLLECTION (Physical) + 0x85, 0x01, // REPORT_ID (1) + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x95, 0x03, // REPORT_COUNT (3) + 0x75, 0x01, // REPORT_SIZE (1) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x05, // REPORT_SIZE (5) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) + 0x09, 0x38, // USAGE (Wheel) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7f, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x03, // REPORT_COUNT (3) + 0x81, 0x06, // INPUT (Data,Var,Rel) + 0xc0, // END_COLLECTION + 0xc0, // END_COLLECTION +}; + +//================================================================================ +//================================================================================ +// Mouse + +Mouse_::Mouse_(void) : _buttons(0) +{ + const static HID_Descriptor cb = { + .length = sizeof(_hidReportDescriptor), + .descriptor = _hidReportDescriptor, + }; + static HIDDescriptorListNode node(&cb); + HID.AppendDescriptor(&node); +} + +void Mouse_::begin(void) +{ +} + +void Mouse_::end(void) +{ +} + +void Mouse_::click(uint8_t b) +{ + _buttons = b; + move(0,0,0); + _buttons = 0; + move(0,0,0); +} + +void Mouse_::move(signed char x, signed char y, signed char wheel) +{ + u8 m[4]; + m[0] = _buttons; + m[1] = x; + m[2] = y; + m[3] = wheel; + HID.SendReport(1,m,4); +} + +void Mouse_::buttons(uint8_t b) +{ + if (b != _buttons) + { + _buttons = b; + move(0,0,0); + } +} + +void Mouse_::press(uint8_t b) +{ + buttons(_buttons | b); +} + +void Mouse_::release(uint8_t b) +{ + buttons(_buttons & ~b); +} + +bool Mouse_::isPressed(uint8_t b) +{ + if ((b & _buttons) > 0) + return true; + return false; +} + +Mouse_ Mouse; + +#endif diff --git a/libraries/Mouse/src/Mouse.h b/libraries/Mouse/src/Mouse.h new file mode 100644 index 00000000000..3ab57a5eb1c --- /dev/null +++ b/libraries/Mouse/src/Mouse.h @@ -0,0 +1,61 @@ +/* + Mouse.h + + Copyright (c) 2015, Arduino LLC + Original code (pre-library): Copyright (c) 2011, Peter Barrett + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef MOUSE_h +#define MOUSE_h + +#include "HID.h" + +#if !defined(_USING_HID) + +#warning "Using legacy HID core (non pluggable)" + +#else + +//================================================================================ +//================================================================================ +// Mouse + +#define MOUSE_LEFT 1 +#define MOUSE_RIGHT 2 +#define MOUSE_MIDDLE 4 +#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) + +class Mouse_ +{ +private: + uint8_t _buttons; + void buttons(uint8_t b); +public: + Mouse_(void); + void begin(void); + void end(void); + void click(uint8_t b = MOUSE_LEFT); + void move(signed char x, signed char y, signed char wheel = 0); + void press(uint8_t b = MOUSE_LEFT); // press LEFT by default + void release(uint8_t b = MOUSE_LEFT); // release LEFT by default + bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default +}; +extern Mouse_ Mouse; +extern HID_ HID; + +#endif +#endif \ No newline at end of file