BLE switch interface using micro:bit with 3 tact switches or 3 Makey Makey sensors
main.cpp@1:9d0e2e5b5d25, 2019-06-06 (annotated)
- Committer:
- masakjm
- Date:
- Thu Jun 06 19:06:06 2019 +0000
- Revision:
- 1:9d0e2e5b5d25
- Parent:
- 0:e0105c17ebb3
- Child:
- 2:8e2e6c6658be
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
masakjm | 1:9d0e2e5b5d25 | 1 | //================================= |
masakjm | 1:9d0e2e5b5d25 | 2 | // microbit_switch_if_3sw |
masakjm | 1:9d0e2e5b5d25 | 3 | //================================= |
masakjm | 1:9d0e2e5b5d25 | 4 | // BLE switch interface using micro:bit with 3 tact switches |
masakjm | 1:9d0e2e5b5d25 | 5 | // or 3 Makey Makey sensors |
masakjm | 1:9d0e2e5b5d25 | 6 | // It is intended for use with ios devices. |
masakjm | 1:9d0e2e5b5d25 | 7 | // |
masakjm | 1:9d0e2e5b5d25 | 8 | // The MIT License (MIT) Copyright (c) 2019 Masatomo Kojima |
masakjm | 1:9d0e2e5b5d25 | 9 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 10 | |
masakjm | 1:9d0e2e5b5d25 | 11 | #define VERSION "3SW-190607" |
masakjm | 1:9d0e2e5b5d25 | 12 | //#define NO_DEBUG |
masakjm | 1:9d0e2e5b5d25 | 13 | |
masakjm | 1:9d0e2e5b5d25 | 14 | #include "microbit_switch_if_3sw.h" |
masakjm | 1:9d0e2e5b5d25 | 15 | #include "KeyValueInt.h" |
masakjm | 1:9d0e2e5b5d25 | 16 | #include <queue> |
masakjm | 1:9d0e2e5b5d25 | 17 | |
masakjm | 1:9d0e2e5b5d25 | 18 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 19 | // KeyBuff |
masakjm | 1:9d0e2e5b5d25 | 20 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 21 | std::queue<int> KeyBuff; |
masakjm | 1:9d0e2e5b5d25 | 22 | |
masakjm | 1:9d0e2e5b5d25 | 23 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 24 | // Display |
masakjm | 1:9d0e2e5b5d25 | 25 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 26 | MicroBitDisplay display; |
masakjm | 1:9d0e2e5b5d25 | 27 | int State; // 状態遷移 |
masakjm | 1:9d0e2e5b5d25 | 28 | char DispChar = DISP_NO_MESSAGE; // LEDに表示する文字コード |
masakjm | 1:9d0e2e5b5d25 | 29 | char DispCharLast = 0; // 最後に表示した文字コード |
masakjm | 1:9d0e2e5b5d25 | 30 | bool TurnOffMode = false; // LED非表示モードのフラグ |
masakjm | 1:9d0e2e5b5d25 | 31 | |
masakjm | 1:9d0e2e5b5d25 | 32 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 33 | * @brief 整数値をLEDに表示する |
masakjm | 1:9d0e2e5b5d25 | 34 | * @param data 整数値 |
masakjm | 1:9d0e2e5b5d25 | 35 | */ |
masakjm | 1:9d0e2e5b5d25 | 36 | static void displayNumber(int data) |
masakjm | 1:9d0e2e5b5d25 | 37 | { |
masakjm | 1:9d0e2e5b5d25 | 38 | if (0<=data && data<=9) { // 1桁はスクロールしない |
masakjm | 1:9d0e2e5b5d25 | 39 | display.print(data); |
masakjm | 1:9d0e2e5b5d25 | 40 | } else { |
masakjm | 1:9d0e2e5b5d25 | 41 | display.scroll(data); |
masakjm | 1:9d0e2e5b5d25 | 42 | } |
masakjm | 1:9d0e2e5b5d25 | 43 | } |
masakjm | 1:9d0e2e5b5d25 | 44 | |
masakjm | 1:9d0e2e5b5d25 | 45 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 46 | // Flash Memory |
masakjm | 1:9d0e2e5b5d25 | 47 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 48 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 49 | * @brief キー名を指定して不揮発メモリから値を読み出す |
masakjm | 1:9d0e2e5b5d25 | 50 | * @param key キー名 |
masakjm | 1:9d0e2e5b5d25 | 51 | * @param init データが保存されていなかった時の初期値 |
masakjm | 1:9d0e2e5b5d25 | 52 | * @return int 取得したデータ |
masakjm | 1:9d0e2e5b5d25 | 53 | */ |
masakjm | 1:9d0e2e5b5d25 | 54 | static int FlashGet(MicroBitStorage storage, const char* key, int init=0) |
masakjm | 1:9d0e2e5b5d25 | 55 | { |
masakjm | 1:9d0e2e5b5d25 | 56 | KeyValuePair* kvp = storage.get(key); |
masakjm | 1:9d0e2e5b5d25 | 57 | if(kvp != NULL) { |
masakjm | 1:9d0e2e5b5d25 | 58 | int data; |
masakjm | 1:9d0e2e5b5d25 | 59 | memcpy(&data, kvp->value, sizeof(int)); |
masakjm | 1:9d0e2e5b5d25 | 60 | DEBUG("== FlashGet exist %s = %d\r\n", key, data); |
masakjm | 1:9d0e2e5b5d25 | 61 | return data; |
masakjm | 1:9d0e2e5b5d25 | 62 | } |
masakjm | 1:9d0e2e5b5d25 | 63 | return init; |
masakjm | 1:9d0e2e5b5d25 | 64 | } |
masakjm | 1:9d0e2e5b5d25 | 65 | |
masakjm | 1:9d0e2e5b5d25 | 66 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 67 | * @brief 不揮発メモリに値を書き込む |
masakjm | 1:9d0e2e5b5d25 | 68 | * @param storage 不揮発メモリインスタンス |
masakjm | 1:9d0e2e5b5d25 | 69 | * @param key キー名 |
masakjm | 1:9d0e2e5b5d25 | 70 | * @param data 値 |
masakjm | 1:9d0e2e5b5d25 | 71 | * @return int MICROBIT_OK = 0 |
masakjm | 1:9d0e2e5b5d25 | 72 | * MICROBIT_INVALID_PARAMETER = -1001, |
masakjm | 1:9d0e2e5b5d25 | 73 | * MICROBIT_NO_RESOURCES = -1005, |
masakjm | 1:9d0e2e5b5d25 | 74 | */ |
masakjm | 1:9d0e2e5b5d25 | 75 | static int FlashPut(MicroBitStorage storage, const char* key, int data) |
masakjm | 1:9d0e2e5b5d25 | 76 | { |
masakjm | 1:9d0e2e5b5d25 | 77 | int ret = storage.put(key, (uint8_t *)&data, sizeof(int)); |
masakjm | 1:9d0e2e5b5d25 | 78 | DEBUG("== FlashPut %s %d %d\r\n", key, data, ret); |
masakjm | 1:9d0e2e5b5d25 | 79 | return ret; |
masakjm | 1:9d0e2e5b5d25 | 80 | } |
masakjm | 1:9d0e2e5b5d25 | 81 | |
masakjm | 1:9d0e2e5b5d25 | 82 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 83 | // Setting |
masakjm | 1:9d0e2e5b5d25 | 84 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 85 | bool setting_inc; // 設定値を増加 |
masakjm | 1:9d0e2e5b5d25 | 86 | bool setting_enter; // 設定値を入力 |
masakjm | 1:9d0e2e5b5d25 | 87 | bool setting_next; // 次の設定値に移動 |
masakjm | 1:9d0e2e5b5d25 | 88 | |
masakjm | 1:9d0e2e5b5d25 | 89 | KeyValueInt kviKeyCode1("keycode1",DISP_SETTING_FREQ, 1, 1, NUM_GROUP1, true); |
masakjm | 1:9d0e2e5b5d25 | 90 | |
masakjm | 1:9d0e2e5b5d25 | 91 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 92 | * @brief 1つのパラメータの表示と変更 |
masakjm | 1:9d0e2e5b5d25 | 93 | * @param storage 不揮発メモリインスタンス |
masakjm | 1:9d0e2e5b5d25 | 94 | * @param para パラメータのキーと値の組 |
masakjm | 1:9d0e2e5b5d25 | 95 | * @param change 変更する時 true |
masakjm | 1:9d0e2e5b5d25 | 96 | * @param disp 今の値を表示する時 true |
masakjm | 1:9d0e2e5b5d25 | 97 | * @return bool true : Success false : Failed |
masakjm | 1:9d0e2e5b5d25 | 98 | */ |
masakjm | 1:9d0e2e5b5d25 | 99 | static bool paraSettingOne(MicroBitStorage storage, KeyValueInt* para, bool change, bool disp) |
masakjm | 1:9d0e2e5b5d25 | 100 | { |
masakjm | 1:9d0e2e5b5d25 | 101 | if(disp){ |
masakjm | 1:9d0e2e5b5d25 | 102 | display.print(para->disp); // 識別文字をLED表示 |
masakjm | 1:9d0e2e5b5d25 | 103 | wait(SETTING_DISPLAY_WAIT); |
masakjm | 1:9d0e2e5b5d25 | 104 | displayNumber(para->value); // 値をLED表示 |
masakjm | 1:9d0e2e5b5d25 | 105 | } |
masakjm | 1:9d0e2e5b5d25 | 106 | if (!change) { |
masakjm | 1:9d0e2e5b5d25 | 107 | wait(SETTING_DISPLAY_WAIT); |
masakjm | 1:9d0e2e5b5d25 | 108 | return true; |
masakjm | 1:9d0e2e5b5d25 | 109 | } |
masakjm | 1:9d0e2e5b5d25 | 110 | |
masakjm | 1:9d0e2e5b5d25 | 111 | DEBUG("== paraSetting\r\n"); |
masakjm | 1:9d0e2e5b5d25 | 112 | setting_inc = false; |
masakjm | 1:9d0e2e5b5d25 | 113 | setting_next = setting_enter = false; |
masakjm | 1:9d0e2e5b5d25 | 114 | while( ! setting_next) { // Bボタンが離されるまで |
masakjm | 1:9d0e2e5b5d25 | 115 | if (setting_inc) { // Aボタンが押されたら |
masakjm | 1:9d0e2e5b5d25 | 116 | setting_inc = false; |
masakjm | 1:9d0e2e5b5d25 | 117 | para->inc(); |
masakjm | 1:9d0e2e5b5d25 | 118 | displayNumber(para->value); |
masakjm | 1:9d0e2e5b5d25 | 119 | } |
masakjm | 1:9d0e2e5b5d25 | 120 | wait(0.2); |
masakjm | 1:9d0e2e5b5d25 | 121 | } |
masakjm | 1:9d0e2e5b5d25 | 122 | int ret = FlashPut(storage, para->key, para->value); |
masakjm | 1:9d0e2e5b5d25 | 123 | if (ret) DEBUG("(strage)Error %d\r\n",ret); |
masakjm | 1:9d0e2e5b5d25 | 124 | return (ret == MICROBIT_OK); |
masakjm | 1:9d0e2e5b5d25 | 125 | } |
masakjm | 1:9d0e2e5b5d25 | 126 | |
masakjm | 1:9d0e2e5b5d25 | 127 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 128 | * @brief よく変更するパラメータの表示と変更 |
masakjm | 1:9d0e2e5b5d25 | 129 | * @param change true:変更する時 |
masakjm | 1:9d0e2e5b5d25 | 130 | * @return char 0 : Success 'e' : Failed |
masakjm | 1:9d0e2e5b5d25 | 131 | */ |
masakjm | 1:9d0e2e5b5d25 | 132 | static char paraSettingFreq(bool change=false) |
masakjm | 1:9d0e2e5b5d25 | 133 | { |
masakjm | 1:9d0e2e5b5d25 | 134 | MicroBitStorage storage; |
masakjm | 1:9d0e2e5b5d25 | 135 | |
masakjm | 1:9d0e2e5b5d25 | 136 | kviKeyCode1.set(FlashGet(storage, kviKeyCode1.key, 1)); |
masakjm | 1:9d0e2e5b5d25 | 137 | if (paraSettingOne(storage, &kviKeyCode1, change, true)) return 0; |
masakjm | 1:9d0e2e5b5d25 | 138 | else return 'e'; |
masakjm | 1:9d0e2e5b5d25 | 139 | } |
masakjm | 1:9d0e2e5b5d25 | 140 | |
masakjm | 1:9d0e2e5b5d25 | 141 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 142 | * @brief デバイス固有のパラメータの表示と変更 |
masakjm | 1:9d0e2e5b5d25 | 143 | * @param change true:変更する時 |
masakjm | 1:9d0e2e5b5d25 | 144 | * @return char 0 : Success 'e' : Failed |
masakjm | 1:9d0e2e5b5d25 | 145 | */ |
masakjm | 1:9d0e2e5b5d25 | 146 | static char paraSettingSpec(bool change=false) |
masakjm | 1:9d0e2e5b5d25 | 147 | { |
masakjm | 1:9d0e2e5b5d25 | 148 | MicroBitStorage storage; |
masakjm | 1:9d0e2e5b5d25 | 149 | |
masakjm | 1:9d0e2e5b5d25 | 150 | // kviStickDirec.set(FlashGet(storage, kviStickDirec.key, 1)); |
masakjm | 1:9d0e2e5b5d25 | 151 | |
masakjm | 1:9d0e2e5b5d25 | 152 | if(State == STATE_SETTING_DEVICE) { |
masakjm | 1:9d0e2e5b5d25 | 153 | // if (paraSettingOne(storage, &kviStickDirec, true , true)) return 0; |
masakjm | 1:9d0e2e5b5d25 | 154 | // else return 'e'; |
masakjm | 1:9d0e2e5b5d25 | 155 | } else { |
masakjm | 1:9d0e2e5b5d25 | 156 | // if (paraSettingOne(storage, &kviStickDirec, false , false)) return 0; |
masakjm | 1:9d0e2e5b5d25 | 157 | // else return 'e'; |
masakjm | 1:9d0e2e5b5d25 | 158 | } |
masakjm | 1:9d0e2e5b5d25 | 159 | } |
masakjm | 1:9d0e2e5b5d25 | 160 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 161 | // BLE & HID |
masakjm | 1:9d0e2e5b5d25 | 162 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 163 | BLE ble; |
masakjm | 1:9d0e2e5b5d25 | 164 | KeyboardService *kbdServicePtr; |
masakjm | 1:9d0e2e5b5d25 | 165 | BLE_MESSAGE bleMessage; |
masakjm | 1:9d0e2e5b5d25 | 166 | |
masakjm | 1:9d0e2e5b5d25 | 167 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 168 | * @brief BLE接続が切断された時のコールバック関数 |
masakjm | 1:9d0e2e5b5d25 | 169 | */ |
masakjm | 1:9d0e2e5b5d25 | 170 | static void onDisconnect(const Gap::DisconnectionCallbackParams_t *params) |
masakjm | 1:9d0e2e5b5d25 | 171 | { |
masakjm | 1:9d0e2e5b5d25 | 172 | DEBUG("(BLE)disconnected\r\n"); |
masakjm | 1:9d0e2e5b5d25 | 173 | ble.gap().startAdvertising(); // restart advertising |
masakjm | 1:9d0e2e5b5d25 | 174 | bleMessage = BLE_NO_MESSAGE; |
masakjm | 1:9d0e2e5b5d25 | 175 | } |
masakjm | 1:9d0e2e5b5d25 | 176 | |
masakjm | 1:9d0e2e5b5d25 | 177 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 178 | * @brief BLE接続が接続された時のコールバック関数 |
masakjm | 1:9d0e2e5b5d25 | 179 | */ |
masakjm | 1:9d0e2e5b5d25 | 180 | static void onConnect(const Gap::ConnectionCallbackParams_t *params) |
masakjm | 1:9d0e2e5b5d25 | 181 | { |
masakjm | 1:9d0e2e5b5d25 | 182 | if(kbdServicePtr->isConnected()) { |
masakjm | 1:9d0e2e5b5d25 | 183 | DEBUG("(BLE)connected\r\n"); |
masakjm | 1:9d0e2e5b5d25 | 184 | ble.gap().stopAdvertising(); |
masakjm | 1:9d0e2e5b5d25 | 185 | bleMessage = BLE_CONNECTED; |
masakjm | 1:9d0e2e5b5d25 | 186 | } |
masakjm | 1:9d0e2e5b5d25 | 187 | } |
masakjm | 1:9d0e2e5b5d25 | 188 | |
masakjm | 1:9d0e2e5b5d25 | 189 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 190 | * @brief パスキー入力を求められた時のコールバック関数 |
masakjm | 1:9d0e2e5b5d25 | 191 | */ |
masakjm | 1:9d0e2e5b5d25 | 192 | static void passkeyDisplayCallback(Gap::Handle_t handle, const SecurityManager::Passkey_t passkey) |
masakjm | 1:9d0e2e5b5d25 | 193 | { |
masakjm | 1:9d0e2e5b5d25 | 194 | printf("(BLE)Input passKey: "); |
masakjm | 1:9d0e2e5b5d25 | 195 | for (unsigned i = 0; i < Gap::ADDR_LEN; i++) { |
masakjm | 1:9d0e2e5b5d25 | 196 | printf("%c", passkey[i]); |
masakjm | 1:9d0e2e5b5d25 | 197 | } |
masakjm | 1:9d0e2e5b5d25 | 198 | printf("\r\n"); |
masakjm | 1:9d0e2e5b5d25 | 199 | } |
masakjm | 1:9d0e2e5b5d25 | 200 | |
masakjm | 1:9d0e2e5b5d25 | 201 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 202 | * @brief セキュリティ設定完了時のコールバック関数 |
masakjm | 1:9d0e2e5b5d25 | 203 | */ |
masakjm | 1:9d0e2e5b5d25 | 204 | static void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status) |
masakjm | 1:9d0e2e5b5d25 | 205 | { |
masakjm | 1:9d0e2e5b5d25 | 206 | if (status == SecurityManager::SEC_STATUS_SUCCESS) { |
masakjm | 1:9d0e2e5b5d25 | 207 | // DEBUG("(BLE)Security success %d\r\n", status); |
masakjm | 1:9d0e2e5b5d25 | 208 | bleMessage = BLE_PAIRING_SUCCESS; |
masakjm | 1:9d0e2e5b5d25 | 209 | |
masakjm | 1:9d0e2e5b5d25 | 210 | } else { |
masakjm | 1:9d0e2e5b5d25 | 211 | // DEBUG("(BLE)Security failed %d\r\n", status); |
masakjm | 1:9d0e2e5b5d25 | 212 | bleMessage = BLE_PAIRING_FAILED; |
masakjm | 1:9d0e2e5b5d25 | 213 | } |
masakjm | 1:9d0e2e5b5d25 | 214 | } |
masakjm | 1:9d0e2e5b5d25 | 215 | |
masakjm | 1:9d0e2e5b5d25 | 216 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 217 | * @brief セキュリティ初期化 |
masakjm | 1:9d0e2e5b5d25 | 218 | * @para _ble BLEインスタンス |
masakjm | 1:9d0e2e5b5d25 | 219 | */ |
masakjm | 1:9d0e2e5b5d25 | 220 | static void initializeSecurity(BLE &_ble) |
masakjm | 1:9d0e2e5b5d25 | 221 | { |
masakjm | 1:9d0e2e5b5d25 | 222 | bool enableBonding = true; |
masakjm | 1:9d0e2e5b5d25 | 223 | bool requireMITM = HID_SECURITY_REQUIRE_MITM; |
masakjm | 1:9d0e2e5b5d25 | 224 | |
masakjm | 1:9d0e2e5b5d25 | 225 | _ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback); |
masakjm | 1:9d0e2e5b5d25 | 226 | _ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback); |
masakjm | 1:9d0e2e5b5d25 | 227 | |
masakjm | 1:9d0e2e5b5d25 | 228 | _ble.securityManager().init(enableBonding, requireMITM, HID_SECURITY_IOCAPS); |
masakjm | 1:9d0e2e5b5d25 | 229 | } |
masakjm | 0:e0105c17ebb3 | 230 | |
masakjm | 1:9d0e2e5b5d25 | 231 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 232 | * @brief HOGP (HID Over GATT Profile) 初期化 |
masakjm | 1:9d0e2e5b5d25 | 233 | * @para _ble BLEインスタンス |
masakjm | 1:9d0e2e5b5d25 | 234 | */ |
masakjm | 1:9d0e2e5b5d25 | 235 | static void initializeHOGP(BLE &_ble) |
masakjm | 1:9d0e2e5b5d25 | 236 | { |
masakjm | 1:9d0e2e5b5d25 | 237 | static const uint16_t uuid16_list[] = {GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE, |
masakjm | 1:9d0e2e5b5d25 | 238 | GattService::UUID_DEVICE_INFORMATION_SERVICE, |
masakjm | 1:9d0e2e5b5d25 | 239 | GattService::UUID_BATTERY_SERVICE |
masakjm | 1:9d0e2e5b5d25 | 240 | }; |
masakjm | 1:9d0e2e5b5d25 | 241 | |
masakjm | 1:9d0e2e5b5d25 | 242 | PnPID_t pnpID; |
masakjm | 1:9d0e2e5b5d25 | 243 | pnpID.vendorID_source = 0x2; // from the USB Implementer's Forum |
masakjm | 1:9d0e2e5b5d25 | 244 | pnpID.vendorID = 0x0D28; // NXP |
masakjm | 1:9d0e2e5b5d25 | 245 | pnpID.productID = 0x0204; // CMSIS-DAP (well, it's a keyboard but oh well) |
masakjm | 1:9d0e2e5b5d25 | 246 | pnpID.productVersion = 0x0100; // v1.0 |
masakjm | 1:9d0e2e5b5d25 | 247 | HIDDeviceInformationService deviceInfo(_ble, "ARM", "m1", "abc", "def", "ghi", "jkl", &pnpID); |
masakjm | 1:9d0e2e5b5d25 | 248 | |
masakjm | 1:9d0e2e5b5d25 | 249 | BatteryService batteryInfo(_ble, 80); |
masakjm | 1:9d0e2e5b5d25 | 250 | |
masakjm | 1:9d0e2e5b5d25 | 251 | _ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | |
masakjm | 1:9d0e2e5b5d25 | 252 | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
masakjm | 1:9d0e2e5b5d25 | 253 | _ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, |
masakjm | 1:9d0e2e5b5d25 | 254 | (uint8_t *)uuid16_list, sizeof(uuid16_list)); |
masakjm | 1:9d0e2e5b5d25 | 255 | |
masakjm | 1:9d0e2e5b5d25 | 256 | // see 5.1.2: HID over GATT Specification (pg. 25) |
masakjm | 1:9d0e2e5b5d25 | 257 | _ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
masakjm | 1:9d0e2e5b5d25 | 258 | // 30ms to 50ms is recommended (5.1.2) |
masakjm | 1:9d0e2e5b5d25 | 259 | _ble.gap().setAdvertisingInterval(50); |
masakjm | 1:9d0e2e5b5d25 | 260 | } |
masakjm | 1:9d0e2e5b5d25 | 261 | |
masakjm | 1:9d0e2e5b5d25 | 262 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 263 | * @brief BLE接続のHID(human interface device) の初期化 |
masakjm | 1:9d0e2e5b5d25 | 264 | */ |
masakjm | 1:9d0e2e5b5d25 | 265 | static void initialize_BLE_HID() |
masakjm | 1:9d0e2e5b5d25 | 266 | { |
masakjm | 1:9d0e2e5b5d25 | 267 | static const char SHORT_DEVICE_NAME[] = "micro:bit"; |
masakjm | 1:9d0e2e5b5d25 | 268 | static char DeviceName[20]; |
masakjm | 1:9d0e2e5b5d25 | 269 | |
masakjm | 1:9d0e2e5b5d25 | 270 | int id = microbit_serial_number()& 0xfff; // シリアル番号の下12桁を4桁の10進で表示 |
masakjm | 1:9d0e2e5b5d25 | 271 | sprintf(DeviceName, "micro:bit %04d", id); |
masakjm | 1:9d0e2e5b5d25 | 272 | DEBUG("(BLE)id %s\r\n", DeviceName); |
masakjm | 1:9d0e2e5b5d25 | 273 | |
masakjm | 1:9d0e2e5b5d25 | 274 | // DEBUG("(BLE)initialising ble\r\n"); |
masakjm | 1:9d0e2e5b5d25 | 275 | ble.init(); |
masakjm | 1:9d0e2e5b5d25 | 276 | |
masakjm | 1:9d0e2e5b5d25 | 277 | ble.gap().onDisconnection(onDisconnect); |
masakjm | 1:9d0e2e5b5d25 | 278 | ble.gap().onConnection(onConnect); |
masakjm | 1:9d0e2e5b5d25 | 279 | |
masakjm | 1:9d0e2e5b5d25 | 280 | initializeSecurity(ble); |
masakjm | 1:9d0e2e5b5d25 | 281 | |
masakjm | 1:9d0e2e5b5d25 | 282 | DEBUG("(BLE)adding hid service\r\n"); |
masakjm | 1:9d0e2e5b5d25 | 283 | KeyboardService kbdService(ble); |
masakjm | 1:9d0e2e5b5d25 | 284 | kbdServicePtr = &kbdService; |
masakjm | 1:9d0e2e5b5d25 | 285 | |
masakjm | 1:9d0e2e5b5d25 | 286 | DEBUG("(BLE)adding device info and battery service\r\n"); |
masakjm | 1:9d0e2e5b5d25 | 287 | initializeHOGP(ble); |
masakjm | 1:9d0e2e5b5d25 | 288 | |
masakjm | 1:9d0e2e5b5d25 | 289 | DEBUG("(BLE)setting up gap\r\n"); |
masakjm | 1:9d0e2e5b5d25 | 290 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD); |
masakjm | 1:9d0e2e5b5d25 | 291 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, |
masakjm | 1:9d0e2e5b5d25 | 292 | (uint8_t *)DeviceName, sizeof(DeviceName)); |
masakjm | 1:9d0e2e5b5d25 | 293 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, |
masakjm | 1:9d0e2e5b5d25 | 294 | (uint8_t *)SHORT_DEVICE_NAME, sizeof(SHORT_DEVICE_NAME)); |
masakjm | 1:9d0e2e5b5d25 | 295 | ble.gap().setDeviceName((const uint8_t *)DeviceName); |
masakjm | 1:9d0e2e5b5d25 | 296 | |
masakjm | 1:9d0e2e5b5d25 | 297 | DEBUG("(BLE)advertising\r\n"); |
masakjm | 1:9d0e2e5b5d25 | 298 | ble.gap().startAdvertising(); |
masakjm | 1:9d0e2e5b5d25 | 299 | } |
masakjm | 1:9d0e2e5b5d25 | 300 | |
masakjm | 1:9d0e2e5b5d25 | 301 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 302 | // Button |
masakjm | 1:9d0e2e5b5d25 | 303 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 304 | MicroBitMessageBus bus; |
masakjm | 1:9d0e2e5b5d25 | 305 | MicroBitButton buttonA(MICROBIT_PIN_BUTTON_A, MICROBIT_ID_BUTTON_A); |
masakjm | 1:9d0e2e5b5d25 | 306 | MicroBitButton buttonB(MICROBIT_PIN_BUTTON_B, MICROBIT_ID_BUTTON_B); |
masakjm | 1:9d0e2e5b5d25 | 307 | MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0, PIN_CAPABILITY_ALL); |
masakjm | 1:9d0e2e5b5d25 | 308 | MicroBitPin P1(MICROBIT_ID_IO_P1, MICROBIT_PIN_P1, PIN_CAPABILITY_ALL); |
masakjm | 1:9d0e2e5b5d25 | 309 | MicroBitPin P2(MICROBIT_ID_IO_P2, MICROBIT_PIN_P2, PIN_CAPABILITY_ALL); |
masakjm | 1:9d0e2e5b5d25 | 310 | |
masakjm | 1:9d0e2e5b5d25 | 311 | //MicroBitButton button0(MICROBIT_PIN_P0, MICROBIT_ID_IO_P0, MICROBIT_BUTTON_ALL_EVENTS, PullUp); |
masakjm | 1:9d0e2e5b5d25 | 312 | //MicroBitButton button1(MICROBIT_PIN_P1, MICROBIT_ID_IO_P1, MICROBIT_BUTTON_ALL_EVENTS, PullUp); |
masakjm | 1:9d0e2e5b5d25 | 313 | //MicroBitButton button2(MICROBIT_PIN_P2, MICROBIT_ID_IO_P2, MICROBIT_BUTTON_ALL_EVENTS, PullUp); |
masakjm | 1:9d0e2e5b5d25 | 314 | MicroBitButton button15(MICROBIT_PIN_P15, MICROBIT_ID_IO_P15, MICROBIT_BUTTON_ALL_EVENTS, PullUp); |
masakjm | 1:9d0e2e5b5d25 | 315 | MicroBitButton button16(MICROBIT_PIN_P16, MICROBIT_ID_IO_P16, MICROBIT_BUTTON_ALL_EVENTS, PullUp); |
masakjm | 1:9d0e2e5b5d25 | 316 | |
masakjm | 1:9d0e2e5b5d25 | 317 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 318 | * @brief キーコードを送信する |
masakjm | 1:9d0e2e5b5d25 | 319 | * @para code 上位8bit:修飾キー 下位8bit:キーコード |
masakjm | 1:9d0e2e5b5d25 | 320 | */ |
masakjm | 1:9d0e2e5b5d25 | 321 | static void sendKeyCode(int code) { |
masakjm | 1:9d0e2e5b5d25 | 322 | if (code) { |
masakjm | 1:9d0e2e5b5d25 | 323 | uint8_t key = code & 0xff; |
masakjm | 1:9d0e2e5b5d25 | 324 | uint8_t modif = code >> 8; |
masakjm | 0:e0105c17ebb3 | 325 | |
masakjm | 1:9d0e2e5b5d25 | 326 | if (key > KEYMAP_SIZE ) { |
masakjm | 1:9d0e2e5b5d25 | 327 | DispChar = DISP_ERROR_INCORRECT_CODE; // キーコード設定間違い |
masakjm | 1:9d0e2e5b5d25 | 328 | } else { |
masakjm | 1:9d0e2e5b5d25 | 329 | ble_error_t ret = kbdServicePtr->keyDownCode(key, modif); |
masakjm | 1:9d0e2e5b5d25 | 330 | // DEBUG(" code=%d modif=%d\r\n",key , modif); |
masakjm | 1:9d0e2e5b5d25 | 331 | if (ret) { |
masakjm | 1:9d0e2e5b5d25 | 332 | DispChar = DISP_BLE_ERROR_SENDDATA; |
masakjm | 1:9d0e2e5b5d25 | 333 | DispCharLast = DISP_NO_MESSAGE; // E が続く時に表示 |
masakjm | 1:9d0e2e5b5d25 | 334 | DEBUG("(BLE)Error %d\r\n",ret); |
masakjm | 1:9d0e2e5b5d25 | 335 | } |
masakjm | 1:9d0e2e5b5d25 | 336 | } |
masakjm | 1:9d0e2e5b5d25 | 337 | } |
masakjm | 1:9d0e2e5b5d25 | 338 | } |
masakjm | 1:9d0e2e5b5d25 | 339 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 340 | * @brief ボタン保持時イベント |
masakjm | 1:9d0e2e5b5d25 | 341 | * @para e イベント |
masakjm | 1:9d0e2e5b5d25 | 342 | */ |
masakjm | 1:9d0e2e5b5d25 | 343 | static void onButtonHold(MicroBitEvent e) |
masakjm | 1:9d0e2e5b5d25 | 344 | { |
masakjm | 1:9d0e2e5b5d25 | 345 | if ((e.source == MICROBIT_ID_BUTTON_A && buttonB.isPressed()) || |
masakjm | 1:9d0e2e5b5d25 | 346 | (e.source == MICROBIT_ID_BUTTON_B && buttonA.isPressed()) ) { |
masakjm | 1:9d0e2e5b5d25 | 347 | KeyBuff.push(BUTTON_STATUS_HOLD + BUTTON_NAME_A + BUTTON_NAME_B); |
masakjm | 1:9d0e2e5b5d25 | 348 | } |
masakjm | 1:9d0e2e5b5d25 | 349 | } |
masakjm | 1:9d0e2e5b5d25 | 350 | |
masakjm | 1:9d0e2e5b5d25 | 351 | static void ButtonHoldProcess(int button) |
masakjm | 1:9d0e2e5b5d25 | 352 | { |
masakjm | 1:9d0e2e5b5d25 | 353 | int code = 0; |
masakjm | 1:9d0e2e5b5d25 | 354 | switch(button) { |
masakjm | 1:9d0e2e5b5d25 | 355 | case BUTTON_NAME_A + BUTTON_NAME_B : |
masakjm | 1:9d0e2e5b5d25 | 356 | DispChar = DISP_HOLD_BUTTON_AB; |
masakjm | 1:9d0e2e5b5d25 | 357 | code = keyCodeGroup_AB[2]; |
masakjm | 1:9d0e2e5b5d25 | 358 | break; |
masakjm | 1:9d0e2e5b5d25 | 359 | } |
masakjm | 1:9d0e2e5b5d25 | 360 | if (code != 0 ) sendKeyCode(code); |
masakjm | 1:9d0e2e5b5d25 | 361 | } |
masakjm | 1:9d0e2e5b5d25 | 362 | |
masakjm | 1:9d0e2e5b5d25 | 363 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 364 | * @brief ボタン押下げ時イベント |
masakjm | 1:9d0e2e5b5d25 | 365 | * @para e イベント |
masakjm | 1:9d0e2e5b5d25 | 366 | */ |
masakjm | 1:9d0e2e5b5d25 | 367 | static void onButtonDown(MicroBitEvent e) |
masakjm | 1:9d0e2e5b5d25 | 368 | { |
masakjm | 1:9d0e2e5b5d25 | 369 | // DEBUG(" Button Down %d State=%d\r\n", e.source, State); |
masakjm | 1:9d0e2e5b5d25 | 370 | |
masakjm | 1:9d0e2e5b5d25 | 371 | switch (State) { |
masakjm | 1:9d0e2e5b5d25 | 372 | case STATE_SETTING_FREQ : |
masakjm | 1:9d0e2e5b5d25 | 373 | case STATE_SETTING_DEVICE : |
masakjm | 1:9d0e2e5b5d25 | 374 | switch(e.source) { |
masakjm | 1:9d0e2e5b5d25 | 375 | case MICROBIT_ID_BUTTON_A : |
masakjm | 1:9d0e2e5b5d25 | 376 | setting_inc = true; |
masakjm | 1:9d0e2e5b5d25 | 377 | break; |
masakjm | 1:9d0e2e5b5d25 | 378 | case MICROBIT_ID_BUTTON_B : |
masakjm | 1:9d0e2e5b5d25 | 379 | setting_enter = true; |
masakjm | 1:9d0e2e5b5d25 | 380 | break; |
masakjm | 1:9d0e2e5b5d25 | 381 | } |
masakjm | 1:9d0e2e5b5d25 | 382 | break; |
masakjm | 1:9d0e2e5b5d25 | 383 | case STATE_OPERATING : |
masakjm | 1:9d0e2e5b5d25 | 384 | switch(e.source) { |
masakjm | 1:9d0e2e5b5d25 | 385 | case MICROBIT_ID_BUTTON_A : |
masakjm | 1:9d0e2e5b5d25 | 386 | KeyBuff.push(BUTTON_STATUS_DOWN + BUTTON_NAME_A); |
masakjm | 1:9d0e2e5b5d25 | 387 | break; |
masakjm | 1:9d0e2e5b5d25 | 388 | case MICROBIT_ID_BUTTON_B : |
masakjm | 1:9d0e2e5b5d25 | 389 | KeyBuff.push(BUTTON_STATUS_DOWN + BUTTON_NAME_B); |
masakjm | 1:9d0e2e5b5d25 | 390 | break; |
masakjm | 1:9d0e2e5b5d25 | 391 | case MICROBIT_ID_IO_P0 : |
masakjm | 1:9d0e2e5b5d25 | 392 | KeyBuff.push(BUTTON_STATUS_DOWN + BUTTON_NAME_P0); |
masakjm | 1:9d0e2e5b5d25 | 393 | break; |
masakjm | 1:9d0e2e5b5d25 | 394 | case MICROBIT_ID_IO_P1 : |
masakjm | 1:9d0e2e5b5d25 | 395 | case MICROBIT_ID_IO_P16 : |
masakjm | 1:9d0e2e5b5d25 | 396 | KeyBuff.push(BUTTON_STATUS_DOWN + BUTTON_NAME_P1); |
masakjm | 1:9d0e2e5b5d25 | 397 | break; |
masakjm | 1:9d0e2e5b5d25 | 398 | case MICROBIT_ID_IO_P2 : |
masakjm | 1:9d0e2e5b5d25 | 399 | case MICROBIT_ID_IO_P15 : |
masakjm | 1:9d0e2e5b5d25 | 400 | KeyBuff.push(BUTTON_STATUS_DOWN + BUTTON_NAME_P2); |
masakjm | 1:9d0e2e5b5d25 | 401 | break; |
masakjm | 1:9d0e2e5b5d25 | 402 | } |
masakjm | 1:9d0e2e5b5d25 | 403 | } |
masakjm | 1:9d0e2e5b5d25 | 404 | } |
masakjm | 1:9d0e2e5b5d25 | 405 | |
masakjm | 1:9d0e2e5b5d25 | 406 | static void ButtonDownProcess(int button) |
masakjm | 1:9d0e2e5b5d25 | 407 | { |
masakjm | 1:9d0e2e5b5d25 | 408 | int code = 0; |
masakjm | 1:9d0e2e5b5d25 | 409 | switch(button) { |
masakjm | 1:9d0e2e5b5d25 | 410 | case BUTTON_NAME_A : |
masakjm | 1:9d0e2e5b5d25 | 411 | DispChar = DISP_PRESS_BUTTON_A; |
masakjm | 1:9d0e2e5b5d25 | 412 | code = keyCodeGroup_AB[0]; |
masakjm | 1:9d0e2e5b5d25 | 413 | break; |
masakjm | 1:9d0e2e5b5d25 | 414 | case BUTTON_NAME_B : |
masakjm | 1:9d0e2e5b5d25 | 415 | DispChar = DISP_PRESS_BUTTON_B; |
masakjm | 1:9d0e2e5b5d25 | 416 | code = keyCodeGroup_AB[1]; |
masakjm | 1:9d0e2e5b5d25 | 417 | break; |
masakjm | 1:9d0e2e5b5d25 | 418 | case BUTTON_NAME_P0 : |
masakjm | 1:9d0e2e5b5d25 | 419 | DispChar = DISP_ACTIVE_IO_P0; |
masakjm | 1:9d0e2e5b5d25 | 420 | code = keyCodeGroup_3SW[kviKeyCode1.value-1][0]; |
masakjm | 1:9d0e2e5b5d25 | 421 | break; |
masakjm | 1:9d0e2e5b5d25 | 422 | case BUTTON_NAME_P1 : |
masakjm | 1:9d0e2e5b5d25 | 423 | DispChar = DISP_ACTIVE_IO_P1; |
masakjm | 1:9d0e2e5b5d25 | 424 | code = keyCodeGroup_3SW[kviKeyCode1.value-1][1]; |
masakjm | 1:9d0e2e5b5d25 | 425 | break; |
masakjm | 1:9d0e2e5b5d25 | 426 | case BUTTON_NAME_P2 : |
masakjm | 1:9d0e2e5b5d25 | 427 | DispChar = DISP_ACTIVE_IO_P2; |
masakjm | 1:9d0e2e5b5d25 | 428 | code = keyCodeGroup_3SW[kviKeyCode1.value-1][2]; |
masakjm | 1:9d0e2e5b5d25 | 429 | break; |
masakjm | 1:9d0e2e5b5d25 | 430 | } |
masakjm | 1:9d0e2e5b5d25 | 431 | if (code != 0 ) sendKeyCode(code); |
masakjm | 1:9d0e2e5b5d25 | 432 | } |
masakjm | 1:9d0e2e5b5d25 | 433 | |
masakjm | 1:9d0e2e5b5d25 | 434 | /** ---------- |
masakjm | 1:9d0e2e5b5d25 | 435 | * @brief ボタン離し時イベント |
masakjm | 1:9d0e2e5b5d25 | 436 | * @para e イベント |
masakjm | 1:9d0e2e5b5d25 | 437 | */ |
masakjm | 1:9d0e2e5b5d25 | 438 | static void onButtonUp(MicroBitEvent e) |
masakjm | 1:9d0e2e5b5d25 | 439 | { |
masakjm | 1:9d0e2e5b5d25 | 440 | // DEBUG(" Button up %d\r\n", e.source); |
masakjm | 1:9d0e2e5b5d25 | 441 | switch (State) { |
masakjm | 1:9d0e2e5b5d25 | 442 | case STATE_SETTING_FREQ : |
masakjm | 1:9d0e2e5b5d25 | 443 | case STATE_SETTING_DEVICE : |
masakjm | 1:9d0e2e5b5d25 | 444 | if(setting_enter) setting_next = true; // 決定ボタンを離したら次へ |
masakjm | 1:9d0e2e5b5d25 | 445 | break; |
masakjm | 1:9d0e2e5b5d25 | 446 | case STATE_OPERATING : |
masakjm | 1:9d0e2e5b5d25 | 447 | KeyBuff.push(BUTTON_STATUS_UP); |
masakjm | 1:9d0e2e5b5d25 | 448 | } |
masakjm | 1:9d0e2e5b5d25 | 449 | } |
masakjm | 1:9d0e2e5b5d25 | 450 | |
masakjm | 1:9d0e2e5b5d25 | 451 | static void ButtonUpProcess() |
masakjm | 1:9d0e2e5b5d25 | 452 | { |
masakjm | 1:9d0e2e5b5d25 | 453 | DispChar = DISP_NO_MESSAGE; |
masakjm | 1:9d0e2e5b5d25 | 454 | ble_error_t ret = kbdServicePtr->keyUpCode(); |
masakjm | 1:9d0e2e5b5d25 | 455 | if (ret) { |
masakjm | 1:9d0e2e5b5d25 | 456 | DispChar = DISP_BLE_ERROR_SENDDATA; |
masakjm | 1:9d0e2e5b5d25 | 457 | DispCharLast = DISP_NO_MESSAGE; // E が続く時に表示 |
masakjm | 1:9d0e2e5b5d25 | 458 | } |
masakjm | 1:9d0e2e5b5d25 | 459 | } |
masakjm | 1:9d0e2e5b5d25 | 460 | |
masakjm | 1:9d0e2e5b5d25 | 461 | //--------------------------------- |
masakjm | 1:9d0e2e5b5d25 | 462 | // Main |
masakjm | 1:9d0e2e5b5d25 | 463 | //--------------------------------- |
masakjm | 0:e0105c17ebb3 | 464 | int main() |
masakjm | 0:e0105c17ebb3 | 465 | { |
masakjm | 1:9d0e2e5b5d25 | 466 | State = STATE_DESABLE_INPUT; |
masakjm | 1:9d0e2e5b5d25 | 467 | |
masakjm | 1:9d0e2e5b5d25 | 468 | wait(0.1); // ボタン状態の更新 |
masakjm | 1:9d0e2e5b5d25 | 469 | bool bA = buttonA.isPressed(); |
masakjm | 1:9d0e2e5b5d25 | 470 | bool bB = buttonB.isPressed(); |
masakjm | 1:9d0e2e5b5d25 | 471 | |
masakjm | 1:9d0e2e5b5d25 | 472 | if (bA && bB) { // ボタンABを押しながら起動 |
masakjm | 1:9d0e2e5b5d25 | 473 | for(int i=0;i<2;i++) { |
masakjm | 1:9d0e2e5b5d25 | 474 | display.scroll(VERSION); |
masakjm | 1:9d0e2e5b5d25 | 475 | wait(0.5); |
masakjm | 1:9d0e2e5b5d25 | 476 | } |
masakjm | 1:9d0e2e5b5d25 | 477 | } else if(bA) { // ボタンAを押しながら起動 |
masakjm | 1:9d0e2e5b5d25 | 478 | State = STATE_SETTING_FREQ; |
masakjm | 1:9d0e2e5b5d25 | 479 | } else if(bB) { // ボタンBを押しながら起動 |
masakjm | 1:9d0e2e5b5d25 | 480 | State = STATE_SETTING_DEVICE; |
masakjm | 1:9d0e2e5b5d25 | 481 | } |
masakjm | 1:9d0e2e5b5d25 | 482 | |
masakjm | 1:9d0e2e5b5d25 | 483 | //----- Display |
masakjm | 1:9d0e2e5b5d25 | 484 | display.setDisplayMode(DISPLAY_MODE_BLACK_AND_WHITE); |
masakjm | 1:9d0e2e5b5d25 | 485 | display.clear(); |
masakjm | 1:9d0e2e5b5d25 | 486 | Timer dispTime; // 連続表示タイマー |
masakjm | 1:9d0e2e5b5d25 | 487 | dispTime.start(); |
masakjm | 1:9d0e2e5b5d25 | 488 | |
masakjm | 1:9d0e2e5b5d25 | 489 | //----- Button |
masakjm | 1:9d0e2e5b5d25 | 490 | bus.listen(MICROBIT_ID_ANY, MICROBIT_BUTTON_EVT_DOWN, onButtonDown); |
masakjm | 1:9d0e2e5b5d25 | 491 | bus.listen(MICROBIT_ID_ANY, MICROBIT_BUTTON_EVT_UP, onButtonUp); |
masakjm | 1:9d0e2e5b5d25 | 492 | bus.listen(MICROBIT_ID_ANY, MICROBIT_BUTTON_EVT_HOLD, onButtonHold); |
masakjm | 1:9d0e2e5b5d25 | 493 | |
masakjm | 1:9d0e2e5b5d25 | 494 | // Put the P0, P1 and P2 pins into touch sense mode. |
masakjm | 1:9d0e2e5b5d25 | 495 | P0.isTouched(); |
masakjm | 1:9d0e2e5b5d25 | 496 | P1.isTouched(); |
masakjm | 1:9d0e2e5b5d25 | 497 | P2.isTouched(); |
masakjm | 1:9d0e2e5b5d25 | 498 | |
masakjm | 1:9d0e2e5b5d25 | 499 | |
masakjm | 1:9d0e2e5b5d25 | 500 | //----- Device specific settings |
masakjm | 1:9d0e2e5b5d25 | 501 | DispChar = paraSettingSpec(); |
masakjm | 1:9d0e2e5b5d25 | 502 | //----- Setting |
masakjm | 1:9d0e2e5b5d25 | 503 | DispChar = paraSettingFreq(State == STATE_SETTING_FREQ); |
masakjm | 1:9d0e2e5b5d25 | 504 | //----- BLE & HID |
masakjm | 1:9d0e2e5b5d25 | 505 | State = STATE_DESABLE_INPUT; |
masakjm | 1:9d0e2e5b5d25 | 506 | initialize_BLE_HID(); |
masakjm | 1:9d0e2e5b5d25 | 507 | display.clear(); |
masakjm | 1:9d0e2e5b5d25 | 508 | |
masakjm | 1:9d0e2e5b5d25 | 509 | //----- Wait to connect |
masakjm | 1:9d0e2e5b5d25 | 510 | display.printChar('W'); |
masakjm | 1:9d0e2e5b5d25 | 511 | while (bleMessage != BLE_CONNECTED) { |
masakjm | 1:9d0e2e5b5d25 | 512 | wait(0.15); |
masakjm | 1:9d0e2e5b5d25 | 513 | ble.waitForEvent(); // BLEイベントを待つ |
masakjm | 1:9d0e2e5b5d25 | 514 | if(bleMessage != BLE_NO_MESSAGE) { // BLEの状態を表示する |
masakjm | 1:9d0e2e5b5d25 | 515 | display.printChar(bleDispChar[bleMessage] ); |
masakjm | 1:9d0e2e5b5d25 | 516 | } |
masakjm | 1:9d0e2e5b5d25 | 517 | } |
masakjm | 1:9d0e2e5b5d25 | 518 | wait(3.0); |
masakjm | 1:9d0e2e5b5d25 | 519 | bleMessage = BLE_NO_MESSAGE; |
masakjm | 1:9d0e2e5b5d25 | 520 | display.clear(); |
masakjm | 1:9d0e2e5b5d25 | 521 | //----- Loop |
masakjm | 1:9d0e2e5b5d25 | 522 | State = STATE_OPERATING; |
masakjm | 1:9d0e2e5b5d25 | 523 | while (true) { |
masakjm | 1:9d0e2e5b5d25 | 524 | wait(0.02); |
masakjm | 1:9d0e2e5b5d25 | 525 | ble.waitForEvent(); // BLEイベントを待つ |
masakjm | 1:9d0e2e5b5d25 | 526 | |
masakjm | 1:9d0e2e5b5d25 | 527 | if(bleMessage != BLE_NO_MESSAGE) { // BLEの状態を表示する |
masakjm | 1:9d0e2e5b5d25 | 528 | DispChar = bleDispChar[bleMessage]; |
masakjm | 1:9d0e2e5b5d25 | 529 | bleMessage = BLE_NO_MESSAGE; |
masakjm | 1:9d0e2e5b5d25 | 530 | } |
masakjm | 1:9d0e2e5b5d25 | 531 | |
masakjm | 1:9d0e2e5b5d25 | 532 | if(! KeyBuff.empty()) { // キーバッファ処理 |
masakjm | 1:9d0e2e5b5d25 | 533 | // DEBUG(" size=%d front=%x\r\n", KeyBuff.size(), KeyBuff.front()); |
masakjm | 1:9d0e2e5b5d25 | 534 | |
masakjm | 1:9d0e2e5b5d25 | 535 | switch (KeyBuff.front() & 0xFF00) { |
masakjm | 1:9d0e2e5b5d25 | 536 | case BUTTON_STATUS_UP : |
masakjm | 1:9d0e2e5b5d25 | 537 | ButtonUpProcess(); |
masakjm | 1:9d0e2e5b5d25 | 538 | break; |
masakjm | 1:9d0e2e5b5d25 | 539 | case BUTTON_STATUS_DOWN : |
masakjm | 1:9d0e2e5b5d25 | 540 | ButtonDownProcess(KeyBuff.front() & 0xFF); |
masakjm | 1:9d0e2e5b5d25 | 541 | break; |
masakjm | 1:9d0e2e5b5d25 | 542 | case BUTTON_STATUS_HOLD : |
masakjm | 1:9d0e2e5b5d25 | 543 | ButtonHoldProcess(KeyBuff.front() & 0xFF); |
masakjm | 1:9d0e2e5b5d25 | 544 | break; |
masakjm | 1:9d0e2e5b5d25 | 545 | } |
masakjm | 1:9d0e2e5b5d25 | 546 | KeyBuff.pop(); |
masakjm | 1:9d0e2e5b5d25 | 547 | } |
masakjm | 1:9d0e2e5b5d25 | 548 | |
masakjm | 1:9d0e2e5b5d25 | 549 | if (DispChar != DispCharLast) { // 表示文字が変更 |
masakjm | 1:9d0e2e5b5d25 | 550 | TurnOffMode = false; |
masakjm | 1:9d0e2e5b5d25 | 551 | dispTime.reset(); |
masakjm | 1:9d0e2e5b5d25 | 552 | display.enable(); |
masakjm | 1:9d0e2e5b5d25 | 553 | if (DispChar) display.printChar(DispChar); |
masakjm | 1:9d0e2e5b5d25 | 554 | else display.clear(); |
masakjm | 1:9d0e2e5b5d25 | 555 | } |
masakjm | 1:9d0e2e5b5d25 | 556 | if (!TurnOffMode) { |
masakjm | 1:9d0e2e5b5d25 | 557 | if (dispTime.read() > TIME_TURN_OFF) { // 長時間表示 |
masakjm | 1:9d0e2e5b5d25 | 558 | TurnOffMode = true; |
masakjm | 1:9d0e2e5b5d25 | 559 | display.disable(); |
masakjm | 1:9d0e2e5b5d25 | 560 | } |
masakjm | 1:9d0e2e5b5d25 | 561 | } |
masakjm | 1:9d0e2e5b5d25 | 562 | DispCharLast = DispChar; |
masakjm | 1:9d0e2e5b5d25 | 563 | } |
masakjm | 1:9d0e2e5b5d25 | 564 | } |
masakjm | 1:9d0e2e5b5d25 | 565 | |
masakjm | 1:9d0e2e5b5d25 | 566 |