Hiroh Satoh / keyboard Featured

Dependencies:   BLE_API mbed-dev nRF51822

Committer:
cho45
Date:
Wed Jul 20 02:05:45 2016 +0900
Revision:
4:54cb552e50c4
Parent:
3:266dfa9f8709
Child:
5:65d4e94735b6
update

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cho45 0:be89b5fdea09 1 /* mbed Microcontroller Library
cho45 0:be89b5fdea09 2 * Copyright (c) 2015 ARM Limited
cho45 0:be89b5fdea09 3 *
cho45 0:be89b5fdea09 4 * Licensed under the Apache License, Version 2.0 (the "License");
cho45 0:be89b5fdea09 5 * you may not use this file except in compliance with the License.
cho45 0:be89b5fdea09 6 * You may obtain a copy of the License at
cho45 0:be89b5fdea09 7 *
cho45 0:be89b5fdea09 8 * http://www.apache.org/licenses/LICENSE-2.0
cho45 0:be89b5fdea09 9 *
cho45 0:be89b5fdea09 10 * Unless required by applicable law or agreed to in writing, software
cho45 0:be89b5fdea09 11 * distributed under the License is distributed on an "AS IS" BASIS,
cho45 0:be89b5fdea09 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
cho45 0:be89b5fdea09 13 * See the License for the specific language governing permissions and
cho45 0:be89b5fdea09 14 * limitations under the License.
cho45 0:be89b5fdea09 15 */
cho45 0:be89b5fdea09 16
cho45 0:be89b5fdea09 17 #include "mbed.h"
cho45 0:be89b5fdea09 18 #include "BLE.h"
cho45 0:be89b5fdea09 19 #include "KeyboardService.h"
cho45 0:be89b5fdea09 20 #include "BatteryService.h"
cho45 0:be89b5fdea09 21 #include "DeviceInformationService.h"
cho45 4:54cb552e50c4 22 #include "mcp23017.h"
cho45 0:be89b5fdea09 23
cho45 0:be89b5fdea09 24 static const char MODEL_NAME[] = "keyboard";
cho45 0:be89b5fdea09 25 static const char SERIAL_NUMBER[] = "X00000";
cho45 0:be89b5fdea09 26 static const char HARDWARE_REVISION[] = "0.1";
cho45 0:be89b5fdea09 27 static const char FIRMWARE_REVISION[] = "0.1";
cho45 0:be89b5fdea09 28 static const char SOFTWARE_REVISION[] = "0.0";
cho45 0:be89b5fdea09 29
cho45 0:be89b5fdea09 30 static const uint8_t DEVICE_NAME[] = "my keyboard";
cho45 0:be89b5fdea09 31 static const uint8_t SHORT_DEVICE_NAME[] = "kbd1";
cho45 0:be89b5fdea09 32
cho45 2:c2e3f240640c 33 static const bool ENABLE_BONDING = true;
cho45 2:c2e3f240640c 34 static const bool REQUIRE_MITM = true;
cho45 2:c2e3f240640c 35 static const uint8_t PASSKEY[6] = {'1','2','3','4','5','6'}; // must be 6-digits number
cho45 2:c2e3f240640c 36
cho45 0:be89b5fdea09 37 static const uint16_t uuid16_list[] = {
cho45 2:c2e3f240640c 38 GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE,
cho45 2:c2e3f240640c 39 GattService::UUID_DEVICE_INFORMATION_SERVICE,
cho45 2:c2e3f240640c 40 GattService::UUID_BATTERY_SERVICE
cho45 0:be89b5fdea09 41 };
cho45 0:be89b5fdea09 42
cho45 0:be89b5fdea09 43 KeyboardService* keyboardService;
cho45 0:be89b5fdea09 44 BatteryService* batteryService;
cho45 0:be89b5fdea09 45 DeviceInformationService* deviceInformationService;
cho45 0:be89b5fdea09 46
cho45 4:54cb552e50c4 47 I2C i2c(I2C_SDA0, I2C_SCL0);
cho45 4:54cb552e50c4 48 MCP23017 gpio1(i2c, 0b0100000);
cho45 4:54cb552e50c4 49 InterruptIn buttonInt(P0_5);
cho45 0:be89b5fdea09 50
cho45 3:266dfa9f8709 51 void updateBatteryLevel() {
cho45 3:266dfa9f8709 52 if (!batteryService) return;
cho45 3:266dfa9f8709 53 static const float BATTERY_MAX = 2.4;
cho45 4:54cb552e50c4 54 static const float REFERNECE = 1.2;
cho45 4:54cb552e50c4 55 static const float PRESCALE = 3;
cho45 3:266dfa9f8709 56
cho45 4:54cb552e50c4 57 NRF_ADC->ENABLE = ADC_ENABLE_ENABLE_Enabled;
cho45 4:54cb552e50c4 58
cho45 4:54cb552e50c4 59 // Use internal 1.2V reference for batteryInput
cho45 4:54cb552e50c4 60 // 1/3 pre-scaled input and 1.2V internal band gap reference
cho45 4:54cb552e50c4 61 // ref. mbed-src/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/analogin_api.c
cho45 4:54cb552e50c4 62 NRF_ADC->CONFIG =
cho45 4:54cb552e50c4 63 (ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
cho45 4:54cb552e50c4 64 // Use VDD 1/3 for input
cho45 4:54cb552e50c4 65 (ADC_CONFIG_INPSEL_SupplyOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
cho45 4:54cb552e50c4 66 // Use internal band gap for reference
cho45 4:54cb552e50c4 67 (ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
cho45 4:54cb552e50c4 68 (ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
cho45 4:54cb552e50c4 69
cho45 4:54cb552e50c4 70 // Start ADC
cho45 4:54cb552e50c4 71 NRF_ADC->TASKS_START = 1;
cho45 4:54cb552e50c4 72 while (((NRF_ADC->BUSY & ADC_BUSY_BUSY_Msk) >> ADC_BUSY_BUSY_Pos) == ADC_BUSY_BUSY_Busy) {
cho45 4:54cb552e50c4 73 // busy loop
cho45 4:54cb552e50c4 74 }
cho45 4:54cb552e50c4 75
cho45 4:54cb552e50c4 76 // Read ADC result
cho45 4:54cb552e50c4 77 uint16_t raw10bit = static_cast<uint16_t>(NRF_ADC->RESULT);
cho45 4:54cb552e50c4 78 float ratio = raw10bit / static_cast<float>(1<<10);
cho45 4:54cb552e50c4 79
cho45 4:54cb552e50c4 80 float batteryVoltage = ratio * (REFERNECE * PRESCALE);
cho45 3:266dfa9f8709 81 float percentage = (batteryVoltage / BATTERY_MAX) * 100;
cho45 3:266dfa9f8709 82 if (percentage > 100) {
cho45 3:266dfa9f8709 83 percentage = 100;
cho45 3:266dfa9f8709 84 }
cho45 4:54cb552e50c4 85 printf("updateBatteryLevel %f V : %d/100\r\n", batteryVoltage, static_cast<uint8_t>(percentage));
cho45 3:266dfa9f8709 86 batteryService->updateBatteryLevel(static_cast<uint8_t>(percentage));
cho45 3:266dfa9f8709 87 }
cho45 3:266dfa9f8709 88
cho45 3:266dfa9f8709 89
cho45 0:be89b5fdea09 90 static void onConnect(const Gap::ConnectionCallbackParams_t *params) {
cho45 2:c2e3f240640c 91 printf("onConnect\r\n");
cho45 0:be89b5fdea09 92 }
cho45 0:be89b5fdea09 93
cho45 2:c2e3f240640c 94 static void onDisconnect(const Gap::DisconnectionCallbackParams_t *params) {
cho45 2:c2e3f240640c 95 printf("onDisconnect\r\n");
cho45 2:c2e3f240640c 96 BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising();
cho45 2:c2e3f240640c 97 }
cho45 2:c2e3f240640c 98
cho45 2:c2e3f240640c 99 static void onTimeout(const Gap::TimeoutSource_t source) {
cho45 2:c2e3f240640c 100 printf("onTimeout\r\n");
cho45 2:c2e3f240640c 101 BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising();
cho45 2:c2e3f240640c 102 }
cho45 0:be89b5fdea09 103
cho45 0:be89b5fdea09 104 static void passkeyDisplayCallback(Gap::Handle_t handle, const SecurityManager::Passkey_t passkey) {
cho45 2:c2e3f240640c 105 printf("Input passKey: ");
cho45 2:c2e3f240640c 106 for (unsigned i = 0; i < Gap::ADDR_LEN; i++) {
cho45 2:c2e3f240640c 107 printf("%c", passkey[i]);
cho45 2:c2e3f240640c 108 }
cho45 2:c2e3f240640c 109 printf("\r\n");
cho45 2:c2e3f240640c 110 }
cho45 2:c2e3f240640c 111
cho45 2:c2e3f240640c 112 static void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status) {
cho45 2:c2e3f240640c 113 if (status == SecurityManager::SEC_STATUS_SUCCESS) {
cho45 2:c2e3f240640c 114 printf("Security success %d\r\n", status);
cho45 2:c2e3f240640c 115 } else {
cho45 2:c2e3f240640c 116 printf("Security failed %d\r\n", status);
cho45 2:c2e3f240640c 117 }
cho45 2:c2e3f240640c 118 }
cho45 2:c2e3f240640c 119
cho45 2:c2e3f240640c 120 static void securitySetupInitiatedCallback(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps) {
cho45 2:c2e3f240640c 121 printf("Security setup initiated\r\n");
cho45 0:be89b5fdea09 122 }
cho45 0:be89b5fdea09 123
cho45 2:c2e3f240640c 124 static void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) {
cho45 2:c2e3f240640c 125 // https://developer.mbed.org/compiler/#nav:/keyboard/BLE_API/ble/blecommon.h;
cho45 2:c2e3f240640c 126 ble_error_t error;
cho45 2:c2e3f240640c 127 BLE &ble = params->ble;
cho45 2:c2e3f240640c 128
cho45 2:c2e3f240640c 129 error = params->error;
cho45 2:c2e3f240640c 130 if (error != BLE_ERROR_NONE) {
cho45 2:c2e3f240640c 131 printf("error on ble.init() \r\n");
cho45 2:c2e3f240640c 132 goto return_error;
cho45 2:c2e3f240640c 133 }
cho45 2:c2e3f240640c 134
cho45 2:c2e3f240640c 135 ble.gap().onDisconnection(onDisconnect);
cho45 2:c2e3f240640c 136 ble.gap().onConnection(onConnect);
cho45 2:c2e3f240640c 137 ble.gap().onTimeout(onTimeout);
cho45 2:c2e3f240640c 138
cho45 2:c2e3f240640c 139 printf("setup ble security manager\r\n");
cho45 2:c2e3f240640c 140 ble.securityManager().onSecuritySetupInitiated(securitySetupInitiatedCallback);
cho45 2:c2e3f240640c 141 ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback);
cho45 2:c2e3f240640c 142 ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback);
cho45 2:c2e3f240640c 143 // bonding with hard-coded passkey.
cho45 2:c2e3f240640c 144 error = ble.securityManager().init(ENABLE_BONDING, REQUIRE_MITM, SecurityManager::IO_CAPS_DISPLAY_ONLY, PASSKEY);
cho45 2:c2e3f240640c 145 if (error != BLE_ERROR_NONE) {
cho45 2:c2e3f240640c 146 printf("error on ble.securityManager().init()");
cho45 2:c2e3f240640c 147 goto return_error;
cho45 2:c2e3f240640c 148 }
cho45 2:c2e3f240640c 149
cho45 2:c2e3f240640c 150 keyboardService = new KeyboardService(ble);
cho45 2:c2e3f240640c 151 deviceInformationService = new DeviceInformationService(ble, "lowreal.net", MODEL_NAME, SERIAL_NUMBER, HARDWARE_REVISION, FIRMWARE_REVISION, SOFTWARE_REVISION);
cho45 3:266dfa9f8709 152 batteryService = new BatteryService(ble, 100);
cho45 3:266dfa9f8709 153 updateBatteryLevel();
cho45 0:be89b5fdea09 154
cho45 2:c2e3f240640c 155 printf("general setup\r\n");
cho45 2:c2e3f240640c 156 error = ble.gap().accumulateAdvertisingPayload(
cho45 2:c2e3f240640c 157 GapAdvertisingData::BREDR_NOT_SUPPORTED |
cho45 2:c2e3f240640c 158 GapAdvertisingData::LE_GENERAL_DISCOVERABLE
cho45 2:c2e3f240640c 159 );
cho45 2:c2e3f240640c 160 if (error != BLE_ERROR_NONE) goto return_error;
cho45 2:c2e3f240640c 161
cho45 2:c2e3f240640c 162 printf("set COMPLETE_LIST_16BIT_SERVICE_IDS\r\n");
cho45 2:c2e3f240640c 163 error = ble.gap().accumulateAdvertisingPayload(
cho45 2:c2e3f240640c 164 GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
cho45 2:c2e3f240640c 165 (uint8_t*)uuid16_list, sizeof(uuid16_list)
cho45 2:c2e3f240640c 166 );
cho45 2:c2e3f240640c 167 if (error != BLE_ERROR_NONE) goto return_error;
cho45 2:c2e3f240640c 168
cho45 2:c2e3f240640c 169 printf("set advertising\r\n");
cho45 2:c2e3f240640c 170 // see 5.1.2: HID over GATT Specification (pg. 25)
cho45 2:c2e3f240640c 171 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
cho45 0:be89b5fdea09 172
cho45 2:c2e3f240640c 173 printf("set advertising interval\r\n");
cho45 2:c2e3f240640c 174 ble.gap().setAdvertisingInterval(50);
cho45 2:c2e3f240640c 175 // XXX
cho45 2:c2e3f240640c 176 // ble.gap().setAdvertisingTimeout(0);
cho45 2:c2e3f240640c 177
cho45 2:c2e3f240640c 178 printf("set keyboard\r\n");
cho45 2:c2e3f240640c 179 error = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD);
cho45 2:c2e3f240640c 180 if (error != BLE_ERROR_NONE) goto return_error;
cho45 2:c2e3f240640c 181
cho45 2:c2e3f240640c 182 printf("set complete local name\r\n");
cho45 2:c2e3f240640c 183 error = ble.gap().accumulateAdvertisingPayload(
cho45 2:c2e3f240640c 184 GapAdvertisingData::COMPLETE_LOCAL_NAME,
cho45 2:c2e3f240640c 185 DEVICE_NAME, sizeof(DEVICE_NAME)
cho45 2:c2e3f240640c 186 );
cho45 2:c2e3f240640c 187 if (error != BLE_ERROR_NONE) goto return_error;
cho45 2:c2e3f240640c 188
cho45 2:c2e3f240640c 189 printf("set device name\r\n");
cho45 2:c2e3f240640c 190 error = ble.gap().setDeviceName(DEVICE_NAME);
cho45 2:c2e3f240640c 191 if (error != BLE_ERROR_NONE) goto return_error;
cho45 2:c2e3f240640c 192 // ble.gap().setTxPower(-12);
cho45 0:be89b5fdea09 193
cho45 0:be89b5fdea09 194
cho45 2:c2e3f240640c 195 printf("advertising\r\n");
cho45 2:c2e3f240640c 196 error = ble.gap().startAdvertising();
cho45 2:c2e3f240640c 197 if (error != BLE_ERROR_NONE) goto return_error;
cho45 2:c2e3f240640c 198 return;
cho45 0:be89b5fdea09 199
cho45 2:c2e3f240640c 200 return_error:
cho45 2:c2e3f240640c 201 printf("error with %d\r\n", error);
cho45 2:c2e3f240640c 202 return;
cho45 0:be89b5fdea09 203 }
cho45 0:be89b5fdea09 204
cho45 4:54cb552e50c4 205 class MyKeyboardService : public HIDServiceBase {
cho45 4:54cb552e50c4 206 union {
cho45 4:54cb552e50c4 207 uint8_t raw[8];
cho45 4:54cb552e50c4 208 struct {
cho45 4:54cb552e50c4 209 uint8_t modifier;
cho45 4:54cb552e50c4 210 uint8_t padding;
cho45 4:54cb552e50c4 211 uint8_t keycode[6];
cho45 4:54cb552e50c4 212 } data;
cho45 4:54cb552e50c4 213 } inputReportData;
cho45 4:54cb552e50c4 214
cho45 4:54cb552e50c4 215 union {
cho45 4:54cb552e50c4 216 uint8_t raw[1];
cho45 4:54cb552e50c4 217 } outputReportData;
cho45 4:54cb552e50c4 218 public:
cho45 4:54cb552e50c4 219 MyKeyboardService(BLE& _ble) :
cho45 4:54cb552e50c4 220 HIDServiceBase(
cho45 4:54cb552e50c4 221 _ble,
cho45 4:54cb552e50c4 222 KEYBOARD_REPORT_MAP,
cho45 4:54cb552e50c4 223 sizeof(KEYBOARD_REPORT_MAP),
cho45 4:54cb552e50c4 224 inputReport = inputReportData.raw,
cho45 4:54cb552e50c4 225 outputReport = outputReportData.raw,
cho45 4:54cb552e50c4 226 featureReport = NULL,
cho45 4:54cb552e50c4 227 inputReportLength = sizeof(inputReportData),
cho45 4:54cb552e50c4 228 outputReportLength = sizeof(outputReportData),
cho45 4:54cb552e50c4 229 featureReportLength = 0,
cho45 4:54cb552e50c4 230 reportTickerDelay = 24
cho45 4:54cb552e50c4 231 )
cho45 4:54cb552e50c4 232 {
cho45 4:54cb552e50c4 233 }
cho45 4:54cb552e50c4 234
cho45 4:54cb552e50c4 235 void appendReportData(uint8_t keycode) {
cho45 4:54cb552e50c4 236 for (int i = 0; i < 6; i++) {
cho45 4:54cb552e50c4 237 if (inputReportData.data.keycode[i] == 0) {
cho45 4:54cb552e50c4 238 inputReportData.data.keycode[i] = keycode;
cho45 4:54cb552e50c4 239 startReportTicker();
cho45 4:54cb552e50c4 240 return;
cho45 4:54cb552e50c4 241 }
cho45 4:54cb552e50c4 242 }
cho45 2:c2e3f240640c 243
cho45 4:54cb552e50c4 244 // TODO: report data is full
cho45 4:54cb552e50c4 245 }
cho45 4:54cb552e50c4 246
cho45 4:54cb552e50c4 247 void deleteReportData(uint8_t keycode) {
cho45 4:54cb552e50c4 248 for (int i = 0; i < 6; i++) {
cho45 4:54cb552e50c4 249 if (inputReportData.data.keycode[i] == keycode) {
cho45 4:54cb552e50c4 250 inputReportData.data.keycode[i] = 0;
cho45 4:54cb552e50c4 251 startReportTicker();
cho45 4:54cb552e50c4 252 return;
cho45 4:54cb552e50c4 253 }
cho45 4:54cb552e50c4 254 }
cho45 2:c2e3f240640c 255 }
cho45 4:54cb552e50c4 256
cho45 4:54cb552e50c4 257 bool isKeyPressed() {
cho45 4:54cb552e50c4 258 for (int i = 0; i < 8; i++) {
cho45 4:54cb552e50c4 259 if (inputReportData.raw[i]) {
cho45 4:54cb552e50c4 260 return 1;
cho45 4:54cb552e50c4 261 }
cho45 4:54cb552e50c4 262 }
cho45 4:54cb552e50c4 263 return 0;
cho45 4:54cb552e50c4 264 }
cho45 2:c2e3f240640c 265
cho45 4:54cb552e50c4 266 virtual void sendCallback(void) {
cho45 4:54cb552e50c4 267 ble_error_t error = HIDServiceBase::send(inputReportData.raw);
cho45 4:54cb552e50c4 268 if (error == BLE_STACK_BUSY) {
cho45 4:54cb552e50c4 269 // retry after
cho45 4:54cb552e50c4 270 return;
cho45 4:54cb552e50c4 271 }
cho45 4:54cb552e50c4 272
cho45 4:54cb552e50c4 273 if (!isKeyPressed()) {
cho45 4:54cb552e50c4 274 stopReportTicker();
cho45 4:54cb552e50c4 275 }
cho45 4:54cb552e50c4 276 }
cho45 4:54cb552e50c4 277 };
cho45 4:54cb552e50c4 278
cho45 4:54cb552e50c4 279 void buttonIntCallback() {
cho45 4:54cb552e50c4 280 int ok;
cho45 4:54cb552e50c4 281 printf("buttonInt!!\r\n");
cho45 4:54cb552e50c4 282 uint8_t read = gpio1.read8(MCP23017::GPIOA, ok);
cho45 4:54cb552e50c4 283 printf("read %x\r\n", read);
cho45 2:c2e3f240640c 284 }
cho45 2:c2e3f240640c 285
cho45 0:be89b5fdea09 286 int main(void) {
cho45 4:54cb552e50c4 287 // printf("init\r\n");
cho45 4:54cb552e50c4 288
cho45 4:54cb552e50c4 289 // mbed's Serial of TARGET_RBLAB_BLENANO sucks
cho45 4:54cb552e50c4 290 // DO NOT CONNECT RTS/CTS AUTOMATICALY!
cho45 4:54cb552e50c4 291 NRF_UART0->PSELRTS = 0xFFFFFFFFUL;
cho45 4:54cb552e50c4 292 NRF_UART0->PSELCTS = 0xFFFFFFFFUL;
cho45 4:54cb552e50c4 293
cho45 4:54cb552e50c4 294 buttonInt.mode(PullUp);
cho45 4:54cb552e50c4 295 buttonInt.fall(buttonIntCallback);
cho45 4:54cb552e50c4 296
cho45 4:54cb552e50c4 297 int ok;
cho45 4:54cb552e50c4 298
cho45 4:54cb552e50c4 299 // 100kHz
cho45 4:54cb552e50c4 300 i2c.frequency(100000);
cho45 4:54cb552e50c4 301
cho45 4:54cb552e50c4 302 ok = gpio1.write8(
cho45 4:54cb552e50c4 303 MCP23017::IOCON,
cho45 4:54cb552e50c4 304 0<<MCP23017::BANK |
cho45 4:54cb552e50c4 305 1<<MCP23017::MIRROR |
cho45 4:54cb552e50c4 306 1<<MCP23017::SEQOP |
cho45 4:54cb552e50c4 307 0<<MCP23017::DISSLW |
cho45 4:54cb552e50c4 308 1<<MCP23017::ODR
cho45 4:54cb552e50c4 309 );
cho45 4:54cb552e50c4 310
cho45 4:54cb552e50c4 311 // IODIR
cho45 4:54cb552e50c4 312 // 1: input
cho45 4:54cb552e50c4 313 // 0: output
cho45 4:54cb552e50c4 314 ok = gpio1.write16(
cho45 4:54cb552e50c4 315 MCP23017::IODIRA,
cho45 4:54cb552e50c4 316 0b1111111100000000
cho45 4:54cb552e50c4 317 );
cho45 4:54cb552e50c4 318
cho45 4:54cb552e50c4 319 // INPUT POLARITY
cho45 4:54cb552e50c4 320 ok = gpio1.write8(
cho45 4:54cb552e50c4 321 MCP23017::IPOLA,
cho45 4:54cb552e50c4 322 0b00000000
cho45 4:54cb552e50c4 323 );
cho45 4:54cb552e50c4 324 // INTERRUPT-ON-CHANGE Enable
cho45 4:54cb552e50c4 325 ok = gpio1.write8(
cho45 4:54cb552e50c4 326 MCP23017::GPINTENA,
cho45 4:54cb552e50c4 327 0b11111111
cho45 4:54cb552e50c4 328 );
cho45 4:54cb552e50c4 329 // INTERRUPT-ON-CHANGE Control
cho45 4:54cb552e50c4 330 // 1: compared with DEFVAL
cho45 4:54cb552e50c4 331 // 0: compared to previous value
cho45 4:54cb552e50c4 332 ok = gpio1.write8(
cho45 4:54cb552e50c4 333 MCP23017::INTCONA,
cho45 4:54cb552e50c4 334 0b00000000
cho45 4:54cb552e50c4 335 );
cho45 4:54cb552e50c4 336 // PULL-UP (for input pin)
cho45 4:54cb552e50c4 337 // 1: pull-up enabled
cho45 4:54cb552e50c4 338 // 0: pull-up disabled
cho45 4:54cb552e50c4 339 ok = gpio1.write8(
cho45 4:54cb552e50c4 340 MCP23017::GPPUA,
cho45 4:54cb552e50c4 341 0b11111111
cho45 4:54cb552e50c4 342 );
cho45 4:54cb552e50c4 343
cho45 4:54cb552e50c4 344 if (!ok) {
cho45 4:54cb552e50c4 345 printf("failed to write to i2c bus\r\n");
cho45 4:54cb552e50c4 346 } else {
cho45 4:54cb552e50c4 347 printf("wrote to i2c bus\r\n");
cho45 4:54cb552e50c4 348 }
cho45 4:54cb552e50c4 349
cho45 4:54cb552e50c4 350 uint8_t read = gpio1.read8(MCP23017::GPIOA, ok);
cho45 4:54cb552e50c4 351 printf("read %x\r\n", read);
cho45 4:54cb552e50c4 352
cho45 4:54cb552e50c4 353 while (1) {}
cho45 4:54cb552e50c4 354
cho45 4:54cb552e50c4 355 return;
cho45 0:be89b5fdea09 356
cho45 2:c2e3f240640c 357 // https://github.com/jpbrucker/BLE_HID/blob/master/examples/examples_common.cpp
cho45 0:be89b5fdea09 358
cho45 2:c2e3f240640c 359 printf("ble.init\r\n");
cho45 2:c2e3f240640c 360 BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
cho45 2:c2e3f240640c 361 ble.init(bleInitComplete);
cho45 0:be89b5fdea09 362
cho45 2:c2e3f240640c 363 while (!ble.hasInitialized()) { }
cho45 0:be89b5fdea09 364
cho45 2:c2e3f240640c 365 printf("ble.hasIntialized\r\n");
cho45 0:be89b5fdea09 366
cho45 2:c2e3f240640c 367 while (1) {
cho45 2:c2e3f240640c 368 ble.waitForEvent();
cho45 2:c2e3f240640c 369 }
cho45 2:c2e3f240640c 370 }