Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBMouse.cpp Source File

USBMouse.cpp

00001 /*
00002  * Copyright (c) 2018-2019, Arm Limited and affiliates.
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #include "stdint.h"
00019 #include "USBMouse.h"
00020 #include "ThisThread.h"
00021 #include "usb_phy_api.h"
00022 
00023 
00024 USBMouse::USBMouse(bool connect_blocking, MOUSE_TYPE mouse_type, uint16_t vendor_id, uint16_t product_id, uint16_t product_release):
00025     USBHID(get_usb_phy(), 0, 0, vendor_id, product_id, product_release)
00026 {
00027     _button = 0;
00028     _mouse_type = mouse_type;
00029 
00030     if (connect_blocking) {
00031         USBDevice::connect();
00032         wait_ready();
00033     } else {
00034         init();
00035     }
00036 }
00037 
00038 USBMouse::USBMouse(USBPhy *phy, MOUSE_TYPE mouse_type, uint16_t vendor_id, uint16_t product_id, uint16_t product_release):
00039     USBHID(get_usb_phy(), 0, 0, vendor_id, product_id, product_release)
00040 {
00041     _button = 0;
00042     _mouse_type = mouse_type;
00043 }
00044 
00045 USBMouse::~USBMouse()
00046 {
00047     deinit();
00048 }
00049 
00050 bool USBMouse::update(int16_t x, int16_t y, uint8_t button, int8_t z)
00051 {
00052     bool ret;
00053     switch (_mouse_type) {
00054         case REL_MOUSE:
00055             _mutex.lock();
00056 
00057             while (x > 127) {
00058                 if (!mouse_send(127, 0, button, z)) {
00059                     _mutex.unlock();
00060                     return false;
00061                 }
00062                 x = x - 127;
00063             }
00064             while (x < -128) {
00065                 if (!mouse_send(-128, 0, button, z)) {
00066                     _mutex.unlock();
00067                     return false;
00068                 }
00069                 x = x + 128;
00070             }
00071             while (y > 127) {
00072                 if (!mouse_send(0, 127, button, z)) {
00073                     _mutex.unlock();
00074                     return false;
00075                 }
00076                 y = y - 127;
00077             }
00078             while (y < -128) {
00079                 if (!mouse_send(0, -128, button, z)) {
00080                     _mutex.unlock();
00081                     return false;
00082                 }
00083                 y = y + 128;
00084             }
00085             ret = mouse_send(x, y, button, z);
00086 
00087             _mutex.unlock();
00088             return ret;
00089         case ABS_MOUSE:
00090             _mutex.lock();
00091 
00092             HID_REPORT report;
00093 
00094             report.data[0] = x & 0xff;
00095             report.data[1] = (x >> 8) & 0xff;
00096             report.data[2] = y & 0xff;
00097             report.data[3] = (y >> 8) & 0xff;
00098             report.data[4] = -z;
00099             report.data[5] = button & 0x07;
00100 
00101             report.length = 6;
00102 
00103             ret = send(&report);
00104 
00105             _mutex.unlock();
00106             return ret;
00107         default:
00108             return false;
00109     }
00110 }
00111 
00112 bool USBMouse::mouse_send(int8_t x, int8_t y, uint8_t buttons, int8_t z)
00113 {
00114     _mutex.lock();
00115 
00116     HID_REPORT report;
00117     report.data[0] = buttons & 0x07;
00118     report.data[1] = x;
00119     report.data[2] = y;
00120     report.data[3] = -z; // >0 to scroll down, <0 to scroll up
00121 
00122     report.length = 4;
00123 
00124     bool ret = send(&report);
00125 
00126     _mutex.unlock();
00127     return ret;
00128 }
00129 
00130 bool USBMouse::move(int16_t x, int16_t y)
00131 {
00132     _mutex.lock();
00133 
00134     bool ret = update(x, y, _button, 0);
00135 
00136     _mutex.unlock();
00137     return ret;
00138 }
00139 
00140 bool USBMouse::scroll(int8_t z)
00141 {
00142     _mutex.lock();
00143 
00144     bool ret = update(0, 0, _button, z);
00145 
00146     _mutex.unlock();
00147     return ret;
00148 }
00149 
00150 
00151 bool USBMouse::double_click()
00152 {
00153     _mutex.lock();
00154 
00155     if (!click(MOUSE_LEFT)) {
00156         _mutex.unlock();
00157         return false;
00158     }
00159     rtos::ThisThread::sleep_for(100);
00160     bool ret = click(MOUSE_LEFT);
00161 
00162     _mutex.unlock();
00163     return ret;
00164 }
00165 
00166 bool USBMouse::click(uint8_t button)
00167 {
00168     _mutex.lock();
00169 
00170     if (!update(0, 0, button, 0)) {
00171         _mutex.unlock();
00172         return false;
00173     }
00174     rtos::ThisThread::sleep_for(10);
00175     bool ret = update(0, 0, 0, 0);
00176 
00177     _mutex.unlock();
00178     return ret;
00179 }
00180 
00181 bool USBMouse::press(uint8_t button)
00182 {
00183     _mutex.lock();
00184 
00185     _button = button & 0x07;
00186     bool ret = update(0, 0, _button, 0);
00187 
00188     _mutex.unlock();
00189     return ret;
00190 }
00191 
00192 bool USBMouse::release(uint8_t button)
00193 {
00194     _mutex.lock();
00195 
00196     _button = (_button & (~button)) & 0x07;
00197     bool ret = update(0, 0, _button, 0);
00198 
00199     _mutex.unlock();
00200     return ret;
00201 }
00202 
00203 
00204 const uint8_t *USBMouse::report_desc()
00205 {
00206 
00207     if (_mouse_type == REL_MOUSE) {
00208         static const uint8_t report_descriptor[] = {
00209             USAGE_PAGE(1),      0x01,       // Genric Desktop
00210             USAGE(1),           0x02,       // Mouse
00211             COLLECTION(1),      0x01,       // Application
00212             USAGE(1),           0x01,       // Pointer
00213             COLLECTION(1),      0x00,       // Physical
00214 
00215             REPORT_COUNT(1),    0x03,
00216             REPORT_SIZE(1),     0x01,
00217             USAGE_PAGE(1),      0x09,       // Buttons
00218             USAGE_MINIMUM(1),       0x1,
00219             USAGE_MAXIMUM(1),       0x3,
00220             LOGICAL_MINIMUM(1),     0x00,
00221             LOGICAL_MAXIMUM(1),     0x01,
00222             INPUT(1),           0x02,
00223             REPORT_COUNT(1),    0x01,
00224             REPORT_SIZE(1),     0x05,
00225             INPUT(1),           0x01,
00226 
00227             REPORT_COUNT(1),    0x03,
00228             REPORT_SIZE(1),     0x08,
00229             USAGE_PAGE(1),      0x01,
00230             USAGE(1),           0x30,       // X
00231             USAGE(1),           0x31,       // Y
00232             USAGE(1),           0x38,       // scroll
00233             LOGICAL_MINIMUM(1),     0x81,
00234             LOGICAL_MAXIMUM(1),     0x7f,
00235             INPUT(1),           0x06,       // Relative data
00236 
00237             END_COLLECTION(0),
00238             END_COLLECTION(0),
00239         };
00240         reportLength = sizeof(report_descriptor);
00241         return report_descriptor;
00242     } else if (_mouse_type == ABS_MOUSE) {
00243         static const uint8_t report_descriptor[] = {
00244             USAGE_PAGE(1), 0x01,           // Generic Desktop
00245             USAGE(1), 0x02,                // Mouse
00246             COLLECTION(1), 0x01,           // Application
00247             USAGE(1), 0x01,                // Pointer
00248             COLLECTION(1), 0x00,           // Physical
00249 
00250             USAGE_PAGE(1), 0x01,            // Generic Desktop
00251             USAGE(1), 0x30,                 // X
00252             USAGE(1), 0x31,                 // Y
00253             LOGICAL_MINIMUM(1), 0x00,       // 0
00254             LOGICAL_MAXIMUM(2), 0xff, 0x7f, // 32767
00255             REPORT_SIZE(1), 0x10,
00256             REPORT_COUNT(1), 0x02,
00257             INPUT(1), 0x02,                 // Data, Variable, Absolute
00258 
00259             USAGE_PAGE(1), 0x01,            // Generic Desktop
00260             USAGE(1), 0x38,                 // scroll
00261             LOGICAL_MINIMUM(1), 0x81,       // -127
00262             LOGICAL_MAXIMUM(1), 0x7f,       // 127
00263             REPORT_SIZE(1), 0x08,
00264             REPORT_COUNT(1), 0x01,
00265             INPUT(1), 0x06,                 // Data, Variable, Relative
00266 
00267             USAGE_PAGE(1), 0x09,            // Buttons
00268             USAGE_MINIMUM(1), 0x01,
00269             USAGE_MAXIMUM(1), 0x03,
00270             LOGICAL_MINIMUM(1), 0x00,       // 0
00271             LOGICAL_MAXIMUM(1), 0x01,       // 1
00272             REPORT_COUNT(1), 0x03,
00273             REPORT_SIZE(1), 0x01,
00274             INPUT(1), 0x02,                 // Data, Variable, Absolute
00275             REPORT_COUNT(1), 0x01,
00276             REPORT_SIZE(1), 0x05,
00277             INPUT(1), 0x01,                 // Constant
00278 
00279             END_COLLECTION(0),
00280             END_COLLECTION(0)
00281         };
00282         reportLength = sizeof(report_descriptor);
00283         return report_descriptor;
00284     }
00285     return NULL;
00286 }
00287 
00288 #define DEFAULT_CONFIGURATION (1)
00289 #define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
00290                                + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
00291                                + (1 * HID_DESCRIPTOR_LENGTH) \
00292                                + (2 * ENDPOINT_DESCRIPTOR_LENGTH))
00293 
00294 const uint8_t *USBMouse::configuration_desc(uint8_t index)
00295 {
00296     if (index != 0) {
00297         return NULL;
00298     }
00299     uint8_t configuration_descriptor_temp[] = {
00300         CONFIGURATION_DESCRIPTOR_LENGTH,    // bLength
00301         CONFIGURATION_DESCRIPTOR,           // bDescriptorType
00302         LSB(TOTAL_DESCRIPTOR_LENGTH),       // wTotalLength (LSB)
00303         MSB(TOTAL_DESCRIPTOR_LENGTH),       // wTotalLength (MSB)
00304         0x01,                               // bNumInterfaces
00305         DEFAULT_CONFIGURATION,              // bConfigurationValue
00306         0x00,                               // iConfiguration
00307         C_RESERVED | C_SELF_POWERED,        // bmAttributes
00308         C_POWER(0),                         // bMaxPower
00309 
00310         INTERFACE_DESCRIPTOR_LENGTH,        // bLength
00311         INTERFACE_DESCRIPTOR,               // bDescriptorType
00312         0x00,                               // bInterfaceNumber
00313         0x00,                               // bAlternateSetting
00314         0x02,                               // bNumEndpoints
00315         HID_CLASS,                          // bInterfaceClass
00316         HID_SUBCLASS_BOOT,                  // bInterfaceSubClass
00317         HID_PROTOCOL_MOUSE,                 // bInterfaceProtocol
00318         0x00,                               // iInterface
00319 
00320         HID_DESCRIPTOR_LENGTH,              // bLength
00321         HID_DESCRIPTOR,                     // bDescriptorType
00322         LSB(HID_VERSION_1_11),              // bcdHID (LSB)
00323         MSB(HID_VERSION_1_11),              // bcdHID (MSB)
00324         0x00,                               // bCountryCode
00325         0x01,                               // bNumDescriptors
00326         REPORT_DESCRIPTOR,                  // bDescriptorType
00327         (uint8_t)(LSB(report_desc_length())), // wDescriptorLength (LSB)
00328         (uint8_t)(MSB(report_desc_length())), // wDescriptorLength (MSB)
00329 
00330         ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
00331         ENDPOINT_DESCRIPTOR,                // bDescriptorType
00332         _int_in,                            // bEndpointAddress
00333         E_INTERRUPT,                        // bmAttributes
00334         LSB(MAX_HID_REPORT_SIZE),           // wMaxPacketSize (LSB)
00335         MSB(MAX_HID_REPORT_SIZE),           // wMaxPacketSize (MSB)
00336         1,                                  // bInterval (milliseconds)
00337 
00338         ENDPOINT_DESCRIPTOR_LENGTH,         // bLength
00339         ENDPOINT_DESCRIPTOR,                // bDescriptorType
00340         _int_out,                           // bEndpointAddress
00341         E_INTERRUPT,                        // bmAttributes
00342         LSB(MAX_HID_REPORT_SIZE),           // wMaxPacketSize (LSB)
00343         MSB(MAX_HID_REPORT_SIZE),           // wMaxPacketSize (MSB)
00344         1,                                  // bInterval (milliseconds)
00345     };
00346     MBED_ASSERT(sizeof(configuration_descriptor_temp) == sizeof(_configuration_descriptor));
00347     memcpy(_configuration_descriptor, configuration_descriptor_temp, sizeof(_configuration_descriptor));
00348     return _configuration_descriptor;
00349 }