The firmware of the Grove Node
Dependencies: BLE_API color_pixels mbed-src-nrf51822 nRF51822
Fork of BLE_LoopbackUART by
Diff: main.cpp
- Revision:
- 9:84cb66d0375d
- Parent:
- 6:e0fc9072e853
- Child:
- 10:f34ff4e47741
--- a/main.cpp Tue Sep 30 02:20:59 2014 +0000 +++ b/main.cpp Thu Nov 06 02:22:01 2014 +0000 @@ -16,27 +16,60 @@ #include "mbed.h" #include "BLEDevice.h" - +#include "DFUService.h" #include "UARTService.h" +#include "nrf_delay.h" +#include "battery.h" -#define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console; - * it will have an impact on code-size and power consumption. */ +#define DEBUG 0 + +#if DEBUG // for Arch BLE +#define LOG(...) { printf(__VA_ARGS__); } +#define BUTTON_DOWN 1 +#define LED_ON 1 +#define LED_OFF 0 -#if NEED_CONSOLE_OUTPUT -#define DEBUG(...) { printf(__VA_ARGS__); } -#else -#define DEBUG(...) /* nothing */ -#endif /* #if NEED_CONSOLE_OUTPUT */ +DigitalOut blue(p30); +DigitalOut green(p17); +InterruptIn button(p5); +#else // for Grove Node BLE +#define LOG(...) +#define BUTTON_DOWN 0 +#define LED_ON 0 +#define LED_OFF 1 + +DigitalOut blue(p18); +DigitalOut green(p17); +InterruptIn button(p30); +#endif + +Battery battery(p5); BLEDevice ble; -DigitalOut led1(LED1); +UARTService *uartServicePtr; +Ticker ticker; + +volatile bool button_event = false; + +const int MAX_ARGS = 8; +char *argv[MAX_ARGS]; -UARTService *uartServicePtr; +static const uint8_t SIZEOF_TX_RX_BUFFER = 32; +uint8_t rxPayload[SIZEOF_TX_RX_BUFFER] = {0,}; + +extern "C" void power_on(); +extern "C" void power_off(); + +extern void node_init(); +extern void node_tick(); +extern void node_parse(int argc, char *argv[]); + +int button_detect(); void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) { - DEBUG("Disconnected!\n\r"); - DEBUG("Restarting the advertising process\n\r"); + LOG("Disconnected!\n"); + LOG("Restarting the advertising process\n"); ble.startAdvertising(); } @@ -44,23 +77,53 @@ { if ((uartServicePtr != NULL) && (params->charHandle == uartServicePtr->getTXCharacteristicHandle())) { uint16_t bytesRead = params->len; - DEBUG("received %u bytes\n\r", bytesRead); - ble.updateCharacteristicValue(uartServicePtr->getRXCharacteristicHandle(), params->data, bytesRead); + LOG("received %u bytes\n\r", bytesRead); + if (bytesRead < sizeof(rxPayload)) { + memcpy(rxPayload, params->data, bytesRead); + rxPayload[bytesRead] = '\0'; + } + + LOG("%s\n", (char *)rxPayload); + + char *piece = strtok((char *)rxPayload, " "); + int argc = 0; + while (piece && argc < MAX_ARGS) { + argv[argc++] = piece; + piece = strtok(0, " "); + } + + if (argc > 0) { + node_parse(argc, argv); + } + } } -void periodicCallback(void) +void tick(void) { - led1 = !led1; + node_tick(); +} + +void button_down(void) +{ + button_event = true; } int main(void) { - led1 = 1; - Ticker ticker; - ticker.attach(periodicCallback, 1); + power_on(); + blue = LED_ON; + green = LED_ON; + +#if BUTTON_DOWN + button.mode(PullDown); + button.rise(button_down); +#else + button.mode(PullUp); + button.fall(button_down); +#endif - DEBUG("Initialising the nRF51822\n\r"); + LOG("Initialising the nRF51822\n"); ble.init(); ble.onDisconnection(disconnectionCallback); ble.onDataWritten(onDataWritten); @@ -69,17 +132,97 @@ ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED); ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME, - (const uint8_t *)"BLE UART", sizeof("BLE UART") - 1); + (const uint8_t *)"NODE", sizeof("NODE")); ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); - ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ - ble.startAdvertising(); + DFUService dfu(ble); UARTService uartService(ble); uartServicePtr = &uartService; + + ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ + ble.startAdvertising(); + + node_init(); + ticker.attach(tick, 1); + blue = LED_OFF; + green = LED_OFF; + while (true) { - ble.waitForEvent(); + if (button_event) { + int click; + + green = LED_ON; + click = button_detect(); + green = LED_OFF; + LOG("click type: %d\n\r", click); + + button_event = false; + + if (1 == click) { + } else if (2 == click) { + //green = LED_ON; + } else if (-1 == click) { + green = LED_OFF; + blue = LED_OFF; + while (BUTTON_DOWN == button.read()) { + + } + nrf_delay_us(3000); + + power_off(); + } else { + continue; + } + + } else { + ble.waitForEvent(); + } } } + +int button_detect(void) +{ + int t = 0; + + while (1) { + if (button.read() != BUTTON_DOWN) { + if (t < 30) { + return 0; // for anti shake + } else { + break; + } + } + + if (t > 30000) { // More than 3 seconds + return -1; // long click + } + + t++; + nrf_delay_us(100); + } + + if (t > 4000) { // More than 0.4 seconds + return 1; // single click + } + + while (true) { + if (button.read() == BUTTON_DOWN) { + nrf_delay_us(1000); + if (button.read() == BUTTON_DOWN) { + return 2; // double click + } + + t += 10; + } + + if (t > 4000) { + return 1; // The interval of double click should less than 0.4 seconds, so it's single click + } + + t++; + nrf_delay_us(100); + } +}