Cycle speed and cadence example for the BLE API using nRF51822 native mode drivers
Dependencies: BLE_API mbed nRF51822
Fork of BLE_HeartRate by
Diff: CyclingSpeedAndCadenceService.h
- Revision:
- 73:bae88c99c2ae
- Parent:
- 72:a15b8451829f
- Child:
- 74:98dee483c173
diff -r a15b8451829f -r bae88c99c2ae CyclingSpeedAndCadenceService.h --- a/CyclingSpeedAndCadenceService.h Sun Aug 16 14:46:43 2015 +0000 +++ b/CyclingSpeedAndCadenceService.h Sun Aug 23 14:00:28 2015 +0000 @@ -28,6 +28,12 @@ */ class CyclingSpeedAndCadenceService { public: + enum Mode { + MODE_SPEED, + MODE_CADENCE, + MODE_SPEED_CADENCE + }; + /** * @enum SensorLocation * @brief Location of sensor on bike. @@ -68,13 +74,15 @@ * @param[in] location * Sensor's location. */ - CyclingSpeedAndCadenceService(BLE &_ble, uint8_t location) : + CyclingSpeedAndCadenceService(BLE &_ble, Mode _mode, uint8_t location) : ble(_ble), - feature(3), - csc(GattCharacteristic::UUID_CSC_MEASUREMENT_CHAR, valueBytes.getPointer(), - valueBytes.getNumValueBytes(), SpeedCadenceValueBytes::MAX_BYTES, + value(_mode), + mode(_mode), + csc(GattCharacteristic::UUID_CSC_MEASUREMENT_CHAR, + value.bytes, + value.getSize(), value.getSize(), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), - cscFeat(GattCharacteristic::UUID_CSC_FEATURE_CHAR, (uint8_t*)&feature, + cscFeat(GattCharacteristic::UUID_CSC_FEATURE_CHAR, (uint8_t*)&mode, 2, 2, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ), scLocation(UUID_SENSOR_LOCATION_CHAR, &location), @@ -90,9 +98,10 @@ * @param[in] eventTime * Time of event. */ - void updateWheelCounter(uint32_t wheelCounter, uint16_t eventTime) { - valueBytes.updateWheelCounter(wheelCounter, eventTime); - ble.gattServer().write(csc.getValueHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes()); + void updateWheelCounter(uint32_t wheelCounter, uint16_t eventTime) + { + value.updateWheelCounter(wheelCounter, eventTime); + sendUpdate(); } /** @@ -103,15 +112,16 @@ * @param[in] eventTime * Time of event. */ - void updateCrankCounter(uint16_t crankCounter, uint16_t eventTime) { - valueBytes.updateCrankCounter(crankCounter, eventTime); - ble.gattServer().write(csc.getValueHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes()); + void updateCrankCounter(uint16_t crankCounter, uint16_t eventTime) + { + value.updateCrankCounter(crankCounter, eventTime); + sendUpdate(); } - void updateCounters(uint32_t wheelCounter, uint16_t crankCounter, uint16_t eventTime) { - valueBytes.updateWheelCounter(wheelCounter, eventTime); - valueBytes.updateCrankCounter(crankCounter, eventTime); - ble.gattServer().write(csc.getValueHandle(), valueBytes.getPointer(), valueBytes.getNumValueBytes()); + void updateCounters(uint32_t wheelCounter, uint16_t crankCounter, uint16_t eventTime) + { + value.updateCounters(wheelCounter, crankCounter, eventTime); + sendUpdate(); } /** @@ -141,80 +151,133 @@ ble.onDataWritten(this, &CyclingSpeedAndCadenceService::onDataWritten); } -protected: - /* Private internal representation for the bytes used to work with the value of the speed cadence characteristic. */ - struct SpeedCadenceValueBytes { - static const uint16_t MAX_BYTES = (1 + 4 + 2 + 2 + 2); - static const uint8_t FLAG_WHEEL_PRESENT = (1 << 0); - static const uint8_t FLAG_CRANK_PRESENT = (1 << 1); - SpeedCadenceValueBytes() - : flags(0) - { - updateWheelCounter(1, 0); - updateCrankCounter(1, 0); - } - - void updateWheelCounter(uint32_t _wheelCounter, uint16_t _when) { - flags |= FLAG_WHEEL_PRESENT; - wheelCounter = _wheelCounter; - lastWheelEvent = _when; - pack(); - } - - void updateCrankCounter(uint16_t _crankCounter, uint16_t _when) { - flags |= FLAG_CRANK_PRESENT; - crankCounter = _crankCounter; - lastCrankEvent = _when; - pack(); - } + void sendUpdate() + { + ble.gattServer().write(csc.getValueHandle(), value.bytes, value.getSize()); + } - uint8_t *getPointer(void) { - return valueBytes; - } - - unsigned getNumValueBytes(void) const { - return 1 + - ((flags & FLAG_WHEEL_PRESENT) ? (4+2) : 0) + - ((flags & FLAG_CRANK_PRESENT) ? (2+2) : 0); - } - - private: - void pack() +protected: + static const uint8_t FLAG_WHEEL_PRESENT = (1 << 0); + static const uint8_t FLAG_CRANK_PRESENT = (1 << 1); + static const uint16_t MAX_BYTES = (1 + 4 + 2 + 2 + 2); + union SpeedCadenceValue + { + SpeedCadenceValue(uint16_t mode) { - valueBytes[0] = flags; - unsigned p = 1; - if (flags & FLAG_WHEEL_PRESENT) + switch (mode) { - valueBytes[p++] = wheelCounter & 0xFF; - valueBytes[p++] = (wheelCounter >> 8) & 0xFF; - valueBytes[p++] = (wheelCounter >> 16) & 0xFF; - valueBytes[p++] = (wheelCounter >> 24) & 0xFF; - valueBytes[p++] = lastWheelEvent & 0xFF; - valueBytes[p++] = (lastWheelEvent >> 8) & 0xFF; - } - if (flags & FLAG_CRANK_PRESENT) - { - valueBytes[p++] = crankCounter & 0xFF; - valueBytes[p++] = (crankCounter >> 8) & 0xFF; - valueBytes[p++] = lastCrankEvent & 0xFF; - valueBytes[p++] = (lastCrankEvent >> 8) & 0xFF; + case MODE_SPEED: + v.flags = FLAG_WHEEL_PRESENT; + break; + case MODE_CADENCE: + v.flags = FLAG_CRANK_PRESENT; + break; + case MODE_SPEED_CADENCE: + v.flags = FLAG_WHEEL_PRESENT | FLAG_CRANK_PRESENT; + break; + default: + v.flags = 0; + break; } } - uint8_t flags; - uint32_t wheelCounter; - uint16_t lastWheelEvent; - uint16_t crankCounter; - uint16_t lastCrankEvent; - uint8_t valueBytes[MAX_BYTES]; + void updateWheelCounter(uint32_t wheelCounter, uint16_t eventTime) + { + switch(v.flags) + { + case FLAG_WHEEL_PRESENT: + v.v.speed.wheelCounter = wheelCounter; + v.v.speed.lastWheelEvent = eventTime; + break; + case FLAG_WHEEL_PRESENT | FLAG_CRANK_PRESENT: + v.v.speedCadence.wheelCounter = wheelCounter; + v.v.speedCadence.lastWheelEvent = eventTime; + break; + default: + break; + } + } + + void updateCrankCounter(uint16_t crankCounter, uint16_t eventTime) + { + switch(v.flags) + { + case FLAG_CRANK_PRESENT: + v.v.cadence.crankCounter = crankCounter; + v.v.cadence.lastCrankEvent = eventTime; + break; + case FLAG_WHEEL_PRESENT | FLAG_CRANK_PRESENT: + v.v.speedCadence.crankCounter = crankCounter; + v.v.speedCadence.lastCrankEvent = eventTime; + break; + default: + break; + } + } + + void updateCounters(uint32_t wheelCounter, uint16_t crankCounter, uint16_t eventTime) + { + switch(v.flags) + { + case FLAG_WHEEL_PRESENT: + v.v.speed.wheelCounter = wheelCounter; + v.v.speed.lastWheelEvent = eventTime; + break; + case FLAG_CRANK_PRESENT: + v.v.cadence.crankCounter = crankCounter; + v.v.cadence.lastCrankEvent = eventTime; + break; + case FLAG_WHEEL_PRESENT | FLAG_CRANK_PRESENT: + v.v.speedCadence.wheelCounter = wheelCounter; + v.v.speedCadence.lastWheelEvent = eventTime; + v.v.speedCadence.crankCounter = crankCounter; + v.v.speedCadence.lastCrankEvent = eventTime; + break; + default: + break; + } + } + + uint16_t getSize() + { + return 1 + + ((v.flags & FLAG_WHEEL_PRESENT) ? (4+2) : 0) + + ((v.flags & FLAG_CRANK_PRESENT) ? (2+2) : 0); + } + + __packed struct Value + { + uint8_t flags; + __packed union + { + __packed struct Speed + { + uint32_t wheelCounter; + uint16_t lastWheelEvent; + } speed; + __packed struct Cadence + { + uint16_t crankCounter; + uint16_t lastCrankEvent; + } cadence; + __packed struct SpeedCadence + { + uint32_t wheelCounter; + uint16_t lastWheelEvent; + uint16_t crankCounter; + uint16_t lastCrankEvent; + } speedCadence; + } v; + } v; + uint8_t bytes[1+4+2+2+2]; }; protected: BLE &ble; - SpeedCadenceValueBytes valueBytes; - uint16_t feature; + SpeedCadenceValue value; + uint16_t mode; uint8_t controlPointValue; GattCharacteristic csc;