Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
[submodule "src/libs/QCBOR"]
path = src/libs/QCBOR
url = https://github.com/laurencelundblade/QCBOR.git
[submodule "src/libs/QR-Code-generator"]
path = src/libs/QR-Code-generator
url = https://github.com/nayuki/QR-Code-generator
1 change: 1 addition & 0 deletions src/BootloaderVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace Pinetime {
static const char* VersionString();
static const bool IsValid();
static void SetVersion(uint32_t v);

private:
static uint32_t version;
static constexpr size_t VERSION_STR_LEN = 12;
Expand Down
25 changes: 23 additions & 2 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,10 @@ set(QCBOR_SRC
libs/QCBOR/src/qcbor_err_to_str.c
libs/QCBOR/src/UsefulBuf.c
)
set(QRCODE_SRC
libs/QR-Code-generator/c/qrcodegen.c
libs/QR-Code-generator/c/qrcodegen.h
)

list(APPEND IMAGE_FILES
displayapp/icons/battery/os_battery_error.c
Expand Down Expand Up @@ -424,6 +428,7 @@ list(APPEND SOURCE_FILES
displayapp/screens/ApplicationList.cpp
displayapp/screens/Notifications.cpp
displayapp/screens/Twos.cpp
displayapp/screens/Qr.cpp
displayapp/screens/HeartRate.cpp
displayapp/screens/Motion.cpp
displayapp/screens/FlashLight.cpp
Expand Down Expand Up @@ -491,6 +496,7 @@ list(APPEND SOURCE_FILES
components/ble/FSService.cpp
components/ble/ImmediateAlertService.cpp
components/ble/ServiceDiscovery.cpp
components/ble/QrService.cpp
components/ble/HeartRateService.cpp
components/ble/MotionService.cpp
components/firmwarevalidator/FirmwareValidator.cpp
Expand Down Expand Up @@ -565,6 +571,7 @@ list(APPEND RECOVERY_SOURCE_FILES
components/ble/NavigationService.cpp
components/ble/HeartRateService.cpp
components/ble/MotionService.cpp
components/ble/QrService.cpp
components/firmwarevalidator/FirmwareValidator.cpp
components/settings/Settings.cpp
components/timer/TimerController.cpp
Expand Down Expand Up @@ -636,6 +643,7 @@ set(INCLUDE_FILES
displayapp/screens/FirmwareUpdate.h
displayapp/screens/FirmwareValidation.h
displayapp/screens/ApplicationList.h
displayapp/screens/Qr.h
displayapp/Apps.h
displayapp/screens/Notifications.h
displayapp/screens/HeartRate.h
Expand Down Expand Up @@ -682,6 +690,7 @@ set(INCLUDE_FILES
components/settings/Settings.h
components/timer/TimerController.h
components/alarm/AlarmController.h
components/ble/QrService.h
drivers/Cst816s.h
FreeRTOS/portmacro.h
FreeRTOS/portmacro_cmsis.h
Expand Down Expand Up @@ -888,13 +897,25 @@ target_compile_options(littlefs PRIVATE
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -x assembler-with-cpp>
)

# qrcode
add_library(qrcode STATIC ${QRCODE_SRC})
target_include_directories(qrcode SYSTEM PUBLIC . ../)
target_include_directories(qrcode SYSTEM PUBLIC ${INCLUDES_FROM_LIBS})
target_compile_options(qrcode PRIVATE
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3>
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3>
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -O0 -g3>
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -O3>
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -std=c99 -x assembler-with-cpp>
)

# Build autonomous binary (without support for bootloader)
set(EXECUTABLE_NAME "pinetime-app")
set(EXECUTABLE_FILE_NAME ${EXECUTABLE_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
set(NRF5_LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/gcc_nrf52.ld")
add_executable(${EXECUTABLE_NAME} ${SOURCE_FILES})
set_target_properties(${EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_FILE_NAME})
target_link_libraries(${EXECUTABLE_NAME} nimble nrf-sdk lvgl littlefs QCBOR)
target_link_libraries(${EXECUTABLE_NAME} nimble nrf-sdk lvgl littlefs QCBOR qrcode)
target_compile_options(${EXECUTABLE_NAME} PUBLIC
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Wextra -Wformat -Wno-missing-field-initializers -Wno-unused-parameter -Og -g3>
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Wextra -Wformat -Wno-missing-field-initializers -Wno-unused-parameter -Os>
Expand Down Expand Up @@ -923,7 +944,7 @@ set(IMAGE_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-image-${pinetime_VERSION_
set(DFU_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip)
set(NRF5_LINKER_SCRIPT_MCUBOOT "${CMAKE_SOURCE_DIR}/gcc_nrf52-mcuboot.ld")
add_executable(${EXECUTABLE_MCUBOOT_NAME} ${SOURCE_FILES})
target_link_libraries(${EXECUTABLE_MCUBOOT_NAME} nimble nrf-sdk lvgl littlefs QCBOR)
target_link_libraries(${EXECUTABLE_MCUBOOT_NAME} nimble nrf-sdk lvgl littlefs QCBOR qrcode)
set_target_properties(${EXECUTABLE_MCUBOOT_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_MCUBOOT_FILE_NAME})
target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -g3>
Expand Down
12 changes: 6 additions & 6 deletions src/components/ble/DfuService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@ int DfuService::WritePacketHandler(uint16_t connectionHandle, os_mbuf* om) {

if ((nbPacketReceived % nbPacketsToNotify) == 0 && bytesReceived != applicationSize) {
uint8_t data[5] {static_cast<uint8_t>(Opcodes::PacketReceiptNotification),
(uint8_t)(bytesReceived & 0x000000FFu),
(uint8_t)(bytesReceived >> 8u),
(uint8_t)(bytesReceived >> 16u),
(uint8_t)(bytesReceived >> 24u)};
(uint8_t) (bytesReceived & 0x000000FFu),
(uint8_t) (bytesReceived >> 8u),
(uint8_t) (bytesReceived >> 16u),
(uint8_t) (bytesReceived >> 24u)};
NRF_LOG_INFO("[DFU] -> Send packet notification: %d bytes received", bytesReceived);
notificationManager.Send(connectionHandle, controlPointCharacteristicHandle, data, 5);
}
Expand Down Expand Up @@ -422,9 +422,9 @@ uint16_t DfuService::DfuImage::ComputeCrc(uint8_t const* p_data, uint32_t size,
uint16_t crc = (p_crc == NULL) ? 0xFFFF : *p_crc;

for (uint32_t i = 0; i < size; i++) {
crc = (uint8_t)(crc >> 8) | (crc << 8);
crc = (uint8_t) (crc >> 8) | (crc << 8);
crc ^= p_data[i];
crc ^= (uint8_t)(crc & 0xFF) >> 4;
crc ^= (uint8_t) (crc & 0xFF) >> 4;
crc ^= (crc << 8) << 4;
crc ^= ((crc & 0xFF) << 4) << 1;
}
Expand Down
7 changes: 4 additions & 3 deletions src/components/ble/HeartRateService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ int HeartRateService::OnHeartRateRequested(uint16_t connectionHandle, uint16_t a
}

void HeartRateService::OnNewHeartRateValue(uint8_t heartRateValue) {
if(!heartRateMeasurementNotificationEnable) return;
if (!heartRateMeasurementNotificationEnable)
return;

uint8_t buffer[2] = {0, heartRateController.HeartRate()}; // [0] = flags, [1] = hr value
auto* om = ble_hs_mbuf_from_flat(buffer, 2);
Expand All @@ -71,11 +72,11 @@ void HeartRateService::OnNewHeartRateValue(uint8_t heartRateValue) {
}

void HeartRateService::SubscribeNotification(uint16_t connectionHandle, uint16_t attributeHandle) {
if(attributeHandle == heartRateMeasurementHandle)
if (attributeHandle == heartRateMeasurementHandle)
heartRateMeasurementNotificationEnable = true;
}

void HeartRateService::UnsubscribeNotification(uint16_t connectionHandle, uint16_t attributeHandle) {
if(attributeHandle == heartRateMeasurementHandle)
if (attributeHandle == heartRateMeasurementHandle)
heartRateMeasurementNotificationEnable = false;
}
32 changes: 14 additions & 18 deletions src/components/ble/MotionService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ using namespace Pinetime::Controllers;
namespace {
// 0003yyxx-78fc-48fe-8e23-433b3a1942d0
constexpr ble_uuid128_t CharUuid(uint8_t x, uint8_t y) {
return ble_uuid128_t{
.u = {.type = BLE_UUID_TYPE_128},
.value = { 0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, x, y, 0x03, 0x00 }
};
return ble_uuid128_t {.u = {.type = BLE_UUID_TYPE_128},
.value = {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, x, y, 0x03, 0x00}};
}

// 00030000-78fc-48fe-8e23-433b3a1942d0
Expand Down Expand Up @@ -44,11 +42,7 @@ MotionService::MotionService(Pinetime::System::SystemTask& system, Controllers::
.val_handle = &motionValuesHandle},
{0}},
serviceDefinition {
{
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = &motionServiceUuid.u,
.characteristics = characteristicDefinition
},
{.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &motionServiceUuid.u, .characteristics = characteristicDefinition},
{0},
} {
// TODO refactor to prevent this loop dependency (service depends on controller and controller depends on service)
Expand All @@ -71,8 +65,8 @@ int MotionService::OnStepCountRequested(uint16_t connectionHandle, uint16_t attr

int res = os_mbuf_append(context->om, &buffer, 4);
return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
} else if(attributeHandle == motionValuesHandle) {
int16_t buffer[3] = { motionController.X(), motionController.Y(), motionController.Z() };
} else if (attributeHandle == motionValuesHandle) {
int16_t buffer[3] = {motionController.X(), motionController.Y(), motionController.Z()};

int res = os_mbuf_append(context->om, buffer, 3 * sizeof(int16_t));
return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
Expand All @@ -81,7 +75,8 @@ int MotionService::OnStepCountRequested(uint16_t connectionHandle, uint16_t attr
}

void MotionService::OnNewStepCountValue(uint32_t stepCount) {
if(!stepCountNoficationEnabled) return;
if (!stepCountNoficationEnabled)
return;

uint32_t buffer = stepCount;
auto* om = ble_hs_mbuf_from_flat(&buffer, 4);
Expand All @@ -95,9 +90,10 @@ void MotionService::OnNewStepCountValue(uint32_t stepCount) {
ble_gattc_notify_custom(connectionHandle, stepCountHandle, om);
}
void MotionService::OnNewMotionValues(int16_t x, int16_t y, int16_t z) {
if(!motionValuesNoficationEnabled) return;
if (!motionValuesNoficationEnabled)
return;

int16_t buffer[3] = { motionController.X(), motionController.Y(), motionController.Z() };
int16_t buffer[3] = {motionController.X(), motionController.Y(), motionController.Z()};
auto* om = ble_hs_mbuf_from_flat(buffer, 3 * sizeof(int16_t));

uint16_t connectionHandle = system.nimble().connHandle();
Expand All @@ -110,15 +106,15 @@ void MotionService::OnNewMotionValues(int16_t x, int16_t y, int16_t z) {
}

void MotionService::SubscribeNotification(uint16_t connectionHandle, uint16_t attributeHandle) {
if(attributeHandle == stepCountHandle)
if (attributeHandle == stepCountHandle)
stepCountNoficationEnabled = true;
else if(attributeHandle == motionValuesHandle)
else if (attributeHandle == motionValuesHandle)
motionValuesNoficationEnabled = true;
}

void MotionService::UnsubscribeNotification(uint16_t connectionHandle, uint16_t attributeHandle) {
if(attributeHandle == stepCountHandle)
if (attributeHandle == stepCountHandle)
stepCountNoficationEnabled = false;
else if(attributeHandle == motionValuesHandle)
else if (attributeHandle == motionValuesHandle)
motionValuesNoficationEnabled = false;
}
88 changes: 29 additions & 59 deletions src/components/ble/MusicService.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,8 @@
namespace {
// 0000yyxx-78fc-48fe-8e23-433b3a1942d0
constexpr ble_uuid128_t CharUuid(uint8_t x, uint8_t y) {
return ble_uuid128_t{
.u = {.type = BLE_UUID_TYPE_128},
.value = { 0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, x, y, 0x00, 0x00 }
};
return ble_uuid128_t {.u = {.type = BLE_UUID_TYPE_128},
.value = {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, x, y, 0x00, 0x00}};
}

// 00000000-78fc-48fe-8e23-433b3a1942d0
Expand Down Expand Up @@ -53,63 +51,35 @@ namespace {
}

Pinetime::Controllers::MusicService::MusicService(Pinetime::System::SystemTask& system) : m_system(system) {
characteristicDefinition[0] = {.uuid = &msEventCharUuid.u,
.access_cb = MusicCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_NOTIFY,
.val_handle = &eventHandle};
characteristicDefinition[1] = {.uuid = &msStatusCharUuid.u,
.access_cb = MusicCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[2] = {.uuid = &msTrackCharUuid.u,
.access_cb = MusicCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[3] = {.uuid = &msArtistCharUuid.u,
.access_cb = MusicCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[4] = {.uuid = &msAlbumCharUuid.u,
.access_cb = MusicCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[5] = {.uuid = &msPositionCharUuid.u,
.access_cb = MusicCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[6] = {.uuid = &msTotalLengthCharUuid.u,
.access_cb = MusicCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[7] = {.uuid = &msTotalLengthCharUuid.u,
.access_cb = MusicCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[8] = {.uuid = &msTrackNumberCharUuid.u,
.access_cb = MusicCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[9] = {.uuid = &msTrackTotalCharUuid.u,
.access_cb = MusicCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[10] = {.uuid = &msPlaybackSpeedCharUuid.u,
.access_cb = MusicCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[11] = {.uuid = &msRepeatCharUuid.u,
.access_cb = MusicCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[12] = {.uuid = &msShuffleCharUuid.u,
.access_cb = MusicCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[0] = {
.uuid = &msEventCharUuid.u, .access_cb = MusicCallback, .arg = this, .flags = BLE_GATT_CHR_F_NOTIFY, .val_handle = &eventHandle};
characteristicDefinition[1] = {
.uuid = &msStatusCharUuid.u, .access_cb = MusicCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[2] = {
.uuid = &msTrackCharUuid.u, .access_cb = MusicCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[3] = {
.uuid = &msArtistCharUuid.u, .access_cb = MusicCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[4] = {
.uuid = &msAlbumCharUuid.u, .access_cb = MusicCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[5] = {
.uuid = &msPositionCharUuid.u, .access_cb = MusicCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[6] = {
.uuid = &msTotalLengthCharUuid.u, .access_cb = MusicCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[7] = {
.uuid = &msTotalLengthCharUuid.u, .access_cb = MusicCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[8] = {
.uuid = &msTrackNumberCharUuid.u, .access_cb = MusicCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[9] = {
.uuid = &msTrackTotalCharUuid.u, .access_cb = MusicCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[10] = {
.uuid = &msPlaybackSpeedCharUuid.u, .access_cb = MusicCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[11] = {
.uuid = &msRepeatCharUuid.u, .access_cb = MusicCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[12] = {
.uuid = &msShuffleCharUuid.u, .access_cb = MusicCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
characteristicDefinition[13] = {0};

serviceDefinition[0] = {
.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &msUuid.u, .characteristics = characteristicDefinition};
serviceDefinition[0] = {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &msUuid.u, .characteristics = characteristicDefinition};
serviceDefinition[1] = {0};
}

Expand Down
2 changes: 2 additions & 0 deletions src/components/ble/NimbleController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask,
navService {systemTask},
batteryInformationService {batteryController},
immediateAlertService {systemTask, notificationManager},
qrService(systemTask),
heartRateService {systemTask, heartRateController},
motionService {systemTask, motionController},
fsService {systemTask, fs},
Expand Down Expand Up @@ -96,6 +97,7 @@ void NimbleController::Init() {
dfuService.Init();
batteryInformationService.Init();
immediateAlertService.Init();
qrService.Init();
heartRateService.Init();
motionService.Init();
fsService.Init();
Expand Down
5 changes: 5 additions & 0 deletions src/components/ble/NimbleController.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "components/ble/weather/WeatherService.h"
#include "components/fs/FS.h"
#include "components/ble/FSService.h"
#include "components/ble/QrService.h"

namespace Pinetime {
namespace Drivers {
Expand Down Expand Up @@ -77,6 +78,9 @@ namespace Pinetime {
Pinetime::Controllers::WeatherService& weather() {
return weatherService;
};
Pinetime::Controllers::QrService& qr() {
return qrService;
};

uint16_t connHandle();
void NotifyBatteryLevel(uint8_t level);
Expand Down Expand Up @@ -108,6 +112,7 @@ namespace Pinetime {
NavigationService navService;
BatteryInformationService batteryInformationService;
ImmediateAlertService immediateAlertService;
QrService qrService;
HeartRateService heartRateService;
MotionService motionService;
FSService fsService;
Expand Down
Loading