back up of work during May 2019

Dependencies:   microbit

Committer:
xx316
Date:
Fri May 31 20:53:51 2019 +0000
Revision:
1:c840c2b6f490
This is the program for bit_board, an accessory developed by a group of Imperial EEE students for MicroBit. This is the first commit to backup the work in May 2019.

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