Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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 }
Generated on Tue Jul 12 2022 13:55:02 by
