51 52 with same code

Dependencies:   MtSense06

Fork of MtConnect04S_MtSense06 by MtM+

Committer:
bcc6
Date:
Wed Feb 22 09:45:51 2017 +0000
Revision:
0:528034040a12
Child:
1:0ec0e5694c4a
First create

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bcc6 0:528034040a12 1 /* Copyright (c) 2016 MtM Technology Corporation, MIT License
bcc6 0:528034040a12 2 *
bcc6 0:528034040a12 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
bcc6 0:528034040a12 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
bcc6 0:528034040a12 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
bcc6 0:528034040a12 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
bcc6 0:528034040a12 7 * furnished to do so, subject to the following conditions:
bcc6 0:528034040a12 8 *
bcc6 0:528034040a12 9 * The above copyright notice and this permission notice shall be included in all copies or
bcc6 0:528034040a12 10 * substantial portions of the Software.
bcc6 0:528034040a12 11 *
bcc6 0:528034040a12 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
bcc6 0:528034040a12 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
bcc6 0:528034040a12 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
bcc6 0:528034040a12 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
bcc6 0:528034040a12 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
bcc6 0:528034040a12 17 */
bcc6 0:528034040a12 18 #ifndef __BLE_PULSE_OXIMETER_SERVICE_H__
bcc6 0:528034040a12 19 #define __BLE_PULSE_OXIMETER_SERVICE_H__
bcc6 0:528034040a12 20
bcc6 0:528034040a12 21 #include "ble/BLE.h"
bcc6 0:528034040a12 22
bcc6 0:528034040a12 23 class PulseOximeterService {
bcc6 0:528034040a12 24 public:
bcc6 0:528034040a12 25 PulseOximeterService(BLE &_ble, float spo2, float pr) :
bcc6 0:528034040a12 26 ble(_ble),
bcc6 0:528034040a12 27 plxMeasValueBytes(spo2, pr),
bcc6 0:528034040a12 28 plxFeatValueBytes(),
bcc6 0:528034040a12 29 rawValueBytes(),
bcc6 0:528034040a12 30 flagSigValueBytes(),
bcc6 0:528034040a12 31 plxSpotCheckMeasurementCharacteristic(0x2A5E/* UUID:PLX Spot-Check Measurement */,
bcc6 0:528034040a12 32 plxMeasValueBytes.getPointer(),
bcc6 0:528034040a12 33 PlxSpotCheckMeasurementValueBytes::SIZEOF_VALUE_BYTES,
bcc6 0:528034040a12 34 PlxSpotCheckMeasurementValueBytes::SIZEOF_VALUE_BYTES,
bcc6 0:528034040a12 35 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE,
bcc6 0:528034040a12 36 NULL, 0, false
bcc6 0:528034040a12 37 ),
bcc6 0:528034040a12 38 plxFeaturesCharacteristic(0x2A60/* UUID:PLX Features */,
bcc6 0:528034040a12 39 plxFeatValueBytes.getPointer(),
bcc6 0:528034040a12 40 PlxFeaturesValueBytes::SIZEOF_VALUE_BYTES,
bcc6 0:528034040a12 41 PlxFeaturesValueBytes::SIZEOF_VALUE_BYTES,
bcc6 0:528034040a12 42 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ,
bcc6 0:528034040a12 43 NULL, 0, false
bcc6 0:528034040a12 44 ),
bcc6 0:528034040a12 45 rawDataCharacteristic(0x2B00/* UUID:Self defined for raw data */,
bcc6 0:528034040a12 46 rawValueBytes.getPointer(),
bcc6 0:528034040a12 47 RawDataValueBytes::SIZEOF_VALUE_BYTES,
bcc6 0:528034040a12 48 RawDataValueBytes::SIZEOF_VALUE_BYTES,
bcc6 0:528034040a12 49 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY,
bcc6 0:528034040a12 50 NULL, 0, false
bcc6 0:528034040a12 51 ),
bcc6 0:528034040a12 52 signalCharacteristic(0x2B01/* UUID:Self defined for flag & signal */,
bcc6 0:528034040a12 53 flagSigValueBytes.getPointer(),
bcc6 0:528034040a12 54 FlagSignalValueBytes::SIZEOF_VALUE_BYTES,
bcc6 0:528034040a12 55 FlagSignalValueBytes::SIZEOF_VALUE_BYTES,
bcc6 0:528034040a12 56 GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ,
bcc6 0:528034040a12 57 NULL, 0, false
bcc6 0:528034040a12 58 )
bcc6 0:528034040a12 59 {
bcc6 0:528034040a12 60 GattCharacteristic *charTable[] = {
bcc6 0:528034040a12 61 &plxSpotCheckMeasurementCharacteristic,
bcc6 0:528034040a12 62 &plxFeaturesCharacteristic,
bcc6 0:528034040a12 63 &rawDataCharacteristic,
bcc6 0:528034040a12 64 &signalCharacteristic
bcc6 0:528034040a12 65 };
bcc6 0:528034040a12 66 GattService PulseOximeterService(0x1822/* UUID:Pulse Oximeter Service */, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
bcc6 0:528034040a12 67 ble.gattServer().addService(PulseOximeterService);
bcc6 0:528034040a12 68 }
bcc6 0:528034040a12 69
bcc6 0:528034040a12 70 void updatePlxMeas(float spo2, float pr) {
bcc6 0:528034040a12 71 plxMeasValueBytes.updatePlxSpotCheckMeasurement(spo2, pr);
bcc6 0:528034040a12 72 ble.gattServer().write(plxSpotCheckMeasurementCharacteristic.getValueHandle(),
bcc6 0:528034040a12 73 plxMeasValueBytes.getPointer(),
bcc6 0:528034040a12 74 PlxSpotCheckMeasurementValueBytes::SIZEOF_VALUE_BYTES
bcc6 0:528034040a12 75 );
bcc6 0:528034040a12 76 }
bcc6 0:528034040a12 77
bcc6 0:528034040a12 78 void updateRaw(uint8_t *raw) {
bcc6 0:528034040a12 79 rawValueBytes.updateRawData(raw);
bcc6 0:528034040a12 80 ble.gattServer().write(rawDataCharacteristic.getValueHandle(),
bcc6 0:528034040a12 81 rawValueBytes.getPointer(),
bcc6 0:528034040a12 82 RawDataValueBytes::SIZEOF_VALUE_BYTES
bcc6 0:528034040a12 83 );
bcc6 0:528034040a12 84 }
bcc6 0:528034040a12 85
bcc6 0:528034040a12 86 void updateStatusFlagAndSignalQuality(uint8_t statusFlag, uint8_t signalQuality) {
bcc6 0:528034040a12 87 flagSigValueBytes.updateFlagSignal(statusFlag, signalQuality);
bcc6 0:528034040a12 88 ble.gattServer().write(signalCharacteristic.getValueHandle(),
bcc6 0:528034040a12 89 flagSigValueBytes.getPointer(),
bcc6 0:528034040a12 90 FlagSignalValueBytes::SIZEOF_VALUE_BYTES
bcc6 0:528034040a12 91 );
bcc6 0:528034040a12 92 }
bcc6 0:528034040a12 93 //==================================================================================
bcc6 0:528034040a12 94 private:
bcc6 0:528034040a12 95 struct PlxSpotCheckMeasurementValueBytes {
bcc6 0:528034040a12 96 static const unsigned OFFSET_OF_FLAGS = 0;
bcc6 0:528034040a12 97 static const unsigned OFFSET_OF_SPO2 = 1;
bcc6 0:528034040a12 98 static const unsigned OFFSET_OF_PR = 3;
bcc6 0:528034040a12 99 static const unsigned SIZEOF_VALUE_BYTES = 5;
bcc6 0:528034040a12 100
bcc6 0:528034040a12 101 PlxSpotCheckMeasurementValueBytes(float spo2, float pr) : bytes() {
bcc6 0:528034040a12 102 bytes[OFFSET_OF_FLAGS] = 0x00; /* All fields aren't present */
bcc6 0:528034040a12 103 updatePlxSpotCheckMeasurement(spo2, pr);
bcc6 0:528034040a12 104 }
bcc6 0:528034040a12 105
bcc6 0:528034040a12 106 void updatePlxSpotCheckMeasurement(float spo2, float pr) {
bcc6 0:528034040a12 107 uint16_t sfloat_spo2 = ieee11073_SFLOAT(spo2);
bcc6 0:528034040a12 108 uint16_t sfloat_pr = ieee11073_SFLOAT(pr);
bcc6 0:528034040a12 109
bcc6 0:528034040a12 110 memcpy(&bytes[OFFSET_OF_SPO2], &sfloat_spo2, sizeof(uint16_t));
bcc6 0:528034040a12 111 memcpy(&bytes[OFFSET_OF_PR], &sfloat_pr, sizeof(uint16_t));
bcc6 0:528034040a12 112 }
bcc6 0:528034040a12 113
bcc6 0:528034040a12 114 uint8_t *getPointer(void) { return bytes; }
bcc6 0:528034040a12 115 const uint8_t *getPointer(void) const { return bytes; }
bcc6 0:528034040a12 116
bcc6 0:528034040a12 117 uint16_t ieee11073_SFLOAT(float v) {
bcc6 0:528034040a12 118 /* Bitmap: eeee_mmmm_mmmm_mmmm */
bcc6 0:528034040a12 119 /* Exponent: 4bits, Base10, 2'sComplement */
bcc6 0:528034040a12 120 /* Mantissa: 12bits, 2's Complement */
bcc6 0:528034040a12 121 uint8_t exponent = 0;
bcc6 0:528034040a12 122 uint16_t mantissa = (uint16_t)v;
bcc6 0:528034040a12 123 return (((uint16_t)exponent) << 12) | mantissa;
bcc6 0:528034040a12 124 }
bcc6 0:528034040a12 125
bcc6 0:528034040a12 126 uint8_t bytes[SIZEOF_VALUE_BYTES];
bcc6 0:528034040a12 127 };
bcc6 0:528034040a12 128 //-------------------------------------------------------------------------------
bcc6 0:528034040a12 129 struct PlxFeaturesValueBytes {
bcc6 0:528034040a12 130 static const unsigned OFFSET_OF_SUPPORTED_FEATURES = 0;
bcc6 0:528034040a12 131 static const unsigned SIZEOF_VALUE_BYTES = 2;
bcc6 0:528034040a12 132
bcc6 0:528034040a12 133 PlxFeaturesValueBytes() : bytes() {
bcc6 0:528034040a12 134 memset(bytes, 0x00, SIZEOF_VALUE_BYTES); /* All features aren't support */
bcc6 0:528034040a12 135 }
bcc6 0:528034040a12 136
bcc6 0:528034040a12 137 void updatePlxFeatures(uint16_t feat) {
bcc6 0:528034040a12 138 memcpy(&bytes[OFFSET_OF_SUPPORTED_FEATURES], &feat, SIZEOF_VALUE_BYTES);
bcc6 0:528034040a12 139 }
bcc6 0:528034040a12 140
bcc6 0:528034040a12 141 uint8_t *getPointer(void) { return bytes; }
bcc6 0:528034040a12 142 const uint8_t *getPointer(void) const { return bytes; }
bcc6 0:528034040a12 143
bcc6 0:528034040a12 144 uint8_t bytes[SIZEOF_VALUE_BYTES];
bcc6 0:528034040a12 145 };
bcc6 0:528034040a12 146 //-------------------------------------------------------------------------------
bcc6 0:528034040a12 147 struct RawDataValueBytes {
bcc6 0:528034040a12 148 static const unsigned OFFSET_OF_RAW = 0;
bcc6 0:528034040a12 149 static const unsigned SIZEOF_VALUE_BYTES = 18;
bcc6 0:528034040a12 150
bcc6 0:528034040a12 151 RawDataValueBytes() : bytes() {
bcc6 0:528034040a12 152 memset(bytes, 0x00, SIZEOF_VALUE_BYTES);
bcc6 0:528034040a12 153 }
bcc6 0:528034040a12 154
bcc6 0:528034040a12 155 void updateRawData(uint8_t *raw) {
bcc6 0:528034040a12 156 memcpy(&bytes[OFFSET_OF_RAW], raw, SIZEOF_VALUE_BYTES);
bcc6 0:528034040a12 157 }
bcc6 0:528034040a12 158
bcc6 0:528034040a12 159 uint8_t *getPointer(void) { return bytes; }
bcc6 0:528034040a12 160 const uint8_t *getPointer(void) const { return bytes; }
bcc6 0:528034040a12 161
bcc6 0:528034040a12 162 uint8_t bytes[SIZEOF_VALUE_BYTES];
bcc6 0:528034040a12 163 };
bcc6 0:528034040a12 164 //-------------------------------------------------------------------------------
bcc6 0:528034040a12 165 struct FlagSignalValueBytes {
bcc6 0:528034040a12 166 static const unsigned OFFSET_OF_FLAG = 0;
bcc6 0:528034040a12 167 static const unsigned OFFSET_OF_SIGNAL_QUALITY = 1;
bcc6 0:528034040a12 168 static const unsigned SIZEOF_VALUE_BYTES = 2;
bcc6 0:528034040a12 169
bcc6 0:528034040a12 170 FlagSignalValueBytes() : bytes() {
bcc6 0:528034040a12 171 memset(bytes, 0x00, SIZEOF_VALUE_BYTES);
bcc6 0:528034040a12 172 }
bcc6 0:528034040a12 173
bcc6 0:528034040a12 174 void updateFlagSignal(uint8_t statusFlag, uint8_t signalQuality) {
bcc6 0:528034040a12 175 bytes[OFFSET_OF_FLAG] = statusFlag;
bcc6 0:528034040a12 176 bytes[OFFSET_OF_SIGNAL_QUALITY] = signalQuality;
bcc6 0:528034040a12 177 }
bcc6 0:528034040a12 178
bcc6 0:528034040a12 179 uint8_t *getPointer(void) { return bytes; }
bcc6 0:528034040a12 180 const uint8_t *getPointer(void) const { return bytes; }
bcc6 0:528034040a12 181
bcc6 0:528034040a12 182 uint8_t bytes[SIZEOF_VALUE_BYTES];
bcc6 0:528034040a12 183 };
bcc6 0:528034040a12 184 //==================================================================================
bcc6 0:528034040a12 185 protected:
bcc6 0:528034040a12 186 BLE &ble;
bcc6 0:528034040a12 187
bcc6 0:528034040a12 188 PlxSpotCheckMeasurementValueBytes plxMeasValueBytes;
bcc6 0:528034040a12 189 PlxFeaturesValueBytes plxFeatValueBytes;
bcc6 0:528034040a12 190 RawDataValueBytes rawValueBytes;
bcc6 0:528034040a12 191 FlagSignalValueBytes flagSigValueBytes;
bcc6 0:528034040a12 192
bcc6 0:528034040a12 193 GattCharacteristic plxSpotCheckMeasurementCharacteristic;
bcc6 0:528034040a12 194 GattCharacteristic plxFeaturesCharacteristic;
bcc6 0:528034040a12 195 GattCharacteristic rawDataCharacteristic;
bcc6 0:528034040a12 196 GattCharacteristic signalCharacteristic;
bcc6 0:528034040a12 197 };
bcc6 0:528034040a12 198
bcc6 0:528034040a12 199 #endif /* #ifndef __BLE_PULSE_OXIMETER_SERVICE_H__*/