Firmware for Keewi v1 electronic board
Dependencies: BLE_API mbed nRF51822
Fork of Keewi_v1 by
main.cpp@2:8ebada2e4924, 2014-07-18 (annotated)
- Committer:
- clemberto
- Date:
- Fri Jul 18 16:54:16 2014 +0000
- Revision:
- 2:8ebada2e4924
- Parent:
- 1:e60b7762dd79
- Child:
- 3:6e08445f54f3
CSC profile simulated ok
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
clemberto | 0:4f6fbeb69f11 | 1 | /* mbed Microcontroller Library |
clemberto | 0:4f6fbeb69f11 | 2 | * Copyright (c) 2006-2013 ARM Limited |
clemberto | 0:4f6fbeb69f11 | 3 | * |
clemberto | 0:4f6fbeb69f11 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
clemberto | 0:4f6fbeb69f11 | 5 | * you may not use this file except in compliance with the License. |
clemberto | 0:4f6fbeb69f11 | 6 | * You may obtain a copy of the License at |
clemberto | 0:4f6fbeb69f11 | 7 | * |
clemberto | 0:4f6fbeb69f11 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
clemberto | 0:4f6fbeb69f11 | 9 | * |
clemberto | 0:4f6fbeb69f11 | 10 | * Unless required by applicable law or agreed to in writing, software |
clemberto | 0:4f6fbeb69f11 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
clemberto | 0:4f6fbeb69f11 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
clemberto | 0:4f6fbeb69f11 | 13 | * See the License for the specific language governing permissions and |
clemberto | 0:4f6fbeb69f11 | 14 | * limitations under the License. |
clemberto | 0:4f6fbeb69f11 | 15 | */ |
clemberto | 0:4f6fbeb69f11 | 16 | |
clemberto | 0:4f6fbeb69f11 | 17 | #include "mbed.h" |
clemberto | 0:4f6fbeb69f11 | 18 | #include "BLEDevice.h" |
clemberto | 0:4f6fbeb69f11 | 19 | |
clemberto | 0:4f6fbeb69f11 | 20 | BLEDevice ble; |
clemberto | 0:4f6fbeb69f11 | 21 | DigitalOut led1(LED1); |
clemberto | 0:4f6fbeb69f11 | 22 | |
clemberto | 1:e60b7762dd79 | 23 | #define NEED_CONSOLE_OUTPUT 1 /* Set this if you need debug messages on the console; |
clemberto | 0:4f6fbeb69f11 | 24 | * it will have an impact on code-size and power consumption. */ |
clemberto | 0:4f6fbeb69f11 | 25 | |
clemberto | 0:4f6fbeb69f11 | 26 | #if NEED_CONSOLE_OUTPUT |
clemberto | 0:4f6fbeb69f11 | 27 | Serial pc(USBTX, USBRX); |
clemberto | 1:e60b7762dd79 | 28 | |
clemberto | 0:4f6fbeb69f11 | 29 | #define DEBUG(...) { pc.printf(__VA_ARGS__); } |
clemberto | 0:4f6fbeb69f11 | 30 | #else |
clemberto | 0:4f6fbeb69f11 | 31 | #define DEBUG(...) /* nothing */ |
clemberto | 0:4f6fbeb69f11 | 32 | #endif /* #if NEED_CONSOLE_OUTPUT */ |
clemberto | 0:4f6fbeb69f11 | 33 | |
clemberto | 1:e60b7762dd79 | 34 | const static char DEVICE_NAME[] = "Keewi v1"; |
clemberto | 0:4f6fbeb69f11 | 35 | |
clemberto | 1:e60b7762dd79 | 36 | // DEVICE_NAME_UUID = '2A00'; // Nordic fixed this to nRF5, can be written |
clemberto | 1:e60b7762dd79 | 37 | |
clemberto | 1:e60b7762dd79 | 38 | // Temperature 0-100 C, simulated |
clemberto | 1:e60b7762dd79 | 39 | static uint8_t temperature = 32; |
clemberto | 1:e60b7762dd79 | 40 | GattCharacteristic tempMeas(GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, (uint8_t *)temperature, sizeof(temperature), sizeof(temperature), |
clemberto | 1:e60b7762dd79 | 41 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); |
clemberto | 1:e60b7762dd79 | 42 | GattCharacteristic *temperatureChars[] = {&tempMeas }; |
clemberto | 1:e60b7762dd79 | 43 | // TODO: config service Health thermo |
clemberto | 1:e60b7762dd79 | 44 | GattService temperatureService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, temperatureChars, sizeof(temperatureChars) / sizeof(GattCharacteristic *)); |
clemberto | 1:e60b7762dd79 | 45 | |
clemberto | 1:e60b7762dd79 | 46 | // SYSTEM |
clemberto | 1:e60b7762dd79 | 47 | static char systemId = 'A'; |
clemberto | 1:e60b7762dd79 | 48 | GattCharacteristic systemID(GattCharacteristic::UUID_SYSTEM_ID_CHAR, (uint8_t *)systemId, sizeof(systemId), sizeof(systemId), |
clemberto | 1:e60b7762dd79 | 49 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
clemberto | 1:e60b7762dd79 | 50 | GattCharacteristic *systemChars[] = {&systemID }; |
clemberto | 1:e60b7762dd79 | 51 | GattService systemService(GattService::UUID_DEVICE_INFORMATION_SERVICE, systemChars, sizeof(systemChars) / sizeof(GattCharacteristic *)); |
clemberto | 1:e60b7762dd79 | 52 | |
clemberto | 1:e60b7762dd79 | 53 | // MODEL |
clemberto | 1:e60b7762dd79 | 54 | static char model[31] = "mBed nRF51822"; |
clemberto | 1:e60b7762dd79 | 55 | GattCharacteristic modelID(GattCharacteristic::UUID_MODEL_NUMBER_STRING_CHAR, (uint8_t *)model, sizeof(model), sizeof(model), |
clemberto | 1:e60b7762dd79 | 56 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
clemberto | 1:e60b7762dd79 | 57 | GattCharacteristic *modelChars[] = {&modelID }; |
clemberto | 1:e60b7762dd79 | 58 | GattService modelService(GattService::UUID_DEVICE_INFORMATION_SERVICE, modelChars, sizeof(modelChars) / sizeof(GattCharacteristic *)); |
clemberto | 1:e60b7762dd79 | 59 | |
clemberto | 1:e60b7762dd79 | 60 | // Firmware |
clemberto | 1:e60b7762dd79 | 61 | static char fwversion[31] = "Firmware: 0216"; |
clemberto | 1:e60b7762dd79 | 62 | GattCharacteristic fwChars(GattCharacteristic::UUID_FIRMWARE_REVISION_STRING_CHAR, (uint8_t *)fwversion, sizeof(fwversion), sizeof(fwversion), |
clemberto | 1:e60b7762dd79 | 63 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
clemberto | 1:e60b7762dd79 | 64 | GattCharacteristic *firmwareChars[] = {&fwChars }; |
clemberto | 1:e60b7762dd79 | 65 | GattService firmwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, firmwareChars, sizeof(firmwareChars) / sizeof(GattCharacteristic *)); |
clemberto | 1:e60b7762dd79 | 66 | |
clemberto | 1:e60b7762dd79 | 67 | // Software |
clemberto | 1:e60b7762dd79 | 68 | static char swversion[31] = "Sensor build (0001)"; |
clemberto | 1:e60b7762dd79 | 69 | GattCharacteristic swChars(GattCharacteristic::UUID_SOFTWARE_REVISION_STRING_CHAR, (uint8_t *)swversion, sizeof(swversion), sizeof(swversion), |
clemberto | 1:e60b7762dd79 | 70 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
clemberto | 1:e60b7762dd79 | 71 | GattCharacteristic *softwareChars[] = {&swChars }; |
clemberto | 1:e60b7762dd79 | 72 | GattService softwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, softwareChars, sizeof(softwareChars) / sizeof(GattCharacteristic *)); |
clemberto | 1:e60b7762dd79 | 73 | // Hardware |
clemberto | 1:e60b7762dd79 | 74 | static char hwversion[31] = "Sensor hw proto 0"; |
clemberto | 1:e60b7762dd79 | 75 | GattCharacteristic hwChars(GattCharacteristic::UUID_HARDWARE_REVISION_STRING_CHAR, (uint8_t *)hwversion, sizeof(hwversion), sizeof(hwversion), |
clemberto | 1:e60b7762dd79 | 76 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
clemberto | 1:e60b7762dd79 | 77 | GattCharacteristic *hardwareChars[] = {&hwChars }; |
clemberto | 1:e60b7762dd79 | 78 | GattService hardwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, hardwareChars, sizeof(hardwareChars) / sizeof(GattCharacteristic *)); |
clemberto | 1:e60b7762dd79 | 79 | // Manufacturer |
clemberto | 1:e60b7762dd79 | 80 | static char vendor[31] = "Busybee.io"; |
clemberto | 1:e60b7762dd79 | 81 | GattCharacteristic vendorChars(GattCharacteristic::UUID_MANUFACTURER_NAME_STRING_CHAR, (uint8_t *)vendor, sizeof(vendor), sizeof(vendor), |
clemberto | 1:e60b7762dd79 | 82 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
clemberto | 1:e60b7762dd79 | 83 | GattCharacteristic *manufacturerChars[] = {&vendorChars }; |
clemberto | 1:e60b7762dd79 | 84 | GattService manufacturerService(GattService::UUID_DEVICE_INFORMATION_SERVICE, manufacturerChars, sizeof(manufacturerChars) / sizeof(GattCharacteristic *)); |
clemberto | 1:e60b7762dd79 | 85 | // Serial number |
clemberto | 1:e60b7762dd79 | 86 | static char serial[31] = "1234567890"; |
clemberto | 1:e60b7762dd79 | 87 | GattCharacteristic serialChars(GattCharacteristic::UUID_SERIAL_NUMBER_STRING_CHAR, (uint8_t *)serial, sizeof(serial), sizeof(serial), |
clemberto | 1:e60b7762dd79 | 88 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
clemberto | 1:e60b7762dd79 | 89 | GattCharacteristic *serialNumberChars[] = {&serialChars }; |
clemberto | 1:e60b7762dd79 | 90 | GattService serialNumberService(GattService::UUID_DEVICE_INFORMATION_SERVICE, serialNumberChars, sizeof(serialNumberChars) / sizeof(GattCharacteristic *)); |
clemberto | 1:e60b7762dd79 | 91 | |
clemberto | 1:e60b7762dd79 | 92 | static uint8_t batteryLevel = 100; |
clemberto | 1:e60b7762dd79 | 93 | GattCharacteristic batteryPercentage(GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, (uint8_t *)batteryLevel, sizeof(batteryLevel), sizeof(batteryLevel), |
clemberto | 1:e60b7762dd79 | 94 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); |
clemberto | 1:e60b7762dd79 | 95 | GattCharacteristic *batteryChars[] = {&batteryPercentage }; |
clemberto | 1:e60b7762dd79 | 96 | GattService batteryService(GattService::UUID_BATTERY_SERVICE, batteryChars, sizeof(batteryChars) / sizeof(GattCharacteristic *)); |
clemberto | 1:e60b7762dd79 | 97 | |
clemberto | 1:e60b7762dd79 | 98 | |
clemberto | 1:e60b7762dd79 | 99 | /* CSC Service */ |
clemberto | 0:4f6fbeb69f11 | 100 | /* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.cycling_speed_and_cadence.xml*/ |
clemberto | 0:4f6fbeb69f11 | 101 | /* CSC Mes: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.csc_measurement.xml */ |
clemberto | 0:4f6fbeb69f11 | 102 | /* Feature: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.csc_feature.xml */ |
clemberto | 0:4f6fbeb69f11 | 103 | /* Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.sensor_location.xml */ |
clemberto | 0:4f6fbeb69f11 | 104 | /* Control point: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.sc_control_point.xml */ |
clemberto | 1:e60b7762dd79 | 105 | static uint8_t cscWheelRevolutionDataSPresent = 1; |
clemberto | 1:e60b7762dd79 | 106 | static uint8_t cscCrankRevolutionDataSPresent = 1; |
clemberto | 1:e60b7762dd79 | 107 | static uint32_t cscCumulativeWheelRevolutions = 0; |
clemberto | 0:4f6fbeb69f11 | 108 | static uint16_t cscLastWheelEventTime = 0; // Unit is second & has a resolution of 1/1024s. |
clemberto | 0:4f6fbeb69f11 | 109 | static uint16_t cscCumulativeCrankRevolutions = 0; |
clemberto | 0:4f6fbeb69f11 | 110 | static uint16_t cscLastCrankEventTime = 0; // Unit is second & has a resolution of 1/1024s. |
clemberto | 1:e60b7762dd79 | 111 | static uint8_t csc_mes_flags = (cscCrankRevolutionDataSPresent << 1) + cscWheelRevolutionDataSPresent; |
clemberto | 2:8ebada2e4924 | 112 | static uint8_t csc_mes[] = { csc_mes_flags, |
clemberto | 2:8ebada2e4924 | 113 | cscCumulativeWheelRevolutions & 0x000000FF , |
clemberto | 2:8ebada2e4924 | 114 | cscCumulativeWheelRevolutions & 0x0000FF00 , |
clemberto | 2:8ebada2e4924 | 115 | cscCumulativeWheelRevolutions & 0x00FF0000 , |
clemberto | 2:8ebada2e4924 | 116 | cscCumulativeWheelRevolutions & 0xFF000000 , |
clemberto | 2:8ebada2e4924 | 117 | cscLastWheelEventTime & 0x00FF , |
clemberto | 2:8ebada2e4924 | 118 | cscLastWheelEventTime & 0xFF00 , |
clemberto | 2:8ebada2e4924 | 119 | cscCumulativeCrankRevolutions & 0x00FF , |
clemberto | 2:8ebada2e4924 | 120 | cscCumulativeCrankRevolutions & 0xFF00 , |
clemberto | 2:8ebada2e4924 | 121 | cscLastCrankEventTime & 0x00FF , |
clemberto | 2:8ebada2e4924 | 122 | cscLastCrankEventTime & 0xFF00 }; |
clemberto | 1:e60b7762dd79 | 123 | GattCharacteristic cscMeasurement(GattCharacteristic::UUID_CSC_MEASUREMENT_CHAR, csc_mes, sizeof(csc_mes), sizeof(csc_mes), |
clemberto | 1:e60b7762dd79 | 124 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); |
clemberto | 0:4f6fbeb69f11 | 125 | static bool cscWheelRevolutionDataSupported = true; |
clemberto | 0:4f6fbeb69f11 | 126 | static bool cscWCrankRevolutionDataSupported = true; |
clemberto | 1:e60b7762dd79 | 127 | static bool cscMultipleSensorLocationsSupported = false; |
clemberto | 1:e60b7762dd79 | 128 | static uint8_t csc_feat_flags = (cscWheelRevolutionDataSupported << 2) + (cscWCrankRevolutionDataSupported << 1) + cscMultipleSensorLocationsSupported; |
clemberto | 1:e60b7762dd79 | 129 | static uint8_t csc_feat[2] = { 0x00, csc_feat_flags }; |
clemberto | 1:e60b7762dd79 | 130 | GattCharacteristic cscFeature(GattCharacteristic::UUID_CSC_FEATURE_CHAR, csc_feat, sizeof(csc_feat), sizeof(csc_feat), |
clemberto | 1:e60b7762dd79 | 131 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
clemberto | 2:8ebada2e4924 | 132 | /* Sensor location */ |
clemberto | 2:8ebada2e4924 | 133 | enum BLE_SENSOR_LOCATION_LIST { /**< possible location for the CSC sensor. */ |
clemberto | 2:8ebada2e4924 | 134 | BLE_SENSOR_LOCATION_OTHER , |
clemberto | 2:8ebada2e4924 | 135 | BLE_SENSOR_LOCATION_TOP_OF_SHOE , |
clemberto | 2:8ebada2e4924 | 136 | BLE_SENSOR_LOCATION_IN_SHOE , |
clemberto | 2:8ebada2e4924 | 137 | BLE_SENSOR_LOCATION_HIP , |
clemberto | 2:8ebada2e4924 | 138 | BLE_SENSOR_LOCATION_FRONT_WHEEL , |
clemberto | 2:8ebada2e4924 | 139 | BLE_SENSOR_LOCATION_LEFT_CRANK , |
clemberto | 2:8ebada2e4924 | 140 | BLE_SENSOR_LOCATION_RIGHT_CRANK , |
clemberto | 2:8ebada2e4924 | 141 | BLE_SENSOR_LOCATION_LEFT_PEDAL , |
clemberto | 2:8ebada2e4924 | 142 | BLE_SENSOR_LOCATION_RIGHT_PEDAL , |
clemberto | 2:8ebada2e4924 | 143 | BLE_SENSOR_LOCATION_FRONT_HUB , |
clemberto | 2:8ebada2e4924 | 144 | BLE_SENSOR_LOCATION_REAR_DROPOUT, |
clemberto | 2:8ebada2e4924 | 145 | BLE_SENSOR_LOCATION_CHAINSTAY , |
clemberto | 2:8ebada2e4924 | 146 | BLE_SENSOR_LOCATION_REAR_WHEEL , |
clemberto | 2:8ebada2e4924 | 147 | BLE_SENSOR_LOCATION_REAR_HUB , |
clemberto | 2:8ebada2e4924 | 148 | BLE_SENSOR_LOCATION_CHEST |
clemberto | 2:8ebada2e4924 | 149 | }; |
clemberto | 2:8ebada2e4924 | 150 | static uint8_t keewi_v1_location_possibilities[] = { /**< possible location for Keewi. */ |
clemberto | 2:8ebada2e4924 | 151 | BLE_SENSOR_LOCATION_OTHER , |
clemberto | 2:8ebada2e4924 | 152 | BLE_SENSOR_LOCATION_FRONT_WHEEL , |
clemberto | 2:8ebada2e4924 | 153 | BLE_SENSOR_LOCATION_LEFT_CRANK , |
clemberto | 2:8ebada2e4924 | 154 | BLE_SENSOR_LOCATION_RIGHT_CRANK , |
clemberto | 2:8ebada2e4924 | 155 | BLE_SENSOR_LOCATION_FRONT_HUB , |
clemberto | 2:8ebada2e4924 | 156 | BLE_SENSOR_LOCATION_REAR_WHEEL , |
clemberto | 2:8ebada2e4924 | 157 | BLE_SENSOR_LOCATION_REAR_HUB |
clemberto | 2:8ebada2e4924 | 158 | }; |
clemberto | 2:8ebada2e4924 | 159 | static const uint8_t location = BLE_SENSOR_LOCATION_FRONT_WHEEL; // Keewi v1 speed sensor default location |
clemberto | 1:e60b7762dd79 | 160 | GattCharacteristic cscLocation(GattCharacteristic::UUID_SENSOR_LOCATION, |
clemberto | 0:4f6fbeb69f11 | 161 | (uint8_t *)&location, sizeof(location), sizeof(location), |
clemberto | 0:4f6fbeb69f11 | 162 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
clemberto | 2:8ebada2e4924 | 163 | |
clemberto | 2:8ebada2e4924 | 164 | // SC Control Point |
clemberto | 2:8ebada2e4924 | 165 | //TODO: implement a Write charac. cf. paramUpdateCallback() |
clemberto | 1:e60b7762dd79 | 166 | GattCharacteristic cscCtrlPoint(GattCharacteristic::UUID_CSC_MEASUREMENT_CHAR, |
clemberto | 1:e60b7762dd79 | 167 | (uint8_t *)&location, sizeof(location), sizeof(location), |
clemberto | 1:e60b7762dd79 | 168 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE); |
clemberto | 2:8ebada2e4924 | 169 | GattCharacteristic *cscChars[] = {&cscMeasurement, &cscFeature, &cscLocation, }; // &cscControlPoint, |
clemberto | 0:4f6fbeb69f11 | 170 | GattService cscService(GattService::UUID_CYCLING_SPEED_AND_CADENCE, cscChars, sizeof(cscChars) / sizeof(GattCharacteristic *)); |
clemberto | 0:4f6fbeb69f11 | 171 | |
clemberto | 2:8ebada2e4924 | 172 | /* Custom LBS service (led & button service) |
clemberto | 2:8ebada2e4924 | 173 | Switch: Front & rear lights |
clemberto | 2:8ebada2e4924 | 174 | Led: Alarm unlock |
clemberto | 2:8ebada2e4924 | 175 | */ |
clemberto | 2:8ebada2e4924 | 176 | #define LBS_UUID_BASE {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00} |
clemberto | 2:8ebada2e4924 | 177 | #define LBS_UUID_LED_CHAR 0x1525 |
clemberto | 2:8ebada2e4924 | 178 | #define LBS_UUID_BUTTON_CHAR 0x1524 |
clemberto | 2:8ebada2e4924 | 179 | static bool alarmState = false; |
clemberto | 2:8ebada2e4924 | 180 | static bool rLightState = true; |
clemberto | 2:8ebada2e4924 | 181 | static bool fLightState = true; |
clemberto | 2:8ebada2e4924 | 182 | static uint8_t lbs_sw_flags = (fLightState << 2) + (rLightState << 1) + alarmState; |
clemberto | 2:8ebada2e4924 | 183 | GattCharacteristic lbsSwitches(LBS_UUID_BUTTON_CHAR, |
clemberto | 2:8ebada2e4924 | 184 | (uint8_t *)&lbs_sw_flags, sizeof(lbs_sw_flags), sizeof(lbs_sw_flags), |
clemberto | 2:8ebada2e4924 | 185 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE); |
clemberto | 2:8ebada2e4924 | 186 | GattCharacteristic lbsIndicators(LBS_UUID_LED_CHAR, |
clemberto | 2:8ebada2e4924 | 187 | (uint8_t *)&location, sizeof(location), sizeof(location), |
clemberto | 2:8ebada2e4924 | 188 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
clemberto | 2:8ebada2e4924 | 189 | GattCharacteristic *lbsChars[] = {&lbsSwitches, &lbsIndicators, }; |
clemberto | 2:8ebada2e4924 | 190 | #define LBS_UUID_SERVICE 0x1523 |
clemberto | 2:8ebada2e4924 | 191 | GattService lbsService(LBS_UUID_SERVICE, lbsChars, sizeof(lbsChars) / sizeof(GattCharacteristic *)); |
clemberto | 1:e60b7762dd79 | 192 | |
clemberto | 2:8ebada2e4924 | 193 | /* Custom UART Service for sending ride data |
clemberto | 2:8ebada2e4924 | 194 | |
clemberto | 2:8ebada2e4924 | 195 | */ |
clemberto | 2:8ebada2e4924 | 196 | #define BLE_UUID_NUS_SERVICE 0x0001 /**< The UUID of the Nordic UART Service. */ |
clemberto | 2:8ebada2e4924 | 197 | #define BLE_UUID_NUS_TX_CHARACTERISTIC 0x0002 /**< The UUID of the TX Characteristic. */ |
clemberto | 2:8ebada2e4924 | 198 | #define BLE_UUID_NUS_RX_CHARACTERISTIC 0x0003 /**< The UUID of the RX Characteristic. */ |
clemberto | 2:8ebada2e4924 | 199 | #define BLE_NUS_MAX_DATA_LEN (GATT_MTU_SIZE_DEFAULT - 3) /**< Maximum length of data (in bytes) that can be transmitted by the Nordic UART service module to the peer. */ |
clemberto | 2:8ebada2e4924 | 200 | #define BLE_NUS_MAX_RX_CHAR_LEN BLE_NUS_MAX_DATA_LEN /**< Maximum length of the RX Characteristic (in bytes). */ |
clemberto | 2:8ebada2e4924 | 201 | #define BLE_NUS_MAX_TX_CHAR_LEN 20 /**< Maximum length of the TX Characteristic (in bytes). */ |
clemberto | 2:8ebada2e4924 | 202 | |
clemberto | 2:8ebada2e4924 | 203 | |
clemberto | 2:8ebada2e4924 | 204 | |
clemberto | 2:8ebada2e4924 | 205 | /* List of all available services */ |
clemberto | 2:8ebada2e4924 | 206 | static const uint16_t uuid16_list[] = { |
clemberto | 2:8ebada2e4924 | 207 | GattService::UUID_CYCLING_SPEED_AND_CADENCE, |
clemberto | 2:8ebada2e4924 | 208 | GattService::UUID_BATTERY_SERVICE, |
clemberto | 2:8ebada2e4924 | 209 | GattService::UUID_CURRENT_TIME_SERVICE, |
clemberto | 2:8ebada2e4924 | 210 | LBS_UUID_SERVICE, |
clemberto | 2:8ebada2e4924 | 211 | }; |
clemberto | 2:8ebada2e4924 | 212 | |
clemberto | 2:8ebada2e4924 | 213 | |
clemberto | 2:8ebada2e4924 | 214 | void paramUpdateCallback() { |
clemberto | 2:8ebada2e4924 | 215 | DEBUG("Param change request ack!"); |
clemberto | 1:e60b7762dd79 | 216 | return; |
clemberto | 1:e60b7762dd79 | 217 | } |
clemberto | 2:8ebada2e4924 | 218 | |
clemberto | 0:4f6fbeb69f11 | 219 | |
clemberto | 0:4f6fbeb69f11 | 220 | void disconnectionCallback(void) |
clemberto | 0:4f6fbeb69f11 | 221 | { |
clemberto | 0:4f6fbeb69f11 | 222 | DEBUG("Disconnected!\n\r"); |
clemberto | 0:4f6fbeb69f11 | 223 | DEBUG("Restarting the advertising process\n\r"); |
clemberto | 0:4f6fbeb69f11 | 224 | ble.startAdvertising(); |
clemberto | 0:4f6fbeb69f11 | 225 | } |
clemberto | 0:4f6fbeb69f11 | 226 | |
clemberto | 0:4f6fbeb69f11 | 227 | /** |
clemberto | 1:e60b7762dd79 | 228 | * Triggered periodically by the 'ticker' interrupt; updates cycling stats & battery value. |
clemberto | 0:4f6fbeb69f11 | 229 | */ |
clemberto | 0:4f6fbeb69f11 | 230 | void periodicCallback(void) |
clemberto | 0:4f6fbeb69f11 | 231 | { |
clemberto | 0:4f6fbeb69f11 | 232 | led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ |
clemberto | 0:4f6fbeb69f11 | 233 | |
clemberto | 0:4f6fbeb69f11 | 234 | if (ble.getGapState().connected) { |
clemberto | 1:e60b7762dd79 | 235 | led1 = 1; |
clemberto | 1:e60b7762dd79 | 236 | |
clemberto | 2:8ebada2e4924 | 237 | // Simulate evolution of battery level |
clemberto | 1:e60b7762dd79 | 238 | batteryLevel--; |
clemberto | 1:e60b7762dd79 | 239 | ble.updateCharacteristicValue(batteryPercentage.getHandle(), &batteryLevel, sizeof(batteryLevel)); |
clemberto | 1:e60b7762dd79 | 240 | |
clemberto | 2:8ebada2e4924 | 241 | // Simulate evolution of Speed & Cadence |
clemberto | 2:8ebada2e4924 | 242 | cscCumulativeWheelRevolutions+=5; |
clemberto | 2:8ebada2e4924 | 243 | cscCumulativeCrankRevolutions+=2; |
clemberto | 2:8ebada2e4924 | 244 | cscLastWheelEventTime+=1000; |
clemberto | 2:8ebada2e4924 | 245 | cscLastCrankEventTime+=1000; |
clemberto | 1:e60b7762dd79 | 246 | uint8_t new_csc_mes[] = {csc_mes_flags, cscCumulativeWheelRevolutions & 0x000000FF, cscCumulativeWheelRevolutions & 0x0000FF00, cscCumulativeWheelRevolutions & 0x00FF0000, cscCumulativeWheelRevolutions & 0xFF000000, cscLastWheelEventTime & 0x00FF, cscLastWheelEventTime & 0xFF00, cscCumulativeCrankRevolutions & 0x00FF, cscCumulativeCrankRevolutions & 0xFF00, cscLastCrankEventTime & 0x00FF, cscLastCrankEventTime & 0xFF00 }; |
clemberto | 2:8ebada2e4924 | 247 | ble.updateCharacteristicValue(cscMeasurement.getHandle(), new_csc_mes, sizeof(new_csc_mes)); |
clemberto | 1:e60b7762dd79 | 248 | |
clemberto | 2:8ebada2e4924 | 249 | // Notify alarm & lights status |
clemberto | 2:8ebada2e4924 | 250 | static uint8_t new_lbs_sw_flags = (fLightState << 2) + (rLightState << 1) + alarmState; |
clemberto | 2:8ebada2e4924 | 251 | ble.updateCharacteristicValue(lbsSwitches.getHandle(), new_lbs_sw_flags, sizeof(new_lbs_sw_flags)); |
clemberto | 2:8ebada2e4924 | 252 | |
clemberto | 2:8ebada2e4924 | 253 | DEBUG("led val = %d - mes val = %d\r\n", csc_feat_flags, csc_mes_flags); |
clemberto | 2:8ebada2e4924 | 254 | |
clemberto | 0:4f6fbeb69f11 | 255 | } |
clemberto | 0:4f6fbeb69f11 | 256 | } |
clemberto | 0:4f6fbeb69f11 | 257 | |
clemberto | 0:4f6fbeb69f11 | 258 | int main(void) |
clemberto | 0:4f6fbeb69f11 | 259 | { |
clemberto | 0:4f6fbeb69f11 | 260 | led1 = 1; |
clemberto | 0:4f6fbeb69f11 | 261 | Ticker ticker; |
clemberto | 0:4f6fbeb69f11 | 262 | ticker.attach(periodicCallback, 1); |
clemberto | 0:4f6fbeb69f11 | 263 | |
clemberto | 1:e60b7762dd79 | 264 | DEBUG("Initialized the nRF51822\n\r"); |
clemberto | 0:4f6fbeb69f11 | 265 | ble.init(); |
clemberto | 0:4f6fbeb69f11 | 266 | ble.onDisconnection(disconnectionCallback); |
clemberto | 2:8ebada2e4924 | 267 | ble.onDataSent(paramUpdateCallback); |
clemberto | 0:4f6fbeb69f11 | 268 | |
clemberto | 0:4f6fbeb69f11 | 269 | /* setup advertising */ |
clemberto | 1:e60b7762dd79 | 270 | ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); // |
clemberto | 0:4f6fbeb69f11 | 271 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t*)uuid16_list, sizeof(uuid16_list)); |
clemberto | 1:e60b7762dd79 | 272 | ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_CYCLING); |
clemberto | 0:4f6fbeb69f11 | 273 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
clemberto | 0:4f6fbeb69f11 | 274 | ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
clemberto | 0:4f6fbeb69f11 | 275 | ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ |
clemberto | 0:4f6fbeb69f11 | 276 | ble.startAdvertising(); |
clemberto | 1:e60b7762dd79 | 277 | |
clemberto | 1:e60b7762dd79 | 278 | /* Setup services */ |
clemberto | 1:e60b7762dd79 | 279 | ble.addService(cscService); |
clemberto | 2:8ebada2e4924 | 280 | ble.addService(batteryService); |
clemberto | 1:e60b7762dd79 | 281 | //ble.addService(firmwareService); |
clemberto | 1:e60b7762dd79 | 282 | ble.addService(manufacturerService); |
clemberto | 2:8ebada2e4924 | 283 | ble.addService(lbsService); |
clemberto | 1:e60b7762dd79 | 284 | ble.addService(temperatureService); |
clemberto | 2:8ebada2e4924 | 285 | |
clemberto | 1:e60b7762dd79 | 286 | DEBUG("Initialized the BLE stack\n\r"); |
clemberto | 0:4f6fbeb69f11 | 287 | |
clemberto | 0:4f6fbeb69f11 | 288 | while (true) { |
clemberto | 0:4f6fbeb69f11 | 289 | ble.waitForEvent(); |
clemberto | 0:4f6fbeb69f11 | 290 | } |
clemberto | 0:4f6fbeb69f11 | 291 | } |