back up of work during May 2019

Dependencies:   microbit

Committer:
tht216
Date:
Wed Jun 05 15:21:14 2019 +0000
Branch:
class_implmentation
Revision:
6:f372773ad32f
Parent:
1:c840c2b6f490
TODO:; 1. multi keypresses; 2. integration

Who changed what in which revision?

UserRevisionLine numberNew contents of line
xx316 1:c840c2b6f490 1 /* mbed Microcontroller Library
xx316 1:c840c2b6f490 2 * Copyright (c) 2015 ARM Limited
xx316 1:c840c2b6f490 3 *
xx316 1:c840c2b6f490 4 * Licensed under the Apache License, Version 2.0 (the "License");
xx316 1:c840c2b6f490 5 * you may not use this file except in compliance with the License.
xx316 1:c840c2b6f490 6 * You may obtain a copy of the License at
xx316 1:c840c2b6f490 7 *
xx316 1:c840c2b6f490 8 * http://www.apache.org/licenses/LICENSE-2.0
xx316 1:c840c2b6f490 9 *
xx316 1:c840c2b6f490 10 * Unless required by applicable law or agreed to in writing, software
xx316 1:c840c2b6f490 11 * distributed under the License is distributed on an "AS IS" BASIS,
xx316 1:c840c2b6f490 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
xx316 1:c840c2b6f490 13 * See the License for the specific language governing permissions and
xx316 1:c840c2b6f490 14 * limitations under the License.
xx316 1:c840c2b6f490 15 */
xx316 1:c840c2b6f490 16
xx316 1:c840c2b6f490 17 #include "mbed.h"
xx316 1:c840c2b6f490 18
xx316 1:c840c2b6f490 19 #include "HIDServiceBase.h"
xx316 1:c840c2b6f490 20
xx316 1:c840c2b6f490 21 enum ButtonState
xx316 1:c840c2b6f490 22 {
xx316 1:c840c2b6f490 23 BUTTON_UP,
xx316 1:c840c2b6f490 24 BUTTON_DOWN
xx316 1:c840c2b6f490 25 };
xx316 1:c840c2b6f490 26
xx316 1:c840c2b6f490 27 enum MouseButton
xx316 1:c840c2b6f490 28 {
xx316 1:c840c2b6f490 29 MOUSE_BUTTON_LEFT = 0x1,
xx316 1:c840c2b6f490 30 MOUSE_BUTTON_RIGHT = 0x2,
xx316 1:c840c2b6f490 31 MOUSE_BUTTON_MIDDLE = 0x4,
xx316 1:c840c2b6f490 32 };
xx316 1:c840c2b6f490 33
xx316 1:c840c2b6f490 34 /**
xx316 1:c840c2b6f490 35 * Report descriptor for a standard 3 buttons + wheel mouse with relative X/Y
xx316 1:c840c2b6f490 36 * moves
xx316 1:c840c2b6f490 37 */
xx316 1:c840c2b6f490 38 report_map_t MOUSE_REPORT_MAP = {
xx316 1:c840c2b6f490 39 USAGE_PAGE(1), 0x01, // Generic Desktop
xx316 1:c840c2b6f490 40 USAGE(1), 0x02, // Mouse
xx316 1:c840c2b6f490 41 COLLECTION(1), 0x01, // Application
xx316 1:c840c2b6f490 42 USAGE(1), 0x01, // Pointer
xx316 1:c840c2b6f490 43 COLLECTION(1), 0x00, // Physical
xx316 1:c840c2b6f490 44 USAGE_PAGE(1), 0x09, // Buttons
xx316 1:c840c2b6f490 45 USAGE_MINIMUM(1), 0x01,
xx316 1:c840c2b6f490 46 USAGE_MAXIMUM(1), 0x03,
xx316 1:c840c2b6f490 47 LOGICAL_MINIMUM(1), 0x00,
xx316 1:c840c2b6f490 48 LOGICAL_MAXIMUM(1), 0x01,
xx316 1:c840c2b6f490 49 REPORT_COUNT(1), 0x03, // 3 bits (Buttons)
xx316 1:c840c2b6f490 50 REPORT_SIZE(1), 0x01,
xx316 1:c840c2b6f490 51 INPUT(1), 0x02, // Data, Variable, Absolute
xx316 1:c840c2b6f490 52 REPORT_COUNT(1), 0x01, // 5 bits (Padding)
xx316 1:c840c2b6f490 53 REPORT_SIZE(1), 0x05,
xx316 1:c840c2b6f490 54 INPUT(1), 0x01, // Constant
xx316 1:c840c2b6f490 55 USAGE_PAGE(1), 0x01, // Generic Desktop
xx316 1:c840c2b6f490 56 USAGE(1), 0x30, // X
xx316 1:c840c2b6f490 57 USAGE(1), 0x31, // Y
xx316 1:c840c2b6f490 58 USAGE(1), 0x38, // Wheel
xx316 1:c840c2b6f490 59 LOGICAL_MINIMUM(1), 0x81, // -127
xx316 1:c840c2b6f490 60 LOGICAL_MAXIMUM(1), 0x7f, // 127
xx316 1:c840c2b6f490 61 REPORT_SIZE(1), 0x08, // Three bytes
xx316 1:c840c2b6f490 62 REPORT_COUNT(1), 0x03,
xx316 1:c840c2b6f490 63 INPUT(1), 0x06, // Data, Variable, Relative
xx316 1:c840c2b6f490 64 END_COLLECTION(0),
xx316 1:c840c2b6f490 65 END_COLLECTION(0),
xx316 1:c840c2b6f490 66 };
xx316 1:c840c2b6f490 67
xx316 1:c840c2b6f490 68 uint8_t report[] = { 0, 0, 0, 0 };
xx316 1:c840c2b6f490 69
xx316 1:c840c2b6f490 70 /**
xx316 1:c840c2b6f490 71 * @class MouseService
xx316 1:c840c2b6f490 72 * @brief HID-over-Gatt mouse service.
xx316 1:c840c2b6f490 73 *
xx316 1:c840c2b6f490 74 * Send mouse moves and button informations over BLE.
xx316 1:c840c2b6f490 75 *
xx316 1:c840c2b6f490 76 * @code
xx316 1:c840c2b6f490 77 * BLE ble;
xx316 1:c840c2b6f490 78 * MouseService mouse(ble);
xx316 1:c840c2b6f490 79 *
xx316 1:c840c2b6f490 80 * Timeout timeout;
xx316 1:c840c2b6f490 81 *
xx316 1:c840c2b6f490 82 * void stop_mouse_move(void)
xx316 1:c840c2b6f490 83 * {
xx316 1:c840c2b6f490 84 * // Set mouse state to immobile
xx316 1:c840c2b6f490 85 * mouse.setButton(MOUSE_BUTTON_LEFT, MOUSE_UP);
xx316 1:c840c2b6f490 86 * mouse.setSpeed(0, 0, 0);
xx316 1:c840c2b6f490 87 * }
xx316 1:c840c2b6f490 88 *
xx316 1:c840c2b6f490 89 * void start_mouse_move(void)
xx316 1:c840c2b6f490 90 * {
xx316 1:c840c2b6f490 91 * // Move left with a left button down. If the focus is on a drawing
xx316 1:c840c2b6f490 92 * // software, for instance, this should draw a line.
xx316 1:c840c2b6f490 93 * mouse.setButton(MOUSE_BUTTON_LEFT, MOUSE_DOWN);
xx316 1:c840c2b6f490 94 * mouse.setSpeed(1, 0, 0);
xx316 1:c840c2b6f490 95 *
xx316 1:c840c2b6f490 96 * timeout.attach(stop_mouse_move, 0.2);
xx316 1:c840c2b6f490 97 * }
xx316 1:c840c2b6f490 98 * @endcode
xx316 1:c840c2b6f490 99 */
xx316 1:c840c2b6f490 100 class MouseService: public HIDServiceBase
xx316 1:c840c2b6f490 101 {
xx316 1:c840c2b6f490 102 public:
xx316 1:c840c2b6f490 103 MouseService(BLE &_ble) :
xx316 1:c840c2b6f490 104 HIDServiceBase(_ble,
xx316 1:c840c2b6f490 105 MOUSE_REPORT_MAP, sizeof(MOUSE_REPORT_MAP),
xx316 1:c840c2b6f490 106 inputReport = report,
xx316 1:c840c2b6f490 107 outputReport = NULL,
xx316 1:c840c2b6f490 108 featureReport = NULL,
xx316 1:c840c2b6f490 109 inputReportLength = sizeof(inputReport),
xx316 1:c840c2b6f490 110 outputReportLength = 0,
xx316 1:c840c2b6f490 111 featureReportLength = 0,
xx316 1:c840c2b6f490 112 reportTickerDelay = 20),
xx316 1:c840c2b6f490 113 buttonsState (0),
xx316 1:c840c2b6f490 114 failedReports (0)
xx316 1:c840c2b6f490 115 {
xx316 1:c840c2b6f490 116 speed[0] = 0;
xx316 1:c840c2b6f490 117 speed[1] = 0;
xx316 1:c840c2b6f490 118 speed[2] = 0;
xx316 1:c840c2b6f490 119
xx316 1:c840c2b6f490 120 startReportTicker();
xx316 1:c840c2b6f490 121 }
xx316 1:c840c2b6f490 122
xx316 1:c840c2b6f490 123 void onConnection(const Gap::ConnectionCallbackParams_t *params)
xx316 1:c840c2b6f490 124 {
xx316 1:c840c2b6f490 125 HIDServiceBase::onConnection(params);
xx316 1:c840c2b6f490 126 startReportTicker();
xx316 1:c840c2b6f490 127 }
xx316 1:c840c2b6f490 128
xx316 1:c840c2b6f490 129 void onDisconnection(const Gap::DisconnectionCallbackParams_t *params)
xx316 1:c840c2b6f490 130 {
xx316 1:c840c2b6f490 131 stopReportTicker();
xx316 1:c840c2b6f490 132 HIDServiceBase::onDisconnection(params);
xx316 1:c840c2b6f490 133 }
xx316 1:c840c2b6f490 134
xx316 1:c840c2b6f490 135 /**
xx316 1:c840c2b6f490 136 * Set X, Y, Z speed of the mouse. Parameters are sticky and will be
xx316 1:c840c2b6f490 137 * transmitted on every tick. Users should therefore reset them to 0 when
xx316 1:c840c2b6f490 138 * the device is immobile.
xx316 1:c840c2b6f490 139 *
xx316 1:c840c2b6f490 140 * @param x Speed on hoizontal axis
xx316 1:c840c2b6f490 141 * @param y Speed on vertical axis
xx316 1:c840c2b6f490 142 * @param wheel Scroll speed
xx316 1:c840c2b6f490 143 *
xx316 1:c840c2b6f490 144 * @returns A status code
xx316 1:c840c2b6f490 145 *
xx316 1:c840c2b6f490 146 * @note Directions depend on the operating system's configuration. It is
xx316 1:c840c2b6f490 147 * customary to increase values on the X axis from left to right, and on the
xx316 1:c840c2b6f490 148 * Y axis from top to bottom.
xx316 1:c840c2b6f490 149 * Wheel is less standard, although positive values will usually scroll up.
xx316 1:c840c2b6f490 150 */
xx316 1:c840c2b6f490 151 int setSpeed(int8_t x, int8_t y, int8_t wheel)
xx316 1:c840c2b6f490 152 {
xx316 1:c840c2b6f490 153 speed[0] = x;
xx316 1:c840c2b6f490 154 speed[1] = y;
xx316 1:c840c2b6f490 155 speed[2] = wheel;
xx316 1:c840c2b6f490 156
xx316 1:c840c2b6f490 157 startReportTicker();
xx316 1:c840c2b6f490 158
xx316 1:c840c2b6f490 159 return 0;
xx316 1:c840c2b6f490 160 }
xx316 1:c840c2b6f490 161
xx316 1:c840c2b6f490 162 /**
xx316 1:c840c2b6f490 163 * Toggle the state of one button
xx316 1:c840c2b6f490 164 *
xx316 1:c840c2b6f490 165 * @returns A status code
xx316 1:c840c2b6f490 166 */
xx316 1:c840c2b6f490 167 int setButton(MouseButton button, ButtonState state)
xx316 1:c840c2b6f490 168 {
xx316 1:c840c2b6f490 169 if (state == BUTTON_UP)
xx316 1:c840c2b6f490 170 buttonsState &= ~(button);
xx316 1:c840c2b6f490 171 else
xx316 1:c840c2b6f490 172 buttonsState |= button;
xx316 1:c840c2b6f490 173
xx316 1:c840c2b6f490 174 startReportTicker();
xx316 1:c840c2b6f490 175
xx316 1:c840c2b6f490 176 return 0;
xx316 1:c840c2b6f490 177 }
xx316 1:c840c2b6f490 178
xx316 1:c840c2b6f490 179 /**
xx316 1:c840c2b6f490 180 * Called by the report ticker
xx316 1:c840c2b6f490 181 */
xx316 1:c840c2b6f490 182 virtual void sendCallback(void) {
xx316 1:c840c2b6f490 183 uint8_t buttons = buttonsState & 0x7;
xx316 1:c840c2b6f490 184
xx316 1:c840c2b6f490 185 if (!connected)
xx316 1:c840c2b6f490 186 return;
xx316 1:c840c2b6f490 187
xx316 1:c840c2b6f490 188 bool can_sleep = (report[0] == 0
xx316 1:c840c2b6f490 189 && report[1] == 0
xx316 1:c840c2b6f490 190 && report[2] == 0
xx316 1:c840c2b6f490 191 && report[3] == 0
xx316 1:c840c2b6f490 192 && report[0] == buttons
xx316 1:c840c2b6f490 193 && report[1] == speed[0]
xx316 1:c840c2b6f490 194 && report[2] == speed[1]
xx316 1:c840c2b6f490 195 && report[3] == speed[2]);
xx316 1:c840c2b6f490 196
xx316 1:c840c2b6f490 197 if (can_sleep) {
xx316 1:c840c2b6f490 198 /* TODO: find out why there always is two more calls to sendCallback after this
xx316 1:c840c2b6f490 199 * stopReportTicker(). */
xx316 1:c840c2b6f490 200 stopReportTicker();
xx316 1:c840c2b6f490 201 return;
xx316 1:c840c2b6f490 202 }
xx316 1:c840c2b6f490 203
xx316 1:c840c2b6f490 204 report[0] = buttons;
xx316 1:c840c2b6f490 205 report[1] = speed[0];
xx316 1:c840c2b6f490 206 report[2] = speed[1];
xx316 1:c840c2b6f490 207 report[3] = speed[2];
xx316 1:c840c2b6f490 208
xx316 1:c840c2b6f490 209 if (send(report))
xx316 1:c840c2b6f490 210 failedReports++;
xx316 1:c840c2b6f490 211 }
xx316 1:c840c2b6f490 212
xx316 1:c840c2b6f490 213 protected:
xx316 1:c840c2b6f490 214 uint8_t buttonsState;
xx316 1:c840c2b6f490 215 uint8_t speed[3];
xx316 1:c840c2b6f490 216
xx316 1:c840c2b6f490 217 public:
xx316 1:c840c2b6f490 218 uint32_t failedReports;
xx316 1:c840c2b6f490 219 };
xx316 1:c840c2b6f490 220