The firmware of the Grove Node

Dependencies:   BLE_API color_pixels mbed-src-nrf51822 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 #if DEBUG       // for Arch BLE
00027 #define LOG(...)        { printf(__VA_ARGS__); }
00028 #define BUTTON_DOWN     1
00029 #define LED_ON          1
00030 #define LED_OFF         0
00031 
00032 DigitalOut  blue(p30);
00033 DigitalOut  green(p17);
00034 InterruptIn button(p5);
00035 #else           // for Grove Node BLE
00036 #define LOG(...)
00037 #define BUTTON_DOWN     0
00038 #define LED_ON          0
00039 #define LED_OFF         1
00040 
00041 DigitalOut  blue(p18);
00042 DigitalOut  green(p17);
00043 InterruptIn button(p30);
00044 #endif
00045 
00046 Battery battery(p5);
00047 
00048 BLEDevice  ble;
00049 UARTService *uartServicePtr;
00050 Ticker ticker;
00051 
00052 volatile bool ble_is_connected = false;
00053 
00054 volatile bool button_event = false;
00055 
00056 const int MAX_ARGS = 8;
00057 char *argv[MAX_ARGS];
00058 
00059 static const uint8_t SIZEOF_TX_RX_BUFFER = 32;
00060 uint8_t rxPayload[SIZEOF_TX_RX_BUFFER] = {0,};
00061 
00062 extern "C" void power_on();
00063 extern "C" void power_off();
00064 
00065 extern void node_init();
00066 extern void node_tick();
00067 extern void node_parse(int argc, char *argv[]);
00068 
00069 int button_detect();
00070 
00071 void connectionCallback(Gap::Handle_t handle, const Gap::ConnectionParams_t *params)
00072 {
00073     LOG("Connected\n");
00074     ble_is_connected = true;
00075 }
00076 
00077 void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
00078 {
00079     LOG("Disconnected!\n");
00080     LOG("Restarting the advertising process\n");
00081     ble.startAdvertising();
00082     ble_is_connected = false;
00083 }
00084 
00085 void onDataWritten(const GattCharacteristicWriteCBParams *params)
00086 {
00087     if ((uartServicePtr != NULL) && (params->charHandle == uartServicePtr->getTXCharacteristicHandle())) {
00088         uint16_t bytesRead = params->len;
00089         LOG("received %u bytes\n\r", bytesRead);
00090         if (bytesRead < sizeof(rxPayload)) {
00091             memcpy(rxPayload, params->data, bytesRead);
00092             rxPayload[bytesRead] = '\0';
00093         }
00094         
00095         LOG("%s\n", (char *)rxPayload);
00096 
00097         char *piece = strtok((char *)rxPayload, " ");
00098         int argc = 0;
00099         while (piece && argc < MAX_ARGS) {
00100             argv[argc++] = piece;
00101             piece = strtok(0, " ");
00102         }
00103         
00104         if (argc > 0) {
00105            node_parse(argc, argv);
00106         }
00107         
00108     }
00109 }
00110 
00111 void tick(void)
00112 {
00113     node_tick();
00114 }
00115 
00116 void button_down(void)
00117 {
00118     button_event = true;
00119 }
00120 
00121 int main(void)
00122 {
00123     power_on();
00124     blue = LED_ON;
00125     green = LED_ON;
00126     
00127 #if BUTTON_DOWN
00128     button.mode(PullDown);
00129     button.rise(button_down);
00130 #else
00131     button.mode(PullUp);
00132     button.fall(button_down);
00133 #endif
00134 
00135     LOG("Initialising the nRF51822\n");
00136     ble.init();
00137     ble.onConnection(connectionCallback);
00138     ble.onDisconnection(disconnectionCallback);
00139     ble.onDataWritten(onDataWritten);
00140 
00141     /* setup advertising */
00142     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
00143     ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00144     ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
00145                                      (const uint8_t *)"NODE", sizeof("NODE"));
00146     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
00147                                      (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
00148 
00149     DFUService dfu(ble);
00150 
00151     UARTService uartService(ble);
00152     uartServicePtr = &uartService;
00153     
00154     ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
00155     ble.startAdvertising();
00156     
00157     node_init();
00158     ticker.attach(tick, 1);
00159 
00160     blue = LED_OFF;
00161     green = LED_OFF;
00162     
00163     while (true) {
00164         if (button_event) {
00165             int click;
00166             
00167             green = LED_ON;
00168             click = button_detect();
00169             green = LED_OFF;
00170             LOG("click type: %d\n\r", click);
00171             
00172             button_event = false;
00173             
00174             if (1 == click) {
00175             } else if (2 == click) {
00176                 //green = LED_ON;
00177             } else if (-1 == click) {
00178                 green = LED_OFF;
00179                 blue = LED_OFF;
00180                 while (BUTTON_DOWN == button.read()) {
00181                     
00182                 }
00183                 nrf_delay_us(3000);
00184                 
00185                 power_off();
00186             } else {
00187                 continue;
00188             }
00189 
00190         } else {
00191             ble.waitForEvent();
00192         }
00193     }
00194 }
00195 
00196 int button_detect(void)
00197 {
00198     int t = 0;
00199     
00200     while (1) {
00201         if (button.read() != BUTTON_DOWN) {
00202             if (t < 30) {
00203                 return 0;     // for anti shake
00204             } else {
00205                 break;
00206             }
00207         }
00208         
00209         if (t > 30000) {        // More than 3 seconds
00210             return -1;          // long click
00211         }
00212         
00213         t++;
00214         nrf_delay_us(100);
00215     }
00216     
00217     if (t > 4000) {             // More than 0.4 seconds
00218         return 1;               // single click
00219     }
00220     
00221     while (true) {
00222         if (button.read() == BUTTON_DOWN) {
00223             nrf_delay_us(1000);
00224             if (button.read() == BUTTON_DOWN) {
00225                 return 2;      // double click
00226             }
00227             
00228             t += 10;
00229         }
00230         
00231         if (t > 4000) {
00232             return 1;          // The interval of double click should less than 0.4 seconds, so it's single click
00233         }
00234         
00235         t++;
00236         nrf_delay_us(100);
00237     }
00238 }