HID-over-GATT implementation with the BLE API. This library allows to create devices such as mouse, keyboard or joystick, over Bluetooth Low Energy.

Dependents:   BLENano_HID BLE_HID_MouseScrollDemo BLE_HID_KeyboardStreamDemo Shervs_TestKeyboard_TinyBLE ... more

The development repository is currently hosted on github. It contains examples and documentation. This is a snapshot of the library. The documentation can be read on github, or on docs.mbed.com.

Committer:
Jean-Philippe Brucker
Date:
Wed Oct 07 11:29:52 2015 +0100
Revision:
1:7a6c2e2c9371
Parent:
0:cfd70fa91663
Publish version 0.1 of the BLE HID lib

This version number is completely arbitrary, and probably won't stick: once the
service is stable, we'll merge it with BLE API.
It is simply used to keep examples in sync with the lib and the github
repository during development.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jean-Philippe Brucker 1:7a6c2e2c9371 1 /* mbed Microcontroller Library
Jean-Philippe Brucker 1:7a6c2e2c9371 2 * Copyright (c) 2015 ARM Limited
Jean-Philippe Brucker 1:7a6c2e2c9371 3 *
Jean-Philippe Brucker 1:7a6c2e2c9371 4 * Licensed under the Apache License, Version 2.0 (the "License");
Jean-Philippe Brucker 1:7a6c2e2c9371 5 * you may not use this file except in compliance with the License.
Jean-Philippe Brucker 1:7a6c2e2c9371 6 * You may obtain a copy of the License at
Jean-Philippe Brucker 1:7a6c2e2c9371 7 *
Jean-Philippe Brucker 1:7a6c2e2c9371 8 * http://www.apache.org/licenses/LICENSE-2.0
Jean-Philippe Brucker 1:7a6c2e2c9371 9 *
Jean-Philippe Brucker 1:7a6c2e2c9371 10 * Unless required by applicable law or agreed to in writing, software
Jean-Philippe Brucker 1:7a6c2e2c9371 11 * distributed under the License is distributed on an "AS IS" BASIS,
Jean-Philippe Brucker 1:7a6c2e2c9371 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Jean-Philippe Brucker 1:7a6c2e2c9371 13 * See the License for the specific language governing permissions and
Jean-Philippe Brucker 1:7a6c2e2c9371 14 * limitations under the License.
Jean-Philippe Brucker 1:7a6c2e2c9371 15 */
Jean-Philippe Brucker 1:7a6c2e2c9371 16
Jean-Philippe Brucker 0:cfd70fa91663 17 #include "mbed.h"
Jean-Philippe Brucker 0:cfd70fa91663 18
Jean-Philippe Brucker 0:cfd70fa91663 19 #include "HIDServiceBase.h"
Jean-Philippe Brucker 0:cfd70fa91663 20
Jean-Philippe Brucker 0:cfd70fa91663 21 enum ButtonState
Jean-Philippe Brucker 0:cfd70fa91663 22 {
Jean-Philippe Brucker 0:cfd70fa91663 23 BUTTON_UP,
Jean-Philippe Brucker 0:cfd70fa91663 24 BUTTON_DOWN
Jean-Philippe Brucker 0:cfd70fa91663 25 };
Jean-Philippe Brucker 0:cfd70fa91663 26
Jean-Philippe Brucker 0:cfd70fa91663 27 enum JoystickButton
Jean-Philippe Brucker 0:cfd70fa91663 28 {
Jean-Philippe Brucker 0:cfd70fa91663 29 JOYSTICK_BUTTON_1 = 0x1,
Jean-Philippe Brucker 0:cfd70fa91663 30 JOYSTICK_BUTTON_2 = 0x2,
Jean-Philippe Brucker 0:cfd70fa91663 31 };
Jean-Philippe Brucker 0:cfd70fa91663 32
Jean-Philippe Brucker 0:cfd70fa91663 33 report_map_t JOYSTICK_REPORT_MAP = {
Jean-Philippe Brucker 0:cfd70fa91663 34 USAGE_PAGE(1), 0x01, // Generic Desktop
Jean-Philippe Brucker 0:cfd70fa91663 35 USAGE(1), 0x04, // Joystick
Jean-Philippe Brucker 0:cfd70fa91663 36 COLLECTION(1), 0x01, // Application
Jean-Philippe Brucker 0:cfd70fa91663 37 COLLECTION(1), 0x00, // Physical
Jean-Philippe Brucker 0:cfd70fa91663 38 USAGE_PAGE(1), 0x09, // Buttons
Jean-Philippe Brucker 0:cfd70fa91663 39 USAGE_MINIMUM(1), 0x01,
Jean-Philippe Brucker 0:cfd70fa91663 40 USAGE_MAXIMUM(1), 0x03,
Jean-Philippe Brucker 0:cfd70fa91663 41 LOGICAL_MINIMUM(1), 0x00,
Jean-Philippe Brucker 0:cfd70fa91663 42 LOGICAL_MAXIMUM(1), 0x01,
Jean-Philippe Brucker 0:cfd70fa91663 43 REPORT_COUNT(1), 0x03, // 2 bits (Buttons)
Jean-Philippe Brucker 0:cfd70fa91663 44 REPORT_SIZE(1), 0x01,
Jean-Philippe Brucker 0:cfd70fa91663 45 INPUT(1), 0x02, // Data, Variable, Absolute
Jean-Philippe Brucker 0:cfd70fa91663 46 REPORT_COUNT(1), 0x01, // 6 bits (Padding)
Jean-Philippe Brucker 0:cfd70fa91663 47 REPORT_SIZE(1), 0x05,
Jean-Philippe Brucker 0:cfd70fa91663 48 INPUT(1), 0x01, // Constant
Jean-Philippe Brucker 0:cfd70fa91663 49 USAGE_PAGE(1), 0x01, // Generic Desktop
Jean-Philippe Brucker 0:cfd70fa91663 50 USAGE(1), 0x30, // X
Jean-Philippe Brucker 0:cfd70fa91663 51 USAGE(1), 0x31, // Y
Jean-Philippe Brucker 0:cfd70fa91663 52 USAGE(1), 0x32, // Z
Jean-Philippe Brucker 0:cfd70fa91663 53 USAGE(1), 0x33, // Rx
Jean-Philippe Brucker 0:cfd70fa91663 54 LOGICAL_MINIMUM(1), 0x81, // -127
Jean-Philippe Brucker 0:cfd70fa91663 55 LOGICAL_MAXIMUM(1), 0x7f, // 127
Jean-Philippe Brucker 0:cfd70fa91663 56 REPORT_SIZE(1), 0x08, // Three bytes
Jean-Philippe Brucker 0:cfd70fa91663 57 REPORT_COUNT(1), 0x04,
Jean-Philippe Brucker 0:cfd70fa91663 58 INPUT(1), 0x02, // Data, Variable, Absolute (unlike mouse)
Jean-Philippe Brucker 0:cfd70fa91663 59 END_COLLECTION(0),
Jean-Philippe Brucker 0:cfd70fa91663 60 END_COLLECTION(0),
Jean-Philippe Brucker 0:cfd70fa91663 61 };
Jean-Philippe Brucker 0:cfd70fa91663 62
Jean-Philippe Brucker 0:cfd70fa91663 63 uint8_t report[] = { 0, 0, 0, 0, 0 };
Jean-Philippe Brucker 0:cfd70fa91663 64
Jean-Philippe Brucker 0:cfd70fa91663 65 class JoystickService: public HIDServiceBase
Jean-Philippe Brucker 0:cfd70fa91663 66 {
Jean-Philippe Brucker 0:cfd70fa91663 67 public:
Jean-Philippe Brucker 0:cfd70fa91663 68 JoystickService(BLE &_ble) :
Jean-Philippe Brucker 0:cfd70fa91663 69 HIDServiceBase(_ble,
Jean-Philippe Brucker 0:cfd70fa91663 70 JOYSTICK_REPORT_MAP, sizeof(JOYSTICK_REPORT_MAP),
Jean-Philippe Brucker 0:cfd70fa91663 71 inputReport = report,
Jean-Philippe Brucker 0:cfd70fa91663 72 outputReport = NULL,
Jean-Philippe Brucker 0:cfd70fa91663 73 featureReport = NULL,
Jean-Philippe Brucker 0:cfd70fa91663 74 inputReportLength = sizeof(inputReport),
Jean-Philippe Brucker 0:cfd70fa91663 75 outputReportLength = 0,
Jean-Philippe Brucker 0:cfd70fa91663 76 featureReportLength = 0,
Jean-Philippe Brucker 0:cfd70fa91663 77 reportTickerDelay = 20),
Jean-Philippe Brucker 0:cfd70fa91663 78 buttonsState (0),
Jean-Philippe Brucker 0:cfd70fa91663 79 failedReports (0)
Jean-Philippe Brucker 0:cfd70fa91663 80 {
Jean-Philippe Brucker 0:cfd70fa91663 81 speed[0] = 0;
Jean-Philippe Brucker 0:cfd70fa91663 82 speed[1] = 0;
Jean-Philippe Brucker 0:cfd70fa91663 83 speed[2] = 0;
Jean-Philippe Brucker 0:cfd70fa91663 84 speed[3] = 0;
Jean-Philippe Brucker 0:cfd70fa91663 85
Jean-Philippe Brucker 0:cfd70fa91663 86 startReportTicker();
Jean-Philippe Brucker 0:cfd70fa91663 87 }
Jean-Philippe Brucker 0:cfd70fa91663 88
Jean-Philippe Brucker 0:cfd70fa91663 89 int setSpeed(int8_t x, int8_t y, int8_t z)
Jean-Philippe Brucker 0:cfd70fa91663 90 {
Jean-Philippe Brucker 0:cfd70fa91663 91 speed[0] = x;
Jean-Philippe Brucker 0:cfd70fa91663 92 speed[1] = y;
Jean-Philippe Brucker 0:cfd70fa91663 93 speed[2] = z;
Jean-Philippe Brucker 0:cfd70fa91663 94
Jean-Philippe Brucker 0:cfd70fa91663 95 return 0;
Jean-Philippe Brucker 0:cfd70fa91663 96 }
Jean-Philippe Brucker 0:cfd70fa91663 97
Jean-Philippe Brucker 0:cfd70fa91663 98 int setButton(JoystickButton button, ButtonState state)
Jean-Philippe Brucker 0:cfd70fa91663 99 {
Jean-Philippe Brucker 0:cfd70fa91663 100 if (state == BUTTON_UP)
Jean-Philippe Brucker 0:cfd70fa91663 101 buttonsState &= ~(button);
Jean-Philippe Brucker 0:cfd70fa91663 102 else
Jean-Philippe Brucker 0:cfd70fa91663 103 buttonsState |= button;
Jean-Philippe Brucker 0:cfd70fa91663 104
Jean-Philippe Brucker 0:cfd70fa91663 105 return 0;
Jean-Philippe Brucker 0:cfd70fa91663 106 }
Jean-Philippe Brucker 0:cfd70fa91663 107
Jean-Philippe Brucker 0:cfd70fa91663 108 virtual void sendCallback(void) {
Jean-Philippe Brucker 0:cfd70fa91663 109 if (!connected)
Jean-Philippe Brucker 0:cfd70fa91663 110 return;
Jean-Philippe Brucker 0:cfd70fa91663 111
Jean-Philippe Brucker 0:cfd70fa91663 112 report[0] = buttonsState & 0x7;
Jean-Philippe Brucker 0:cfd70fa91663 113 report[1] = speed[0];
Jean-Philippe Brucker 0:cfd70fa91663 114 report[2] = speed[1];
Jean-Philippe Brucker 0:cfd70fa91663 115 report[3] = speed[2];
Jean-Philippe Brucker 0:cfd70fa91663 116 report[4] = speed[3];
Jean-Philippe Brucker 0:cfd70fa91663 117
Jean-Philippe Brucker 0:cfd70fa91663 118 if (send(report))
Jean-Philippe Brucker 0:cfd70fa91663 119 failedReports++;
Jean-Philippe Brucker 0:cfd70fa91663 120 }
Jean-Philippe Brucker 0:cfd70fa91663 121
Jean-Philippe Brucker 0:cfd70fa91663 122 protected:
Jean-Philippe Brucker 0:cfd70fa91663 123 uint8_t buttonsState;
Jean-Philippe Brucker 0:cfd70fa91663 124 uint8_t speed[4];
Jean-Philippe Brucker 0:cfd70fa91663 125
Jean-Philippe Brucker 0:cfd70fa91663 126 public:
Jean-Philippe Brucker 0:cfd70fa91663 127 uint32_t failedReports;
Jean-Philippe Brucker 0:cfd70fa91663 128 };