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: Seeed_Tiny_BLE_FTHR_Peripheral
Fork of BLE_HID by
JoystickService.h@1:7a6c2e2c9371, 2015-10-07 (annotated)
- Committer:
- Jean-Philippe Brucker
- Date:
- Wed Oct 07 11:29:52 2015 +0100
- Revision:
- 1:7a6c2e2c9371
- Parent:
- 0:cfd70fa91663
- Child:
- 4:24365c168c4e
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?
User | Revision | Line number | New 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 | }; |