Pair function with BLE_Paired_Client. If missing BLE_Paired_Server side, Client side of BZ will ON for notice.

Dependencies:   BLE_API mbed nRF51822 nRF51_LowPwr nRF51_Vdd

Fork of BLE_GATT_Example by Bluetooth Low Energy

Revision:
23:f826de46d652
Parent:
22:406127954d1f
Child:
24:391e76b51b21
--- a/main.cpp	Mon Nov 09 17:08:47 2015 +0000
+++ b/main.cpp	Wed Jun 01 12:37:52 2016 +0000
@@ -1,104 +1,229 @@
+/*
+ *  /////// Tested on Switch Science mbed TY51822r3 ///////
+ *  Modified by Kenji Arai
+ *      http://www.page.sannet.ne.jp/kenjia/index.html
+ *      http://mbed.org/users/kenjiArai/
+ *
+ *      Started:  April     5th, 2016
+ *      Revised:  June      1st, 2016
+ *
+ *  Original program:
+ *      BLE_GATT_Example
+ *      https://developer.mbed.org/teams/Bluetooth-Low-Energy/code/BLE_GATT_Example/
+ *  Tested Device:
+ *      BLE_Paired_Client
+ *
+ */
+
+//  Include ---------------------------------------------------------------------------------------
 #include "mbed.h"
-#include "ble/BLE.h"
+#include "BLE.h"
+#include "nRF51_Vdd.h"
+#include "nRF51_lowpwr.h"
 
-DigitalOut led(LED1, 1);
-uint16_t customServiceUUID  = 0xA000;
-uint16_t readCharUUID       = 0xA001;
-uint16_t writeCharUUID      = 0xA002;
+//  Definition ------------------------------------------------------------------------------------
+//  Before using this function, please specify your program are used following functions or not.
+#define    USE_DEVICE_STDIO_MESSAGES       0   // printf
+#define    USE_DEVICE_SERIAL               0   // Serial or DEBUG & etc.
+#define    USE_DEVICE_I2C                  1   // Sensors with I2C, LCD, EEPROM, Driver chips & etc.
+#define    USE_DEVICE_SPI                  0   // Sensors with SOI, LCD, EEPROM, Driver chips & etc.
+#define    USE_DEVICE_SPISLAVE             0   // Communication with master vis SPI
+#define    USE_DEVICE_PWMOUT               0   // PWM duty output, Serve & etc.
+#define    USE_DEVICE_ANALOGIN             0   // Analog adc
+
+#define    SHOW_MY_MAC                     0
+
+#if USE_DEVICE_STDIO_MESSAGES
+#define DEBUG(...) { printf(__VA_ARGS__); }
+#else
+#define DEBUG(...)
+#endif
+
+//  Object ----------------------------------------------------------------------------------------
+Ticker      ticker;
+InterruptIn sw(P0_0);
+nRF51_Vdd   vdd(3.6f, 1.8f, ONLY4VDD);
 
-const static char     DEVICE_NAME[]        = "ChangeMe!!"; // change this
-static const uint16_t uuid16_list[]        = {0xFFFF}; //Custom UUID, FFFF is reserved for development
+//  ROM / Constant data ---------------------------------------------------------------------------
+const static char     DEVICE_NAME[]     = "JH1PJL";
+static const uint16_t uuid16_list[]     = {0xFFFF};//Custom UUID, FFFF is reserved for development
+const uint16_t        customServiceUUID = 0xA000;
+const uint16_t        readCharUUID      = 0xA001;
+const uint16_t        writeCharUUID     = 0xA002;
+const int8_t          tx_power_level[8] = 
+                        {
+                            RADIO_TXPOWER_TXPOWER_Pos4dBm,      // 0
+                            RADIO_TXPOWER_TXPOWER_0dBm,         // 1
+                            RADIO_TXPOWER_TXPOWER_Neg4dBm,      // 2
+                            RADIO_TXPOWER_TXPOWER_Neg8dBm,      // 3
+                            RADIO_TXPOWER_TXPOWER_Neg12dBm,     // 4
+                            RADIO_TXPOWER_TXPOWER_Neg16dBm,     // 5
+                            RADIO_TXPOWER_TXPOWER_Neg20dBm,     // 6
+                            RADIO_TXPOWER_TXPOWER_Neg30dBm      // 7
+                        };
 
-/* Set Up custom Characteristics */
-static uint8_t readValue[10] = {0};
-ReadOnlyArrayGattCharacteristic<uint8_t, sizeof(readValue)> readChar(readCharUUID, readValue);
+const nRF51_LOWPWR_TypeDef  lowpwr_table = 
+                        {
+                        #if USE_DEVICE_STDIO_MESSAGES 
+                            true,
+                        #else
+                            false,
+                        #endif
+                        #if USE_DEVICE_SERIAL
+                            true,
+                        #else
+                            false,
+                        #endif
+                        #if USE_DEVICE_I2C
+                            true,
+                        #else
+                            false,
+                        #endif
+                        #if USE_DEVICE_SPI
+                            true,
+                        #else
+                            false,
+                        #endif
+                        #if USE_DEVICE_SPISLAVE
+                            true,
+                        #else
+                            false,
+                        #endif
+                        #if USE_DEVICE_PWMOUT
+                            true,
+                        #else
+                            false,
+                        #endif
+                        #if USE_DEVICE_ANALOGIN
+                            true
+                        #else
+                            false
+                        #endif
+                        };
 
-static uint8_t writeValue[10] = {0};
+//  RAM -------------------------------------------------------------------------------------------
+volatile bool   triggerSensorPolling    = false;
+static uint8_t  readValue[10]           = {0};
+static uint8_t  writeValue[10]          = {0};
+ReadOnlyArrayGattCharacteristic<uint8_t, sizeof(readValue)> readChar(readCharUUID, readValue);
 WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(writeCharUUID, writeValue);
-
 /* Set up custom service */
 GattCharacteristic *characteristics[] = {&readChar, &writeChar};
-GattService        customService(customServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
+GattService     customService(
+                 customServiceUUID,
+                 characteristics,
+                 sizeof(characteristics) / sizeof(GattCharacteristic *)
+                );
 
+//  Function prototypes ---------------------------------------------------------------------------
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *);
+void periodicCallback(void);
+void buttonPressedCallback(void);
+void buttonReleasedCallback(void);
+void connectionCallback(const Gap::ConnectionCallbackParams_t *params);
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params);
+
+//-------------------------------------------------------------------------------------------------
+//  Control Program
+//-------------------------------------------------------------------------------------------------
+void reset_cpu(){
+    NVIC_SystemReset();     // System RESET!!
+}
 
-/*
- *  Restart advertising when phone app disconnects
-*/
-void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *)
-{
+int main(void){
+    uint8_t     n = 0;
+    uint8_t     bf_send_to_client[10];
+    uint16_t    len_send;
+
+    LowPwr set_lowpwr(&lowpwr_table);
+    sw.fall(&reset_cpu);
+    ticker.attach(periodicCallback, 5);
+    BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
+    ble.init(bleInitComplete);
+    while (ble.hasInitialized()  == false){ ;}
+    while (true){
+        if (triggerSensorPolling){  //  Send Chip Vdd value
+            triggerSensorPolling = false;
+            if (++n >= 100){ n = 0;}
+            sprintf((char *)bf_send_to_client,"%02u %3.2f[V]", n, vdd.read_real_value());
+            len_send = strlen((const char *)bf_send_to_client);
+            ble.gattServer().write(readChar.getValueHandle(), bf_send_to_client, len_send);
+        }
+        ble.waitForEvent();     // Save power
+    }
+}
+
+void periodicCallback(void){
+    triggerSensorPolling = true;
+}
+
+void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *){
     BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising();
 }
 
-/*
- *  Handle writes to writeCharacteristic
-*/
-void writeCharCallback(const GattWriteCallbackParams *params)
-{
-    /* Check to see what characteristic was written, by handle */
-    if(params->handle == writeChar.getValueHandle()) {
-        /* toggle LED if only 1 byte is written */
-        if(params->len == 1) {
-            led = params->data[0];
-            (params->data[0] == 0x00) ? printf("led on\n\r") : printf("led off\n\r"); // print led toggle
-        }
-        /* Print the data if more than 1 byte is written */
-        else {
-            printf("Data received: length = %d, data = 0x",params->len);
-            for(int x=0; x < params->len; x++) {
-                printf("%x", params->data[x]);
-            }
-            printf("\n\r");
-        }
-        /* Update the readChar with the value of writeChar */
-        BLE::Instance(BLE::DEFAULT_INSTANCE).gattServer().write(readChar.getValueHandle(), params->data, params->len);
-    }
-}
-/*
- * Initialization callback
- */
-void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
-{
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){
     BLE &ble          = params->ble;
     ble_error_t error = params->error;
     
-    if (error != BLE_ERROR_NONE) {
-        return;
-    }
-
+    if (error != BLE_ERROR_NONE) { return;}
+#if SHOW_MY_MAC
+    Gap::AddressType_t my_mac_type;
+    Gap::Address_t   my_mac;
+    ble.gap().getAddress(&my_mac_type, my_mac);
+    DEBUG(
+        "  my_MAC %02x:%02x:%02x:%02x:%02x:%02x (%s)\r\n",
+        my_mac[5], my_mac[4], my_mac[3], my_mac[2], my_mac[1], my_mac[0],
+        (my_mac_type == Gap::ADDR_TYPE_PUBLIC) ? "public" : "random"
+    );
+    DEBUG(
+        "  mac_board_? = {0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x};\r\n",
+        my_mac[0], my_mac[1], my_mac[2], my_mac[3], my_mac[4], my_mac[5]
+    );
+#endif
+    ble.gap().onConnection(connectionCallback);
     ble.gap().onDisconnection(disconnectionCallback);
-    ble.gattServer().onDataWritten(writeCharCallback);
-
-    /* Setup advertising */
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); // BLE only, no classic BT
-    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); // advertising type
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); // add name
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // UUID's broadcast in advertising packet
-    ble.gap().setAdvertisingInterval(100); // 100ms.
-
-    /* Add our custom service */
+    ble.gap().accumulateAdvertisingPayload(
+        GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE
+    ); // BLE only, no classic BT
+    ble.gap().setAdvertisingType(
+        GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED
+    ); // advertising type
+    ble.gap().accumulateAdvertisingPayload(
+        GapAdvertisingData::COMPLETE_LOCAL_NAME,
+        (uint8_t *)DEVICE_NAME,
+        sizeof(DEVICE_NAME)
+    ); // add name
+    ble.gap().accumulateAdvertisingPayload(
+        GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS,
+        (uint8_t *)uuid16_list,
+        sizeof(uuid16_list)
+    ); // UUID's broadcast in advertising packet
+    ble.gap().setTxPower(tx_power_level[2]);
+    ble.gap().setAdvertisingInterval(1000); // 1000ms.
     ble.addService(customService);
-
-    /* Start advertising */
     ble.gap().startAdvertising();
 }
 
-/*
- *  Main loop
-*/
-int main(void)
-{
-    /* initialize stuff */
-    printf("\n\r********* Starting Main Loop *********\n\r");
-    
-    BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE);
-    ble.init(bleInitComplete);
-    
-    /* SpinWait for initialization to complete. This is necessary because the
-     * BLE object is used in the main loop below. */
-    while (ble.hasInitialized()  == false) { /* spin loop */ }
-
-    /* Infinite loop waiting for BLE interrupt events */
-    while (true) {
-        ble.waitForEvent(); /* Save power */
+void connectionCallback(const Gap::ConnectionCallbackParams_t *params){
+    DEBUG("connected as device (handle = %d)\r\n\r", params->handle);
+    DEBUG(
+        "Conn. params => min=%d, max=%d, slave=%d, supervision=%d\r\n",
+        params->connectionParams->minConnectionInterval,
+        params->connectionParams->maxConnectionInterval,
+        params->connectionParams->slaveLatency,
+        params->connectionParams->connectionSupervisionTimeout
+    );
+#if 0
+    Gap::ConnectionParams_t connectionParams;
+    connectionParams.minConnectionInterval        = 200;
+    connectionParams.maxConnectionInterval        = 500;
+    connectionParams.slaveLatency                 = 0;
+    connectionParams.connectionSupervisionTimeout = 1500;
+    if (BLE::Instance(
+        BLE::DEFAULT_INSTANCE).gap().updateConnectionParams(params->handle,
+        &connectionParams) != BLE_ERROR_NONE
+    ){
+        DEBUG("failed to update connection parameter\r\n");
     }
-}
\ No newline at end of file
+#endif
+}