Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API mbed nRF51822
Revision 2:95c770f35636, committed 2015-08-17
- Comitter:
- jslater8
- Date:
- Mon Aug 17 09:49:55 2015 +0000
- Parent:
- 1:4bdebb81dcd5
- Commit message:
- Initial
Changed in this revision
diff -r 4bdebb81dcd5 -r 95c770f35636 BLE_API.lib --- a/BLE_API.lib Mon Jul 27 07:30:47 2015 +0000 +++ b/BLE_API.lib Mon Aug 17 09:49:55 2015 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#6884e374e2eb +http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#8d316a3271a8
diff -r 4bdebb81dcd5 -r 95c770f35636 ButtonService.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ButtonService.h Mon Aug 17 09:49:55 2015 +0000
@@ -0,0 +1,42 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __BLE_BUTTON_SERVICE_H__
+#define __BLE_BUTTON_SERVICE_H__
+
+class ButtonService {
+public:
+ const static uint16_t BUTTON_SERVICE_UUID = 0xA002;
+ const static uint16_t BUTTON_STATE_CHARACTERISTIC_UUID = 0xA003;
+
+ ButtonService(BLE &_ble, bool buttonPressedInitial) :
+ ble(_ble), buttonState(BUTTON_STATE_CHARACTERISTIC_UUID, &buttonPressedInitial, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)
+ {
+ GattCharacteristic *charTable[] = {&buttonState};
+ GattService buttonService(ButtonService::BUTTON_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+ ble.gattServer().addService(buttonService);
+ }
+
+ void updateButtonState(bool newState) {
+ ble.gattServer().write(buttonState.getValueHandle(), (uint8_t *)&newState, sizeof(bool));
+ }
+
+private:
+ BLE &ble;
+ ReadOnlyGattCharacteristic<bool> buttonState;
+};
+
+#endif /* #ifndef __BLE_BUTTON_SERVICE_H__ */
\ No newline at end of file
diff -r 4bdebb81dcd5 -r 95c770f35636 LEDService.h
--- a/LEDService.h Mon Jul 27 07:30:47 2015 +0000
+++ b/LEDService.h Mon Aug 17 09:49:55 2015 +0000
@@ -13,15 +13,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+
#ifndef __BLE_LED_SERVICE_H__
#define __BLE_LED_SERVICE_H__
-
+
class LEDService {
public:
const static uint16_t LED_SERVICE_UUID = 0xA000;
const static uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xA001;
-
+
LEDService(BLEDevice &_ble, bool initialValueForLEDCharacteristic) :
ble(_ble), ledState(LED_STATE_CHARACTERISTIC_UUID, &initialValueForLEDCharacteristic)
{
@@ -29,14 +29,14 @@
GattService ledService(LED_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
ble.addService(ledService);
}
-
+
GattAttribute::Handle_t getValueHandle() const {
return ledState.getValueHandle();
}
-
+
private:
BLEDevice &ble;
ReadWriteGattCharacteristic<bool> ledState;
};
-
-#endif /* #ifndef __BLE_LED_SERVICE_H__ */
\ No newline at end of file
+
+#endif /* #ifndef __BLE_LED_SERVICE_H__ */
diff -r 4bdebb81dcd5 -r 95c770f35636 main.cpp
--- a/main.cpp Mon Jul 27 07:30:47 2015 +0000
+++ b/main.cpp Mon Aug 17 09:49:55 2015 +0000
@@ -20,167 +20,197 @@
#include "ble/services/BatteryService.h"
#include "ble/services/DeviceInformationService.h"
#include "LEDService.h"
-
-#define BLE_CHECK(X) (X == BLE_ERROR_NONE) ? (printf("{{success}}\r\n")) : printf("{{failure}} %s at line %u ERROR CODE: %u\r\n", #X, __LINE__, (X));
-#define BLE_EQUAL(X,Y) ((X)==(Y)) ? (printf("{{sucess}}\n")) : printf("{{failure}}\n");
+#include "ButtonService.h"
-BLE ble;
-DigitalOut led1(LED1);
-Gap::Address_t address;
-Gap::AddressType_t *addressType;
+#define ASSERT_NO_FAILURE(CMD) do { \
+ ble_error_t error = (CMD); \
+ if (error == BLE_ERROR_NONE){ \
+ printf("{{success}}\r\n"); \
+ } else{ \
+ printf("{{failure}} %s at line %u ERROR CODE: %u\r\n", #CMD, __LINE__, (error)); \
+ return; \
+ } \
+ }while (0)
+#define CHECK_EQUALS(X,Y) ((X)==(Y)) ? (printf("{{success}}\r\n")) : printf("{{failure}}\r\n");
-const static char DEVICE_NAME[] = "HRMTEST";
-static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE,
- GattService::UUID_DEVICE_INFORMATION_SERVICE,
- LEDService::LED_SERVICE_UUID};
-static volatile bool triggerSensorPolling = false;
+BLE ble;
+Gap::Address_t address;
+GapAdvertisingData::Appearance appearance;
+
+const static char DEVICE_NAME[] = "HRMTEST";
+static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE,
+ GattService::UUID_DEVICE_INFORMATION_SERVICE,
+ LEDService::LED_SERVICE_UUID};
+
+ButtonService *btnServicePtr;
void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
{
ble.gap().startAdvertising(); // restart advertising
}
-void periodicCallback(void)
-{
- led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
-
- /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
- * heavy-weight sensor polling from the main thread. */
+void connectionCallback(const Gap::ConnectionCallbackParams_t *params){
+ printf("Connected to: %d:%d:%d:%d:%d:%d\n",
+ params->peerAddr[0], params->peerAddr[1], params->peerAddr[2], params->peerAddr[3], params->peerAddr[4], params->peerAddr[5]);
}
-void connectionCallback(const Gap::ConnectionCallbackParams_t *params){
- printf("Connected to: %d:%d:%d:%d:%d:%d\n", params->peerAddr[0], params->peerAddr[1], params->peerAddr[2], params->peerAddr[3], params->peerAddr[4], params->peerAddr[5]);
-
-}
-
-void dataReadCallback(const GattReadCallbackParams *params){
- printf("%d\n", params->data[1]);
-}
-
-void testDeviceName(){
- if (ble.gap().getState().connected){
+void testDeviceName()
+{
+ if (ble.gap().getState().connected) {
printf("Device must be disconnected\n");
return;
}
- uint8_t deviceName[10];
- uint8_t deviceNameIn[] = {0x4A, 0x4F, 0x53, 0x48, 0x54, 0x45, 0x53, 0x54, 0x00};
- unsigned length = 10;
- BLE_CHECK(ble.gap().setDeviceName(deviceNameIn));
+
+ uint8_t deviceNameIn[] = "Josh-test";
+ ASSERT_NO_FAILURE(ble.gap().setDeviceName(deviceNameIn));
wait(0.5);
- BLE_CHECK(ble.gap().getDeviceName(deviceName, &length));
- wait(0.5);
- for (int i = 0; i < length; i++){
- printf("%02x ", deviceName[i]);
+
+ const size_t MAX_DEVICE_NAME_LEN = 50;
+ uint8_t deviceName[MAX_DEVICE_NAME_LEN];
+ unsigned length = MAX_DEVICE_NAME_LEN;
+ ASSERT_NO_FAILURE(ble.gap().getDeviceName(deviceName, &length));
+ printf("ASSERTIONS DONE\r\n");
+ for (unsigned i = 0; i < length; i++) {
+ printf("%c", deviceName[i]);
}
printf("\r\n");
- for (int i = 0; i < 8; i++){
- printf("%02x ", deviceNameIn[i]);
+ for (unsigned i = 0; i < strlen((char *)deviceNameIn); i++) {
+ printf("%c", deviceNameIn[i]);
}
printf("\r\n");
}
-void testAppearance(){
- if ((ble.gap().getState().connected)){
+void testAppearance()
+{
+ if ((ble.gap().getState().connected)) {
printf("Device must be disconnected\n");
return;
}
- GapAdvertisingData::Appearance appearance;
- BLE_CHECK(ble.gap().setAppearance(GapAdvertisingData::GENERIC_PHONE));
- wait(0.5);
- BLE_CHECK(ble.gap().getAppearance(&appearance));
- wait(0.5);
- printf("%d\r\n",appearance);
-}
-void connParams(){
- if ((ble.gap().getState().connected)){
+ ASSERT_NO_FAILURE(ble.gap().setAppearance(GapAdvertisingData::GENERIC_PHONE));
+ ASSERT_NO_FAILURE(ble.gap().getAppearance(&appearance));
+ printf("ASSERTIONS DONE\r\n");
+ printf("%d\r\n", appearance);
+}
+
+void connParams()
+{
+ if ((ble.gap().getState().connected)) {
printf("Device must be disconnected\n");
return;
}
+
Gap::ConnectionParams_t params;
- Gap::ConnectionParams_t paramsOut = {50,500,0,500};
+ Gap::ConnectionParams_t paramsOut = {50, 500, 0, 500};
Gap::ConnectionParams_t temp;
- BLE_CHECK(ble.gap().getPreferredConnectionParams(&temp));
- BLE_CHECK(ble.gap().setPreferredConnectionParams(¶msOut));
+
+ ASSERT_NO_FAILURE(ble.gap().getPreferredConnectionParams(&temp));
+ ASSERT_NO_FAILURE(ble.gap().setPreferredConnectionParams(¶msOut));
+
+ printf("ASSERTIONS DONE\r\n");
+
ble.gap().getPreferredConnectionParams(¶ms);
+
printf("%d\n", params.minConnectionInterval);
printf("%d\n", params.maxConnectionInterval);
printf("%d\n", params.slaveLatency);
printf("%d\n", params.connectionSupervisionTimeout);
+
ble.gap().setPreferredConnectionParams(&temp);
-
-}
+}
+
+void notificationTest(void) {
+ btnServicePtr->updateButtonState(true);
+}
+
+void commandInterpreter(void)
+{
+ const static size_t MAX_SIZEOF_COMMAND = 50;
+ while (true) {
+ char command[MAX_SIZEOF_COMMAND];
+ scanf("%s", command);
+
+ if (!strcmp(command, "setDeviceName")) {
+ testDeviceName();
+ } else if (!strcmp(command, "appearance")) {
+ testAppearance();
+ } else if (!strcmp(command, "connParam")) {
+ connParams();
+ } else if (!strcmp(command, "notification")) {
+ notificationTest();
+ }
+ }
+}
-void commandInterpreter(void){
- char command[50];
- while(1){
- scanf("%s", command);
- if (!strcmp(command, "setDeviceName")) testDeviceName();
- else if (!strcmp(command, "setAppearance")) testAppearance();
- else if (!strcmp(command, "testConnectionParams")) connParams();
+/**
+ * @return 0 if basic assumptions are validated. Non-zero returns are used to
+ * terminate the second-level python script early.
+ */
+unsigned verifyBasicAssumptions()
+{
+ ble.gap().onDisconnection(disconnectionCallback);
+ ble.gap().onConnection(connectionCallback);
+
+ /* Setup advertising. */
+ if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE)) {
+ return 1;
+ }
+ if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list))) {
+ return 1;
}
+ if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR)) {
+ return 1;
+ }
+ if (ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME))) {
+ return 1;
+ }
+ ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+ ble.gap().setAdvertisingInterval(1000); /* 1000ms */
+
+ if (ble.gap().startAdvertising()) {
+ return 1;
+ }
+
+ const char *version = ble.getVersion();
+ printf("%s\r\n", version);
+ if (!strcmp(version, "")) return 1;
+ return 0;
}
int main(void)
{
- led1 = 1;
- Ticker ticker;
- ticker.attach(periodicCallback, 1); // blink LED every second
-
- BLE_CHECK(ble.init());
- ble.gap().onDisconnection(disconnectionCallback);
- ble.gap().onConnection(connectionCallback);
- /* Setup primary service. */
- uint8_t hrmCounter = 100; // init HRM to 100bps
- HeartRateService hrService(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
-
- bool initialValueForLEDCharacteristic = false;
- LEDService ledService(ble, initialValueForLEDCharacteristic);
+ unsigned errorCode = ble.init();
+ if (errorCode == 0) {
+ uint8_t hrmCounter = 100; // init HRM to 100bps
+ HeartRateService *hrService = new HeartRateService(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
+
+ bool initialValueForLEDCharacteristic = false;
+ LEDService *ledService = new LEDService(ble, initialValueForLEDCharacteristic);
- /* Setup auxiliary service. */
- DeviceInformationService deviceInfo(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
+ DeviceInformationService *deviceInfo = new DeviceInformationService(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
+
+ btnServicePtr = new ButtonService(ble, false);
+ }
+ errorCode |= verifyBasicAssumptions();
+ if (errorCode == 0) {
+ printf("{{success}}\r\n{{end}}\r\n"); /* hand over control from the host test to the python script. */
+ } else {
+ printf("{{failure}}\r\n{{end}}\r\n"); /* hand over control from the host test to the python script. */
+ }
- /* Setup advertising. */
- BLE_CHECK(ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE));
- BLE_CHECK(ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)));
- BLE_CHECK(ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR));
- BLE_CHECK(ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)));
- ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
- ble.gap().setAdvertisingInterval(1000); /* 1000ms */
+ unsigned synchronize;
+ scanf("%u", &synchronize);
- BLE_CHECK(ble.gap().startAdvertising());
- BLE_CHECK(ble.gap().getAddress(addressType, address));
- printf("{{success}}" "\n" "{{end}}" "\n");
- int x;
- scanf("%d" , &x);
+ if (errorCode != 0) {
+ printf("Initial basic assumptions failed\r\n");
+ return -1;
+ }
+
+ Gap::AddressType_t addressType;
+ ASSERT_NO_FAILURE(ble.gap().getAddress(&addressType, address));
+
+ /* write out the MAC address to allow the second level python script to target this device. */
printf("%d:%d:%d:%d:%d:%d\n", address[0], address[1], address[2], address[3], address[4], address[5]);
+
commandInterpreter();
-/*
- scanf("%d", &x);
- testDeviceName();
- //printf("%d\n",ble.gattServer().onDataRead(dataReadCallback));
- scanf("%d", &x);
- testAppearance();
- scanf("%d", &x);
- connParams();
- // infinite loop
- while (1) {
- // check for trigger from periodicCallback()
- if (triggerSensorPolling && ble.getGapState().connected) {
- triggerSensorPolling = false;
-
- // Do blocking calls or whatever is necessary for sensor polling.
- // In our case, we simply update the HRM measurement.
- hrmCounter++;
- // 100 <= HRM bps <=175
- if (hrmCounter == 175) {
- hrmCounter = 100;
- }
- // update bps
- hrService.updateHeartRate(hrmCounter);
- } else {
- ble.waitForEvent(); // low power wait for event
- }
- }
-*/
}
diff -r 4bdebb81dcd5 -r 95c770f35636 nRF51822.lib --- a/nRF51822.lib Mon Jul 27 07:30:47 2015 +0000 +++ b/nRF51822.lib Mon Aug 17 09:49:55 2015 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#7455428e5ddb +http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#ca9c9c2cfc6a