Chris Majoros / USBDevice

Dependents:   loststone

Fork of USBDevice by mbed official

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBMouse.cpp Source File

USBMouse.cpp

00001 /* Copyright (c) 2010-2011 mbed.org, MIT License
00002 *
00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00004 * and associated documentation files (the "Software"), to deal in the Software without
00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
00007 * Software is furnished to do so, subject to the following conditions:
00008 *
00009 * The above copyright notice and this permission notice shall be included in all copies or
00010 * substantial portions of the Software.
00011 *
00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017 */
00018 
00019 #include "stdint.h"
00020 #include "USBMouse.h"
00021 
00022 bool USBMouse::update(int16_t x, int16_t y, uint8_t button, int8_t z, int8_t h) {
00023     switch (mouse_type) {
00024         case REL_MOUSE:
00025             return mouseSend(x, y, button, z, h);
00026         case ABS_MOUSE:
00027             HID_REPORT report;
00028 
00029             report.data[0] = x & 0xff;
00030             report.data[1] = (x >> 8) & 0xff;
00031             report.data[2] = y & 0xff;
00032             report.data[3] = (y >> 8) & 0xff;
00033             report.data[4] = -z;
00034             report.data[5] = button & 0x07;
00035 
00036             report.length = 6;
00037 
00038             return send(&report);
00039         default:
00040             return false;
00041     }
00042 }
00043 
00044 bool USBMouse::mouseSend(int16_t x, int16_t y, uint8_t buttons, int8_t z, int8_t h) {
00045     HID_REPORT report;
00046 
00047     report.data[0] = buttons;// & 0x07;
00048 
00049     report.data[1] = (unsigned int) x & 0x00FF;
00050     report.data[2] = (unsigned int) x >> 8;
00051     report.data[3] = (unsigned int) y & 0x00FF;
00052     report.data[4] = (unsigned int) y >> 8;
00053     report.data[5] = -z; // >0 to scroll down, <0 to scroll up
00054     report.data[6] = h;
00055 
00056     report.length = 7;
00057 
00058     return send(&report);
00059 }
00060 
00061 bool USBMouse::move(int16_t x, int16_t y) {
00062     return update(x, y, button, 0, 0);
00063 }
00064 
00065 bool USBMouse::scroll(int8_t z, int8_t h) {
00066     return update(0, 0, button, z, h);
00067 }
00068 
00069 
00070 bool USBMouse::doubleClick() {
00071     if (!click(MOUSE_LEFT))
00072         return false;
00073     wait(0.1);
00074     return click(MOUSE_LEFT);
00075 }
00076 
00077 bool USBMouse::click(uint8_t button) {
00078     if (!update(0, 0, button, 0, 0))
00079         return false;
00080     wait(0.01);
00081     return update(0, 0, 0, 0, 0);
00082 }
00083 
00084 bool USBMouse::press(uint8_t button_) {
00085     printf("btn_press\n\r");
00086     button = button_ & 0x07;
00087     return update(0, 0, button, 0, 0);
00088 }
00089 
00090 bool USBMouse::release(uint8_t button_) {
00091     printf("btn_release\n\r");
00092     button = (button & (~button_)) & 0x07;
00093     return update(0, 0, button, 0, 0);
00094 }
00095 
00096 
00097 uint8_t * USBMouse::reportDesc() {
00098 
00099     if (mouse_type == REL_MOUSE) {
00100 //
00101 // Wheel Mouse - simplified version - 5 button, vertical and horizontal wheel
00102 //
00103 // Input report - 5 bytes
00104 //
00105 //     Byte | D7      D6      D5      D4      D3      D2      D1      D0
00106 //    ------+---------------------------------------------------------------------
00107 //      0   |  0       0       0    Forward  Back    Middle  Right   Left (Buttons)
00108 //      1   |                             X High
00109 //      2   |                             X Low
00110 //      3   |                             Y High
00111 //      4   |                             Y Low
00112 //      5   |                       Vertical Wheel
00113 //      6   |                    Horizontal (Tilt) Wheel
00114 //
00115 // Feature report - 1 byte
00116 //
00117 //     Byte | D7      D6      D5      D4   |  D3      D2  |   D1      D0
00118 //    ------+------------------------------+--------------+----------------
00119 //      0   |  0       0       0       0   |  Horizontal  |    Vertical
00120 //                                             (Resolution multiplier)
00121 //
00122 // Reference
00123 //    Wheel.docx in "Enhanced Wheel Support in Windows Vista" on MS WHDC
00124 //    http://www.microsoft.com/whdc/device/input/wheel.mspx
00125 //
00126         static uint8_t reportDescriptor[] = {
00127             0x05, 0x01,        // USAGE_PAGE (Generic Desktop)
00128             0x09, 0x02,        // USAGE (Mouse)
00129             0xa1, 0x01,        // COLLECTION (Application)
00130             0x09, 0x02,        //   USAGE (Mouse)
00131             0xa1, 0x02,        //   COLLECTION (Logical)
00132             0x09, 0x01,        //     USAGE (Pointer)
00133             0xa1, 0x00,        //     COLLECTION (Physical)
00134                                // ------------------------------  Buttons
00135             0x05, 0x09,        //       USAGE_PAGE (Button)
00136             0x19, 0x01,        //       USAGE_MINIMUM (Button 1)
00137             0x29, 0x05,        //       USAGE_MAXIMUM (Button 5)
00138             0x15, 0x00,        //       LOGICAL_MINIMUM (0)
00139             0x25, 0x01,        //       LOGICAL_MAXIMUM (1)
00140             0x75, 0x01,        //       REPORT_SIZE (1)
00141             0x95, 0x05,        //       REPORT_COUNT (5)
00142             0x81, 0x02,        //       INPUT (Data,Var,Abs)
00143                                // ------------------------------  Padding
00144             0x75, 0x03,        //       REPORT_SIZE (3)
00145             0x95, 0x01,        //       REPORT_COUNT (1)
00146             0x81, 0x03,        //       INPUT (Cnst,Var,Abs)
00147                                // ------------------------------  X,Y position
00148             0x05, 0x01,        //       USAGE_PAGE (Generic Desktop)
00149             0x09, 0x30,        //       USAGE (X)
00150             0x09, 0x31,        //       USAGE (Y)
00151             0x16, 0x00, 0x81,  //       LOGICAL_MINIMUM (-32768)
00152             0x26, 0xff, 0x7f,  //       LOGICAL_MAXIMUM (32767)
00153             0x75, 0x10,        //       REPORT_SIZE (16)
00154             0x95, 0x02,        //       REPORT_COUNT (2)
00155             0x81, 0x06,        //       INPUT (Data,Var,Rel)
00156             0xa1, 0x02,        //       COLLECTION (Logical)
00157                                // ------------------------------  Vertical wheel res multiplier
00158             0x09, 0x48,        //         USAGE (Resolution Multiplier)
00159             0x15, 0x00,        //         LOGICAL_MINIMUM (0)
00160             0x25, 0x01,        //         LOGICAL_MAXIMUM (1)
00161             0x35, 0x01,        //         PHYSICAL_MINIMUM (1)
00162             0x45, 0x04,        //         PHYSICAL_MAXIMUM (4)
00163             0x75, 0x02,        //         REPORT_SIZE (2)
00164             0x95, 0x01,        //         REPORT_COUNT (1)
00165             0xa4,              //         PUSH
00166             0xb1, 0x02,        //         FEATURE (Data,Var,Abs)
00167                                // ------------------------------  Vertical wheel
00168             0x09, 0x38,        //         USAGE (Wheel)
00169             0x15, 0x81,        //         LOGICAL_MINIMUM (-127)
00170             0x25, 0x7f,        //         LOGICAL_MAXIMUM (127)
00171             0x35, 0x00,        //         PHYSICAL_MINIMUM (0)        - reset physical
00172             0x45, 0x00,        //         PHYSICAL_MAXIMUM (0)
00173             0x75, 0x08,        //         REPORT_SIZE (8)
00174             0x81, 0x06,        //         INPUT (Data,Var,Rel)
00175             0xc0,              //       END_COLLECTION
00176             0xa1, 0x02,        //       COLLECTION (Logical)
00177                                // ------------------------------  Horizontal wheel res multiplier
00178             0x09, 0x48,        //         USAGE (Resolution Multiplier)
00179             0xb4,              //         POP
00180             0xb1, 0x02,        //         FEATURE (Data,Var,Abs)
00181                                // ------------------------------  Padding for Feature report
00182             0x35, 0x00,        //         PHYSICAL_MINIMUM (0)        - reset physical
00183             0x45, 0x00,        //         PHYSICAL_MAXIMUM (0)
00184             0x75, 0x04,        //         REPORT_SIZE (4)
00185             0xb1, 0x03,        //         FEATURE (Cnst,Var,Abs)
00186                                // ------------------------------  Horizontal wheel
00187             0x05, 0x0c,        //         USAGE_PAGE (Consumer Devices)
00188             0x0a, 0x38, 0x02,  //         USAGE (AC Pan)
00189             0x15, 0x81,        //         LOGICAL_MINIMUM (-127)
00190             0x25, 0x7f,        //         LOGICAL_MAXIMUM (127)
00191             0x75, 0x08,        //         REPORT_SIZE (8)
00192             0x81, 0x06,        //         INPUT (Data,Var,Rel)
00193             0xc0,              //       END_COLLECTION
00194             0xc0,              //     END_COLLECTION
00195             0xc0,              //   END_COLLECTION
00196            0xc0               // END_COLLECTION
00197         };
00198 
00199         reportLength = sizeof(reportDescriptor);
00200         return reportDescriptor;
00201     } else if (mouse_type == ABS_MOUSE) {
00202         static uint8_t reportDescriptor[] = {
00203 
00204             USAGE_PAGE(1), 0x01,           // Generic Desktop
00205             USAGE(1), 0x02,                // Mouse
00206             COLLECTION(1), 0x01,           // Application
00207             USAGE(1), 0x01,                // Pointer
00208             COLLECTION(1), 0x00,           // Physical
00209 
00210             USAGE_PAGE(1), 0x01,            // Generic Desktop
00211             USAGE(1), 0x30,                 // X
00212             USAGE(1), 0x31,                 // Y
00213             LOGICAL_MINIMUM(1), 0x00,       // 0
00214             LOGICAL_MAXIMUM(2), 0xff, 0x7f, // 32767
00215             REPORT_SIZE(1), 0x10,
00216             REPORT_COUNT(1), 0x02,
00217             INPUT(1), 0x02,                 // Data, Variable, Absolute
00218 
00219             USAGE_PAGE(1), 0x01,            // Generic Desktop
00220             USAGE(1), 0x38,                 // scroll
00221             LOGICAL_MINIMUM(1), 0x81,       // -127
00222             LOGICAL_MAXIMUM(1), 0x7f,       // 127
00223             REPORT_SIZE(1), 0x08,
00224             REPORT_COUNT(1), 0x01,
00225             INPUT(1), 0x06,                 // Data, Variable, Relative
00226 
00227             USAGE_PAGE(1), 0x09,            // Buttons
00228             USAGE_MINIMUM(1), 0x01,
00229             USAGE_MAXIMUM(1), 0x03,
00230             LOGICAL_MINIMUM(1), 0x00,       // 0
00231             LOGICAL_MAXIMUM(1), 0x01,       // 1
00232             REPORT_COUNT(1), 0x03,
00233             REPORT_SIZE(1), 0x01,
00234             INPUT(1), 0x02,                 // Data, Variable, Absolute
00235             REPORT_COUNT(1), 0x01,
00236             REPORT_SIZE(1), 0x05,
00237             INPUT(1), 0x01,                 // Constant
00238 
00239             END_COLLECTION(0),
00240             END_COLLECTION(0)
00241         };
00242         reportLength = sizeof(reportDescriptor);
00243         return reportDescriptor;
00244     }
00245     return NULL;
00246 }
00247 
00248 #define DEFAULT_CONFIGURATION (1)
00249 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
00250                                + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
00251                                + (1 * HID_DESCRIPTOR_LENGTH) \
00252                                + (2 * ENDPOINT_DESCRIPTOR_LENGTH))
00253 
00254 uint8_t * USBMouse::configurationDesc() {
00255     static uint8_t configurationDescriptor[] = {
00256         CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
00257         CONFIGURATION_DESCRIPTOR,       // bDescriptorType
00258         LSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (LSB)
00259         MSB(TOTAL_DESCRIPTOR_LENGTH),   // wTotalLength (MSB)
00260         0x01,                           // bNumInterfaces
00261         DEFAULT_CONFIGURATION,          // bConfigurationValue
00262         0x00,                           // iConfiguration
00263         C_RESERVED | C_SELF_POWERED,    // bmAttributes
00264         C_POWER(0),                     // bMaxPowerHello World from Mbed
00265 
00266         INTERFACE_DESCRIPTOR_LENGTH,    // bLength
00267         INTERFACE_DESCRIPTOR,           // bDescriptorType
00268         0x00,                           // bInterfaceNumber
00269         0x00,                           // bAlternateSetting
00270         0x02,                           // bNumEndpoints
00271         HID_CLASS,                      // bInterfaceClass
00272         1,                              // bInterfaceSubClass
00273         2,                              // bInterfaceProtocol (mouse)
00274         0x00,                           // iInterface
00275 
00276         HID_DESCRIPTOR_LENGTH,          // bLength
00277         HID_DESCRIPTOR,                 // bDescriptorType
00278         LSB(HID_VERSION_1_11),          // bcdHID (LSB)
00279         MSB(HID_VERSION_1_11),          // bcdHID (MSB)
00280         0x00,                           // bCountryCode
00281         0x01,                           // bNumDescriptors
00282         REPORT_DESCRIPTOR,              // bDescriptorType
00283         LSB(reportDescLength()),        // wDescriptorLength (LSB)
00284         MSB(reportDescLength()),        // wDescriptorLength (MSB)
00285 
00286         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
00287         ENDPOINT_DESCRIPTOR,            // bDescriptorType
00288         PHY_TO_DESC(EPINT_IN),          // bEndpointAddress
00289         E_INTERRUPT,                    // bmAttributes
00290         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
00291         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
00292         1,                              // bInterval (milliseconds)
00293 
00294         ENDPOINT_DESCRIPTOR_LENGTH,     // bLength
00295         ENDPOINT_DESCRIPTOR,            // bDescriptorType
00296         PHY_TO_DESC(EPINT_OUT),         // bEndpointAddress
00297         E_INTERRUPT,                    // bmAttributes
00298         LSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (LSB)
00299         MSB(MAX_PACKET_SIZE_EPINT),     // wMaxPacketSize (MSB)
00300         1,                              // bInterval (milliseconds)
00301     };
00302     return configurationDescriptor;
00303 }