Reformatted all the files according to clang-format style

This commit is contained in:
Avamander 2021-04-18 20:28:14 +03:00
parent e56ebb8bd6
commit 40d45d923b
179 changed files with 10119 additions and 10688 deletions

View file

@ -1,6 +1,6 @@
--- ---
Language: Cpp Language: Cpp
AccessModifierOffset: -2 AccessModifierOffset: 2
AlignAfterOpenBracket: Align AlignAfterOpenBracket: Align
AlignConsecutiveMacros: true AlignConsecutiveMacros: true
AlignConsecutiveAssignments: false AlignConsecutiveAssignments: false
@ -21,8 +21,8 @@ AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true BinPackArguments: false
BinPackParameters: true BinPackParameters: false
BraceWrapping: BraceWrapping:
AfterCaseLabel: false AfterCaseLabel: false
AfterClass: false AfterClass: false
@ -52,14 +52,14 @@ BreakStringLiterals: true
ColumnLimit: 140 ColumnLimit: 140
CommentPragmas: '^ IWYU pragma:' CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 2 ConstructorInitializerIndentWidth: 2
ContinuationIndentWidth: 2 ContinuationIndentWidth: 2
Cpp11BracedListStyle: true Cpp11BracedListStyle: true
DeriveLineEnding: false DeriveLineEnding: false
DerivePointerAlignment: false DerivePointerAlignment: false
DisableFormat: false DisableFormat: false
ExperimentalAutoDetectBinPacking: false ExperimentalAutoDetectBinPacking: true
FixNamespaceComments: false FixNamespaceComments: false
ForEachMacros: ForEachMacros:
- foreach - foreach
@ -90,10 +90,6 @@ MacroBlockBegin: ''
MacroBlockEnd: '' MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1 MaxEmptyLinesToKeep: 1
NamespaceIndentation: All NamespaceIndentation: All
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2 PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19 PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300 PenaltyBreakComment: 300

View file

@ -75,7 +75,7 @@ As of now, here is the list of achievements of this project:
- [Flash, upgrade (OTA), time synchronization,...](doc/gettingStarted/gettingStarted.md) - [Flash, upgrade (OTA), time synchronization,...](doc/gettingStarted/gettingStarted.md)
### Develop ### Develop
- [Generate the fonts and symbols](src/displayapp/fonts/Readme.md) - [Generate the fonts and symbols](src/displayapp/fonts/README.md)
- [Creating a stopwatch in Pinetime(article)](https://pankajraghav.com/2021/04/03/PINETIME-STOPCLOCK.html) - [Creating a stopwatch in Pinetime(article)](https://pankajraghav.com/2021/04/03/PINETIME-STOPCLOCK.html)
### Build, flash and debug ### Build, flash and debug

View file

@ -26,7 +26,6 @@
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef FREERTOS_CONFIG_H #ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H
@ -103,7 +102,6 @@
/* Tickless idle/low power functionality. */ /* Tickless idle/low power functionality. */
/* Define to trap errors during development. */ /* Define to trap errors during development. */
#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER) #if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER)
#define configASSERT(x) ASSERT(x) #define configASSERT(x) ASSERT(x)
@ -140,7 +138,6 @@ INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */ PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY _PRIO_APP_HIGH #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY _PRIO_APP_HIGH
/* Interrupt priorities used by the kernel port layer itself. These are generic /* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */ to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY configLIBRARY_LOWEST_INTERRUPT_PRIORITY #define configKERNEL_INTERRUPT_PRIORITY configLIBRARY_LOWEST_INTERRUPT_PRIORITY
@ -154,7 +151,6 @@ standard names - or at least those used in the unmodified vector table. */
#define vPortSVCHandler SVC_Handler #define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler #define xPortPendSVHandler PendSV_Handler
/*----------------------------------------------------------- /*-----------------------------------------------------------
* Settings that are generated automatically * Settings that are generated automatically
* basing on the settings above * basing on the settings above
@ -198,9 +194,9 @@ standard names - or at least those used in the unmodified vector table. */
* one or more RTC ticks are lost. The tick interrupt inside RTOS will detect this and make a correction needed. This is needed * one or more RTC ticks are lost. The tick interrupt inside RTOS will detect this and make a correction needed. This is needed
* for the RTOS internal timers to be more accurate. * for the RTOS internal timers to be more accurate.
* 1. The auto correction for RTOS tick is disabled even though few RTC tick interrupts were lost. This feature is desirable when debugging * 1. The auto correction for RTOS tick is disabled even though few RTC tick interrupts were lost. This feature is desirable when debugging
* the RTOS application and stepping though the code. After stepping when the application is continued in debug mode, the auto-corrections of * the RTOS application and stepping though the code. After stepping when the application is continued in debug mode, the
* RTOS tick might cause asserts. Setting configUSE_DISABLE_TICK_AUTO_CORRECTION_DEBUG to 1 will make RTC and RTOS go out of sync but could be * auto-corrections of RTOS tick might cause asserts. Setting configUSE_DISABLE_TICK_AUTO_CORRECTION_DEBUG to 1 will make RTC and RTOS go
* convenient for debugging. * out of sync but could be convenient for debugging.
*/ */
#define configUSE_DISABLE_TICK_AUTO_CORRECTION_DEBUG 0 #define configUSE_DISABLE_TICK_AUTO_CORRECTION_DEBUG 0

View file

@ -23,14 +23,14 @@ void Battery::Update() {
isCharging = !nrf_gpio_pin_read(chargingPin); isCharging = !nrf_gpio_pin_read(chargingPin);
isPowerPresent = !nrf_gpio_pin_read(powerPresentPin); isPowerPresent = !nrf_gpio_pin_read(powerPresentPin);
if ( isReading ) return; if (isReading)
return;
// Non blocking read // Non blocking read
samples = 0; samples = 0;
isReading = true; isReading = true;
SaadcInit(); SaadcInit();
nrfx_saadc_sample(); nrfx_saadc_sample();
} }
void Battery::adcCallbackStatic(nrfx_saadc_evt_t const* event) { void Battery::adcCallbackStatic(nrfx_saadc_evt_t const* event) {
@ -41,8 +41,7 @@ void Battery::SaadcInit() {
nrfx_saadc_config_t adcConfig = NRFX_SAADC_DEFAULT_CONFIG; nrfx_saadc_config_t adcConfig = NRFX_SAADC_DEFAULT_CONFIG;
APP_ERROR_CHECK(nrfx_saadc_init(&adcConfig, adcCallbackStatic)); APP_ERROR_CHECK(nrfx_saadc_init(&adcConfig, adcCallbackStatic));
nrf_saadc_channel_config_t adcChannelConfig = { nrf_saadc_channel_config_t adcChannelConfig = {.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
.resistor_n = NRF_SAADC_RESISTOR_DISABLED, .resistor_n = NRF_SAADC_RESISTOR_DISABLED,
.gain = NRF_SAADC_GAIN1_5, .gain = NRF_SAADC_GAIN1_5,
.reference = NRF_SAADC_REFERENCE_INTERNAL, .reference = NRF_SAADC_REFERENCE_INTERNAL,
@ -50,11 +49,9 @@ void Battery::SaadcInit() {
.mode = NRF_SAADC_MODE_SINGLE_ENDED, .mode = NRF_SAADC_MODE_SINGLE_ENDED,
.burst = NRF_SAADC_BURST_ENABLED, .burst = NRF_SAADC_BURST_ENABLED,
.pin_p = batteryVoltageAdcInput, .pin_p = batteryVoltageAdcInput,
.pin_n = NRF_SAADC_INPUT_DISABLED .pin_n = NRF_SAADC_INPUT_DISABLED};
};
APP_ERROR_CHECK(nrfx_saadc_channel_init(0, &adcChannelConfig)); APP_ERROR_CHECK(nrfx_saadc_channel_init(0, &adcChannelConfig));
APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1)); APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1));
} }
void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) {
@ -85,4 +82,3 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * p_event) {
} }
} }
} }

View file

@ -11,10 +11,10 @@ namespace Pinetime {
out the sensor values. The total capacity of the CircBuffer out the sensor values. The total capacity of the CircBuffer
is given as the template parameter N. is given as the template parameter N.
*/ */
template <int N> template <int N> class CircBuffer {
class CircBuffer {
public: public:
CircBuffer() : arr{}, sz{}, cap{N}, head{} {} CircBuffer() : arr {}, sz {}, cap {N}, head {} {
}
/** /**
insert member function overwrites the next data to the current insert member function overwrites the next data to the current
HEAD and moves the HEAD to the newly inserted value. HEAD and moves the HEAD to the newly inserted value.
@ -41,18 +41,25 @@ namespace Pinetime {
class Battery { class Battery {
public: public:
Battery(); Battery();
void Init(); void Init();
void Update(); void Update();
int PercentRemaining() const { return percentRemainingBuffer.GetAverage(); } int PercentRemaining() const {
return percentRemainingBuffer.GetAverage();
}
float Voltage() const { return voltage; } float Voltage() const {
return voltage;
}
bool IsCharging() const { return isCharging; } bool IsCharging() const {
bool IsPowerPresent() const { return isPowerPresent; } return isCharging;
}
bool IsPowerPresent() const {
return isPowerPresent;
}
private: private:
static Battery* instance; static Battery* instance;

View file

@ -12,50 +12,42 @@ constexpr ble_uuid16_t AlertNotificationClient::unreadAlertStatusUuid;
constexpr ble_uuid16_t AlertNotificationClient::controlPointUuid; constexpr ble_uuid16_t AlertNotificationClient::controlPointUuid;
namespace { namespace {
int int OnDiscoveryEventCallback(uint16_t conn_handle, const struct ble_gatt_error* error, const struct ble_gatt_svc* service, void* arg) {
OnDiscoveryEventCallback(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *service,
void *arg) {
auto client = static_cast<AlertNotificationClient*>(arg); auto client = static_cast<AlertNotificationClient*>(arg);
return client->OnDiscoveryEvent(conn_handle, error, service); return client->OnDiscoveryEvent(conn_handle, error, service);
} }
int OnAlertNotificationCharacteristicDiscoveredCallback(uint16_t conn_handle, const struct ble_gatt_error *error, int OnAlertNotificationCharacteristicDiscoveredCallback(uint16_t conn_handle,
const struct ble_gatt_chr *chr, void *arg) { const struct ble_gatt_error* error,
const struct ble_gatt_chr* chr,
void* arg) {
auto client = static_cast<AlertNotificationClient*>(arg); auto client = static_cast<AlertNotificationClient*>(arg);
return client->OnCharacteristicsDiscoveryEvent(conn_handle, error, chr); return client->OnCharacteristicsDiscoveryEvent(conn_handle, error, chr);
} }
int OnAlertNotificationDescriptorDiscoveryEventCallback(uint16_t conn_handle, int OnAlertNotificationDescriptorDiscoveryEventCallback(
const struct ble_gatt_error *error, uint16_t conn_handle, const struct ble_gatt_error* error, uint16_t chr_val_handle, const struct ble_gatt_dsc* dsc, void* arg) {
uint16_t chr_val_handle,
const struct ble_gatt_dsc *dsc,
void *arg) {
auto client = static_cast<AlertNotificationClient*>(arg); auto client = static_cast<AlertNotificationClient*>(arg);
return client->OnDescriptorDiscoveryEventCallback(conn_handle, error, chr_val_handle, dsc); return client->OnDescriptorDiscoveryEventCallback(conn_handle, error, chr_val_handle, dsc);
} }
int NewAlertSubcribeCallback(uint16_t conn_handle, int NewAlertSubcribeCallback(uint16_t conn_handle, const struct ble_gatt_error* error, struct ble_gatt_attr* attr, void* arg) {
const struct ble_gatt_error *error,
struct ble_gatt_attr *attr,
void *arg) {
auto client = static_cast<AlertNotificationClient*>(arg); auto client = static_cast<AlertNotificationClient*>(arg);
return client->OnNewAlertSubcribe(conn_handle, error, attr); return client->OnNewAlertSubcribe(conn_handle, error, attr);
} }
} }
AlertNotificationClient::AlertNotificationClient(Pinetime::System::SystemTask& systemTask, AlertNotificationClient::AlertNotificationClient(Pinetime::System::SystemTask& systemTask,
Pinetime::Controllers::NotificationManager &notificationManager) : Pinetime::Controllers::NotificationManager& notificationManager)
systemTask{systemTask}, notificationManager{notificationManager} { : systemTask {systemTask}, notificationManager {notificationManager} {
} }
bool AlertNotificationClient::OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, bool AlertNotificationClient::OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_svc* service) {
const ble_gatt_svc *service) {
if (service == nullptr && error->status == BLE_HS_EDONE) { if (service == nullptr && error->status == BLE_HS_EDONE) {
if (isDiscovered) { if (isDiscovered) {
NRF_LOG_INFO("ANS Discovery found, starting characteristics discovery"); NRF_LOG_INFO("ANS Discovery found, starting characteristics discovery");
ble_gattc_disc_all_chrs(connectionHandle, ansStartHandle, ansEndHandle, ble_gattc_disc_all_chrs(connectionHandle, ansStartHandle, ansEndHandle, OnAlertNotificationCharacteristicDiscoveredCallback, this);
OnAlertNotificationCharacteristicDiscoveredCallback, this);
} else { } else {
NRF_LOG_INFO("ANS not found"); NRF_LOG_INFO("ANS not found");
onServiceDiscovered(connectionHandle); onServiceDiscovered(connectionHandle);
@ -72,7 +64,8 @@ bool AlertNotificationClient::OnDiscoveryEvent(uint16_t connectionHandle, const
return false; return false;
} }
int AlertNotificationClient::OnCharacteristicsDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, int AlertNotificationClient::OnCharacteristicsDiscoveryEvent(uint16_t connectionHandle,
const ble_gatt_error* error,
const ble_gatt_chr* characteristic) { const ble_gatt_chr* characteristic) {
if (error->status != 0 && error->status != BLE_HS_EDONE) { if (error->status != 0 && error->status != BLE_HS_EDONE) {
NRF_LOG_INFO("ANS Characteristic discovery ERROR"); NRF_LOG_INFO("ANS Characteristic discovery ERROR");
@ -83,41 +76,34 @@ int AlertNotificationClient::OnCharacteristicsDiscoveryEvent(uint16_t connection
if (characteristic == nullptr && error->status == BLE_HS_EDONE) { if (characteristic == nullptr && error->status == BLE_HS_EDONE) {
NRF_LOG_INFO("ANS Characteristic discovery complete"); NRF_LOG_INFO("ANS Characteristic discovery complete");
if (isCharacteristicDiscovered) { if (isCharacteristicDiscovered) {
ble_gattc_disc_all_dscs(connectionHandle, ble_gattc_disc_all_dscs(connectionHandle, newAlertHandle, ansEndHandle, OnAlertNotificationDescriptorDiscoveryEventCallback, this);
newAlertHandle, ansEndHandle,
OnAlertNotificationDescriptorDiscoveryEventCallback, this);
} else } else
onServiceDiscovered(connectionHandle); onServiceDiscovered(connectionHandle);
} else { } else {
if (characteristic != nullptr && if (characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*) &supportedNewAlertCategoryUuid), &characteristic->uuid.u) == 0) {
ble_uuid_cmp(((ble_uuid_t *) &supportedNewAlertCategoryUuid), &characteristic->uuid.u) == 0) {
NRF_LOG_INFO("ANS Characteristic discovered : supportedNewAlertCategoryUuid"); NRF_LOG_INFO("ANS Characteristic discovered : supportedNewAlertCategoryUuid");
supportedNewAlertCategoryHandle = characteristic->val_handle; supportedNewAlertCategoryHandle = characteristic->val_handle;
} else if (characteristic != nullptr && } else if (characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*) &supportedUnreadAlertCategoryUuid), &characteristic->uuid.u) == 0) {
ble_uuid_cmp(((ble_uuid_t *) &supportedUnreadAlertCategoryUuid), &characteristic->uuid.u) == 0) {
NRF_LOG_INFO("ANS Characteristic discovered : supportedUnreadAlertCategoryUuid"); NRF_LOG_INFO("ANS Characteristic discovered : supportedUnreadAlertCategoryUuid");
supportedUnreadAlertCategoryHandle = characteristic->val_handle; supportedUnreadAlertCategoryHandle = characteristic->val_handle;
} else if (characteristic != nullptr && } else if (characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*) &newAlertUuid), &characteristic->uuid.u) == 0) {
ble_uuid_cmp(((ble_uuid_t *) &newAlertUuid), &characteristic->uuid.u) == 0) {
NRF_LOG_INFO("ANS Characteristic discovered : newAlertUuid"); NRF_LOG_INFO("ANS Characteristic discovered : newAlertUuid");
newAlertHandle = characteristic->val_handle; newAlertHandle = characteristic->val_handle;
newAlertDefHandle = characteristic->def_handle; newAlertDefHandle = characteristic->def_handle;
isCharacteristicDiscovered = true; isCharacteristicDiscovered = true;
} else if (characteristic != nullptr && } else if (characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*) &unreadAlertStatusUuid), &characteristic->uuid.u) == 0) {
ble_uuid_cmp(((ble_uuid_t *) &unreadAlertStatusUuid), &characteristic->uuid.u) == 0) {
NRF_LOG_INFO("ANS Characteristic discovered : unreadAlertStatusUuid"); NRF_LOG_INFO("ANS Characteristic discovered : unreadAlertStatusUuid");
unreadAlertStatusHandle = characteristic->val_handle; unreadAlertStatusHandle = characteristic->val_handle;
} else if (characteristic != nullptr && } else if (characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*) &controlPointUuid), &characteristic->uuid.u) == 0) {
ble_uuid_cmp(((ble_uuid_t *) &controlPointUuid), &characteristic->uuid.u) == 0) {
NRF_LOG_INFO("ANS Characteristic discovered : controlPointUuid"); NRF_LOG_INFO("ANS Characteristic discovered : controlPointUuid");
controlPointHandle = characteristic->val_handle; controlPointHandle = characteristic->val_handle;
} else NRF_LOG_INFO("ANS Characteristic discovered : 0x%x", characteristic->val_handle); } else
NRF_LOG_INFO("ANS Characteristic discovered : 0x%x", characteristic->val_handle);
} }
return 0; return 0;
} }
int AlertNotificationClient::OnNewAlertSubcribe(uint16_t connectionHandle, const ble_gatt_error *error, int AlertNotificationClient::OnNewAlertSubcribe(uint16_t connectionHandle, const ble_gatt_error* error, ble_gatt_attr* attribute) {
ble_gatt_attr *attribute) {
if (error->status == 0) { if (error->status == 0) {
NRF_LOG_INFO("ANS New alert subscribe OK"); NRF_LOG_INFO("ANS New alert subscribe OK");
} else { } else {
@ -128,12 +114,12 @@ int AlertNotificationClient::OnNewAlertSubcribe(uint16_t connectionHandle, const
return 0; return 0;
} }
int AlertNotificationClient::OnDescriptorDiscoveryEventCallback(uint16_t connectionHandle, const ble_gatt_error *error, int AlertNotificationClient::OnDescriptorDiscoveryEventCallback(uint16_t connectionHandle,
const ble_gatt_error* error,
uint16_t characteristicValueHandle, uint16_t characteristicValueHandle,
const ble_gatt_dsc* descriptor) { const ble_gatt_dsc* descriptor) {
if (error->status == 0) { if (error->status == 0) {
if (characteristicValueHandle == newAlertHandle && if (characteristicValueHandle == newAlertHandle && ble_uuid_cmp(((ble_uuid_t*) &newAlertUuid), &descriptor->uuid.u)) {
ble_uuid_cmp(((ble_uuid_t *) &newAlertUuid), &descriptor->uuid.u)) {
if (newAlertDescriptorHandle == 0) { if (newAlertDescriptorHandle == 0) {
NRF_LOG_INFO("ANS Descriptor discovered : %d", descriptor->handle); NRF_LOG_INFO("ANS Descriptor discovered : %d", descriptor->handle);
newAlertDescriptorHandle = descriptor->handle; newAlertDescriptorHandle = descriptor->handle;
@ -160,7 +146,8 @@ void AlertNotificationClient::OnNotification(ble_gap_event *event) {
// Ignore notifications with empty message // Ignore notifications with empty message
const auto packetLen = OS_MBUF_PKTLEN(event->notify_rx.om); const auto packetLen = OS_MBUF_PKTLEN(event->notify_rx.om);
if(packetLen <= headerSize) return; if (packetLen <= headerSize)
return;
size_t bufferSize = std::min(packetLen + stringTerminatorSize, maxBufferSize); size_t bufferSize = std::min(packetLen + stringTerminatorSize, maxBufferSize);
auto messageSize = std::min(maxMessageSize, (bufferSize - headerSize)); auto messageSize = std::min(maxMessageSize, (bufferSize - headerSize));

View file

@ -24,11 +24,12 @@ namespace Pinetime {
Pinetime::Controllers::NotificationManager& notificationManager); Pinetime::Controllers::NotificationManager& notificationManager);
bool OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_svc* service); bool OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_svc* service);
int OnCharacteristicsDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, int OnCharacteristicsDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_chr* characteristic);
const ble_gatt_chr *characteristic);
int OnNewAlertSubcribe(uint16_t connectionHandle, const ble_gatt_error* error, ble_gatt_attr* attribute); int OnNewAlertSubcribe(uint16_t connectionHandle, const ble_gatt_error* error, ble_gatt_attr* attribute);
int OnDescriptorDiscoveryEventCallback(uint16_t connectionHandle, const ble_gatt_error *error, int OnDescriptorDiscoveryEventCallback(uint16_t connectionHandle,
uint16_t characteristicValueHandle, const ble_gatt_dsc *descriptor); const ble_gatt_error* error,
uint16_t characteristicValueHandle,
const ble_gatt_dsc* descriptor);
void OnNotification(ble_gap_event* event); void OnNotification(ble_gap_event* event);
void Reset(); void Reset();
void Discover(uint16_t connectionHandle, std::function<void(uint16_t)> lambda) override; void Discover(uint16_t connectionHandle, std::function<void(uint16_t)> lambda) override;
@ -41,30 +42,13 @@ namespace Pinetime {
static constexpr uint16_t unreadAlertStatusId = 0x2a45; static constexpr uint16_t unreadAlertStatusId = 0x2a45;
static constexpr uint16_t controlPointId = 0x2a44; static constexpr uint16_t controlPointId = 0x2a44;
static constexpr ble_uuid16_t ansServiceUuid{ static constexpr ble_uuid16_t ansServiceUuid {.u {.type = BLE_UUID_TYPE_16}, .value = ansServiceId};
.u {.type = BLE_UUID_TYPE_16}, static constexpr ble_uuid16_t supportedNewAlertCategoryUuid {.u {.type = BLE_UUID_TYPE_16}, .value = supportedNewAlertCategoryId};
.value = ansServiceId static constexpr ble_uuid16_t supportedUnreadAlertCategoryUuid {.u {.type = BLE_UUID_TYPE_16},
}; .value = supportedUnreadAlertCategoryId};
static constexpr ble_uuid16_t supportedNewAlertCategoryUuid{ static constexpr ble_uuid16_t newAlertUuid {.u {.type = BLE_UUID_TYPE_16}, .value = newAlertId};
.u {.type = BLE_UUID_TYPE_16}, static constexpr ble_uuid16_t unreadAlertStatusUuid {.u {.type = BLE_UUID_TYPE_16}, .value = unreadAlertStatusId};
.value = supportedNewAlertCategoryId static constexpr ble_uuid16_t controlPointUuid {.u {.type = BLE_UUID_TYPE_16}, .value = controlPointId};
};
static constexpr ble_uuid16_t supportedUnreadAlertCategoryUuid{
.u {.type = BLE_UUID_TYPE_16},
.value = supportedUnreadAlertCategoryId
};
static constexpr ble_uuid16_t newAlertUuid{
.u {.type = BLE_UUID_TYPE_16},
.value = newAlertId
};
static constexpr ble_uuid16_t unreadAlertStatusUuid{
.u {.type = BLE_UUID_TYPE_16},
.value = unreadAlertStatusId
};
static constexpr ble_uuid16_t controlPointUuid{
.u {.type = BLE_UUID_TYPE_16},
.value = controlPointId
};
uint16_t ansStartHandle = 0; uint16_t ansStartHandle = 0;
uint16_t ansEndHandle = 0; uint16_t ansEndHandle = 0;

View file

@ -11,7 +11,6 @@ constexpr ble_uuid16_t AlertNotificationService::ansUuid;
constexpr ble_uuid16_t AlertNotificationService::ansCharUuid; constexpr ble_uuid16_t AlertNotificationService::ansCharUuid;
constexpr ble_uuid128_t AlertNotificationService::notificationEventUuid; constexpr ble_uuid128_t AlertNotificationService::notificationEventUuid;
int AlertNotificationCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) { int AlertNotificationCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) {
auto anService = static_cast<AlertNotificationService*>(arg); auto anService = static_cast<AlertNotificationService*>(arg);
return anService->OnAlert(conn_handle, attr_handle, ctxt); return anService->OnAlert(conn_handle, attr_handle, ctxt);
@ -27,39 +26,28 @@ void AlertNotificationService::Init() {
} }
AlertNotificationService::AlertNotificationService(System::SystemTask& systemTask, NotificationManager& notificationManager) AlertNotificationService::AlertNotificationService(System::SystemTask& systemTask, NotificationManager& notificationManager)
: characteristicDefinition{ : characteristicDefinition {{.uuid = (ble_uuid_t*) &ansCharUuid,
{
.uuid = (ble_uuid_t *) &ansCharUuid,
.access_cb = AlertNotificationCallback, .access_cb = AlertNotificationCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_WRITE .flags = BLE_GATT_CHR_F_WRITE},
}, {.uuid = (ble_uuid_t*) &notificationEventUuid,
{
.uuid = (ble_uuid_t *) &notificationEventUuid,
.access_cb = AlertNotificationCallback, .access_cb = AlertNotificationCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_NOTIFY, .flags = BLE_GATT_CHR_F_NOTIFY,
.val_handle = &eventHandle .val_handle = &eventHandle},
}, {0}},
{
0
}
},
serviceDefinition { serviceDefinition {
{ {/* Device Information Service */
/* Device Information Service */
.type = BLE_GATT_SVC_TYPE_PRIMARY, .type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = (ble_uuid_t*) &ansUuid, .uuid = (ble_uuid_t*) &ansUuid,
.characteristics = characteristicDefinition .characteristics = characteristicDefinition},
{0},
}, },
{ systemTask {systemTask},
0 notificationManager {notificationManager} {
},
}, systemTask{systemTask}, notificationManager{notificationManager} {
} }
int AlertNotificationService::OnAlert(uint16_t conn_handle, uint16_t attr_handle, int AlertNotificationService::OnAlert(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) {
struct ble_gatt_access_ctxt *ctxt) {
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
constexpr size_t stringTerminatorSize = 1; // end of string '\0' constexpr size_t stringTerminatorSize = 1; // end of string '\0'
constexpr size_t headerSize = 3; constexpr size_t headerSize = 3;
@ -68,7 +56,8 @@ int AlertNotificationService::OnAlert(uint16_t conn_handle, uint16_t attr_handle
// Ignore notifications with empty message // Ignore notifications with empty message
const auto packetLen = OS_MBUF_PKTLEN(ctxt->om); const auto packetLen = OS_MBUF_PKTLEN(ctxt->om);
if(packetLen <= headerSize) return 0; if (packetLen <= headerSize)
return 0;
size_t bufferSize = std::min(packetLen + stringTerminatorSize, maxBufferSize); size_t bufferSize = std::min(packetLen + stringTerminatorSize, maxBufferSize);
auto messageSize = std::min(maxMessageSize, (bufferSize - headerSize)); auto messageSize = std::min(maxMessageSize, (bufferSize - headerSize));

View file

@ -8,7 +8,8 @@
#undef min #undef min
// 00020001-78fc-48fe-8e23-433b3a1942d0 // 00020001-78fc-48fe-8e23-433b3a1942d0
#define NOTIFICATION_EVENT_SERVICE_UUID_BASE {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, 0x01, 0x00, 0x02, 0x00} #define NOTIFICATION_EVENT_SERVICE_UUID_BASE \
{ 0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, 0x01, 0x00, 0x02, 0x00 }
namespace Pinetime { namespace Pinetime {
@ -20,22 +21,16 @@ namespace Pinetime {
class AlertNotificationService { class AlertNotificationService {
public: public:
AlertNotificationService(Pinetime::System::SystemTask &systemTask, AlertNotificationService(Pinetime::System::SystemTask& systemTask, Pinetime::Controllers::NotificationManager& notificationManager);
Pinetime::Controllers::NotificationManager &notificationManager);
void Init(); void Init();
int OnAlert(uint16_t conn_handle, uint16_t attr_handle, int OnAlert(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt);
struct ble_gatt_access_ctxt *ctxt);
void AcceptIncomingCall(); void AcceptIncomingCall();
void RejectIncomingCall(); void RejectIncomingCall();
void MuteIncomingCall(); void MuteIncomingCall();
enum class IncomingCallResponses : uint8_t { enum class IncomingCallResponses : uint8_t { Reject = 0x00, Answer = 0x01, Mute = 0x02 };
Reject = 0x00,
Answer = 0x01,
Mute = 0x02
};
private: private:
enum class Categories : uint8_t { enum class Categories : uint8_t {
@ -55,20 +50,11 @@ namespace Pinetime {
static constexpr uint16_t ansId {0x1811}; static constexpr uint16_t ansId {0x1811};
static constexpr uint16_t ansCharId {0x2a46}; static constexpr uint16_t ansCharId {0x2a46};
static constexpr ble_uuid16_t ansUuid { static constexpr ble_uuid16_t ansUuid {.u {.type = BLE_UUID_TYPE_16}, .value = ansId};
.u { .type = BLE_UUID_TYPE_16 },
.value = ansId
};
static constexpr ble_uuid16_t ansCharUuid { static constexpr ble_uuid16_t ansCharUuid {.u {.type = BLE_UUID_TYPE_16}, .value = ansCharId};
.u { .type = BLE_UUID_TYPE_16 },
.value = ansCharId
};
static constexpr ble_uuid128_t notificationEventUuid { static constexpr ble_uuid128_t notificationEventUuid {.u {.type = BLE_UUID_TYPE_128}, .value = NOTIFICATION_EVENT_SERVICE_UUID_BASE};
.u { .type = BLE_UUID_TYPE_128 },
.value = NOTIFICATION_EVENT_SERVICE_UUID_BASE
};
struct ble_gatt_chr_def characteristicDefinition[3]; struct ble_gatt_chr_def characteristicDefinition[3];
struct ble_gatt_svc_def serviceDefinition[2]; struct ble_gatt_svc_def serviceDefinition[2];

View file

@ -7,39 +7,26 @@ using namespace Pinetime::Controllers;
constexpr ble_uuid16_t BatteryInformationService::batteryInformationServiceUuid; constexpr ble_uuid16_t BatteryInformationService::batteryInformationServiceUuid;
constexpr ble_uuid16_t BatteryInformationService::batteryLevelUuid; constexpr ble_uuid16_t BatteryInformationService::batteryLevelUuid;
int BatteryInformationServiceCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) { int BatteryInformationServiceCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) {
auto* batteryInformationService = static_cast<BatteryInformationService*>(arg); auto* batteryInformationService = static_cast<BatteryInformationService*>(arg);
return batteryInformationService->OnBatteryServiceRequested(conn_handle, attr_handle, ctxt); return batteryInformationService->OnBatteryServiceRequested(conn_handle, attr_handle, ctxt);
} }
BatteryInformationService::BatteryInformationService(Controllers::Battery& batteryController) : BatteryInformationService::BatteryInformationService(Controllers::Battery& batteryController)
batteryController{batteryController}, : batteryController {batteryController},
characteristicDefinition{ characteristicDefinition {{.uuid = (ble_uuid_t*) &batteryLevelUuid,
{
.uuid = (ble_uuid_t *) &batteryLevelUuid,
.access_cb = BatteryInformationServiceCallback, .access_cb = BatteryInformationServiceCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_READ, .flags = BLE_GATT_CHR_F_READ,
.val_handle = &batteryLevelHandle .val_handle = &batteryLevelHandle},
}, {0}},
{
0
}
},
serviceDefinition { serviceDefinition {
{ {/* Device Information Service */
/* Device Information Service */
.type = BLE_GATT_SVC_TYPE_PRIMARY, .type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = (ble_uuid_t*) &batteryInformationServiceUuid, .uuid = (ble_uuid_t*) &batteryInformationServiceUuid,
.characteristics = characteristicDefinition .characteristics = characteristicDefinition},
}, {0},
{
0
},
} { } {
} }
void BatteryInformationService::Init() { void BatteryInformationService::Init() {
@ -51,7 +38,8 @@ void BatteryInformationService::Init() {
ASSERT(res == 0); ASSERT(res == 0);
} }
int BatteryInformationService::OnBatteryServiceRequested(uint16_t connectionHandle, uint16_t attributeHandle, int BatteryInformationService::OnBatteryServiceRequested(uint16_t connectionHandle,
uint16_t attributeHandle,
ble_gatt_access_ctxt* context) { ble_gatt_access_ctxt* context) {
if (attributeHandle == batteryLevelHandle) { if (attributeHandle == batteryLevelHandle) {
NRF_LOG_INFO("BATTERY : handle = %d", batteryLevelHandle); NRF_LOG_INFO("BATTERY : handle = %d", batteryLevelHandle);

View file

@ -16,29 +16,21 @@ namespace Pinetime {
BatteryInformationService(Controllers::Battery& batteryController); BatteryInformationService(Controllers::Battery& batteryController);
void Init(); void Init();
int int OnBatteryServiceRequested(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context);
OnBatteryServiceRequested(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt *context);
private: private:
Controllers::Battery& batteryController; Controllers::Battery& batteryController;
static constexpr uint16_t batteryInformationServiceId {0x180F}; static constexpr uint16_t batteryInformationServiceId {0x180F};
static constexpr uint16_t batteryLevelId {0x2A19}; static constexpr uint16_t batteryLevelId {0x2A19};
static constexpr ble_uuid16_t batteryInformationServiceUuid { static constexpr ble_uuid16_t batteryInformationServiceUuid {.u {.type = BLE_UUID_TYPE_16}, .value = batteryInformationServiceId};
.u {.type = BLE_UUID_TYPE_16},
.value = batteryInformationServiceId
};
static constexpr ble_uuid16_t batteryLevelUuid { static constexpr ble_uuid16_t batteryLevelUuid {.u {.type = BLE_UUID_TYPE_16}, .value = batteryLevelId};
.u {.type = BLE_UUID_TYPE_16},
.value = batteryLevelId
};
struct ble_gatt_chr_def characteristicDefinition[3]; struct ble_gatt_chr_def characteristicDefinition[3];
struct ble_gatt_svc_def serviceDefinition[2]; struct ble_gatt_svc_def serviceDefinition[2];
uint16_t batteryLevelHandle; uint16_t batteryLevelHandle;
}; };
} }
} }

View file

@ -25,5 +25,3 @@ void Ble::FirmwareUpdateTotalBytes(uint32_t totalBytes) {
void Ble::FirmwareUpdateCurrentBytes(uint32_t currentBytes) { void Ble::FirmwareUpdateCurrentBytes(uint32_t currentBytes) {
firmwareUpdateCurrentBytes = currentBytes; firmwareUpdateCurrentBytes = currentBytes;
} }

View file

@ -12,7 +12,9 @@ namespace Pinetime {
enum class AddressTypes { Public, Random }; enum class AddressTypes { Public, Random };
Ble() = default; Ble() = default;
bool IsConnected() const {return isConnected;} bool IsConnected() const {
return isConnected;
}
void Connect(); void Connect();
void Disconnect(); void Disconnect();
@ -20,16 +22,33 @@ namespace Pinetime {
void StopFirmwareUpdate(); void StopFirmwareUpdate();
void FirmwareUpdateTotalBytes(uint32_t totalBytes); void FirmwareUpdateTotalBytes(uint32_t totalBytes);
void FirmwareUpdateCurrentBytes(uint32_t currentBytes); void FirmwareUpdateCurrentBytes(uint32_t currentBytes);
void State(FirmwareUpdateStates state) { firmwareUpdateState = state; } void State(FirmwareUpdateStates state) {
firmwareUpdateState = state;
}
bool IsFirmwareUpdating() const { return isFirmwareUpdating; } bool IsFirmwareUpdating() const {
uint32_t FirmwareUpdateTotalBytes() const { return firmwareUpdateTotalBytes; } return isFirmwareUpdating;
uint32_t FirmwareUpdateCurrentBytes() const { return firmwareUpdateCurrentBytes; } }
FirmwareUpdateStates State() const { return firmwareUpdateState; } uint32_t FirmwareUpdateTotalBytes() const {
return firmwareUpdateTotalBytes;
}
uint32_t FirmwareUpdateCurrentBytes() const {
return firmwareUpdateCurrentBytes;
}
FirmwareUpdateStates State() const {
return firmwareUpdateState;
}
void Address(BleAddress&& addr) {
address = addr;
}
const BleAddress& Address() const {
return address;
}
void AddressType(AddressTypes t) {
addressType = t;
}
void Address(BleAddress&& addr) { address = addr; }
const BleAddress& Address() const { return address; }
void AddressType(AddressTypes t) { addressType = t;}
private: private:
bool isConnected = false; bool isConnected = false;
bool isFirmwareUpdating = false; bool isFirmwareUpdating = false;
@ -38,7 +57,6 @@ namespace Pinetime {
FirmwareUpdateStates firmwareUpdateState = FirmwareUpdateStates::Idle; FirmwareUpdateStates firmwareUpdateState = FirmwareUpdateStates::Idle;
BleAddress address; BleAddress address;
AddressTypes addressType; AddressTypes addressType;
}; };
} }
} }

View file

@ -14,8 +14,10 @@ namespace {
return client->OnDiscoveryEvent(conn_handle, error, service); return client->OnDiscoveryEvent(conn_handle, error, service);
} }
int OnCurrentTimeCharacteristicDiscoveredCallback(uint16_t conn_handle, const struct ble_gatt_error *error, int OnCurrentTimeCharacteristicDiscoveredCallback(uint16_t conn_handle,
const struct ble_gatt_chr *chr, void *arg) { const struct ble_gatt_error* error,
const struct ble_gatt_chr* chr,
void* arg) {
auto client = static_cast<CurrentTimeClient*>(arg); auto client = static_cast<CurrentTimeClient*>(arg);
return client->OnCharacteristicDiscoveryEvent(conn_handle, error, chr); return client->OnCharacteristicDiscoveryEvent(conn_handle, error, chr);
} }
@ -27,21 +29,17 @@ namespace {
} }
CurrentTimeClient::CurrentTimeClient(DateTime& dateTimeController) : dateTimeController {dateTimeController} { CurrentTimeClient::CurrentTimeClient(DateTime& dateTimeController) : dateTimeController {dateTimeController} {
} }
void CurrentTimeClient::Init() { void CurrentTimeClient::Init() {
} }
bool CurrentTimeClient::OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, bool CurrentTimeClient::OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_svc* service) {
const ble_gatt_svc *service) {
if (service == nullptr && error->status == BLE_HS_EDONE) { if (service == nullptr && error->status == BLE_HS_EDONE) {
if (isDiscovered) { if (isDiscovered) {
NRF_LOG_INFO("CTS found, starting characteristics discovery"); NRF_LOG_INFO("CTS found, starting characteristics discovery");
ble_gattc_disc_all_chrs(connectionHandle, ctsStartHandle, ctsEndHandle, ble_gattc_disc_all_chrs(connectionHandle, ctsStartHandle, ctsEndHandle, OnCurrentTimeCharacteristicDiscoveredCallback, this);
OnCurrentTimeCharacteristicDiscoveredCallback, this);
} else { } else {
NRF_LOG_INFO("CTS not found"); NRF_LOG_INFO("CTS not found");
onServiceDiscovered(connectionHandle); onServiceDiscovered(connectionHandle);
@ -59,7 +57,8 @@ bool CurrentTimeClient::OnDiscoveryEvent(uint16_t connectionHandle, const ble_ga
return false; return false;
} }
int CurrentTimeClient::OnCharacteristicDiscoveryEvent(uint16_t conn_handle, const ble_gatt_error *error, int CurrentTimeClient::OnCharacteristicDiscoveryEvent(uint16_t conn_handle,
const ble_gatt_error* error,
const ble_gatt_chr* characteristic) { const ble_gatt_chr* characteristic) {
if (characteristic == nullptr && error->status == BLE_HS_EDONE) { if (characteristic == nullptr && error->status == BLE_HS_EDONE) {
if (isCharacteristicDiscovered) { if (isCharacteristicDiscovered) {
@ -73,8 +72,7 @@ int CurrentTimeClient::OnCharacteristicDiscoveryEvent(uint16_t conn_handle, cons
return 0; return 0;
} }
if (characteristic != nullptr && if (characteristic != nullptr && ble_uuid_cmp(((ble_uuid_t*) &currentTimeCharacteristicUuid), &characteristic->uuid.u) == 0) {
ble_uuid_cmp(((ble_uuid_t *) &currentTimeCharacteristicUuid), &characteristic->uuid.u) == 0) {
NRF_LOG_INFO("CTS Characteristic discovered : 0x%x", characteristic->val_handle); NRF_LOG_INFO("CTS Characteristic discovered : 0x%x", characteristic->val_handle);
isCharacteristicDiscovered = true; isCharacteristicDiscovered = true;
currentTimeHandle = characteristic->val_handle; currentTimeHandle = characteristic->val_handle;
@ -82,17 +80,15 @@ int CurrentTimeClient::OnCharacteristicDiscoveryEvent(uint16_t conn_handle, cons
return 0; return 0;
} }
int CurrentTimeClient::OnCurrentTimeReadResult(uint16_t conn_handle, const ble_gatt_error *error, int CurrentTimeClient::OnCurrentTimeReadResult(uint16_t conn_handle, const ble_gatt_error* error, const ble_gatt_attr* attribute) {
const ble_gatt_attr *attribute) {
if (error->status == 0) { if (error->status == 0) {
// TODO check that attribute->handle equals the handle discovered in OnCharacteristicDiscoveryEvent // TODO check that attribute->handle equals the handle discovered in OnCharacteristicDiscoveryEvent
CtsData result; CtsData result;
os_mbuf_copydata(attribute->om, 0, sizeof(CtsData), &result); os_mbuf_copydata(attribute->om, 0, sizeof(CtsData), &result);
NRF_LOG_INFO("Received data: %d-%d-%d %d:%d:%d", result.year, NRF_LOG_INFO(
result.month, result.dayofmonth, "Received data: %d-%d-%d %d:%d:%d", result.year, result.month, result.dayofmonth, result.hour, result.minute, result.second);
result.hour, result.minute, result.second); dateTimeController.SetTime(
dateTimeController.SetTime(result.year, result.month, result.dayofmonth, result.year, result.month, result.dayofmonth, 0, result.hour, result.minute, result.second, nrf_rtc_counter_get(portNRF_RTC_REG));
0, result.hour, result.minute, result.second, nrf_rtc_counter_get(portNRF_RTC_REG));
} else { } else {
NRF_LOG_INFO("Error retrieving current time: %d", error->status); NRF_LOG_INFO("Error retrieving current time: %d", error->status);
} }

View file

@ -17,11 +17,14 @@ namespace Pinetime {
void Init(); void Init();
void Reset(); void Reset();
bool OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_svc* service); bool OnDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_svc* service);
int OnCharacteristicDiscoveryEvent(uint16_t conn_handle, const ble_gatt_error *error, int OnCharacteristicDiscoveryEvent(uint16_t conn_handle, const ble_gatt_error* error, const ble_gatt_chr* characteristic);
const ble_gatt_chr *characteristic);
int OnCurrentTimeReadResult(uint16_t conn_handle, const ble_gatt_error* error, const ble_gatt_attr* attribute); int OnCurrentTimeReadResult(uint16_t conn_handle, const ble_gatt_error* error, const ble_gatt_attr* attribute);
static constexpr const ble_uuid16_t* Uuid() { return &CurrentTimeClient::ctsServiceUuid; } static constexpr const ble_uuid16_t* Uuid() {
static constexpr const ble_uuid16_t* CurrentTimeCharacteristicUuid() { return &CurrentTimeClient::currentTimeCharacteristicUuid; } return &CurrentTimeClient::ctsServiceUuid;
}
static constexpr const ble_uuid16_t* CurrentTimeCharacteristicUuid() {
return &CurrentTimeClient::currentTimeCharacteristicUuid;
}
void Discover(uint16_t connectionHandle, std::function<void(uint16_t)> lambda) override; void Discover(uint16_t connectionHandle, std::function<void(uint16_t)> lambda) override;
private: private:
@ -39,14 +42,8 @@ namespace Pinetime {
static constexpr uint16_t ctsServiceId {0x1805}; static constexpr uint16_t ctsServiceId {0x1805};
static constexpr uint16_t currentTimeCharacteristicId {0x2a2b}; static constexpr uint16_t currentTimeCharacteristicId {0x2a2b};
static constexpr ble_uuid16_t ctsServiceUuid { static constexpr ble_uuid16_t ctsServiceUuid {.u {.type = BLE_UUID_TYPE_16}, .value = ctsServiceId};
.u { .type = BLE_UUID_TYPE_16 }, static constexpr ble_uuid16_t currentTimeCharacteristicUuid {.u {.type = BLE_UUID_TYPE_16}, .value = currentTimeCharacteristicId};
.value = ctsServiceId
};
static constexpr ble_uuid16_t currentTimeCharacteristicUuid {
.u { .type = BLE_UUID_TYPE_16 },
.value = currentTimeCharacteristicId
};
DateTime& dateTimeController; DateTime& dateTimeController;
bool isDiscovered = false; bool isDiscovered = false;

View file

@ -7,7 +7,6 @@ using namespace Pinetime::Controllers;
constexpr ble_uuid16_t CurrentTimeService::ctsUuid; constexpr ble_uuid16_t CurrentTimeService::ctsUuid;
constexpr ble_uuid16_t CurrentTimeService::ctChrUuid; constexpr ble_uuid16_t CurrentTimeService::ctChrUuid;
int CTSCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) { int CTSCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) {
auto cts = static_cast<CurrentTimeService*>(arg); auto cts = static_cast<CurrentTimeService*>(arg);
return cts->OnTimeAccessed(conn_handle, attr_handle, ctxt); return cts->OnTimeAccessed(conn_handle, attr_handle, ctxt);
@ -22,9 +21,7 @@ void CurrentTimeService::Init() {
ASSERT(res == 0); ASSERT(res == 0);
} }
int CurrentTimeService::OnTimeAccessed(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) {
int CurrentTimeService::OnTimeAccessed(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt) {
NRF_LOG_INFO("Setting time..."); NRF_LOG_INFO("Setting time...");
@ -32,12 +29,11 @@ int CurrentTimeService::OnTimeAccessed(uint16_t conn_handle, uint16_t attr_handl
CtsData result; CtsData result;
os_mbuf_copydata(ctxt->om, 0, sizeof(CtsData), &result); os_mbuf_copydata(ctxt->om, 0, sizeof(CtsData), &result);
NRF_LOG_INFO("Received data: %d-%d-%d %d:%d:%d", result.year, NRF_LOG_INFO(
result.month, result.dayofmonth, "Received data: %d-%d-%d %d:%d:%d", result.year, result.month, result.dayofmonth, result.hour, result.minute, result.second);
result.hour, result.minute, result.second);
m_dateTimeController.SetTime(result.year, result.month, result.dayofmonth, m_dateTimeController.SetTime(
0, result.hour, result.minute, result.second, nrf_rtc_counter_get(portNRF_RTC_REG)); result.year, result.month, result.dayofmonth, 0, result.hour, result.minute, result.second, nrf_rtc_counter_get(portNRF_RTC_REG));
} else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) { } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
CtsData currentDateTime; CtsData currentDateTime;
@ -49,39 +45,26 @@ int CurrentTimeService::OnTimeAccessed(uint16_t conn_handle, uint16_t attr_handl
currentDateTime.second = m_dateTimeController.Seconds(); currentDateTime.second = m_dateTimeController.Seconds();
currentDateTime.millis = 0; currentDateTime.millis = 0;
int res = os_mbuf_append(ctxt->om, &currentDateTime, sizeof(CtsData)); int res = os_mbuf_append(ctxt->om, &currentDateTime, sizeof(CtsData));
return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
} }
return 0; return 0;
} }
CurrentTimeService::CurrentTimeService(DateTime &dateTimeController) : CurrentTimeService::CurrentTimeService(DateTime& dateTimeController)
characteristicDefinition{ : characteristicDefinition {{.uuid = (ble_uuid_t*) &ctChrUuid,
{
.uuid = (ble_uuid_t *) &ctChrUuid,
.access_cb = CTSCallback, .access_cb = CTSCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ},
}, {0}},
{
0
}
},
serviceDefinition { serviceDefinition {
{ {/* Device Information Service */
/* Device Information Service */
.type = BLE_GATT_SVC_TYPE_PRIMARY, .type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = (ble_uuid_t*) &ctsUuid, .uuid = (ble_uuid_t*) &ctsUuid,
.characteristics = characteristicDefinition .characteristics = characteristicDefinition},
{0},
}, },
{ m_dateTimeController {dateTimeController} {
0
},
}, m_dateTimeController{dateTimeController} {
} }

View file

@ -16,22 +16,15 @@ namespace Pinetime {
CurrentTimeService(DateTime& dateTimeController); CurrentTimeService(DateTime& dateTimeController);
void Init(); void Init();
int OnTimeAccessed(uint16_t conn_handle, uint16_t attr_handle, int OnTimeAccessed(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt);
struct ble_gatt_access_ctxt *ctxt);
private: private:
static constexpr uint16_t ctsId {0x1805}; static constexpr uint16_t ctsId {0x1805};
static constexpr uint16_t ctsCharId {0x2a2b}; static constexpr uint16_t ctsCharId {0x2a2b};
static constexpr ble_uuid16_t ctsUuid { static constexpr ble_uuid16_t ctsUuid {.u {.type = BLE_UUID_TYPE_16}, .value = ctsId};
.u { .type = BLE_UUID_TYPE_16 },
.value = ctsId
};
static constexpr ble_uuid16_t ctChrUuid { static constexpr ble_uuid16_t ctChrUuid {.u {.type = BLE_UUID_TYPE_16}, .value = ctsCharId};
.u { .type = BLE_UUID_TYPE_16 },
.value = ctsCharId
};
struct ble_gatt_chr_def characteristicDefinition[2]; struct ble_gatt_chr_def characteristicDefinition[2];
struct ble_gatt_svc_def serviceDefinition[2]; struct ble_gatt_svc_def serviceDefinition[2];

View file

@ -10,7 +10,6 @@ constexpr ble_uuid16_t DeviceInformationService::deviceInfoUuid;
constexpr ble_uuid16_t DeviceInformationService::hwRevisionUuid; constexpr ble_uuid16_t DeviceInformationService::hwRevisionUuid;
constexpr ble_uuid16_t DeviceInformationService::swRevisionUuid; constexpr ble_uuid16_t DeviceInformationService::swRevisionUuid;
int DeviceInformationCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) { int DeviceInformationCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) {
auto deviceInformationService = static_cast<DeviceInformationService*>(arg); auto deviceInformationService = static_cast<DeviceInformationService*>(arg);
return deviceInformationService->OnDeviceInfoRequested(conn_handle, attr_handle, ctxt); return deviceInformationService->OnDeviceInfoRequested(conn_handle, attr_handle, ctxt);
@ -25,9 +24,7 @@ void DeviceInformationService::Init() {
ASSERT(res == 0); ASSERT(res == 0);
} }
int DeviceInformationService::OnDeviceInfoRequested(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) {
int DeviceInformationService::OnDeviceInfoRequested(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt) {
const char* str; const char* str;
switch (ble_uuid_u16(ctxt->chr->uuid)) { switch (ble_uuid_u16(ctxt->chr->uuid)) {
@ -57,9 +54,8 @@ int DeviceInformationService::OnDeviceInfoRequested(uint16_t conn_handle, uint16
return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
} }
DeviceInformationService::DeviceInformationService() : DeviceInformationService::DeviceInformationService()
characteristicDefinition{ : characteristicDefinition {{
{
.uuid = (ble_uuid_t*) &manufacturerNameUuid, .uuid = (ble_uuid_t*) &manufacturerNameUuid,
.access_cb = DeviceInformationCallback, .access_cb = DeviceInformationCallback,
.arg = this, .arg = this,
@ -95,22 +91,12 @@ DeviceInformationService::DeviceInformationService() :
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_READ, .flags = BLE_GATT_CHR_F_READ,
}, },
{ {0}},
0
}
},
serviceDefinition { serviceDefinition {
{ {/* Device Information Service */
/* Device Information Service */
.type = BLE_GATT_SVC_TYPE_PRIMARY, .type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = (ble_uuid_t*) &deviceInfoUuid, .uuid = (ble_uuid_t*) &deviceInfoUuid,
.characteristics = characteristicDefinition .characteristics = characteristicDefinition},
}, {0},
{ } {
0
},
} }
{
}

View file

@ -13,8 +13,7 @@ namespace Pinetime {
DeviceInformationService(); DeviceInformationService();
void Init(); void Init();
int OnDeviceInfoRequested(uint16_t conn_handle, uint16_t attr_handle, int OnDeviceInfoRequested(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt);
struct ble_gatt_access_ctxt *ctxt);
private: private:
static constexpr uint16_t deviceInfoId {0x180a}; static constexpr uint16_t deviceInfoId {0x180a};
@ -32,46 +31,22 @@ namespace Pinetime {
static constexpr const char* fwRevision = Version::VersionString(); static constexpr const char* fwRevision = Version::VersionString();
static constexpr const char* swRevision = "InfiniTime"; static constexpr const char* swRevision = "InfiniTime";
static constexpr ble_uuid16_t deviceInfoUuid {.u {.type = BLE_UUID_TYPE_16}, .value = deviceInfoId};
static constexpr ble_uuid16_t deviceInfoUuid { static constexpr ble_uuid16_t manufacturerNameUuid {.u {.type = BLE_UUID_TYPE_16}, .value = manufacturerNameId};
.u { .type = BLE_UUID_TYPE_16 },
.value = deviceInfoId
};
static constexpr ble_uuid16_t manufacturerNameUuid { static constexpr ble_uuid16_t modelNumberUuid {.u {.type = BLE_UUID_TYPE_16}, .value = modelNumberId};
.u { .type = BLE_UUID_TYPE_16 },
.value = manufacturerNameId
};
static constexpr ble_uuid16_t modelNumberUuid { static constexpr ble_uuid16_t serialNumberUuid {.u {.type = BLE_UUID_TYPE_16}, .value = serialNumberId};
.u { .type = BLE_UUID_TYPE_16 },
.value = modelNumberId
};
static constexpr ble_uuid16_t serialNumberUuid { static constexpr ble_uuid16_t fwRevisionUuid {.u {.type = BLE_UUID_TYPE_16}, .value = fwRevisionId};
.u { .type = BLE_UUID_TYPE_16 },
.value = serialNumberId
};
static constexpr ble_uuid16_t fwRevisionUuid { static constexpr ble_uuid16_t hwRevisionUuid {.u {.type = BLE_UUID_TYPE_16}, .value = hwRevisionId};
.u { .type = BLE_UUID_TYPE_16 },
.value = fwRevisionId
};
static constexpr ble_uuid16_t hwRevisionUuid { static constexpr ble_uuid16_t swRevisionUuid {.u {.type = BLE_UUID_TYPE_16}, .value = swRevisionId};
.u {.type = BLE_UUID_TYPE_16},
.value = hwRevisionId
};
static constexpr ble_uuid16_t swRevisionUuid {
.u {.type = BLE_UUID_TYPE_16},
.value = swRevisionId
};
struct ble_gatt_chr_def characteristicDefinition[7]; struct ble_gatt_chr_def characteristicDefinition[7];
struct ble_gatt_svc_def serviceDefinition[2]; struct ble_gatt_svc_def serviceDefinition[2];
}; };
} }
} }

View file

@ -11,8 +11,7 @@ constexpr ble_uuid128_t DfuService::controlPointCharacteristicUuid;
constexpr ble_uuid128_t DfuService::revisionCharacteristicUuid; constexpr ble_uuid128_t DfuService::revisionCharacteristicUuid;
constexpr ble_uuid128_t DfuService::packetCharacteristicUuid; constexpr ble_uuid128_t DfuService::packetCharacteristicUuid;
int DfuServiceCallback(uint16_t conn_handle, uint16_t attr_handle, int DfuServiceCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) {
struct ble_gatt_access_ctxt *ctxt, void *arg) {
auto dfuService = static_cast<DfuService*>(arg); auto dfuService = static_cast<DfuService*>(arg);
return dfuService->OnServiceData(conn_handle, attr_handle, ctxt); return dfuService->OnServiceData(conn_handle, attr_handle, ctxt);
} }
@ -27,13 +26,13 @@ void TimeoutTimerCallback(TimerHandle_t xTimer) {
dfuService->OnTimeout(); dfuService->OnTimeout();
} }
DfuService::DfuService(Pinetime::System::SystemTask &systemTask, Pinetime::Controllers::Ble &bleController, DfuService::DfuService(Pinetime::System::SystemTask& systemTask,
Pinetime::Drivers::SpiNorFlash &spiNorFlash) : Pinetime::Controllers::Ble& bleController,
systemTask{systemTask}, Pinetime::Drivers::SpiNorFlash& spiNorFlash)
: systemTask {systemTask},
bleController {bleController}, bleController {bleController},
dfuImage {spiNorFlash}, dfuImage {spiNorFlash},
characteristicDefinition{ characteristicDefinition {{
{
.uuid = (ble_uuid_t*) &packetCharacteristicUuid, .uuid = (ble_uuid_t*) &packetCharacteristicUuid,
.access_cb = DfuServiceCallback, .access_cb = DfuServiceCallback,
.arg = this, .arg = this,
@ -55,21 +54,15 @@ DfuService::DfuService(Pinetime::System::SystemTask &systemTask, Pinetime::Contr
.val_handle = &revision, .val_handle = &revision,
}, },
{ {0}
0
}
}, },
serviceDefinition { serviceDefinition {
{ {/* Device Information Service */
/* Device Information Service */
.type = BLE_GATT_SVC_TYPE_PRIMARY, .type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = (ble_uuid_t*) &serviceUuid, .uuid = (ble_uuid_t*) &serviceUuid,
.characteristics = characteristicDefinition .characteristics = characteristicDefinition},
}, {0},
{
0
},
} { } {
timeoutTimer = xTimerCreate("notificationTimer", 10000, pdFALSE, this, TimeoutTimerCallback); timeoutTimer = xTimerCreate("notificationTimer", 10000, pdFALSE, this, TimeoutTimerCallback);
} }
@ -88,26 +81,25 @@ int DfuService::OnServiceData(uint16_t connectionHandle, uint16_t attributeHandl
xTimerStart(timeoutTimer, 0); xTimerStart(timeoutTimer, 0);
} }
ble_gatts_find_chr((ble_uuid_t*) &serviceUuid, (ble_uuid_t*) &packetCharacteristicUuid, nullptr, &packetCharacteristicHandle);
ble_gatts_find_chr((ble_uuid_t *) &serviceUuid, (ble_uuid_t *) &packetCharacteristicUuid, nullptr, ble_gatts_find_chr((ble_uuid_t*) &serviceUuid, (ble_uuid_t*) &controlPointCharacteristicUuid, nullptr, &controlPointCharacteristicHandle);
&packetCharacteristicHandle); ble_gatts_find_chr((ble_uuid_t*) &serviceUuid, (ble_uuid_t*) &revisionCharacteristicUuid, nullptr, &revisionCharacteristicHandle);
ble_gatts_find_chr((ble_uuid_t *) &serviceUuid, (ble_uuid_t *) &controlPointCharacteristicUuid, nullptr,
&controlPointCharacteristicHandle);
ble_gatts_find_chr((ble_uuid_t *) &serviceUuid, (ble_uuid_t *) &revisionCharacteristicUuid, nullptr,
&revisionCharacteristicHandle);
if (attributeHandle == packetCharacteristicHandle) { if (attributeHandle == packetCharacteristicHandle) {
if (context->op == BLE_GATT_ACCESS_OP_WRITE_CHR) if (context->op == BLE_GATT_ACCESS_OP_WRITE_CHR)
return WritePacketHandler(connectionHandle, context->om); return WritePacketHandler(connectionHandle, context->om);
else return 0; else
return 0;
} else if (attributeHandle == controlPointCharacteristicHandle) { } else if (attributeHandle == controlPointCharacteristicHandle) {
if (context->op == BLE_GATT_ACCESS_OP_WRITE_CHR) if (context->op == BLE_GATT_ACCESS_OP_WRITE_CHR)
return ControlPointHandler(connectionHandle, context->om); return ControlPointHandler(connectionHandle, context->om);
else return 0; else
return 0;
} else if (attributeHandle == revisionCharacteristicHandle) { } else if (attributeHandle == revisionCharacteristicHandle) {
if (context->op == BLE_GATT_ACCESS_OP_READ_CHR) if (context->op == BLE_GATT_ACCESS_OP_READ_CHR)
return SendDfuRevision(context->om); return SendDfuRevision(context->om);
else return 0; else
return 0;
} else { } else {
NRF_LOG_INFO("[DFU] Unknown Characteristic : %d", attributeHandle); NRF_LOG_INFO("[DFU] Unknown Characteristic : %d", attributeHandle);
return 0; return 0;
@ -126,8 +118,8 @@ int DfuService::WritePacketHandler(uint16_t connectionHandle, os_mbuf *om) {
bootloaderSize = om->om_data[4] + (om->om_data[5] << 8) + (om->om_data[6] << 16) + (om->om_data[7] << 24); bootloaderSize = om->om_data[4] + (om->om_data[5] << 8) + (om->om_data[6] << 16) + (om->om_data[7] << 24);
applicationSize = om->om_data[8] + (om->om_data[9] << 8) + (om->om_data[10] << 16) + (om->om_data[11] << 24); applicationSize = om->om_data[8] + (om->om_data[9] << 8) + (om->om_data[10] << 16) + (om->om_data[11] << 24);
bleController.FirmwareUpdateTotalBytes(applicationSize); bleController.FirmwareUpdateTotalBytes(applicationSize);
NRF_LOG_INFO("[DFU] -> Start data received : SD size : %d, BT size : %d, app size : %d", softdeviceSize, NRF_LOG_INFO(
bootloaderSize, applicationSize); "[DFU] -> Start data received : SD size : %d, BT size : %d, app size : %d", softdeviceSize, bootloaderSize, applicationSize);
dfuImage.Erase(); dfuImage.Erase();
@ -139,19 +131,22 @@ int DfuService::WritePacketHandler(uint16_t connectionHandle, os_mbuf *om) {
case States::Init: { case States::Init: {
uint16_t deviceType = om->om_data[0] + (om->om_data[1] << 8); uint16_t deviceType = om->om_data[0] + (om->om_data[1] << 8);
uint16_t deviceRevision = om->om_data[2] + (om->om_data[3] << 8); uint16_t deviceRevision = om->om_data[2] + (om->om_data[3] << 8);
uint32_t applicationVersion = uint32_t applicationVersion = om->om_data[4] + (om->om_data[5] << 8) + (om->om_data[6] << 16) + (om->om_data[7] << 24);
om->om_data[4] + (om->om_data[5] << 8) + (om->om_data[6] << 16) + (om->om_data[7] << 24);
uint16_t softdeviceArrayLength = om->om_data[8] + (om->om_data[9] << 8); uint16_t softdeviceArrayLength = om->om_data[8] + (om->om_data[9] << 8);
uint16_t sd[softdeviceArrayLength]; uint16_t sd[softdeviceArrayLength];
for (int i = 0; i < softdeviceArrayLength; i++) { for (int i = 0; i < softdeviceArrayLength; i++) {
sd[i] = om->om_data[10 + (i * 2)] + (om->om_data[10 + (i * 2) + 1] << 8); sd[i] = om->om_data[10 + (i * 2)] + (om->om_data[10 + (i * 2) + 1] << 8);
} }
expectedCrc = expectedCrc = om->om_data[10 + (softdeviceArrayLength * 2)] + (om->om_data[10 + (softdeviceArrayLength * 2) + 1] << 8);
om->om_data[10 + (softdeviceArrayLength * 2)] + (om->om_data[10 + (softdeviceArrayLength * 2) + 1] << 8);
NRF_LOG_INFO( NRF_LOG_INFO(
"[DFU] -> Init data received : deviceType = %d, deviceRevision = %d, applicationVersion = %d, nb SD = %d, First SD = %d, CRC = %u", "[DFU] -> Init data received : deviceType = %d, deviceRevision = %d, applicationVersion = %d, nb SD = %d, First SD = %d, CRC = %u",
deviceType, deviceRevision, applicationVersion, softdeviceArrayLength, sd[0], expectedCrc); deviceType,
deviceRevision,
applicationVersion,
softdeviceArrayLength,
sd[0],
expectedCrc);
return 0; return 0;
} }
@ -164,8 +159,10 @@ int DfuService::WritePacketHandler(uint16_t connectionHandle, os_mbuf *om) {
if ((nbPacketReceived % nbPacketsToNotify) == 0 && bytesReceived != applicationSize) { if ((nbPacketReceived % nbPacketsToNotify) == 0 && bytesReceived != applicationSize) {
uint8_t data[5] {static_cast<uint8_t>(Opcodes::PacketReceiptNotification), uint8_t data[5] {static_cast<uint8_t>(Opcodes::PacketReceiptNotification),
(uint8_t) (bytesReceived & 0x000000FFu), (uint8_t) (bytesReceived >> 8u), (uint8_t) (bytesReceived & 0x000000FFu),
(uint8_t) (bytesReceived >> 16u), (uint8_t) (bytesReceived >> 24u)}; (uint8_t) (bytesReceived >> 8u),
(uint8_t) (bytesReceived >> 16u),
(uint8_t) (bytesReceived >> 24u)};
NRF_LOG_INFO("[DFU] -> Send packet notification: %d bytes received", bytesReceived); NRF_LOG_INFO("[DFU] -> Send packet notification: %d bytes received", bytesReceived);
notificationManager.Send(connectionHandle, controlPointCharacteristicHandle, data, 5); notificationManager.Send(connectionHandle, controlPointCharacteristicHandle, data, 5);
} }
@ -214,8 +211,7 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf *om) {
NRF_LOG_INFO("[DFU] -> Start DFU, mode %d not supported!", imageType); NRF_LOG_INFO("[DFU] -> Start DFU, mode %d not supported!", imageType);
return 0; return 0;
} }
} } break;
break;
case Opcodes::InitDFUParameters: { case Opcodes::InitDFUParameters: {
if (state != States::Init) { if (state != States::Init) {
NRF_LOG_INFO("[DFU] -> Init DFU requested, but we are not in Init state"); NRF_LOG_INFO("[DFU] -> Init DFU requested, but we are not in Init state");
@ -225,11 +221,9 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf *om) {
NRF_LOG_INFO("[DFU] -> Init DFU parameters %s", isInitComplete ? " complete" : " not complete"); NRF_LOG_INFO("[DFU] -> Init DFU parameters %s", isInitComplete ? " complete" : " not complete");
if (isInitComplete) { if (isInitComplete) {
uint8_t data[3] { uint8_t data[3] {static_cast<uint8_t>(Opcodes::Response),
static_cast<uint8_t>(Opcodes::Response),
static_cast<uint8_t>(Opcodes::InitDFUParameters), static_cast<uint8_t>(Opcodes::InitDFUParameters),
(isInitComplete ? uint8_t{1} : uint8_t{0}) (isInitComplete ? uint8_t {1} : uint8_t {0})};
};
notificationManager.AsyncSend(connectionHandle, controlPointCharacteristicHandle, data, 3); notificationManager.AsyncSend(connectionHandle, controlPointCharacteristicHandle, data, 3);
return 0; return 0;
} }
@ -262,21 +256,17 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf *om) {
bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated); bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated);
NRF_LOG_INFO("Image OK"); NRF_LOG_INFO("Image OK");
uint8_t data[3] { uint8_t data[3] {static_cast<uint8_t>(Opcodes::Response),
static_cast<uint8_t>(Opcodes::Response),
static_cast<uint8_t>(Opcodes::ValidateFirmware), static_cast<uint8_t>(Opcodes::ValidateFirmware),
static_cast<uint8_t>(ErrorCodes::NoError) static_cast<uint8_t>(ErrorCodes::NoError)};
};
notificationManager.AsyncSend(connectionHandle, controlPointCharacteristicHandle, data, 3); notificationManager.AsyncSend(connectionHandle, controlPointCharacteristicHandle, data, 3);
} else { } else {
bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Error); bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Error);
NRF_LOG_INFO("Image Error : bad CRC"); NRF_LOG_INFO("Image Error : bad CRC");
uint8_t data[3] { uint8_t data[3] {static_cast<uint8_t>(Opcodes::Response),
static_cast<uint8_t>(Opcodes::Response),
static_cast<uint8_t>(Opcodes::ValidateFirmware), static_cast<uint8_t>(Opcodes::ValidateFirmware),
static_cast<uint8_t>(ErrorCodes::CrcError) static_cast<uint8_t>(ErrorCodes::CrcError)};
};
notificationManager.AsyncSend(connectionHandle, controlPointCharacteristicHandle, data, 3); notificationManager.AsyncSend(connectionHandle, controlPointCharacteristicHandle, data, 3);
} }
@ -354,7 +344,8 @@ void DfuService::NotificationManager::Reset() {
} }
void DfuService::DfuImage::Init(size_t chunkSize, size_t totalSize, uint16_t expectedCrc) { void DfuService::DfuImage::Init(size_t chunkSize, size_t totalSize, uint16_t expectedCrc) {
if(chunkSize != 20) return; if (chunkSize != 20)
return;
this->chunkSize = chunkSize; this->chunkSize = chunkSize;
this->totalSize = totalSize; this->totalSize = totalSize;
this->expectedCrc = expectedCrc; this->expectedCrc = expectedCrc;
@ -362,7 +353,8 @@ void DfuService::DfuImage::Init(size_t chunkSize, size_t totalSize, uint16_t exp
} }
void DfuService::DfuImage::Append(uint8_t* data, size_t size) { void DfuService::DfuImage::Append(uint8_t* data, size_t size) {
if(!ready) return; if (!ready)
return;
ASSERT(size <= 20); ASSERT(size <= 20);
std::memcpy(tempBuffer + bufferWriteIndex, data, size); std::memcpy(tempBuffer + bufferWriteIndex, data, size);
@ -383,7 +375,8 @@ void DfuService::DfuImage::Append(uint8_t *data, size_t size) {
} }
void DfuService::DfuImage::WriteMagicNumber() { void DfuService::DfuImage::WriteMagicNumber() {
uint32_t magic[4] = { // TODO When this variable is a static constexpr, the values written to the memory are not correct. Why? uint32_t magic[4] = {
// TODO When this variable is a static constexpr, the values written to the memory are not correct. Why?
0xf395c277, 0xf395c277,
0x7fefd260, 0x7fefd260,
0x0f505235, 0x0f505235,
@ -436,6 +429,7 @@ uint16_t DfuService::DfuImage::ComputeCrc(uint8_t const *p_data, uint32_t size,
} }
bool DfuService::DfuImage::IsComplete() { bool DfuService::DfuImage::IsComplete() {
if(!ready) return false; if (!ready)
return false;
return totalWriteIndex == totalSize; return totalWriteIndex == totalSize;
} }

View file

@ -21,7 +21,8 @@ namespace Pinetime {
class DfuService { class DfuService {
public: public:
DfuService(Pinetime::System::SystemTask &systemTask, Pinetime::Controllers::Ble &bleController, DfuService(Pinetime::System::SystemTask& systemTask,
Pinetime::Controllers::Ble& bleController,
Pinetime::Drivers::SpiNorFlash& spiNorFlash); Pinetime::Drivers::SpiNorFlash& spiNorFlash);
void Init(); void Init();
int OnServiceData(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context); int OnServiceData(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context);
@ -33,19 +34,22 @@ namespace Pinetime {
NotificationManager(); NotificationManager();
bool AsyncSend(uint16_t connection, uint16_t charactHandle, uint8_t* data, size_t size); bool AsyncSend(uint16_t connection, uint16_t charactHandle, uint8_t* data, size_t size);
void Send(uint16_t connection, uint16_t characteristicHandle, const uint8_t* data, const size_t s); void Send(uint16_t connection, uint16_t characteristicHandle, const uint8_t* data, const size_t s);
private: private:
TimerHandle_t timer; TimerHandle_t timer;
uint16_t connectionHandle = 0; uint16_t connectionHandle = 0;
uint16_t characteristicHandle = 0; uint16_t characteristicHandle = 0;
size_t size = 0; size_t size = 0;
uint8_t buffer[10]; uint8_t buffer[10];
public: public:
void OnNotificationTimer(); void OnNotificationTimer();
void Reset(); void Reset();
}; };
class DfuImage { class DfuImage {
public: public:
DfuImage(Pinetime::Drivers::SpiNorFlash& spiNorFlash) : spiNorFlash{spiNorFlash} {} DfuImage(Pinetime::Drivers::SpiNorFlash& spiNorFlash) : spiNorFlash {spiNorFlash} {
}
void Init(size_t chunkSize, size_t totalSize, uint16_t expectedCrc); void Init(size_t chunkSize, size_t totalSize, uint16_t expectedCrc);
void Erase(); void Erase();
void Append(uint8_t* data, size_t size); void Append(uint8_t* data, size_t size);
@ -67,7 +71,6 @@ namespace Pinetime {
void WriteMagicNumber(); void WriteMagicNumber();
uint16_t ComputeCrc(uint8_t const* p_data, uint32_t size, uint16_t const* p_crc); uint16_t ComputeCrc(uint8_t const* p_data, uint32_t size, uint16_t const* p_crc);
}; };
private: private:
@ -85,27 +88,19 @@ namespace Pinetime {
static constexpr ble_uuid128_t serviceUuid { static constexpr ble_uuid128_t serviceUuid {
.u {.type = BLE_UUID_TYPE_128}, .u {.type = BLE_UUID_TYPE_128},
.value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, .value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, 0xDE, 0xEF, 0x12, 0x12, 0x30, 0x15, 0x00, 0x00}};
0xDE, 0xEF, 0x12, 0x12, 0x30, 0x15, 0x00, 0x00}
};
static constexpr ble_uuid128_t packetCharacteristicUuid { static constexpr ble_uuid128_t packetCharacteristicUuid {
.u {.type = BLE_UUID_TYPE_128}, .u {.type = BLE_UUID_TYPE_128},
.value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, .value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, 0xDE, 0xEF, 0x12, 0x12, 0x32, 0x15, 0x00, 0x00}};
0xDE, 0xEF, 0x12, 0x12, 0x32, 0x15, 0x00, 0x00}
};
static constexpr ble_uuid128_t controlPointCharacteristicUuid { static constexpr ble_uuid128_t controlPointCharacteristicUuid {
.u {.type = BLE_UUID_TYPE_128}, .u {.type = BLE_UUID_TYPE_128},
.value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, .value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, 0xDE, 0xEF, 0x12, 0x12, 0x31, 0x15, 0x00, 0x00}};
0xDE, 0xEF, 0x12, 0x12, 0x31, 0x15, 0x00, 0x00}
};
static constexpr ble_uuid128_t revisionCharacteristicUuid { static constexpr ble_uuid128_t revisionCharacteristicUuid {
.u {.type = BLE_UUID_TYPE_128}, .u {.type = BLE_UUID_TYPE_128},
.value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, .value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, 0xDE, 0xEF, 0x12, 0x12, 0x34, 0x15, 0x00, 0x00}};
0xDE, 0xEF, 0x12, 0x12, 0x34, 0x15, 0x00, 0x00}
};
struct ble_gatt_chr_def characteristicDefinition[4]; struct ble_gatt_chr_def characteristicDefinition[4];
struct ble_gatt_svc_def serviceDefinition[2]; struct ble_gatt_svc_def serviceDefinition[2];
@ -113,9 +108,7 @@ namespace Pinetime {
uint16_t controlPointCharacteristicHandle; uint16_t controlPointCharacteristicHandle;
uint16_t revisionCharacteristicHandle; uint16_t revisionCharacteristicHandle;
enum class States : uint8_t { enum class States : uint8_t { Idle, Init, Start, Data, Validate, Validated };
Idle, Init, Start, Data, Validate, Validated
};
States state = States::Idle; States state = States::Idle;
enum class ImageTypes : uint8_t { enum class ImageTypes : uint8_t {

View file

@ -15,31 +15,21 @@ namespace {
} }
// TODO Refactoring - remove dependency to SystemTask // TODO Refactoring - remove dependency to SystemTask
HeartRateService::HeartRateService(Pinetime::System::SystemTask &system, Controllers::HeartRateController& heartRateController) : HeartRateService::HeartRateService(Pinetime::System::SystemTask& system, Controllers::HeartRateController& heartRateController)
system{system}, : system {system},
heartRateController {heartRateController}, heartRateController {heartRateController},
characteristicDefinition{ characteristicDefinition {{.uuid = (ble_uuid_t*) &heartRateMeasurementUuid,
{
.uuid = (ble_uuid_t *) &heartRateMeasurementUuid,
.access_cb = HeartRateServiceServiceCallback, .access_cb = HeartRateServiceServiceCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY,
.val_handle = &heartRateMeasurementHandle .val_handle = &heartRateMeasurementHandle},
}, {0}},
{
0
}
},
serviceDefinition { serviceDefinition {
{ {/* Device Information Service */
/* Device Information Service */
.type = BLE_GATT_SVC_TYPE_PRIMARY, .type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = (ble_uuid_t*) &heartRateServiceUuid, .uuid = (ble_uuid_t*) &heartRateServiceUuid,
.characteristics = characteristicDefinition .characteristics = characteristicDefinition},
}, {0},
{
0
},
} { } {
// TODO refactor to prevent this loop dependency (service depends on controller and controller depends on service) // TODO refactor to prevent this loop dependency (service depends on controller and controller depends on service)
heartRateController.SetService(this); heartRateController.SetService(this);
@ -54,8 +44,7 @@ void HeartRateService::Init() {
ASSERT(res == 0); ASSERT(res == 0);
} }
int HeartRateService::OnHeartRateRequested(uint16_t connectionHandle, uint16_t attributeHandle, int HeartRateService::OnHeartRateRequested(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context) {
ble_gatt_access_ctxt *context) {
if (attributeHandle == heartRateMeasurementHandle) { if (attributeHandle == heartRateMeasurementHandle) {
NRF_LOG_INFO("HEARTRATE : handle = %d", heartRateMeasurementHandle); NRF_LOG_INFO("HEARTRATE : handle = %d", heartRateMeasurementHandle);
uint8_t buffer[2] = {0, heartRateController.HeartRate()}; // [0] = flags, [1] = hr value uint8_t buffer[2] = {0, heartRateController.HeartRate()}; // [0] = flags, [1] = hr value

View file

@ -24,21 +24,14 @@ namespace Pinetime {
static constexpr uint16_t heartRateServiceId {0x180D}; static constexpr uint16_t heartRateServiceId {0x180D};
static constexpr uint16_t heartRateMeasurementId {0x2A37}; static constexpr uint16_t heartRateMeasurementId {0x2A37};
static constexpr ble_uuid16_t heartRateServiceUuid { static constexpr ble_uuid16_t heartRateServiceUuid {.u {.type = BLE_UUID_TYPE_16}, .value = heartRateServiceId};
.u {.type = BLE_UUID_TYPE_16},
.value = heartRateServiceId
};
static constexpr ble_uuid16_t heartRateMeasurementUuid { static constexpr ble_uuid16_t heartRateMeasurementUuid {.u {.type = BLE_UUID_TYPE_16}, .value = heartRateMeasurementId};
.u {.type = BLE_UUID_TYPE_16},
.value = heartRateMeasurementId
};
struct ble_gatt_chr_def characteristicDefinition[3]; struct ble_gatt_chr_def characteristicDefinition[3];
struct ble_gatt_svc_def serviceDefinition[2]; struct ble_gatt_svc_def serviceDefinition[2];
uint16_t heartRateMeasurementHandle; uint16_t heartRateMeasurementHandle;
}; };
} }
} }

View file

@ -16,42 +16,35 @@ namespace {
const char* ToString(ImmediateAlertService::Levels level) { const char* ToString(ImmediateAlertService::Levels level) {
switch (level) { switch (level) {
case ImmediateAlertService::Levels::NoAlert: return "Alert : None"; case ImmediateAlertService::Levels::NoAlert:
case ImmediateAlertService::Levels::HighAlert: return "Alert : High"; return "Alert : None";
case ImmediateAlertService::Levels::MildAlert: return "Alert : Mild"; case ImmediateAlertService::Levels::HighAlert:
default: return ""; return "Alert : High";
case ImmediateAlertService::Levels::MildAlert:
return "Alert : Mild";
default:
return "";
} }
} }
} }
ImmediateAlertService::ImmediateAlertService(Pinetime::System::SystemTask& systemTask, ImmediateAlertService::ImmediateAlertService(Pinetime::System::SystemTask& systemTask,
Pinetime::Controllers::NotificationManager &notificationManager) : Pinetime::Controllers::NotificationManager& notificationManager)
systemTask{systemTask}, : systemTask {systemTask},
notificationManager {notificationManager}, notificationManager {notificationManager},
characteristicDefinition{ characteristicDefinition {{.uuid = (ble_uuid_t*) &alertLevelUuid,
{
.uuid = (ble_uuid_t *) &alertLevelUuid,
.access_cb = AlertLevelCallback, .access_cb = AlertLevelCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_WRITE_NO_RSP, .flags = BLE_GATT_CHR_F_WRITE_NO_RSP,
.val_handle = &alertLevelHandle .val_handle = &alertLevelHandle},
}, {0}},
{
0
}
},
serviceDefinition { serviceDefinition {
{ {/* Device Information Service */
/* Device Information Service */
.type = BLE_GATT_SVC_TYPE_PRIMARY, .type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = (ble_uuid_t*) &immediateAlertServiceUuid, .uuid = (ble_uuid_t*) &immediateAlertServiceUuid,
.characteristics = characteristicDefinition .characteristics = characteristicDefinition},
}, {0},
{
0
},
} { } {
} }
void ImmediateAlertService::Init() { void ImmediateAlertService::Init() {

View file

@ -13,14 +13,9 @@ namespace Pinetime {
class NotificationManager; class NotificationManager;
class ImmediateAlertService { class ImmediateAlertService {
public: public:
enum class Levels : uint8_t { enum class Levels : uint8_t { NoAlert = 0, MildAlert = 1, HighAlert = 2 };
NoAlert = 0,
MildAlert = 1,
HighAlert = 2
};
ImmediateAlertService(Pinetime::System::SystemTask &systemTask, ImmediateAlertService(Pinetime::System::SystemTask& systemTask, Pinetime::Controllers::NotificationManager& notificationManager);
Pinetime::Controllers::NotificationManager &notificationManager);
void Init(); void Init();
int OnAlertLevelChanged(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context); int OnAlertLevelChanged(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context);
@ -31,15 +26,9 @@ namespace Pinetime {
static constexpr uint16_t immediateAlertServiceId {0x1802}; static constexpr uint16_t immediateAlertServiceId {0x1802};
static constexpr uint16_t alertLevelId {0x2A06}; static constexpr uint16_t alertLevelId {0x2A06};
static constexpr ble_uuid16_t immediateAlertServiceUuid { static constexpr ble_uuid16_t immediateAlertServiceUuid {.u {.type = BLE_UUID_TYPE_16}, .value = immediateAlertServiceId};
.u {.type = BLE_UUID_TYPE_16},
.value = immediateAlertServiceId
};
static constexpr ble_uuid16_t alertLevelUuid { static constexpr ble_uuid16_t alertLevelUuid {.u {.type = BLE_UUID_TYPE_16}, .value = alertLevelId};
.u {.type = BLE_UUID_TYPE_16},
.value = alertLevelId
};
struct ble_gatt_chr_def characteristicDefinition[3]; struct ble_gatt_chr_def characteristicDefinition[3];
struct ble_gatt_svc_def serviceDefinition[2]; struct ble_gatt_svc_def serviceDefinition[2];

View file

@ -91,75 +91,44 @@ Pinetime::Controllers::MusicService::MusicService(Pinetime::System::SystemTask &
.access_cb = MSCallback, .access_cb = MSCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_NOTIFY, .flags = BLE_GATT_CHR_F_NOTIFY,
.val_handle = &eventHandle .val_handle = &eventHandle};
}; characteristicDefinition[1] = {
characteristicDefinition[1] = {.uuid = (ble_uuid_t *) (&msStatusCharUuid), .uuid = (ble_uuid_t*) (&msStatusCharUuid), .access_cb = MSCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
.access_cb = MSCallback, characteristicDefinition[2] = {
.arg = this, .uuid = (ble_uuid_t*) (&msTrackCharUuid), .access_cb = MSCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ characteristicDefinition[3] = {
}; .uuid = (ble_uuid_t*) (&msArtistCharUuid), .access_cb = MSCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[2] = {.uuid = (ble_uuid_t *) (&msTrackCharUuid), characteristicDefinition[4] = {
.access_cb = MSCallback, .uuid = (ble_uuid_t*) (&msAlbumCharUuid), .access_cb = MSCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
.arg = this, characteristicDefinition[5] = {
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ .uuid = (ble_uuid_t*) (&msPositionCharUuid), .access_cb = MSCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
};
characteristicDefinition[3] = {.uuid = (ble_uuid_t *) (&msArtistCharUuid),
.access_cb = MSCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ
};
characteristicDefinition[4] = {.uuid = (ble_uuid_t *) (&msAlbumCharUuid),
.access_cb = MSCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ
};
characteristicDefinition[5] = {.uuid = (ble_uuid_t *) (&msPositionCharUuid),
.access_cb = MSCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ
};
characteristicDefinition[6] = {.uuid = (ble_uuid_t*) (&msTotalLengthCharUuid), characteristicDefinition[6] = {.uuid = (ble_uuid_t*) (&msTotalLengthCharUuid),
.access_cb = MSCallback, .access_cb = MSCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
};
characteristicDefinition[7] = {.uuid = (ble_uuid_t*) (&msTotalLengthCharUuid), characteristicDefinition[7] = {.uuid = (ble_uuid_t*) (&msTotalLengthCharUuid),
.access_cb = MSCallback, .access_cb = MSCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
};
characteristicDefinition[8] = {.uuid = (ble_uuid_t*) (&msTrackNumberCharUuid), characteristicDefinition[8] = {.uuid = (ble_uuid_t*) (&msTrackNumberCharUuid),
.access_cb = MSCallback, .access_cb = MSCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
};
characteristicDefinition[9] = {.uuid = (ble_uuid_t*) (&msTrackTotalCharUuid), characteristicDefinition[9] = {.uuid = (ble_uuid_t*) (&msTrackTotalCharUuid),
.access_cb = MSCallback, .access_cb = MSCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
};
characteristicDefinition[10] = {.uuid = (ble_uuid_t*) (&msPlaybackSpeedCharUuid), characteristicDefinition[10] = {.uuid = (ble_uuid_t*) (&msPlaybackSpeedCharUuid),
.access_cb = MSCallback, .access_cb = MSCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
}; characteristicDefinition[11] = {
characteristicDefinition[11] = {.uuid = (ble_uuid_t *) (&msRepeatCharUuid), .uuid = (ble_uuid_t*) (&msRepeatCharUuid), .access_cb = MSCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
.access_cb = MSCallback, characteristicDefinition[12] = {
.arg = this, .uuid = (ble_uuid_t*) (&msShuffleCharUuid), .access_cb = MSCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ
};
characteristicDefinition[12] = {.uuid = (ble_uuid_t *) (&msShuffleCharUuid),
.access_cb = MSCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ
};
characteristicDefinition[13] = {0}; characteristicDefinition[13] = {0};
serviceDefinition[0] = { serviceDefinition[0] = {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = (ble_uuid_t*) &msUuid, .characteristics = characteristicDefinition};
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = (ble_uuid_t *) &msUuid,
.characteristics = characteristicDefinition
};
serviceDefinition[1] = {0}; serviceDefinition[1] = {0};
artistName = "Waiting for"; artistName = "Waiting for";
@ -182,8 +151,7 @@ void Pinetime::Controllers::MusicService::Init() {
ASSERT(res == 0); ASSERT(res == 0);
} }
int Pinetime::Controllers::MusicService::OnCommand(uint16_t conn_handle, uint16_t attr_handle, int Pinetime::Controllers::MusicService::OnCommand(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) {
struct ble_gatt_access_ctxt *ctxt) {
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
size_t notifSize = OS_MBUF_PKTLEN(ctxt->om); size_t notifSize = OS_MBUF_PKTLEN(ctxt->om);
@ -257,4 +225,3 @@ int Pinetime::Controllers::MusicService::getProgress() {
int Pinetime::Controllers::MusicService::getTrackLength() { int Pinetime::Controllers::MusicService::getTrackLength() {
return trackLength; return trackLength;
} }

View file

@ -27,7 +27,8 @@
#undef min #undef min
// 00000000-78fc-48fe-8e23-433b3a1942d0 // 00000000-78fc-48fe-8e23-433b3a1942d0
#define MUSIC_SERVICE_UUID_BASE {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, 0x00, 0x00, 0x00, 0x00} #define MUSIC_SERVICE_UUID_BASE \
{ 0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, 0x00, 0x00, 0x00, 0x00 }
namespace Pinetime { namespace Pinetime {
namespace System { namespace System {
@ -41,8 +42,7 @@ namespace Pinetime {
void Init(); void Init();
int OnCommand(uint16_t conn_handle, uint16_t attr_handle, int OnCommand(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt);
struct ble_gatt_access_ctxt *ctxt);
void event(char event); void event(char event);
@ -68,10 +68,8 @@ namespace Pinetime {
static const char EVENT_MUSIC_VOLUP = 0x05; static const char EVENT_MUSIC_VOLUP = 0x05;
static const char EVENT_MUSIC_VOLDOWN = 0x06; static const char EVENT_MUSIC_VOLDOWN = 0x06;
enum MusicStatus { enum MusicStatus { NotPlaying = 0x00, Playing = 0x01 };
NotPlaying = 0x00,
Playing = 0x01
};
private: private:
static constexpr uint8_t msId[2] = {0x00, 0x00}; static constexpr uint8_t msId[2] = {0x00, 0x00};
static constexpr uint8_t msEventCharId[2] = {0x01, 0x00}; static constexpr uint8_t msEventCharId[2] = {0x01, 0x00};
@ -87,59 +85,20 @@ namespace Pinetime {
static constexpr uint8_t msRepeatCharId[2] = {0x0b, 0x00}; static constexpr uint8_t msRepeatCharId[2] = {0x0b, 0x00};
static constexpr uint8_t msShuffleCharId[2] = {0x0c, 0x00}; static constexpr uint8_t msShuffleCharId[2] = {0x0c, 0x00};
ble_uuid128_t msUuid{ ble_uuid128_t msUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
.u = {.type = BLE_UUID_TYPE_128},
.value = MUSIC_SERVICE_UUID_BASE
};
ble_uuid128_t msEventCharUuid{ ble_uuid128_t msEventCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
.u = {.type = BLE_UUID_TYPE_128}, ble_uuid128_t msStatusCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
.value = MUSIC_SERVICE_UUID_BASE ble_uuid128_t msArtistCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
}; ble_uuid128_t msTrackCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
ble_uuid128_t msStatusCharUuid{ ble_uuid128_t msAlbumCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
.u = {.type = BLE_UUID_TYPE_128}, ble_uuid128_t msPositionCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
.value = MUSIC_SERVICE_UUID_BASE ble_uuid128_t msTotalLengthCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
}; ble_uuid128_t msTrackNumberCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
ble_uuid128_t msArtistCharUuid{ ble_uuid128_t msTrackTotalCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
.u = {.type = BLE_UUID_TYPE_128}, ble_uuid128_t msPlaybackSpeedCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
.value = MUSIC_SERVICE_UUID_BASE ble_uuid128_t msRepeatCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
}; ble_uuid128_t msShuffleCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
ble_uuid128_t msTrackCharUuid{
.u = {.type = BLE_UUID_TYPE_128},
.value = MUSIC_SERVICE_UUID_BASE
};
ble_uuid128_t msAlbumCharUuid{
.u = {.type = BLE_UUID_TYPE_128},
.value = MUSIC_SERVICE_UUID_BASE
};
ble_uuid128_t msPositionCharUuid{
.u = {.type = BLE_UUID_TYPE_128},
.value = MUSIC_SERVICE_UUID_BASE
};
ble_uuid128_t msTotalLengthCharUuid{
.u = {.type = BLE_UUID_TYPE_128},
.value = MUSIC_SERVICE_UUID_BASE
};
ble_uuid128_t msTrackNumberCharUuid{
.u = {.type = BLE_UUID_TYPE_128},
.value = MUSIC_SERVICE_UUID_BASE
};
ble_uuid128_t msTrackTotalCharUuid{
.u = {.type = BLE_UUID_TYPE_128},
.value = MUSIC_SERVICE_UUID_BASE
};
ble_uuid128_t msPlaybackSpeedCharUuid{
.u = {.type = BLE_UUID_TYPE_128},
.value = MUSIC_SERVICE_UUID_BASE
};
ble_uuid128_t msRepeatCharUuid{
.u = {.type = BLE_UUID_TYPE_128},
.value = MUSIC_SERVICE_UUID_BASE
};
ble_uuid128_t msShuffleCharUuid{
.u = {.type = BLE_UUID_TYPE_128},
.value = MUSIC_SERVICE_UUID_BASE
};
struct ble_gatt_chr_def characteristicDefinition[14]; struct ble_gatt_chr_def characteristicDefinition[14];
struct ble_gatt_svc_def serviceDefinition[2]; struct ble_gatt_svc_def serviceDefinition[2];
@ -166,4 +125,3 @@ namespace Pinetime {
}; };
} }
} }

View file

@ -49,35 +49,25 @@ Pinetime::Controllers::NavigationService::NavigationService(Pinetime::System::Sy
navProgressCharUuid.value[14] = navId[0]; navProgressCharUuid.value[14] = navId[0];
navProgressCharUuid.value[15] = navId[1]; navProgressCharUuid.value[15] = navId[1];
characteristicDefinition[0] = {.uuid = (ble_uuid_t *) (&navFlagCharUuid), characteristicDefinition[0] = {
.access_cb = NAVCallback, .uuid = (ble_uuid_t*) (&navFlagCharUuid), .access_cb = NAVCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ
};
characteristicDefinition[1] = {.uuid = (ble_uuid_t*) (&navNarrativeCharUuid), characteristicDefinition[1] = {.uuid = (ble_uuid_t*) (&navNarrativeCharUuid),
.access_cb = NAVCallback, .access_cb = NAVCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
};
characteristicDefinition[2] = {.uuid = (ble_uuid_t*) (&navManDistCharUuid), characteristicDefinition[2] = {.uuid = (ble_uuid_t*) (&navManDistCharUuid),
.access_cb = NAVCallback, .access_cb = NAVCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
};
characteristicDefinition[3] = {.uuid = (ble_uuid_t*) (&navProgressCharUuid), characteristicDefinition[3] = {.uuid = (ble_uuid_t*) (&navProgressCharUuid),
.access_cb = NAVCallback, .access_cb = NAVCallback,
.arg = this, .arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
};
characteristicDefinition[4] = {0}; characteristicDefinition[4] = {0};
serviceDefinition[0] = { serviceDefinition[0] = {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = (ble_uuid_t*) &navUuid, .characteristics = characteristicDefinition};
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = (ble_uuid_t *) &navUuid,
.characteristics = characteristicDefinition
};
serviceDefinition[1] = {0}; serviceDefinition[1] = {0};
m_progress = 0; m_progress = 0;
@ -92,8 +82,7 @@ void Pinetime::Controllers::NavigationService::Init() {
ASSERT(res == 0); ASSERT(res == 0);
} }
int Pinetime::Controllers::NavigationService::OnCommand(uint16_t conn_handle, uint16_t attr_handle, int Pinetime::Controllers::NavigationService::OnCommand(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) {
struct ble_gatt_access_ctxt *ctxt) {
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
size_t notifSize = OS_MBUF_PKTLEN(ctxt->om); size_t notifSize = OS_MBUF_PKTLEN(ctxt->om);
@ -114,23 +103,18 @@ int Pinetime::Controllers::NavigationService::OnCommand(uint16_t conn_handle, ui
return 0; return 0;
} }
std::string Pinetime::Controllers::NavigationService::getFlag() std::string Pinetime::Controllers::NavigationService::getFlag() {
{
return m_flag; return m_flag;
} }
std::string Pinetime::Controllers::NavigationService::getNarrative() std::string Pinetime::Controllers::NavigationService::getNarrative() {
{
return m_narrative; return m_narrative;
} }
std::string Pinetime::Controllers::NavigationService::getManDist() std::string Pinetime::Controllers::NavigationService::getManDist() {
{
return m_manDist; return m_manDist;
} }
int Pinetime::Controllers::NavigationService::getProgress() int Pinetime::Controllers::NavigationService::getProgress() {
{
return m_progress; return m_progress;
} }

View file

@ -27,7 +27,8 @@
#undef min #undef min
// c7e60000-78fc-48fe-8e23-433b3a1942d0 // c7e60000-78fc-48fe-8e23-433b3a1942d0
#define NAVIGATION_SERVICE_UUID_BASE {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, 0x00, 0x00, 0x00, 0x00} #define NAVIGATION_SERVICE_UUID_BASE \
{ 0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, 0x00, 0x00, 0x00, 0x00 }
namespace Pinetime { namespace Pinetime {
namespace System { namespace System {
@ -41,8 +42,7 @@ namespace Pinetime {
void Init(); void Init();
int OnCommand(uint16_t conn_handle, uint16_t attr_handle, int OnCommand(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt);
struct ble_gatt_access_ctxt *ctxt);
std::string getFlag(); std::string getFlag();
@ -59,27 +59,12 @@ namespace Pinetime {
static constexpr uint8_t navManDistCharId[2] = {0x03, 0x00}; static constexpr uint8_t navManDistCharId[2] = {0x03, 0x00};
static constexpr uint8_t navProgressCharId[2] = {0x04, 0x00}; static constexpr uint8_t navProgressCharId[2] = {0x04, 0x00};
ble_uuid128_t navUuid{ ble_uuid128_t navUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = NAVIGATION_SERVICE_UUID_BASE};
.u = {.type = BLE_UUID_TYPE_128},
.value = NAVIGATION_SERVICE_UUID_BASE
};
ble_uuid128_t navFlagCharUuid{ ble_uuid128_t navFlagCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = NAVIGATION_SERVICE_UUID_BASE};
.u = {.type = BLE_UUID_TYPE_128}, ble_uuid128_t navNarrativeCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = NAVIGATION_SERVICE_UUID_BASE};
.value = NAVIGATION_SERVICE_UUID_BASE ble_uuid128_t navManDistCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = NAVIGATION_SERVICE_UUID_BASE};
}; ble_uuid128_t navProgressCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = NAVIGATION_SERVICE_UUID_BASE};
ble_uuid128_t navNarrativeCharUuid{
.u = {.type = BLE_UUID_TYPE_128},
.value = NAVIGATION_SERVICE_UUID_BASE
};
ble_uuid128_t navManDistCharUuid{
.u = {.type = BLE_UUID_TYPE_128},
.value = NAVIGATION_SERVICE_UUID_BASE
};
ble_uuid128_t navProgressCharUuid{
.u = {.type = BLE_UUID_TYPE_128},
.value = NAVIGATION_SERVICE_UUID_BASE
};
struct ble_gatt_chr_def characteristicDefinition[5]; struct ble_gatt_chr_def characteristicDefinition[5];
struct ble_gatt_svc_def serviceDefinition[2]; struct ble_gatt_svc_def serviceDefinition[2];
@ -93,4 +78,3 @@ namespace Pinetime {
}; };
} }
} }

View file

@ -23,8 +23,8 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask,
Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::NotificationManager& notificationManager,
Controllers::Battery& batteryController, Controllers::Battery& batteryController,
Pinetime::Drivers::SpiNorFlash& spiNorFlash, Pinetime::Drivers::SpiNorFlash& spiNorFlash,
Controllers::HeartRateController& heartRateController) : Controllers::HeartRateController& heartRateController)
systemTask{systemTask}, : systemTask {systemTask},
bleController {bleController}, bleController {bleController},
dateTimeController {dateTimeController}, dateTimeController {dateTimeController},
notificationManager {notificationManager}, notificationManager {notificationManager},
@ -48,7 +48,8 @@ int GAPEventCallback(struct ble_gap_event *event, void *arg) {
} }
void NimbleController::Init() { void NimbleController::Init() {
while (!ble_hs_synced()) {} while (!ble_hs_synced()) {
}
ble_svc_gap_init(); ble_svc_gap_init();
ble_svc_gatt_init(); ble_svc_gatt_init();
@ -81,7 +82,8 @@ void NimbleController::Init() {
} }
void NimbleController::StartAdvertising() { void NimbleController::StartAdvertising() {
if(bleController.IsConnected() || ble_gap_conn_active() || ble_gap_adv_active()) return; if (bleController.IsConnected() || ble_gap_conn_active() || ble_gap_adv_active())
return;
ble_svc_gap_device_name_set(deviceName); ble_svc_gap_device_name_set(deviceName);
@ -101,8 +103,7 @@ void NimbleController::StartAdvertising() {
adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
fields.flags = BLE_HS_ADV_F_DISC_GEN | fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP;
BLE_HS_ADV_F_BREDR_UNSUP;
// fields.uuids128 = BLE_UUID128(BLE_UUID128_DECLARE( // fields.uuids128 = BLE_UUID128(BLE_UUID128_DECLARE(
// 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
// 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff)); // 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff));
@ -121,8 +122,7 @@ void NimbleController::StartAdvertising() {
ble_gap_adv_rsp_set_fields(&rsp_fields); ble_gap_adv_rsp_set_fields(&rsp_fields);
// ASSERT(res == 0); // ASSERT(res == 0);
ble_gap_adv_start(addrType, NULL, 180000, ble_gap_adv_start(addrType, NULL, 180000, &adv_params, GAPEventCallback, this);
&adv_params, GAPEventCallback, this);
// ASSERT(res == 0);// TODO I've disabled these ASSERT as they sometime asserts and reset the mcu. // ASSERT(res == 0);// TODO I've disabled these ASSERT as they sometime asserts and reset the mcu.
// For now, the advertising is restarted as soon as it ends. There may be a race condition // For now, the advertising is restarted as soon as it ends. There may be a race condition
// that prevent the advertising from restarting reliably. // that prevent the advertising from restarting reliably.
@ -141,8 +141,7 @@ int NimbleController::OnGAPEvent(ble_gap_event *event) {
NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_CONNECT"); NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_CONNECT");
/* A new connection was established or a connection attempt failed. */ /* A new connection was established or a connection attempt failed. */
NRF_LOG_INFO("connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", NRF_LOG_INFO("connection %s; status=%d ", event->connect.status == 0 ? "established" : "failed", event->connect.status);
event->connect.status);
if (event->connect.status != 0) { if (event->connect.status != 0) {
/* Connection failed; resume advertising. */ /* Connection failed; resume advertising. */
@ -154,8 +153,7 @@ int NimbleController::OnGAPEvent(ble_gap_event *event) {
connectionHandle = event->connect.conn_handle; connectionHandle = event->connect.conn_handle;
// Service discovery is deffered via systemtask // Service discovery is deffered via systemtask
} }
} } break;
break;
case BLE_GAP_EVENT_DISCONNECT: case BLE_GAP_EVENT_DISCONNECT:
NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_DISCONNECT"); NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_DISCONNECT");
NRF_LOG_INFO("disconnect; reason=%d", event->disconnect.reason); NRF_LOG_INFO("disconnect; reason=%d", event->disconnect.reason);
@ -187,10 +185,7 @@ int NimbleController::OnGAPEvent(ble_gap_event *event) {
event->subscribe.prev_indicate); event->subscribe.prev_indicate);
return 0; return 0;
case BLE_GAP_EVENT_MTU: case BLE_GAP_EVENT_MTU:
NRF_LOG_INFO("mtu update event; conn_handle=%d cid=%d mtu=%d\n", NRF_LOG_INFO("mtu update event; conn_handle=%d cid=%d mtu=%d\n", event->mtu.conn_handle, event->mtu.channel_id, event->mtu.value);
event->mtu.conn_handle,
event->mtu.channel_id,
event->mtu.value);
return 0; return 0;
case BLE_GAP_EVENT_REPEAT_PAIRING: { case BLE_GAP_EVENT_REPEAT_PAIRING: {
@ -216,9 +211,7 @@ int NimbleController::OnGAPEvent(ble_gap_event *event) {
NRF_LOG_INFO("received %s; conn_handle=%d attr_handle=%d " NRF_LOG_INFO("received %s; conn_handle=%d attr_handle=%d "
"attr_len=%d", "attr_len=%d",
event->notify_rx.indication ? event->notify_rx.indication ? "indication" : "notification",
"indication" :
"notification",
event->notify_rx.conn_handle, event->notify_rx.conn_handle,
event->notify_rx.attr_handle, event->notify_rx.attr_handle,
notifSize); notifSize);
@ -239,8 +232,6 @@ void NimbleController::StartDiscovery() {
serviceDiscovery.StartDiscovery(connectionHandle); serviceDiscovery.StartDiscovery(connectionHandle);
} }
uint16_t NimbleController::connHandle() { uint16_t NimbleController::connHandle() {
return connectionHandle; return connectionHandle;
} }

View file

@ -37,28 +37,37 @@ namespace Pinetime {
class NimbleController { class NimbleController {
public: public:
NimbleController(Pinetime::System::SystemTask& systemTask, Pinetime::Controllers::Ble& bleController, NimbleController(Pinetime::System::SystemTask& systemTask,
DateTime& dateTimeController, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::Ble& bleController,
Controllers::Battery& batteryController, Pinetime::Drivers::SpiNorFlash& spiNorFlash, DateTime& dateTimeController,
Pinetime::Controllers::NotificationManager& notificationManager,
Controllers::Battery& batteryController,
Pinetime::Drivers::SpiNorFlash& spiNorFlash,
Controllers::HeartRateController& heartRateController); Controllers::HeartRateController& heartRateController);
void Init(); void Init();
void StartAdvertising(); void StartAdvertising();
int OnGAPEvent(ble_gap_event* event); int OnGAPEvent(ble_gap_event* event);
int OnDiscoveryEvent(uint16_t i, const ble_gatt_error* pError, const ble_gatt_svc* pSvc); int OnDiscoveryEvent(uint16_t i, const ble_gatt_error* pError, const ble_gatt_svc* pSvc);
int OnCTSCharacteristicDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error, int OnCTSCharacteristicDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_chr* characteristic);
const ble_gatt_chr *characteristic); int OnANSCharacteristicDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error* error, const ble_gatt_chr* characteristic);
int OnANSCharacteristicDiscoveryEvent(uint16_t connectionHandle, const ble_gatt_error *error,
const ble_gatt_chr *characteristic);
int OnCurrentTimeReadResult(uint16_t connectionHandle, const ble_gatt_error* error, ble_gatt_attr* attribute); int OnCurrentTimeReadResult(uint16_t connectionHandle, const ble_gatt_error* error, ble_gatt_attr* attribute);
int OnANSDescriptorDiscoveryEventCallback(uint16_t connectionHandle, const ble_gatt_error *error, int OnANSDescriptorDiscoveryEventCallback(uint16_t connectionHandle,
uint16_t characteristicValueHandle, const ble_gatt_dsc *descriptor); const ble_gatt_error* error,
uint16_t characteristicValueHandle,
const ble_gatt_dsc* descriptor);
void StartDiscovery(); void StartDiscovery();
Pinetime::Controllers::MusicService& music() {return musicService;}; Pinetime::Controllers::MusicService& music() {
Pinetime::Controllers::NavigationService& navigation() {return navService;}; return musicService;
Pinetime::Controllers::AlertNotificationService& alertService() {return anService;}; };
Pinetime::Controllers::NavigationService& navigation() {
return navService;
};
Pinetime::Controllers::AlertNotificationService& alertService() {
return anService;
};
uint16_t connHandle(); uint16_t connHandle();
@ -87,9 +96,7 @@ namespace Pinetime {
ble_uuid128_t dfuServiceUuid { ble_uuid128_t dfuServiceUuid {
.u {.type = BLE_UUID_TYPE_128}, .u {.type = BLE_UUID_TYPE_128},
.value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, .value = {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, 0xDE, 0xEF, 0x12, 0x12, 0x30, 0x15, 0x00, 0x00}};
0xDE, 0xEF, 0x12, 0x12, 0x30, 0x15, 0x00, 0x00}
};
ServiceDiscovery serviceDiscovery; ServiceDiscovery serviceDiscovery;
}; };

View file

@ -6,7 +6,6 @@ using namespace Pinetime::Controllers;
constexpr uint8_t NotificationManager::MessageSize; constexpr uint8_t NotificationManager::MessageSize;
void NotificationManager::Push(NotificationManager::Notification&& notif) { void NotificationManager::Push(NotificationManager::Notification&& notif) {
notif.id = GetNextId(); notif.id = GetNextId();
notif.valid = true; notif.valid = true;
@ -14,7 +13,8 @@ void NotificationManager::Push(NotificationManager::Notification &&notif) {
writeIndex = (writeIndex + 1 < TotalNbNotifications) ? writeIndex + 1 : 0; writeIndex = (writeIndex + 1 < TotalNbNotifications) ? writeIndex + 1 : 0;
if (!empty) if (!empty)
readIndex = (readIndex + 1 < TotalNbNotifications) ? readIndex + 1 : 0; readIndex = (readIndex + 1 < TotalNbNotifications) ? readIndex + 1 : 0;
else empty = false; else
empty = false;
newNotification = true; newNotification = true;
} }
@ -30,8 +30,11 @@ NotificationManager::Notification::Id NotificationManager::GetNextId() {
} }
NotificationManager::Notification NotificationManager::GetNext(NotificationManager::Notification::Id id) { NotificationManager::Notification NotificationManager::GetNext(NotificationManager::Notification::Id id) {
auto currentIterator = std::find_if(notifications.begin(), notifications.end(), [id](const Notification& n){return n.valid && n.id == id;}); auto currentIterator = std::find_if(notifications.begin(), notifications.end(), [id](const Notification& n) {
if(currentIterator == notifications.end() || currentIterator->id != id) return Notification{}; return n.valid && n.id == id;
});
if (currentIterator == notifications.end() || currentIterator->id != id)
return Notification {};
auto& lastNotification = notifications[readIndex]; auto& lastNotification = notifications[readIndex];
@ -42,15 +45,19 @@ NotificationManager::Notification NotificationManager::GetNext(NotificationManag
else else
result = *(currentIterator + 1); result = *(currentIterator + 1);
if(result.id <= id) return {}; if (result.id <= id)
return {};
result.index = (lastNotification.id - result.id) + 1; result.index = (lastNotification.id - result.id) + 1;
return result; return result;
} }
NotificationManager::Notification NotificationManager::GetPrevious(NotificationManager::Notification::Id id) { NotificationManager::Notification NotificationManager::GetPrevious(NotificationManager::Notification::Id id) {
auto currentIterator = std::find_if(notifications.begin(), notifications.end(), [id](const Notification& n){return n.valid && n.id == id;}); auto currentIterator = std::find_if(notifications.begin(), notifications.end(), [id](const Notification& n) {
if(currentIterator == notifications.end() || currentIterator->id != id) return Notification{}; return n.valid && n.id == id;
});
if (currentIterator == notifications.end() || currentIterator->id != id)
return Notification {};
auto& lastNotification = notifications[readIndex]; auto& lastNotification = notifications[readIndex];
@ -61,7 +68,8 @@ NotificationManager::Notification NotificationManager::GetPrevious(NotificationM
else else
result = *(currentIterator - 1); result = *(currentIterator - 1);
if(result.id >= id) return {}; if (result.id >= id)
return {};
result.index = (lastNotification.id - result.id) + 1; result.index = (lastNotification.id - result.id) + 1;
return result; return result;
@ -84,7 +92,9 @@ bool NotificationManager::ClearNewNotificationFlag() {
} }
size_t NotificationManager::NbNotifications() const { size_t NotificationManager::NbNotifications() const {
return std::count_if(notifications.begin(), notifications.end(), [](const Notification& n){ return n.valid;}); return std::count_if(notifications.begin(), notifications.end(), [](const Notification& n) {
return n.valid;
});
} }
const char* NotificationManager::Notification::Message() const { const char* NotificationManager::Notification::Message() const {

View file

@ -9,7 +9,19 @@ namespace Pinetime {
namespace Controllers { namespace Controllers {
class NotificationManager { class NotificationManager {
public: public:
enum class Categories {Unknown, SimpleAlert, Email, News, IncomingCall, MissedCall, Sms, VoiceMail, Schedule, HighProriotyAlert, InstantMessage }; enum class Categories {
Unknown,
SimpleAlert,
Email,
News,
IncomingCall,
MissedCall,
Sms,
VoiceMail,
Schedule,
HighProriotyAlert,
InstantMessage
};
static constexpr uint8_t MessageSize {100}; static constexpr uint8_t MessageSize {100};
struct Notification { struct Notification {
@ -35,7 +47,9 @@ namespace Pinetime {
bool IsVibrationEnabled(); bool IsVibrationEnabled();
void ToggleVibrations(); void ToggleVibrations();
static constexpr size_t MaximumMessageSize() { return MessageSize; }; static constexpr size_t MaximumMessageSize() {
return MessageSize;
};
size_t NbNotifications() const; size_t NbNotifications() const;
private: private:

View file

@ -5,7 +5,6 @@
using namespace Pinetime::Controllers; using namespace Pinetime::Controllers;
ServiceDiscovery::ServiceDiscovery(std::array<BleClient*, 2>&& clients) : clients {clients} { ServiceDiscovery::ServiceDiscovery(std::array<BleClient*, 2>&& clients) : clients {clients} {
} }
void ServiceDiscovery::StartDiscovery(uint16_t connectionHandle) { void ServiceDiscovery::StartDiscovery(uint16_t connectionHandle) {

View file

@ -13,7 +13,6 @@ namespace Pinetime {
void StartDiscovery(uint16_t connectionHandle); void StartDiscovery(uint16_t connectionHandle);
private: private:
BleClient** clientIterator; BleClient** clientIterator;
std::array<BleClient*, 2> clients; std::array<BleClient*, 2> clients;

View file

@ -4,7 +4,6 @@
using namespace Pinetime::Controllers; using namespace Pinetime::Controllers;
void BrightnessController::Init() { void BrightnessController::Init() {
nrf_gpio_cfg_output(pinLcdBacklight1); nrf_gpio_cfg_output(pinLcdBacklight1);
nrf_gpio_cfg_output(pinLcdBacklight2); nrf_gpio_cfg_output(pinLcdBacklight2);
@ -41,19 +40,33 @@ void BrightnessController::Set(BrightnessController::Levels level) {
void BrightnessController::Lower() { void BrightnessController::Lower() {
switch (level) { switch (level) {
case Levels::High: Set(Levels::Medium); break; case Levels::High:
case Levels::Medium: Set(Levels::Low); break; Set(Levels::Medium);
case Levels::Low: Set(Levels::Off); break; break;
default: break; case Levels::Medium:
Set(Levels::Low);
break;
case Levels::Low:
Set(Levels::Off);
break;
default:
break;
} }
} }
void BrightnessController::Higher() { void BrightnessController::Higher() {
switch (level) { switch (level) {
case Levels::Off: Set(Levels::Low); break; case Levels::Off:
case Levels::Low: Set(Levels::Medium); break; Set(Levels::Low);
case Levels::Medium: Set(Levels::High); break; break;
default: break; case Levels::Low:
Set(Levels::Medium);
break;
case Levels::Medium:
Set(Levels::High);
break;
default:
break;
} }
} }
@ -71,28 +84,43 @@ void BrightnessController::Restore() {
void BrightnessController::Step() { void BrightnessController::Step() {
switch (level) { switch (level) {
case Levels::Low: Set(Levels::Medium); break; case Levels::Low:
case Levels::Medium: Set(Levels::High); break; Set(Levels::Medium);
case Levels::High: Set(Levels::Low); break; break;
default: break; case Levels::Medium:
Set(Levels::High);
break;
case Levels::High:
Set(Levels::Low);
break;
default:
break;
} }
} }
const char* BrightnessController::GetIcon() { const char* BrightnessController::GetIcon() {
switch (level) { switch (level) {
case Levels::Medium: return Applications::Screens::Symbols::brightnessMedium; case Levels::Medium:
case Levels::High: return Applications::Screens::Symbols::brightnessHigh; return Applications::Screens::Symbols::brightnessMedium;
default: break; case Levels::High:
return Applications::Screens::Symbols::brightnessHigh;
default:
break;
} }
return Applications::Screens::Symbols::brightnessLow; return Applications::Screens::Symbols::brightnessLow;
} }
const char* BrightnessController::ToString() { const char* BrightnessController::ToString() {
switch (level) { switch (level) {
case Levels::Off: return "Off"; case Levels::Off:
case Levels::Low: return "Low"; return "Off";
case Levels::Medium: return "Medium"; case Levels::Low:
case Levels::High: return "High"; return "Low";
default : return "???"; case Levels::Medium:
return "Medium";
case Levels::High:
return "High";
default:
return "???";
} }
} }

View file

@ -6,13 +6,12 @@
using namespace Pinetime::Controllers; using namespace Pinetime::Controllers;
DateTime::DateTime(System::SystemTask& systemTask) : systemTask {systemTask} { DateTime::DateTime(System::SystemTask& systemTask) : systemTask {systemTask} {
} }
void DateTime::SetTime(
void DateTime::SetTime(uint16_t year, uint8_t month, uint8_t day, uint8_t dayOfWeek, uint8_t hour, uint8_t minute, uint16_t year, uint8_t month, uint8_t day, uint8_t dayOfWeek, uint8_t hour, uint8_t minute, uint8_t second, uint32_t systickCounter) {
uint8_t second, uint32_t systickCounter) { std::tm tm = {
std::tm tm = { /* .tm_sec = */ second, /* .tm_sec = */ second,
/* .tm_min = */ minute, /* .tm_min = */ minute,
/* .tm_hour = */ hour, /* .tm_hour = */ hour,
/* .tm_mday = */ day, /* .tm_mday = */ day,
@ -105,95 +104,17 @@ const char *DateTime::DayOfWeekShortToStringLow() {
return DateTime::DaysStringShortLow[(uint8_t) dayOfWeek]; return DateTime::DaysStringShortLow[(uint8_t) dayOfWeek];
} }
char const* DateTime::DaysStringLow[] = {"--", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
char const *DateTime::DaysStringLow[] = { char const* DateTime::DaysStringShortLow[] = {"--", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
"--",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
};
char const *DateTime::DaysStringShortLow[] = { char const* DateTime::DaysStringShort[] = {"--", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN"};
"--",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"Sun"
};
char const *DateTime::DaysStringShort[] = { char const* DateTime::DaysString[] = {"--", "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY", "SATURDAY", "SUNDAY"};
"--",
"MON",
"TUE",
"WED",
"THU",
"FRI",
"SAT",
"SUN"
};
char const *DateTime::DaysString[] = { char const* DateTime::MonthsString[] = {"--", "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
"--",
"MONDAY",
"TUESDAY",
"WEDNESDAY",
"THURSDAY",
"FRIDAY",
"SATURDAY",
"SUNDAY"
};
char const *DateTime::MonthsString[] = { char const* DateTime::MonthsStringLow[] = {"--", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
"--",
"JAN",
"FEB",
"MAR",
"APR",
"MAY",
"JUN",
"JUL",
"AUG",
"SEP",
"OCT",
"NOV",
"DEC"
};
char const *DateTime::MonthsStringLow[] = {
"--",
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
};
char const* DateTime::MonthsLow[] = { char const* DateTime::MonthsLow[] = {
"--", "--", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};

View file

@ -11,19 +11,54 @@ namespace Pinetime {
class DateTime { class DateTime {
public: public:
enum class Days : uint8_t { Unknown, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }; enum class Days : uint8_t { Unknown, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday };
enum class Months : uint8_t {Unknown, January, February, March, April, May, June, July, August, September, October, November, December}; enum class Months : uint8_t {
Unknown,
January,
February,
March,
April,
May,
June,
July,
August,
September,
October,
November,
December
};
DateTime(System::SystemTask& systemTask); DateTime(System::SystemTask& systemTask);
void SetTime(uint16_t year, uint8_t month, uint8_t day, uint8_t dayOfWeek, uint8_t hour, uint8_t minute, uint8_t second, uint32_t systickCounter); void SetTime(uint16_t year,
uint8_t month,
uint8_t day,
uint8_t dayOfWeek,
uint8_t hour,
uint8_t minute,
uint8_t second,
uint32_t systickCounter);
void UpdateTime(uint32_t systickCounter); void UpdateTime(uint32_t systickCounter);
uint16_t Year() const { return year; } uint16_t Year() const {
Months Month() const { return month; } return year;
uint8_t Day() const { return day; } }
Days DayOfWeek() const { return dayOfWeek; } Months Month() const {
uint8_t Hours() const { return hour; } return month;
uint8_t Minutes() const { return minute; } }
uint8_t Seconds() const { return second; } uint8_t Day() const {
return day;
}
Days DayOfWeek() const {
return dayOfWeek;
}
uint8_t Hours() const {
return hour;
}
uint8_t Minutes() const {
return minute;
}
uint8_t Seconds() const {
return second;
}
const char* MonthShortToString(); const char* MonthShortToString();
const char* MonthShortToStringLow(); const char* MonthShortToStringLow();
@ -33,8 +68,13 @@ namespace Pinetime {
const char* DayOfWeekToStringLow(); const char* DayOfWeekToStringLow();
const char* DayOfWeekShortToStringLow(); const char* DayOfWeekShortToStringLow();
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> CurrentDateTime() const { return currentDateTime; } std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> CurrentDateTime() const {
std::chrono::seconds Uptime() const { return uptime; } return currentDateTime;
}
std::chrono::seconds Uptime() const {
return uptime;
}
private: private:
System::SystemTask& systemTask; System::SystemTask& systemTask;
uint16_t year = 0; uint16_t year = 0;
@ -58,7 +98,6 @@ namespace Pinetime {
static char const* MonthsString[]; static char const* MonthsString[];
static char const* MonthsStringLow[]; static char const* MonthsStringLow[];
static char const* MonthsLow[]; static char const* MonthsLow[];
}; };
} }
} }

View file

@ -10,6 +10,7 @@ namespace Pinetime {
bool IsValidated() const; bool IsValidated() const;
void Reset(); void Reset();
private: private:
static constexpr uint32_t validBitAdress {0x7BFE8}; static constexpr uint32_t validBitAdress {0x7BFE8};
static constexpr uint32_t validBitValue {1}; static constexpr uint32_t validBitValue {1};

View file

@ -6,7 +6,6 @@ Gfx::Gfx(Pinetime::Drivers::St7789 &lcd) : lcd{lcd} {
} }
void Gfx::Init() { void Gfx::Init() {
} }
void Gfx::ClearScreen() { void Gfx::ClearScreen() {
@ -20,7 +19,6 @@ void Gfx::ClearScreen() {
lcd.DrawBuffer(0, 0, width, height, reinterpret_cast<const uint8_t*>(buffer), width * 2); lcd.DrawBuffer(0, 0, width, height, reinterpret_cast<const uint8_t*>(buffer), width * 2);
WaitTransferFinished(); WaitTransferFinished();
} }
void Gfx::FillRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint16_t color) { void Gfx::FillRectangle(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint16_t color) {
@ -101,8 +99,7 @@ void Gfx::DrawChar(const FONT_INFO *font, uint8_t c, uint8_t *x, uint8_t y, uint
for (uint8_t k = 0; k < 8; k++) { for (uint8_t k = 0; k < 8; k++) {
if ((1 << (7 - k)) & font->data[font->charInfo[char_idx].offset + j]) { if ((1 << (7 - k)) & font->data[font->charInfo[char_idx].offset + j]) {
buffer[(j * 8) + k] = color; buffer[(j * 8) + k] = color;
} } else {
else {
buffer[(j * 8) + k] = bg; buffer[(j * 8) + k] = bg;
} }
} }
@ -142,7 +139,8 @@ void Gfx::SetBackgroundColor(uint16_t color) {
} }
bool Gfx::GetNextBuffer(uint8_t** data, size_t& size) { bool Gfx::GetNextBuffer(uint8_t** data, size_t& size) {
if(!state.busy) return false; if (!state.busy)
return false;
state.remainingIterations--; state.remainingIterations--;
if (state.remainingIterations == 0) { if (state.remainingIterations == 0) {
state.busy = false; state.busy = false;
@ -162,8 +160,7 @@ bool Gfx::GetNextBuffer(uint8_t **data, size_t &size) {
for (uint8_t k = 0; k < 8; k++) { for (uint8_t k = 0; k < 8; k++) {
if ((1 << (7 - k)) & state.font->data[state.font->charInfo[char_idx].offset + ((state.currentIteration + 1) * bytes_in_line) + j]) { if ((1 << (7 - k)) & state.font->data[state.font->charInfo[char_idx].offset + ((state.currentIteration + 1) * bytes_in_line) + j]) {
buffer[(j * 8) + k] = state.color; buffer[(j * 8) + k] = state.color;
} } else {
else {
buffer[(j * 8) + k] = bg; buffer[(j * 8) + k] = bg;
} }
} }

View file

@ -23,20 +23,19 @@ namespace Pinetime {
void SetScrollArea(uint16_t topFixedLines, uint16_t scrollLines, uint16_t bottomFixedLines); void SetScrollArea(uint16_t topFixedLines, uint16_t scrollLines, uint16_t bottomFixedLines);
void SetScrollStartLine(uint16_t line); void SetScrollStartLine(uint16_t line);
void Sleep(); void Sleep();
void Wakeup(); void Wakeup();
bool GetNextBuffer(uint8_t** buffer, size_t& size) override; bool GetNextBuffer(uint8_t** buffer, size_t& size) override;
void pixel_draw(uint8_t x, uint8_t y, uint16_t color); void pixel_draw(uint8_t x, uint8_t y, uint16_t color);
private: private:
static constexpr uint8_t width = 240; static constexpr uint8_t width = 240;
static constexpr uint8_t height = 240; static constexpr uint8_t height = 240;
enum class Action { None, FillRectangle, DrawChar }; enum class Action { None, FillRectangle, DrawChar };
struct State { struct State {
State() : busy{false}, action{Action::None}, remainingIterations{0}, currentIteration{0} {} State() : busy {false}, action {Action::None}, remainingIterations {0}, currentIteration {0} {
}
volatile bool busy; volatile bool busy;
volatile Action action; volatile Action action;
volatile uint16_t remainingIterations; volatile uint16_t remainingIterations;

View file

@ -10,7 +10,6 @@ using namespace Pinetime::Controllers;
/** Original implementation from wasp-os : https://github.com/daniel-thompson/wasp-os/blob/master/wasp/ppg.py */ /** Original implementation from wasp-os : https://github.com/daniel-thompson/wasp-os/blob/master/wasp/ppg.py */
Biquad::Biquad(float b0, float b1, float b2, float a1, float a2) : b0 {b0}, b1 {b1}, b2 {b2}, a1 {a1}, a2 {a2} { Biquad::Biquad(float b0, float b1, float b2, float a1, float a2) : b0 {b0}, b1 {b1}, b2 {b2}, a1 {a1}, a2 {a2} {
} }
float Biquad::Step(float x) { float Biquad::Step(float x) {

View file

@ -5,10 +5,8 @@
using namespace Pinetime::Controllers; using namespace Pinetime::Controllers;
HeartRateController::HeartRateController(Pinetime::System::SystemTask& systemTask) : systemTask {systemTask} { HeartRateController::HeartRateController(Pinetime::System::SystemTask& systemTask) : systemTask {systemTask} {
} }
void HeartRateController::Update(HeartRateController::States newState, uint8_t heartRate) { void HeartRateController::Update(HeartRateController::States newState, uint8_t heartRate) {
this->state = newState; this->state = newState;
if (this->heartRate != heartRate) { if (this->heartRate != heartRate) {
@ -38,4 +36,3 @@ void HeartRateController::SetHeartRateTask(Pinetime::Applications::HeartRateTask
void HeartRateController::SetService(Pinetime::Controllers::HeartRateService* service) { void HeartRateController::SetService(Pinetime::Controllers::HeartRateService* service) {
this->service = service; this->service = service;
} }

View file

@ -22,8 +22,12 @@ namespace Pinetime {
void Update(States newState, uint8_t heartRate); void Update(States newState, uint8_t heartRate);
void SetHeartRateTask(Applications::HeartRateTask* task); void SetHeartRateTask(Applications::HeartRateTask* task);
States State() const { return state; } States State() const {
uint8_t HeartRate() const { return heartRate; } return state;
}
uint8_t HeartRate() const {
return heartRate;
}
void SetService(Pinetime::Controllers::HeartRateService* service); void SetService(Pinetime::Controllers::HeartRateService* service);

View file

@ -38,11 +38,11 @@ namespace {
} }
} }
Ppg::Ppg(float spl) : offset{spl}, Ppg::Ppg(float spl)
: offset {spl},
hpf {0.87033078, -1.74066156, 0.87033078, -1.72377617, 0.75754694}, hpf {0.87033078, -1.74066156, 0.87033078, -1.72377617, 0.75754694},
agc {20, 0.971, 2}, agc {20, 0.971, 2},
lpf {0.11595249, 0.23190498, 0.11595249, -0.72168143, 0.18549138} { lpf {0.11595249, 0.23190498, 0.11595249, -0.72168143, 0.18549138} {
} }
int Ppg::Preprocess(float spl) { int Ppg::Preprocess(float spl) {

View file

@ -24,7 +24,6 @@ namespace Pinetime {
Ptagc agc; Ptagc agc;
Biquad lpf; Biquad lpf;
float ProcessHeartRate(); float ProcessHeartRate();
}; };
} }

View file

@ -11,7 +11,6 @@ using namespace Pinetime::Controllers;
/** Original implementation from wasp-os : https://github.com/daniel-thompson/wasp-os/blob/master/wasp/ppg.py */ /** Original implementation from wasp-os : https://github.com/daniel-thompson/wasp-os/blob/master/wasp/ppg.py */
Ptagc::Ptagc(float start, float decay, float threshold) : peak {start}, decay {decay}, boost {1.0f / decay}, threshold {threshold} { Ptagc::Ptagc(float start, float decay, float threshold) : peak {start}, decay {decay}, boost {1.0f / decay}, threshold {threshold} {
} }
float Ptagc::Step(float spl) { float Ptagc::Step(float spl) {

View file

@ -12,7 +12,6 @@ namespace Pinetime {
float decay; float decay;
float boost; float boost;
float threshold; float threshold;
}; };
} }
} }

View file

@ -8,14 +8,24 @@ namespace Pinetime {
public: public:
void Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps); void Update(int16_t x, int16_t y, int16_t z, uint32_t nbSteps);
uint16_t X() const { return x; } uint16_t X() const {
uint16_t Y() const { return y; } return x;
uint16_t Z() const { return z; } }
uint32_t NbSteps() const { return nbSteps; } uint16_t Y() const {
return y;
}
uint16_t Z() const {
return z;
}
uint32_t NbSteps() const {
return nbSteps;
}
bool ShouldWakeUp(bool isSleeping); bool ShouldWakeUp(bool isSleeping);
void IsSensorOk(bool isOk); void IsSensorOk(bool isOk);
bool IsSensorOk() const { return isSensorOk; } bool IsSensorOk() const {
return isSensorOk;
}
private: private:
uint32_t nbSteps; uint32_t nbSteps;

View file

@ -7,7 +7,8 @@ APP_TIMER_DEF(vibTimer);
using namespace Pinetime::Controllers; using namespace Pinetime::Controllers;
MotorController::MotorController( Controllers::Settings &settingsController ) : settingsController{settingsController} {} MotorController::MotorController(Controllers::Settings& settingsController) : settingsController {settingsController} {
}
void MotorController::Init() { void MotorController::Init() {
nrf_gpio_cfg_output(pinMotor); nrf_gpio_cfg_output(pinMotor);
@ -18,7 +19,8 @@ void MotorController::Init() {
void MotorController::SetDuration(uint8_t motorDuration) { void MotorController::SetDuration(uint8_t motorDuration) {
if ( settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF ) return; if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF)
return;
nrf_gpio_pin_clear(pinMotor); nrf_gpio_pin_clear(pinMotor);
/* Start timer for motorDuration miliseconds and timer triggers vibrate() when it finishes*/ /* Start timer for motorDuration miliseconds and timer triggers vibrate() when it finishes*/

View file

@ -3,7 +3,6 @@
using namespace Pinetime::Tools; using namespace Pinetime::Tools;
RleDecoder::RleDecoder(const uint8_t* buffer, size_t size) : buffer {buffer}, size {size} { RleDecoder::RleDecoder(const uint8_t* buffer, size_t size) : buffer {buffer}, size {size} {
} }
RleDecoder::RleDecoder(const uint8_t* buffer, size_t size, uint16_t foregroundColor, uint16_t backgroundColor) : RleDecoder {buffer, size} { RleDecoder::RleDecoder(const uint8_t* buffer, size_t size, uint16_t foregroundColor, uint16_t backgroundColor) : RleDecoder {buffer, size} {
@ -11,7 +10,6 @@ RleDecoder::RleDecoder(const uint8_t *buffer, size_t size, uint16_t foregroundCo
this->backgroundColor = backgroundColor; this->backgroundColor = backgroundColor;
} }
void RleDecoder::DecodeNext(uint8_t* output, size_t maxBytes) { void RleDecoder::DecodeNext(uint8_t* output, size_t maxBytes) {
for (; encodedBufferIndex < size; encodedBufferIndex++) { for (; encodedBufferIndex < size; encodedBufferIndex++) {
uint8_t rl = buffer[encodedBufferIndex] - processedCount; uint8_t rl = buffer[encodedBufferIndex] - processedCount;
@ -36,4 +34,3 @@ void RleDecoder::DecodeNext(uint8_t *output, size_t maxBytes) {
color = backgroundColor; color = backgroundColor;
} }
} }

View file

@ -11,14 +11,13 @@ struct SettingsHeader {
#define HEADER_SIZE sizeof(SettingsHeader) #define HEADER_SIZE sizeof(SettingsHeader)
Settings::Settings(Pinetime::Drivers::SpiNorFlash& spiNorFlash) : spiNorFlash {spiNorFlash} {
Settings::Settings( Pinetime::Drivers::SpiNorFlash &spiNorFlash ) : spiNorFlash{spiNorFlash} {} }
void Settings::Init() { void Settings::Init() {
// Load default settings from Flash // Load default settings from Flash
LoadSettingsFromFlash(); LoadSettingsFromFlash();
} }
void Settings::SaveSettings() { void Settings::SaveSettings() {
@ -30,7 +29,6 @@ void Settings::SaveSettings() {
settingsChanged = false; settingsChanged = false;
} }
bool Settings::FindHeader() { bool Settings::FindHeader() {
SettingsHeader settingsHeader; SettingsHeader settingsHeader;
uint8_t bufferHead[sizeof(settingsHeader)]; uint8_t bufferHead[sizeof(settingsHeader)];
@ -66,7 +64,6 @@ void Settings::SetHeader( bool state ) {
std::memcpy(bufferHead, &settingsHeader, sizeof(settingsHeader)); std::memcpy(bufferHead, &settingsHeader, sizeof(settingsHeader));
spiNorFlash.Write(settingsBaseAddr + (settingsFlashBlock * 0x1000), bufferHead, sizeof(settingsHeader)); spiNorFlash.Write(settingsBaseAddr + (settingsFlashBlock * 0x1000), bufferHead, sizeof(settingsHeader));
} }
void Settings::SaveSettingsData() { void Settings::SaveSettingsData() {
@ -89,7 +86,6 @@ void Settings::LoadSettingsFromFlash() {
// never used :) // never used :)
ReadSettingsData(); ReadSettingsData();
} }
} }
void Settings::SaveSettingsToFlash() { void Settings::SaveSettingsToFlash() {
@ -106,7 +102,8 @@ void Settings::SaveSettingsToFlash() {
} }
settingsFlashBlock++; settingsFlashBlock++;
if ( settingsFlashBlock > 9 ) settingsFlashBlock = 0; if (settingsFlashBlock > 9)
settingsFlashBlock = 0;
EraseBlock(); EraseBlock();
SetHeader(true); SetHeader(true);

View file

@ -19,49 +19,74 @@ namespace Pinetime {
void SaveSettings(); void SaveSettings();
void SetClockFace(uint8_t face) { void SetClockFace(uint8_t face) {
if ( face != settings.clockFace ) settingsChanged = true; if (face != settings.clockFace)
settingsChanged = true;
settings.clockFace = face; settings.clockFace = face;
}; };
uint8_t GetClockFace() const { return settings.clockFace; }; uint8_t GetClockFace() const {
return settings.clockFace;
};
void SetAppMenu( uint8_t menu ) { appMenu = menu; }; void SetAppMenu(uint8_t menu) {
uint8_t GetAppMenu() { return appMenu; }; appMenu = menu;
};
uint8_t GetAppMenu() {
return appMenu;
};
void SetSettingsMenu( uint8_t menu ) { settingsMenu = menu; }; void SetSettingsMenu(uint8_t menu) {
uint8_t GetSettingsMenu() const { return settingsMenu; }; settingsMenu = menu;
};
uint8_t GetSettingsMenu() const {
return settingsMenu;
};
void SetClockType(ClockType clocktype) { void SetClockType(ClockType clocktype) {
if ( clocktype != settings.clockType ) settingsChanged = true; if (clocktype != settings.clockType)
settingsChanged = true;
settings.clockType = clocktype; settings.clockType = clocktype;
}; };
ClockType GetClockType() const { return settings.clockType; }; ClockType GetClockType() const {
return settings.clockType;
};
void SetVibrationStatus(Vibration status) { void SetVibrationStatus(Vibration status) {
if ( status != settings.vibrationStatus ) settingsChanged = true; if (status != settings.vibrationStatus)
settingsChanged = true;
settings.vibrationStatus = status; settings.vibrationStatus = status;
}; };
Vibration GetVibrationStatus() const { return settings.vibrationStatus; }; Vibration GetVibrationStatus() const {
return settings.vibrationStatus;
};
void SetScreenTimeOut(uint32_t timeout) { void SetScreenTimeOut(uint32_t timeout) {
if ( timeout != settings.screenTimeOut ) settingsChanged = true; if (timeout != settings.screenTimeOut)
settingsChanged = true;
settings.screenTimeOut = timeout; settings.screenTimeOut = timeout;
}; };
uint32_t GetScreenTimeOut() const { return settings.screenTimeOut; }; uint32_t GetScreenTimeOut() const {
return settings.screenTimeOut;
};
void setWakeUpMode(WakeUpMode wakeUp) { void setWakeUpMode(WakeUpMode wakeUp) {
if ( wakeUp != settings.wakeUpMode ) settingsChanged = true; if (wakeUp != settings.wakeUpMode)
settingsChanged = true;
settings.wakeUpMode = wakeUp; settings.wakeUpMode = wakeUp;
}; };
WakeUpMode getWakeUpMode() const { return settings.wakeUpMode; }; WakeUpMode getWakeUpMode() const {
return settings.wakeUpMode;
};
void SetBrightness(Controllers::BrightnessController::Levels level) { void SetBrightness(Controllers::BrightnessController::Levels level) {
if ( level != settings.brightLevel ) settingsChanged = true; if (level != settings.brightLevel)
settingsChanged = true;
settings.brightLevel = level; settings.brightLevel = level;
}; };
Controllers::BrightnessController::Levels GetBrightness() const { return settings.brightLevel; }; Controllers::BrightnessController::Levels GetBrightness() const {
return settings.brightLevel;
};
private: private:
Pinetime::Drivers::SpiNorFlash& spiNorFlash; Pinetime::Drivers::SpiNorFlash& spiNorFlash;
struct SettingsData { struct SettingsData {
@ -76,7 +101,6 @@ namespace Pinetime {
WakeUpMode wakeUpMode = WakeUpMode::None; WakeUpMode wakeUpMode = WakeUpMode::None;
Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium;
}; };
SettingsData settings; SettingsData settings;
@ -99,7 +123,6 @@ namespace Pinetime {
void SaveSettingsData(); void SaveSettingsData();
void LoadSettingsFromFlash(); void LoadSettingsFromFlash();
void SaveSettingsToFlash(); void SaveSettingsToFlash();
}; };
} }
} }

View file

@ -3,9 +3,30 @@
namespace Pinetime { namespace Pinetime {
namespace Applications { namespace Applications {
enum class Apps { enum class Apps {
None, Launcher, Clock, SysInfo, FirmwareUpdate, FirmwareValidation, NotificationsPreview, Notifications, FlashLight, BatteryInfo, None,
Music, Paint, Paddle, Twos, HeartRate, Navigation, StopWatch, Motion, Launcher,
QuickSettings, Settings, SettingWatchFace, SettingTimeFormat, SettingDisplay, SettingWakeUp Clock,
SysInfo,
FirmwareUpdate,
FirmwareValidation,
NotificationsPreview,
Notifications,
FlashLight,
BatteryInfo,
Music,
Paint,
Paddle,
Twos,
HeartRate,
Navigation,
StopWatch,
Motion,
QuickSettings,
Settings,
SettingWatchFace,
SettingTimeFormat,
SettingDisplay,
SettingWakeUp
}; };
} }
} }

View file

@ -40,15 +40,19 @@
using namespace Pinetime::Applications; using namespace Pinetime::Applications;
using namespace Pinetime::Applications::Display; using namespace Pinetime::Applications::Display;
DisplayApp::DisplayApp(Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Drivers::Cst816S &touchPanel, DisplayApp::DisplayApp(Drivers::St7789& lcd,
Controllers::Battery &batteryController, Controllers::Ble &bleController, Components::LittleVgl& lvgl,
Controllers::DateTime &dateTimeController, Drivers::WatchdogView &watchdog, Drivers::Cst816S& touchPanel,
Controllers::Battery& batteryController,
Controllers::Ble& bleController,
Controllers::DateTime& dateTimeController,
Drivers::WatchdogView& watchdog,
System::SystemTask& systemTask, System::SystemTask& systemTask,
Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::NotificationManager& notificationManager,
Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Controllers::HeartRateController& heartRateController,
Controllers::Settings& settingsController, Controllers::Settings& settingsController,
Pinetime::Controllers::MotionController& motionController) : Pinetime::Controllers::MotionController& motionController)
lcd{lcd}, : lcd {lcd},
lvgl {lvgl}, lvgl {lvgl},
touchPanel {touchPanel}, touchPanel {touchPanel},
batteryController {batteryController}, batteryController {batteryController},
@ -129,7 +133,8 @@ void DisplayApp::Refresh() {
systemTask.PushMessage(System::SystemTask::Messages::UpdateTimeOut); systemTask.PushMessage(System::SystemTask::Messages::UpdateTimeOut);
break; break;
case Messages::UpdateBleConnection: case Messages::UpdateBleConnection:
// clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected : Screens::Clock::BleConnectionStates::NotConnected); // clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected :
// Screens::Clock::BleConnectionStates::NotConnected);
break; break;
case Messages::UpdateBatteryLevel: case Messages::UpdateBatteryLevel:
batteryController.Update(); batteryController.Update();
@ -138,7 +143,8 @@ void DisplayApp::Refresh() {
LoadApp(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down); LoadApp(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down);
break; break;
case Messages::TouchEvent: { case Messages::TouchEvent: {
if (state != States::Running) break; if (state != States::Running)
break;
auto gesture = OnTouchEvent(); auto gesture = OnTouchEvent();
if (!currentScreen->OnTouchEvent(gesture)) { if (!currentScreen->OnTouchEvent(gesture)) {
if (currentApp == Apps::Clock) { if (currentApp == Apps::Clock) {
@ -162,8 +168,7 @@ void DisplayApp::Refresh() {
LoadApp(returnToApp, returnDirection); LoadApp(returnToApp, returnDirection);
} }
} }
} } break;
break;
case Messages::ButtonPushed: case Messages::ButtonPushed:
if (currentApp == Apps::Clock) { if (currentApp == Apps::Clock) {
systemTask.PushMessage(System::SystemTask::Messages::GoToSleep); systemTask.PushMessage(System::SystemTask::Messages::GoToSleep);
@ -225,7 +230,14 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
break; break;
case Apps::None: case Apps::None:
case Apps::Clock: case Apps::Clock:
currentScreen = std::make_unique<Screens::Clock>(this, dateTimeController, batteryController, bleController, notificationManager, settingsController, heartRateController, motionController); currentScreen = std::make_unique<Screens::Clock>(this,
dateTimeController,
batteryController,
bleController,
notificationManager,
settingsController,
heartRateController,
motionController);
break; break;
case Apps::FirmwareValidation: case Apps::FirmwareValidation:
@ -237,17 +249,20 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
break; break;
case Apps::Notifications: case Apps::Notifications:
currentScreen = std::make_unique<Screens::Notifications>(this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Normal); currentScreen = std::make_unique<Screens::Notifications>(
this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Normal);
returnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); returnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp);
break; break;
case Apps::NotificationsPreview: case Apps::NotificationsPreview:
currentScreen = std::make_unique<Screens::Notifications>(this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Preview); currentScreen = std::make_unique<Screens::Notifications>(
this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Preview);
returnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); returnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp);
break; break;
// Settings // Settings
case Apps::QuickSettings: case Apps::QuickSettings:
currentScreen = std::make_unique<Screens::QuickSettings>(this, batteryController, dateTimeController, brightnessController, settingsController); currentScreen =
std::make_unique<Screens::QuickSettings>(this, batteryController, dateTimeController, brightnessController, settingsController);
returnApp(Apps::Clock, FullRefreshDirections::LeftAnim, TouchEvents::SwipeLeft); returnApp(Apps::Clock, FullRefreshDirections::LeftAnim, TouchEvents::SwipeLeft);
break; break;
case Apps::Settings: case Apps::Settings:
@ -275,7 +290,8 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
returnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); returnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
break; break;
case Apps::SysInfo: case Apps::SysInfo:
currentScreen = std::make_unique<Screens::SystemInfo>(this, dateTimeController, batteryController, brightnessController, bleController, watchdog); currentScreen =
std::make_unique<Screens::SystemInfo>(this, dateTimeController, batteryController, brightnessController, bleController, watchdog);
returnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); returnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown);
break; break;
// //
@ -313,7 +329,6 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
} }
void DisplayApp::IdleState() { void DisplayApp::IdleState() {
} }
void DisplayApp::PushMessage(Messages msg) { void DisplayApp::PushMessage(Messages msg) {
@ -374,11 +389,11 @@ void DisplayApp::SetFullRefresh(DisplayApp::FullRefreshDirections direction) {
case DisplayApp::FullRefreshDirections::RightAnim: case DisplayApp::FullRefreshDirections::RightAnim:
lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::RightAnim); lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::RightAnim);
break; break;
default: break; default:
break;
} }
} }
void DisplayApp::SetTouchMode(DisplayApp::TouchModes mode) { void DisplayApp::SetTouchMode(DisplayApp::TouchModes mode) {
touchMode = mode; touchMode = mode;
} }

View file

@ -40,15 +40,18 @@ namespace Pinetime {
enum class FullRefreshDirections { None, Up, Down, Left, Right, LeftAnim, RightAnim }; enum class FullRefreshDirections { None, Up, Down, Left, Right, LeftAnim, RightAnim };
enum class TouchModes { Gestures, Polling }; enum class TouchModes { Gestures, Polling };
DisplayApp(Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Drivers::Cst816S &, DisplayApp(Drivers::St7789& lcd,
Controllers::Battery &batteryController, Controllers::Ble &bleController, Components::LittleVgl& lvgl,
Controllers::DateTime &dateTimeController, Drivers::WatchdogView &watchdog, Drivers::Cst816S&,
Controllers::Battery& batteryController,
Controllers::Ble& bleController,
Controllers::DateTime& dateTimeController,
Drivers::WatchdogView& watchdog,
System::SystemTask& systemTask, System::SystemTask& systemTask,
Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::NotificationManager& notificationManager,
Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Controllers::HeartRateController& heartRateController,
Controllers::Settings& settingsController, Controllers::Settings& settingsController,
Pinetime::Controllers::MotionController& motionController Pinetime::Controllers::MotionController& motionController);
);
void Start(); void Start();
void PushMessage(Display::Messages msg); void PushMessage(Display::Messages msg);
@ -58,7 +61,6 @@ namespace Pinetime {
void SetTouchMode(TouchModes mode); void SetTouchMode(TouchModes mode);
private: private:
Pinetime::Drivers::St7789& lcd; Pinetime::Drivers::St7789& lcd;
Pinetime::Components::LittleVgl& lvgl; Pinetime::Components::LittleVgl& lvgl;
Pinetime::Drivers::Cst816S& touchPanel; Pinetime::Drivers::Cst816S& touchPanel;
@ -100,9 +102,6 @@ namespace Pinetime {
void Refresh(); void Refresh();
void returnApp(Apps app, DisplayApp::FullRefreshDirections direction, TouchEvents touchEvent); void returnApp(Apps app, DisplayApp::FullRefreshDirections direction, TouchEvents touchEvent);
void LoadApp(Apps app, DisplayApp::FullRefreshDirections direction); void LoadApp(Apps app, DisplayApp::FullRefreshDirections direction);
}; };
} }
} }

View file

@ -7,17 +7,20 @@
using namespace Pinetime::Applications; using namespace Pinetime::Applications;
DisplayApp::DisplayApp(Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Drivers::Cst816S &touchPanel, DisplayApp::DisplayApp(Drivers::St7789& lcd,
Controllers::Battery &batteryController, Controllers::Ble &bleController, Components::LittleVgl& lvgl,
Controllers::DateTime &dateTimeController, Drivers::WatchdogView &watchdog, Drivers::Cst816S& touchPanel,
Controllers::Battery& batteryController,
Controllers::Ble& bleController,
Controllers::DateTime& dateTimeController,
Drivers::WatchdogView& watchdog,
System::SystemTask& systemTask, System::SystemTask& systemTask,
Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::NotificationManager& notificationManager,
Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Controllers::HeartRateController& heartRateController,
Pinetime::Controllers::Settings& settingsController, Pinetime::Controllers::Settings& settingsController,
Pinetime::Controllers::MotionController& motionController): Pinetime::Controllers::MotionController& motionController)
lcd{lcd}, bleController{bleController} { : lcd {lcd}, bleController {bleController} {
msgQueue = xQueueCreate(queueSize, itemSize); msgQueue = xQueueCreate(queueSize, itemSize);
} }
void DisplayApp::Start() { void DisplayApp::Start() {
@ -61,8 +64,9 @@ void DisplayApp::Refresh() {
} }
if (bleController.IsFirmwareUpdating()) { if (bleController.IsFirmwareUpdating()) {
uint8_t percent = (static_cast<float>(bleController.FirmwareUpdateCurrentBytes()) / uint8_t percent =
static_cast<float>(bleController.FirmwareUpdateTotalBytes())) * 100.0f; (static_cast<float>(bleController.FirmwareUpdateCurrentBytes()) / static_cast<float>(bleController.FirmwareUpdateTotalBytes())) *
100.0f;
switch (bleController.State()) { switch (bleController.State()) {
case Controllers::Ble::FirmwareUpdateStates::Running: case Controllers::Ble::FirmwareUpdateStates::Running:
DisplayOtaProgress(percent, colorWhite); DisplayOtaProgress(percent, colorWhite);

View file

@ -30,9 +30,13 @@ namespace Pinetime {
namespace Applications { namespace Applications {
class DisplayApp { class DisplayApp {
public: public:
DisplayApp(Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Drivers::Cst816S &, DisplayApp(Drivers::St7789& lcd,
Controllers::Battery &batteryController, Controllers::Ble &bleController, Components::LittleVgl& lvgl,
Controllers::DateTime &dateTimeController, Drivers::WatchdogView &watchdog, Drivers::Cst816S&,
Controllers::Battery& batteryController,
Controllers::Ble& bleController,
Controllers::DateTime& dateTimeController,
Drivers::WatchdogView& watchdog,
System::SystemTask& systemTask, System::SystemTask& systemTask,
Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::NotificationManager& notificationManager,
Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Controllers::HeartRateController& heartRateController,
@ -66,10 +70,6 @@ namespace Pinetime {
static constexpr uint16_t colorRedSwapped = 0x00ff; static constexpr uint16_t colorRedSwapped = 0x00ff;
static constexpr uint16_t colorBlack = 0x0000; static constexpr uint16_t colorBlack = 0x0000;
uint8_t displayBuffer[displayWidth * bytesPerPixel]; uint8_t displayBuffer[displayWidth * bytesPerPixel];
}; };
} }
} }

View file

@ -11,20 +11,23 @@ namespace Pinetime {
class LittleVgl { class LittleVgl {
public: public:
enum class FullRefreshDirections { None, Up, Down }; enum class FullRefreshDirections { None, Up, Down };
LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel) {} LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel) {
}
LittleVgl(const LittleVgl&) = delete; LittleVgl(const LittleVgl&) = delete;
LittleVgl& operator=(const LittleVgl&) = delete; LittleVgl& operator=(const LittleVgl&) = delete;
LittleVgl(LittleVgl&&) = delete; LittleVgl(LittleVgl&&) = delete;
LittleVgl& operator=(LittleVgl&&) = delete; LittleVgl& operator=(LittleVgl&&) = delete;
void FlushDisplay(const lv_area_t * area, lv_color_t * color_p) {} void FlushDisplay(const lv_area_t* area, lv_color_t* color_p) {
bool GetTouchPadInfo(lv_indev_data_t *ptr) {return false;} }
void SetFullRefresh(FullRefreshDirections direction) {} bool GetTouchPadInfo(lv_indev_data_t* ptr) {
void SetNewTapEvent(uint16_t x, uint16_t y) {} return false;
}
void SetFullRefresh(FullRefreshDirections direction) {
}
void SetNewTapEvent(uint16_t x, uint16_t y) {
}
}; };
} }
} }

View file

@ -21,7 +21,8 @@ bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) {
return lvgl->GetTouchPadInfo(data); return lvgl->GetTouchPadInfo(data);
} }
LittleVgl::LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel) : lcd{lcd}, touchPanel{touchPanel}, previousClick{0,0} { LittleVgl::LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel)
: lcd {lcd}, touchPanel {touchPanel}, previousClick {0, 0} {
lv_init(); lv_init();
InitTheme(); InitTheme();
InitDisplay(); InitDisplay();
@ -203,13 +204,7 @@ bool LittleVgl::GetTouchPadInfo(lv_indev_data_t *ptr) {
void LittleVgl::InitTheme() { void LittleVgl::InitTheme() {
lv_theme_t* th = lv_pinetime_theme_init( lv_theme_t* th = lv_pinetime_theme_init(
LV_COLOR_WHITE, LV_COLOR_SILVER, LV_COLOR_WHITE, LV_COLOR_SILVER, 0, &jetbrains_mono_bold_20, &jetbrains_mono_bold_20, &jetbrains_mono_bold_20, &jetbrains_mono_bold_20);
0,
&jetbrains_mono_bold_20,
&jetbrains_mono_bold_20,
&jetbrains_mono_bold_20,
&jetbrains_mono_bold_20);
lv_theme_set_act(th); lv_theme_set_act(th);
} }

View file

@ -29,11 +29,9 @@ namespace Pinetime {
void InitTouchpad(); void InitTouchpad();
void InitTheme(); void InitTheme();
Pinetime::Drivers::St7789& lcd; Pinetime::Drivers::St7789& lcd;
Pinetime::Drivers::Cst816S& touchPanel; Pinetime::Drivers::Cst816S& touchPanel;
lv_disp_buf_t disp_buf_2; lv_disp_buf_t disp_buf_2;
lv_color_t buf2_1[LV_HOR_RES_MAX * 4]; lv_color_t buf2_1[LV_HOR_RES_MAX * 4];
lv_color_t buf2_2[LV_HOR_RES_MAX * 4]; lv_color_t buf2_2[LV_HOR_RES_MAX * 4];
@ -45,7 +43,9 @@ namespace Pinetime {
static constexpr uint8_t nbWriteLines = 4; static constexpr uint8_t nbWriteLines = 4;
static constexpr uint16_t totalNbLines = 320; static constexpr uint16_t totalNbLines = 320;
static constexpr uint16_t visibleNbLines = 240; static constexpr uint16_t visibleNbLines = 240;
static constexpr uint8_t MaxScrollOffset() { return LV_VER_RES_MAX - nbWriteLines; } static constexpr uint8_t MaxScrollOffset() {
return LV_VER_RES_MAX - nbWriteLines;
}
FullRefreshDirections scrollDirection = FullRefreshDirections::None; FullRefreshDirections scrollDirection = FullRefreshDirections::None;
uint16_t writeOffset = 0; uint16_t writeOffset = 0;
uint16_t scrollOffset = 0; uint16_t scrollOffset = 0;
@ -56,4 +56,3 @@ namespace Pinetime {
}; };
} }
} }

View file

@ -3,8 +3,16 @@ namespace Pinetime {
namespace Applications { namespace Applications {
namespace Display { namespace Display {
enum class Messages : uint8_t { enum class Messages : uint8_t {
GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent, ButtonPushed, GoToSleep,
NewNotification, BleFirmwareUpdateStarted, UpdateTimeOut GoToRunning,
UpdateDateTime,
UpdateBleConnection,
UpdateBatteryLevel,
TouchEvent,
ButtonPushed,
NewNotification,
BleFirmwareUpdateStarted,
UpdateTimeOut
}; };
} }
} }

View file

@ -0,0 +1,44 @@
# Fonts
* [Jetbrains Mono](https://www.jetbrains.com/fr-fr/lp/mono/)
* [Awesome font from LVGL](https://lvgl.io/assets/others/FontAwesome5-Solid+Brands+Regular.woff)
## Generate the fonts:
* Open the [LVGL font converter](https://lvgl.io/tools/fontconverter)
* Name : jetbrains_mono_bold_20
* Size : 20
* Bpp : 1 bit-per-pixel
* Do not enable font compression and horizontal subpixel hinting
* Load the file `JetBrainsMono-Bold.tff` and specify the following range : `0x20-0x7f, 0x410-0x44f`
* Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following
range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf029, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024`
* Click on Convert, and download the file `jetbrains_mono_bold_20.c` and copy it in `src/DisplayApp/Fonts`
Add new symbols:
* Browse the [cheatsheet](https://fontawesome.com/cheatsheet/free/solid) and find your new symbols
* For each symbol, add its hex code (0xf641 for the 'Ad' icon, for example) to the *Range* list (Remember to keep this
readme updated with newest range list)
* Convert this hex value into a UTF-8 code
using [this site](http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=f185&mode=hex)
* Define the new symbols in `src/DisplayApp/Screens/Symbols.h`:
```
static constex char* newSymbol = "\xEF\x86\x85";
```
#### Navigation font
To create the navigtion.ttf I use the web app [icomoon](https://icomoon.io/app)
this app can import the svg files from the folder *src/displayapp/icons/navigation/unique* and creat a ttf file the
project for the site is *lv_font_navi_80.json* you can import it to add or remove icons
You can also use the online LVGL tool to create the .c
ttf file : navigation.ttf name : lv_font_navi_80 size : 80px Bpp : 2 bit-per-pixel range : 0xe900-0xe929
$lv_font_conv --font navigation.ttf -r '0xe900-0xe929' --size 80 --format lvgl --bpp 2 --no-prefilter -o
lv_font_navi_80.c
#### I use the method above to create the other ttf

View file

@ -1,41 +0,0 @@
#Fonts
* [Jetbrains Mono](https://www.jetbrains.com/fr-fr/lp/mono/)
* [Awesome font from LVGL](https://lvgl.io/assets/others/FontAwesome5-Solid+Brands+Regular.woff)
## Generate the fonts:
* Open the [LVGL font converter](https://lvgl.io/tools/fontconverter)
* Name : jetbrains_mono_bold_20
* Size : 20
* Bpp : 1 bit-per-pixel
* Do not enable font compression and horizontal subpixel hinting
* Load the file `JetBrainsMono-Bold.tff` and specify the following range : `0x20-0x7f, 0x410-0x44f`
* Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf029, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024`
* Click on Convert, and download the file `jetbrains_mono_bold_20.c` and copy it in `src/DisplayApp/Fonts`
Add new symbols:
* Browse the [cheatsheet](https://fontawesome.com/cheatsheet/free/solid) and find your new symbols
* For each symbol, add its hex code (0xf641 for the 'Ad' icon, for example) to the *Range* list (Remember to keep this readme updated with newest range list)
* Convert this hex value into a UTF-8 code using [this site](http://www.ltg.ed.ac.uk/~richard/utf-8.cgi?input=f185&mode=hex)
* Define the new symbols in `src/DisplayApp/Screens/Symbols.h`:
```
static constex char* newSymbol = "\xEF\x86\x85";
```
#### Navigation font
To create the navigtion.ttf I use the web app [icomoon](https://icomoon.io/app)
this app can import the svg files from the folder *src/displayapp/icons/navigation/unique* and creat a ttf file
the project for the site is *lv_font_navi_80.json* you can import it to add or remove icons
You can also use the online LVGL tool to create the .c
ttf file : navigation.ttf
name : lv_font_navi_80
size : 80px
Bpp : 2 bit-per-pixel
range : 0xe900-0xe929
$lv_font_conv --font navigation.ttf -r '0xe900-0xe929' --size 80 --format lvgl --bpp 2 --no-prefilter -o lv_font_navi_80.c
#### I use the method above to create the other ttf

View file

@ -67,15 +67,14 @@ static bool inited;
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
static void style_init_reset(lv_style_t * style) static void style_init_reset(lv_style_t* style) {
{ if (inited)
if(inited) lv_style_reset(style); lv_style_reset(style);
else lv_style_init(style); else
lv_style_init(style);
} }
static void basic_init(void) {
static void basic_init(void)
{
style_init_reset(&style_pad); style_init_reset(&style_pad);
lv_style_set_pad_top(&style_pad, LV_STATE_DEFAULT, LV_VER_RES / 30); lv_style_set_pad_top(&style_pad, LV_STATE_DEFAULT, LV_VER_RES / 30);
@ -103,7 +102,6 @@ static void basic_init(void)
lv_style_set_border_color(&style_box_border, LV_STATE_DEFAULT, LV_PINETIME_GRAY); lv_style_set_border_color(&style_box_border, LV_STATE_DEFAULT, LV_PINETIME_GRAY);
lv_style_set_text_color(&style_box, LV_STATE_DEFAULT, LV_PINETIME_BLUE); lv_style_set_text_color(&style_box, LV_STATE_DEFAULT, LV_PINETIME_BLUE);
style_init_reset(&style_title); style_init_reset(&style_title);
lv_style_set_text_color(&style_title, LV_STATE_DEFAULT, LV_PINETIME_WHITE); lv_style_set_text_color(&style_title, LV_STATE_DEFAULT, LV_PINETIME_WHITE);
lv_style_set_text_font(&style_title, LV_STATE_DEFAULT, theme.font_subtitle); lv_style_set_text_font(&style_title, LV_STATE_DEFAULT, theme.font_subtitle);
@ -301,10 +299,8 @@ static void basic_init(void)
lv_style_set_pad_right(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8)); lv_style_set_pad_right(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8));
lv_style_set_pad_top(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8)); lv_style_set_pad_top(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8));
lv_style_set_pad_bottom(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8)); lv_style_set_pad_bottom(&style_cb_bullet, LV_STATE_DEFAULT, LV_DPX(8));
} }
/********************** /**********************
* GLOBAL FUNCTIONS * GLOBAL FUNCTIONS
**********************/ **********************/
@ -320,10 +316,13 @@ static void basic_init(void)
* @param font_title pointer to a extra large font * @param font_title pointer to a extra large font
* @return a pointer to reference this theme later * @return a pointer to reference this theme later
*/ */
lv_theme_t * lv_pinetime_theme_init(lv_color_t color_primary, lv_color_t color_secondary, uint32_t flags, lv_theme_t* lv_pinetime_theme_init(lv_color_t color_primary,
const lv_font_t * font_small, const lv_font_t * font_normal, const lv_font_t * font_subtitle, lv_color_t color_secondary,
const lv_font_t * font_title) uint32_t flags,
{ const lv_font_t* font_small,
const lv_font_t* font_normal,
const lv_font_t* font_subtitle,
const lv_font_t* font_title) {
theme.color_primary = color_primary; theme.color_primary = color_primary;
theme.color_secondary = color_secondary; theme.color_secondary = color_secondary;
theme.font_small = font_small; theme.font_small = font_small;
@ -341,9 +340,7 @@ lv_theme_t * lv_pinetime_theme_init(lv_color_t color_primary, lv_color_t color_s
return &theme; return &theme;
} }
static void theme_apply(lv_obj_t* obj, lv_theme_style_t name) {
static void theme_apply(lv_obj_t * obj, lv_theme_style_t name)
{
lv_style_list_t* list; lv_style_list_t* list;
/*To avoid warnings*/ /*To avoid warnings*/
@ -442,7 +439,6 @@ static void theme_apply(lv_obj_t * obj, lv_theme_style_t name)
_lv_style_list_add_style(list, &style_list_btn); _lv_style_list_add_style(list, &style_list_btn);
break; break;
case LV_THEME_ARC: case LV_THEME_ARC:
lv_obj_clean_style_list(obj, LV_ARC_PART_BG); lv_obj_clean_style_list(obj, LV_ARC_PART_BG);
list = lv_obj_get_style_list(obj, LV_ARC_PART_BG); list = lv_obj_get_style_list(obj, LV_ARC_PART_BG);
@ -453,7 +449,6 @@ static void theme_apply(lv_obj_t * obj, lv_theme_style_t name)
_lv_style_list_add_style(list, &style_arc_indic); _lv_style_list_add_style(list, &style_arc_indic);
break; break;
case LV_THEME_SWITCH: case LV_THEME_SWITCH:
lv_obj_clean_style_list(obj, LV_SWITCH_PART_BG); lv_obj_clean_style_list(obj, LV_SWITCH_PART_BG);
list = lv_obj_get_style_list(obj, LV_SWITCH_PART_BG); list = lv_obj_get_style_list(obj, LV_SWITCH_PART_BG);
@ -526,15 +521,11 @@ static void theme_apply(lv_obj_t * obj, lv_theme_style_t name)
_lv_style_list_add_style(list, &style_cb_bullet); _lv_style_list_add_style(list, &style_cb_bullet);
break; break;
default: default:
break; break;
} }
lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL); lv_obj_refresh_style(obj, LV_OBJ_PART_ALL, LV_STYLE_PROP_ALL);
} }
/********************** /**********************

View file

@ -31,12 +31,10 @@ extern "C" {
* TYPEDEFS * TYPEDEFS
**********************/ **********************/
/********************** /**********************
* GLOBAL PROTOTYPES * GLOBAL PROTOTYPES
**********************/ **********************/
/** /**
* Initialize the default * Initialize the default
* @param color_primary the primary color of the theme * @param color_primary the primary color of the theme
@ -48,8 +46,12 @@ extern "C" {
* @param font_title pointer to a extra large font * @param font_title pointer to a extra large font
* @return a pointer to reference this theme later * @return a pointer to reference this theme later
*/ */
lv_theme_t * lv_pinetime_theme_init(lv_color_t color_primary, lv_color_t color_secondary, uint32_t flags, lv_theme_t* lv_pinetime_theme_init(lv_color_t color_primary,
const lv_font_t * font_small, const lv_font_t * font_normal, const lv_font_t * font_subtitle, lv_color_t color_secondary,
uint32_t flags,
const lv_font_t* font_small,
const lv_font_t* font_normal,
const lv_font_t* font_subtitle,
const lv_font_t* font_title); const lv_font_t* font_title);
/********************** /**********************
* MACROS * MACROS

View file

@ -11,21 +11,24 @@ using namespace Pinetime::Applications::Screens;
ApplicationList::ApplicationList(Pinetime::Applications::DisplayApp* app, ApplicationList::ApplicationList(Pinetime::Applications::DisplayApp* app,
Pinetime::Controllers::Settings& settingsController, Pinetime::Controllers::Settings& settingsController,
Pinetime::Controllers::Battery& batteryController, Pinetime::Controllers::Battery& batteryController,
Controllers::DateTime& dateTimeController) : Controllers::DateTime& dateTimeController)
Screen(app), : Screen(app),
settingsController {settingsController}, settingsController {settingsController},
batteryController {batteryController}, batteryController {batteryController},
dateTimeController {dateTimeController}, dateTimeController {dateTimeController},
screens {app, screens {app,
settingsController.GetAppMenu(), settingsController.GetAppMenu(),
{ {
[this]() -> std::unique_ptr<Screen> { return CreateScreen1(); }, [this]() -> std::unique_ptr<Screen> {
[this]() -> std::unique_ptr<Screen> { return CreateScreen2(); }, return CreateScreen1();
},
[this]() -> std::unique_ptr<Screen> {
return CreateScreen2();
},
//[this]() -> std::unique_ptr<Screen> { return CreateScreen3(); } //[this]() -> std::unique_ptr<Screen> { return CreateScreen3(); }
}, },
Screens::ScreenListModes::UpDown Screens::ScreenListModes::UpDown} {
} {} }
ApplicationList::~ApplicationList() { ApplicationList::~ApplicationList() {
lv_obj_clean(lv_scr_act()); lv_obj_clean(lv_scr_act());
@ -42,31 +45,27 @@ bool ApplicationList::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
} }
std::unique_ptr<Screen> ApplicationList::CreateScreen1() { std::unique_ptr<Screen> ApplicationList::CreateScreen1() {
std::array<Screens::Tile::Applications, 6> applications { std::array<Screens::Tile::Applications, 6> applications {{
{
{Symbols::stopWatch, Apps::StopWatch}, {Symbols::stopWatch, Apps::StopWatch},
{Symbols::music, Apps::Music}, {Symbols::music, Apps::Music},
{Symbols::map, Apps::Navigation}, {Symbols::map, Apps::Navigation},
{Symbols::shoe, Apps::Motion}, {Symbols::shoe, Apps::Motion},
{Symbols::heartBeat, Apps::HeartRate}, {Symbols::heartBeat, Apps::HeartRate},
{"", Apps::None}, {"", Apps::None},
} }};
};
return std::make_unique<Screens::Tile>(0, 2, app, settingsController, batteryController, dateTimeController, applications); return std::make_unique<Screens::Tile>(0, 2, app, settingsController, batteryController, dateTimeController, applications);
} }
std::unique_ptr<Screen> ApplicationList::CreateScreen2() { std::unique_ptr<Screen> ApplicationList::CreateScreen2() {
std::array<Screens::Tile::Applications, 6> applications { std::array<Screens::Tile::Applications, 6> applications {{
{
{Symbols::paintbrush, Apps::Paint}, {Symbols::paintbrush, Apps::Paint},
{Symbols::paddle, Apps::Paddle}, {Symbols::paddle, Apps::Paddle},
{"2", Apps::Twos}, {"2", Apps::Twos},
{"", Apps::None}, {"", Apps::None},
{"", Apps::None}, {"", Apps::None},
{"", Apps::None}, {"", Apps::None},
} }};
};
return std::make_unique<Screens::Tile>(1, 2, app, settingsController, batteryController, dateTimeController, applications); return std::make_unique<Screens::Tile>(1, 2, app, settingsController, batteryController, dateTimeController, applications);
} }
@ -84,4 +83,3 @@ std::unique_ptr<Screen> ApplicationList::CreateScreen2() {
return std::make_unique<Screens::Tile>(2, 3, app, settingsController, batteryController, dateTimeController, applications); return std::make_unique<Screens::Tile>(2, 3, app, settingsController, batteryController, dateTimeController, applications);
}*/ }*/

View file

@ -20,8 +20,8 @@ namespace Pinetime {
~ApplicationList() override; ~ApplicationList() override;
bool Refresh() override; bool Refresh() override;
bool OnTouchEvent(TouchEvents event) override; bool OnTouchEvent(TouchEvents event) override;
private:
private:
Controllers::Settings& settingsController; Controllers::Settings& settingsController;
Pinetime::Controllers::Battery& batteryController; Pinetime::Controllers::Battery& batteryController;
Controllers::DateTime& dateTimeController; Controllers::DateTime& dateTimeController;

View file

@ -4,10 +4,14 @@
using namespace Pinetime::Applications::Screens; using namespace Pinetime::Applications::Screens;
const char* BatteryIcon::GetBatteryIcon(int batteryPercent) { const char* BatteryIcon::GetBatteryIcon(int batteryPercent) {
if(batteryPercent > 90) return Symbols::batteryFull; if (batteryPercent > 90)
if(batteryPercent > 75) return Symbols::batteryThreeQuarter; return Symbols::batteryFull;
if(batteryPercent > 50) return Symbols::batteryHalf; if (batteryPercent > 75)
if(batteryPercent > 25) return Symbols::batteryOneQuarter; return Symbols::batteryThreeQuarter;
if (batteryPercent > 50)
return Symbols::batteryHalf;
if (batteryPercent > 25)
return Symbols::batteryOneQuarter;
return Symbols::batteryEmpty; return Symbols::batteryEmpty;
} }
@ -18,5 +22,6 @@ const char* BatteryIcon::GetUnknownIcon() {
const char* BatteryIcon::GetPlugIcon(bool isCharging) { const char* BatteryIcon::GetPlugIcon(bool isCharging) {
if (isCharging) if (isCharging)
return Symbols::plug; return Symbols::plug;
else return ""; else
return "";
} }

View file

@ -14,12 +14,8 @@ static void lv_anim_task(struct _lv_task_t *task) {
user_data->UpdateAnim(); user_data->UpdateAnim();
} }
BatteryInfo::BatteryInfo( BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Battery& batteryController)
Pinetime::Applications::DisplayApp *app, : Screen(app), batteryController {batteryController} {
Pinetime::Controllers::Battery& batteryController) :
Screen(app),
batteryController{batteryController}
{
batteryPercent = batteryController.PercentRemaining(); batteryPercent = batteryController.PercentRemaining();
batteryVoltage = batteryController.Voltage(); batteryVoltage = batteryController.Voltage();
@ -53,7 +49,8 @@ BatteryInfo::BatteryInfo(
// hack to not use the flot functions from printf // hack to not use the flot functions from printf
uint8_t batteryVoltageBytes[2]; uint8_t batteryVoltageBytes[2];
batteryVoltageBytes[1] = static_cast<uint8_t>(batteryVoltage); // truncate whole numbers batteryVoltageBytes[1] = static_cast<uint8_t>(batteryVoltage); // truncate whole numbers
batteryVoltageBytes[0] = static_cast<uint8_t>((batteryVoltage - batteryVoltageBytes[1]) * 100); //remove whole part of flt and shift 2 places over batteryVoltageBytes[0] =
static_cast<uint8_t>((batteryVoltage - batteryVoltageBytes[1]) * 100); // remove whole part of flt and shift 2 places over
// //
voltage = lv_label_create(lv_scr_act(), nullptr); voltage = lv_label_create(lv_scr_act(), nullptr);
@ -73,7 +70,6 @@ BatteryInfo::BatteryInfo(
UpdateScreen(); UpdateScreen();
} }
BatteryInfo::~BatteryInfo() { BatteryInfo::~BatteryInfo() {
lv_task_del(taskUpdate); lv_task_del(taskUpdate);
lv_task_del(taskAnim); lv_task_del(taskAnim);
@ -136,14 +132,13 @@ void BatteryInfo::UpdateScreen() {
// hack to not use the flot functions from printf // hack to not use the flot functions from printf
uint8_t batteryVoltageBytes[2]; uint8_t batteryVoltageBytes[2];
batteryVoltageBytes[1] = static_cast<uint8_t>(batteryVoltage); // truncate whole numbers batteryVoltageBytes[1] = static_cast<uint8_t>(batteryVoltage); // truncate whole numbers
batteryVoltageBytes[0] = static_cast<uint8_t>((batteryVoltage - batteryVoltageBytes[1]) * 100); //remove whole part of flt and shift 2 places over batteryVoltageBytes[0] =
static_cast<uint8_t>((batteryVoltage - batteryVoltageBytes[1]) * 100); // remove whole part of flt and shift 2 places over
// //
lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltageBytes[1], batteryVoltageBytes[0]); lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltageBytes[1], batteryVoltageBytes[0]);
} }
bool BatteryInfo::Refresh() { bool BatteryInfo::Refresh() {
return running; return running;
} }

View file

@ -6,7 +6,6 @@
#include "Screen.h" #include "Screen.h"
#include <lvgl/lvgl.h> #include <lvgl/lvgl.h>
namespace Pinetime { namespace Pinetime {
namespace Controllers { namespace Controllers {
class Battery; class Battery;
@ -17,18 +16,15 @@ namespace Pinetime {
class BatteryInfo : public Screen { class BatteryInfo : public Screen {
public: public:
BatteryInfo(DisplayApp* app, BatteryInfo(DisplayApp* app, Pinetime::Controllers::Battery& batteryController);
Pinetime::Controllers::Battery& batteryController);
~BatteryInfo() override; ~BatteryInfo() override;
bool Refresh() override; bool Refresh() override;
void UpdateScreen(); void UpdateScreen();
void UpdateAnim(); void UpdateAnim();
private: private:
Pinetime::Controllers::Battery& batteryController; Pinetime::Controllers::Battery& batteryController;
lv_obj_t* voltage; lv_obj_t* voltage;
@ -42,7 +38,6 @@ namespace Pinetime {
int8_t animation = 0; int8_t animation = 0;
int8_t batteryPercent = -1; int8_t batteryPercent = -1;
float batteryVoltage = 0.0f; float batteryVoltage = 0.0f;
}; };
} }
} }

View file

@ -3,6 +3,8 @@
using namespace Pinetime::Applications::Screens; using namespace Pinetime::Applications::Screens;
const char* BleIcon::GetIcon(bool isConnected) { const char* BleIcon::GetIcon(bool isConnected) {
if(isConnected) return Symbols::bluetooth; if (isConnected)
else return ""; return Symbols::bluetooth;
else
return "";
} }

View file

@ -10,7 +10,8 @@ void slider_event_cb(lv_obj_t * slider, lv_event_t event) {
} }
} }
Brightness::Brightness(Pinetime::Applications::DisplayApp *app, Controllers::BrightnessController& brightness) : Screen(app), brightness{brightness} { Brightness::Brightness(Pinetime::Applications::DisplayApp* app, Controllers::BrightnessController& brightness)
: Screen(app), brightness {brightness} {
slider = lv_slider_create(lv_scr_act(), nullptr); slider = lv_slider_create(lv_scr_act(), nullptr);
lv_obj_set_user_data(slider, this); lv_obj_set_user_data(slider, this);
lv_obj_set_width(slider, LV_DPI * 2); lv_obj_set_width(slider, LV_DPI * 2);
@ -35,11 +36,16 @@ bool Brightness::Refresh() {
const char* Brightness::LevelToString(Pinetime::Controllers::BrightnessController::Levels level) { const char* Brightness::LevelToString(Pinetime::Controllers::BrightnessController::Levels level) {
switch (level) { switch (level) {
case Pinetime::Controllers::BrightnessController::Levels::Off: return "Off"; case Pinetime::Controllers::BrightnessController::Levels::Off:
case Pinetime::Controllers::BrightnessController::Levels::Low: return "Low"; return "Off";
case Pinetime::Controllers::BrightnessController::Levels::Medium: return "Medium"; case Pinetime::Controllers::BrightnessController::Levels::Low:
case Pinetime::Controllers::BrightnessController::Levels::High: return "High"; return "Low";
default : return "???"; case Pinetime::Controllers::BrightnessController::Levels::Medium:
return "Medium";
case Pinetime::Controllers::BrightnessController::Levels::High:
return "High";
default:
return "???";
} }
} }
@ -49,20 +55,31 @@ void Brightness::OnValueChanged() {
void Brightness::SetValue(uint8_t value) { void Brightness::SetValue(uint8_t value) {
switch (value) { switch (value) {
case 0: brightness.Set(Controllers::BrightnessController::Levels::Low); break; case 0:
case 1: brightness.Set(Controllers::BrightnessController::Levels::Medium); break; brightness.Set(Controllers::BrightnessController::Levels::Low);
case 2: brightness.Set(Controllers::BrightnessController::Levels::High); break; break;
case 1:
brightness.Set(Controllers::BrightnessController::Levels::Medium);
break;
case 2:
brightness.Set(Controllers::BrightnessController::Levels::High);
break;
} }
lv_label_set_text(slider_label, LevelToString(brightness.Level())); lv_label_set_text(slider_label, LevelToString(brightness.Level()));
} }
uint8_t Brightness::LevelToInt(Pinetime::Controllers::BrightnessController::Levels level) { uint8_t Brightness::LevelToInt(Pinetime::Controllers::BrightnessController::Levels level) {
switch (level) { switch (level) {
case Pinetime::Controllers::BrightnessController::Levels::Off: return 0; case Pinetime::Controllers::BrightnessController::Levels::Off:
case Pinetime::Controllers::BrightnessController::Levels::Low: return 0; return 0;
case Pinetime::Controllers::BrightnessController::Levels::Medium: return 1; case Pinetime::Controllers::BrightnessController::Levels::Low:
case Pinetime::Controllers::BrightnessController::Levels::High: return 2; return 0;
default : return 0; case Pinetime::Controllers::BrightnessController::Levels::Medium:
return 1;
case Pinetime::Controllers::BrightnessController::Levels::High:
return 2;
default:
return 0;
} }
} }

View file

@ -17,8 +17,8 @@ namespace Pinetime {
bool OnTouchEvent(TouchEvents event) override; bool OnTouchEvent(TouchEvents event) override;
void OnValueChanged(); void OnValueChanged();
private:
private:
Controllers::BrightnessController& brightness; Controllers::BrightnessController& brightness;
lv_obj_t* slider_label; lv_obj_t* slider_label;

View file

@ -15,7 +15,6 @@
#include "WatchFaceDigital.h" #include "WatchFaceDigital.h"
#include "WatchFaceAnalog.h" #include "WatchFaceAnalog.h"
using namespace Pinetime::Applications::Screens; using namespace Pinetime::Applications::Screens;
Clock::Clock(DisplayApp* app, Clock::Clock(DisplayApp* app,
@ -25,33 +24,37 @@ Clock::Clock(DisplayApp* app,
Controllers::NotificationManager& notificatioManager, Controllers::NotificationManager& notificatioManager,
Controllers::Settings& settingsController, Controllers::Settings& settingsController,
Controllers::HeartRateController& heartRateController, Controllers::HeartRateController& heartRateController,
Controllers::MotionController& motionController) : Screen(app), Controllers::MotionController& motionController)
dateTimeController{dateTimeController}, batteryController{batteryController}, : Screen(app),
bleController{bleController}, notificatioManager{notificatioManager}, dateTimeController {dateTimeController},
batteryController {batteryController},
bleController {bleController},
notificatioManager {notificatioManager},
settingsController {settingsController}, settingsController {settingsController},
heartRateController {heartRateController}, heartRateController {heartRateController},
motionController {motionController}, motionController {motionController},
screens {app, screens {app,
settingsController.GetClockFace(), settingsController.GetClockFace(),
{ {
[this]() -> std::unique_ptr<Screen> { return WatchFaceDigitalScreen(); }, [this]() -> std::unique_ptr<Screen> {
[this]() -> std::unique_ptr<Screen> { return WatchFaceAnalogScreen(); }, return WatchFaceDigitalScreen();
},
[this]() -> std::unique_ptr<Screen> {
return WatchFaceAnalogScreen();
},
// Examples for more watch faces // Examples for more watch faces
//[this]() -> std::unique_ptr<Screen> { return WatchFaceMinimalScreen(); }, //[this]() -> std::unique_ptr<Screen> { return WatchFaceMinimalScreen(); },
//[this]() -> std::unique_ptr<Screen> { return WatchFaceCustomScreen(); } //[this]() -> std::unique_ptr<Screen> { return WatchFaceCustomScreen(); }
}, },
Screens::ScreenListModes::LongPress Screens::ScreenListModes::LongPress} {
} {
settingsController.SetAppMenu(0); settingsController.SetAppMenu(0);
} }
Clock::~Clock() { Clock::~Clock() {
lv_obj_clean(lv_scr_act()); lv_obj_clean(lv_scr_act());
} }
bool Clock::Refresh() { bool Clock::Refresh() {
screens.Refresh(); screens.Refresh();
return running; return running;
@ -62,20 +65,30 @@ bool Clock::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
} }
std::unique_ptr<Screen> Clock::WatchFaceDigitalScreen() { std::unique_ptr<Screen> Clock::WatchFaceDigitalScreen() {
return std::make_unique<Screens::WatchFaceDigital>(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController, heartRateController, motionController); return std::make_unique<Screens::WatchFaceDigital>(app,
dateTimeController,
batteryController,
bleController,
notificatioManager,
settingsController,
heartRateController,
motionController);
} }
std::unique_ptr<Screen> Clock::WatchFaceAnalogScreen() { std::unique_ptr<Screen> Clock::WatchFaceAnalogScreen() {
return std::make_unique<Screens::WatchFaceAnalog>(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController); return std::make_unique<Screens::WatchFaceAnalog>(
app, dateTimeController, batteryController, bleController, notificatioManager, settingsController);
} }
/* /*
// Examples for more watch faces // Examples for more watch faces
std::unique_ptr<Screen> Clock::WatchFaceMinimalScreen() { std::unique_ptr<Screen> Clock::WatchFaceMinimalScreen() {
return std::make_unique<Screens::WatchFaceMinimal>(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController); return std::make_unique<Screens::WatchFaceMinimal>(app, dateTimeController, batteryController, bleController, notificatioManager,
settingsController);
} }
std::unique_ptr<Screen> Clock::WatchFaceCustomScreen() { std::unique_ptr<Screen> Clock::WatchFaceCustomScreen() {
return std::make_unique<Screens::WatchFaceCustom>(app, dateTimeController, batteryController, bleController, notificatioManager, settingsController); return std::make_unique<Screens::WatchFaceCustom>(app, dateTimeController, batteryController, bleController, notificatioManager,
settingsController);
} }
*/ */

View file

@ -39,7 +39,6 @@ namespace Pinetime {
bool OnTouchEvent(TouchEvents event) override; bool OnTouchEvent(TouchEvents event) override;
private: private:
Controllers::DateTime& dateTimeController; Controllers::DateTime& dateTimeController;
Controllers::Battery& batteryController; Controllers::Battery& batteryController;
Controllers::Ble& bleController; Controllers::Ble& bleController;
@ -48,7 +47,6 @@ namespace Pinetime {
Controllers::HeartRateController& heartRateController; Controllers::HeartRateController& heartRateController;
Controllers::MotionController& motionController; Controllers::MotionController& motionController;
ScreenList<2> screens; ScreenList<2> screens;
std::unique_ptr<Screen> WatchFaceDigitalScreen(); std::unique_ptr<Screen> WatchFaceDigitalScreen();
std::unique_ptr<Screen> WatchFaceAnalogScreen(); std::unique_ptr<Screen> WatchFaceAnalogScreen();
@ -56,9 +54,6 @@ namespace Pinetime {
// Examples for more watch faces // Examples for more watch faces
// std::unique_ptr<Screen> WatchFaceMinimalScreen(); // std::unique_ptr<Screen> WatchFaceMinimalScreen();
// std::unique_ptr<Screen> WatchFaceCustomScreen(); // std::unique_ptr<Screen> WatchFaceCustomScreen();
}; };
} }
} }

View file

@ -8,7 +8,8 @@ using namespace Pinetime::Applications::Screens;
DropDownDemo::DropDownDemo(Pinetime::Applications::DisplayApp* app) : Screen(app) { DropDownDemo::DropDownDemo(Pinetime::Applications::DisplayApp* app) : Screen(app) {
// Create the dropdown object, with many item, and fix its height // Create the dropdown object, with many item, and fix its height
ddlist = lv_ddlist_create(lv_scr_act(), nullptr); ddlist = lv_ddlist_create(lv_scr_act(), nullptr);
lv_ddlist_set_options(ddlist, "Apple\n" lv_ddlist_set_options(ddlist,
"Apple\n"
"Banana\n" "Banana\n"
"Orange\n" "Orange\n"
"Melon\n" "Melon\n"
@ -54,4 +55,3 @@ bool DropDownDemo::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
return false; return false;
} }
} }

View file

@ -5,9 +5,8 @@
using namespace Pinetime::Applications::Screens; using namespace Pinetime::Applications::Screens;
FirmwareUpdate::FirmwareUpdate(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Ble& bleController)
FirmwareUpdate::FirmwareUpdate(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::Ble& bleController) : : Screen(app), bleController {bleController} {
Screen(app), bleController{bleController} {
lv_obj_t * backgroundLabel = lv_label_create(lv_scr_act(), nullptr); lv_obj_t * backgroundLabel = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP);

View file

@ -17,7 +17,6 @@ namespace Pinetime {
bool Refresh() override; bool Refresh() override;
private: private:
enum class States { Idle, Running, Validated, Error }; enum class States { Idle, Running, Validated, Error };
Pinetime::Controllers::Ble& bleController; Pinetime::Controllers::Ble& bleController;

View file

@ -7,23 +7,20 @@
using namespace Pinetime::Applications::Screens; using namespace Pinetime::Applications::Screens;
namespace { namespace {
static void ButtonEventHandler(lv_obj_t * obj, lv_event_t event) static void ButtonEventHandler(lv_obj_t* obj, lv_event_t event) {
{
FirmwareValidation* screen = static_cast<FirmwareValidation*>(obj->user_data); FirmwareValidation* screen = static_cast<FirmwareValidation*>(obj->user_data);
screen->OnButtonEvent(obj, event); screen->OnButtonEvent(obj, event);
} }
} }
FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp *app, FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::FirmwareValidator& validator)
Pinetime::Controllers::FirmwareValidator &validator)
: Screen {app}, validator {validator} { : Screen {app}, validator {validator} {
labelVersionInfo = lv_label_create(lv_scr_act(), nullptr); labelVersionInfo = lv_label_create(lv_scr_act(), nullptr);
lv_obj_align(labelVersionInfo, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); lv_obj_align(labelVersionInfo, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0);
lv_label_set_text(labelVersionInfo, "Version : "); lv_label_set_text(labelVersionInfo, "Version : ");
lv_label_set_align(labelVersionInfo, LV_LABEL_ALIGN_LEFT); lv_label_set_align(labelVersionInfo, LV_LABEL_ALIGN_LEFT);
labelVersionValue = lv_label_create(lv_scr_act(), nullptr); labelVersionValue = lv_label_create(lv_scr_act(), nullptr);
lv_obj_align(labelVersionValue, labelVersionInfo, LV_ALIGN_OUT_RIGHT_MID, 0, 0); lv_obj_align(labelVersionValue, labelVersionInfo, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
lv_label_set_recolor(labelVersionValue, true); lv_label_set_recolor(labelVersionValue, true);
@ -39,8 +36,7 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp *app,
if (validator.IsValidated()) if (validator.IsValidated())
lv_label_set_text(labelIsValidated, "You have already\n#00ff00 validated# this firmware#"); lv_label_set_text(labelIsValidated, "You have already\n#00ff00 validated# this firmware#");
else { else {
lv_label_set_text(labelIsValidated, lv_label_set_text(labelIsValidated, "Please #00ff00 Validate# this version or\n#ff0000 Reset# to rollback to the previous version.");
"Please #00ff00 Validate# this version or\n#ff0000 Reset# to rollback to the previous version.");
buttonValidate = lv_btn_create(lv_scr_act(), nullptr); buttonValidate = lv_btn_create(lv_scr_act(), nullptr);
lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
@ -62,7 +58,6 @@ FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp *app,
} }
} }
FirmwareValidation::~FirmwareValidation() { FirmwareValidation::~FirmwareValidation() {
lv_obj_clean(lv_scr_act()); lv_obj_clean(lv_scr_act());
} }
@ -78,5 +73,4 @@ void FirmwareValidation::OnButtonEvent(lv_obj_t *object, lv_event_t event) {
} else if (object == buttonReset && event == LV_EVENT_PRESSED) { } else if (object == buttonReset && event == LV_EVENT_PRESSED) {
validator.Reset(); validator.Reset();
} }
} }

View file

@ -18,7 +18,6 @@ namespace Pinetime {
bool Refresh() override; bool Refresh() override;
void OnButtonEvent(lv_obj_t* object, lv_event_t event); void OnButtonEvent(lv_obj_t* object, lv_event_t event);
private: private:
@ -32,7 +31,6 @@ namespace Pinetime {
lv_obj_t* labelButtonValidate; lv_obj_t* labelButtonValidate;
lv_obj_t* buttonReset; lv_obj_t* buttonReset;
lv_obj_t* labelButtonReset; lv_obj_t* labelButtonReset;
}; };
} }
} }

View file

@ -11,11 +11,10 @@ namespace {
} }
} }
FlashLight::FlashLight( FlashLight::FlashLight(Pinetime::Applications::DisplayApp* app,
Pinetime::Applications::DisplayApp *app,
System::SystemTask& systemTask, System::SystemTask& systemTask,
Controllers::BrightnessController& brightness) : Controllers::BrightnessController& brightness)
Screen(app), : Screen(app),
systemTask {systemTask}, systemTask {systemTask},
brightness {brightness} brightness {brightness}
@ -41,10 +40,8 @@ FlashLight::FlashLight(
lv_obj_set_event_cb(backgroundAction, event_handler); lv_obj_set_event_cb(backgroundAction, event_handler);
systemTask.PushMessage(Pinetime::System::SystemTask::Messages::DisableSleeping); systemTask.PushMessage(Pinetime::System::SystemTask::Messages::DisableSleeping);
} }
FlashLight::~FlashLight() { FlashLight::~FlashLight() {
lv_obj_clean(lv_scr_act()); lv_obj_clean(lv_scr_act());
lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000));
@ -64,7 +61,6 @@ void FlashLight::OnClickEvent(lv_obj_t *obj, lv_event_t event) {
lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000)); lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x000000));
lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFFFFFF)); lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xFFFFFF));
} }
} }
} }
} }
@ -76,4 +72,3 @@ bool FlashLight::Refresh() {
bool FlashLight::OnTouchEvent(Pinetime::Applications::TouchEvents event) { bool FlashLight::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
return true; return true;
} }

View file

@ -6,7 +6,6 @@
#include "systemtask/SystemTask.h" #include "systemtask/SystemTask.h"
#include "components/brightness/BrightnessController.h" #include "components/brightness/BrightnessController.h"
namespace Pinetime { namespace Pinetime {
namespace Applications { namespace Applications {
@ -29,7 +28,6 @@ namespace Pinetime {
lv_obj_t* flashLight; lv_obj_t* flashLight;
lv_obj_t* backgroundAction; lv_obj_t* backgroundAction;
bool isOn = true; bool isOn = true;
}; };
} }
} }

View file

@ -27,8 +27,10 @@ namespace {
} }
} }
HeartRate::HeartRate(Pinetime::Applications::DisplayApp *app, Controllers::HeartRateController& heartRateController, System::SystemTask &systemTask) : HeartRate::HeartRate(Pinetime::Applications::DisplayApp* app,
Screen(app), heartRateController{heartRateController}, systemTask{systemTask} { Controllers::HeartRateController& heartRateController,
System::SystemTask& systemTask)
: Screen(app), heartRateController {heartRateController}, systemTask {systemTask} {
bool isHrRunning = heartRateController.State() != Controllers::HeartRateController::States::Stopped; bool isHrRunning = heartRateController.State() != Controllers::HeartRateController::States::Stopped;
label_hr = lv_label_create(lv_scr_act(), nullptr); label_hr = lv_label_create(lv_scr_act(), nullptr);
@ -95,8 +97,7 @@ void HeartRate::OnStartStopEvent(lv_event_t event) {
UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped); UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped);
systemTask.PushMessage(Pinetime::System::SystemTask::Messages::DisableSleeping); systemTask.PushMessage(Pinetime::System::SystemTask::Messages::DisableSleeping);
lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN); lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
} } else {
else {
heartRateController.Stop(); heartRateController.Stop();
UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped); UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped);
systemTask.PushMessage(Pinetime::System::SystemTask::Messages::EnableSleeping); systemTask.PushMessage(Pinetime::System::SystemTask::Messages::EnableSleeping);

View file

@ -33,9 +33,6 @@ namespace Pinetime {
lv_obj_t* label_status; lv_obj_t* label_status;
lv_obj_t* btn_startStop; lv_obj_t* btn_startStop;
lv_obj_t* label_startStop; lv_obj_t* label_startStop;
}; };
} }
} }

View file

@ -72,4 +72,3 @@ bool InfiniPaint::OnTouchEvent(uint16_t x, uint16_t y) {
lvgl.FlushDisplay(&area, b); lvgl.FlushDisplay(&area, b);
return true; return true;
} }

View file

@ -31,7 +31,6 @@ namespace Pinetime {
lv_color_t b[bufferSize]; lv_color_t b[bufferSize];
lv_color_t selectColor = LV_COLOR_WHITE; lv_color_t selectColor = LV_COLOR_WHITE;
uint8_t color = 2; uint8_t color = 2;
}; };
} }
} }

View file

@ -2,10 +2,8 @@
using namespace Pinetime::Applications::Screens; using namespace Pinetime::Applications::Screens;
Label::Label(uint8_t screenID, uint8_t numScreens, Label::Label(uint8_t screenID, uint8_t numScreens, Pinetime::Applications::DisplayApp* app, lv_obj_t* labelText)
Pinetime::Applications::DisplayApp *app, lv_obj_t* labelText) : : Screen(app), labelText {labelText} {
Screen(app),
labelText{labelText} {
if (numScreens > 1) { if (numScreens > 1) {
pageIndicatorBasePoints[0].x = 240 - 1; pageIndicatorBasePoints[0].x = 240 - 1;
@ -19,7 +17,6 @@ Label::Label(uint8_t screenID, uint8_t numScreens,
lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true);
lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2);
uint16_t indicatorSize = 228 / numScreens; uint16_t indicatorSize = 228 / numScreens;
uint16_t indicatorPos = indicatorSize * screenID; uint16_t indicatorPos = indicatorSize * screenID;
@ -34,7 +31,6 @@ Label::Label(uint8_t screenID, uint8_t numScreens,
lv_obj_set_style_local_line_rounded(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); lv_obj_set_style_local_line_rounded(pageIndicator, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true);
lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); lv_line_set_points(pageIndicator, pageIndicatorPoints, 2);
} }
} }
Label::~Label() { Label::~Label() {

View file

@ -9,15 +9,12 @@ namespace Pinetime {
class Label : public Screen { class Label : public Screen {
public: public:
Label( uint8_t screenID, uint8_t numScreens, Label(uint8_t screenID, uint8_t numScreens, DisplayApp* app, lv_obj_t* labelText);
DisplayApp* app, lv_obj_t* labelText );
~Label() override; ~Label() override;
bool Refresh() override; bool Refresh() override;
private: private:
bool running = true; bool running = true;
lv_obj_t* labelText = nullptr; lv_obj_t* labelText = nullptr;

View file

@ -12,13 +12,12 @@ namespace {
} }
List::List(uint8_t screenID, uint8_t numScreens, List::List(uint8_t screenID,
uint8_t numScreens,
DisplayApp* app, DisplayApp* app,
Controllers::Settings& settingsController, Controllers::Settings& settingsController,
std::array<Applications, MAXLISTITEMS>& applications) : std::array<Applications, MAXLISTITEMS>& applications)
Screen(app), : Screen(app), settingsController {settingsController} {
settingsController{settingsController}
{
// Set the background to Black // Set the background to Black
lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_make(0, 0, 0)); lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_make(0, 0, 0));
@ -37,7 +36,6 @@ List::List(uint8_t screenID, uint8_t numScreens,
lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true); lv_obj_set_style_local_line_rounded(pageIndicatorBase, LV_LINE_PART_MAIN, LV_STATE_DEFAULT, true);
lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2); lv_line_set_points(pageIndicatorBase, pageIndicatorBasePoints, 2);
uint16_t indicatorSize = 228 / numScreens; uint16_t indicatorSize = 228 / numScreens;
uint16_t indicatorPos = indicatorSize * screenID; uint16_t indicatorPos = indicatorSize * screenID;
@ -53,7 +51,6 @@ List::List(uint8_t screenID, uint8_t numScreens,
lv_line_set_points(pageIndicator, pageIndicatorPoints, 2); lv_line_set_points(pageIndicator, pageIndicatorPoints, 2);
} }
lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr);
// lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111)); // lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x111111));
@ -91,7 +88,6 @@ List::List(uint8_t screenID, uint8_t numScreens,
labelBt = lv_label_create(itemApps[i], nullptr); labelBt = lv_label_create(itemApps[i], nullptr);
lv_label_set_text_fmt(labelBt, " %s", applications[i].name); lv_label_set_text_fmt(labelBt, " %s", applications[i].name);
} }
} }
@ -100,7 +96,6 @@ List::List(uint8_t screenID, uint8_t numScreens,
lv_obj_set_size(backgroundLabel, LV_HOR_RES, LV_VER_RES); lv_obj_set_size(backgroundLabel, LV_HOR_RES, LV_VER_RES);
lv_obj_set_pos(backgroundLabel, 0, 0); lv_obj_set_pos(backgroundLabel, 0, 0);
lv_label_set_text_static(backgroundLabel, ""); lv_label_set_text_static(backgroundLabel, "");
} }
List::~List() { List::~List() {
@ -123,4 +118,3 @@ void List::OnButtonEvent(lv_obj_t * object, lv_event_t event) {
} }
} }
} }

View file

@ -20,7 +20,8 @@ namespace Pinetime {
Pinetime::Applications::Apps application; Pinetime::Applications::Apps application;
}; };
explicit List(uint8_t screenID, uint8_t numScreens, explicit List(uint8_t screenID,
uint8_t numScreens,
DisplayApp* app, DisplayApp* app,
Controllers::Settings& settingsController, Controllers::Settings& settingsController,
std::array<Applications, MAXLISTITEMS>& applications); std::array<Applications, MAXLISTITEMS>& applications);
@ -28,11 +29,9 @@ namespace Pinetime {
bool Refresh() override; bool Refresh() override;
void OnButtonEvent(lv_obj_t* object, lv_event_t event); void OnButtonEvent(lv_obj_t* object, lv_event_t event);
private: private:
Controllers::Settings& settingsController; Controllers::Settings& settingsController;
Pinetime::Applications::Apps apps[MAXLISTITEMS]; Pinetime::Applications::Apps apps[MAXLISTITEMS];
@ -42,7 +41,6 @@ namespace Pinetime {
lv_point_t pageIndicatorPoints[2]; lv_point_t pageIndicatorPoints[2];
lv_obj_t* pageIndicatorBase; lv_obj_t* pageIndicatorBase;
lv_obj_t* pageIndicator; lv_obj_t* pageIndicator;
}; };
} }
} }

View file

@ -4,7 +4,6 @@
using namespace Pinetime::Applications::Screens; using namespace Pinetime::Applications::Screens;
Meter::Meter(Pinetime::Applications::DisplayApp* app) : Screen(app) { Meter::Meter(Pinetime::Applications::DisplayApp* app) : Screen(app) {
/*Create a line meter */ /*Create a line meter */
@ -21,18 +20,17 @@ Meter::Meter(Pinetime::Applications::DisplayApp *app) : Screen(app) {
lv_obj_set_size(lmeter, 200, 200); lv_obj_set_size(lmeter, 200, 200);
lv_obj_align(lmeter, nullptr, LV_ALIGN_CENTER, 0, 0); lv_obj_align(lmeter, nullptr, LV_ALIGN_CENTER, 0, 0);
} }
Meter::~Meter() { Meter::~Meter() {
lv_obj_clean(lv_scr_act()); lv_obj_clean(lv_scr_act());
} }
bool Meter::Refresh() { bool Meter::Refresh() {
lv_linemeter_set_value(lmeter, value++); /*Set the current value*/ lv_linemeter_set_value(lmeter, value++); /*Set the current value*/
if(value>=60) value = 0; if (value >= 60)
value = 0;
return running; return running;
} }

View file

@ -21,8 +21,6 @@ namespace Pinetime {
lv_obj_t* lmeter; lv_obj_t* lmeter;
uint32_t value = 0; uint32_t value = 0;
}; };
} }
} }

View file

@ -6,8 +6,8 @@ using namespace Pinetime::Applications::Screens;
extern lv_font_t jetbrains_mono_extrabold_compressed; extern lv_font_t jetbrains_mono_extrabold_compressed;
extern lv_font_t jetbrains_mono_bold_20; extern lv_font_t jetbrains_mono_bold_20;
Motion::Motion(Pinetime::Applications::DisplayApp* app, Controllers::MotionController& motionController)
Motion::Motion(Pinetime::Applications::DisplayApp *app, Controllers::MotionController& motionController) : Screen(app), motionController{motionController} { : Screen(app), motionController {motionController} {
chart = lv_chart_create(lv_scr_act(), NULL); chart = lv_chart_create(lv_scr_act(), NULL);
lv_obj_set_size(chart, 240, 240); lv_obj_set_size(chart, 240, 240);
lv_obj_align(chart, NULL, LV_ALIGN_IN_TOP_MID, 0, 0); lv_obj_align(chart, NULL, LV_ALIGN_IN_TOP_MID, 0, 0);

View file

@ -32,7 +32,6 @@ namespace Pinetime {
static constexpr uint8_t nbStepsBufferSize = 9; static constexpr uint8_t nbStepsBufferSize = 9;
char nbStepsBuffer[nbStepsBufferSize + 1]; char nbStepsBuffer[nbStepsBufferSize + 1];
bool running = true; bool running = true;
}; };
} }
} }

View file

@ -125,7 +125,6 @@ Music::Music(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::Mus
lv_obj_set_width(txtArtist, LV_HOR_RES - 12); lv_obj_set_width(txtArtist, LV_HOR_RES - 12);
lv_label_set_text(txtArtist, "Artist Name"); lv_label_set_text(txtArtist, "Artist Name");
txtTrack = lv_label_create(lv_scr_act(), nullptr); txtTrack = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_long_mode(txtTrack, LV_LABEL_LONG_SROLL_CIRC); lv_label_set_long_mode(txtTrack, LV_LABEL_LONG_SROLL_CIRC);
lv_label_set_anim_speed(txtTrack, 1); lv_label_set_anim_speed(txtTrack, 1);
@ -202,8 +201,8 @@ bool Music::Refresh() {
frameB = !frameB; frameB = !frameB;
if (currentLength < totalLength) { if (currentLength < totalLength) {
currentLength += static_cast<int>((static_cast<float>(xTaskGetTickCount() - lastIncrement) / 1024.0f) * currentLength +=
musicService.getPlaybackSpeed()); static_cast<int>((static_cast<float>(xTaskGetTickCount() - lastIncrement) / 1024.0f) * musicService.getPlaybackSpeed());
} else { } else {
// Let's assume the getTrack finished, paused when the timer ends // Let's assume the getTrack finished, paused when the timer ends
// and there's no new getTrack being sent to us // and there's no new getTrack being sent to us
@ -226,21 +225,21 @@ void Music::UpdateLength() {
lv_label_set_text(txtTrackDuration, "Inf/Inf"); lv_label_set_text(txtTrackDuration, "Inf/Inf");
} else if (totalLength > (99 * 60)) { } else if (totalLength > (99 * 60)) {
char timer[12]; char timer[12];
sprintf(timer, "%02d:%02d/%02d:%02d", sprintf(timer,
"%02d:%02d/%02d:%02d",
(currentLength / (60 * 60)) % 100, (currentLength / (60 * 60)) % 100,
((currentLength % (60 * 60)) / 60) % 100, ((currentLength % (60 * 60)) / 60) % 100,
(totalLength / (60 * 60)) % 100, (totalLength / (60 * 60)) % 100,
((totalLength % (60 * 60)) / 60) % 100 ((totalLength % (60 * 60)) / 60) % 100);
);
lv_label_set_text(txtTrackDuration, timer); lv_label_set_text(txtTrackDuration, timer);
} else { } else {
char timer[12]; char timer[12];
sprintf(timer, "%02d:%02d/%02d:%02d", sprintf(timer,
"%02d:%02d/%02d:%02d",
(currentLength / 60) % 100, (currentLength / 60) % 100,
(currentLength % 60) % 100, (currentLength % 60) % 100,
(totalLength / 60) % 100, (totalLength / 60) % 100,
(totalLength % 60) % 100 (totalLength % 60) % 100);
);
lv_label_set_text(txtTrackDuration, timer); lv_label_set_text(txtTrackDuration, timer);
} }
} }
@ -272,7 +271,6 @@ void Music::OnObjectEvent(lv_obj_t *obj, lv_event_t event) {
} }
} }
bool Music::OnTouchEvent(Pinetime::Applications::TouchEvents event) { bool Music::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
switch (event) { switch (event) {
case TouchEvents::SwipeUp: { case TouchEvents::SwipeUp: {

View file

@ -37,8 +37,6 @@ namespace Pinetime {
bool Refresh() override; bool Refresh() override;
void OnObjectEvent(lv_obj_t* obj, lv_event_t event); void OnObjectEvent(lv_obj_t* obj, lv_event_t event);
private: private:
@ -81,7 +79,6 @@ namespace Pinetime {
bool playing; bool playing;
/** Watchapp */ /** Watchapp */
}; };
} }
} }

View file

@ -28,7 +28,8 @@ LV_FONT_DECLARE(lv_font_navi_80)
* Navigation watchapp * Navigation watchapp
* *
*/ */
Navigation::Navigation(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::NavigationService &nav) : Screen(app), navService(nav) { Navigation::Navigation(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::NavigationService& nav)
: Screen(app), navService(nav) {
imgFlag = lv_label_create(lv_scr_act(), nullptr); imgFlag = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_font(imgFlag, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_navi_80); lv_obj_set_style_local_text_font(imgFlag, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_navi_80);
@ -36,7 +37,6 @@ Navigation::Navigation(Pinetime::Applications::DisplayApp *app, Pinetime::Contro
lv_label_set_text(imgFlag, iconForName("flag")); lv_label_set_text(imgFlag, iconForName("flag"));
lv_obj_align(imgFlag, nullptr, LV_ALIGN_CENTER, 0, -60); lv_obj_align(imgFlag, nullptr, LV_ALIGN_CENTER, 0, -60);
txtNarrative = lv_label_create(lv_scr_act(), nullptr); txtNarrative = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_long_mode(txtNarrative, LV_LABEL_LONG_BREAK); lv_label_set_long_mode(txtNarrative, LV_LABEL_LONG_BREAK);
lv_obj_set_width(txtNarrative, LV_HOR_RES); lv_obj_set_width(txtNarrative, LV_HOR_RES);

View file

@ -23,7 +23,6 @@
#include "Screen.h" #include "Screen.h"
#include <array> #include <array>
namespace Pinetime { namespace Pinetime {
namespace Controllers { namespace Controllers {
class NavigationService; class NavigationService;
@ -39,7 +38,6 @@ namespace Pinetime {
bool Refresh() override; bool Refresh() override;
private: private:
lv_obj_t* imgFlag; lv_obj_t* imgFlag;
lv_obj_t* txtNarrative; lv_obj_t* txtNarrative;
lv_obj_t* txtManDist; lv_obj_t* txtManDist;

View file

@ -3,6 +3,8 @@
using namespace Pinetime::Applications::Screens; using namespace Pinetime::Applications::Screens;
const char* NotificationIcon::GetIcon(bool newNotificationAvailable) { const char* NotificationIcon::GetIcon(bool newNotificationAvailable) {
if(newNotificationAvailable) return Symbols::info; if (newNotificationAvailable)
else return ""; return Symbols::info;
else
return "";
} }

Some files were not shown because too many files have changed in this diff Show more