Solution for Bluetooth SIG hands-on training course
Dependencies: BLE_API mbed-dev-bin nRF51822-bluetooth-mdw
Fork of microbit-dal-bluetooth-mdw_starter by
source/bluetooth/MicroBitMagnetometerService.cpp@22:23d7b9a4b082, 2016-07-13 (annotated)
- Committer:
- LancasterUniversity
- Date:
- Wed Jul 13 12:17:54 2016 +0100
- Revision:
- 22:23d7b9a4b082
- Parent:
- 21:cab56b701601
- Child:
- 23:6055f6c19fa6
Synchronized with git rev 7cf98c22
Author: James Devine
microbit-dal: patch for fiber_wake_on_event
fiber_wake_on_event used to crash after forking a FOB fiber.
It would attempt to obtain a new fiber context, and would place it on the wait queue.
Then when that fiber was paged in, the context of that fiber would not have been
initialised, as the function presumed schedule would be called immediately after
fiber initialisation.
This patch catches that edge case.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Jonathan Austin |
1:8aa5cdb4ab67 | 1 | /* |
Jonathan Austin |
1:8aa5cdb4ab67 | 2 | The MIT License (MIT) |
Jonathan Austin |
1:8aa5cdb4ab67 | 3 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 4 | Copyright (c) 2016 British Broadcasting Corporation. |
Jonathan Austin |
1:8aa5cdb4ab67 | 5 | This software is provided by Lancaster University by arrangement with the BBC. |
Jonathan Austin |
1:8aa5cdb4ab67 | 6 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 7 | Permission is hereby granted, free of charge, to any person obtaining a |
Jonathan Austin |
1:8aa5cdb4ab67 | 8 | copy of this software and associated documentation files (the "Software"), |
Jonathan Austin |
1:8aa5cdb4ab67 | 9 | to deal in the Software without restriction, including without limitation |
Jonathan Austin |
1:8aa5cdb4ab67 | 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, |
Jonathan Austin |
1:8aa5cdb4ab67 | 11 | and/or sell copies of the Software, and to permit persons to whom the |
Jonathan Austin |
1:8aa5cdb4ab67 | 12 | Software is furnished to do so, subject to the following conditions: |
Jonathan Austin |
1:8aa5cdb4ab67 | 13 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 14 | The above copyright notice and this permission notice shall be included in |
Jonathan Austin |
1:8aa5cdb4ab67 | 15 | all copies or substantial portions of the Software. |
Jonathan Austin |
1:8aa5cdb4ab67 | 16 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
Jonathan Austin |
1:8aa5cdb4ab67 | 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
Jonathan Austin |
1:8aa5cdb4ab67 | 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
Jonathan Austin |
1:8aa5cdb4ab67 | 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
Jonathan Austin |
1:8aa5cdb4ab67 | 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
Jonathan Austin |
1:8aa5cdb4ab67 | 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
Jonathan Austin |
1:8aa5cdb4ab67 | 23 | DEALINGS IN THE SOFTWARE. |
Jonathan Austin |
1:8aa5cdb4ab67 | 24 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 25 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 26 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 27 | * Class definition for the MicroBit BLE Magnetometer Service. |
Jonathan Austin |
1:8aa5cdb4ab67 | 28 | * Provides access to live magnetometer data via BLE, and provides basic configuration options. |
Jonathan Austin |
1:8aa5cdb4ab67 | 29 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 30 | #include "MicroBitConfig.h" |
Jonathan Austin |
1:8aa5cdb4ab67 | 31 | #include "ble/UUID.h" |
Jonathan Austin |
1:8aa5cdb4ab67 | 32 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 33 | #include "MicroBitMagnetometerService.h" |
Jonathan Austin |
1:8aa5cdb4ab67 | 34 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 35 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 36 | * Constructor. |
Jonathan Austin |
1:8aa5cdb4ab67 | 37 | * Create a representation of the MagnetometerService. |
Jonathan Austin |
1:8aa5cdb4ab67 | 38 | * @param _ble The instance of a BLE device that we're running on. |
Jonathan Austin |
1:8aa5cdb4ab67 | 39 | * @param _compass An instance of MicroBitCompass to use as our Magnetometer source. |
Jonathan Austin |
1:8aa5cdb4ab67 | 40 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 41 | MicroBitMagnetometerService::MicroBitMagnetometerService(BLEDevice &_ble, MicroBitCompass &_compass) : |
Jonathan Austin |
1:8aa5cdb4ab67 | 42 | ble(_ble), compass(_compass) |
Jonathan Austin |
1:8aa5cdb4ab67 | 43 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 44 | // Create the data structures that represent each of our characteristics in Soft Device. |
Jonathan Austin |
1:8aa5cdb4ab67 | 45 | GattCharacteristic magnetometerDataCharacteristic(MicroBitMagnetometerServiceDataUUID, (uint8_t *)magnetometerDataCharacteristicBuffer, 0, |
Jonathan Austin |
1:8aa5cdb4ab67 | 46 | sizeof(magnetometerDataCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); |
Jonathan Austin |
1:8aa5cdb4ab67 | 47 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 48 | GattCharacteristic magnetometerBearingCharacteristic(MicroBitMagnetometerServiceBearingUUID, (uint8_t *)&magnetometerBearingCharacteristicBuffer, 0, |
Jonathan Austin |
1:8aa5cdb4ab67 | 49 | sizeof(magnetometerBearingCharacteristicBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); |
Jonathan Austin |
1:8aa5cdb4ab67 | 50 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 51 | GattCharacteristic magnetometerPeriodCharacteristic(MicroBitMagnetometerServicePeriodUUID, (uint8_t *)&magnetometerPeriodCharacteristicBuffer, 0, |
Jonathan Austin |
1:8aa5cdb4ab67 | 52 | sizeof(magnetometerPeriodCharacteristicBuffer), |
Jonathan Austin |
1:8aa5cdb4ab67 | 53 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE); |
Jonathan Austin |
1:8aa5cdb4ab67 | 54 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 55 | // Initialise our characteristic values. |
Jonathan Austin |
1:8aa5cdb4ab67 | 56 | magnetometerDataCharacteristicBuffer[0] = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 57 | magnetometerDataCharacteristicBuffer[1] = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 58 | magnetometerDataCharacteristicBuffer[2] = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 59 | magnetometerBearingCharacteristicBuffer = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 60 | magnetometerPeriodCharacteristicBuffer = compass.getPeriod(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 61 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 62 | // Set default security requirements |
Jonathan Austin |
1:8aa5cdb4ab67 | 63 | magnetometerDataCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL); |
Jonathan Austin |
1:8aa5cdb4ab67 | 64 | magnetometerBearingCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL); |
Jonathan Austin |
1:8aa5cdb4ab67 | 65 | magnetometerPeriodCharacteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL); |
Jonathan Austin |
1:8aa5cdb4ab67 | 66 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 67 | GattCharacteristic *characteristics[] = {&magnetometerDataCharacteristic, &magnetometerBearingCharacteristic, &magnetometerPeriodCharacteristic}; |
Jonathan Austin |
1:8aa5cdb4ab67 | 68 | GattService service(MicroBitMagnetometerServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *)); |
Jonathan Austin |
1:8aa5cdb4ab67 | 69 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 70 | ble.addService(service); |
Jonathan Austin |
1:8aa5cdb4ab67 | 71 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 72 | magnetometerDataCharacteristicHandle = magnetometerDataCharacteristic.getValueHandle(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 73 | magnetometerBearingCharacteristicHandle = magnetometerBearingCharacteristic.getValueHandle(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 74 | magnetometerPeriodCharacteristicHandle = magnetometerPeriodCharacteristic.getValueHandle(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 75 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 76 | ble.gattServer().notify(magnetometerDataCharacteristicHandle,(uint8_t *)magnetometerDataCharacteristicBuffer, sizeof(magnetometerDataCharacteristicBuffer)); |
LancasterUniversity | 22:23d7b9a4b082 | 77 | ble.gattServer().notify(magnetometerBearingCharacteristicHandle,(uint8_t *)&magnetometerBearingCharacteristicBuffer, sizeof(magnetometerDataCharacteristicBuffer)); |
Jonathan Austin |
1:8aa5cdb4ab67 | 78 | ble.gattServer().write(magnetometerPeriodCharacteristicHandle, (const uint8_t *)&magnetometerPeriodCharacteristicBuffer, sizeof(magnetometerPeriodCharacteristicBuffer)); |
Jonathan Austin |
1:8aa5cdb4ab67 | 79 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 80 | ble.onDataWritten(this, &MicroBitMagnetometerService::onDataWritten); |
Jonathan Austin |
1:8aa5cdb4ab67 | 81 | if (EventModel::defaultEventBus) |
Jonathan Austin |
1:8aa5cdb4ab67 | 82 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 83 | EventModel::defaultEventBus->listen(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_DATA_UPDATE, this, &MicroBitMagnetometerService::magnetometerUpdate, MESSAGE_BUS_LISTENER_IMMEDIATE); |
Jonathan Austin |
1:8aa5cdb4ab67 | 84 | EventModel::defaultEventBus->listen(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_CONFIG_NEEDED, this, &MicroBitMagnetometerService::samplePeriodUpdateNeeded); |
Jonathan Austin |
1:8aa5cdb4ab67 | 85 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 86 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 87 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 88 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 89 | * Callback. Invoked when any of our attributes are written via BLE. |
Jonathan Austin |
1:8aa5cdb4ab67 | 90 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 91 | void MicroBitMagnetometerService::onDataWritten(const GattWriteCallbackParams *params) |
Jonathan Austin |
1:8aa5cdb4ab67 | 92 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 93 | if (params->handle == magnetometerPeriodCharacteristicHandle && params->len >= sizeof(magnetometerPeriodCharacteristicBuffer)) |
Jonathan Austin |
1:8aa5cdb4ab67 | 94 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 95 | magnetometerPeriodCharacteristicBuffer = *((uint16_t *)params->data); |
Jonathan Austin |
1:8aa5cdb4ab67 | 96 | MicroBitEvent evt(MICROBIT_ID_COMPASS, MICROBIT_COMPASS_EVT_CONFIG_NEEDED); |
Jonathan Austin |
1:8aa5cdb4ab67 | 97 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 98 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 99 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 100 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 101 | * Magnetometer update callback |
Jonathan Austin |
1:8aa5cdb4ab67 | 102 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 103 | void MicroBitMagnetometerService::magnetometerUpdate(MicroBitEvent) |
Jonathan Austin |
1:8aa5cdb4ab67 | 104 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 105 | if (ble.getGapState().connected) |
Jonathan Austin |
1:8aa5cdb4ab67 | 106 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 107 | magnetometerDataCharacteristicBuffer[0] = compass.getX(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 108 | magnetometerDataCharacteristicBuffer[1] = compass.getY(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 109 | magnetometerDataCharacteristicBuffer[2] = compass.getZ(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 110 | magnetometerPeriodCharacteristicBuffer = compass.getPeriod(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 111 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 112 | ble.gattServer().write(magnetometerPeriodCharacteristicHandle, (const uint8_t *)&magnetometerPeriodCharacteristicBuffer, sizeof(magnetometerPeriodCharacteristicBuffer)); |
Jonathan Austin |
1:8aa5cdb4ab67 | 113 | ble.gattServer().notify(magnetometerDataCharacteristicHandle,(uint8_t *)magnetometerDataCharacteristicBuffer, sizeof(magnetometerDataCharacteristicBuffer)); |
Jonathan Austin |
1:8aa5cdb4ab67 | 114 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 115 | if (compass.isCalibrated()) |
Jonathan Austin |
1:8aa5cdb4ab67 | 116 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 117 | magnetometerBearingCharacteristicBuffer = (uint16_t) compass.heading(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 118 | ble.gattServer().notify(magnetometerBearingCharacteristicHandle,(uint8_t *)&magnetometerBearingCharacteristicBuffer, sizeof(magnetometerBearingCharacteristicBuffer)); |
Jonathan Austin |
1:8aa5cdb4ab67 | 119 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 120 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 121 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 122 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 123 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 124 | * Sample Period Change Needed callback. |
Jonathan Austin |
1:8aa5cdb4ab67 | 125 | * Reconfiguring the magnetometer can to a REALLY long time (sometimes even seconds to complete) |
Jonathan Austin |
1:8aa5cdb4ab67 | 126 | * So we do this in the background when necessary, through this event handler. |
Jonathan Austin |
1:8aa5cdb4ab67 | 127 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 128 | void MicroBitMagnetometerService::samplePeriodUpdateNeeded(MicroBitEvent) |
Jonathan Austin |
1:8aa5cdb4ab67 | 129 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 130 | // Reconfigure the compass. This might take a while... |
Jonathan Austin |
1:8aa5cdb4ab67 | 131 | compass.setPeriod(magnetometerPeriodCharacteristicBuffer); |
Jonathan Austin |
1:8aa5cdb4ab67 | 132 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 133 | // The compass will choose the nearest sample period to that we've specified. |
Jonathan Austin |
1:8aa5cdb4ab67 | 134 | // Read the ACTUAL sample period back. |
Jonathan Austin |
1:8aa5cdb4ab67 | 135 | magnetometerPeriodCharacteristicBuffer = compass.getPeriod(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 136 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 137 | // Ensure this is reflected in our BLE connection. |
Jonathan Austin |
1:8aa5cdb4ab67 | 138 | ble.gattServer().write(magnetometerPeriodCharacteristicHandle, (const uint8_t *)&magnetometerPeriodCharacteristicBuffer, sizeof(magnetometerPeriodCharacteristicBuffer)); |
Jonathan Austin |
1:8aa5cdb4ab67 | 139 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 140 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 141 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 142 | const uint8_t MicroBitMagnetometerServiceUUID[] = { |
Jonathan Austin |
1:8aa5cdb4ab67 | 143 | 0xe9,0x5d,0xf2,0xd8,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 |
Jonathan Austin |
1:8aa5cdb4ab67 | 144 | }; |
Jonathan Austin |
1:8aa5cdb4ab67 | 145 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 146 | const uint8_t MicroBitMagnetometerServiceDataUUID[] = { |
Jonathan Austin |
1:8aa5cdb4ab67 | 147 | 0xe9,0x5d,0xfb,0x11,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 |
Jonathan Austin |
1:8aa5cdb4ab67 | 148 | }; |
Jonathan Austin |
1:8aa5cdb4ab67 | 149 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 150 | const uint8_t MicroBitMagnetometerServicePeriodUUID[] = { |
Jonathan Austin |
1:8aa5cdb4ab67 | 151 | 0xe9,0x5d,0x38,0x6c,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 |
Jonathan Austin |
1:8aa5cdb4ab67 | 152 | }; |
Jonathan Austin |
1:8aa5cdb4ab67 | 153 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 154 | const uint8_t MicroBitMagnetometerServiceBearingUUID[] = { |
Jonathan Austin |
1:8aa5cdb4ab67 | 155 | 0xe9,0x5d,0x97,0x15,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 |
LancasterUniversity | 21:cab56b701601 | 156 | }; |