mbed.org local branch of microbit-dal. The real version lives in git at https://github.com/lancaster-university/microbit-dal

Dependencies:   BLE_API nRF51822 mbed-dev-bin

Dependents:   microbit Microbit IoTChallenge1 microbit ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MicroBitMagnetometerService.cpp Source File

MicroBitMagnetometerService.cpp

00001 /*
00002 The MIT License (MIT)
00003 
00004 Copyright (c) 2016 British Broadcasting Corporation.
00005 This software is provided by Lancaster University by arrangement with the BBC.
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a
00008 copy of this software and associated documentation files (the "Software"),
00009 to deal in the Software without restriction, including without limitation
00010 the rights to use, copy, modify, merge, publish, distribute, sublicense,
00011 and/or sell copies of the Software, and to permit persons to whom the
00012 Software is furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included in
00015 all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
00023 DEALINGS IN THE SOFTWARE.
00024 */
00025 
00026 /**
00027   * Class definition for the MicroBit BLE Magnetometer Service.
00028   * Provides access to live magnetometer data via BLE, and provides basic configuration options.
00029   */
00030 #include "MicroBitConfig.h"
00031 #include "ble/UUID.h"
00032 
00033 #include "MicroBitMagnetometerService.h"
00034 
00035 /**
00036   * Constructor.
00037   * Create a representation of the MagnetometerService.
00038   * @param _ble The instance of a BLE device that we're running on.
00039   * @param _compass An instance of MicroBitCompass to use as our Magnetometer source.
00040   */
00041 MicroBitMagnetometerService::MicroBitMagnetometerService(BLEDevice &_ble, MicroBitCompass &_compass) :
00042         ble(_ble), compass(_compass)
00043 {
00044     // Create the data structures that represent each of our characteristics in Soft Device.
00045     GattCharacteristic  magnetometerDataCharacteristic(MicroBitMagnetometerServiceDataUUID, (uint8_t *)magnetometerDataCharacteristicBuffer, 0,
00046     sizeof(magnetometerDataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
00047 
00048     GattCharacteristic  magnetometerBearingCharacteristic(MicroBitMagnetometerServiceBearingUUID, (uint8_t *)&magnetometerBearingCharacteristicBuffer, 0,
00049     sizeof(magnetometerBearingCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
00050 
00051     GattCharacteristic  magnetometerPeriodCharacteristic(MicroBitMagnetometerServicePeriodUUID, (uint8_t *)&magnetometerPeriodCharacteristicBuffer, 0,
00052     sizeof(magnetometerPeriodCharacteristicBuffer),
00053     GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE);
00054 
00055     // Initialise our characteristic values.
00056     magnetometerDataCharacteristicBuffer[0] = 0;
00057     magnetometerDataCharacteristicBuffer[1] = 0;
00058     magnetometerDataCharacteristicBuffer[2] = 0;
00059     magnetometerBearingCharacteristicBuffer = 0;
00060     magnetometerPeriodCharacteristicBuffer = compass.getPeriod();
00061 
00062     // Set default security requirements
00063     magnetometerDataCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
00064     magnetometerBearingCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
00065     magnetometerPeriodCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL);
00066 
00067     GattCharacteristic *characteristics[] = {&magnetometerDataCharacteristic, &magnetometerBearingCharacteristic, &magnetometerPeriodCharacteristic};
00068     GattService         service(MicroBitMagnetometerServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *));
00069 
00070     ble.addService(service);
00071 
00072     magnetometerDataCharacteristicHandle = magnetometerDataCharacteristic.getValueHandle();
00073     magnetometerBearingCharacteristicHandle = magnetometerBearingCharacteristic.getValueHandle();
00074     magnetometerPeriodCharacteristicHandle = magnetometerPeriodCharacteristic.getValueHandle();
00075 
00076     ble.gattServer().notify(magnetometerDataCharacteristicHandle,(uint8_t *)magnetometerDataCharacteristicBuffer, sizeof(magnetometerDataCharacteristicBuffer));
00077     ble.gattServer().notify(magnetometerBearingCharacteristicHandle,(uint8_t *)&magnetometerBearingCharacteristicBuffer, sizeof(magnetometerBearingCharacteristicBuffer));
00078     ble.gattServer().write(magnetometerPeriodCharacteristicHandle, (const uint8_t *)&magnetometerPeriodCharacteristicBuffer, sizeof(magnetometerPeriodCharacteristicBuffer));
00079 
00080     ble.onDataWritten(this, &MicroBitMagnetometerService::onDataWritten);
00081     if (EventModel::defaultEventBus)
00082     {
00083         EventModel::defaultEventBus->listen(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_DATA_UPDATE, this, &MicroBitMagnetometerService::magnetometerUpdate, MESSAGE_BUS_LISTENER_IMMEDIATE);
00084         EventModel::defaultEventBus->listen(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_CONFIG_NEEDED, this, &MicroBitMagnetometerService::samplePeriodUpdateNeeded);
00085     }
00086 }
00087 
00088 /**
00089   * Callback. Invoked when any of our attributes are written via BLE.
00090   */
00091 void MicroBitMagnetometerService::onDataWritten(const GattWriteCallbackParams *params)
00092 {
00093     if (params->handle == magnetometerPeriodCharacteristicHandle && params->len >= sizeof(magnetometerPeriodCharacteristicBuffer))
00094     {
00095         magnetometerPeriodCharacteristicBuffer = *((uint16_t *)params->data);
00096         MicroBitEvent evt(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_CONFIG_NEEDED);
00097     }
00098 }
00099 
00100 /**
00101   * Magnetometer update callback
00102   */
00103 void MicroBitMagnetometerService::magnetometerUpdate(MicroBitEvent)
00104 {
00105     if (ble.getGapState().connected)
00106     {
00107         magnetometerDataCharacteristicBuffer[0] = compass.getX();
00108         magnetometerDataCharacteristicBuffer[1] = compass.getY();
00109         magnetometerDataCharacteristicBuffer[2] = compass.getZ();
00110         magnetometerPeriodCharacteristicBuffer = compass.getPeriod();
00111 
00112         ble.gattServer().write(magnetometerPeriodCharacteristicHandle, (const uint8_t *)&magnetometerPeriodCharacteristicBuffer, sizeof(magnetometerPeriodCharacteristicBuffer));
00113         ble.gattServer().notify(magnetometerDataCharacteristicHandle,(uint8_t *)magnetometerDataCharacteristicBuffer, sizeof(magnetometerDataCharacteristicBuffer));
00114 
00115         if (compass.isCalibrated())
00116         {
00117             magnetometerBearingCharacteristicBuffer = (uint16_t) compass.heading();
00118             ble.gattServer().notify(magnetometerBearingCharacteristicHandle,(uint8_t *)&magnetometerBearingCharacteristicBuffer, sizeof(magnetometerBearingCharacteristicBuffer));
00119         }
00120     }
00121 }
00122 
00123 /**
00124  * Sample Period Change Needed callback.
00125  * Reconfiguring the magnetometer can to a REALLY long time (sometimes even seconds to complete)
00126  * So we do this in the background when necessary, through this event handler.
00127  */
00128 void MicroBitMagnetometerService::samplePeriodUpdateNeeded(MicroBitEvent)
00129 {
00130     // Reconfigure the compass. This might take a while...
00131     compass.setPeriod(magnetometerPeriodCharacteristicBuffer);
00132 
00133     // The compass will choose the nearest sample period to that we've specified.
00134     // Read the ACTUAL sample period back.
00135     magnetometerPeriodCharacteristicBuffer = compass.getPeriod();
00136 
00137     // Ensure this is reflected in our BLE connection.
00138     ble.gattServer().write(magnetometerPeriodCharacteristicHandle, (const uint8_t *)&magnetometerPeriodCharacteristicBuffer, sizeof(magnetometerPeriodCharacteristicBuffer));
00139 
00140 }
00141 
00142 const uint8_t  MicroBitMagnetometerServiceUUID[] = {
00143     0xe9,0x5d,0xf2,0xd8,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
00144 };
00145 
00146 const uint8_t  MicroBitMagnetometerServiceDataUUID[] = {
00147     0xe9,0x5d,0xfb,0x11,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
00148 };
00149 
00150 const uint8_t  MicroBitMagnetometerServicePeriodUUID[] = {
00151     0xe9,0x5d,0x38,0x6c,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
00152 };
00153 
00154 const uint8_t  MicroBitMagnetometerServiceBearingUUID[] = {
00155     0xe9,0x5d,0x97,0x15,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8
00156 };