Bluetooth Low Energy enabled device with "Analog" feature, compatible with BlueST Protocol.

Dependencies:   X_NUCLEO_LED61A1

Bluetooth Low Energy enabled device with "Analog" feature, compatible with BlueST Protocol.

source/main.cpp

Committer:
Davidroid
Date:
2018-05-10
Revision:
0:43dcd7811b58
Child:
1:71b8b1f19322

File content as of revision 0:43dcd7811b58:

/**
 ******************************************************************************
 * @file    main.cpp
 * @author  Davide Aliprandi, STMicroelectronics
 * @version V1.0.0
 * @date    Ocober 31st, 2017
 * @brief   mbed test application for the STMicroelectronics X-NUCLEO-LED61A1
 *          LED expansion board and the X-NUCLEO-IDB05A1 Bluetooth expansion
 *          board.
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *   1. Redistributions of source code must retain the above copyright notice,
 *      this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright notice,
 *      this list of conditions and the following disclaimer in the documentation
 *      and/or other materials provided with the distribution.
 *   3. Neither the name of STMicroelectronics nor the names of its contributors
 *      may be used to endorse or promote products derived from this software
 *      without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ******************************************************************************
 */


/* Includes ------------------------------------------------------------------*/

/* mbed specific header files. */
#include <events/mbed_events.h>
#include <mbed.h>
#include "ble/BLE.h"
#include "CustomService.h"

/* Component specific header files. */
#include "Led6001.h"


/* Definitions ---------------------------------------------------------------*/

#define BLE_ADVERTISING_INTERVAL_ms 1000


/* Variables -----------------------------------------------------------------*/

/* Blinky LED to indicate system aliveness. */
DigitalOut alivenessLED(LED1, 0);

/* Bluetooth. */
const static char    DEVICE_NAME[] = "LED_DEVICE";
const static uint8_t MANUFACTURER_SPECIFIC_DATA[]= {0x01,0x80,0x00,0x00,0x20,0x00};
static EventQueue event_queue(/* event count */ 10 * EVENTS_EVENT_SIZE);
CustomService *custom_service;

/* LED Control Component. */
Led6001 *led;


/* Bluetooth related functions -----------------------------------------------*/

void on_disconnection_callback(const Gap::DisconnectionCallbackParams_t *params)
{
    (void) params;
    BLE::Instance().gap().startAdvertising();
}

void aliveness_callback(void)
{
    alivenessLED = !alivenessLED; /* Do blinky to indicate system aliveness. */
}

/**
 * This callback allows the custom service to receive updates for the
 * characteristic.
 *
 * @param[in] params
 *     Information about the characterisitc being updated.
 */
void on_data_written_callback(const GattWriteCallbackParams *params) {
    if ((params->handle == custom_service->getValueHandle())) {
        switch ((CustomService::led_commands_t) ((uint8_t *) (params->data))[0])
        {
            //Power Off
            case CustomService::LED_POWER_OFF:
                led->power_off();
                break;
            //Power On
            case CustomService::LED_POWER_ON:
                led->power_on();
                break;
            //Other
            default:
                break;
        }
    }
}

/**
 * This function is called when the ble initialization process has failled
 */
void on_ble_init_error_callback(BLE &ble, ble_error_t error)
{
    /* Initialization error handling should go here */
}

/**
 * Callback triggered when the ble initialization process has finished
 */
void ble_init_complete(BLE::InitializationCompleteCallbackContext *params)
{
    BLE& ble   = params->ble;
    ble_error_t error = params->error;

    if (error != BLE_ERROR_NONE) {
        /* In case of error, forward the error handling to on_ble_init_error_callback */
        on_ble_init_error_callback(ble, error);
        return;
    }

    /* Ensure that it is the default instance of BLE */
    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
        return;
    }

    ble.gap().onDisconnection(on_disconnection_callback);
    ble.gattServer().onDataWritten(on_data_written_callback);

    custom_service = new CustomService(ble);

    /* Setup advertising data. */
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, (uint8_t *) CUSTOM_LED_SERVICE_UUID, sizeof(CUSTOM_LED_SERVICE_UUID));
    ble.gap().accumulateScanResponse(GapAdvertisingData::MANUFACTURER_SPECIFIC_DATA, MANUFACTURER_SPECIFIC_DATA, sizeof(MANUFACTURER_SPECIFIC_DATA));
    ble.gap().accumulateScanResponse(GapAdvertisingData::COMPLETE_LOCAL_NAME, (const uint8_t *) DEVICE_NAME, sizeof(DEVICE_NAME) - 1);
    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.gap().setAdvertisingInterval(BLE_ADVERTISING_INTERVAL_ms);
    ble.gap().startAdvertising();
}

void schedule_ble_events_processing(BLE::OnEventsToProcessCallbackContext* context) {
    BLE &ble = BLE::Instance();
    event_queue.call(Callback<void()>(&ble, &BLE::processEvents));
}


/* Custom service related functions ------------------------------------------*/

/**
 * @brief  Interrupt Handler for the component's XFAULT interrupt.
 * @param  None.
 * @retval None.
 */
void xfault_irq_handler(void)
{
    /* Printing to the console. */
    printf("XFAULT Interrupt detected! Re-initializing LED driver...");

    /* Re-starting-up LED Control Component. */
    led->start_up();

    /* Printing to the console. */
    printf("Done.\r\n\n");
}


/* Main function -------------------------------------------------------------*/

int main()
{
    /*----- Initialization. -----*/

    /* Printing to the console. */
    printf("LED Node Application Example\r\n\n");

    /* Aliveness callback. */
    event_queue.call_every(500, aliveness_callback);

    /* Bluetooth. */
    BLE &ble = BLE::Instance();
    ble.onEventsToProcess(schedule_ble_events_processing);
    ble.init(ble_init_complete);
    
    /* Initializing LED Control Component. */
    led = new Led6001(D4, A3, D6, D5);
    if (led->init() != COMPONENT_OK) {
        exit(EXIT_FAILURE);
    }

    /* Attaching and enabling interrupt handlers. */
    led->attach_xfault_irq(&xfault_irq_handler);
    led->enable_xfault_irq();

    /* Powering OFF. */
    led->power_off();

    /* Start. */
    event_queue.dispatch_forever();

    return 0;
}