init

Dependencies:   BLE_API mbed nRF51822

Committer:
jslater8
Date:
Tue Jul 21 08:39:03 2015 +0000
Revision:
0:84779d0d1ff5
Child:
1:4bdebb81dcd5
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jslater8 0:84779d0d1ff5 1 /* mbed Microcontroller Library
jslater8 0:84779d0d1ff5 2 * Copyright (c) 2006-2015 ARM Limited
jslater8 0:84779d0d1ff5 3 *
jslater8 0:84779d0d1ff5 4 * Licensed under the Apache License, Version 2.0 (the "License");
jslater8 0:84779d0d1ff5 5 * you may not use this file except in compliance with the License.
jslater8 0:84779d0d1ff5 6 * You may obtain a copy of the License at
jslater8 0:84779d0d1ff5 7 *
jslater8 0:84779d0d1ff5 8 * http://www.apache.org/licenses/LICENSE-2.0
jslater8 0:84779d0d1ff5 9 *
jslater8 0:84779d0d1ff5 10 * Unless required by applicable law or agreed to in writing, software
jslater8 0:84779d0d1ff5 11 * distributed under the License is distributed on an "AS IS" BASIS,
jslater8 0:84779d0d1ff5 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
jslater8 0:84779d0d1ff5 13 * See the License for the specific language governing permissions and
jslater8 0:84779d0d1ff5 14 * limitations under the License.
jslater8 0:84779d0d1ff5 15 */
jslater8 0:84779d0d1ff5 16
jslater8 0:84779d0d1ff5 17 #include "mbed.h"
jslater8 0:84779d0d1ff5 18 #include "ble/BLE.h"
jslater8 0:84779d0d1ff5 19 #include "ble/services/HeartRateService.h"
jslater8 0:84779d0d1ff5 20 #include "ble/services/BatteryService.h"
jslater8 0:84779d0d1ff5 21 #include "ble/services/DeviceInformationService.h"
jslater8 0:84779d0d1ff5 22 #include "LEDService.h"
jslater8 0:84779d0d1ff5 23
jslater8 0:84779d0d1ff5 24 #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));
jslater8 0:84779d0d1ff5 25 #define BLE_EQUAL(X,Y) ((X)==(Y)) ? (printf("{{sucess}}\n")) : printf("{{failure}}\n");
jslater8 0:84779d0d1ff5 26
jslater8 0:84779d0d1ff5 27 BLE ble;
jslater8 0:84779d0d1ff5 28 DigitalOut led1(LED1);
jslater8 0:84779d0d1ff5 29 Gap::Address_t address;
jslater8 0:84779d0d1ff5 30 Gap::AddressType_t *addressType;
jslater8 0:84779d0d1ff5 31
jslater8 0:84779d0d1ff5 32 const static char DEVICE_NAME[] = "HRMTEST";
jslater8 0:84779d0d1ff5 33 static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE,
jslater8 0:84779d0d1ff5 34 GattService::UUID_DEVICE_INFORMATION_SERVICE};
jslater8 0:84779d0d1ff5 35 static volatile bool triggerSensorPolling = false;
jslater8 0:84779d0d1ff5 36
jslater8 0:84779d0d1ff5 37 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
jslater8 0:84779d0d1ff5 38 {
jslater8 0:84779d0d1ff5 39 ble.gap().startAdvertising(); // restart advertising
jslater8 0:84779d0d1ff5 40 }
jslater8 0:84779d0d1ff5 41
jslater8 0:84779d0d1ff5 42 void periodicCallback(void)
jslater8 0:84779d0d1ff5 43 {
jslater8 0:84779d0d1ff5 44 led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */
jslater8 0:84779d0d1ff5 45
jslater8 0:84779d0d1ff5 46 /* Note that the periodicCallback() executes in interrupt context, so it is safer to do
jslater8 0:84779d0d1ff5 47 * heavy-weight sensor polling from the main thread. */
jslater8 0:84779d0d1ff5 48 if (ble.getGapState().connected){
jslater8 0:84779d0d1ff5 49 hrmCounter++;
jslater8 0:84779d0d1ff5 50 // 100 <= HRM bps <=175
jslater8 0:84779d0d1ff5 51 if (hrmCounter == 175) {
jslater8 0:84779d0d1ff5 52 hrmCounter = 100;
jslater8 0:84779d0d1ff5 53 }
jslater8 0:84779d0d1ff5 54 // update bps
jslater8 0:84779d0d1ff5 55 hrService.updateHeartRate(hrmCounter);
jslater8 0:84779d0d1ff5 56 }
jslater8 0:84779d0d1ff5 57 }
jslater8 0:84779d0d1ff5 58
jslater8 0:84779d0d1ff5 59 void connectionCallback(const Gap::ConnectionCallbackParams_t *params){
jslater8 0:84779d0d1ff5 60 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]);
jslater8 0:84779d0d1ff5 61
jslater8 0:84779d0d1ff5 62 }
jslater8 0:84779d0d1ff5 63
jslater8 0:84779d0d1ff5 64 void dataReadCallback(const GattReadCallbackParams *params){
jslater8 0:84779d0d1ff5 65 printf("%d\n", params->data[1]);
jslater8 0:84779d0d1ff5 66 }
jslater8 0:84779d0d1ff5 67
jslater8 0:84779d0d1ff5 68 void testDeviceName(){
jslater8 0:84779d0d1ff5 69 uint8_t deviceName[10];
jslater8 0:84779d0d1ff5 70 uint8_t deviceNameIn[] = {0x4A, 0x4F, 0x53, 0x48, 0x54, 0x45, 0x53, 0x54, 0x00};
jslater8 0:84779d0d1ff5 71 unsigned length = 10;
jslater8 0:84779d0d1ff5 72 BLE_CHECK(ble.gap().setDeviceName(deviceNameIn));
jslater8 0:84779d0d1ff5 73 BLE_CHECK(ble.gap().getDeviceName(deviceName, &length));
jslater8 0:84779d0d1ff5 74 for (int i = 0; i < length; i++){
jslater8 0:84779d0d1ff5 75 printf("%02x ", deviceName[i]);
jslater8 0:84779d0d1ff5 76 }
jslater8 0:84779d0d1ff5 77 printf("\r\n");
jslater8 0:84779d0d1ff5 78 for (int i = 0; i < 8; i++){
jslater8 0:84779d0d1ff5 79 printf("%02x ", deviceNameIn[i]);
jslater8 0:84779d0d1ff5 80 }
jslater8 0:84779d0d1ff5 81 printf("\r\n");
jslater8 0:84779d0d1ff5 82 }
jslater8 0:84779d0d1ff5 83
jslater8 0:84779d0d1ff5 84 void testAppearance(){
jslater8 0:84779d0d1ff5 85 GapAdvertisingData::Appearance appearance;
jslater8 0:84779d0d1ff5 86 BLE_CHECK(ble.gap().setAppearance(GapAdvertisingData::GENERIC_PHONE));
jslater8 0:84779d0d1ff5 87 BLE_CHECK(ble.gap().getAppearance(&appearance));
jslater8 0:84779d0d1ff5 88 printf("%d\r\n",appearance);
jslater8 0:84779d0d1ff5 89 }
jslater8 0:84779d0d1ff5 90
jslater8 0:84779d0d1ff5 91 void connParams(){
jslater8 0:84779d0d1ff5 92 Gap::ConnectionParams_t params;
jslater8 0:84779d0d1ff5 93 Gap::ConnectionParams_t paramsOut = {50,500,0,500};
jslater8 0:84779d0d1ff5 94 Gap::ConnectionParams_t temp;
jslater8 0:84779d0d1ff5 95 BLE_CHECK(ble.gap().getPreferredConnectionParams(&temp));
jslater8 0:84779d0d1ff5 96 BLE_CHECK(ble.gap().setPreferredConnectionParams(&paramsOut));
jslater8 0:84779d0d1ff5 97 ble.gap().getPreferredConnectionParams(&params);
jslater8 0:84779d0d1ff5 98 printf("%d\n", params.minConnectionInterval);
jslater8 0:84779d0d1ff5 99 printf("%d\n", params.maxConnectionInterval);
jslater8 0:84779d0d1ff5 100 printf("%d\n", params.slaveLatency);
jslater8 0:84779d0d1ff5 101 printf("%d\n", params.connectionSupervisionTimeout);
jslater8 0:84779d0d1ff5 102 ble.gap().setPreferredConnectionParams(&temp);
jslater8 0:84779d0d1ff5 103
jslater8 0:84779d0d1ff5 104 }
jslater8 0:84779d0d1ff5 105
jslater8 0:84779d0d1ff5 106 void testcentre(void){
jslater8 0:84779d0d1ff5 107
jslater8 0:84779d0d1ff5 108 scanf("%d", &x);
jslater8 0:84779d0d1ff5 109 testDeviceName();
jslater8 0:84779d0d1ff5 110 scanf("%d", &x);
jslater8 0:84779d0d1ff5 111 testAppearance();
jslater8 0:84779d0d1ff5 112 scanf("%d", &x);
jslater8 0:84779d0d1ff5 113 connParams();
jslater8 0:84779d0d1ff5 114 int x;
jslater8 0:84779d0d1ff5 115 while(1){
jslater8 0:84779d0d1ff5 116 scanf("%d", &x);
jslater8 0:84779d0d1ff5 117 switch(x){
jslater8 0:84779d0d1ff5 118 case 0:
jslater8 0:84779d0d1ff5 119 testDeviceName();
jslater8 0:84779d0d1ff5 120 break;
jslater8 0:84779d0d1ff5 121 case 1:
jslater8 0:84779d0d1ff5 122 testAppearance();
jslater8 0:84779d0d1ff5 123 break;
jslater8 0:84779d0d1ff5 124 case 2:
jslater8 0:84779d0d1ff5 125 connParams();
jslater8 0:84779d0d1ff5 126 break;
jslater8 0:84779d0d1ff5 127 case 3:
jslater8 0:84779d0d1ff5 128
jslater8 0:84779d0d1ff5 129 break;
jslater8 0:84779d0d1ff5 130 }
jslater8 0:84779d0d1ff5 131 }
jslater8 0:84779d0d1ff5 132 }
jslater8 0:84779d0d1ff5 133
jslater8 0:84779d0d1ff5 134 int main(void)
jslater8 0:84779d0d1ff5 135 {
jslater8 0:84779d0d1ff5 136 led1 = 1;
jslater8 0:84779d0d1ff5 137 Ticker ticker;
jslater8 0:84779d0d1ff5 138 ticker.attach(periodicCallback, 1); // blink LED every second
jslater8 0:84779d0d1ff5 139
jslater8 0:84779d0d1ff5 140 BLE_CHECK(ble.init());
jslater8 0:84779d0d1ff5 141 ble.gap().onDisconnection(disconnectionCallback);
jslater8 0:84779d0d1ff5 142 ble.gap().onConnection(connectionCallback);
jslater8 0:84779d0d1ff5 143 /* Setup primary service. */
jslater8 0:84779d0d1ff5 144 uint8_t hrmCounter = 100; // init HRM to 100bps
jslater8 0:84779d0d1ff5 145 HeartRateService hrService(ble, hrmCounter, HeartRateService::LOCATION_FINGER);
jslater8 0:84779d0d1ff5 146
jslater8 0:84779d0d1ff5 147 /* Setup auxiliary service. */
jslater8 0:84779d0d1ff5 148 DeviceInformationService deviceInfo(ble, "ARM", "Model1", "SN1", "hw-rev1", "fw-rev1", "soft-rev1");
jslater8 0:84779d0d1ff5 149
jslater8 0:84779d0d1ff5 150 /* Setup advertising. */
jslater8 0:84779d0d1ff5 151 BLE_CHECK(ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE));
jslater8 0:84779d0d1ff5 152 BLE_CHECK(ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)));
jslater8 0:84779d0d1ff5 153 BLE_CHECK(ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_HEART_RATE_SENSOR));
jslater8 0:84779d0d1ff5 154 BLE_CHECK(ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)));
jslater8 0:84779d0d1ff5 155 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
jslater8 0:84779d0d1ff5 156 ble.gap().setAdvertisingInterval(1000); /* 1000ms */
jslater8 0:84779d0d1ff5 157
jslater8 0:84779d0d1ff5 158 BLE_CHECK(ble.gap().startAdvertising());
jslater8 0:84779d0d1ff5 159 BLE_CHECK(ble.gap().getAddress(addressType, address));
jslater8 0:84779d0d1ff5 160 printf("{{success}}" "\n" "{{end}}" "\n");
jslater8 0:84779d0d1ff5 161 int x;
jslater8 0:84779d0d1ff5 162 scanf("%d" , &x);
jslater8 0:84779d0d1ff5 163 printf("%d:%d:%d:%d:%d:%d\n", address[0], address[1], address[2], address[3], address[4], address[5]);
jslater8 0:84779d0d1ff5 164 testCentre();
jslater8 0:84779d0d1ff5 165 scanf("%d", &x);
jslater8 0:84779d0d1ff5 166 testDeviceName();
jslater8 0:84779d0d1ff5 167 //printf("%d\n",ble.gattServer().onDataRead(dataReadCallback));
jslater8 0:84779d0d1ff5 168 scanf("%d", &x);
jslater8 0:84779d0d1ff5 169 testAppearance();
jslater8 0:84779d0d1ff5 170 scanf("%d", &x);
jslater8 0:84779d0d1ff5 171 connParams();
jslater8 0:84779d0d1ff5 172 // infinite loop
jslater8 0:84779d0d1ff5 173 while (1) {
jslater8 0:84779d0d1ff5 174 // check for trigger from periodicCallback()
jslater8 0:84779d0d1ff5 175 if (triggerSensorPolling && ble.getGapState().connected) {
jslater8 0:84779d0d1ff5 176 triggerSensorPolling = false;
jslater8 0:84779d0d1ff5 177
jslater8 0:84779d0d1ff5 178 // Do blocking calls or whatever is necessary for sensor polling.
jslater8 0:84779d0d1ff5 179 // In our case, we simply update the HRM measurement.
jslater8 0:84779d0d1ff5 180 hrmCounter++;
jslater8 0:84779d0d1ff5 181 // 100 <= HRM bps <=175
jslater8 0:84779d0d1ff5 182 if (hrmCounter == 175) {
jslater8 0:84779d0d1ff5 183 hrmCounter = 100;
jslater8 0:84779d0d1ff5 184 }
jslater8 0:84779d0d1ff5 185 // update bps
jslater8 0:84779d0d1ff5 186 hrService.updateHeartRate(hrmCounter);
jslater8 0:84779d0d1ff5 187 } else {
jslater8 0:84779d0d1ff5 188 ble.waitForEvent(); // low power wait for event
jslater8 0:84779d0d1ff5 189 }
jslater8 0:84779d0d1ff5 190 }
jslater8 0:84779d0d1ff5 191 }