BLE HID keyboard with gesture

Dependencies:   BLE_API BLE_HID PAJ7620U2 mbed nRF51822

https://mtmtechblog.files.wordpress.com/2017/01/mtsense04-pi-on-mbed.jpeg We have full tutorial, please visit our blog

Committer:
bcc6
Date:
Tue Jan 17 03:53:35 2017 +0000
Revision:
3:656f8fb89f05
Parent:
2:6109e375f9a7
After reset, purge all bonding state.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mtmkimi 2:6109e375f9a7 1 /* Copyright (c) 2016 MtM Technology Corporation, MIT License
mtmkimi 2:6109e375f9a7 2 *
mtmkimi 2:6109e375f9a7 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
mtmkimi 2:6109e375f9a7 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
mtmkimi 2:6109e375f9a7 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
mtmkimi 2:6109e375f9a7 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
mtmkimi 2:6109e375f9a7 7 * furnished to do so, subject to the following conditions:
mtmkimi 2:6109e375f9a7 8 *
mtmkimi 2:6109e375f9a7 9 * The above copyright notice and this permission notice shall be included in all copies or
mtmkimi 2:6109e375f9a7 10 * substantial portions of the Software.
mtmkimi 2:6109e375f9a7 11 *
mtmkimi 2:6109e375f9a7 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
mtmkimi 2:6109e375f9a7 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
mtmkimi 2:6109e375f9a7 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
mtmkimi 2:6109e375f9a7 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
mtmkimi 2:6109e375f9a7 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
mtmkimi 2:6109e375f9a7 17 */
bcc6 0:55c7f79a524c 18 #include "mbed.h"
bcc6 0:55c7f79a524c 19 #include "ble/BLE.h"
bcc6 0:55c7f79a524c 20
bcc6 3:656f8fb89f05 21 #include "debug.h"
mtmkimi 2:6109e375f9a7 22 #include "PAJ7620U2.h"
bcc6 0:55c7f79a524c 23
bcc6 3:656f8fb89f05 24 #include "BLE_HID/DeviceInformationService.h"
bcc6 3:656f8fb89f05 25 #include "BLE_HID/BatteryService.h"
bcc6 3:656f8fb89f05 26 #include "BLE_HID/HIDServiceBase.h"
bcc6 3:656f8fb89f05 27 #include "BLE_HID/KeyboardService.h"
bcc6 0:55c7f79a524c 28
bcc6 0:55c7f79a524c 29
bcc6 3:656f8fb89f05 30 #define DEVICE_NAME ("MtM_gHID")
bcc6 3:656f8fb89f05 31
bcc6 3:656f8fb89f05 32 #define TX_POWER_dBm (0) // -40, -20, -16, -12, -8, -4, 0, 4
bcc6 3:656f8fb89f05 33
bcc6 3:656f8fb89f05 34 #define BD_ADDRESS_TYPE (BLEProtocol::AddressType::RANDOM_STATIC)
bcc6 3:656f8fb89f05 35 #define BD_ADDRESS ((Gap::Address_t){0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC})
bcc6 3:656f8fb89f05 36
bcc6 3:656f8fb89f05 37 #define ENABLE_BONDING (true)
bcc6 3:656f8fb89f05 38 #define REQUIRE_MITM (false)
bcc6 3:656f8fb89f05 39 #define IOCAPS (SecurityManager::IO_CAPS_NONE)
bcc6 3:656f8fb89f05 40 #define PASSKEY ((SecurityManager::Passkey_t){'1', '2', '3', '4', '5', '6'})
bcc6 3:656f8fb89f05 41
bcc6 3:656f8fb89f05 42 #define MANUFACTURERS_NAME ("MtM")
bcc6 3:656f8fb89f05 43 #define MODEL_NAME (NULL)
bcc6 3:656f8fb89f05 44 #define SERIAL_NUMBER (NULL)
bcc6 3:656f8fb89f05 45 #define HW_VERSION (NULL)
bcc6 3:656f8fb89f05 46 #define FW_VERSION (NULL)
bcc6 3:656f8fb89f05 47 #define SW_VERSION (NULL)
bcc6 3:656f8fb89f05 48 #if 0
bcc6 3:656f8fb89f05 49 #define PNP_ID &((PnPID_t){0x01, 0xFFFE, 0x0001, 0x0001}) // From Bluetooth SIG
bcc6 3:656f8fb89f05 50 #else
bcc6 3:656f8fb89f05 51 #define PNP_ID &((PnPID_t){0x02, 0x1915, 0xEEEE, 0x0001}) // From USB-IF
bcc6 0:55c7f79a524c 52 #endif
bcc6 0:55c7f79a524c 53
bcc6 3:656f8fb89f05 54 #define MIN_CONN_INTERVAL (Gap::MSEC_TO_GAP_DURATION_UNITS(10)); // 10ms
bcc6 3:656f8fb89f05 55 #define MAX_CONN_INTERVAL (Gap::MSEC_TO_GAP_DURATION_UNITS(30)); // 30ms
bcc6 3:656f8fb89f05 56 #define SLAVE_LATENCY (6)
bcc6 3:656f8fb89f05 57 #define CONN_SUP_TIMEOUT (43) // 430ms
bcc6 3:656f8fb89f05 58
bcc6 3:656f8fb89f05 59 #define ADV_INTERVAL (50) // 50ms
bcc6 3:656f8fb89f05 60 #define ADV_TIMEOUT (60) // 60sec
bcc6 0:55c7f79a524c 61
bcc6 0:55c7f79a524c 62
bcc6 3:656f8fb89f05 63 /* UART for debug (log, assert) */
bcc6 3:656f8fb89f05 64 Serial dbg(p5, p4);
bcc6 0:55c7f79a524c 65
bcc6 0:55c7f79a524c 66 /* Sensor */
mtmkimi 2:6109e375f9a7 67 PAJ7620U2 gesture(p3, p2, p0);
bcc6 0:55c7f79a524c 68 volatile bool gestureHasIntEvent = false;
bcc6 0:55c7f79a524c 69
bcc6 0:55c7f79a524c 70 /* HID service */
bcc6 0:55c7f79a524c 71 KeyboardService *kbService = NULL;
bcc6 0:55c7f79a524c 72
bcc6 3:656f8fb89f05 73
bcc6 3:656f8fb89f05 74 static void connectionCallback(const Gap::ConnectionCallbackParams_t *params)
bcc6 3:656f8fb89f05 75 {
bcc6 3:656f8fb89f05 76 log("connection\n");
bcc6 0:55c7f79a524c 77
bcc6 3:656f8fb89f05 78 log("role(%d)\n", params->role);
bcc6 3:656f8fb89f05 79 log("peerAddrType(%d), peerAddr(%02X:%02X:%02X:%02X:%02X:%02X)\n",
bcc6 3:656f8fb89f05 80 params->peerAddrType,
bcc6 3:656f8fb89f05 81 params->peerAddr[5], params->peerAddr[4], params->peerAddr[3], params->peerAddr[2], params->peerAddr[1], params->peerAddr[0]);
bcc6 3:656f8fb89f05 82 log("ownAddrType(%d), ownAddr(%02X:%02X:%02X:%02X:%02X:%02X)\n",
bcc6 3:656f8fb89f05 83 params->ownAddrType,
bcc6 3:656f8fb89f05 84 params->ownAddr[5], params->ownAddr[4], params->ownAddr[3], params->ownAddr[2], params->ownAddr[1], params->ownAddr[0]);
bcc6 0:55c7f79a524c 85
bcc6 3:656f8fb89f05 86 log("connectionParams(%d, %d, %d, %d)\n",
bcc6 3:656f8fb89f05 87 params->connectionParams->minConnectionInterval,
bcc6 3:656f8fb89f05 88 params->connectionParams->maxConnectionInterval,
bcc6 3:656f8fb89f05 89 params->connectionParams->slaveLatency,
bcc6 3:656f8fb89f05 90 params->connectionParams->connectionSupervisionTimeout);
bcc6 0:55c7f79a524c 91 }
bcc6 0:55c7f79a524c 92
bcc6 3:656f8fb89f05 93 static void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
bcc6 0:55c7f79a524c 94 {
bcc6 0:55c7f79a524c 95 BLE::Instance().gap().startAdvertising(); // restart advertising
bcc6 0:55c7f79a524c 96
bcc6 3:656f8fb89f05 97 log("disconnection\n");
bcc6 0:55c7f79a524c 98 }
bcc6 0:55c7f79a524c 99
bcc6 3:656f8fb89f05 100 static void timeoutCallback(const Gap::TimeoutSource_t source)
bcc6 0:55c7f79a524c 101 {
bcc6 3:656f8fb89f05 102 log("timeout(%d)\n", source);
bcc6 3:656f8fb89f05 103 }
bcc6 3:656f8fb89f05 104
bcc6 3:656f8fb89f05 105 static void securitySetupInitiatedCallback(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps)
bcc6 3:656f8fb89f05 106 {
bcc6 3:656f8fb89f05 107 log("Security setup initiated\r\n");
bcc6 0:55c7f79a524c 108 }
bcc6 0:55c7f79a524c 109
bcc6 0:55c7f79a524c 110 static void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status)
bcc6 0:55c7f79a524c 111 {
bcc6 0:55c7f79a524c 112 if (status == SecurityManager::SEC_STATUS_SUCCESS) {
bcc6 3:656f8fb89f05 113 log("Security success %d\r\n", status);
bcc6 0:55c7f79a524c 114 } else {
bcc6 3:656f8fb89f05 115 log("Security failed %d\r\n", status);
bcc6 0:55c7f79a524c 116 }
bcc6 0:55c7f79a524c 117 }
bcc6 0:55c7f79a524c 118
bcc6 3:656f8fb89f05 119 static void passkeyDisplayCallback(Gap::Handle_t handle, const SecurityManager::Passkey_t passkey)
bcc6 0:55c7f79a524c 120 {
bcc6 3:656f8fb89f05 121 log("Input passKey: ");
bcc6 3:656f8fb89f05 122 for (unsigned i = 0; i < Gap::ADDR_LEN; i++) {
bcc6 3:656f8fb89f05 123 log("%c", passkey[i]);
bcc6 3:656f8fb89f05 124 }
bcc6 3:656f8fb89f05 125 log("\r\n");
bcc6 0:55c7f79a524c 126 }
bcc6 0:55c7f79a524c 127
bcc6 3:656f8fb89f05 128 static void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
bcc6 0:55c7f79a524c 129 {
bcc6 3:656f8fb89f05 130 log("InitComplete\n");
bcc6 0:55c7f79a524c 131
bcc6 0:55c7f79a524c 132 BLE &ble = params->ble;
bcc6 0:55c7f79a524c 133 ble_error_t error = params->error;
bcc6 0:55c7f79a524c 134
bcc6 3:656f8fb89f05 135 assert(error == BLE_ERROR_NONE);
bcc6 3:656f8fb89f05 136
bcc6 3:656f8fb89f05 137
bcc6 3:656f8fb89f05 138 /* Set Tx power */
bcc6 3:656f8fb89f05 139 error = ble.gap().setTxPower(TX_POWER_dBm);
bcc6 3:656f8fb89f05 140 assert(error == BLE_ERROR_NONE);
bcc6 3:656f8fb89f05 141
bcc6 3:656f8fb89f05 142 /* Set address */
bcc6 3:656f8fb89f05 143 error = ble.gap().setAddress(BD_ADDRESS_TYPE, BD_ADDRESS);
bcc6 3:656f8fb89f05 144 assert(error == BLE_ERROR_NONE);
bcc6 3:656f8fb89f05 145
bcc6 3:656f8fb89f05 146 /* Initialize BLE security */
bcc6 3:656f8fb89f05 147 error = ble.securityManager().init(ENABLE_BONDING, REQUIRE_MITM, IOCAPS, PASSKEY);
bcc6 3:656f8fb89f05 148 assert(error == BLE_ERROR_NONE);
bcc6 3:656f8fb89f05 149
bcc6 3:656f8fb89f05 150 #if 1 // After reset, clear bonding state
bcc6 3:656f8fb89f05 151 /* Purge all bonding state */
bcc6 3:656f8fb89f05 152 error = ble.securityManager().purgeAllBondingState();
bcc6 3:656f8fb89f05 153 assert(error == BLE_ERROR_NONE);
bcc6 3:656f8fb89f05 154 #endif
bcc6 3:656f8fb89f05 155
bcc6 3:656f8fb89f05 156 #if 0 // Disable white-list
bcc6 3:656f8fb89f05 157 /* Set white-list */
bcc6 3:656f8fb89f05 158 BLEProtocol::Address_t addresses[2];
bcc6 3:656f8fb89f05 159 Gap::Whitelist_t whitelist;
bcc6 3:656f8fb89f05 160 whitelist.addresses = addresses;
bcc6 3:656f8fb89f05 161 whitelist.size = 0;
bcc6 3:656f8fb89f05 162 whitelist.capacity = 2;
bcc6 3:656f8fb89f05 163 error = ble.securityManager().getAddressesFromBondTable(whitelist);
bcc6 3:656f8fb89f05 164 assert(error == BLE_ERROR_NONE);
bcc6 3:656f8fb89f05 165
bcc6 3:656f8fb89f05 166 log("getAddressesFromBondTable (%d)\n", whitelist.size);
bcc6 3:656f8fb89f05 167 for(int i=0; i<whitelist.size; i++) {
bcc6 3:656f8fb89f05 168 int type = (int)whitelist.addresses[i].type;
bcc6 3:656f8fb89f05 169 uint8_t *addr = (uint8_t *)whitelist.addresses[i].address;
bcc6 3:656f8fb89f05 170 log("type(%d), addr(%02X:%02X:%02X:%02X:%02X:%02X)\n",
bcc6 3:656f8fb89f05 171 type, addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
bcc6 0:55c7f79a524c 172 }
bcc6 3:656f8fb89f05 173 error = ble.gap().setWhitelist(whitelist);
bcc6 3:656f8fb89f05 174 assert(error == BLE_ERROR_NONE);
bcc6 3:656f8fb89f05 175 error = ble.gap().setAdvertisingPolicyMode(Gap::ADV_POLICY_IGNORE_WHITELIST); // Allow scan requests and connect requests from any device
bcc6 3:656f8fb89f05 176 assert(error == BLE_ERROR_NONE);
bcc6 3:656f8fb89f05 177 #endif
bcc6 0:55c7f79a524c 178
bcc6 3:656f8fb89f05 179 /* Set callback functions */
bcc6 0:55c7f79a524c 180 ble.gap().onConnection(connectionCallback);
bcc6 0:55c7f79a524c 181 ble.gap().onDisconnection(disconnectionCallback);
bcc6 3:656f8fb89f05 182 ble.gap().onTimeout(timeoutCallback);
bcc6 3:656f8fb89f05 183 ble.securityManager().onSecuritySetupInitiated(securitySetupInitiatedCallback);
bcc6 3:656f8fb89f05 184 ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback);
bcc6 3:656f8fb89f05 185 ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback);
bcc6 0:55c7f79a524c 186
bcc6 3:656f8fb89f05 187 /* Setup primary service */
bcc6 3:656f8fb89f05 188 DeviceInformationService deviceInfo(ble, MANUFACTURERS_NAME, MODEL_NAME, SERIAL_NUMBER, HW_VERSION, FW_VERSION, SW_VERSION, PNP_ID);
bcc6 3:656f8fb89f05 189 BatteryService batteryInfo(ble, 80);
bcc6 0:55c7f79a524c 190 kbService = new KeyboardService(ble);
bcc6 3:656f8fb89f05 191
bcc6 3:656f8fb89f05 192 /* Connection parameters */
bcc6 3:656f8fb89f05 193 Gap::ConnectionParams_t conn_params;
bcc6 3:656f8fb89f05 194 conn_params.minConnectionInterval = MIN_CONN_INTERVAL;
bcc6 3:656f8fb89f05 195 conn_params.maxConnectionInterval = MAX_CONN_INTERVAL;
bcc6 3:656f8fb89f05 196 conn_params.slaveLatency = SLAVE_LATENCY;
bcc6 3:656f8fb89f05 197 conn_params.connectionSupervisionTimeout = CONN_SUP_TIMEOUT;
bcc6 3:656f8fb89f05 198 ble.gap().setPreferredConnectionParams(&conn_params);
bcc6 0:55c7f79a524c 199
bcc6 0:55c7f79a524c 200 /* Setup advertising. */
bcc6 3:656f8fb89f05 201 static const uint16_t uuid16_list[] = {
bcc6 3:656f8fb89f05 202 GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE
bcc6 3:656f8fb89f05 203 };
bcc6 3:656f8fb89f05 204 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
bcc6 3:656f8fb89f05 205 ble.gap().setAdvertisingInterval(ADV_INTERVAL);
bcc6 3:656f8fb89f05 206 ble.gap().setAdvertisingTimeout(ADV_TIMEOUT);
bcc6 3:656f8fb89f05 207 error = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_LIMITED_DISCOVERABLE);
bcc6 3:656f8fb89f05 208 assert(error == BLE_ERROR_NONE);
bcc6 3:656f8fb89f05 209 error = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
bcc6 3:656f8fb89f05 210 assert(error == BLE_ERROR_NONE);
bcc6 3:656f8fb89f05 211 error = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD);
bcc6 3:656f8fb89f05 212 assert(error == BLE_ERROR_NONE);
bcc6 3:656f8fb89f05 213 error = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (const uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
bcc6 3:656f8fb89f05 214 assert(error == BLE_ERROR_NONE);
bcc6 3:656f8fb89f05 215 error = ble.gap().setDeviceName((const uint8_t *)DEVICE_NAME);
bcc6 3:656f8fb89f05 216 assert(error == BLE_ERROR_NONE);
bcc6 3:656f8fb89f05 217 error = ble.gap().startAdvertising();
bcc6 3:656f8fb89f05 218 assert(error == BLE_ERROR_NONE);
bcc6 0:55c7f79a524c 219 }
bcc6 0:55c7f79a524c 220
bcc6 3:656f8fb89f05 221 static void gestureIntEventCallback()
bcc6 0:55c7f79a524c 222 {
bcc6 3:656f8fb89f05 223 log("gestureIntEventCallback\n");
bcc6 0:55c7f79a524c 224 gestureHasIntEvent = true;
bcc6 0:55c7f79a524c 225 }
bcc6 0:55c7f79a524c 226
bcc6 0:55c7f79a524c 227 int main(void)
bcc6 0:55c7f79a524c 228 {
bcc6 3:656f8fb89f05 229 /* Disable the hardware flow control of Serial */
bcc6 0:55c7f79a524c 230 *((uint32_t *)(0x40002000+0x56C)) = 0;
bcc6 3:656f8fb89f05 231 log("\n");
bcc6 3:656f8fb89f05 232 log("~ Hell World ~\n");
bcc6 3:656f8fb89f05 233 log("\n");
bcc6 0:55c7f79a524c 234
bcc6 0:55c7f79a524c 235 /* Init BLE */
bcc6 0:55c7f79a524c 236 BLE& ble = BLE::Instance();
bcc6 0:55c7f79a524c 237 ble.init(bleInitComplete);
bcc6 0:55c7f79a524c 238 while(ble.hasInitialized() == false) { /* spin loop */ }
bcc6 0:55c7f79a524c 239
bcc6 0:55c7f79a524c 240 /* Config sensor */
bcc6 3:656f8fb89f05 241 log("PID(0x%04X), VID(0x%02X)\n", gesture.PID, gesture.VID);
bcc6 0:55c7f79a524c 242 gesture.IntEvent(&gestureIntEventCallback);
bcc6 0:55c7f79a524c 243
bcc6 0:55c7f79a524c 244 /* Main loop */
bcc6 0:55c7f79a524c 245 while(1){
bcc6 0:55c7f79a524c 246 /* Process interrupt event */
bcc6 0:55c7f79a524c 247 if(gestureHasIntEvent && ble.getGapState().connected){
bcc6 0:55c7f79a524c 248 gestureHasIntEvent = false;
bcc6 0:55c7f79a524c 249
bcc6 0:55c7f79a524c 250 /* Get sensor data */
bcc6 0:55c7f79a524c 251 uint16_t int_flag = gesture.ReadIntFlag();
bcc6 3:656f8fb89f05 252 log("(0x%04X)\n", int_flag);
bcc6 0:55c7f79a524c 253
bcc6 0:55c7f79a524c 254 /* Send HID code */
bcc6 0:55c7f79a524c 255 if(kbService!=NULL && kbService->isConnected()){
bcc6 0:55c7f79a524c 256 switch(int_flag){
bcc6 0:55c7f79a524c 257 case 0x0001: // Up
bcc6 3:656f8fb89f05 258 log("UpArrow\n");
bcc6 0:55c7f79a524c 259 kbService->printf("%c", UP_ARROW);
bcc6 0:55c7f79a524c 260 break;
bcc6 0:55c7f79a524c 261 case 0x0002: // Down
bcc6 3:656f8fb89f05 262 log("DownArrow\n");
bcc6 0:55c7f79a524c 263 kbService->printf("%c", DOWN_ARROW);
bcc6 0:55c7f79a524c 264 break;
bcc6 0:55c7f79a524c 265 case 0x0004: // Left
bcc6 3:656f8fb89f05 266 log("LeftArrow\n");
bcc6 0:55c7f79a524c 267 kbService->printf("%c", LEFT_ARROW);
bcc6 0:55c7f79a524c 268 break;
bcc6 0:55c7f79a524c 269 case 0x0008: // Right
bcc6 3:656f8fb89f05 270 log("RightArrow\n");
bcc6 0:55c7f79a524c 271 kbService->printf("%c", RIGHT_ARROW);
bcc6 0:55c7f79a524c 272 break;
bcc6 0:55c7f79a524c 273 case 0x0010: // Forward
bcc6 3:656f8fb89f05 274 log("PageDown\n");
bcc6 0:55c7f79a524c 275 kbService->printf("%c", KEY_PAGE_DOWN);
bcc6 0:55c7f79a524c 276 break;
bcc6 0:55c7f79a524c 277 case 0x0020: // Backword
bcc6 3:656f8fb89f05 278 log("PageUp\n");
bcc6 0:55c7f79a524c 279 kbService->printf("%c", KEY_PAGE_UP);
bcc6 0:55c7f79a524c 280 break;
bcc6 0:55c7f79a524c 281 case 0x0040: // Clockwise
bcc6 3:656f8fb89f05 282 log("F5\n");
bcc6 0:55c7f79a524c 283 kbService->printf("%c", KEY_F5);
bcc6 0:55c7f79a524c 284 break;
bcc6 0:55c7f79a524c 285 case 0x0080: // Counter-Clockwise
bcc6 3:656f8fb89f05 286 log("ESC\n");
bcc6 0:55c7f79a524c 287 kbService->printf("%c", 27);
bcc6 0:55c7f79a524c 288 break;
bcc6 0:55c7f79a524c 289 case 0x0100: // Wave
bcc6 3:656f8fb89f05 290 log("Bye Bye\n");
bcc6 0:55c7f79a524c 291 kbService->printf("Bye Bye\n");
bcc6 0:55c7f79a524c 292 break;
bcc6 0:55c7f79a524c 293 }// End of switch
bcc6 0:55c7f79a524c 294 }
bcc6 0:55c7f79a524c 295 }
bcc6 0:55c7f79a524c 296
bcc6 0:55c7f79a524c 297 /* low power wait for event */
bcc6 3:656f8fb89f05 298 // log("sleep\n");
bcc6 0:55c7f79a524c 299 ble.waitForEvent();
bcc6 3:656f8fb89f05 300 // log("wakeup\n");
bcc6 0:55c7f79a524c 301
bcc6 0:55c7f79a524c 302 }// End of while
bcc6 0:55c7f79a524c 303 }
bcc6 3:656f8fb89f05 304