example firmware for nRF51-Dongle to use with Opentrigger

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_Button by Bluetooth Low Energy

http://www.opentrigger.com

Committer:
0xf10
Date:
Tue Jun 07 18:20:12 2016 +0000
Revision:
13:0f26a3fc1f32
Parent:
12:2cb903df877d
Child:
14:09f208b24460
working button

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 0:28f095301cb2 1 /* mbed Microcontroller Library
rgrover1 0:28f095301cb2 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 0:28f095301cb2 3 *
rgrover1 0:28f095301cb2 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 0:28f095301cb2 5 * you may not use this file except in compliance with the License.
rgrover1 0:28f095301cb2 6 * You may obtain a copy of the License at
rgrover1 0:28f095301cb2 7 *
rgrover1 0:28f095301cb2 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 0:28f095301cb2 9 *
rgrover1 0:28f095301cb2 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 0:28f095301cb2 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 0:28f095301cb2 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 0:28f095301cb2 13 * See the License for the specific language governing permissions and
rgrover1 0:28f095301cb2 14 * limitations under the License.
rgrover1 0:28f095301cb2 15 */
rgrover1 0:28f095301cb2 16
rgrover1 0:28f095301cb2 17 #include "mbed.h"
andresag 10:7943b5c1117a 18 #include "ble/BLE.h"
rgrover1 0:28f095301cb2 19 #include "ButtonService.h"
rgrover1 0:28f095301cb2 20
rgrover1 0:28f095301cb2 21 DigitalOut led1(LED1);
0xf10 12:2cb903df877d 22 DigitalOut led2(LED2);
0xf10 13:0f26a3fc1f32 23 InterruptIn button(P0_15); /* The Pin where your Button is Connected */
rgrover1 0:28f095301cb2 24
0xf10 13:0f26a3fc1f32 25 const uint16_t MIN_ADVERT_INTERVAL = 50; /* msec */
rgrover1 0:28f095301cb2 26 const static char DEVICE_NAME[] = "Button";
rgrover1 0:28f095301cb2 27 static const uint16_t uuid16_list[] = {ButtonService::BUTTON_SERVICE_UUID};
rgrover1 0:28f095301cb2 28
rgrover1 9:0f6951db24f1 29 enum {
rgrover1 9:0f6951db24f1 30 RELEASED = 0,
rgrover1 9:0f6951db24f1 31 PRESSED,
rgrover1 9:0f6951db24f1 32 IDLE
rgrover1 9:0f6951db24f1 33 };
rgrover1 9:0f6951db24f1 34 static uint8_t buttonState = IDLE;
rgrover1 9:0f6951db24f1 35
andresag 10:7943b5c1117a 36 static ButtonService *buttonServicePtr;
rgrover1 0:28f095301cb2 37
0xf10 11:5b6d98e98127 38 void blinkLed(void){
0xf10 12:2cb903df877d 39 led2 = !led2;
0xf10 11:5b6d98e98127 40 }
0xf10 11:5b6d98e98127 41
rgrover1 0:28f095301cb2 42 void buttonPressedCallback(void)
rgrover1 0:28f095301cb2 43 {
rgrover1 9:0f6951db24f1 44 /* Note that the buttonPressedCallback() executes in interrupt context, so it is safer to access
rgrover1 9:0f6951db24f1 45 * BLE device API from the main thread. */
rgrover1 9:0f6951db24f1 46 buttonState = PRESSED;
rgrover1 0:28f095301cb2 47 }
rgrover1 0:28f095301cb2 48
rgrover1 0:28f095301cb2 49 void buttonReleasedCallback(void)
rgrover1 0:28f095301cb2 50 {
rgrover1 9:0f6951db24f1 51 /* Note that the buttonReleasedCallback() executes in interrupt context, so it is safer to access
rgrover1 9:0f6951db24f1 52 * BLE device API from the main thread. */
rgrover1 9:0f6951db24f1 53 buttonState = RELEASED;
rgrover1 0:28f095301cb2 54 }
rgrover1 0:28f095301cb2 55
rgrover1 8:a7ba7aaba460 56 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
rgrover1 0:28f095301cb2 57 {
andresag 10:7943b5c1117a 58 BLE::Instance().gap().startAdvertising();
rgrover1 0:28f095301cb2 59 }
rgrover1 0:28f095301cb2 60
rgrover1 0:28f095301cb2 61 void periodicCallback(void)
rgrover1 0:28f095301cb2 62 {
0xf10 12:2cb903df877d 63 blinkLed();
rgrover1 0:28f095301cb2 64 }
rgrover1 0:28f095301cb2 65
andresag 10:7943b5c1117a 66 /**
andresag 10:7943b5c1117a 67 * This function is called when the ble initialization process has failled
andresag 10:7943b5c1117a 68 */
andresag 10:7943b5c1117a 69 void onBleInitError(BLE &ble, ble_error_t error)
andresag 10:7943b5c1117a 70 {
andresag 10:7943b5c1117a 71 /* Initialization error handling should go here */
0xf10 13:0f26a3fc1f32 72 error("Panic!");
andresag 10:7943b5c1117a 73 }
andresag 10:7943b5c1117a 74
0xf10 11:5b6d98e98127 75 void setPir(uint8_t pir){
0xf10 13:0f26a3fc1f32 76 uint8_t data[] = {
0xf10 13:0f26a3fc1f32 77 0xee, 0xff, // Tokencube Manufacturer ID
0xf10 13:0f26a3fc1f32 78 0x04, // Token Module Version
0xf10 13:0f26a3fc1f32 79 0x01, // Firmware Version
0xf10 13:0f26a3fc1f32 80 0x11, // Page 1 of 1
0xf10 13:0f26a3fc1f32 81 0x07, pir // pir value
0xf10 13:0f26a3fc1f32 82 };
0xf10 11:5b6d98e98127 83 BLE::Instance().gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, data, sizeof(data));
0xf10 11:5b6d98e98127 84 }
0xf10 11:5b6d98e98127 85
andresag 10:7943b5c1117a 86 /**
andresag 10:7943b5c1117a 87 * Callback triggered when the ble initialization process has finished
andresag 10:7943b5c1117a 88 */
andresag 10:7943b5c1117a 89 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
andresag 10:7943b5c1117a 90 {
andresag 10:7943b5c1117a 91 BLE& ble = params->ble;
andresag 10:7943b5c1117a 92 ble_error_t error = params->error;
andresag 10:7943b5c1117a 93
andresag 10:7943b5c1117a 94 if (error != BLE_ERROR_NONE) {
andresag 10:7943b5c1117a 95 /* In case of error, forward the error handling to onBleInitError */
andresag 10:7943b5c1117a 96 onBleInitError(ble, error);
andresag 10:7943b5c1117a 97 return;
andresag 10:7943b5c1117a 98 }
andresag 10:7943b5c1117a 99
andresag 10:7943b5c1117a 100 /* Ensure that it is the default instance of BLE */
andresag 10:7943b5c1117a 101 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
andresag 10:7943b5c1117a 102 return;
andresag 10:7943b5c1117a 103 }
0xf10 11:5b6d98e98127 104
0xf10 13:0f26a3fc1f32 105 uint8_t macAddress[6] = {0x00};
0xf10 13:0f26a3fc1f32 106 BLEProtocol::AddressType_t pubAddr = BLEProtocol::AddressType::PUBLIC;
0xf10 13:0f26a3fc1f32 107 ble.gap().getAddress(&pubAddr, macAddress);
0xf10 13:0f26a3fc1f32 108
0xf10 13:0f26a3fc1f32 109 /* change device MAC address */
0xf10 13:0f26a3fc1f32 110 //const uint8_t address1[] = {0xe7,0xAA,0xAA,0xAA,0xAA,0xAA};
0xf10 13:0f26a3fc1f32 111 //ble.gap().setAddress(pubAddr, address1);
andresag 10:7943b5c1117a 112
andresag 10:7943b5c1117a 113 ble.gap().onDisconnection(disconnectionCallback);
andresag 10:7943b5c1117a 114
andresag 10:7943b5c1117a 115 /* Setup primary service */
andresag 10:7943b5c1117a 116 buttonServicePtr = new ButtonService(ble, false /* initial value for button pressed */);
andresag 10:7943b5c1117a 117
andresag 10:7943b5c1117a 118 /* setup advertising */
andresag 10:7943b5c1117a 119 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
andresag 10:7943b5c1117a 120 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
andresag 10:7943b5c1117a 121 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
andresag 10:7943b5c1117a 122 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
0xf10 13:0f26a3fc1f32 123
0xf10 13:0f26a3fc1f32 124 uint16_t minInterval = ble.gap().getMinAdvertisingInterval();
0xf10 13:0f26a3fc1f32 125 if(minInterval < 50) minInterval = 50;
0xf10 13:0f26a3fc1f32 126 ble.gap().setAdvertisingInterval(minInterval); /* ms. */
0xf10 11:5b6d98e98127 127 setPir(0x00);
andresag 10:7943b5c1117a 128 ble.gap().startAdvertising();
0xf10 13:0f26a3fc1f32 129
0xf10 13:0f26a3fc1f32 130 // Print Interval and MAC Address
0xf10 13:0f26a3fc1f32 131 printf("advertisingInterval = %i\n\r", minInterval);
0xf10 13:0f26a3fc1f32 132 printf("MAC Address = %02X:%02X:%02X:%02X:%02X:%02X\n\r", macAddress[5], macAddress[4], macAddress[3], macAddress[2], macAddress[1], macAddress[0]);
andresag 10:7943b5c1117a 133
andresag 10:7943b5c1117a 134 }
andresag 10:7943b5c1117a 135
0xf10 11:5b6d98e98127 136
0xf10 11:5b6d98e98127 137
rgrover1 0:28f095301cb2 138 int main(void)
rgrover1 0:28f095301cb2 139 {
0xf10 11:5b6d98e98127 140 led1 = !0;
0xf10 12:2cb903df877d 141 led2 = !0;
rgrover1 0:28f095301cb2 142 Ticker ticker;
rgrover1 0:28f095301cb2 143 ticker.attach(periodicCallback, 1);
rgrover1 0:28f095301cb2 144 button.fall(buttonPressedCallback);
rgrover1 0:28f095301cb2 145 button.rise(buttonReleasedCallback);
rgrover1 0:28f095301cb2 146
andresag 10:7943b5c1117a 147 BLE &ble = BLE::Instance();
andresag 10:7943b5c1117a 148 ble.init(bleInitComplete);
andresag 10:7943b5c1117a 149
andresag 10:7943b5c1117a 150 /* SpinWait for initialization to complete. This is necessary because the
andresag 10:7943b5c1117a 151 * BLE object is used in the main loop below. */
andresag 10:7943b5c1117a 152 while (ble.hasInitialized() == false) { /* spin loop */ }
andresag 10:7943b5c1117a 153
rgrover1 0:28f095301cb2 154 while (true) {
andresag 10:7943b5c1117a 155 if (buttonState != IDLE) {
rgrover1 9:0f6951db24f1 156 buttonServicePtr->updateButtonState(buttonState);
0xf10 13:0f26a3fc1f32 157 if(buttonState == PRESSED) {led1=!1; setPir(0x01);}
0xf10 13:0f26a3fc1f32 158 if(buttonState == RELEASED) {led1=!0; setPir(0x00);}
rgrover1 9:0f6951db24f1 159 buttonState = IDLE;
rgrover1 9:0f6951db24f1 160 }
rgrover1 9:0f6951db24f1 161
rgrover1 0:28f095301cb2 162 ble.waitForEvent();
rgrover1 0:28f095301cb2 163 }
rgrover1 0:28f095301cb2 164 }