Test code for Grove Node BLE

Dependencies:   BLE_API nRF51822

Fork of BLE_LoopbackUART by Bluetooth Low Energy

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "mbed.h"
00018 #include "BLEDevice.h"
00019 #include "DFUService.h"
00020 #include "UARTService.h"
00021 #include "nrf_delay.h"
00022 #include "battery.h"
00023 
00024 #define DEBUG   0
00025 
00026 
00027 #define LOG(...)
00028 #define BUTTON_DOWN     0
00029 #define LED_ON          0
00030 #define LED_OFF         1
00031 
00032 DigitalOut  blue(p18);
00033 DigitalOut  green(p17);
00034 InterruptIn button(p30);
00035 Battery     battery(p5);
00036 AnalogIn    vcc(p6);
00037 
00038 BLEDevice  ble;
00039 UARTService *uartServicePtr;
00040 Ticker ticker;
00041 
00042 BusOut outputGrove(p3, p4);
00043 BusIn  inputGrove(p1, p2);
00044 BusIn  charge(p29, p28);
00045 
00046 volatile bool button_event = false;
00047 
00048 static const uint8_t SIZEOF_TX_RX_BUFFER = 32;
00049 uint8_t rxPayload[SIZEOF_TX_RX_BUFFER] = {0,};
00050 
00051 extern "C" void power_on();
00052 extern "C" void power_off();
00053 
00054 
00055 int button_detect();
00056 
00057 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
00058 {
00059     LOG("Disconnected!\n");
00060     LOG("Restarting the advertising process\n");
00061     ble.startAdvertising();
00062 }
00063 
00064 void onDataWritten(const GattCharacteristicWriteCBParams *params)
00065 {
00066     if ((uartServicePtr != NULL) && (params->charHandle == uartServicePtr->getTXCharacteristicHandle())) {
00067         uint16_t bytesRead = params->len;
00068         LOG("received %u bytes\n\r", bytesRead);
00069         if (bytesRead < sizeof(rxPayload)) {
00070             memcpy(rxPayload, params->data, bytesRead);
00071             rxPayload[bytesRead] = '\0';
00072         }
00073         
00074         LOG("%s\n", (char *)rxPayload);
00075         
00076     }
00077 }
00078 
00079 void tick(void)
00080 {
00081     green = !green;
00082     
00083     static uint8_t output = 0x01;
00084     uint8_t input;
00085     
00086     outputGrove = output;
00087     
00088     uartServicePtr->printf("battery:%3.2fV\n", battery.read());
00089     
00090     uartServicePtr->printf("vcc:%3.2fV\n", vcc.read() * 1.2 * 12.2 / 2.2);
00091     
00092     
00093     input = inputGrove;
00094     uartServicePtr->printf("o->i:%d->%d\n", output, input);
00095     
00096     output = 3 - output;
00097     
00098     uint8_t chargeStatus = charge;
00099     uartServicePtr->printf("charge:%d\n", chargeStatus);
00100 }
00101 
00102 void button_down(void)
00103 {
00104     button_event = true;
00105 }
00106 
00107 int main(void)
00108 {
00109     power_on();
00110     blue = LED_ON;
00111     green = LED_ON;
00112     
00113 #if BUTTON_DOWN
00114     button.mode(PullDown);
00115     button.rise(button_down);
00116 #else
00117     button.mode(PullUp);
00118     button.fall(button_down);
00119 #endif
00120 
00121     LOG("Initialising the nRF51822\n");
00122     ble.init();
00123     ble.onDisconnection(disconnectionCallback);
00124     ble.onDataWritten(onDataWritten);
00125 
00126     /* setup advertising */
00127     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
00128     ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00129     ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
00130                                      (const uint8_t *)"NODE TEST", sizeof("NODE TEST"));
00131     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
00132                                      (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
00133 
00134     //DFUService dfu(ble);
00135 
00136     UARTService uartService(ble);
00137     uartService.retargetStdout();
00138     uartServicePtr = &uartService;
00139     
00140     ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
00141     ble.startAdvertising();
00142     
00143     blue = LED_OFF;
00144     
00145     ticker.attach(tick, 3);
00146 
00147     while (true) {
00148         if (button_event) {
00149             int click;
00150             
00151             blue = LED_ON;
00152             click = button_detect();
00153             blue = LED_OFF;
00154             LOG("click type: %d\n\r", click);
00155             
00156             button_event = false;
00157             
00158             if (1 == click) {
00159                 blue = !blue;
00160             } else if (2 == click) {
00161                 //green = LED_ON;
00162             } else if (-1 == click) {
00163                 ticker.detach();
00164                 green = LED_OFF;
00165                 blue = LED_OFF;
00166                 while (BUTTON_DOWN == button.read()) {
00167                     
00168                 }
00169                 nrf_delay_us(3000);
00170                 
00171                 power_off();
00172             } else {
00173                 continue;
00174             }
00175 
00176         } else {
00177             ble.waitForEvent();
00178         }
00179     }
00180 }
00181 
00182 int button_detect(void)
00183 {
00184     int t = 0;
00185     
00186     while (1) {
00187         if (button.read() != BUTTON_DOWN) {
00188             if (t < 30) {
00189                 return 0;     // for anti shake
00190             } else {
00191                 break;
00192             }
00193         }
00194         
00195         if (t > 30000) {        // More than 3 seconds
00196             return -1;          // long click
00197         }
00198         
00199         t++;
00200         nrf_delay_us(100);
00201     }
00202     
00203     if (t > 4000) {             // More than 0.4 seconds
00204         return 1;               // single click
00205     }
00206     
00207     while (true) {
00208         if (button.read() == BUTTON_DOWN) {
00209             nrf_delay_us(1000);
00210             if (button.read() == BUTTON_DOWN) {
00211                 return 2;      // double click
00212             }
00213             
00214             t += 10;
00215         }
00216         
00217         if (t > 4000) {
00218             return 1;          // The interval of double click should less than 0.4 seconds, so it's single click
00219         }
00220         
00221         t++;
00222         nrf_delay_us(100);
00223     }
00224 }