Auto updating alarm watch - accepts alarm settings from a BLE device like a Raspberry Pi and buzzes at the appropriate time - also displays binary time
Dependencies: BLE_API mbed-src nRF51822 nrf51_rtc
Revision 6:4a12e0f03381, committed 2016-03-01
- Comitter:
- Bobty
- Date:
- Tue Mar 01 13:03:32 2016 +0000
- Parent:
- 5:2682353a8c32
- Commit message:
- Completed work on display and alarm
Changed in this revision
diff -r 2682353a8c32 -r 4a12e0f03381 LedDisplay.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/LedDisplay.h Tue Mar 01 13:03:32 2016 +0000 @@ -0,0 +1,184 @@ +#ifndef __LED_DISPLAY_H__ +#define __LED_DISPLAY_H__ + +#include "nrf51_rtc.h" + +// Hour LEDs +const int numHourPins = 5; +DigitalOut hourPins[numHourPins] = { p0, p1, p2, p3, p4 }; + +// Minute LEDs +const int numMinPins = 6; +DigitalOut minPins[numMinPins] = { p23, p24, p25, p28, p29, p30 }; + +// Status LEDs +const int numStatusPins = 3; +DigitalOut statusPins[numStatusPins] = { p6, p10, p11 }; + +// Status bit numbers +const int STATUS_BITS_EXTRA_BIT = 0; +const int STATUS_BITS_SECS_BIT = 1; +const int STATUS_BITS_ALARM_BIT = 2; + +void callbackForLEDMuxing(); + +class LedDisplay +{ +public: + enum DispType { + DispType_None = 0, + DispType_CurTime = 1, + DispType_AlarmTime = 2, + }; + + LedDisplay() + { + _dispType = DispType_None; + _timeDisplayStartTime = 0; + _secsToDisplayFor = 0; + _timeToShow_Hour = 0; + _timeToShow_Min = 0; + _statusBits = 0; + _curTimeLEDBitPos = 0; + clear(); + } + + void clear() + { + // Clear all LEDs + for (int i = 0; i < numHourPins; i++) + hourPins[i] = 0; + for (int i = 0; i < numMinPins; i++) + minPins[i] = 0; + for (int i = 0; i < numStatusPins; i++) + statusPins[i] = 0; + } + + void start(time_t timeToShow, DispType dispType, int secsToDisplayFor, bool extraInfoBit) + { + // Save time to show + _timeToShow_time_t = timeToShow; + _dispType = dispType; + _secsToDisplayFor = secsToDisplayFor; + if (dispType == DispType_None) + return; + + // Convert time to binary displayable info (localtime) + if (((int)_timeToShow_time_t != -1) && ((int)_timeToShow_time_t != 0)) + { + struct tm * timeinfo; + timeinfo = localtime (&_timeToShow_time_t); + _timeToShow_Hour = timeinfo->tm_hour; + _timeToShow_Min = timeinfo->tm_min; + } + else + { + _timeToShow_Hour = 0; + _timeToShow_Min = 0; + } + + // Status - extra bit + _statusBits = 0; + if (extraInfoBit) + _statusBits |= (1 << STATUS_BITS_EXTRA_BIT); + + // Status - alarm bit + if (dispType == DispType_AlarmTime) + _statusBits |= (1 << STATUS_BITS_ALARM_BIT); + else + _statusBits &= (~(1 << STATUS_BITS_ALARM_BIT)); + + // Record time we started displaying + time_t curTime = rtc.time(); + _timeDisplayStartTime = curTime; + + // Ready to display on next callback + _curTimeLEDBitPos = 0; + _timerForLEDMuxing.attach(callbackForLEDMuxing, 0.001); + + } + + void stop() + { + _dispType = DispType_None; + } + + void showNext() + { + // Clear LEDs + clear(); + + // Check display type + if (_dispType == DispType_None) + return; + + // Get current time + time_t curTime = rtc.time(); + + // Stop displaying time after a certain number of seconds + if (curTime - _timeDisplayStartTime >= _secsToDisplayFor) + { + stop(); + return; + } + + // Flash status seconds + if (_dispType == DispType_CurTime) + { + if ((curTime % 2) == 0) + _statusBits |= (1 << STATUS_BITS_SECS_BIT); + else + _statusBits &= (~(1 << STATUS_BITS_SECS_BIT)); + } + + // Display binary time + int mask = 1 << _curTimeLEDBitPos; + if ((_curTimeLEDBitPos < numHourPins) && ((_timeToShow_Hour & mask) != 0)) + hourPins[_curTimeLEDBitPos] = 1; + if ((_curTimeLEDBitPos < numMinPins) && ((_timeToShow_Min & mask) != 0)) + minPins[_curTimeLEDBitPos] = 1; + if ((_curTimeLEDBitPos < numStatusPins) && ((_statusBits & mask) != 0)) + statusPins[_curTimeLEDBitPos] = 1; + + // Next bit pos + _curTimeLEDBitPos++; + if (_curTimeLEDBitPos > numMinPins) + _curTimeLEDBitPos = 0; + + // Set for another callback + _timerForLEDMuxing.attach(callbackForLEDMuxing, 0.001); + } + +private: + + // Display type + DispType _dispType; + + // Time to show + time_t _timeToShow_time_t; + int _timeToShow_Hour; + int _timeToShow_Min; + + // Time displaying started and time to show for + time_t _timeDisplayStartTime; + int _secsToDisplayFor; + + // Status bit + int _statusBits; + + // Timeout used to display LEDs + Timeout _timerForLEDMuxing; + + // Cur time disp info + int _curTimeLEDBitPos; +}; + +static LedDisplay ledDisplay; + +void callbackForLEDMuxing() +{ + ledDisplay.showNext(); +} + + +#endif /* #ifndef __BLE_BUTTON_SERVICE_H__ */ \ No newline at end of file
diff -r 2682353a8c32 -r 4a12e0f03381 WatchTimeService.h --- a/WatchTimeService.h Mon Dec 14 22:58:31 2015 +0000 +++ b/WatchTimeService.h Tue Mar 01 13:03:32 2016 +0000 @@ -4,38 +4,73 @@ #ifndef __BLE_WATCHTIME_SERVICE_H__ #define __BLE_WATCHTIME_SERVICE_H__ -//typedef void (*GetCurTimeCallbackFn)(uint8_t* curWatchTime) - class WatchTimeService { public: static const int WatchTime_BlockSize = 7; const static uint16_t WATCHTIME_SERVICE_UUID = 0xFE32; const static uint16_t WATCHTIME_STATE_CHARACTERISTIC_UUID = 0xFE33; + const static uint16_t ALARMTIME_STATE_CHARACTERISTIC_UUID = 0xFE34; - WatchTimeService(BLE &ble, uint8_t* pInitialWatchTime) : + WatchTimeService(BLE &ble, uint8_t* pInitialWatchTime, uint8_t* pInitialAlarmTime) : _ble(ble), - _watchTimeVal(WATCHTIME_STATE_CHARACTERISTIC_UUID, pInitialWatchTime, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) + _watchTimeVal(WATCHTIME_STATE_CHARACTERISTIC_UUID, pInitialWatchTime, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), + _alarmTimeVal(ALARMTIME_STATE_CHARACTERISTIC_UUID, pInitialAlarmTime, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { - GattCharacteristic *charTable[] = {&_watchTimeVal}; + GattCharacteristic *charTable[] = {&_watchTimeVal, &_alarmTimeVal}; GattService watchTimeService(WatchTimeService::WATCHTIME_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); _ble.gattServer().addService(watchTimeService); } - void writeWatchTime(uint8_t* pWatchTime) + void writeWatchTime(time_t timeToWrite) { - _ble.gattServer().write(_watchTimeVal.getValueHandle(), pWatchTime, WatchTime_BlockSize); + uint8_t watchTime[WatchTimeService::WatchTime_BlockSize]; + unixTimeToWatchTime(timeToWrite, watchTime); + _ble.gattServer().write(_watchTimeVal.getValueHandle(), watchTime, WatchTime_BlockSize); } - GattAttribute::Handle_t getValueHandle() + GattAttribute::Handle_t getWatchTimeValueHandle() { return _watchTimeVal.getValueHandle(); } + + GattAttribute::Handle_t getAlarmTimeValueHandle() + { + return _alarmTimeVal.getValueHandle(); + } + + static time_t watchTimeToUnixTime(const uint8_t* pWatchTime) + { + struct tm tminfo; + tminfo.tm_year = int(pWatchTime[0])*256 + pWatchTime[1] - 1900; + tminfo.tm_mon = pWatchTime[2] - 1; + tminfo.tm_mday = pWatchTime[3]; + tminfo.tm_hour = pWatchTime[4]; + tminfo.tm_min = pWatchTime[5]; + tminfo.tm_sec = pWatchTime[6]; + tminfo.tm_isdst = -1; + time_t timest = mktime(&tminfo); + return timest; + } + + static void unixTimeToWatchTime(time_t unixTime, uint8_t* pWatchTime) + { + // Convert to localtime + struct tm * timeinfo; + timeinfo = localtime (&unixTime); + pWatchTime[0] = (timeinfo->tm_year + 1900) / 256; + pWatchTime[1] = (timeinfo->tm_year + 1900) % 256; + pWatchTime[2] = timeinfo->tm_mon + 1; + pWatchTime[3] = timeinfo->tm_mday; + pWatchTime[4] = timeinfo->tm_hour; + pWatchTime[5] = timeinfo->tm_min; + pWatchTime[6] = timeinfo->tm_sec; + } private: BLE &_ble; ReadWriteArrayGattCharacteristic<uint8_t, WatchTime_BlockSize> _watchTimeVal; -// GetCurTimeCallbackFn _pGetCurTimeCallback; + ReadWriteArrayGattCharacteristic<uint8_t, WatchTime_BlockSize> _alarmTimeVal; }; #endif /* #ifndef __BLE_WATCHTIME_SERVICE_H__ */
diff -r 2682353a8c32 -r 4a12e0f03381 main.cpp --- a/main.cpp Mon Dec 14 22:58:31 2015 +0000 +++ b/main.cpp Tue Mar 01 13:03:32 2016 +0000 @@ -4,188 +4,136 @@ #include "mbed.h" #include "BLE.h" -#include "ButtonService.h" +#include "LedDisplay.h" #include "WatchTimeService.h" #include "nrf51_rtc.h" +#include "DFUService.h" // BLE platform BLE ble; -// Hour LEDs -DigitalOut hourPins[5] = { p0, p1, p2, p3, p4 }; - -// Minute LEDs -DigitalOut minPins[6] = { p23, p24, p25, p28, p29, p30 }; - // Button press to show time InterruptIn button(p5); +// Vibration motor +DigitalOut vibrationMotor(p9); + // Device name - this is the visible name of device on BLE const static char DEVICE_NAME[] = "JoesAlarm"; // UUIDs of services offered -static const uint16_t uuid16_list[] = {ButtonService::BUTTON_SERVICE_UUID, WatchTimeService::WATCHTIME_SERVICE_UUID}; +static const uint16_t uuid16_list[] = {WatchTimeService::WATCHTIME_SERVICE_UUID}; // Service offering to read and set the time on the watch WatchTimeService *pWatchTimeService; -// Time display state variables -const int timeDisplayState_None = 0; -const int timeDisplayState_ShowTime = 1; -const int timeDisplayState_ShowAlarm = 2; -int timeDisplayState = timeDisplayState_None; -uint8_t curBinaryLedDisplayVal[WatchTimeService::WatchTime_BlockSize]; -int timeDisplayLastButtonTime = 0; -const int timeDisplayShowTimeSecs = 10; -const int timeDisplayMoveToShowAlarmSecs = 5; +// Time watch button last pressed +time_t watchButtonLastPressed = 0; -// Cur time disp info -int curTimeLEDBitPos = 0; +// Time between periodic callbacks used to keep RTC functioning +const int PERIODIC_CALLBACK_SECS = 2; + +// Time for double press detection (2 presses within this number of secs == double press) +const int DOUBLE_PRESS_SECS = 2; -// TEST CODE -int callbackCount = 0; -uint8_t testbuf[WatchTimeService::WatchTime_BlockSize]; -time_t retval = 0; -int servcode = 0; -int buflen = 0; -int mycode = 0; -int offs = 0; -int butcode = 0; -ButtonService *buttonServicePtr; -Ticker periodicCallbackToKeepTimerGoing; -Timeout timerForLEDMuxing; +// Time to display LEDs +const int DISPLAY_ON_TIME = 5; + +// Alarm on time +const int ALARM_ON_TIME = 120; + +// Control whether time characteristic is updated when BLE is connected +// This is currently set false because it is probably not needed - really just a debug function +// and, since the code runs in an interrupt, it may be brittle although it seems to work ok +int UPDATE_BLE_TIME_WHEN_CONNECTED = false; + +// Time alarm set to +time_t alarmSetTime = 0; -time_t watchTimeToUnix(const uint8_t* pWatchTime) +// Ticker needed to keep the RTC from losing time on counter rollover +Ticker periodicCallbackToKeepTimerGoing; + +// Timeout to avoid bounce on button +Timeout buttonDebounceTimeout; +bool buttonAlreadyPressed = false; + +// Alarm state +enum AlarmState { - struct tm tminfo; - tminfo.tm_year = int(pWatchTime[0])*256 + pWatchTime[1] - 1900; - tminfo.tm_mon = pWatchTime[2] - 1; - tminfo.tm_mday = pWatchTime[3]; - tminfo.tm_hour = pWatchTime[4]; - tminfo.tm_min = pWatchTime[5]; - tminfo.tm_sec = pWatchTime[6]; - tminfo.tm_isdst = -1; - time_t timest = mktime(&tminfo); - return timest; -} + AlarmState_off, + AlarmState_on_sounding, + AlarmState_on_resting +}; +AlarmState alarmState = AlarmState_off; -void unixTimeToWatchTime(time_t unixTime, uint8_t* pWatchTime) +// Time alarm was activated +time_t alarmInitiatedTime = 0; + +// Set alarm on +void AlarmOn() { - // Convert to localtime - struct tm * timeinfo; - timeinfo = localtime (&unixTime); - pWatchTime[0] = (timeinfo->tm_year + 1900) / 256; - pWatchTime[1] = (timeinfo->tm_year + 1900) % 256; - pWatchTime[2] = timeinfo->tm_mon + 1; - pWatchTime[3] = timeinfo->tm_mday; - pWatchTime[4] = timeinfo->tm_hour; - pWatchTime[5] = timeinfo->tm_min; - pWatchTime[6] = timeinfo->tm_sec; + alarmState = AlarmState_on_sounding; + vibrationMotor = 1; + alarmInitiatedTime = rtc.time(); } -int watchTimeToBCD(const uint8_t* pWatchTime) +// Set alarm on +void AlarmOff() { - // Simply combine the hour and minute values in a 4 digit BCD number - int bcdHourMin = pWatchTime[4] / 10; - bcdHourMin = (bcdHourMin << 4) + pWatchTime[4] % 10; - bcdHourMin = (bcdHourMin << 4) + pWatchTime[5] / 10; - bcdHourMin = (bcdHourMin << 4) + pWatchTime[5] % 10; - return bcdHourMin; -} - -void callbackForLEDMuxing(); - -void clearTimeLEDs() -{ - for (int i = 0; i < 5; i++) - hourPins[i] = 0; - for (int i = 0; i < 6; i++) - minPins[i] = 0; + alarmState = AlarmState_off; + vibrationMotor = 0; } -//uint8_t* GetCurTimeAsWatchTime() -//{ -// // Get current time and convert to displayable time -// time_t rawtime=rtc.time(); -// unixTimeToWatchTime(rawtime, curBinaryLedDisplayVal); -//} - -void nextShowingTimeLEDs() +// Button debounce callback +void buttonDebounceCallback() { - // Get current time and convert to displayable time - time_t rawtime=rtc.time(); - unixTimeToWatchTime(rawtime, curBinaryLedDisplayVal); - - // Clear LEDs - clearTimeLEDs(); - - // Stop displaying time after a certain number of seconds - if (rawtime - timeDisplayLastButtonTime >= timeDisplayShowTimeSecs) - return; - - // Display binary time - int hours = curBinaryLedDisplayVal[4]; - int mins = curBinaryLedDisplayVal[5]; - int mask = 1 << curTimeLEDBitPos; - if ((curTimeLEDBitPos < 5) && ((hours & mask) != 0)) - hourPins[curTimeLEDBitPos] = 1; - if ((mins & mask) != 0) - minPins[curTimeLEDBitPos] = 1; - curTimeLEDBitPos++; - if (curTimeLEDBitPos > 5) - curTimeLEDBitPos = 0; - - // Set for another callback - timerForLEDMuxing.attach(callbackForLEDMuxing, 0.001); -} - -void callbackForLEDMuxing() -{ - nextShowingTimeLEDs(); + buttonAlreadyPressed = false; } -void startShowingTimeLEDs() +bool datesAreTheSame(time_t dateTime1, time_t dateTime2) { - curTimeLEDBitPos = 0; - timerForLEDMuxing.attach(callbackForLEDMuxing, 0.001); -} - -void stopShowingTimeLEDs() -{ - clearTimeLEDs(); + struct tm * timeinfo; + timeinfo = localtime (&dateTime1); + int alarmMDay = timeinfo->tm_mday; + int alarmMonth = timeinfo->tm_mon; + int alarmYear = timeinfo->tm_year; + timeinfo = localtime (&dateTime2); + return (alarmMDay == timeinfo->tm_mday) && (alarmMonth == timeinfo->tm_mon) && (alarmYear == timeinfo->tm_year); } // Handle button press to read watch void buttonPressedCallback(void) { + // Handle debounce + if (buttonAlreadyPressed) + return; + buttonAlreadyPressed = true; + buttonDebounceTimeout.attach(buttonDebounceCallback, 0.2); + + // Stop alarm + AlarmOff(); + // Get the time to display - time_t rawtime=rtc.time(); + time_t curTime = rtc.time(); // Check if we should display current time or alarm time - if (rawtime - timeDisplayLastButtonTime > timeDisplayMoveToShowAlarmSecs) + if (curTime - watchButtonLastPressed > DOUBLE_PRESS_SECS) { - timeDisplayState = timeDisplayState_ShowTime; + ledDisplay.start(rtc.time(), LedDisplay::DispType_CurTime, DISPLAY_ON_TIME, false); } else { - // TO BE DONE - // - move alarm time value to the curBinaryLedDisplayVal - timeDisplayState = timeDisplayState_ShowAlarm; + bool alarmIsLaterToday = (alarmSetTime > curTime) && datesAreTheSame(alarmSetTime, curTime); + ledDisplay.start(alarmSetTime, LedDisplay::DispType_AlarmTime, DISPLAY_ON_TIME, alarmIsLaterToday); } - startShowingTimeLEDs(); // Remember when button last pressed - timeDisplayLastButtonTime = rawtime; - - // Update the button-state service - buttonServicePtr->updateButtonState(true); + watchButtonLastPressed = curTime; } -// TEST CODE +// Button released void buttonReleasedCallback(void) { - // Update the button-state service - buttonServicePtr->updateButtonState(false); } // Handle BLE disconnection - restart advertising @@ -194,47 +142,107 @@ ble.gap().startAdvertising(); } -// TEST CODE +// Callback required for RTC operation void periodicCallback(void) { // Update the rtc library time (it says in the notes on the rtc lib that this needs to happen // more than once every few hundred seconds to avoid a rollover - rtc.time(); + time_t curTime = rtc.time(); + + // Update the time characteristic if we are connected + if (UPDATE_BLE_TIME_WHEN_CONNECTED) + { + Gap::GapState_t gapState = ble.gap().getState(); + if (gapState.connected) + { + time_t curTime = rtc.time(); + pWatchTimeService->writeWatchTime(curTime); + } + } + + // Check if alarm went off recently + if (alarmInitiatedTime + PERIODIC_CALLBACK_SECS*2 + ALARM_ON_TIME > curTime) + { + // Stop the alarm after it has been on for the allotted time + if (alarmInitiatedTime + ALARM_ON_TIME < curTime) + AlarmOff(); + } + else + { + // Check if time for alarm + if (alarmSetTime > 0) + { + if ((curTime >= alarmSetTime) && (curTime < alarmSetTime + PERIODIC_CALLBACK_SECS*2)) + { + AlarmOn(); + } + } + } + + // Pulse the alarm + if (alarmState == AlarmState_on_sounding) + { + alarmState = AlarmState_on_resting; + vibrationMotor = 0; + } + else if (alarmState == AlarmState_on_resting) + { + alarmState = AlarmState_on_sounding; + vibrationMotor = 1; + } + +// // TEST TEST TEST +// int testMin = 0; +// int testHr = 0; +// if (testNum < 6) +// testMin = 1 << testNum; +// else +// testHr = 1 << (testNum - 6); +// testNum++; +// if (testNum >= 11) +// testNum = 0; +// +// uint8_t testTime[] = { uint8_t(2015/256), uint8_t(2015%256), 12, 18, testHr, testMin, 0 }; +// time_t testTimeT = WatchTimeService::watchTimeToUnixTime(testTime); +// +// ledDisplay.start(testTimeT, LedDisplay::DispType_CurTime, DISPLAY_ON_TIME); + } +// Helper void setRTCfromWatchTime(const uint8_t* pWatchTime) { - time_t timest = watchTimeToUnix(pWatchTime); - retval = timest; + time_t timest = WatchTimeService::watchTimeToUnixTime(pWatchTime); if ((int)timest != -1) { rtc.set_time(timest); - minPins[5] = !minPins[5]; } } void onDataWrittenCallback(const GattWriteCallbackParams *params) { - // TEST code - callbackCount++; - memcpy(testbuf, params->data, WatchTimeService::WatchTime_BlockSize); - servcode = params->handle; - buflen = params->len; - mycode = pWatchTimeService->getValueHandle(); - butcode = buttonServicePtr->getValueHandle(); - offs = params->offset; - // Check if this is time setting - if (pWatchTimeService->getValueHandle() == params->handle) + if (pWatchTimeService->getWatchTimeValueHandle() == params->handle) { if (params->len == WatchTimeService::WatchTime_BlockSize) { setRTCfromWatchTime(params->data); } } + else if (pWatchTimeService->getAlarmTimeValueHandle() == params->handle) + { + if (params->len == WatchTimeService::WatchTime_BlockSize) + { + time_t timest = WatchTimeService::watchTimeToUnixTime(params->data); + if (((int)timest != -1) && ((int)timest != 0)) + alarmSetTime = timest; + else + alarmSetTime = 0; + } + } } -// TEST CODE +// DEBUG CODE void print_time() { time_t rawtime=rtc.time(); @@ -251,31 +259,35 @@ { printf("AlarmWatch\r\n"); - // TEST CODE - memset(testbuf, 0, WatchTimeService::WatchTime_BlockSize); - int loopCount = 0; - periodicCallbackToKeepTimerGoing.attach(periodicCallback, 1); + // This is necessary to keep the clock ticking - doesn't have to be so frequent + // According to this https://developer.mbed.org/users/fxschumacher/code/nRF51_rtc_example/file/c1f06d0a5e11/main.cpp + // any time less than 512 seconds is ok + periodicCallbackToKeepTimerGoing.attach(periodicCallback, PERIODIC_CALLBACK_SECS); + + // Handlers for the button press button.fall(buttonPressedCallback); button.rise(buttonReleasedCallback); // Clear display - clearTimeLEDs(); + ledDisplay.clear(); // BLE init ble.init(); ble.gap().onDisconnection(disconnectionCallback); ble.onDataWritten(onDataWrittenCallback); - // TEST CODE - ButtonService buttonService(ble, false /* initial value for button pressed */); - buttonServicePtr = &buttonService; - // Watch Time Service - uint8_t initialTime[] = { uint8_t(2015/256), uint8_t(2015%256), 7, 26, 12, 8, 0 }; - WatchTimeService watchTimeService(ble, initialTime); + uint8_t initialTime[] = { uint8_t(2015/256), uint8_t(2015%256), 12, 18, 10, 10, 0 }; + uint8_t alarmTime[] = { 0, 0, 0, 0, 0, 0, 0 }; + WatchTimeService watchTimeService(ble, initialTime, alarmTime); setRTCfromWatchTime(initialTime); pWatchTimeService = &watchTimeService; + /* Enable over-the-air firmware updates. Instantiating DFUSservice introduces a + * control characteristic which can be used to trigger the application to + * handover control to a resident bootloader. */ + DFUService dfu(ble); + // Setup advertising ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); @@ -284,175 +296,11 @@ ble.gap().setAdvertisingInterval(1000); /* 1000ms. */ ble.gap().startAdvertising(); - uint8_t curWatchTime[WatchTimeService::WatchTime_BlockSize]; + // Turn off any alarm + AlarmOff(); + while (true) { ble.waitForEvent(); - - // TEST CODE - loopCount++; - if (loopCount < 5) - continue; - loopCount = 0; - - print_time(); - // Get current time and convert to watch time - time_t rawtime=rtc.time(); - unixTimeToWatchTime(rawtime, curWatchTime); - pWatchTimeService->writeWatchTime(curWatchTime); - - -/* printf ("Timest %02x %02x %02x %02x %02x %02x %02x %ld\r\n", testbuf[0], - testbuf[1], testbuf[2], testbuf[3], testbuf[4], testbuf[5], testbuf[6], retval); - printf ("serv %d buflen %d mycode %d offs %d butcode %d\r\n", servcode, buflen, mycode, offs, butcode); - printf ("val %ld\r\n", watchTimeService.getValueHandle()); - print_time(); - - if (timeDisplayState != timeDisplayState_None) - { - int watchLedTime = watchTimeToBCD(curBinaryLedDisplayVal); - printf("watchTime %04x = ", watchLedTime); - for (int i = 15; i >= 0; i--) - { - printf("%d", (watchLedTime >> i) % 2); - } - printf("\r\n"); - } - */ } } - -/* - -#include "mbed.h" -#include "BLEDevice.h" -#include "DeviceInformationService.h" - -// BLE Device etc -BLEDevice ble; -DigitalOut ledIndicator(LED1); -DigitalOut testOut(p1); - -// Device name -const static char DEVICE_NAME[] = "JOESALARM"; - -// UUID for CurTimeService & TimeBlockCharacteristic -const uint16_t UUID_CUR_TIME_SERVICE = 0xA000; -const uint16_t UUID_TIME_BLOCK_CHARACTERISTIC = 0xA001; - -// List of supported service UUIDs -static const uint16_t uuid16_list[] = {UUID_CUR_TIME_SERVICE}; - -// Time is packed in an array of bytes -const int SIZE_OF_TIME_BLOCK = 7; -uint8_t timeBlockInitValue[SIZE_OF_TIME_BLOCK]; -uint8_t curTimeBlock[SIZE_OF_TIME_BLOCK]; - -// GATT Characteristic for time block -GattCharacteristic timeBlockCharacteristic(UUID_TIME_BLOCK_CHARACTERISTIC, timeBlockInitValue, SIZE_OF_TIME_BLOCK, SIZE_OF_TIME_BLOCK, - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); - -// Callback when connection lost -void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) -{ - ble.startAdvertising(); // restart advertising -} - -// Callback for ticker -int tickCount = 0; -bool showInfo = false; -int writeSinceLast = 0; -void periodicCallback(void) -{ - ledIndicator = !ledIndicator; - testOut = !testOut; - tickCount++; - if (tickCount > 100) - { - showInfo = true; - tickCount = 0; - } -} - -// Data written callback -void onDataWrittenCallback(const GattCharacteristicWriteCBParams *params) -{ - if ((params->charHandle == timeBlockCharacteristic.getValueHandle())) - { - // Validate time - int year = params->data[0] * 100 + params->data[1]; - int month = params->data[2]; - int day = params->data[3]; -// && (params->len == SIZE_OF_TIME_BLOCK) - writeSinceLast = params->len; - memcpy(curTimeBlock, params->data, SIZE_OF_TIME_BLOCK); - } - writeSinceLast = true; -} - -// Main -int main(void) -{ - ledIndicator = 0; - testOut = 0; - - // Ticker is interrupt driven - Ticker ticker; - ticker.attach_us(periodicCallback, 100000); - - // Initial value for the time block characteristic - memset(timeBlockInitValue, 0, sizeof(timeBlockInitValue)); - - // Init BLE and register callbacks - ble.init(); - ble.onDisconnection(disconnectionCallback); - ble.onDataWritten(onDataWrittenCallback); - - // Add the time setting service - GattCharacteristic *charTable[] = {&timeBlockCharacteristic}; - GattService timeBlockService(UUID_CUR_TIME_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); - ble.addService(timeBlockService); - - // Setup advertising - // BREDR_NOT_SUPPORTED means classic bluetooth not supported; - // LE_GENERAL_DISCOVERABLE means that this peripheral can be - // discovered by any BLE scanner--i.e. any phone. - ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); - - // Add services to payload - ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); - - // This is where we're collecting the device name into the advertisement payload. - ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); - - // We'd like for this BLE peripheral to be connectable. - ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); - - // set the interval at which advertisements are sent out; this has - // an implication power consumption--radio activity being a - // biggest draw on average power. The other software controllable - // parameter which influences power is the radio's TX power - // level--there's an API to adjust that. - ble.setAdvertisingInterval(Gap::MSEC_TO_ADVERTISEMENT_DURATION_UNITS(1000)); - - - ble.startAdvertising(); - - while (true) - { - ble.waitForEvent(); - - if (showInfo) - { - printf("Time info: "); - for (int i = 0; i < SIZE_OF_TIME_BLOCK; i++) - { - printf("%02d", curTimeBlock[i]); - } - printf(" - writeSinceLast %d\r\n", writeSinceLast); - showInfo = false; - writeSinceLast = 0; - } - } -} -*/
diff -r 2682353a8c32 -r 4a12e0f03381 nRF51822.lib --- a/nRF51822.lib Mon Dec 14 22:58:31 2015 +0000 +++ b/nRF51822.lib Tue Mar 01 13:03:32 2016 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#c7adea3c1e37 +http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#1751e2e2637a