back up of work during May 2019
Dependencies: microbit
MouseService.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "mbed.h" 00018 00019 #include "HIDServiceBase.h" 00020 00021 enum ButtonState 00022 { 00023 BUTTON_UP, 00024 BUTTON_DOWN 00025 }; 00026 00027 enum MouseButton 00028 { 00029 MOUSE_BUTTON_LEFT = 0x1, 00030 MOUSE_BUTTON_RIGHT = 0x2, 00031 MOUSE_BUTTON_MIDDLE = 0x4, 00032 }; 00033 00034 /** 00035 * Report descriptor for a standard 3 buttons + wheel mouse with relative X/Y 00036 * moves 00037 */ 00038 report_map_t MOUSE_REPORT_MAP = { 00039 USAGE_PAGE(1), 0x01, // Generic Desktop 00040 USAGE(1), 0x02, // Mouse 00041 COLLECTION(1), 0x01, // Application 00042 USAGE(1), 0x01, // Pointer 00043 COLLECTION(1), 0x00, // Physical 00044 USAGE_PAGE(1), 0x09, // Buttons 00045 USAGE_MINIMUM(1), 0x01, 00046 USAGE_MAXIMUM(1), 0x03, 00047 LOGICAL_MINIMUM(1), 0x00, 00048 LOGICAL_MAXIMUM(1), 0x01, 00049 REPORT_COUNT(1), 0x03, // 3 bits (Buttons) 00050 REPORT_SIZE(1), 0x01, 00051 INPUT(1), 0x02, // Data, Variable, Absolute 00052 REPORT_COUNT(1), 0x01, // 5 bits (Padding) 00053 REPORT_SIZE(1), 0x05, 00054 INPUT(1), 0x01, // Constant 00055 USAGE_PAGE(1), 0x01, // Generic Desktop 00056 USAGE(1), 0x30, // X 00057 USAGE(1), 0x31, // Y 00058 USAGE(1), 0x38, // Wheel 00059 LOGICAL_MINIMUM(1), 0x81, // -127 00060 LOGICAL_MAXIMUM(1), 0x7f, // 127 00061 REPORT_SIZE(1), 0x08, // Three bytes 00062 REPORT_COUNT(1), 0x03, 00063 INPUT(1), 0x06, // Data, Variable, Relative 00064 END_COLLECTION(0), 00065 END_COLLECTION(0), 00066 }; 00067 00068 uint8_t report[] = { 0, 0, 0, 0 }; 00069 00070 /** 00071 * @class MouseService 00072 * @brief HID-over-Gatt mouse service. 00073 * 00074 * Send mouse moves and button informations over BLE. 00075 * 00076 * @code 00077 * BLE ble; 00078 * MouseService mouse(ble); 00079 * 00080 * Timeout timeout; 00081 * 00082 * void stop_mouse_move(void) 00083 * { 00084 * // Set mouse state to immobile 00085 * mouse.setButton(MOUSE_BUTTON_LEFT, MOUSE_UP); 00086 * mouse.setSpeed(0, 0, 0); 00087 * } 00088 * 00089 * void start_mouse_move(void) 00090 * { 00091 * // Move left with a left button down. If the focus is on a drawing 00092 * // software, for instance, this should draw a line. 00093 * mouse.setButton(MOUSE_BUTTON_LEFT, MOUSE_DOWN); 00094 * mouse.setSpeed(1, 0, 0); 00095 * 00096 * timeout.attach(stop_mouse_move, 0.2); 00097 * } 00098 * @endcode 00099 */ 00100 class MouseService: public HIDServiceBase 00101 { 00102 public: 00103 MouseService(BLE &_ble) : 00104 HIDServiceBase(_ble, 00105 MOUSE_REPORT_MAP, sizeof(MOUSE_REPORT_MAP), 00106 inputReport = report, 00107 outputReport = NULL, 00108 featureReport = NULL, 00109 inputReportLength = sizeof(inputReport), 00110 outputReportLength = 0, 00111 featureReportLength = 0, 00112 reportTickerDelay = 20), 00113 buttonsState (0), 00114 failedReports (0) 00115 { 00116 speed[0] = 0; 00117 speed[1] = 0; 00118 speed[2] = 0; 00119 00120 startReportTicker(); 00121 } 00122 00123 void onConnection(const Gap::ConnectionCallbackParams_t *params) 00124 { 00125 HIDServiceBase::onConnection(params); 00126 startReportTicker(); 00127 } 00128 00129 void onDisconnection(const Gap::DisconnectionCallbackParams_t *params) 00130 { 00131 stopReportTicker(); 00132 HIDServiceBase::onDisconnection(params); 00133 } 00134 00135 /** 00136 * Set X, Y, Z speed of the mouse. Parameters are sticky and will be 00137 * transmitted on every tick. Users should therefore reset them to 0 when 00138 * the device is immobile. 00139 * 00140 * @param x Speed on hoizontal axis 00141 * @param y Speed on vertical axis 00142 * @param wheel Scroll speed 00143 * 00144 * @returns A status code 00145 * 00146 * @note Directions depend on the operating system's configuration. It is 00147 * customary to increase values on the X axis from left to right, and on the 00148 * Y axis from top to bottom. 00149 * Wheel is less standard, although positive values will usually scroll up. 00150 */ 00151 int setSpeed(int8_t x, int8_t y, int8_t wheel) 00152 { 00153 speed[0] = x; 00154 speed[1] = y; 00155 speed[2] = wheel; 00156 00157 startReportTicker(); 00158 00159 return 0; 00160 } 00161 00162 /** 00163 * Toggle the state of one button 00164 * 00165 * @returns A status code 00166 */ 00167 int setButton(MouseButton button, ButtonState state) 00168 { 00169 if (state == BUTTON_UP) 00170 buttonsState &= ~(button); 00171 else 00172 buttonsState |= button; 00173 00174 startReportTicker(); 00175 00176 return 0; 00177 } 00178 00179 /** 00180 * Called by the report ticker 00181 */ 00182 virtual void sendCallback(void) { 00183 uint8_t buttons = buttonsState & 0x7; 00184 00185 if (!connected) 00186 return; 00187 00188 bool can_sleep = (report[0] == 0 00189 && report[1] == 0 00190 && report[2] == 0 00191 && report[3] == 0 00192 && report[0] == buttons 00193 && report[1] == speed[0] 00194 && report[2] == speed[1] 00195 && report[3] == speed[2]); 00196 00197 if (can_sleep) { 00198 /* TODO: find out why there always is two more calls to sendCallback after this 00199 * stopReportTicker(). */ 00200 stopReportTicker(); 00201 return; 00202 } 00203 00204 report[0] = buttons; 00205 report[1] = speed[0]; 00206 report[2] = speed[1]; 00207 report[3] = speed[2]; 00208 00209 if (send(report)) 00210 failedReports++; 00211 } 00212 00213 protected: 00214 uint8_t buttonsState; 00215 uint8_t speed[3]; 00216 00217 public: 00218 uint32_t failedReports; 00219 }; 00220
Generated on Mon Jul 18 2022 14:25:12 by 1.7.2