Initial release

Dependencies:   microbit

Committer:
masakjm
Date:
Fri Dec 14 18:26:16 2018 +0000
Revision:
5:80cb8f9db01e
Parent:
4:4fe5674bf409
Child:
6:e2074d02065b

        

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