BLE switch interface with GROVE joystic for micro:bit http://mahoro-ba.net/e2073.html

Dependencies:   microbit

Committer:
masakjm
Date:
Mon Sep 17 02:48:51 2018 +0000
Revision:
0:28fb3e9ef81a
Child:
1:3b9ae1dbcdcf
first release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
masakjm 0:28fb3e9ef81a 1 //=================================
masakjm 0:28fb3e9ef81a 2 // microbit_switch_if_3sw
masakjm 0:28fb3e9ef81a 3 //=================================
masakjm 0:28fb3e9ef81a 4 // BLE switch interface with 3 tact switches for micro:bit
masakjm 0:28fb3e9ef81a 5 // It is intended for use with ios devices.
masakjm 0:28fb3e9ef81a 6 //
masakjm 0:28fb3e9ef81a 7 // The MIT License (MIT) Copyright (c) 2018 Masatomo Kojima
masakjm 0:28fb3e9ef81a 8 //
masakjm 0:28fb3e9ef81a 9 // LED message
masakjm 0:28fb3e9ef81a 10 // S key code setting sw1,2
masakjm 0:28fb3e9ef81a 11 // T key code setting sw3
masakjm 0:28fb3e9ef81a 12 // W Waiting
masakjm 0:28fb3e9ef81a 13 // C Conected
masakjm 0:28fb3e9ef81a 14 // P success Pearing
masakjm 0:28fb3e9ef81a 15 // F Fail pearing
masakjm 0:28fb3e9ef81a 16 // E Error at sending data by ble
masakjm 0:28fb3e9ef81a 17 // e Error at writting data to flash memory
masakjm 0:28fb3e9ef81a 18 // I Error by Incorrect cording
masakjm 0:28fb3e9ef81a 19 //
masakjm 0:28fb3e9ef81a 20 // Please refer to the following site. (Japanese only)
masakjm 0:28fb3e9ef81a 21 // http://mahoro-ba.net/e2036.html
masakjm 0:28fb3e9ef81a 22 // http://mahoro-ba.net/e2038.html
masakjm 0:28fb3e9ef81a 23 //
masakjm 0:28fb3e9ef81a 24 // I refer to information written on the following sites.
masakjm 0:28fb3e9ef81a 25 // (1)https://os.mbed.com/teams/microbit/code/microbit_presenter/
masakjm 0:28fb3e9ef81a 26 // Licensed under the Apache License, Version 2.0
masakjm 0:28fb3e9ef81a 27 //
masakjm 0:28fb3e9ef81a 28 // (2)https://lancaster-university.github.io/microbit-docs/
masakjm 0:28fb3e9ef81a 29 // The MIT License (MIT)
masakjm 0:28fb3e9ef81a 30 // Copyright (c) 2016 British Broadcasting Corporation.
masakjm 0:28fb3e9ef81a 31 //
masakjm 0:28fb3e9ef81a 32 //---------------------------------
masakjm 0:28fb3e9ef81a 33
masakjm 0:28fb3e9ef81a 34 #define VERSION "3SW-180917"
masakjm 0:28fb3e9ef81a 35 //#define NO_DEBUG
masakjm 0:28fb3e9ef81a 36
masakjm 0:28fb3e9ef81a 37 #include "microbit_switch_if.h"
masakjm 0:28fb3e9ef81a 38 #include "KeyValueInt.h"
masakjm 0:28fb3e9ef81a 39
masakjm 0:28fb3e9ef81a 40 //---------------------------------
masakjm 0:28fb3e9ef81a 41 // Display
masakjm 0:28fb3e9ef81a 42 //---------------------------------
masakjm 0:28fb3e9ef81a 43 MicroBitDisplay display;
masakjm 0:28fb3e9ef81a 44 int state; // 状態遷移
masakjm 0:28fb3e9ef81a 45 char dispChar = 0; // LEDに表示する文字コード
masakjm 0:28fb3e9ef81a 46 char dispCharLast = 0; // 最後に表示した文字コード
masakjm 0:28fb3e9ef81a 47 bool turnOffMode = false; // LED非表示モードのフラグ
masakjm 0:28fb3e9ef81a 48
masakjm 0:28fb3e9ef81a 49 //----- 数値の表示
masakjm 0:28fb3e9ef81a 50 static void displayNumber(int data)
masakjm 0:28fb3e9ef81a 51 {
masakjm 0:28fb3e9ef81a 52 if (0<=data && data<=9) { // 1桁はスクロールしない
masakjm 0:28fb3e9ef81a 53 display.print(data);
masakjm 0:28fb3e9ef81a 54 } else {
masakjm 0:28fb3e9ef81a 55 display.scroll(data);
masakjm 0:28fb3e9ef81a 56 }
masakjm 0:28fb3e9ef81a 57 }
masakjm 0:28fb3e9ef81a 58
masakjm 0:28fb3e9ef81a 59 //---------------------------------
masakjm 0:28fb3e9ef81a 60 // Flash Memory
masakjm 0:28fb3e9ef81a 61 //---------------------------------
masakjm 0:28fb3e9ef81a 62
masakjm 0:28fb3e9ef81a 63 //----- 不揮発メモリの読み出し
masakjm 0:28fb3e9ef81a 64 static int FlashGet(MicroBitStorage storage, const char* key, int init=0)
masakjm 0:28fb3e9ef81a 65 {
masakjm 0:28fb3e9ef81a 66 KeyValuePair* kvp = storage.get(key);
masakjm 0:28fb3e9ef81a 67 if(kvp != NULL) {
masakjm 0:28fb3e9ef81a 68 int data;
masakjm 0:28fb3e9ef81a 69 memcpy(&data, kvp->value, sizeof(int));
masakjm 0:28fb3e9ef81a 70 DEBUG("== FlashGet exist %s = %d\r\n", key, data);
masakjm 0:28fb3e9ef81a 71 return data;
masakjm 0:28fb3e9ef81a 72 }
masakjm 0:28fb3e9ef81a 73 return init;
masakjm 0:28fb3e9ef81a 74 }
masakjm 0:28fb3e9ef81a 75
masakjm 0:28fb3e9ef81a 76 //----- 不揮発メモリの書き込み
masakjm 0:28fb3e9ef81a 77 // MICROBIT_OK = 0
masakjm 0:28fb3e9ef81a 78 // MICROBIT_INVALID_PARAMETER = -1001,
masakjm 0:28fb3e9ef81a 79 // MICROBIT_NO_RESOURCES = -1005,
masakjm 0:28fb3e9ef81a 80 static int FlashPut(MicroBitStorage storage, const char* key, int data)
masakjm 0:28fb3e9ef81a 81 {
masakjm 0:28fb3e9ef81a 82 int ret = storage.put(key, (uint8_t *)&data, sizeof(int));
masakjm 0:28fb3e9ef81a 83 DEBUG("== FlashPut %s %d %d\r\n", key, data, ret);
masakjm 0:28fb3e9ef81a 84 return ret;
masakjm 0:28fb3e9ef81a 85 }
masakjm 0:28fb3e9ef81a 86
masakjm 0:28fb3e9ef81a 87 //---------------------------------
masakjm 0:28fb3e9ef81a 88 // Setting
masakjm 0:28fb3e9ef81a 89 //---------------------------------
masakjm 0:28fb3e9ef81a 90 bool setting_inc; // 設定値を増加
masakjm 0:28fb3e9ef81a 91 bool setting_enter; // 設定値を入力
masakjm 0:28fb3e9ef81a 92 bool setting_next; // 次の設定値に移動
masakjm 0:28fb3e9ef81a 93
masakjm 0:28fb3e9ef81a 94 KeyValueInt kviKeyCode1("keycode1",'S', 1, 1, NUM_GROUP1, true);
masakjm 0:28fb3e9ef81a 95 KeyValueInt kviKeyCode2("keycode2",'T', 1, 1, NUM_GROUP2, true);
masakjm 0:28fb3e9ef81a 96
masakjm 0:28fb3e9ef81a 97 //----- パラメータ設定
masakjm 0:28fb3e9ef81a 98
masakjm 0:28fb3e9ef81a 99 static int paraSettingOne(MicroBitStorage storage, KeyValueInt* para, bool change)
masakjm 0:28fb3e9ef81a 100 {
masakjm 0:28fb3e9ef81a 101 display.print(para->disp); // 識別文字をLED表示
masakjm 0:28fb3e9ef81a 102 wait(SETTING_DISPLAY_WAIT);
masakjm 0:28fb3e9ef81a 103 displayNumber(para->value); // 値をLED表示
masakjm 0:28fb3e9ef81a 104 if (!change) {
masakjm 0:28fb3e9ef81a 105 wait(SETTING_DISPLAY_WAIT);
masakjm 0:28fb3e9ef81a 106 return 0;
masakjm 0:28fb3e9ef81a 107 }
masakjm 0:28fb3e9ef81a 108
masakjm 0:28fb3e9ef81a 109 DEBUG("== paraSetting\r\n");
masakjm 0:28fb3e9ef81a 110 setting_inc = false;
masakjm 0:28fb3e9ef81a 111 setting_next = setting_enter = false;
masakjm 0:28fb3e9ef81a 112 while( ! setting_next) { // Bボタンが離されるまで
masakjm 0:28fb3e9ef81a 113 if (setting_inc) { // Aボタンが押されたら
masakjm 0:28fb3e9ef81a 114 setting_inc = false;
masakjm 0:28fb3e9ef81a 115 para->inc();
masakjm 0:28fb3e9ef81a 116 displayNumber(para->value);
masakjm 0:28fb3e9ef81a 117 }
masakjm 0:28fb3e9ef81a 118 wait(0.2);
masakjm 0:28fb3e9ef81a 119 }
masakjm 0:28fb3e9ef81a 120 if (FlashPut(storage, para->key, para->value)) {
masakjm 0:28fb3e9ef81a 121 dispChar = 'e';
masakjm 0:28fb3e9ef81a 122 return -1;
masakjm 0:28fb3e9ef81a 123 } else {
masakjm 0:28fb3e9ef81a 124 dispChar = 0;
masakjm 0:28fb3e9ef81a 125 return 0;
masakjm 0:28fb3e9ef81a 126 }
masakjm 0:28fb3e9ef81a 127 }
masakjm 0:28fb3e9ef81a 128
masakjm 0:28fb3e9ef81a 129 static void paraSetting(bool change)
masakjm 0:28fb3e9ef81a 130 {
masakjm 0:28fb3e9ef81a 131 MicroBitStorage storage;
masakjm 0:28fb3e9ef81a 132
masakjm 0:28fb3e9ef81a 133 kviKeyCode1.set(FlashGet(storage, kviKeyCode1.key, 1));
masakjm 0:28fb3e9ef81a 134 kviKeyCode2.set(FlashGet(storage, kviKeyCode2.key, 1));
masakjm 0:28fb3e9ef81a 135 int err = paraSettingOne(storage, &kviKeyCode1, change);
masakjm 0:28fb3e9ef81a 136 if (err) return;
masakjm 0:28fb3e9ef81a 137 paraSettingOne(storage, &kviKeyCode2, change);
masakjm 0:28fb3e9ef81a 138 }
masakjm 0:28fb3e9ef81a 139 //---------------------------------
masakjm 0:28fb3e9ef81a 140 // BLE & HID
masakjm 0:28fb3e9ef81a 141 //---------------------------------
masakjm 0:28fb3e9ef81a 142 BLE ble;
masakjm 0:28fb3e9ef81a 143 KeyboardService *kbdServicePtr;
masakjm 0:28fb3e9ef81a 144
masakjm 0:28fb3e9ef81a 145 //----- BLE接続が切断された
masakjm 0:28fb3e9ef81a 146 static void onDisconnect(const Gap::DisconnectionCallbackParams_t *params)
masakjm 0:28fb3e9ef81a 147 {
masakjm 0:28fb3e9ef81a 148 DEBUG("(BLE)disconnected\r\n");
masakjm 0:28fb3e9ef81a 149 ble.gap().startAdvertising(); // restart advertising
masakjm 0:28fb3e9ef81a 150 dispChar = 0;
masakjm 0:28fb3e9ef81a 151 }
masakjm 0:28fb3e9ef81a 152
masakjm 0:28fb3e9ef81a 153 //----- BLE接続された
masakjm 0:28fb3e9ef81a 154 static void onConnect(const Gap::ConnectionCallbackParams_t *params)
masakjm 0:28fb3e9ef81a 155 {
masakjm 0:28fb3e9ef81a 156 if(kbdServicePtr->isConnected()) {
masakjm 0:28fb3e9ef81a 157 DEBUG("(BLE)connected\r\n");
masakjm 0:28fb3e9ef81a 158 dispChar = 'C';
masakjm 0:28fb3e9ef81a 159 }
masakjm 0:28fb3e9ef81a 160 }
masakjm 0:28fb3e9ef81a 161
masakjm 0:28fb3e9ef81a 162 //----- BLE接続待ち状態
masakjm 0:28fb3e9ef81a 163 static void waiting()
masakjm 0:28fb3e9ef81a 164 {
masakjm 0:28fb3e9ef81a 165 if (!kbdServicePtr->isConnected()) {
masakjm 0:28fb3e9ef81a 166 dispChar ='W';
masakjm 0:28fb3e9ef81a 167 }
masakjm 0:28fb3e9ef81a 168 }
masakjm 0:28fb3e9ef81a 169
masakjm 0:28fb3e9ef81a 170 //----- パスキー表示
masakjm 0:28fb3e9ef81a 171 static void passkeyDisplayCallback(Gap::Handle_t handle, const SecurityManager::Passkey_t passkey)
masakjm 0:28fb3e9ef81a 172 {
masakjm 0:28fb3e9ef81a 173 printf("(BLE)Input passKey: ");
masakjm 0:28fb3e9ef81a 174 for (unsigned i = 0; i < Gap::ADDR_LEN; i++) {
masakjm 0:28fb3e9ef81a 175 printf("%c", passkey[i]);
masakjm 0:28fb3e9ef81a 176 }
masakjm 0:28fb3e9ef81a 177 printf("\r\n");
masakjm 0:28fb3e9ef81a 178 }
masakjm 0:28fb3e9ef81a 179
masakjm 0:28fb3e9ef81a 180 //----- セキュリティ設定完了
masakjm 0:28fb3e9ef81a 181 static void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status)
masakjm 0:28fb3e9ef81a 182 {
masakjm 0:28fb3e9ef81a 183 if (status == SecurityManager::SEC_STATUS_SUCCESS) {
masakjm 0:28fb3e9ef81a 184 // DEBUG("(BLE)Security success %d\r\n", status);
masakjm 0:28fb3e9ef81a 185 dispChar = 'P';
masakjm 0:28fb3e9ef81a 186
masakjm 0:28fb3e9ef81a 187 } else {
masakjm 0:28fb3e9ef81a 188 // DEBUG("(BLE)Security failed %d\r\n", status);
masakjm 0:28fb3e9ef81a 189 dispChar = 'F';
masakjm 0:28fb3e9ef81a 190 }
masakjm 0:28fb3e9ef81a 191 }
masakjm 0:28fb3e9ef81a 192
masakjm 0:28fb3e9ef81a 193 //----- セキュリティ初期設定
masakjm 0:28fb3e9ef81a 194 static void securitySetupInitiatedCallback(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps)
masakjm 0:28fb3e9ef81a 195 {
masakjm 0:28fb3e9ef81a 196 DEBUG("(BLE)Security setup initiated\r\n");
masakjm 0:28fb3e9ef81a 197 }
masakjm 0:28fb3e9ef81a 198
masakjm 0:28fb3e9ef81a 199 //----- セキュリティ初期設定
masakjm 0:28fb3e9ef81a 200 static void initializeSecurity(BLE &ble)
masakjm 0:28fb3e9ef81a 201 {
masakjm 0:28fb3e9ef81a 202 bool enableBonding = true;
masakjm 0:28fb3e9ef81a 203 bool requireMITM = HID_SECURITY_REQUIRE_MITM;
masakjm 0:28fb3e9ef81a 204
masakjm 0:28fb3e9ef81a 205 ble.securityManager().onSecuritySetupInitiated(securitySetupInitiatedCallback);
masakjm 0:28fb3e9ef81a 206 ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback);
masakjm 0:28fb3e9ef81a 207 ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback);
masakjm 0:28fb3e9ef81a 208
masakjm 0:28fb3e9ef81a 209 ble.securityManager().init(enableBonding, requireMITM, HID_SECURITY_IOCAPS);
masakjm 0:28fb3e9ef81a 210 }
masakjm 0:28fb3e9ef81a 211
masakjm 0:28fb3e9ef81a 212 //----- HOGP (HID Over GATT Profile) 初期化
masakjm 0:28fb3e9ef81a 213 static void initializeHOGP(BLE &ble)
masakjm 0:28fb3e9ef81a 214 {
masakjm 0:28fb3e9ef81a 215 static const uint16_t uuid16_list[] = {GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE,
masakjm 0:28fb3e9ef81a 216 GattService::UUID_DEVICE_INFORMATION_SERVICE,
masakjm 0:28fb3e9ef81a 217 GattService::UUID_BATTERY_SERVICE
masakjm 0:28fb3e9ef81a 218 };
masakjm 0:28fb3e9ef81a 219
masakjm 0:28fb3e9ef81a 220 PnPID_t pnpID;
masakjm 0:28fb3e9ef81a 221 pnpID.vendorID_source = 0x2; // from the USB Implementer's Forum
masakjm 0:28fb3e9ef81a 222 pnpID.vendorID = 0x0D28; // NXP
masakjm 0:28fb3e9ef81a 223 pnpID.productID = 0x0204; // CMSIS-DAP (well, it's a keyboard but oh well)
masakjm 0:28fb3e9ef81a 224 pnpID.productVersion = 0x0100; // v1.0
masakjm 0:28fb3e9ef81a 225 HIDDeviceInformationService deviceInfo(ble, "ARM", "m1", "abc", "def", "ghi", "jkl", &pnpID);
masakjm 0:28fb3e9ef81a 226
masakjm 0:28fb3e9ef81a 227 BatteryService batteryInfo(ble, 80);
masakjm 0:28fb3e9ef81a 228
masakjm 0:28fb3e9ef81a 229 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED |
masakjm 0:28fb3e9ef81a 230 GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
masakjm 0:28fb3e9ef81a 231 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
masakjm 0:28fb3e9ef81a 232 (uint8_t *)uuid16_list, sizeof(uuid16_list));
masakjm 0:28fb3e9ef81a 233
masakjm 0:28fb3e9ef81a 234 // see 5.1.2: HID over GATT Specification (pg. 25)
masakjm 0:28fb3e9ef81a 235 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
masakjm 0:28fb3e9ef81a 236 // 30ms to 50ms is recommended (5.1.2)
masakjm 0:28fb3e9ef81a 237 ble.gap().setAdvertisingInterval(50);
masakjm 0:28fb3e9ef81a 238 }
masakjm 0:28fb3e9ef81a 239
masakjm 0:28fb3e9ef81a 240 //----- BLE接続のHID(human interface device) の初期化
masakjm 0:28fb3e9ef81a 241 static void initialize_BLE_HID()
masakjm 0:28fb3e9ef81a 242 {
masakjm 0:28fb3e9ef81a 243 static const char SHORT_DEVICE_NAME[] = "micro:bit";
masakjm 0:28fb3e9ef81a 244 static char DeviceName[20];
masakjm 0:28fb3e9ef81a 245
masakjm 0:28fb3e9ef81a 246 int id = microbit_serial_number()& 0xfff; // シリアル番号の下12桁を4桁の10進で表示
masakjm 0:28fb3e9ef81a 247 sprintf(DeviceName, "micro:bit %04d", id);
masakjm 0:28fb3e9ef81a 248 DEBUG("(BLE)id %s\r\n", DeviceName);
masakjm 0:28fb3e9ef81a 249
masakjm 0:28fb3e9ef81a 250 // DEBUG("(BLE)initialising ble\r\n");
masakjm 0:28fb3e9ef81a 251 ble.init();
masakjm 0:28fb3e9ef81a 252
masakjm 0:28fb3e9ef81a 253 ble.gap().onDisconnection(onDisconnect);
masakjm 0:28fb3e9ef81a 254 ble.gap().onConnection(onConnect);
masakjm 0:28fb3e9ef81a 255
masakjm 0:28fb3e9ef81a 256 initializeSecurity(ble);
masakjm 0:28fb3e9ef81a 257
masakjm 0:28fb3e9ef81a 258 DEBUG("(BLE)adding hid service\r\n");
masakjm 0:28fb3e9ef81a 259 KeyboardService kbdService(ble);
masakjm 0:28fb3e9ef81a 260 kbdServicePtr = &kbdService;
masakjm 0:28fb3e9ef81a 261
masakjm 0:28fb3e9ef81a 262 DEBUG("(BLE)adding device info and battery service\r\n");
masakjm 0:28fb3e9ef81a 263 initializeHOGP(ble);
masakjm 0:28fb3e9ef81a 264
masakjm 0:28fb3e9ef81a 265 DEBUG("(BLE)setting up gap\r\n");
masakjm 0:28fb3e9ef81a 266 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD);
masakjm 0:28fb3e9ef81a 267 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME,
masakjm 0:28fb3e9ef81a 268 (uint8_t *)DeviceName, sizeof(DeviceName));
masakjm 0:28fb3e9ef81a 269 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
masakjm 0:28fb3e9ef81a 270 (uint8_t *)SHORT_DEVICE_NAME, sizeof(SHORT_DEVICE_NAME));
masakjm 0:28fb3e9ef81a 271 ble.gap().setDeviceName((const uint8_t *)DeviceName);
masakjm 0:28fb3e9ef81a 272
masakjm 0:28fb3e9ef81a 273 DEBUG("(BLE)advertising\r\n");
masakjm 0:28fb3e9ef81a 274 ble.gap().startAdvertising();
masakjm 0:28fb3e9ef81a 275 }
masakjm 0:28fb3e9ef81a 276
masakjm 0:28fb3e9ef81a 277 //---------------------------------
masakjm 0:28fb3e9ef81a 278 // Button
masakjm 0:28fb3e9ef81a 279 //---------------------------------
masakjm 0:28fb3e9ef81a 280 MicroBitMessageBus bus;
masakjm 0:28fb3e9ef81a 281 MicroBitButton buttonA(MICROBIT_PIN_BUTTON_A, MICROBIT_ID_BUTTON_A);
masakjm 0:28fb3e9ef81a 282 MicroBitButton buttonB(MICROBIT_PIN_BUTTON_B, MICROBIT_ID_BUTTON_B);
masakjm 0:28fb3e9ef81a 283 MicroBitButton button0(MICROBIT_PIN_P0, MICROBIT_ID_IO_P0, MICROBIT_BUTTON_ALL_EVENTS, PullUp);
masakjm 0:28fb3e9ef81a 284 MicroBitButton button1(MICROBIT_PIN_P1, MICROBIT_ID_IO_P1, MICROBIT_BUTTON_ALL_EVENTS, PullUp);
masakjm 0:28fb3e9ef81a 285 MicroBitButton button2(MICROBIT_PIN_P2, MICROBIT_ID_IO_P2, MICROBIT_BUTTON_ALL_EVENTS, PullUp);
masakjm 0:28fb3e9ef81a 286
masakjm 0:28fb3e9ef81a 287 //----- ボタン押下げ時イベント
masakjm 0:28fb3e9ef81a 288 static void onButtonDown(MicroBitEvent e)
masakjm 0:28fb3e9ef81a 289 {
masakjm 0:28fb3e9ef81a 290 // DEBUG(" Button Down %d state=%d\r\n", e.source, state);
masakjm 0:28fb3e9ef81a 291 int code = 0;
masakjm 0:28fb3e9ef81a 292
masakjm 0:28fb3e9ef81a 293 switch (state) {
masakjm 0:28fb3e9ef81a 294 case STATE_SETTING :
masakjm 0:28fb3e9ef81a 295 switch(e.source) {
masakjm 0:28fb3e9ef81a 296 case MICROBIT_ID_BUTTON_A :
masakjm 0:28fb3e9ef81a 297 setting_inc = true;
masakjm 0:28fb3e9ef81a 298 break;
masakjm 0:28fb3e9ef81a 299 case MICROBIT_ID_BUTTON_B :
masakjm 0:28fb3e9ef81a 300 setting_enter = true;
masakjm 0:28fb3e9ef81a 301 break;
masakjm 0:28fb3e9ef81a 302 }
masakjm 0:28fb3e9ef81a 303 break;
masakjm 0:28fb3e9ef81a 304 case STATE_OPERATING :
masakjm 0:28fb3e9ef81a 305 switch(e.source) {
masakjm 0:28fb3e9ef81a 306 case MICROBIT_ID_BUTTON_A :
masakjm 0:28fb3e9ef81a 307 dispChar = 'A';
masakjm 0:28fb3e9ef81a 308 code = keyCodeGroup0[0];
masakjm 0:28fb3e9ef81a 309 break;
masakjm 0:28fb3e9ef81a 310 case MICROBIT_ID_BUTTON_B :
masakjm 0:28fb3e9ef81a 311 dispChar = 'B';
masakjm 0:28fb3e9ef81a 312 code = keyCodeGroup0[1];
masakjm 0:28fb3e9ef81a 313 break;
masakjm 0:28fb3e9ef81a 314 case MICROBIT_ID_IO_P0 :
masakjm 0:28fb3e9ef81a 315 dispChar = '1';
masakjm 0:28fb3e9ef81a 316 code = keyCodeGroup1[kviKeyCode1.value-1][0];
masakjm 0:28fb3e9ef81a 317 break;
masakjm 0:28fb3e9ef81a 318 case MICROBIT_ID_IO_P1 :
masakjm 0:28fb3e9ef81a 319 dispChar = '2';
masakjm 0:28fb3e9ef81a 320 code = keyCodeGroup1[kviKeyCode1.value-1][1];
masakjm 0:28fb3e9ef81a 321 break;
masakjm 0:28fb3e9ef81a 322 case MICROBIT_ID_IO_P2 :
masakjm 0:28fb3e9ef81a 323 dispChar = '3';
masakjm 0:28fb3e9ef81a 324 code = keyCodeGroup2[kviKeyCode2.value-1];
masakjm 0:28fb3e9ef81a 325 break;
masakjm 0:28fb3e9ef81a 326 }
masakjm 0:28fb3e9ef81a 327
masakjm 0:28fb3e9ef81a 328 if (code) {
masakjm 0:28fb3e9ef81a 329 uint8_t key = code & 0xff;
masakjm 0:28fb3e9ef81a 330 uint8_t modif = code >> 8;
masakjm 0:28fb3e9ef81a 331
masakjm 0:28fb3e9ef81a 332 if (key > KEYMAP_SIZE ) {
masakjm 0:28fb3e9ef81a 333 dispChar ='I'; // キーコード設定間違い
masakjm 0:28fb3e9ef81a 334 } else {
masakjm 0:28fb3e9ef81a 335 ble_error_t ret = kbdServicePtr->keyDownCode(key, modif);
masakjm 0:28fb3e9ef81a 336 // DEBUG(" code=%d modif=%d\r\n",key , modif);
masakjm 0:28fb3e9ef81a 337 if (ret) {
masakjm 0:28fb3e9ef81a 338 dispChar ='E';
masakjm 0:28fb3e9ef81a 339 dispCharLast =0; // E が続く時に表示
masakjm 0:28fb3e9ef81a 340 DEBUG("(BLE)Error %d\r\n",ret);
masakjm 0:28fb3e9ef81a 341 }
masakjm 0:28fb3e9ef81a 342 }
masakjm 0:28fb3e9ef81a 343 }
masakjm 0:28fb3e9ef81a 344 }
masakjm 0:28fb3e9ef81a 345 }
masakjm 0:28fb3e9ef81a 346
masakjm 0:28fb3e9ef81a 347 //----- ボタン離し時イベント
masakjm 0:28fb3e9ef81a 348 static void onButtonUp(MicroBitEvent e)
masakjm 0:28fb3e9ef81a 349 {
masakjm 0:28fb3e9ef81a 350 // DEBUG(" Button up %d\r\n", e.source);
masakjm 0:28fb3e9ef81a 351 switch (state) {
masakjm 0:28fb3e9ef81a 352 case STATE_SETTING :
masakjm 0:28fb3e9ef81a 353 if(setting_enter) setting_next = true; // 決定ボタンを離したら次へ
masakjm 0:28fb3e9ef81a 354 break;
masakjm 0:28fb3e9ef81a 355 case STATE_OPERATING :
masakjm 0:28fb3e9ef81a 356 dispChar = 0;
masakjm 0:28fb3e9ef81a 357 ble_error_t ret = kbdServicePtr->keyUpCode();
masakjm 0:28fb3e9ef81a 358 if (ret) {
masakjm 0:28fb3e9ef81a 359 dispChar ='E';
masakjm 0:28fb3e9ef81a 360 dispCharLast =0; // E が続く時に表示
masakjm 0:28fb3e9ef81a 361 }
masakjm 0:28fb3e9ef81a 362 }
masakjm 0:28fb3e9ef81a 363 }
masakjm 0:28fb3e9ef81a 364
masakjm 0:28fb3e9ef81a 365 //---------------------------------
masakjm 0:28fb3e9ef81a 366 // Main
masakjm 0:28fb3e9ef81a 367 //---------------------------------
masakjm 0:28fb3e9ef81a 368 int main()
masakjm 0:28fb3e9ef81a 369 {
masakjm 0:28fb3e9ef81a 370 state = STATE_NORMAL;
masakjm 0:28fb3e9ef81a 371
masakjm 0:28fb3e9ef81a 372 wait(0.1); // ボタン状態の更新
masakjm 0:28fb3e9ef81a 373 bool bA = buttonA.isPressed();
masakjm 0:28fb3e9ef81a 374 bool bB = buttonB.isPressed();
masakjm 0:28fb3e9ef81a 375
masakjm 0:28fb3e9ef81a 376 if (bA && bB) { // ボタンABを押しながら起動
masakjm 0:28fb3e9ef81a 377 while(1) {
masakjm 0:28fb3e9ef81a 378 display.scroll(VERSION);
masakjm 0:28fb3e9ef81a 379 wait(0.5);
masakjm 0:28fb3e9ef81a 380 }
masakjm 0:28fb3e9ef81a 381 } else if(bA) // ボタンAを押しながら起動
masakjm 0:28fb3e9ef81a 382 state = STATE_SETTING;
masakjm 0:28fb3e9ef81a 383
masakjm 0:28fb3e9ef81a 384 //----- Display
masakjm 0:28fb3e9ef81a 385 display.setDisplayMode(DISPLAY_MODE_BLACK_AND_WHITE);
masakjm 0:28fb3e9ef81a 386 display.clear();
masakjm 0:28fb3e9ef81a 387 Timer dispTime; // 連続表示タイマー
masakjm 0:28fb3e9ef81a 388 dispTime.start();
masakjm 0:28fb3e9ef81a 389
masakjm 0:28fb3e9ef81a 390 //----- Button
masakjm 0:28fb3e9ef81a 391 bus.listen(MICROBIT_ID_ANY, MICROBIT_BUTTON_EVT_DOWN, onButtonDown);
masakjm 0:28fb3e9ef81a 392 bus.listen(MICROBIT_ID_ANY, MICROBIT_BUTTON_EVT_UP, onButtonUp);
masakjm 0:28fb3e9ef81a 393
masakjm 0:28fb3e9ef81a 394 //----- Setting
masakjm 0:28fb3e9ef81a 395 paraSetting(state == STATE_SETTING);
masakjm 0:28fb3e9ef81a 396 state = STATE_OPERATING;
masakjm 0:28fb3e9ef81a 397
masakjm 0:28fb3e9ef81a 398 //----- BLE & HID
masakjm 0:28fb3e9ef81a 399 Ticker heartbeat;
masakjm 0:28fb3e9ef81a 400 heartbeat.attach(waiting, 1); // 1秒毎に関数waiting を呼び出す
masakjm 0:28fb3e9ef81a 401 initialize_BLE_HID();
masakjm 0:28fb3e9ef81a 402 display.clear();
masakjm 0:28fb3e9ef81a 403
masakjm 0:28fb3e9ef81a 404 //----- Loop
masakjm 0:28fb3e9ef81a 405 while (true) {
masakjm 0:28fb3e9ef81a 406 ble.waitForEvent(); // BLEイベントを待つ
masakjm 0:28fb3e9ef81a 407
masakjm 0:28fb3e9ef81a 408 if (dispChar != dispCharLast) { // 表示文字が変更
masakjm 0:28fb3e9ef81a 409 turnOffMode = false;
masakjm 0:28fb3e9ef81a 410 dispTime.reset();
masakjm 0:28fb3e9ef81a 411 display.enable();
masakjm 0:28fb3e9ef81a 412 if (dispChar) display.printChar(dispChar);
masakjm 0:28fb3e9ef81a 413 else display.clear();
masakjm 0:28fb3e9ef81a 414 }
masakjm 0:28fb3e9ef81a 415 if (!turnOffMode) {
masakjm 0:28fb3e9ef81a 416 if (dispTime.read() > TIME_TURN_OFF) { // 長時間表示
masakjm 0:28fb3e9ef81a 417 turnOffMode = true;
masakjm 0:28fb3e9ef81a 418 display.disable();
masakjm 0:28fb3e9ef81a 419 }
masakjm 0:28fb3e9ef81a 420 }
masakjm 0:28fb3e9ef81a 421 dispCharLast = dispChar;
masakjm 0:28fb3e9ef81a 422 }
masakjm 0:28fb3e9ef81a 423 }