to cai
Dependencies: BLE_API nRF51822
Fork of BLE_NODE_TEST by
main.cpp@9:05f0b5a3a70a, 2014-10-29 (annotated)
- Committer:
- yihui
- Date:
- Wed Oct 29 06:23:47 2014 +0000
- Revision:
- 9:05f0b5a3a70a
- Parent:
- 6:e0fc9072e853
- Child:
- 10:808a025c9b4f
- Child:
- 11:22480ac31879
initial
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yihui | 0:e910d9bb040f | 1 | /* mbed Microcontroller Library |
yihui | 0:e910d9bb040f | 2 | * Copyright (c) 2006-2013 ARM Limited |
yihui | 0:e910d9bb040f | 3 | * |
yihui | 0:e910d9bb040f | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
yihui | 0:e910d9bb040f | 5 | * you may not use this file except in compliance with the License. |
yihui | 0:e910d9bb040f | 6 | * You may obtain a copy of the License at |
yihui | 0:e910d9bb040f | 7 | * |
yihui | 0:e910d9bb040f | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
yihui | 0:e910d9bb040f | 9 | * |
yihui | 0:e910d9bb040f | 10 | * Unless required by applicable law or agreed to in writing, software |
yihui | 0:e910d9bb040f | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
yihui | 0:e910d9bb040f | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
yihui | 0:e910d9bb040f | 13 | * See the License for the specific language governing permissions and |
yihui | 0:e910d9bb040f | 14 | * limitations under the License. |
yihui | 0:e910d9bb040f | 15 | */ |
yihui | 0:e910d9bb040f | 16 | |
yihui | 0:e910d9bb040f | 17 | #include "mbed.h" |
Rohit Grover |
2:e060367b9024 | 18 | #include "BLEDevice.h" |
yihui | 9:05f0b5a3a70a | 19 | #include "DFUService.h" |
rgrover1 | 6:e0fc9072e853 | 20 | #include "UARTService.h" |
yihui | 9:05f0b5a3a70a | 21 | #include "nrf_delay.h" |
yihui | 9:05f0b5a3a70a | 22 | #include "battery.h" |
yihui | 0:e910d9bb040f | 23 | |
yihui | 9:05f0b5a3a70a | 24 | #define DEBUG 0 |
yihui | 9:05f0b5a3a70a | 25 | |
yihui | 0:e910d9bb040f | 26 | |
yihui | 9:05f0b5a3a70a | 27 | #define LOG(...) |
yihui | 9:05f0b5a3a70a | 28 | #define BUTTON_DOWN 0 |
yihui | 9:05f0b5a3a70a | 29 | #define LED_ON 0 |
yihui | 9:05f0b5a3a70a | 30 | #define LED_OFF 1 |
yihui | 9:05f0b5a3a70a | 31 | |
yihui | 9:05f0b5a3a70a | 32 | DigitalOut blue(p18); |
yihui | 9:05f0b5a3a70a | 33 | DigitalOut green(p17); |
yihui | 9:05f0b5a3a70a | 34 | InterruptIn button(p30); |
yihui | 9:05f0b5a3a70a | 35 | Battery battery(p5); |
yihui | 0:e910d9bb040f | 36 | |
Rohit Grover |
2:e060367b9024 | 37 | BLEDevice ble; |
yihui | 9:05f0b5a3a70a | 38 | UARTService *uartServicePtr; |
yihui | 9:05f0b5a3a70a | 39 | Ticker ticker; |
yihui | 9:05f0b5a3a70a | 40 | |
yihui | 9:05f0b5a3a70a | 41 | BusOut outputGrove(p3, p4); |
yihui | 9:05f0b5a3a70a | 42 | BusIn inputGrove(p1, p2); |
yihui | 9:05f0b5a3a70a | 43 | BusIn charge(p6, p7); |
yihui | 9:05f0b5a3a70a | 44 | |
yihui | 9:05f0b5a3a70a | 45 | volatile bool button_event = false; |
yihui | 0:e910d9bb040f | 46 | |
yihui | 9:05f0b5a3a70a | 47 | static const uint8_t SIZEOF_TX_RX_BUFFER = 32; |
yihui | 9:05f0b5a3a70a | 48 | uint8_t rxPayload[SIZEOF_TX_RX_BUFFER] = {0,}; |
yihui | 9:05f0b5a3a70a | 49 | |
yihui | 9:05f0b5a3a70a | 50 | extern "C" void power_on(); |
yihui | 9:05f0b5a3a70a | 51 | extern "C" void power_off(); |
yihui | 9:05f0b5a3a70a | 52 | |
yihui | 9:05f0b5a3a70a | 53 | |
yihui | 9:05f0b5a3a70a | 54 | int button_detect(); |
yihui | 0:e910d9bb040f | 55 | |
rgrover1 | 5:4bc41267a03a | 56 | void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) |
yihui | 0:e910d9bb040f | 57 | { |
yihui | 9:05f0b5a3a70a | 58 | LOG("Disconnected!\n"); |
yihui | 9:05f0b5a3a70a | 59 | LOG("Restarting the advertising process\n"); |
Rohit Grover |
2:e060367b9024 | 60 | ble.startAdvertising(); |
Rohit Grover |
2:e060367b9024 | 61 | } |
yihui | 0:e910d9bb040f | 62 | |
rgrover1 | 6:e0fc9072e853 | 63 | void onDataWritten(const GattCharacteristicWriteCBParams *params) |
yihui | 0:e910d9bb040f | 64 | { |
rgrover1 | 6:e0fc9072e853 | 65 | if ((uartServicePtr != NULL) && (params->charHandle == uartServicePtr->getTXCharacteristicHandle())) { |
rgrover1 | 5:4bc41267a03a | 66 | uint16_t bytesRead = params->len; |
yihui | 9:05f0b5a3a70a | 67 | LOG("received %u bytes\n\r", bytesRead); |
yihui | 9:05f0b5a3a70a | 68 | if (bytesRead < sizeof(rxPayload)) { |
yihui | 9:05f0b5a3a70a | 69 | memcpy(rxPayload, params->data, bytesRead); |
yihui | 9:05f0b5a3a70a | 70 | rxPayload[bytesRead] = '\0'; |
yihui | 9:05f0b5a3a70a | 71 | } |
yihui | 9:05f0b5a3a70a | 72 | |
yihui | 9:05f0b5a3a70a | 73 | LOG("%s\n", (char *)rxPayload); |
yihui | 9:05f0b5a3a70a | 74 | |
yihui | 0:e910d9bb040f | 75 | } |
Rohit Grover |
2:e060367b9024 | 76 | } |
yihui | 0:e910d9bb040f | 77 | |
yihui | 9:05f0b5a3a70a | 78 | void tick(void) |
Rohit Grover |
2:e060367b9024 | 79 | { |
yihui | 9:05f0b5a3a70a | 80 | green = !green; |
yihui | 9:05f0b5a3a70a | 81 | |
yihui | 9:05f0b5a3a70a | 82 | static uint8_t output = 0x01; |
yihui | 9:05f0b5a3a70a | 83 | uint8_t input; |
yihui | 9:05f0b5a3a70a | 84 | |
yihui | 9:05f0b5a3a70a | 85 | outputGrove = output; |
yihui | 9:05f0b5a3a70a | 86 | |
yihui | 9:05f0b5a3a70a | 87 | button_event = true; |
yihui | 9:05f0b5a3a70a | 88 | uartServicePtr->printf("battery:%3.2fV\n", battery.read()); |
yihui | 9:05f0b5a3a70a | 89 | |
yihui | 9:05f0b5a3a70a | 90 | |
yihui | 9:05f0b5a3a70a | 91 | input = inputGrove; |
yihui | 9:05f0b5a3a70a | 92 | uartServicePtr->printf("o->i:%d->%d\n", output, input); |
yihui | 9:05f0b5a3a70a | 93 | |
yihui | 9:05f0b5a3a70a | 94 | output = 3 - output; |
yihui | 9:05f0b5a3a70a | 95 | |
yihui | 9:05f0b5a3a70a | 96 | uint8_t chargeStatus = charge; |
yihui | 9:05f0b5a3a70a | 97 | uartServicePtr->printf("charge:%d\n", chargeStatus); |
yihui | 9:05f0b5a3a70a | 98 | } |
yihui | 9:05f0b5a3a70a | 99 | |
yihui | 9:05f0b5a3a70a | 100 | void button_down(void) |
yihui | 9:05f0b5a3a70a | 101 | { |
yihui | 9:05f0b5a3a70a | 102 | button_event = true; |
Rohit Grover |
2:e060367b9024 | 103 | } |
yihui | 0:e910d9bb040f | 104 | |
yihui | 0:e910d9bb040f | 105 | int main(void) |
yihui | 0:e910d9bb040f | 106 | { |
yihui | 9:05f0b5a3a70a | 107 | power_on(); |
yihui | 9:05f0b5a3a70a | 108 | blue = LED_ON; |
yihui | 9:05f0b5a3a70a | 109 | green = LED_ON; |
yihui | 9:05f0b5a3a70a | 110 | |
yihui | 9:05f0b5a3a70a | 111 | #if BUTTON_DOWN |
yihui | 9:05f0b5a3a70a | 112 | button.mode(PullDown); |
yihui | 9:05f0b5a3a70a | 113 | button.rise(button_down); |
yihui | 9:05f0b5a3a70a | 114 | #else |
yihui | 9:05f0b5a3a70a | 115 | button.mode(PullUp); |
yihui | 9:05f0b5a3a70a | 116 | button.fall(button_down); |
yihui | 9:05f0b5a3a70a | 117 | #endif |
yihui | 0:e910d9bb040f | 118 | |
yihui | 9:05f0b5a3a70a | 119 | LOG("Initialising the nRF51822\n"); |
Rohit Grover |
2:e060367b9024 | 120 | ble.init(); |
Rohit Grover |
2:e060367b9024 | 121 | ble.onDisconnection(disconnectionCallback); |
Rohit Grover |
2:e060367b9024 | 122 | ble.onDataWritten(onDataWritten); |
yihui | 0:e910d9bb040f | 123 | |
Rohit Grover |
2:e060367b9024 | 124 | /* setup advertising */ |
Rohit Grover |
2:e060367b9024 | 125 | ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); |
Rohit Grover |
2:e060367b9024 | 126 | ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
Rohit Grover |
2:e060367b9024 | 127 | ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, |
yihui | 9:05f0b5a3a70a | 128 | (const uint8_t *)"NODE TEST", sizeof("NODE TEST")); |
Rohit Grover |
2:e060367b9024 | 129 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, |
rgrover1 | 6:e0fc9072e853 | 130 | (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); |
yihui | 0:e910d9bb040f | 131 | |
yihui | 9:05f0b5a3a70a | 132 | //DFUService dfu(ble); |
yihui | 0:e910d9bb040f | 133 | |
rgrover1 | 6:e0fc9072e853 | 134 | UARTService uartService(ble); |
yihui | 9:05f0b5a3a70a | 135 | uartService.retargetStdout(); |
rgrover1 | 6:e0fc9072e853 | 136 | uartServicePtr = &uartService; |
yihui | 9:05f0b5a3a70a | 137 | |
yihui | 9:05f0b5a3a70a | 138 | ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ |
yihui | 9:05f0b5a3a70a | 139 | ble.startAdvertising(); |
yihui | 9:05f0b5a3a70a | 140 | |
yihui | 9:05f0b5a3a70a | 141 | blue = LED_OFF; |
yihui | 9:05f0b5a3a70a | 142 | |
yihui | 9:05f0b5a3a70a | 143 | ticker.attach(tick, 3); |
yihui | 0:e910d9bb040f | 144 | |
Rohit Grover |
2:e060367b9024 | 145 | while (true) { |
yihui | 9:05f0b5a3a70a | 146 | if (button_event) { |
yihui | 9:05f0b5a3a70a | 147 | int click; |
yihui | 9:05f0b5a3a70a | 148 | |
yihui | 9:05f0b5a3a70a | 149 | blue = LED_ON; |
yihui | 9:05f0b5a3a70a | 150 | click = button_detect(); |
yihui | 9:05f0b5a3a70a | 151 | blue = LED_OFF; |
yihui | 9:05f0b5a3a70a | 152 | LOG("click type: %d\n\r", click); |
yihui | 9:05f0b5a3a70a | 153 | |
yihui | 9:05f0b5a3a70a | 154 | button_event = false; |
yihui | 9:05f0b5a3a70a | 155 | |
yihui | 9:05f0b5a3a70a | 156 | if (1 == click) { |
yihui | 9:05f0b5a3a70a | 157 | blue = !blue; |
yihui | 9:05f0b5a3a70a | 158 | } else if (2 == click) { |
yihui | 9:05f0b5a3a70a | 159 | //green = LED_ON; |
yihui | 9:05f0b5a3a70a | 160 | } else if (-1 == click) { |
yihui | 9:05f0b5a3a70a | 161 | ticker.detach(); |
yihui | 9:05f0b5a3a70a | 162 | green = LED_OFF; |
yihui | 9:05f0b5a3a70a | 163 | blue = LED_OFF; |
yihui | 9:05f0b5a3a70a | 164 | while (BUTTON_DOWN == button.read()) { |
yihui | 9:05f0b5a3a70a | 165 | |
yihui | 9:05f0b5a3a70a | 166 | } |
yihui | 9:05f0b5a3a70a | 167 | nrf_delay_us(3000); |
yihui | 9:05f0b5a3a70a | 168 | |
yihui | 9:05f0b5a3a70a | 169 | power_off(); |
yihui | 9:05f0b5a3a70a | 170 | } else { |
yihui | 9:05f0b5a3a70a | 171 | continue; |
yihui | 9:05f0b5a3a70a | 172 | } |
yihui | 9:05f0b5a3a70a | 173 | |
yihui | 9:05f0b5a3a70a | 174 | } else { |
yihui | 9:05f0b5a3a70a | 175 | ble.waitForEvent(); |
yihui | 9:05f0b5a3a70a | 176 | } |
yihui | 0:e910d9bb040f | 177 | } |
yihui | 0:e910d9bb040f | 178 | } |
yihui | 9:05f0b5a3a70a | 179 | |
yihui | 9:05f0b5a3a70a | 180 | int button_detect(void) |
yihui | 9:05f0b5a3a70a | 181 | { |
yihui | 9:05f0b5a3a70a | 182 | int t = 0; |
yihui | 9:05f0b5a3a70a | 183 | |
yihui | 9:05f0b5a3a70a | 184 | while (1) { |
yihui | 9:05f0b5a3a70a | 185 | if (button.read() != BUTTON_DOWN) { |
yihui | 9:05f0b5a3a70a | 186 | if (t < 30) { |
yihui | 9:05f0b5a3a70a | 187 | return 0; // for anti shake |
yihui | 9:05f0b5a3a70a | 188 | } else { |
yihui | 9:05f0b5a3a70a | 189 | break; |
yihui | 9:05f0b5a3a70a | 190 | } |
yihui | 9:05f0b5a3a70a | 191 | } |
yihui | 9:05f0b5a3a70a | 192 | |
yihui | 9:05f0b5a3a70a | 193 | if (t > 30000) { // More than 3 seconds |
yihui | 9:05f0b5a3a70a | 194 | return -1; // long click |
yihui | 9:05f0b5a3a70a | 195 | } |
yihui | 9:05f0b5a3a70a | 196 | |
yihui | 9:05f0b5a3a70a | 197 | t++; |
yihui | 9:05f0b5a3a70a | 198 | nrf_delay_us(100); |
yihui | 9:05f0b5a3a70a | 199 | } |
yihui | 9:05f0b5a3a70a | 200 | |
yihui | 9:05f0b5a3a70a | 201 | if (t > 4000) { // More than 0.4 seconds |
yihui | 9:05f0b5a3a70a | 202 | return 1; // single click |
yihui | 9:05f0b5a3a70a | 203 | } |
yihui | 9:05f0b5a3a70a | 204 | |
yihui | 9:05f0b5a3a70a | 205 | while (true) { |
yihui | 9:05f0b5a3a70a | 206 | if (button.read() == BUTTON_DOWN) { |
yihui | 9:05f0b5a3a70a | 207 | nrf_delay_us(1000); |
yihui | 9:05f0b5a3a70a | 208 | if (button.read() == BUTTON_DOWN) { |
yihui | 9:05f0b5a3a70a | 209 | return 2; // double click |
yihui | 9:05f0b5a3a70a | 210 | } |
yihui | 9:05f0b5a3a70a | 211 | |
yihui | 9:05f0b5a3a70a | 212 | t += 10; |
yihui | 9:05f0b5a3a70a | 213 | } |
yihui | 9:05f0b5a3a70a | 214 | |
yihui | 9:05f0b5a3a70a | 215 | if (t > 4000) { |
yihui | 9:05f0b5a3a70a | 216 | return 1; // The interval of double click should less than 0.4 seconds, so it's single click |
yihui | 9:05f0b5a3a70a | 217 | } |
yihui | 9:05f0b5a3a70a | 218 | |
yihui | 9:05f0b5a3a70a | 219 | t++; |
yihui | 9:05f0b5a3a70a | 220 | nrf_delay_us(100); |
yihui | 9:05f0b5a3a70a | 221 | } |
yihui | 9:05f0b5a3a70a | 222 | } |