Hiroh Satoh / keyboard Featured

Dependencies:   BLE_API mbed-dev nRF51822

Revision:
2:c2e3f240640c
Parent:
0:be89b5fdea09
Child:
3:266dfa9f8709
--- a/main.cpp	Mon Jul 18 08:19:28 2016 +0900
+++ b/main.cpp	Mon Jul 18 09:23:15 2016 +0900
@@ -29,13 +29,16 @@
 static const uint8_t DEVICE_NAME[] = "my keyboard";
 static const uint8_t SHORT_DEVICE_NAME[] = "kbd1";
 
+static const bool ENABLE_BONDING = true;
+static const bool REQUIRE_MITM = true;
+static const uint8_t PASSKEY[6] = {'1','2','3','4','5','6'}; // must be 6-digits number
+
 InterruptIn button1(D2);
 
-
 static const uint16_t uuid16_list[] =  {
-    GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE,
-    GattService::UUID_DEVICE_INFORMATION_SERVICE,
-    GattService::UUID_BATTERY_SERVICE
+	GattService::UUID_HUMAN_INTERFACE_DEVICE_SERVICE,
+	GattService::UUID_DEVICE_INFORMATION_SERVICE,
+	GattService::UUID_BATTERY_SERVICE
 };
 
 KeyboardService* keyboardService;
@@ -43,163 +46,175 @@
 DeviceInformationService* deviceInformationService;
 
 // I2C i2c(D2, D3);
-// AnalogIn batteryInput(A4);
-
-static void onDisconnect(const Gap::DisconnectionCallbackParams_t *params) {
-    printf("onDisconnect\r\n");
-    BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising();
-}
-
+AnalogIn batteryInput(A4);
 
 static void onConnect(const Gap::ConnectionCallbackParams_t *params) {
-    printf("onConnect\r\n");
+	printf("onConnect\r\n");
 }
 
+static void onDisconnect(const Gap::DisconnectionCallbackParams_t *params) {
+	printf("onDisconnect\r\n");
+	BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising();
+}
+
+static void onTimeout(const Gap::TimeoutSource_t source) {
+	printf("onTimeout\r\n");
+	BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising();
+}
 
 static void passkeyDisplayCallback(Gap::Handle_t handle, const SecurityManager::Passkey_t passkey) {
-    printf("Input passKey: ");
-    for (unsigned i = 0; i < Gap::ADDR_LEN; i++) {
-        printf("%c", passkey[i]);
-    }
-    printf("\r\n");
+	printf("Input passKey: ");
+	for (unsigned i = 0; i < Gap::ADDR_LEN; i++) {
+		printf("%c", passkey[i]);
+	}
+	printf("\r\n");
+}
+
+static void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status) {
+	if (status == SecurityManager::SEC_STATUS_SUCCESS) {
+		printf("Security success %d\r\n", status);
+	} else {
+		printf("Security failed %d\r\n", status);
+	}
+}
+
+static void securitySetupInitiatedCallback(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps) {
+	printf("Security setup initiated\r\n");
 }
 
-static void securitySetupCompletedCallback(Gap::Handle_t handle, SecurityManager::SecurityCompletionStatus_t status)
-{
-    if (status == SecurityManager::SEC_STATUS_SUCCESS) {
-        printf("Security success %d\r\n", status);
-    } else {
-        printf("Security failed %d\r\n", status);
-    }
-}
+static void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) {
+	// https://developer.mbed.org/compiler/#nav:/keyboard/BLE_API/ble/blecommon.h;
+	ble_error_t error;
+	BLE &ble          = params->ble;
+	
+	error = params->error;
+	if (error != BLE_ERROR_NONE) {
+		printf("error on ble.init() \r\n");
+		goto return_error;
+	}
+
+	ble.gap().onDisconnection(onDisconnect);
+	ble.gap().onConnection(onConnect);
+	ble.gap().onTimeout(onTimeout);
+
+	printf("setup ble security manager\r\n");
+	ble.securityManager().onSecuritySetupInitiated(securitySetupInitiatedCallback);
+	ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback);
+	ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback);
+	// bonding with hard-coded passkey.
+	error = ble.securityManager().init(ENABLE_BONDING, REQUIRE_MITM, SecurityManager::IO_CAPS_DISPLAY_ONLY, PASSKEY);
+	if (error != BLE_ERROR_NONE) {
+		printf("error on ble.securityManager().init()");
+		goto return_error;
+	}
+
+	keyboardService = new KeyboardService(ble);
+	deviceInformationService = new DeviceInformationService(ble, "lowreal.net", MODEL_NAME, SERIAL_NUMBER, HARDWARE_REVISION, FIRMWARE_REVISION, SOFTWARE_REVISION);
+	batteryService = new BatteryService(ble, 10);
 
-static void securitySetupInitiatedCallback(Gap::Handle_t, bool allowBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps)
-{
-    printf("Security setup initiated\r\n");
-}
+	printf("general setup\r\n");
+	error = ble.gap().accumulateAdvertisingPayload(
+		GapAdvertisingData::BREDR_NOT_SUPPORTED |
+		GapAdvertisingData::LE_GENERAL_DISCOVERABLE
+	);
+	if (error != BLE_ERROR_NONE) goto return_error;
+
+	printf("set COMPLETE_LIST_16BIT_SERVICE_IDS\r\n");
+	error = ble.gap().accumulateAdvertisingPayload(
+		GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
+		(uint8_t*)uuid16_list, sizeof(uuid16_list)
+	);
+	if (error != BLE_ERROR_NONE) goto return_error;
+
+	printf("set advertising\r\n");
+	// see 5.1.2: HID over GATT Specification (pg. 25)
+	ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
 
-void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) {
-    BLE &ble          = params->ble;
-    ble_error_t error = params->error;
-    
-    if (error != BLE_ERROR_NONE) {
-        printf("error on ble.init() \r\n");
-        return;
-    }
-     
-    ble.gap().onDisconnection(onDisconnect);
-    ble.gap().onConnection(onConnect);
+	printf("set advertising interval\r\n");
+	ble.gap().setAdvertisingInterval(50);
+	// XXX
+	// ble.gap().setAdvertisingTimeout(0);
+
+	printf("set keyboard\r\n");
+	error = ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD);
+	if (error != BLE_ERROR_NONE) goto return_error;
+
+	printf("set complete local name\r\n");
+	error = ble.gap().accumulateAdvertisingPayload(
+		GapAdvertisingData::COMPLETE_LOCAL_NAME,
+		DEVICE_NAME, sizeof(DEVICE_NAME)
+	);
+	if (error != BLE_ERROR_NONE) goto return_error;
+
+	printf("set device name\r\n");
+	error = ble.gap().setDeviceName(DEVICE_NAME);
+	if (error != BLE_ERROR_NONE) goto return_error;
+	// ble.gap().setTxPower(-12);
 
 
-    bool enableBonding = true;
-    bool requireMITM = true;
-    uint8_t passkey[] = "123456";
-
-    printf("setup ble security manager\r\n");
-    ble.securityManager().onSecuritySetupInitiated(securitySetupInitiatedCallback);
-    ble.securityManager().onPasskeyDisplay(passkeyDisplayCallback);
-    ble.securityManager().onSecuritySetupCompleted(securitySetupCompletedCallback);
-    // TODO 
-    // ble.securityManager().init(true, true, SecurityManager::IO_CAPS_DISPLAY_ONLY);
-    // ble.securityManager().init(enableBonding, requireMITM, SecurityManager::IO_CAPS_KEYBOARD_ONLY, passkey);
-    // ble.securityManager().init(enableBonding, requireMITM, SecurityManager::IO_CAPS_NONE);
-    ble.securityManager().init(enableBonding, requireMITM, SecurityManager::IO_CAPS_DISPLAY_ONLY, passkey);
-
-    keyboardService = new KeyboardService(ble);
-    deviceInformationService = new DeviceInformationService(ble, "lowreal.net", MODEL_NAME, SERIAL_NUMBER, HARDWARE_REVISION, FIRMWARE_REVISION, SOFTWARE_REVISION);
-    batteryService = new BatteryService(ble, 10);
+	printf("advertising\r\n");
+	error = ble.gap().startAdvertising();
+	if (error != BLE_ERROR_NONE) goto return_error;
+	return;
 
-    printf("general setup\r\n");
-    ble.gap().accumulateAdvertisingPayload(
-        GapAdvertisingData::BREDR_NOT_SUPPORTED |
-        GapAdvertisingData::LE_GENERAL_DISCOVERABLE
-    );
-    ble.gap().accumulateAdvertisingPayload(
-        GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
-        (uint8_t*)uuid16_list, sizeof(uuid16_list)
-    );
-
-    printf("set advertising\r\n");
-    // see 5.1.2: HID over GATT Specification (pg. 25)
-    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
-    printf("set advertising interval\r\n");
-    ble.gap().setAdvertisingInterval(50);
-    // XXX
-    ble.gap().setAdvertisingTimeout(0);
-    
-    printf("set key board\r\n");
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::KEYBOARD);
-    ble.gap().accumulateAdvertisingPayload(
-        GapAdvertisingData::COMPLETE_LOCAL_NAME,
-        DEVICE_NAME, sizeof(DEVICE_NAME)
-    );
-    ble.gap().accumulateAdvertisingPayload(
-        GapAdvertisingData::SHORTENED_LOCAL_NAME,
-        SHORT_DEVICE_NAME, sizeof(SHORT_DEVICE_NAME)
-    );
-
-    printf("set device name\r\n");
-    ble.gap().setDeviceName(DEVICE_NAME);
-    // ble.gap().setTxPower(-12);
-    
-
-    printf("advertising\r\n");
-    ble.gap().startAdvertising();
+return_error:
+	printf("error with %d\r\n", error);
+	return;
 }
 
 void send_string(const char * c) {
-    if (!keyboardService)
-        return;
- 
-    if (!keyboardService->isConnected()) {
-        printf("we haven't connected yet...");
-    } else {
-        int len = strlen(c);
-        keyboardService->printf(c);
-        printf("sending %d chars\r\n", len);
-    }
+	if (!keyboardService) return;
+
+	if (!keyboardService->isConnected()) {
+		printf("we haven't connected yet...");
+	} else {
+		int len = strlen(c);
+		keyboardService->printf(c);
+		printf("sending %d chars\r\n", len);
+	}
 }
- 
+
 void send_stuff() {
-    send_string("hello world!\n");
+	send_string("hello world!\n");
+}
+
+void updateBatteryLevel() {
+	if (!batteryService) return;
+	static const float BATTERY_MAX = 2.4;
+
+	float batteryVoltage = batteryInput.read() * 1.2 * 3;
+	float percentage = (batteryVoltage / BATTERY_MAX) * 100;
+	if (percentage > 100) {
+		percentage = 100;
+	}
+	batteryService->updateBatteryLevel(static_cast<uint8_t>(percentage));
 }
 
 int main(void) {
-    
-    // https://github.com/jpbrucker/BLE_HID/blob/master/examples/examples_common.cpp
-
-    printf("ble.init\r\n");
-    BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
-    ble.init(bleInitComplete);
-
-    button1.rise(send_stuff);
-    
-    // TODO: Use internal 1.2V reference for batteryInput
-    while (!ble.hasInitialized()) { }
-    
-    printf("ble.hasIntialized\r\n");
-        
-    while(1) {
-        ble.waitForEvent(); 
-    }
-}
+	// Use internal 1.2V reference for batteryInput
+	//	1/3 pre-scaled input and 1.2V internal band gap reference
+	//	(mbed uses vdd for reference but i want use band gap)
+	// ref. mbed-src/targets/hal/TARGET_NORDIC/TARGET_MCU_NRF51822/analogin_api.c
+	NRF_ADC->CONFIG =
+		(ADC_CONFIG_RES_10bit << ADC_CONFIG_RES_Pos) |
+		(ADC_CONFIG_INPSEL_AnalogInputOneThirdPrescaling << ADC_CONFIG_INPSEL_Pos) |
+		(ADC_CONFIG_REFSEL_VBG << ADC_CONFIG_REFSEL_Pos) |
+		(ADC_CONFIG_EXTREFSEL_None << ADC_CONFIG_EXTREFSEL_Pos);
 
 
-
-
-
+	// https://github.com/jpbrucker/BLE_HID/blob/master/examples/examples_common.cpp
 
-
+	printf("ble.init\r\n");
+	BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
+	ble.init(bleInitComplete);
 
-
-
+	button1.rise(send_stuff);
 
-
+	while (!ble.hasInitialized()) { }
 
-
-
+	printf("ble.hasIntialized\r\n");
 
-
-
-
-
+	while (1) {
+		ble.waitForEvent();
+	}
+}