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:
Mon Jun 13 17:09:43 2016 +0000
Revision:
14:09f208b24460
Parent:
13:0f26a3fc1f32
Child:
15:9f9f5d82743d
GPIO Support

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 14:09f208b24460 23 InterruptIn button0(P0_15);
0xf10 14:09f208b24460 24 InterruptIn button1(P0_16);
0xf10 14:09f208b24460 25 InterruptIn button2(P0_17);
0xf10 14:09f208b24460 26 InterruptIn button3(P0_18);
0xf10 14:09f208b24460 27 InterruptIn button4(P0_19);
0xf10 14:09f208b24460 28 InterruptIn button5(P0_20);
rgrover1 0:28f095301cb2 29
0xf10 13:0f26a3fc1f32 30 const uint16_t MIN_ADVERT_INTERVAL = 50; /* msec */
0xf10 14:09f208b24460 31 const static char DEVICE_NAME[] = "OT";
rgrover1 0:28f095301cb2 32 static const uint16_t uuid16_list[] = {ButtonService::BUTTON_SERVICE_UUID};
0xf10 14:09f208b24460 33 static uint8_t gpio_states[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
rgrover1 0:28f095301cb2 34
rgrover1 9:0f6951db24f1 35 enum {
rgrover1 9:0f6951db24f1 36 RELEASED = 0,
rgrover1 9:0f6951db24f1 37 PRESSED,
rgrover1 9:0f6951db24f1 38 IDLE
rgrover1 9:0f6951db24f1 39 };
rgrover1 9:0f6951db24f1 40 static uint8_t buttonState = IDLE;
rgrover1 9:0f6951db24f1 41
andresag 10:7943b5c1117a 42 static ButtonService *buttonServicePtr;
rgrover1 0:28f095301cb2 43
0xf10 11:5b6d98e98127 44 void blinkLed(void){
0xf10 12:2cb903df877d 45 led2 = !led2;
0xf10 11:5b6d98e98127 46 }
0xf10 11:5b6d98e98127 47
0xf10 14:09f208b24460 48 void button0PressedCallback(void)
rgrover1 0:28f095301cb2 49 {
rgrover1 9:0f6951db24f1 50 /* Note that the buttonPressedCallback() executes in interrupt context, so it is safer to access
rgrover1 9:0f6951db24f1 51 * BLE device API from the main thread. */
rgrover1 9:0f6951db24f1 52 buttonState = PRESSED;
0xf10 14:09f208b24460 53 gpio_states[0]=0x01;
rgrover1 0:28f095301cb2 54 }
rgrover1 0:28f095301cb2 55
0xf10 14:09f208b24460 56 void button0ReleasedCallback(void)
rgrover1 0:28f095301cb2 57 {
rgrover1 9:0f6951db24f1 58 /* Note that the buttonReleasedCallback() executes in interrupt context, so it is safer to access
rgrover1 9:0f6951db24f1 59 * BLE device API from the main thread. */
rgrover1 9:0f6951db24f1 60 buttonState = RELEASED;
0xf10 14:09f208b24460 61 gpio_states[0]=0x00;
rgrover1 0:28f095301cb2 62 }
rgrover1 0:28f095301cb2 63
0xf10 14:09f208b24460 64 void button1PressedCallback(void) { buttonState = PRESSED; gpio_states[1]=0x01; }
0xf10 14:09f208b24460 65 void button1ReleasedCallback(void){ buttonState = RELEASED; gpio_states[1]=0x00; }
0xf10 14:09f208b24460 66 void button2PressedCallback(void) { buttonState = PRESSED; gpio_states[2]=0x01; }
0xf10 14:09f208b24460 67 void button2ReleasedCallback(void){ buttonState = RELEASED; gpio_states[2]=0x00; }
0xf10 14:09f208b24460 68 void button3PressedCallback(void) { buttonState = PRESSED; gpio_states[3]=0x01; }
0xf10 14:09f208b24460 69 void button3ReleasedCallback(void){ buttonState = RELEASED; gpio_states[3]=0x00; }
0xf10 14:09f208b24460 70 void button4PressedCallback(void) { buttonState = PRESSED; gpio_states[4]=0x01; }
0xf10 14:09f208b24460 71 void button4ReleasedCallback(void){ buttonState = RELEASED; gpio_states[4]=0x00; }
0xf10 14:09f208b24460 72 void button5PressedCallback(void) { buttonState = PRESSED; gpio_states[5]=0x01; }
0xf10 14:09f208b24460 73 void button5ReleasedCallback(void){ buttonState = RELEASED; gpio_states[5]=0x00; }
0xf10 14:09f208b24460 74
rgrover1 8:a7ba7aaba460 75 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
rgrover1 0:28f095301cb2 76 {
andresag 10:7943b5c1117a 77 BLE::Instance().gap().startAdvertising();
rgrover1 0:28f095301cb2 78 }
rgrover1 0:28f095301cb2 79
rgrover1 0:28f095301cb2 80 void periodicCallback(void)
rgrover1 0:28f095301cb2 81 {
0xf10 12:2cb903df877d 82 blinkLed();
rgrover1 0:28f095301cb2 83 }
rgrover1 0:28f095301cb2 84
andresag 10:7943b5c1117a 85 /**
andresag 10:7943b5c1117a 86 * This function is called when the ble initialization process has failled
andresag 10:7943b5c1117a 87 */
0xf10 14:09f208b24460 88 void onBleInitError(BLE &ble, ble_error_t bt_error)
andresag 10:7943b5c1117a 89 {
andresag 10:7943b5c1117a 90 /* Initialization error handling should go here */
0xf10 13:0f26a3fc1f32 91 error("Panic!");
andresag 10:7943b5c1117a 92 }
andresag 10:7943b5c1117a 93
0xf10 11:5b6d98e98127 94 void setPir(uint8_t pir){
0xf10 14:09f208b24460 95 // http://tokencube.com/bluetooth-sensor.html
0xf10 13:0f26a3fc1f32 96 uint8_t data[] = {
0xf10 13:0f26a3fc1f32 97 0xee, 0xff, // Tokencube Manufacturer ID
0xf10 13:0f26a3fc1f32 98 0x04, // Token Module Version
0xf10 13:0f26a3fc1f32 99 0x01, // Firmware Version
0xf10 13:0f26a3fc1f32 100 0x11, // Page 1 of 1
0xf10 14:09f208b24460 101 0x07, pir, // pir value
0xf10 14:09f208b24460 102 // custom data - state of all 6 gpio's
0xf10 14:09f208b24460 103 0x0F, gpio_states[0], gpio_states[1], gpio_states[2], gpio_states[3], gpio_states[4], gpio_states[5]
0xf10 13:0f26a3fc1f32 104 };
0xf10 11:5b6d98e98127 105 BLE::Instance().gap().accumulateAdvertisingPayload(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, data, sizeof(data));
0xf10 11:5b6d98e98127 106 }
0xf10 11:5b6d98e98127 107
andresag 10:7943b5c1117a 108 /**
andresag 10:7943b5c1117a 109 * Callback triggered when the ble initialization process has finished
andresag 10:7943b5c1117a 110 */
andresag 10:7943b5c1117a 111 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
andresag 10:7943b5c1117a 112 {
andresag 10:7943b5c1117a 113 BLE& ble = params->ble;
andresag 10:7943b5c1117a 114 ble_error_t error = params->error;
andresag 10:7943b5c1117a 115
andresag 10:7943b5c1117a 116 if (error != BLE_ERROR_NONE) {
andresag 10:7943b5c1117a 117 /* In case of error, forward the error handling to onBleInitError */
andresag 10:7943b5c1117a 118 onBleInitError(ble, error);
andresag 10:7943b5c1117a 119 return;
andresag 10:7943b5c1117a 120 }
andresag 10:7943b5c1117a 121
andresag 10:7943b5c1117a 122 /* Ensure that it is the default instance of BLE */
andresag 10:7943b5c1117a 123 if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
andresag 10:7943b5c1117a 124 return;
andresag 10:7943b5c1117a 125 }
0xf10 11:5b6d98e98127 126
0xf10 13:0f26a3fc1f32 127 uint8_t macAddress[6] = {0x00};
0xf10 13:0f26a3fc1f32 128 BLEProtocol::AddressType_t pubAddr = BLEProtocol::AddressType::PUBLIC;
0xf10 13:0f26a3fc1f32 129 ble.gap().getAddress(&pubAddr, macAddress);
0xf10 13:0f26a3fc1f32 130
0xf10 13:0f26a3fc1f32 131 /* change device MAC address */
0xf10 13:0f26a3fc1f32 132 //const uint8_t address1[] = {0xe7,0xAA,0xAA,0xAA,0xAA,0xAA};
0xf10 13:0f26a3fc1f32 133 //ble.gap().setAddress(pubAddr, address1);
andresag 10:7943b5c1117a 134
andresag 10:7943b5c1117a 135 ble.gap().onDisconnection(disconnectionCallback);
andresag 10:7943b5c1117a 136
andresag 10:7943b5c1117a 137 /* Setup primary service */
andresag 10:7943b5c1117a 138 buttonServicePtr = new ButtonService(ble, false /* initial value for button pressed */);
andresag 10:7943b5c1117a 139
andresag 10:7943b5c1117a 140 /* setup advertising */
andresag 10:7943b5c1117a 141 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
andresag 10:7943b5c1117a 142 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
andresag 10:7943b5c1117a 143 ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
andresag 10:7943b5c1117a 144 ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
0xf10 13:0f26a3fc1f32 145
0xf10 13:0f26a3fc1f32 146 uint16_t minInterval = ble.gap().getMinAdvertisingInterval();
0xf10 14:09f208b24460 147 if(minInterval < MIN_ADVERT_INTERVAL) minInterval = MIN_ADVERT_INTERVAL;
0xf10 13:0f26a3fc1f32 148 ble.gap().setAdvertisingInterval(minInterval); /* ms. */
0xf10 11:5b6d98e98127 149 setPir(0x00);
andresag 10:7943b5c1117a 150 ble.gap().startAdvertising();
0xf10 13:0f26a3fc1f32 151
0xf10 13:0f26a3fc1f32 152 // Print Interval and MAC Address
0xf10 13:0f26a3fc1f32 153 printf("advertisingInterval = %i\n\r", minInterval);
0xf10 13:0f26a3fc1f32 154 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 155
andresag 10:7943b5c1117a 156 }
andresag 10:7943b5c1117a 157
0xf10 11:5b6d98e98127 158
0xf10 11:5b6d98e98127 159
rgrover1 0:28f095301cb2 160 int main(void)
rgrover1 0:28f095301cb2 161 {
rgrover1 0:28f095301cb2 162 Ticker ticker;
0xf10 14:09f208b24460 163
0xf10 14:09f208b24460 164 led1 = !0; led2 = !0;
0xf10 14:09f208b24460 165
rgrover1 0:28f095301cb2 166 ticker.attach(periodicCallback, 1);
0xf10 14:09f208b24460 167 button0.fall(button0PressedCallback);
0xf10 14:09f208b24460 168 button0.rise(button0ReleasedCallback);
0xf10 14:09f208b24460 169 button1.fall(button1PressedCallback);
0xf10 14:09f208b24460 170 button1.rise(button1ReleasedCallback);
0xf10 14:09f208b24460 171 button2.fall(button2PressedCallback);
0xf10 14:09f208b24460 172 button2.rise(button2ReleasedCallback);
0xf10 14:09f208b24460 173 button3.fall(button3PressedCallback);
0xf10 14:09f208b24460 174 button3.rise(button3ReleasedCallback);
0xf10 14:09f208b24460 175 button4.fall(button4PressedCallback);
0xf10 14:09f208b24460 176 button4.rise(button4ReleasedCallback);
0xf10 14:09f208b24460 177 button5.fall(button5PressedCallback);
0xf10 14:09f208b24460 178 button5.rise(button5ReleasedCallback);
rgrover1 0:28f095301cb2 179
andresag 10:7943b5c1117a 180 BLE &ble = BLE::Instance();
andresag 10:7943b5c1117a 181 ble.init(bleInitComplete);
andresag 10:7943b5c1117a 182
andresag 10:7943b5c1117a 183 /* SpinWait for initialization to complete. This is necessary because the
andresag 10:7943b5c1117a 184 * BLE object is used in the main loop below. */
andresag 10:7943b5c1117a 185 while (ble.hasInitialized() == false) { /* spin loop */ }
andresag 10:7943b5c1117a 186
rgrover1 0:28f095301cb2 187 while (true) {
andresag 10:7943b5c1117a 188 if (buttonState != IDLE) {
rgrover1 9:0f6951db24f1 189 buttonServicePtr->updateButtonState(buttonState);
0xf10 13:0f26a3fc1f32 190 if(buttonState == PRESSED) {led1=!1; setPir(0x01);}
0xf10 13:0f26a3fc1f32 191 if(buttonState == RELEASED) {led1=!0; setPir(0x00);}
rgrover1 9:0f6951db24f1 192 buttonState = IDLE;
rgrover1 9:0f6951db24f1 193 }
rgrover1 9:0f6951db24f1 194
rgrover1 0:28f095301cb2 195 ble.waitForEvent();
rgrover1 0:28f095301cb2 196 }
rgrover1 0:28f095301cb2 197 }