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

main.cpp

Committer:
kenjiArai
Date:
2016-06-12
Revision:
24:391e76b51b21
Parent:
23:f826de46d652

File content as of revision 24:391e76b51b21:

/*
 *  /////// 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     12th, 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.h"
#include "nRF51_Vdd.h"
#include "nRF51_lowpwr.h"

//  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                  0   // 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);

//  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
                        };

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
                        };

//  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 *)
                );

//  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!!
}

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();
}

void bleInitComplete(BLE::InitializationCompleteCallbackContext *params){
    BLE &ble          = params->ble;
    ble_error_t error = params->error;
    
    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.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);
    ble.gap().startAdvertising();
}

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");
    }
#endif
}