wenzel reichmuth / Mbed OS bel-example-pentabarf

Dependencies:   BleSerial Cli ConfigFile MbedJSONValue

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-2014 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 "Hardware.h"
00018 #include "ble/BLE.h"
00019 #include "ble/Gap.h"
00020 #include "ble/services/BatteryService.h"
00021 
00022 const uint16_t LIGHTBULB_SERVICE = 0xff10;
00023 const uint16_t SWITCH_CHARACTERISTIC = 0xff11;
00024 const uint16_t DIMMER_CHARACTERISTIC = 0xff12;
00025 
00026 Hardware myHardware = Hardware();
00027 static BatteryService* batteryServicePtr;
00028 static DFUService* dfuServicePtr;
00029 static uint8_t batteryLevel = 50;
00030 int bleCmdLen = 0;
00031 
00032 const static char     *DEVICE_NAME = "BleDev";
00033 static const uint16_t uuid16_list[] = {GattService::UUID_BATTERY_SERVICE, LIGHTBULB_SERVICE};
00034 
00035 /* Setup Lightbulb service */
00036 // Set Up custom Characteristics
00037 static uint8_t dimmerValue[10] = {0};
00038 ReadWriteArrayGattCharacteristic<uint8_t, sizeof(dimmerValue)> dimmer(DIMMER_CHARACTERISTIC, dimmerValue);
00039 
00040 static uint8_t switchValue[10] = {0};
00041 ReadWriteArrayGattCharacteristic<uint8_t, sizeof(switchValue)> _switch(SWITCH_CHARACTERISTIC, switchValue);
00042 
00043 // Set up custom service
00044 GattCharacteristic *characteristics[] = {&_switch, &dimmer};
00045 GattService customService(LIGHTBULB_SERVICE, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
00046 
00047 EventQueue *eventQueue;
00048 //EventQueue eventQueue2(32 * EVENTS_EVENT_SIZE);
00049 Thread *t;
00050 
00051 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params) {
00052     BLE::Instance().gap().startAdvertising();
00053 }
00054 
00055 void updateSensorValue() {
00056     batteryLevel++;
00057     if (batteryLevel > 100) {
00058         batteryLevel = 20;
00059     }
00060 
00061     batteryServicePtr->updateBatteryLevel(batteryLevel);
00062 }
00063 
00064 void blinkCallback(void) {
00065     //*(myHardware.led1) = !*(myHardware.led1); /* Do blinky on LED1 while we're waiting for BLE events */
00066 
00067     BLE &ble = BLE::Instance();
00068     if (ble.gap().getState().connected) {
00069         eventQueue->call(updateSensorValue);
00070     }
00071 }
00072 
00073 float ledVal = 0.0f;
00074 
00075 void setLedCb(void) {
00076   if(ledVal > 1.0f)
00077     ledVal = 0.0f;
00078   (myHardware.led)->write(ledVal);
00079   ledVal += 0.05f;    
00080 }
00081 
00082 /**
00083  * This function is called when the ble initialization process has failled
00084  */
00085 void onBleInitError(BLE &ble, ble_error_t error) {
00086     /* Initialization error handling should go here */
00087 }
00088 
00089 /**
00090  * Callback triggered when the ble initialization process has finished
00091  */
00092 void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) {
00093     BLE&        ble   = params->ble;
00094     ble_error_t error = params->error;
00095 
00096     if (error != BLE_ERROR_NONE) {
00097         /* In case of error, forward the error handling to onBleInitError */
00098         onBleInitError(ble, error);
00099         return;
00100     }
00101 
00102     /* Ensure that it is the default instance of BLE */
00103     if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
00104         return;
00105     }
00106 
00107     ble.gap().onDisconnection(disconnectionCallback);
00108 
00109     /* Setup primary service */
00110     batteryServicePtr = new BatteryService(ble, batteryLevel);
00111     
00112     /* Enable over-the-air firmware updates. Instantiating DFUSservice introduces a
00113     * control characteristic which can be used to trigger the application to
00114     * handover control to a resident bootloader. */
00115     dfuServicePtr = new DFUService(ble);
00116 
00117     /* Setup advertising */
00118     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00119     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *) uuid16_list, sizeof(uuid16_list));
00120     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
00121                                      (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
00122     ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *) DEVICE_NAME, sizeof(DEVICE_NAME));
00123 
00124     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00125     ble.gap().setAdvertisingInterval(200); /* 200ms */
00126     
00127     ble.addService(customService);
00128     
00129     ble.gap().startAdvertising();
00130 }
00131 
00132 void scheduleBleEventsProcessing(BLE::OnEventsToProcessCallbackContext* context) {
00133     BLE &ble = BLE::Instance();
00134     eventQueue->call(Callback<void()>(&ble, &BLE::processEvents));
00135 }
00136     
00137 void processBleCli(void) {
00138     for(int i = 0; i < bleCmdLen; i++){        
00139         (myHardware.bleCli)->process();
00140     }
00141     (myHardware.bleCli)->doEnter();
00142 }
00143 
00144 void postToQueue(); 
00145  
00146 void processCli() {
00147     (myHardware.myCli)->process();
00148     (myHardware.pc)->attach(postToQueue, Serial::RxIrq);
00149 }
00150  
00151 void postToQueue() {
00152     (myHardware.pc)->attach(NULL, Serial::RxIrq);
00153     eventQueue->call(processCli);
00154 }
00155 
00156 /*ISR when ble uart data arraived. scedules cli proscess*/
00157 void bleDataWritten(const GattWriteCallbackParams *params) {
00158     if (params->handle == (myHardware.bleSerial)->getTXCHandle()) {
00159         bleCmdLen = params->len;
00160         eventQueue->call(processBleCli);
00161     }
00162     if(params->handle == dimmer.getValueHandle()) {
00163         // toggle LED if only 1 byte is written
00164         if(params->len == 1) {
00165             //led = params->data[0];
00166             float ledVal = (float) params->data[0] / 255.0f;
00167             (myHardware.led)->write(ledVal);
00168             //(myHardware.pc)->printf("\n\r %d", params->data[0]);
00169         }
00170         // print the data if more than 1 byte is written
00171         else {
00172             (myHardware.pc)->printf("\n\r Data received: length = %d, data = 0x",params->len); 
00173         }
00174         // update the readChar with the value of writeChar
00175         BLE::Instance(BLE::DEFAULT_INSTANCE).gattServer().write(dimmer.getValueHandle(), params->data, params->len);
00176     }
00177 }
00178 
00179 int main()
00180 {
00181     eventQueue = new EventQueue(32 * EVENTS_EVENT_SIZE);
00182     t = new Thread(osPriorityNormal);
00183     
00184     //(myHardware.pc)->printf("INIT BLE\n");
00185     BLE &ble = BLE::Instance();
00186     ble.onEventsToProcess(scheduleBleEventsProcessing);
00187     ble.init(bleInitComplete);
00188     
00189     ble.gattServer().onDataWritten(bleDataWritten);//chaining ist von vorn nach hinten!
00190     
00191     myHardware.init();
00192     
00193     //(myHardware.pc)->printf("INIT RTOS\n");
00194     t->start(callback(eventQueue, &EventQueue::dispatch_forever));
00195     eventQueue->call_every(500, blinkCallback);
00196     //eventQueue->call_every(100, setLedCb);
00197     (myHardware.pc)->attach(postToQueue, Serial::RxIrq);
00198     
00199     (myHardware.led)->write((float)dimmerValue[0]/255.0f);
00200     
00201     while(true) sleep();
00202 
00203     return 0;
00204 }