Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
--- /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
--- 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__ */
--- 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;
- }
- }
-}
-*/
--- 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