Firmware for Keewi v1 electronic board
Dependencies: BLE_API mbed nRF51822
Fork of Keewi_v1 by
Revision 1:e60b7762dd79, committed 2014-07-18
- Comitter:
- clemberto
- Date:
- Fri Jul 18 10:42:51 2014 +0000
- Parent:
- 0:4f6fbeb69f11
- Child:
- 2:8ebada2e4924
- Commit message:
- CSC profile connecting
Changed in this revision
BLE_API.lib | Show annotated file Show diff for this revision Revisions of this file |
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/BLE_API.lib Thu Jul 17 15:23:32 2014 +0000 +++ b/BLE_API.lib Fri Jul 18 10:42:51 2014 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#8890715aaf55 +http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#c163aa495b58
--- a/main.cpp Thu Jul 17 15:23:32 2014 +0000 +++ b/main.cpp Fri Jul 18 10:42:51 2014 +0000 @@ -20,45 +20,129 @@ BLEDevice ble; DigitalOut led1(LED1); -#define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console; +#define NEED_CONSOLE_OUTPUT 1 /* Set this if you need debug messages on the console; * it will have an impact on code-size and power consumption. */ #if NEED_CONSOLE_OUTPUT Serial pc(USBTX, USBRX); + #define DEBUG(...) { pc.printf(__VA_ARGS__); } #else #define DEBUG(...) /* nothing */ #endif /* #if NEED_CONSOLE_OUTPUT */ -const static char DEVICE_NAME[] = "Keewi_v1"; +const static char DEVICE_NAME[] = "Keewi v1"; -/* Heart Rate Service */ +// DEVICE_NAME_UUID = '2A00'; // Nordic fixed this to nRF5, can be written + +// Temperature 0-100 C, simulated +static uint8_t temperature = 32; +GattCharacteristic tempMeas(GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, (uint8_t *)temperature, sizeof(temperature), sizeof(temperature), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); +GattCharacteristic *temperatureChars[] = {&tempMeas }; +// TODO: config service Health thermo +GattService temperatureService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, temperatureChars, sizeof(temperatureChars) / sizeof(GattCharacteristic *)); + +// SYSTEM +static char systemId = 'A'; +GattCharacteristic systemID(GattCharacteristic::UUID_SYSTEM_ID_CHAR, (uint8_t *)systemId, sizeof(systemId), sizeof(systemId), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); +GattCharacteristic *systemChars[] = {&systemID }; +GattService systemService(GattService::UUID_DEVICE_INFORMATION_SERVICE, systemChars, sizeof(systemChars) / sizeof(GattCharacteristic *)); + +// MODEL +static char model[31] = "mBed nRF51822"; +GattCharacteristic modelID(GattCharacteristic::UUID_MODEL_NUMBER_STRING_CHAR, (uint8_t *)model, sizeof(model), sizeof(model), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); +GattCharacteristic *modelChars[] = {&modelID }; +GattService modelService(GattService::UUID_DEVICE_INFORMATION_SERVICE, modelChars, sizeof(modelChars) / sizeof(GattCharacteristic *)); + +// Firmware +static char fwversion[31] = "Firmware: 0216"; +GattCharacteristic fwChars(GattCharacteristic::UUID_FIRMWARE_REVISION_STRING_CHAR, (uint8_t *)fwversion, sizeof(fwversion), sizeof(fwversion), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); +GattCharacteristic *firmwareChars[] = {&fwChars }; +GattService firmwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, firmwareChars, sizeof(firmwareChars) / sizeof(GattCharacteristic *)); + +// Software +static char swversion[31] = "Sensor build (0001)"; +GattCharacteristic swChars(GattCharacteristic::UUID_SOFTWARE_REVISION_STRING_CHAR, (uint8_t *)swversion, sizeof(swversion), sizeof(swversion), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); +GattCharacteristic *softwareChars[] = {&swChars }; +GattService softwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, softwareChars, sizeof(softwareChars) / sizeof(GattCharacteristic *)); +// Hardware +static char hwversion[31] = "Sensor hw proto 0"; +GattCharacteristic hwChars(GattCharacteristic::UUID_HARDWARE_REVISION_STRING_CHAR, (uint8_t *)hwversion, sizeof(hwversion), sizeof(hwversion), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); +GattCharacteristic *hardwareChars[] = {&hwChars }; +GattService hardwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, hardwareChars, sizeof(hardwareChars) / sizeof(GattCharacteristic *)); +// Manufacturer +static char vendor[31] = "Busybee.io"; +GattCharacteristic vendorChars(GattCharacteristic::UUID_MANUFACTURER_NAME_STRING_CHAR, (uint8_t *)vendor, sizeof(vendor), sizeof(vendor), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); +GattCharacteristic *manufacturerChars[] = {&vendorChars }; +GattService manufacturerService(GattService::UUID_DEVICE_INFORMATION_SERVICE, manufacturerChars, sizeof(manufacturerChars) / sizeof(GattCharacteristic *)); +// Serial number +static char serial[31] = "1234567890"; +GattCharacteristic serialChars(GattCharacteristic::UUID_SERIAL_NUMBER_STRING_CHAR, (uint8_t *)serial, sizeof(serial), sizeof(serial), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); +GattCharacteristic *serialNumberChars[] = {&serialChars }; +GattService serialNumberService(GattService::UUID_DEVICE_INFORMATION_SERVICE, serialNumberChars, sizeof(serialNumberChars) / sizeof(GattCharacteristic *)); + +static uint8_t batteryLevel = 100; +GattCharacteristic batteryPercentage(GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, (uint8_t *)batteryLevel, sizeof(batteryLevel), sizeof(batteryLevel), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); +GattCharacteristic *batteryChars[] = {&batteryPercentage }; +GattService batteryService(GattService::UUID_BATTERY_SERVICE, batteryChars, sizeof(batteryChars) / sizeof(GattCharacteristic *)); + + +/* CSC Service */ /* Service: https://developer.bluetooth.org/gatt/services/Pages/ServiceViewer.aspx?u=org.bluetooth.service.cycling_speed_and_cadence.xml*/ /* CSC Mes: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.csc_measurement.xml */ /* Feature: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.csc_feature.xml */ /* Location: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.sensor_location.xml */ /* Control point: https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.sc_control_point.xml */ -static uint16_t cscCumulativeWheelRevolutions = 0; +static uint8_t cscWheelRevolutionDataSPresent = 1; +static uint8_t cscCrankRevolutionDataSPresent = 1; +static uint32_t cscCumulativeWheelRevolutions = 0; static uint16_t cscLastWheelEventTime = 0; // Unit is second & has a resolution of 1/1024s. static uint16_t cscCumulativeCrankRevolutions = 0; static uint16_t cscLastCrankEventTime = 0; // Unit is second & has a resolution of 1/1024s. +static uint8_t csc_mes_flags = (cscCrankRevolutionDataSPresent << 1) + cscWheelRevolutionDataSPresent; +static uint8_t 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 }; +//static uint8_t csc_mes[5] = { (cscCrankRevolutionDataSPresent << 1) + cscWheelRevolutionDataSPresent, cscCumulativeWheelRevolutions & 0x000000FF, cscLastWheelEventTime & 0x00FF, cscCumulativeCrankRevolutions & 0x00FF, cscLastCrankEventTime & 0x00FF }; + +GattCharacteristic cscMeasurement(GattCharacteristic::UUID_CSC_MEASUREMENT_CHAR, csc_mes, sizeof(csc_mes), sizeof(csc_mes), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); static bool cscWheelRevolutionDataSupported = true; static bool cscWCrankRevolutionDataSupported = true; -static bool cscMultipleSensorLocationsSupported = true; +static bool cscMultipleSensorLocationsSupported = false; +static uint8_t csc_feat_flags = (cscWheelRevolutionDataSupported << 2) + (cscWCrankRevolutionDataSupported << 1) + cscMultipleSensorLocationsSupported; +static uint8_t csc_feat[2] = { 0x00, csc_feat_flags }; +GattCharacteristic cscFeature(GattCharacteristic::UUID_CSC_FEATURE_CHAR, csc_feat, sizeof(csc_feat), sizeof(csc_feat), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); -static uint8_t csc_mes[4] = {cscCumulativeWheelRevolutions, cscLastWheelEventTime, cscCumulativeCrankRevolutions, cscLastCrankEventTime}; -static uint8_t csc_feat[3] = {cscWheelRevolutionDataSupported, cscWCrankRevolutionDataSupported, cscMultipleSensorLocationsSupported}; -GattCharacteristic cscMeasurement(GattCharacteristic::UUID_CSC_MEASUREMENT_CHAR, csc_mes, sizeof(csc_mes), sizeof(csc_mes), - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); static const uint8_t location = 0x09; /* Front Hub */ -GattCharacteristic cscMesLocation(GattCharacteristic::UUID_CSC_MEASUREMENT_CHAR, +GattCharacteristic cscLocation(GattCharacteristic::UUID_SENSOR_LOCATION, (uint8_t *)&location, sizeof(location), sizeof(location), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); -GattCharacteristic *cscChars[] = {&cscMeasurement, &cscMesLocation, }; + +/* TODO: implement a Write charac. cf. wheelSizeCallback() +GattCharacteristic cscCtrlPoint(GattCharacteristic::UUID_CSC_MEASUREMENT_CHAR, + (uint8_t *)&location, sizeof(location), sizeof(location), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE); +*/ +GattCharacteristic *cscChars[] = {&cscMeasurement, &cscFeature, }; //&cscLocation, &cscControlPoint, GattService cscService(GattService::UUID_CYCLING_SPEED_AND_CADENCE, cscChars, sizeof(cscChars) / sizeof(GattCharacteristic *)); -static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE}; +static const uint16_t uuid16_list[] = {GattService::UUID_CYCLING_SPEED_AND_CADENCE}; + +void wheelSizeCallback() { + DEBUG("Wheel size request ack!"); + return; +} + void disconnectionCallback(void) { @@ -68,22 +152,29 @@ } /** - * Triggered periodically by the 'ticker' interrupt; updates hrmCounter. + * Triggered periodically by the 'ticker' interrupt; updates cycling stats & battery value. */ void periodicCallback(void) { led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */ if (ble.getGapState().connected) { - /* Update the HRM measurement */ - /* First byte = 8-bit values, no extra info, Second byte = uint8_t HRM value */ - /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */ + DEBUG("Ble connected!"); + led1 = 1; + + /* Update the CSC measurement */ cscCumulativeWheelRevolutions+=3; - cscCumulativeCrankRevolutions++; + cscCumulativeCrankRevolutions+=2; + cscLastWheelEventTime++; + cscLastCrankEventTime++; - csc_mes[1] = cscCumulativeWheelRevolutions; - csc_mes[3] = cscCumulativeCrankRevolutions; - ble.updateCharacteristicValue(cscMeasurement.getHandle(), csc_mes, sizeof(csc_mes)); + // Update the battery level + batteryLevel--; + ble.updateCharacteristicValue(batteryPercentage.getHandle(), &batteryLevel, sizeof(batteryLevel)); + + 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 }; + + ble.updateCharacteristicValue(cscMeasurement.getHandle(), new_csc_mes, sizeof(new_csc_mes)); } } @@ -93,20 +184,32 @@ Ticker ticker; ticker.attach(periodicCallback, 1); - DEBUG("Initialising the nRF51822\n\r"); + DEBUG("Initialized the nRF51822\n\r"); ble.init(); ble.onDisconnection(disconnectionCallback); + ble.onDataSent(wheelSizeCallback); /* setup advertising */ - ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); // ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t*)uuid16_list, sizeof(uuid16_list)); - ble.accumulateAdvertisingPayload(GapAdvertisingData::CYCLING_SPEED_AND_CADENCE_SENSOR); + ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_CYCLING); ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ ble.startAdvertising(); + + /* Setup services */ + ble.addService(cscService); + /*ble.addService(batteryService); + //ble.addService(firmwareService); + ble.addService(manufacturerService); + ble.addService(modelService); + ble.addService(temperatureService); +*/ + DEBUG("Initialized the BLE stack\n\r"); - ble.addService(cscService); +DEBUG("feat val = %d - mes val = %d", csc_feat_flags, csc_mes_flags); +DEBUG("\r\n"); while (true) { ble.waitForEvent();