diff --git a/.gitmodules b/.gitmodules index 8d302ae72e..a01f252597 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 diff --git a/src/BootloaderVersion.h b/src/BootloaderVersion.h index 309c23c350..7ed90fa9da 100644 --- a/src/BootloaderVersion.h +++ b/src/BootloaderVersion.h @@ -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; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 062d8a5000..951be2fa70 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -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 @@ -888,13 +897,25 @@ target_compile_options(littlefs PRIVATE $<$: -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 + $<$,$>: ${COMMON_FLAGS} -O0 -g3> + $<$,$>: ${COMMON_FLAGS} -O3> + $<$,$>: ${COMMON_FLAGS} -O0 -g3> + $<$,$>: ${COMMON_FLAGS} -O3> + $<$: -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 $<$,$>: ${COMMON_FLAGS} -Wextra -Wformat -Wno-missing-field-initializers -Wno-unused-parameter -Og -g3> $<$,$>: ${COMMON_FLAGS} -Wextra -Wformat -Wno-missing-field-initializers -Wno-unused-parameter -Os> @@ -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 $<$,$>: ${COMMON_FLAGS} -Og -g3> diff --git a/src/components/ble/DfuService.cpp b/src/components/ble/DfuService.cpp index 71dcc7e637..9bc5026534 100644 --- a/src/components/ble/DfuService.cpp +++ b/src/components/ble/DfuService.cpp @@ -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(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); } @@ -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; } diff --git a/src/components/ble/HeartRateService.cpp b/src/components/ble/HeartRateService.cpp index f178af795a..36b5e2b84e 100644 --- a/src/components/ble/HeartRateService.cpp +++ b/src/components/ble/HeartRateService.cpp @@ -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); @@ -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; } \ No newline at end of file diff --git a/src/components/ble/MotionService.cpp b/src/components/ble/MotionService.cpp index 6381915df4..5f5ead650f 100644 --- a/src/components/ble/MotionService.cpp +++ b/src/components/ble/MotionService.cpp @@ -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 @@ -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) @@ -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; @@ -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); @@ -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(); @@ -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; } diff --git a/src/components/ble/MusicService.cpp b/src/components/ble/MusicService.cpp index 3457ce4cef..35075ef5aa 100644 --- a/src/components/ble/MusicService.cpp +++ b/src/components/ble/MusicService.cpp @@ -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 @@ -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}; } diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index d8510bd36c..554004d043 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -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}, @@ -96,6 +97,7 @@ void NimbleController::Init() { dfuService.Init(); batteryInformationService.Init(); immediateAlertService.Init(); + qrService.Init(); heartRateService.Init(); motionService.Init(); fsService.Init(); diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 2b300e630e..aafb66177c 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -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 { @@ -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); @@ -108,6 +112,7 @@ namespace Pinetime { NavigationService navService; BatteryInformationService batteryInformationService; ImmediateAlertService immediateAlertService; + QrService qrService; HeartRateService heartRateService; MotionService motionService; FSService fsService; diff --git a/src/components/ble/QrService.cpp b/src/components/ble/QrService.cpp new file mode 100644 index 0000000000..381458e0a3 --- /dev/null +++ b/src/components/ble/QrService.cpp @@ -0,0 +1,85 @@ +#include "QrService.h" +#include "systemtask/SystemTask.h" + +using namespace Pinetime::Controllers; + +namespace { + // 0004yyxx-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, 0x04, 0x00}}; + } + + // 00040000-78fc-48fe-8e23-433b3a1942d0 + constexpr ble_uuid128_t BaseUuid() { + return CharUuid(0x00, 0x00); + } + + constexpr ble_uuid128_t qrServiceUuid {BaseUuid()}; + constexpr ble_uuid128_t qrCharUuid {CharUuid(0x01, 0x00)}; + + int QrCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) { + auto qrService = static_cast(arg); + return qrService->OnCommand(conn_handle, attr_handle, ctxt); + } +} + +QrService::QrService(Pinetime::System::SystemTask& system) + : system {system}, + characteristicDefinition { + {.uuid = &qrCharUuid.u, .access_cb = QrCallback, .arg = this, .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ}, {0}}, + serviceDefinition { + {.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &qrServiceUuid.u, .characteristics = characteristicDefinition}, + {0}, + } { + qrList[0].name = "Github"; + qrList[0].text = "https://github.com/InfiniTimeOrg/InfiniTime"; + qrList[1].name = "Twitter"; + qrList[1].text = "https://twitter.com/codingfield"; + qrList[2].name = "Mastodon"; + qrList[2].text = "https://mastodon.codingfield.com/@JF"; + qrList[3].name = "Donate!"; + qrList[3].text = "https://liberapay.com/JF002"; +} + +void QrService::Init() { + int res = 0; + res = ble_gatts_count_cfg(serviceDefinition); + ASSERT(res == 0); + + res = ble_gatts_add_svcs(serviceDefinition); + ASSERT(res == 0); +} + +int QrService::OnCommand(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) { + if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) { + size_t notifSize = OS_MBUF_PKTLEN(ctxt->om); + uint8_t data[notifSize + 1]; + data[notifSize] = '\0'; + os_mbuf_copydata(ctxt->om, 0, notifSize, data); + char* s = (char*) &data[0]; + NRF_LOG_INFO("DATA : %s", s); + + const char* d = "|"; + const char* qrId = strtok(s, d); + const char* qrName = strtok(NULL, d); + const char* qrText = strtok(NULL, d); + + if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t*) &qrCharUuid) == 0) { + if (qrId != NULL) { + if (atoi(qrId) == 0 || qrName == NULL || qrText == NULL) { + qrList[0].name = "Wrong format"; + qrList[0].text = qrId; + } else if (atoi(qrId) > 0 && atoi(qrId) < MAXLISTITEMS + 1) { + qrList[atoi(qrId) - 1].name = qrName; + qrList[atoi(qrId) - 1].text = qrText; + } + } + } + } + return 0; +} + +std::array QrService::getQrList() { + return qrList; +} diff --git a/src/components/ble/QrService.h b/src/components/ble/QrService.h new file mode 100644 index 0000000000..1f5528f1b9 --- /dev/null +++ b/src/components/ble/QrService.h @@ -0,0 +1,47 @@ +#pragma once + +#include +#include +#include +#define min // workaround: nimble's min/max macros conflict with libstdc++ +#define max +#include +#include +#undef max +#undef min + +#define MAXLISTITEMS 4 + +namespace Pinetime { + namespace System { + class SystemTask; + } + namespace Controllers { + class QrService { + public: + struct QrInfo { + std::string name; + std::string text; + bool operator==(const QrInfo& rhs) const { + return (rhs.name == name && rhs.text == text); + } + }; + + explicit QrService(Pinetime::System::SystemTask& system); + + void Init(); + + int OnCommand(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt); + + std::array getQrList(); + + private: + Pinetime::System::SystemTask& system; + + struct ble_gatt_chr_def characteristicDefinition[2]; + struct ble_gatt_svc_def serviceDefinition[2]; + + std::array qrList; + }; + } +} diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp index 8c98ae344a..14b05525dd 100644 --- a/src/components/fs/FS.cpp +++ b/src/components/fs/FS.cpp @@ -95,8 +95,8 @@ int FS::DirRewind(lfs_dir_t* dir) { int FS::DirCreate(const char* path) { return lfs_mkdir(&lfs, path); } -int FS::Rename(const char* oldPath, const char* newPath){ - return lfs_rename(&lfs,oldPath,newPath); +int FS::Rename(const char* oldPath, const char* newPath) { + return lfs_rename(&lfs, oldPath, newPath); } int FS::Stat(const char* path, lfs_info* info) { return lfs_stat(&lfs, path, info); diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h index 2b27ae5d3f..87fcdc23f4 100644 --- a/src/components/fs/FS.h +++ b/src/components/fs/FS.h @@ -26,7 +26,7 @@ namespace Pinetime { int DirRead(lfs_dir_t* dir, lfs_info* info); int DirRewind(lfs_dir_t* dir); int DirCreate(const char* path); - + lfs_ssize_t GetFSSize(); int Rename(const char* oldPath, const char* newPath); int Stat(const char* path, lfs_info* info); diff --git a/src/components/settings/Settings.cpp b/src/components/settings/Settings.cpp index ef73ad1c6b..36340bd579 100644 --- a/src/components/settings/Settings.cpp +++ b/src/components/settings/Settings.cpp @@ -26,12 +26,12 @@ void Settings::LoadSettingsFromFile() { SettingsData bufferSettings; lfs_file_t settingsFile; - if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) { + if (fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) { return; } fs.FileRead(&settingsFile, reinterpret_cast(&bufferSettings), sizeof(settings)); fs.FileClose(&settingsFile); - if ( bufferSettings.version == settingsVersion ) { + if (bufferSettings.version == settingsVersion) { settings = bufferSettings; } } @@ -39,7 +39,7 @@ void Settings::LoadSettingsFromFile() { void Settings::SaveSettingsToFile() { lfs_file_t settingsFile; - if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) { + if (fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) { return; } fs.FileWrite(&settingsFile, reinterpret_cast(&settings), sizeof(settings)); diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 6de44aac71..e1b76d9303 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -19,7 +19,23 @@ namespace Pinetime { Shake = 3, }; enum class Colors : uint8_t { - White, Silver, Gray, Black, Red, Maroon, Yellow, Olive, Lime, Green, Cyan, Teal, Blue, Navy, Magenta, Purple, Orange + White, + Silver, + Gray, + Black, + Red, + Maroon, + Yellow, + Olive, + Lime, + Green, + Cyan, + Teal, + Blue, + Navy, + Magenta, + Purple, + Orange }; struct PineTimeStyle { Colors ColorTime = Colors::Teal; @@ -125,15 +141,14 @@ namespace Pinetime { return settings.screenTimeOut; }; - void SetShakeThreshold(uint16_t thresh){ - if(settings.shakeWakeThreshold != thresh){ - settings.shakeWakeThreshold = thresh; - settingsChanged = true; + void SetShakeThreshold(uint16_t thresh) { + if (settings.shakeWakeThreshold != thresh) { + settings.shakeWakeThreshold = thresh; + settingsChanged = true; } - } - int16_t GetShakeThreshold() const{ + int16_t GetShakeThreshold() const { return settings.shakeWakeThreshold; } @@ -175,14 +190,16 @@ namespace Pinetime { return settings.brightLevel; }; - void SetStepsGoal( uint32_t goal ) { - if ( goal != settings.stepsGoal ) { + void SetStepsGoal(uint32_t goal) { + if (goal != settings.stepsGoal) { settingsChanged = true; } - settings.stepsGoal = goal; + settings.stepsGoal = goal; + }; + + uint32_t GetStepsGoal() const { + return settings.stepsGoal; }; - - uint32_t GetStepsGoal() const { return settings.stepsGoal; }; private: Pinetime::Controllers::FS& fs; diff --git a/src/components/timer/TimerController.cpp b/src/components/timer/TimerController.cpp index 79e44d6f80..9ac38ed206 100644 --- a/src/components/timer/TimerController.cpp +++ b/src/components/timer/TimerController.cpp @@ -9,18 +9,16 @@ using namespace Pinetime::Controllers; - APP_TIMER_DEF(timerAppTimer); namespace { void TimerEnd(void* p_context) { - auto* controller = static_cast (p_context); - if(controller != nullptr) + auto* controller = static_cast(p_context); + if (controller != nullptr) controller->OnTimerEnd(); } } - void TimerController::Init() { app_timer_create(&timerAppTimer, APP_TIMER_MODE_SINGLE_SHOT, TimerEnd); } @@ -38,7 +36,7 @@ uint32_t TimerController::GetTimeRemaining() { return 0; } auto currentTicks = xTaskGetTickCount(); - + TickType_t deltaTicks = 0; if (currentTicks > endTicks) { deltaTicks = 0xffffffff - currentTicks; @@ -46,7 +44,7 @@ uint32_t TimerController::GetTimeRemaining() { } else { deltaTicks = endTicks - currentTicks; } - + return (static_cast(deltaTicks) / static_cast(configTICK_RATE_HZ)) * 1000; } @@ -60,7 +58,7 @@ bool TimerController::IsRunning() { } void TimerController::OnTimerEnd() { timerRunning = false; - if(systemTask != nullptr) + if (systemTask != nullptr) systemTask->PushMessage(System::Messages::OnTimerDone); } diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index b876020eac..193b20408d 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -27,6 +27,7 @@ namespace Pinetime { Steps, Weather, PassKey, + Qr, QuickSettings, Settings, SettingWatchFace, diff --git a/src/displayapp/Colors.cpp b/src/displayapp/Colors.cpp index 93b1aa06fe..35f784e5d0 100644 --- a/src/displayapp/Colors.cpp +++ b/src/displayapp/Colors.cpp @@ -5,23 +5,41 @@ using namespace Pinetime::Controllers; lv_color_t Pinetime::Applications::Convert(Pinetime::Controllers::Settings::Colors color) { switch (color) { - case Pinetime::Controllers::Settings::Colors::White: return LV_COLOR_WHITE; - case Pinetime::Controllers::Settings::Colors::Silver: return LV_COLOR_SILVER; - case Pinetime::Controllers::Settings::Colors::Gray: return LV_COLOR_GRAY; - case Pinetime::Controllers::Settings::Colors::Black: return LV_COLOR_BLACK; - case Pinetime::Controllers::Settings::Colors::Red: return LV_COLOR_RED; - case Pinetime::Controllers::Settings::Colors::Maroon: return LV_COLOR_MAROON; - case Pinetime::Controllers::Settings::Colors::Yellow: return LV_COLOR_YELLOW; - case Pinetime::Controllers::Settings::Colors::Olive: return LV_COLOR_OLIVE; - case Pinetime::Controllers::Settings::Colors::Lime: return LV_COLOR_LIME; - case Pinetime::Controllers::Settings::Colors::Green: return LV_COLOR_GREEN; - case Pinetime::Controllers::Settings::Colors::Cyan: return LV_COLOR_CYAN; - case Pinetime::Controllers::Settings::Colors::Teal: return LV_COLOR_TEAL; - case Pinetime::Controllers::Settings::Colors::Blue: return LV_COLOR_BLUE; - case Pinetime::Controllers::Settings::Colors::Navy: return LV_COLOR_NAVY; - case Pinetime::Controllers::Settings::Colors::Magenta: return LV_COLOR_MAGENTA; - case Pinetime::Controllers::Settings::Colors::Purple: return LV_COLOR_PURPLE; - case Pinetime::Controllers::Settings::Colors::Orange: return LV_COLOR_ORANGE; - default: return LV_COLOR_WHITE; + case Pinetime::Controllers::Settings::Colors::White: + return LV_COLOR_WHITE; + case Pinetime::Controllers::Settings::Colors::Silver: + return LV_COLOR_SILVER; + case Pinetime::Controllers::Settings::Colors::Gray: + return LV_COLOR_GRAY; + case Pinetime::Controllers::Settings::Colors::Black: + return LV_COLOR_BLACK; + case Pinetime::Controllers::Settings::Colors::Red: + return LV_COLOR_RED; + case Pinetime::Controllers::Settings::Colors::Maroon: + return LV_COLOR_MAROON; + case Pinetime::Controllers::Settings::Colors::Yellow: + return LV_COLOR_YELLOW; + case Pinetime::Controllers::Settings::Colors::Olive: + return LV_COLOR_OLIVE; + case Pinetime::Controllers::Settings::Colors::Lime: + return LV_COLOR_LIME; + case Pinetime::Controllers::Settings::Colors::Green: + return LV_COLOR_GREEN; + case Pinetime::Controllers::Settings::Colors::Cyan: + return LV_COLOR_CYAN; + case Pinetime::Controllers::Settings::Colors::Teal: + return LV_COLOR_TEAL; + case Pinetime::Controllers::Settings::Colors::Blue: + return LV_COLOR_BLUE; + case Pinetime::Controllers::Settings::Colors::Navy: + return LV_COLOR_NAVY; + case Pinetime::Controllers::Settings::Colors::Magenta: + return LV_COLOR_MAGENTA; + case Pinetime::Controllers::Settings::Colors::Purple: + return LV_COLOR_PURPLE; + case Pinetime::Controllers::Settings::Colors::Orange: + return LV_COLOR_ORANGE; + default: + return LV_COLOR_WHITE; } } diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 7a73f12362..7b3d2d797b 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -31,7 +31,7 @@ #include "displayapp/screens/Steps.h" #include "displayapp/screens/PassKey.h" #include "displayapp/screens/Error.h" - +#include "displayapp/screens/Qr.h" #include "drivers/Cst816s.h" #include "drivers/St7789.h" #include "drivers/Watchdog.h" @@ -425,7 +425,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::SettingShakeThreshold: - currentScreen = std::make_unique(this, settingsController,motionController,*systemTask); + currentScreen = std::make_unique(this, settingsController, motionController, *systemTask); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::BatteryInfo: @@ -472,6 +472,9 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) case Apps::Steps: currentScreen = std::make_unique(this, motionController, settingsController); break; + case Apps::Qr: + currentScreen = std::make_unique(this, lvgl, systemTask->nimble().qr()); + break; } currentApp = app; } diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index fd7017a451..cb899cc8df 100644 --- a/src/displayapp/DisplayAppRecovery.cpp +++ b/src/displayapp/DisplayAppRecovery.cpp @@ -25,7 +25,6 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, Pinetime::Controllers::AlarmController& alarmController, Pinetime::Controllers::TouchHandler& touchHandler) : lcd {lcd}, bleController {bleController} { - } void DisplayApp::Start() { @@ -120,5 +119,4 @@ void DisplayApp::PushMessage(Display::Messages msg) { } void DisplayApp::Register(Pinetime::System::SystemTask* systemTask) { - } diff --git a/src/displayapp/DisplayAppRecovery.h b/src/displayapp/DisplayAppRecovery.h index 86e956d133..3a91b42144 100644 --- a/src/displayapp/DisplayAppRecovery.h +++ b/src/displayapp/DisplayAppRecovery.h @@ -59,7 +59,9 @@ namespace Pinetime { Pinetime::Controllers::AlarmController& alarmController, Pinetime::Controllers::TouchHandler& touchHandler); void Start(); - void Start(Pinetime::System::BootErrors){ Start(); }; + void Start(Pinetime::System::BootErrors) { + Start(); + }; void PushMessage(Pinetime::Applications::Display::Messages msg); void Register(Pinetime::System::SystemTask* systemTask); diff --git a/src/displayapp/DummyLittleVgl.h b/src/displayapp/DummyLittleVgl.h index 47c9e021dc..05355a9730 100644 --- a/src/displayapp/DummyLittleVgl.h +++ b/src/displayapp/DummyLittleVgl.h @@ -20,7 +20,6 @@ namespace Pinetime { LittleVgl& operator=(LittleVgl&&) = delete; void Init() { - } void FlushDisplay(const lv_area_t* area, lv_color_t* color_p) { @@ -33,7 +32,6 @@ namespace Pinetime { void SetNewTapEvent(uint16_t x, uint16_t y) { } void SetNewTouchPoint(uint16_t x, uint16_t y, bool contact) { - } }; } diff --git a/src/displayapp/LittleVgl.cpp b/src/displayapp/LittleVgl.cpp index e7b58c1620..3e38c7665f 100644 --- a/src/displayapp/LittleVgl.cpp +++ b/src/displayapp/LittleVgl.cpp @@ -23,7 +23,6 @@ bool touchpad_read(lv_indev_drv_t* indev_drv, lv_indev_data_t* data) { LittleVgl::LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel) : lcd {lcd}, touchPanel {touchPanel}, previousClick {0, 0} { - } void LittleVgl::Init() { diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp index 29c8affbc6..cdf703ad83 100644 --- a/src/displayapp/screens/ApplicationList.cpp +++ b/src/displayapp/screens/ApplicationList.cpp @@ -57,7 +57,7 @@ std::unique_ptr ApplicationList::CreateScreen2() { {Symbols::paddle, Apps::Paddle}, {"2", Apps::Twos}, {Symbols::chartLine, Apps::Motion}, - {Symbols::drum, Apps::Metronome}, + {Symbols::qrcode, Apps::Qr}, {Symbols::clock, Apps::Alarm}, }}; diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index 1415e8ec0c..447d406081 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -76,11 +76,6 @@ std::unique_ptr Clock::WatchFaceAnalogScreen() { } std::unique_ptr Clock::PineTimeStyleScreen() { - return std::make_unique(app, - dateTimeController, - batteryController, - bleController, - notificatioManager, - settingsController, - motionController); + return std::make_unique( + app, dateTimeController, batteryController, bleController, notificatioManager, settingsController, motionController); } diff --git a/src/displayapp/screens/Error.cpp b/src/displayapp/screens/Error.cpp index 1dbc3447a4..1f2c61d606 100644 --- a/src/displayapp/screens/Error.cpp +++ b/src/displayapp/screens/Error.cpp @@ -9,8 +9,7 @@ namespace { } } -Error::Error(Pinetime::Applications::DisplayApp* app, System::BootErrors error) - : Screen(app) { +Error::Error(Pinetime::Applications::DisplayApp* app, System::BootErrors error) : Screen(app) { lv_obj_t* warningLabel = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(warningLabel, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); diff --git a/src/displayapp/screens/Error.h b/src/displayapp/screens/Error.h index 2316754569..6dbcc38bb8 100644 --- a/src/displayapp/screens/Error.h +++ b/src/displayapp/screens/Error.h @@ -13,6 +13,7 @@ namespace Pinetime { ~Error() override; void ButtonEventHandler(); + private: lv_obj_t* btnOk; }; diff --git a/src/displayapp/screens/FlashLight.cpp b/src/displayapp/screens/FlashLight.cpp index c4d0264320..e7f607eba8 100644 --- a/src/displayapp/screens/FlashLight.cpp +++ b/src/displayapp/screens/FlashLight.cpp @@ -28,7 +28,7 @@ FlashLight::FlashLight(Pinetime::Applications::DisplayApp* app, lv_label_set_text_static(flashLight, Symbols::highlight); lv_obj_align(flashLight, nullptr, LV_ALIGN_CENTER, 0, 0); - for (auto & i : indicators) { + for (auto& i : indicators) { i = lv_obj_create(lv_scr_act(), nullptr); lv_obj_set_size(i, 15, 10); lv_obj_set_style_local_border_width(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, 2); @@ -64,7 +64,7 @@ void FlashLight::SetColors() { if (isOn) { lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); - for (auto & i : indicators) { + for (auto& i : indicators) { lv_obj_set_style_local_bg_color(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); lv_obj_set_style_local_bg_color(i, LV_OBJ_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_WHITE); lv_obj_set_style_local_border_color(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); @@ -72,7 +72,7 @@ void FlashLight::SetColors() { } else { lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); lv_obj_set_style_local_text_color(flashLight, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); - for (auto & i : indicators) { + for (auto& i : indicators) { lv_obj_set_style_local_bg_color(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); lv_obj_set_style_local_bg_color(i, LV_OBJ_PART_MAIN, LV_STATE_DISABLED, LV_COLOR_BLACK); lv_obj_set_style_local_border_color(i, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE); diff --git a/src/displayapp/screens/Metronome.h b/src/displayapp/screens/Metronome.h index 6e6589fedd..8933b17eda 100644 --- a/src/displayapp/screens/Metronome.h +++ b/src/displayapp/screens/Metronome.h @@ -30,7 +30,7 @@ namespace Pinetime { lv_obj_t *bpmArc, *bpmTap, *bpmValue; lv_obj_t *bpbDropdown, *currentBpbText; - lv_obj_t *playPause; + lv_obj_t* playPause; lv_task_t* taskRefresh; }; diff --git a/src/displayapp/screens/Paddle.cpp b/src/displayapp/screens/Paddle.cpp index 608eb64439..a844a0c226 100644 --- a/src/displayapp/screens/Paddle.cpp +++ b/src/displayapp/screens/Paddle.cpp @@ -53,7 +53,7 @@ void Paddle::Refresh() { if (ballX >= LV_HOR_RES - ballSize - 1) { dx *= -1; dy += rand() % 3 - 1; // add a little randomization in wall bounce direction, one of [-1, 0, 1] - if (dy > 5) { // limit dy to be in range [-5 to 5] + if (dy > 5) { // limit dy to be in range [-5 to 5] dy = 5; } if (dy < -5) { diff --git a/src/displayapp/screens/PassKey.cpp b/src/displayapp/screens/PassKey.cpp index 9e43a5415a..d4645ad0ec 100644 --- a/src/displayapp/screens/PassKey.cpp +++ b/src/displayapp/screens/PassKey.cpp @@ -21,4 +21,3 @@ PassKey::PassKey(Pinetime::Applications::DisplayApp* app, uint32_t key) : Screen PassKey::~PassKey() { lv_obj_clean(lv_scr_act()); } - diff --git a/src/displayapp/screens/PineTimeStyle.h b/src/displayapp/screens/PineTimeStyle.h index df8b7d5abb..b7ad24b664 100644 --- a/src/displayapp/screens/PineTimeStyle.h +++ b/src/displayapp/screens/PineTimeStyle.h @@ -36,7 +36,7 @@ namespace Pinetime { void Refresh() override; - void UpdateSelected(lv_obj_t *object, lv_event_t event); + void UpdateSelected(lv_obj_t* object, lv_event_t event); private: char displayedChar[5]; diff --git a/src/displayapp/screens/Qr.cpp b/src/displayapp/screens/Qr.cpp new file mode 100644 index 0000000000..bece46878e --- /dev/null +++ b/src/displayapp/screens/Qr.cpp @@ -0,0 +1,150 @@ +#include +#include "../DisplayApp.h" +#include "../LittleVgl.h" +#include "libs/QR-Code-generator/c/qrcodegen.h" +#include "components/ble/QrService.h" +#include "Qr.h" + +using namespace Pinetime::Applications::Screens; + +static void buttonEventHandler(lv_obj_t* obj, lv_event_t event) { + Qr* screen = static_cast(obj->user_data); + if (screen->showingQrCode == false) { + screen->OnButtonEvent(obj, event); + } +} + +Qr::Qr(Pinetime::Applications::DisplayApp* app, Pinetime::Components::LittleVgl& lvgl, Pinetime::Controllers::QrService& qrService) + : Screen(app), lvgl {lvgl}, qrService(qrService) { + drawQrList(); + taskRefresh = lv_task_create(RefreshTaskCallback, 100, LV_TASK_PRIO_MID, this); +} + +Qr::~Qr() { + lv_task_del(taskRefresh); + lv_obj_clean(lv_scr_act()); +} + +void Qr::Refresh() { + if (qrList != qrService.getQrList()) { + qrList = qrService.getQrList(); + drawQrList(); + showingQrCode = false; + } +} + +bool Qr::OnButtonPushed() { + if (showingQrCode) { + drawQrList(); + showingQrCode = false; + } else { + return false; + } + return true; +} + +bool Qr::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return true; +} + +bool Qr::OnTouchEvent(uint16_t x, uint16_t y) { + return true; +} + +void Qr::drawQrList() { + lv_obj_clean(lv_scr_act()); + // 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_t* container1 = lv_cont_create(lv_scr_act(), nullptr); + + lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); + lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); + lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0); + + lv_obj_set_pos(container1, 0, 0); + lv_obj_set_width(container1, LV_HOR_RES - 15); + lv_obj_set_height(container1, LV_VER_RES); + lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); + + lv_obj_t* labelBt; + + for (uint8_t i = 0; i < MAXLISTITEMS; i++) { + if (qrList[i].text != "") { + + itemApps[i] = lv_btn_create(container1, nullptr); + lv_obj_set_style_local_radius(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 20); + lv_obj_set_style_local_bg_color(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_AQUA); + lv_obj_set_style_local_bg_opa(itemApps[i], LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_20); + lv_obj_set_width(itemApps[i], LV_HOR_RES - 25); + lv_obj_set_height(itemApps[i], 52); + lv_obj_set_event_cb(itemApps[i], buttonEventHandler); + lv_btn_set_layout(itemApps[i], LV_LAYOUT_ROW_MID); + itemApps[i]->user_data = this; + + labelBt = lv_label_create(itemApps[i], nullptr); + lv_label_set_text(labelBt, qrList[i].name.c_str()); + } + } + + lv_obj_t* backgroundLabel = lv_label_create(lv_scr_act(), nullptr); + lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); + lv_obj_set_size(backgroundLabel, LV_HOR_RES, LV_VER_RES); + lv_obj_set_pos(backgroundLabel, 0, 0); + lv_label_set_text_static(backgroundLabel, ""); +} + +void Qr::drawQr(std::string qrText) { + + resetScreen(); + showingQrCode = true; + + bool ok = + qrcodegen_encodeText(qrText.c_str(), tempBuffer, qrcode, qrcodegen_Ecc_HIGH, qrVersionMin, qrVersionMax, qrcodegen_Mask_AUTO, true); + if (ok) { + qrSize = qrcodegen_getSize(qrcode); + qrModuleSize = LV_HOR_RES_MAX / (qrSize + 2 * border); + offset = (LV_HOR_RES_MAX - (qrSize + 2 * border) * qrModuleSize) / 2; + + std::fill(colorBuffer, colorBuffer + colorBufferSize, LV_COLOR_WHITE); + + for (int16_t y = 0; y < qrSize + border * 2; y++) { + for (int16_t x = 0; x < (qrSize + border * 2); x++) { + if (!qrcodegen_getModule(qrcode, x - border, y - border)) { + area.x1 = qrModuleSize * x + offset; + area.y1 = qrModuleSize * y + offset; + area.x2 = qrModuleSize * (x + 1) + offset - 1; + area.y2 = qrModuleSize * (y + 1) + offset - 1; + lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::None); + lvgl.FlushDisplay(&area, colorBuffer); + } + } + } + } +} + +void Qr::resetScreen() { + std::fill(colorBuffer, colorBuffer + colorBufferSize, LV_COLOR_BLACK); + for (uint8_t y = 0; y < (LV_VER_RES_MAX / maxPixelsPerQrModuleSide); y++) { + for (uint8_t x = 0; x < (LV_HOR_RES_MAX / maxPixelsPerQrModuleSide); x++) { + area.x1 = maxPixelsPerQrModuleSide * x; + area.y1 = maxPixelsPerQrModuleSide * y; + area.x2 = maxPixelsPerQrModuleSide * (x + 1) - 1; + area.y2 = maxPixelsPerQrModuleSide * (y + 1) - 1; + lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::None); + lvgl.FlushDisplay(&area, colorBuffer); + } + } +} + +void Qr::OnButtonEvent(lv_obj_t* object, lv_event_t event) { + if (event == LV_EVENT_RELEASED) { + for (int i = 0; i < MAXLISTITEMS; i++) { + if (qrList[i].text != "" && object == itemApps[i]) { + drawQr(qrList[i].text); + return; + } + } + } +} diff --git a/src/displayapp/screens/Qr.h b/src/displayapp/screens/Qr.h new file mode 100644 index 0000000000..aee76cfb83 --- /dev/null +++ b/src/displayapp/screens/Qr.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include +#include +#include "Screen.h" +#include "components/ble/QrService.h" +#include "libs/QR-Code-generator/c/qrcodegen.h" + +#define MAXLISTITEMS 4 + +namespace Pinetime { + namespace Components { + class LittleVgl; + } + namespace Applications { + namespace Screens { + + class Qr : public Screen { + public: + Qr(DisplayApp* app, Pinetime::Components::LittleVgl& lvgl, Pinetime::Controllers::QrService& qrService); + + ~Qr() override; + + void Refresh() override; + + bool OnButtonPushed() override; + + bool OnTouchEvent(TouchEvents event) override; + + bool OnTouchEvent(uint16_t x, uint16_t y) override; + + void drawQrList(); + void drawQr(std::string qrText); + + void resetScreen(); + + void OnButtonEvent(lv_obj_t* object, lv_event_t event); + + bool showingQrCode = false; + + private: + lv_task_t* taskRefresh; + std::array qrList; + lv_obj_t* itemApps[MAXLISTITEMS]; + + Pinetime::Components::LittleVgl& lvgl; + Pinetime::Controllers::QrService& qrService; + + uint8_t qrSize; + uint8_t qrModuleSize; + uint8_t offset; + lv_area_t area; + + static constexpr uint16_t border = 1; + static constexpr uint16_t maxPixelsPerQrModuleSide = LV_HOR_RES_MAX / (21 + 2); + + static constexpr uint8_t colorBufferSize = maxPixelsPerQrModuleSide * maxPixelsPerQrModuleSide; + lv_color_t colorBuffer[colorBufferSize]; + + static constexpr uint8_t qrVersionMin = 1; + static constexpr uint8_t qrVersionMax = 25; + uint8_t qrcode[qrcodegen_BUFFER_LEN_FOR_VERSION(qrVersionMax)]; + uint8_t tempBuffer[qrcodegen_BUFFER_LEN_FOR_VERSION(qrVersionMax)]; + }; + } + } +} diff --git a/src/displayapp/screens/ScreenList.h b/src/displayapp/screens/ScreenList.h index e316e3605b..ad882948de 100644 --- a/src/displayapp/screens/ScreenList.h +++ b/src/displayapp/screens/ScreenList.h @@ -17,8 +17,12 @@ namespace Pinetime { uint8_t initScreen, const std::array()>, N>&& screens, ScreenListModes mode) - : Screen(app), initScreen {initScreen}, screens {std::move(screens)}, mode {mode}, screenIndex{initScreen}, current {this->screens[initScreen]()} { - + : Screen(app), + initScreen {initScreen}, + screens {std::move(screens)}, + mode {mode}, + screenIndex {initScreen}, + current {this->screens[initScreen]()} { } ScreenList(const ScreenList&) = delete; diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index ba764a2e25..b19aced973 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -11,7 +11,8 @@ namespace { } static void event_handler(lv_obj_t* obj, lv_event_t event) { - if (event != LV_EVENT_VALUE_CHANGED) return; + if (event != LV_EVENT_VALUE_CHANGED) + return; Tile* screen = static_cast(obj->user_data); auto* eventDataPtr = (uint32_t*) lv_event_get_data(); @@ -124,7 +125,8 @@ void Tile::UpdateScreen() { } void Tile::OnValueChangedEvent(lv_obj_t* obj, uint32_t buttonId) { - if(obj != btnm1) return; + if (obj != btnm1) + return; app->StartApp(apps[buttonId], DisplayApp::FullRefreshDirections::Up); running = false; diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index f027a74447..49f9a5c64f 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -12,35 +12,33 @@ LV_IMG_DECLARE(bg_clock); using namespace Pinetime::Applications::Screens; namespace { -constexpr int16_t HourLength = 70; -constexpr int16_t MinuteLength = 90; -constexpr int16_t SecondLength = 110; + constexpr int16_t HourLength = 70; + constexpr int16_t MinuteLength = 90; + constexpr int16_t SecondLength = 110; -// sin(90) = 1 so the value of _lv_trigo_sin(90) is the scaling factor -const auto LV_TRIG_SCALE = _lv_trigo_sin(90); + // sin(90) = 1 so the value of _lv_trigo_sin(90) is the scaling factor + const auto LV_TRIG_SCALE = _lv_trigo_sin(90); -int16_t Cosine(int16_t angle) { - return _lv_trigo_sin(angle + 90); -} + int16_t Cosine(int16_t angle) { + return _lv_trigo_sin(angle + 90); + } -int16_t Sine(int16_t angle) { - return _lv_trigo_sin(angle); -} + int16_t Sine(int16_t angle) { + return _lv_trigo_sin(angle); + } -int16_t CoordinateXRelocate(int16_t x) { - return (x + LV_HOR_RES / 2); -} + int16_t CoordinateXRelocate(int16_t x) { + return (x + LV_HOR_RES / 2); + } -int16_t CoordinateYRelocate(int16_t y) { - return std::abs(y - LV_HOR_RES / 2); -} + int16_t CoordinateYRelocate(int16_t y) { + return std::abs(y - LV_HOR_RES / 2); + } -lv_point_t CoordinateRelocate(int16_t radius, int16_t angle) { - return lv_point_t{ - .x = CoordinateXRelocate(radius * static_cast(Sine(angle)) / LV_TRIG_SCALE), - .y = CoordinateYRelocate(radius * static_cast(Cosine(angle)) / LV_TRIG_SCALE) - }; -} + lv_point_t CoordinateRelocate(int16_t radius, int16_t angle) { + return lv_point_t {.x = CoordinateXRelocate(radius * static_cast(Sine(angle)) / LV_TRIG_SCALE), + .y = CoordinateYRelocate(radius * static_cast(Cosine(angle)) / LV_TRIG_SCALE)}; + } } diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp index 4d9eaf3722..88612ca564 100644 --- a/src/displayapp/screens/WatchFaceDigital.cpp +++ b/src/displayapp/screens/WatchFaceDigital.cpp @@ -197,9 +197,11 @@ void WatchFaceDigital::Refresh() { if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) { - lv_label_set_text_fmt(label_date, "%s %d %s %d", dateTimeController.DayOfWeekShortToString(), day, dateTimeController.MonthShortToString(), year); + lv_label_set_text_fmt( + label_date, "%s %d %s %d", dateTimeController.DayOfWeekShortToString(), day, dateTimeController.MonthShortToString(), year); } else { - lv_label_set_text_fmt(label_date, "%s %s %d %d", dateTimeController.DayOfWeekShortToString(), dateTimeController.MonthShortToString(), day, year); + lv_label_set_text_fmt( + label_date, "%s %s %d %d", dateTimeController.DayOfWeekShortToString(), dateTimeController.MonthShortToString(), day, year); } lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_CENTER, 0, 60); diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index 5d3a98342a..beeaa22816 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -46,7 +46,7 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, static constexpr uint8_t barHeight = 20 + innerDistance; static constexpr uint8_t buttonHeight = (LV_VER_RES_MAX - barHeight - innerDistance) / 2; static constexpr uint8_t buttonWidth = (LV_HOR_RES_MAX - innerDistance) / 2; // wide buttons - //static constexpr uint8_t buttonWidth = buttonHeight; // square buttons + // static constexpr uint8_t buttonWidth = buttonHeight; // square buttons static constexpr uint8_t buttonXOffset = (LV_HOR_RES_MAX - buttonWidth * 2 - innerDistance) / 2; lv_style_init(&btn_style); @@ -69,7 +69,7 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, lv_obj_set_event_cb(btn2, ButtonEventHandler); lv_obj_add_style(btn2, LV_BTN_PART_MAIN, &btn_style); lv_obj_set_size(btn2, buttonWidth, buttonHeight); - lv_obj_align(btn2, nullptr, LV_ALIGN_IN_TOP_RIGHT, - buttonXOffset, barHeight); + lv_obj_align(btn2, nullptr, LV_ALIGN_IN_TOP_RIGHT, -buttonXOffset, barHeight); lv_obj_t* lbl_btn; lbl_btn = lv_label_create(btn2, nullptr); @@ -100,7 +100,7 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, lv_obj_set_event_cb(btn4, ButtonEventHandler); lv_obj_add_style(btn4, LV_BTN_PART_MAIN, &btn_style); lv_obj_set_size(btn4, buttonWidth, buttonHeight); - lv_obj_align(btn4, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, - buttonXOffset, 0); + lv_obj_align(btn4, nullptr, LV_ALIGN_IN_BOTTOM_RIGHT, -buttonXOffset, 0); lbl_btn = lv_label_create(btn4, nullptr); lv_obj_set_style_local_text_font(lbl_btn, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &lv_font_sys_48); diff --git a/src/displayapp/screens/settings/SettingDisplay.cpp b/src/displayapp/screens/settings/SettingDisplay.cpp index 9e972afcef..876880da89 100644 --- a/src/displayapp/screens/settings/SettingDisplay.cpp +++ b/src/displayapp/screens/settings/SettingDisplay.cpp @@ -46,7 +46,7 @@ SettingDisplay::SettingDisplay(Pinetime::Applications::DisplayApp* app, Pinetime char buffer[12]; for (unsigned int i = 0; i < options.size(); i++) { cbOption[i] = lv_checkbox_create(container1, nullptr); - sprintf(buffer, "%3d seconds", options[i] / 1000); + sprintf(buffer, "%3d seconds", options[i] / 1000); lv_checkbox_set_text(cbOption[i], buffer); cbOption[i]->user_data = this; lv_obj_set_event_cb(cbOption[i], event_handler); diff --git a/src/displayapp/screens/settings/SettingSetDate.cpp b/src/displayapp/screens/settings/SettingSetDate.cpp index 8bfded3490..cf8c4ee894 100644 --- a/src/displayapp/screens/settings/SettingSetDate.cpp +++ b/src/displayapp/screens/settings/SettingSetDate.cpp @@ -15,23 +15,22 @@ namespace { constexpr int16_t POS_Y_TEXT = -6; constexpr int16_t POS_Y_MINUS = 40; - void event_handler(lv_obj_t * obj, lv_event_t event) { - auto* screen = static_cast(obj->user_data); + void event_handler(lv_obj_t* obj, lv_event_t event) { + auto* screen = static_cast(obj->user_data); screen->HandleButtonPress(obj, event); } } -SettingSetDate::SettingSetDate(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::DateTime &dateTimeController) : - Screen(app), - dateTimeController {dateTimeController} { - lv_obj_t * title = lv_label_create(lv_scr_act(), nullptr); +SettingSetDate::SettingSetDate(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::DateTime& dateTimeController) + : Screen(app), dateTimeController {dateTimeController} { + lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text_static(title, "Set current date"); lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 15); - lv_obj_t * icon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); - + lv_label_set_text_static(icon, Symbols::clock); lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); @@ -113,7 +112,7 @@ SettingSetDate::~SettingSetDate() { lv_obj_clean(lv_scr_act()); } -void SettingSetDate::HandleButtonPress(lv_obj_t *object, lv_event_t event) { +void SettingSetDate::HandleButtonPress(lv_obj_t* object, lv_event_t event) { if (event != LV_EVENT_CLICKED) return; diff --git a/src/displayapp/screens/settings/SettingSetTime.cpp b/src/displayapp/screens/settings/SettingSetTime.cpp index 5351adebae..5916c0286e 100644 --- a/src/displayapp/screens/settings/SettingSetTime.cpp +++ b/src/displayapp/screens/settings/SettingSetTime.cpp @@ -16,23 +16,22 @@ namespace { constexpr int16_t POS_Y_MINUS = 40; constexpr int16_t OFS_Y_COLON = -2; - void event_handler(lv_obj_t * obj, lv_event_t event) { - auto* screen = static_cast(obj->user_data); + void event_handler(lv_obj_t* obj, lv_event_t event) { + auto* screen = static_cast(obj->user_data); screen->HandleButtonPress(obj, event); } } -SettingSetTime::SettingSetTime(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::DateTime &dateTimeController) : - Screen(app), - dateTimeController {dateTimeController} { - lv_obj_t * title = lv_label_create(lv_scr_act(), nullptr); +SettingSetTime::SettingSetTime(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::DateTime& dateTimeController) + : Screen(app), dateTimeController {dateTimeController} { + lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text_static(title, "Set current time"); lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 15); - lv_obj_t * icon = lv_label_create(lv_scr_act(), nullptr); + lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); - + lv_label_set_text_static(icon, Symbols::clock); lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); @@ -45,7 +44,7 @@ SettingSetTime::SettingSetTime(Pinetime::Applications::DisplayApp *app, Pinetime lv_obj_align(lblHours, lv_scr_act(), LV_ALIGN_CENTER, POS_X_HOURS, POS_Y_TEXT); lv_obj_set_auto_realign(lblHours, true); - lv_obj_t * lblColon1 = lv_label_create(lv_scr_act(), nullptr); + lv_obj_t* lblColon1 = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(lblColon1, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); lv_label_set_text_static(lblColon1, ":"); lv_label_set_align(lblColon1, LV_LABEL_ALIGN_CENTER); @@ -59,13 +58,13 @@ SettingSetTime::SettingSetTime(Pinetime::Applications::DisplayApp *app, Pinetime lv_obj_align(lblMinutes, lv_scr_act(), LV_ALIGN_CENTER, POS_X_MINUTES, POS_Y_TEXT); lv_obj_set_auto_realign(lblMinutes, true); - lv_obj_t * lblColon2 = lv_label_create(lv_scr_act(), nullptr); + lv_obj_t* lblColon2 = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(lblColon2, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); lv_label_set_text_static(lblColon2, ":"); lv_label_set_align(lblColon2, LV_LABEL_ALIGN_CENTER); lv_obj_align(lblColon2, lv_scr_act(), LV_ALIGN_CENTER, (POS_X_MINUTES + POS_X_SECONDS) / 2, POS_Y_TEXT + OFS_Y_COLON); - lv_obj_t * lblSeconds = lv_label_create(lv_scr_act(), nullptr); + lv_obj_t* lblSeconds = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(lblSeconds, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42); lv_label_set_text_static(lblSeconds, "00"); lv_label_set_align(lblSeconds, LV_LABEL_ALIGN_CENTER); @@ -111,7 +110,7 @@ SettingSetTime::~SettingSetTime() { lv_obj_clean(lv_scr_act()); } -void SettingSetTime::HandleButtonPress(lv_obj_t *object, lv_event_t event) { +void SettingSetTime::HandleButtonPress(lv_obj_t* object, lv_event_t event) { if (event != LV_EVENT_CLICKED) return; diff --git a/src/displayapp/screens/settings/SettingShakeThreshold.cpp b/src/displayapp/screens/settings/SettingShakeThreshold.cpp index 1791b550e7..cbcbadc019 100644 --- a/src/displayapp/screens/settings/SettingShakeThreshold.cpp +++ b/src/displayapp/screens/settings/SettingShakeThreshold.cpp @@ -64,9 +64,9 @@ SettingShakeThreshold::SettingShakeThreshold(DisplayApp* app, vDecay = xTaskGetTickCount(); calibrating = false; EnableForCal = false; - if(!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake)){ + if (!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake)) { EnableForCal = true; - settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::Shake,true); + settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::Shake, true); } refreshTask = lv_task_create(RefreshTaskCallback, LV_DISP_DEF_REFR_PERIOD, LV_TASK_PRIO_MID, this); } @@ -74,8 +74,8 @@ SettingShakeThreshold::SettingShakeThreshold(DisplayApp* app, SettingShakeThreshold::~SettingShakeThreshold() { settingsController.SetShakeThreshold(lv_arc_get_value(positionArc)); - if(EnableForCal){ - settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::Shake,false); + if (EnableForCal) { + settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::Shake, false); EnableForCal = false; } lv_task_del(refreshTask); diff --git a/src/displayapp/screens/settings/SettingShakeThreshold.h b/src/displayapp/screens/settings/SettingShakeThreshold.h index b9ddd8b428..9c0f4ccc0d 100644 --- a/src/displayapp/screens/settings/SettingShakeThreshold.h +++ b/src/displayapp/screens/settings/SettingShakeThreshold.h @@ -27,8 +27,8 @@ namespace Pinetime { System::SystemTask& systemTask; uint8_t calibrating; bool EnableForCal; - uint32_t vDecay,vCalTime; - lv_obj_t *positionArc, *animArc,*calButton, *calLabel; + uint32_t vDecay, vCalTime; + lv_obj_t *positionArc, *animArc, *calButton, *calLabel; lv_task_t* refreshTask; }; } diff --git a/src/displayapp/screens/settings/SettingSteps.cpp b/src/displayapp/screens/settings/SettingSteps.cpp index 5ca3eecd12..e92600c2c7 100644 --- a/src/displayapp/screens/settings/SettingSteps.cpp +++ b/src/displayapp/screens/settings/SettingSteps.cpp @@ -12,15 +12,12 @@ namespace { } } -SettingSteps::SettingSteps( - Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::Settings &settingsController) : - Screen(app), - settingsController{settingsController} -{ +SettingSteps::SettingSteps(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) + : Screen(app), settingsController {settingsController} { - 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)); lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); lv_obj_set_style_local_pad_all(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 10); lv_obj_set_style_local_pad_inner(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5); @@ -31,13 +28,13 @@ SettingSteps::SettingSteps( lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT); lv_obj_t* title = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text_static(title,"Daily steps goal"); + lv_label_set_text_static(title, "Daily steps goal"); lv_label_set_align(title, LV_LABEL_ALIGN_CENTER); lv_obj_align(title, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 15, 15); lv_obj_t* icon = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_color(icon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE); - + lv_label_set_text_static(icon, Symbols::shoe); lv_label_set_align(icon, LV_LABEL_ALIGN_CENTER); lv_obj_align(icon, title, LV_ALIGN_OUT_LEFT_MID, -10, 0); @@ -61,7 +58,6 @@ SettingSteps::SettingSteps( lv_obj_set_event_cb(btnMinus, event_handler); lv_obj_align(btnMinus, lv_scr_act(), LV_ALIGN_CENTER, -55, 80); lv_obj_set_style_local_value_str(btnMinus, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, "-"); - } SettingSteps::~SettingSteps() { @@ -69,24 +65,23 @@ SettingSteps::~SettingSteps() { settingsController.SaveSettings(); } -void SettingSteps::UpdateSelected(lv_obj_t *object, lv_event_t event) { +void SettingSteps::UpdateSelected(lv_obj_t* object, lv_event_t event) { uint32_t value = settingsController.GetStepsGoal(); - if(object == btnPlus && (event == LV_EVENT_PRESSED)) { + if (object == btnPlus && (event == LV_EVENT_PRESSED)) { value += 1000; - if ( value <= 500000 ) { + if (value <= 500000) { settingsController.SetStepsGoal(value); lv_label_set_text_fmt(stepValue, "%lu", settingsController.GetStepsGoal()); lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_CENTER, 0, -10); } } - if(object == btnMinus && (event == LV_EVENT_PRESSED)) { + if (object == btnMinus && (event == LV_EVENT_PRESSED)) { value -= 1000; - if ( value >= 1000 ) { + if (value >= 1000) { settingsController.SetStepsGoal(value); lv_label_set_text_fmt(stepValue, "%lu", settingsController.GetStepsGoal()); lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_CENTER, 0, -10); } } - } diff --git a/src/displayapp/screens/settings/Settings.cpp b/src/displayapp/screens/settings/Settings.cpp index 7bc90b4704..3f99288040 100644 --- a/src/displayapp/screens/settings/Settings.cpp +++ b/src/displayapp/screens/settings/Settings.cpp @@ -57,12 +57,10 @@ std::unique_ptr Settings::CreateScreen2() { std::unique_ptr Settings::CreateScreen3() { - std::array applications {{ - {Symbols::clock, "Chimes", Apps::SettingChimes}, - {Symbols::tachometer, "Shake Calib.", Apps::SettingShakeThreshold}, - {Symbols::check, "Firmware", Apps::FirmwareValidation}, - {Symbols::list, "About", Apps::SysInfo} - }}; + std::array applications {{{Symbols::clock, "Chimes", Apps::SettingChimes}, + {Symbols::tachometer, "Shake Calib.", Apps::SettingShakeThreshold}, + {Symbols::check, "Firmware", Apps::FirmwareValidation}, + {Symbols::list, "About", Apps::SysInfo}}}; return std::make_unique(2, 3, app, settingsController, applications); } diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp index 2f60f42fe5..539cc8d1d3 100644 --- a/src/drivers/Bma421.cpp +++ b/src/drivers/Bma421.cpp @@ -42,10 +42,16 @@ void Bma421::Init() { if (ret != BMA4_OK) return; - switch(bma.chip_id) { - case BMA423_CHIP_ID: deviceType = DeviceTypes::BMA421; break; - case BMA425_CHIP_ID: deviceType = DeviceTypes::BMA425; break; - default: deviceType = DeviceTypes::Unknown; break; + switch (bma.chip_id) { + case BMA423_CHIP_ID: + deviceType = DeviceTypes::BMA421; + break; + case BMA425_CHIP_ID: + deviceType = DeviceTypes::BMA425; + break; + default: + deviceType = DeviceTypes::Unknown; + break; } ret = bma423_write_config_file(&bma); diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp index e9573df1b0..cf10c895f5 100644 --- a/src/drivers/Cst816s.cpp +++ b/src/drivers/Cst816s.cpp @@ -80,14 +80,9 @@ Cst816S::TouchInfos Cst816S::GetTouchInfo() { Gestures gesture = static_cast(touchData[gestureIndex]); // Validity check - if(x >= maxX || y >= maxY || - (gesture != Gestures::None && - gesture != Gestures::SlideDown && - gesture != Gestures::SlideUp && - gesture != Gestures::SlideLeft && - gesture != Gestures::SlideRight && - gesture != Gestures::SingleTap && - gesture != Gestures::DoubleTap && + if (x >= maxX || y >= maxY || + (gesture != Gestures::None && gesture != Gestures::SlideDown && gesture != Gestures::SlideUp && gesture != Gestures::SlideLeft && + gesture != Gestures::SlideRight && gesture != Gestures::SingleTap && gesture != Gestures::DoubleTap && gesture != Gestures::LongPress)) { info.isValid = false; return info; diff --git a/src/drivers/Cst816s.h b/src/drivers/Cst816s.h index 4a548d45e3..9d426c9db9 100644 --- a/src/drivers/Cst816s.h +++ b/src/drivers/Cst816s.h @@ -44,21 +44,22 @@ namespace Pinetime { uint8_t GetFwVersion() const { return fwVersion; } + private: bool CheckDeviceIds(); // Unused/Unavailable commented out static constexpr uint8_t gestureIndex = 1; static constexpr uint8_t touchPointNumIndex = 2; - //static constexpr uint8_t touchEventIndex = 3; + // static constexpr uint8_t touchEventIndex = 3; static constexpr uint8_t touchXHighIndex = 3; static constexpr uint8_t touchXLowIndex = 4; - //static constexpr uint8_t touchIdIndex = 5; + // static constexpr uint8_t touchIdIndex = 5; static constexpr uint8_t touchYHighIndex = 5; static constexpr uint8_t touchYLowIndex = 6; - //static constexpr uint8_t touchStep = 6; - //static constexpr uint8_t touchXYIndex = 7; - //static constexpr uint8_t touchMiscIndex = 8; + // static constexpr uint8_t touchStep = 6; + // static constexpr uint8_t touchXYIndex = 7; + // static constexpr uint8_t touchMiscIndex = 8; static constexpr uint8_t maxX = 240; static constexpr uint8_t maxY = 240; diff --git a/src/drivers/PinMap.h b/src/drivers/PinMap.h index 579bf38a85..167a87715d 100644 --- a/src/drivers/PinMap.h +++ b/src/drivers/PinMap.h @@ -3,18 +3,18 @@ namespace Pinetime { namespace PinMap { - - #ifdef WATCH_P8 - // COLMI P8 - static constexpr uint8_t Charging = 19; - static constexpr uint8_t Cst816sReset = 13; - static constexpr uint8_t Button = 17; - #else - // Pinetime - static constexpr uint8_t Charging = 12; - static constexpr uint8_t Cst816sReset = 10; - static constexpr uint8_t Button = 13; - #endif + +#ifdef WATCH_P8 + // COLMI P8 + static constexpr uint8_t Charging = 19; + static constexpr uint8_t Cst816sReset = 13; + static constexpr uint8_t Button = 17; +#else + // Pinetime + static constexpr uint8_t Charging = 12; + static constexpr uint8_t Cst816sReset = 10; + static constexpr uint8_t Button = 13; +#endif static constexpr uint8_t Cst816sIrq = 28; static constexpr uint8_t PowerPresent = 19; diff --git a/src/drivers/SpiMaster.cpp b/src/drivers/SpiMaster.cpp index 747dbc84a4..38f72fee62 100644 --- a/src/drivers/SpiMaster.cpp +++ b/src/drivers/SpiMaster.cpp @@ -10,7 +10,7 @@ SpiMaster::SpiMaster(const SpiMaster::SpiModule spi, const SpiMaster::Parameters } bool SpiMaster::Init() { - if(mutex == nullptr) { + if (mutex == nullptr) { mutex = xSemaphoreCreateBinary(); ASSERT(mutex != nullptr); } diff --git a/src/drivers/TwiMaster.cpp b/src/drivers/TwiMaster.cpp index 9b456d5f00..25d23c28ce 100644 --- a/src/drivers/TwiMaster.cpp +++ b/src/drivers/TwiMaster.cpp @@ -13,19 +13,13 @@ TwiMaster::TwiMaster(NRF_TWIM_Type* module, uint32_t frequency, uint8_t pinSda, } void TwiMaster::ConfigurePins() const { - NRF_GPIO->PIN_CNF[pinScl] = - (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | - (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | - (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | - (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | - (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); - - NRF_GPIO->PIN_CNF[pinSda] = - (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | - (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | - (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | - (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | - (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + NRF_GPIO->PIN_CNF[pinScl] = (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | + (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); + + NRF_GPIO->PIN_CNF[pinSda] = (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | + (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | + (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos); } void TwiMaster::Init() { diff --git a/src/heartratetask/HeartRateTask.cpp b/src/heartratetask/HeartRateTask.cpp index 213ab4a7e3..3dbfb53072 100644 --- a/src/heartratetask/HeartRateTask.cpp +++ b/src/heartratetask/HeartRateTask.cpp @@ -6,7 +6,7 @@ using namespace Pinetime::Applications; HeartRateTask::HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller) - : heartRateSensor {heartRateSensor}, controller {controller}, ppg{} { + : heartRateSensor {heartRateSensor}, controller {controller}, ppg {} { } void HeartRateTask::Start() { diff --git a/src/libs/QR-Code-generator b/src/libs/QR-Code-generator new file mode 160000 index 0000000000..2fc287904a --- /dev/null +++ b/src/libs/QR-Code-generator @@ -0,0 +1 @@ +Subproject commit 2fc287904a8c2f2cb504c5710ee58684dd2bf697 diff --git a/src/systemtask/Messages.h b/src/systemtask/Messages.h index 4d5ab4ced1..ff618b80c9 100644 --- a/src/systemtask/Messages.h +++ b/src/systemtask/Messages.h @@ -2,35 +2,35 @@ namespace Pinetime { namespace System { - enum class Messages { - GoToSleep, - GoToRunning, - TouchWakeUp, - OnNewTime, - OnNewNotification, - OnTimerDone, - OnNewCall, - BleConnected, - UpdateTimeOut, - BleFirmwareUpdateStarted, - BleFirmwareUpdateFinished, - OnTouchEvent, - HandleButtonEvent, - HandleButtonTimerEvent, - OnDisplayTaskSleeping, - EnableSleeping, - DisableSleeping, - OnNewDay, - OnNewHour, - OnNewHalfHour, - OnChargingEvent, - OnPairing, - SetOffAlarm, - StopRinging, - MeasureBatteryTimerExpired, - BatteryPercentageUpdated, - StartFileTransfer, - StopFileTransfer, - }; - } + enum class Messages { + GoToSleep, + GoToRunning, + TouchWakeUp, + OnNewTime, + OnNewNotification, + OnTimerDone, + OnNewCall, + BleConnected, + UpdateTimeOut, + BleFirmwareUpdateStarted, + BleFirmwareUpdateFinished, + OnTouchEvent, + HandleButtonEvent, + HandleButtonTimerEvent, + OnDisplayTaskSleeping, + EnableSleeping, + DisableSleeping, + OnNewDay, + OnNewHour, + OnNewHalfHour, + OnChargingEvent, + OnPairing, + SetOffAlarm, + StopRinging, + MeasureBatteryTimerExpired, + BatteryPercentageUpdated, + StartFileTransfer, + StopFileTransfer, + }; + } } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 94d40c997d..d61f69a1f3 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -405,7 +405,8 @@ void SystemTask::Work() { break; case Messages::OnNewHour: using Pinetime::Controllers::AlarmController; - if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours && alarmController.State() != AlarmController::AlarmState::Alerting) { + if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours && + alarmController.State() != AlarmController::AlarmState::Alerting) { if (isSleeping && !isWakingUp) { GoToRunning(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::Clock); @@ -415,7 +416,8 @@ void SystemTask::Work() { break; case Messages::OnNewHalfHour: using Pinetime::Controllers::AlarmController; - if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours && alarmController.State() != AlarmController::AlarmState::Alerting) { + if (settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours && + alarmController.State() != AlarmController::AlarmState::Alerting) { if (isSleeping && !isWakingUp) { GoToRunning(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::Clock);