Merge remote-tracking branch 'upstream/develop' into pinetimestyle-colorpicker
This commit is contained in:
commit
db99ac88d9
|
@ -1,4 +1,5 @@
|
||||||
Checks: '*,
|
Checks: '*,
|
||||||
|
-altera-unroll-loops,
|
||||||
-llvmlibc-callee-namespace,
|
-llvmlibc-callee-namespace,
|
||||||
-llvm-header-guard,
|
-llvm-header-guard,
|
||||||
-llvm-namespace-comment,
|
-llvm-namespace-comment,
|
||||||
|
@ -14,15 +15,18 @@ Checks: '*,
|
||||||
-cppcoreguidelines-avoid-magic-numbers,
|
-cppcoreguidelines-avoid-magic-numbers,
|
||||||
-cppcoreguidelines-avoid-non-const-global-variables,
|
-cppcoreguidelines-avoid-non-const-global-variables,
|
||||||
-cppcoreguidelines-avoid-c-arrays,
|
-cppcoreguidelines-avoid-c-arrays,
|
||||||
|
-cppcoreguidelines-special-member-functions,
|
||||||
-readability-magic-numbers,
|
-readability-magic-numbers,
|
||||||
-readability-uppercase-literal-suffix,
|
-readability-uppercase-literal-suffix,
|
||||||
-modernize-use-trailing-return-type,
|
-modernize-use-trailing-return-type,
|
||||||
-modernize-avoid-c-arrays,
|
-modernize-avoid-c-arrays,
|
||||||
-hicpp-signed-bitwise,
|
|
||||||
-hicpp-no-assembler,
|
|
||||||
-hicpp-avoid-c-arrays,
|
-hicpp-avoid-c-arrays,
|
||||||
-hicpp-uppercase-literal-suffix,
|
-hicpp-uppercase-literal-suffix,
|
||||||
|
-hicpp-vararg,
|
||||||
|
-hicpp-no-assembler,
|
||||||
-hicpp-no-array-decay,
|
-hicpp-no-array-decay,
|
||||||
|
-hicpp-signed-bitwise,
|
||||||
|
-hicpp-special-member-functions,
|
||||||
-cert-err58-cpp,
|
-cert-err58-cpp,
|
||||||
-cert-err60-cpp'
|
-cert-err60-cpp'
|
||||||
CheckOptions:
|
CheckOptions:
|
||||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -1,3 +1,6 @@
|
||||||
[submodule "src/libs/lvgl"]
|
[submodule "src/libs/lvgl"]
|
||||||
path = src/libs/lvgl
|
path = src/libs/lvgl
|
||||||
url = https://github.com/joaquimorg/lvgl.git
|
url = https://github.com/joaquimorg/lvgl.git
|
||||||
|
[submodule "src/libs/littlefs"]
|
||||||
|
path = src/libs/littlefs
|
||||||
|
url = https://github.com/littlefs-project/littlefs.git
|
||||||
|
|
|
@ -12,6 +12,29 @@
|
||||||
<option name="SPACE_BEFORE_REFERENCE_IN_DECLARATION" value="false" />
|
<option name="SPACE_BEFORE_REFERENCE_IN_DECLARATION" value="false" />
|
||||||
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
|
||||||
</Objective-C>
|
</Objective-C>
|
||||||
|
<Objective-C-extensions>
|
||||||
|
<rules>
|
||||||
|
<rule entity="NAMESPACE" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="MACRO" visibility="ANY" specifier="ANY" prefix="" style="SCREAMING_SNAKE_CASE" suffix="" />
|
||||||
|
<rule entity="CLASS" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="STRUCT" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="ENUM" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="ENUMERATOR" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="TYPEDEF" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="UNION" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="CLASS_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="STRUCT_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="CLASS_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="STRUCT_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="GLOBAL_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" />
|
||||||
|
<rule entity="GLOBAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="PARAMETER" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
<rule entity="LOCAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="CAMEL_CASE" suffix="" />
|
||||||
|
</rules>
|
||||||
|
</Objective-C-extensions>
|
||||||
|
<clangFormatSettings>
|
||||||
|
<option name="ENABLED" value="true" />
|
||||||
|
</clangFormatSettings>
|
||||||
<codeStyleSettings language="ObjectiveC">
|
<codeStyleSettings language="ObjectiveC">
|
||||||
<option name="RIGHT_MARGIN" value="140" />
|
<option name="RIGHT_MARGIN" value="140" />
|
||||||
<option name="IF_BRACE_FORCE" value="3" />
|
<option name="IF_BRACE_FORCE" value="3" />
|
||||||
|
|
|
@ -53,6 +53,7 @@ As of now, here is the list of achievements of this project:
|
||||||
* Two (2048 clone game)
|
* Two (2048 clone game)
|
||||||
* Stopwatch (with all the necessary functions such as play, pause, lap, stop)
|
* Stopwatch (with all the necessary functions such as play, pause, lap, stop)
|
||||||
* Motion sensor and step counter (displays the number of steps and the state of the motion sensor in real-time)
|
* Motion sensor and step counter (displays the number of steps and the state of the motion sensor in real-time)
|
||||||
|
* Metronome (vibrates to a given bpm with a customizable beats per bar)
|
||||||
- User settings:
|
- User settings:
|
||||||
* Display timeout
|
* Display timeout
|
||||||
* Wake-up condition
|
* Wake-up condition
|
||||||
|
|
|
@ -27,7 +27,7 @@ CMake configures the project according to variables you specify the command line
|
||||||
**NRFJPROG**|Path to the NRFJProg executable. Used only if `USE_JLINK` is 1.|`-DNRFJPROG=/opt/nrfjprog/nrfjprog`
|
**NRFJPROG**|Path to the NRFJProg executable. Used only if `USE_JLINK` is 1.|`-DNRFJPROG=/opt/nrfjprog/nrfjprog`
|
||||||
**GDB_CLIENT_BIN_PATH**|Path to arm-none-eabi-gdb executable. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_BIN_PATH=/home/jf/nrf52/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-gdb`
|
**GDB_CLIENT_BIN_PATH**|Path to arm-none-eabi-gdb executable. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_BIN_PATH=/home/jf/nrf52/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-gdb`
|
||||||
**GDB_CLIENT_TARGET_REMOTE**|Target remote connection string. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_TARGET_REMOTE=/dev/ttyACM0`
|
**GDB_CLIENT_TARGET_REMOTE**|Target remote connection string. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_TARGET_REMOTE=/dev/ttyACM0`
|
||||||
**BUILD_DFU (\*\*)**|Build DFU files while building (needs [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil)).|`-BUILD_DFU=1`
|
**BUILD_DFU (\*\*)**|Build DFU files while building (needs [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil)).|`-DBUILD_DFU=1`
|
||||||
|
|
||||||
####(**) Note about **CMAKE_BUILD_TYPE**:
|
####(**) Note about **CMAKE_BUILD_TYPE**:
|
||||||
By default, this variable is set to *Release*. It compiles the code with size and speed optimizations. We use this value for all the binaries we publish when we [release](https://github.com/JF002/InfiniTime/releases) new versions of InfiniTime.
|
By default, this variable is set to *Release*. It compiles the code with size and speed optimizations. We use this value for all the binaries we publish when we [release](https://github.com/JF002/InfiniTime/releases) new versions of InfiniTime.
|
||||||
|
|
|
@ -166,6 +166,13 @@ set(NIMBLE_SRC
|
||||||
libs/mynewt-nimble/nimble/host/util/src/addr.c
|
libs/mynewt-nimble/nimble/host/util/src/addr.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(LITTLEFS_SRC
|
||||||
|
libs/littlefs/lfs_util.h
|
||||||
|
libs/littlefs/lfs.h
|
||||||
|
libs/littlefs/lfs_util.c
|
||||||
|
libs/littlefs/lfs.c
|
||||||
|
)
|
||||||
|
|
||||||
set(LVGL_SRC
|
set(LVGL_SRC
|
||||||
libs/lv_conf.h
|
libs/lv_conf.h
|
||||||
libs/lvgl/lvgl.h
|
libs/lvgl/lvgl.h
|
||||||
|
@ -466,6 +473,7 @@ list(APPEND SOURCE_FILES
|
||||||
components/motor/MotorController.cpp
|
components/motor/MotorController.cpp
|
||||||
components/settings/Settings.cpp
|
components/settings/Settings.cpp
|
||||||
components/timer/TimerController.cpp
|
components/timer/TimerController.cpp
|
||||||
|
components/fs/FS.cpp
|
||||||
drivers/Cst816s.cpp
|
drivers/Cst816s.cpp
|
||||||
FreeRTOS/port.c
|
FreeRTOS/port.c
|
||||||
FreeRTOS/port_cmsis_systick.c
|
FreeRTOS/port_cmsis_systick.c
|
||||||
|
@ -544,6 +552,7 @@ list(APPEND RECOVERY_SOURCE_FILES
|
||||||
components/heartrate/Biquad.cpp
|
components/heartrate/Biquad.cpp
|
||||||
components/heartrate/Ptagc.cpp
|
components/heartrate/Ptagc.cpp
|
||||||
components/motor/MotorController.cpp
|
components/motor/MotorController.cpp
|
||||||
|
components/fs/FS.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND RECOVERYLOADER_SOURCE_FILES
|
list(APPEND RECOVERYLOADER_SOURCE_FILES
|
||||||
|
@ -802,13 +811,25 @@ target_compile_options(lvgl PRIVATE
|
||||||
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -x assembler-with-cpp>
|
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -x assembler-with-cpp>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# LITTLEFS_SRC
|
||||||
|
add_library(littlefs STATIC ${LITTLEFS_SRC})
|
||||||
|
target_include_directories(littlefs SYSTEM PUBLIC . ../)
|
||||||
|
target_include_directories(littlefs SYSTEM PUBLIC ${INCLUDES_FROM_LIBS})
|
||||||
|
target_compile_options(littlefs PRIVATE
|
||||||
|
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Wno-unused-function -Og -g3>
|
||||||
|
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Wno-unused-function -Os>
|
||||||
|
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Wno-unused-function -Og -g3 -fno-rtti>
|
||||||
|
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Wno-unused-function -Os -fno-rtti>
|
||||||
|
$<$<COMPILE_LANGUAGE:ASM>: -MP -MD -x assembler-with-cpp>
|
||||||
|
)
|
||||||
|
|
||||||
# Build autonomous binary (without support for bootloader)
|
# Build autonomous binary (without support for bootloader)
|
||||||
set(EXECUTABLE_NAME "pinetime-app")
|
set(EXECUTABLE_NAME "pinetime-app")
|
||||||
set(EXECUTABLE_FILE_NAME ${EXECUTABLE_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
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")
|
set(NRF5_LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/gcc_nrf52.ld")
|
||||||
add_executable(${EXECUTABLE_NAME} ${SOURCE_FILES})
|
add_executable(${EXECUTABLE_NAME} ${SOURCE_FILES})
|
||||||
set_target_properties(${EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_FILE_NAME})
|
set_target_properties(${EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_FILE_NAME})
|
||||||
target_link_libraries(${EXECUTABLE_NAME} nimble nrf-sdk lvgl)
|
target_link_libraries(${EXECUTABLE_NAME} nimble nrf-sdk lvgl littlefs)
|
||||||
target_compile_options(${EXECUTABLE_NAME} PUBLIC
|
target_compile_options(${EXECUTABLE_NAME} PUBLIC
|
||||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -g3>
|
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -g3>
|
||||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Os>
|
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:RELEASE>>: ${COMMON_FLAGS} -Os>
|
||||||
|
@ -837,7 +858,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(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")
|
set(NRF5_LINKER_SCRIPT_MCUBOOT "${CMAKE_SOURCE_DIR}/gcc_nrf52-mcuboot.ld")
|
||||||
add_executable(${EXECUTABLE_MCUBOOT_NAME} ${SOURCE_FILES})
|
add_executable(${EXECUTABLE_MCUBOOT_NAME} ${SOURCE_FILES})
|
||||||
target_link_libraries(${EXECUTABLE_MCUBOOT_NAME} nimble nrf-sdk lvgl)
|
target_link_libraries(${EXECUTABLE_MCUBOOT_NAME} nimble nrf-sdk lvgl littlefs)
|
||||||
set_target_properties(${EXECUTABLE_MCUBOOT_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_MCUBOOT_FILE_NAME})
|
set_target_properties(${EXECUTABLE_MCUBOOT_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_MCUBOOT_FILE_NAME})
|
||||||
target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC
|
target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC
|
||||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -g3>
|
$<$<AND:$<COMPILE_LANGUAGE:C>,$<CONFIG:DEBUG>>: ${COMMON_FLAGS} -Og -g3>
|
||||||
|
@ -873,7 +894,7 @@ endif()
|
||||||
set(EXECUTABLE_RECOVERY_NAME "pinetime-recovery")
|
set(EXECUTABLE_RECOVERY_NAME "pinetime-recovery")
|
||||||
set(EXECUTABLE_RECOVERY_FILE_NAME ${EXECUTABLE_RECOVERY_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
set(EXECUTABLE_RECOVERY_FILE_NAME ${EXECUTABLE_RECOVERY_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH})
|
||||||
add_executable(${EXECUTABLE_RECOVERY_NAME} ${RECOVERY_SOURCE_FILES})
|
add_executable(${EXECUTABLE_RECOVERY_NAME} ${RECOVERY_SOURCE_FILES})
|
||||||
target_link_libraries(${EXECUTABLE_RECOVERY_NAME} nimble nrf-sdk)
|
target_link_libraries(${EXECUTABLE_RECOVERY_NAME} nimble nrf-sdk littlefs)
|
||||||
set_target_properties(${EXECUTABLE_RECOVERY_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERY_FILE_NAME})
|
set_target_properties(${EXECUTABLE_RECOVERY_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERY_FILE_NAME})
|
||||||
target_compile_definitions(${EXECUTABLE_RECOVERY_NAME} PUBLIC "PINETIME_IS_RECOVERY")
|
target_compile_definitions(${EXECUTABLE_RECOVERY_NAME} PUBLIC "PINETIME_IS_RECOVERY")
|
||||||
target_compile_options(${EXECUTABLE_RECOVERY_NAME} PUBLIC
|
target_compile_options(${EXECUTABLE_RECOVERY_NAME} PUBLIC
|
||||||
|
@ -903,7 +924,7 @@ set(EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-${
|
||||||
set(IMAGE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.bin)
|
set(IMAGE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.bin)
|
||||||
set(DFU_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip)
|
set(DFU_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip)
|
||||||
add_executable(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} ${RECOVERY_SOURCE_FILES})
|
add_executable(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} ${RECOVERY_SOURCE_FILES})
|
||||||
target_link_libraries(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} nimble nrf-sdk)
|
target_link_libraries(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} nimble nrf-sdk littlefs)
|
||||||
set_target_properties(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME})
|
set_target_properties(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME})
|
||||||
target_compile_definitions(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC "PINETIME_IS_RECOVERY")
|
target_compile_definitions(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC "PINETIME_IS_RECOVERY")
|
||||||
target_compile_options(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC
|
target_compile_options(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC
|
||||||
|
|
|
@ -14,7 +14,7 @@ Battery::Battery() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Battery::Init() {
|
void Battery::Init() {
|
||||||
nrf_gpio_cfg_input(chargingPin, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pullup);
|
nrf_gpio_cfg_input(chargingPin, static_cast<nrf_gpio_pin_pull_t> GPIO_PIN_CNF_PULL_Pullup);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Battery::Update() {
|
void Battery::Update() {
|
||||||
|
@ -22,8 +22,9 @@ void Battery::Update() {
|
||||||
isCharging = !nrf_gpio_pin_read(chargingPin);
|
isCharging = !nrf_gpio_pin_read(chargingPin);
|
||||||
isPowerPresent = !nrf_gpio_pin_read(powerPresentPin);
|
isPowerPresent = !nrf_gpio_pin_read(powerPresentPin);
|
||||||
|
|
||||||
if (isReading)
|
if (isReading) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
// Non blocking read
|
// Non blocking read
|
||||||
samples = 0;
|
samples = 0;
|
||||||
isReading = true;
|
isReading = true;
|
||||||
|
@ -55,17 +56,21 @@ void Battery::SaadcInit() {
|
||||||
|
|
||||||
void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) {
|
void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) {
|
||||||
|
|
||||||
const float battery_max = 4.18; // maximum voltage of battery ( max charging voltage is 4.21 )
|
const uint16_t battery_max = 4180; // maximum voltage of battery ( max charging voltage is 4.21 )
|
||||||
const float battery_min = 3.20; // minimum voltage of battery before shutdown ( depends on the battery )
|
const uint16_t battery_min = 3200; // minimum voltage of battery before shutdown ( depends on the battery )
|
||||||
|
|
||||||
if (p_event->type == NRFX_SAADC_EVT_DONE) {
|
if (p_event->type == NRFX_SAADC_EVT_DONE) {
|
||||||
|
|
||||||
APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1));
|
APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1));
|
||||||
|
|
||||||
voltage = (static_cast<float>(p_event->data.done.p_buffer[0]) * 2.04f) / (1024 / 3.0f);
|
// A hardware voltage divider divides the battery voltage by 2
|
||||||
voltage = roundf(voltage * 100) / 100;
|
// ADC gain is 1/5
|
||||||
|
// thus adc_voltage = battery_voltage / 2 * gain = battery_voltage / 10
|
||||||
|
// reference_voltage is 0.6V
|
||||||
|
// p_event->data.done.p_buffer[0] = (adc_voltage / reference_voltage) * 1024
|
||||||
|
voltage = p_event->data.done.p_buffer[0] * 6000 / 1024;
|
||||||
|
|
||||||
percentRemaining = static_cast<int>(((voltage - battery_min) / (battery_max - battery_min)) * 100);
|
percentRemaining = (voltage - battery_min) * 100 / (battery_max - battery_min);
|
||||||
|
|
||||||
percentRemaining = std::max(percentRemaining, 0);
|
percentRemaining = std::max(percentRemaining, 0);
|
||||||
percentRemaining = std::min(percentRemaining, 100);
|
percentRemaining = std::min(percentRemaining, 100);
|
||||||
|
|
|
@ -50,7 +50,7 @@ namespace Pinetime {
|
||||||
return percentRemainingBuffer.GetAverage();
|
return percentRemainingBuffer.GetAverage();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Voltage() const {
|
uint16_t Voltage() const {
|
||||||
return voltage;
|
return voltage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ namespace Pinetime {
|
||||||
static constexpr uint32_t chargingPin = 12;
|
static constexpr uint32_t chargingPin = 12;
|
||||||
static constexpr uint32_t powerPresentPin = 19;
|
static constexpr uint32_t powerPresentPin = 19;
|
||||||
static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7;
|
static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7;
|
||||||
float voltage = 0.0f;
|
uint16_t voltage = 0;
|
||||||
int percentRemaining = -1;
|
int percentRemaining = -1;
|
||||||
|
|
||||||
bool isCharging = false;
|
bool isCharging = false;
|
||||||
|
|
|
@ -18,79 +18,99 @@
|
||||||
#include "MusicService.h"
|
#include "MusicService.h"
|
||||||
#include "systemtask/SystemTask.h"
|
#include "systemtask/SystemTask.h"
|
||||||
|
|
||||||
int MusicCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) {
|
namespace {
|
||||||
return static_cast<Pinetime::Controllers::MusicService*>(arg)->OnCommand(conn_handle, attr_handle, ctxt);
|
// 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 }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// 00000000-78fc-48fe-8e23-433b3a1942d0
|
||||||
|
constexpr ble_uuid128_t BaseUuid() {
|
||||||
|
return CharUuid(0x00, 0x00);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr ble_uuid128_t msUuid {BaseUuid()};
|
||||||
|
|
||||||
|
constexpr ble_uuid128_t msEventCharUuid {CharUuid(0x01, 0x00)};
|
||||||
|
constexpr ble_uuid128_t msStatusCharUuid {CharUuid(0x02, 0x00)};
|
||||||
|
constexpr ble_uuid128_t msArtistCharUuid {CharUuid(0x03, 0x00)};
|
||||||
|
constexpr ble_uuid128_t msTrackCharUuid {CharUuid(0x04, 0x00)};
|
||||||
|
constexpr ble_uuid128_t msAlbumCharUuid {CharUuid(0x05, 0x00)};
|
||||||
|
constexpr ble_uuid128_t msPositionCharUuid {CharUuid(0x06, 0x00)};
|
||||||
|
constexpr ble_uuid128_t msTotalLengthCharUuid {CharUuid(0x07, 0x00)};
|
||||||
|
constexpr ble_uuid128_t msTrackNumberCharUuid {CharUuid(0x08, 0x00)};
|
||||||
|
constexpr ble_uuid128_t msTrackTotalCharUuid {CharUuid(0x09, 0x00)};
|
||||||
|
constexpr ble_uuid128_t msPlaybackSpeedCharUuid {CharUuid(0x0a, 0x00)};
|
||||||
|
constexpr ble_uuid128_t msRepeatCharUuid {CharUuid(0x0b, 0x00)};
|
||||||
|
constexpr ble_uuid128_t msShuffleCharUuid {CharUuid(0x0c, 0x00)};
|
||||||
|
|
||||||
|
int MusicCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) {
|
||||||
|
return static_cast<Pinetime::Controllers::MusicService*>(arg)->OnCommand(conn_handle, attr_handle, ctxt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Pinetime::Controllers::MusicService::MusicService(Pinetime::System::SystemTask& system) : m_system(system) {
|
Pinetime::Controllers::MusicService::MusicService(Pinetime::System::SystemTask& system) : m_system(system) {
|
||||||
characteristicDefinition[0] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msEventCharUuid),
|
characteristicDefinition[0] = {.uuid = &msEventCharUuid.u,
|
||||||
.access_cb = MusicCallback,
|
.access_cb = MusicCallback,
|
||||||
.arg = this,
|
.arg = this,
|
||||||
.flags = BLE_GATT_CHR_F_NOTIFY,
|
.flags = BLE_GATT_CHR_F_NOTIFY,
|
||||||
.val_handle = &eventHandle};
|
.val_handle = &eventHandle};
|
||||||
characteristicDefinition[1] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msStatusCharUuid),
|
characteristicDefinition[1] = {.uuid = &msStatusCharUuid.u,
|
||||||
.access_cb = MusicCallback,
|
.access_cb = MusicCallback,
|
||||||
.arg = this,
|
.arg = this,
|
||||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
||||||
characteristicDefinition[2] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msTrackCharUuid),
|
characteristicDefinition[2] = {.uuid = &msTrackCharUuid.u,
|
||||||
.access_cb = MusicCallback,
|
.access_cb = MusicCallback,
|
||||||
.arg = this,
|
.arg = this,
|
||||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
||||||
characteristicDefinition[3] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msArtistCharUuid),
|
characteristicDefinition[3] = {.uuid = &msArtistCharUuid.u,
|
||||||
.access_cb = MusicCallback,
|
.access_cb = MusicCallback,
|
||||||
.arg = this,
|
.arg = this,
|
||||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
||||||
characteristicDefinition[4] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msAlbumCharUuid),
|
characteristicDefinition[4] = {.uuid = &msAlbumCharUuid.u,
|
||||||
.access_cb = MusicCallback,
|
.access_cb = MusicCallback,
|
||||||
.arg = this,
|
.arg = this,
|
||||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
||||||
characteristicDefinition[5] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msPositionCharUuid),
|
characteristicDefinition[5] = {.uuid = &msPositionCharUuid.u,
|
||||||
.access_cb = MusicCallback,
|
.access_cb = MusicCallback,
|
||||||
.arg = this,
|
.arg = this,
|
||||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
||||||
characteristicDefinition[6] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msTotalLengthCharUuid),
|
characteristicDefinition[6] = {.uuid = &msTotalLengthCharUuid.u,
|
||||||
.access_cb = MusicCallback,
|
.access_cb = MusicCallback,
|
||||||
.arg = this,
|
.arg = this,
|
||||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
||||||
characteristicDefinition[7] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msTotalLengthCharUuid),
|
characteristicDefinition[7] = {.uuid = &msTotalLengthCharUuid.u,
|
||||||
.access_cb = MusicCallback,
|
.access_cb = MusicCallback,
|
||||||
.arg = this,
|
.arg = this,
|
||||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
||||||
characteristicDefinition[8] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msTrackNumberCharUuid),
|
characteristicDefinition[8] = {.uuid = &msTrackNumberCharUuid.u,
|
||||||
.access_cb = MusicCallback,
|
.access_cb = MusicCallback,
|
||||||
.arg = this,
|
.arg = this,
|
||||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
||||||
characteristicDefinition[9] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msTrackTotalCharUuid),
|
characteristicDefinition[9] = {.uuid = &msTrackTotalCharUuid.u,
|
||||||
.access_cb = MusicCallback,
|
.access_cb = MusicCallback,
|
||||||
.arg = this,
|
.arg = this,
|
||||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
||||||
characteristicDefinition[10] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msPlaybackSpeedCharUuid),
|
characteristicDefinition[10] = {.uuid = &msPlaybackSpeedCharUuid.u,
|
||||||
.access_cb = MusicCallback,
|
.access_cb = MusicCallback,
|
||||||
.arg = this,
|
.arg = this,
|
||||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
||||||
characteristicDefinition[11] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msRepeatCharUuid),
|
characteristicDefinition[11] = {.uuid = &msRepeatCharUuid.u,
|
||||||
.access_cb = MusicCallback,
|
.access_cb = MusicCallback,
|
||||||
.arg = this,
|
.arg = this,
|
||||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
||||||
characteristicDefinition[12] = {.uuid = reinterpret_cast<ble_uuid_t*>(&msShuffleCharUuid),
|
characteristicDefinition[12] = {.uuid = &msShuffleCharUuid.u,
|
||||||
.access_cb = MusicCallback,
|
.access_cb = MusicCallback,
|
||||||
.arg = this,
|
.arg = this,
|
||||||
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ};
|
||||||
characteristicDefinition[13] = {0};
|
characteristicDefinition[13] = {0};
|
||||||
|
|
||||||
serviceDefinition[0] = {
|
serviceDefinition[0] = {
|
||||||
.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = reinterpret_cast<ble_uuid_t*>(&msUuid), .characteristics = characteristicDefinition};
|
.type = BLE_GATT_SVC_TYPE_PRIMARY, .uuid = &msUuid.u, .characteristics = characteristicDefinition};
|
||||||
serviceDefinition[1] = {0};
|
serviceDefinition[1] = {0};
|
||||||
|
|
||||||
artistName = "Waiting for";
|
|
||||||
albumName = "";
|
|
||||||
trackName = "track information..";
|
|
||||||
playing = false;
|
|
||||||
repeat = false;
|
|
||||||
shuffle = false;
|
|
||||||
playbackSpeed = 1.0f;
|
|
||||||
trackProgress = 0;
|
|
||||||
trackLength = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pinetime::Controllers::MusicService::Init() {
|
void Pinetime::Controllers::MusicService::Init() {
|
||||||
|
@ -109,27 +129,27 @@ int Pinetime::Controllers::MusicService::OnCommand(uint16_t conn_handle, uint16_
|
||||||
data[notifSize] = '\0';
|
data[notifSize] = '\0';
|
||||||
os_mbuf_copydata(ctxt->om, 0, notifSize, data);
|
os_mbuf_copydata(ctxt->om, 0, notifSize, data);
|
||||||
char* s = &data[0];
|
char* s = &data[0];
|
||||||
if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msArtistCharUuid)) == 0) {
|
if (ble_uuid_cmp(ctxt->chr->uuid, &msArtistCharUuid.u) == 0) {
|
||||||
artistName = s;
|
artistName = s;
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msTrackCharUuid)) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msTrackCharUuid.u) == 0) {
|
||||||
trackName = s;
|
trackName = s;
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msAlbumCharUuid)) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msAlbumCharUuid.u) == 0) {
|
||||||
albumName = s;
|
albumName = s;
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msStatusCharUuid)) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msStatusCharUuid.u) == 0) {
|
||||||
playing = s[0];
|
playing = s[0];
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msRepeatCharUuid)) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msRepeatCharUuid.u) == 0) {
|
||||||
repeat = s[0];
|
repeat = s[0];
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msShuffleCharUuid)) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msShuffleCharUuid.u) == 0) {
|
||||||
shuffle = s[0];
|
shuffle = s[0];
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msPositionCharUuid)) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msPositionCharUuid.u) == 0) {
|
||||||
trackProgress = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
trackProgress = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msTotalLengthCharUuid)) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msTotalLengthCharUuid.u) == 0) {
|
||||||
trackLength = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
trackLength = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msTrackNumberCharUuid)) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msTrackNumberCharUuid.u) == 0) {
|
||||||
trackNumber = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
trackNumber = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msTrackTotalCharUuid)) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msTrackTotalCharUuid.u) == 0) {
|
||||||
tracksTotal = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
tracksTotal = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
|
||||||
} else if (ble_uuid_cmp(ctxt->chr->uuid, reinterpret_cast<ble_uuid_t*>(&msPlaybackSpeedCharUuid)) == 0) {
|
} else if (ble_uuid_cmp(ctxt->chr->uuid, &msPlaybackSpeedCharUuid.u) == 0) {
|
||||||
playbackSpeed = static_cast<float>(((s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3])) / 100.0f;
|
playbackSpeed = static_cast<float>(((s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3])) / 100.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,18 +26,11 @@
|
||||||
#undef max
|
#undef max
|
||||||
#undef min
|
#undef min
|
||||||
|
|
||||||
// 00000000-78fc-48fe-8e23-433b3a1942d0
|
|
||||||
#define MUSIC_SERVICE_UUID_BASE \
|
|
||||||
{ 0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, 0x00, 0x00, 0x00, 0x00 }
|
|
||||||
#define MUSIC_SERVICE_CHAR_UUID(x, y) \
|
|
||||||
{ 0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, x, y, 0x00, 0x00 }
|
|
||||||
|
|
||||||
namespace Pinetime {
|
namespace Pinetime {
|
||||||
namespace System {
|
namespace System {
|
||||||
class SystemTask;
|
class SystemTask;
|
||||||
}
|
}
|
||||||
namespace Controllers {
|
namespace Controllers {
|
||||||
|
|
||||||
class MusicService {
|
class MusicService {
|
||||||
public:
|
public:
|
||||||
explicit MusicService(Pinetime::System::SystemTask& system);
|
explicit MusicService(Pinetime::System::SystemTask& system);
|
||||||
|
@ -73,41 +66,26 @@ namespace Pinetime {
|
||||||
enum MusicStatus { NotPlaying = 0x00, Playing = 0x01 };
|
enum MusicStatus { NotPlaying = 0x00, Playing = 0x01 };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ble_uuid128_t msUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_UUID_BASE};
|
|
||||||
|
|
||||||
ble_uuid128_t msEventCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_CHAR_UUID(0x01, 0x00)};
|
|
||||||
ble_uuid128_t msStatusCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_CHAR_UUID(0x02, 0x00)};
|
|
||||||
ble_uuid128_t msArtistCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_CHAR_UUID(0x03, 0x00)};
|
|
||||||
ble_uuid128_t msTrackCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_CHAR_UUID(0x04, 0x00)};
|
|
||||||
ble_uuid128_t msAlbumCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_CHAR_UUID(0x05, 0x00)};
|
|
||||||
ble_uuid128_t msPositionCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_CHAR_UUID(0x06, 0x00)};
|
|
||||||
ble_uuid128_t msTotalLengthCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_CHAR_UUID(0x07, 0x00)};
|
|
||||||
ble_uuid128_t msTrackNumberCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_CHAR_UUID(0x08, 0x00)};
|
|
||||||
ble_uuid128_t msTrackTotalCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_CHAR_UUID(0x09, 0x00)};
|
|
||||||
ble_uuid128_t msPlaybackSpeedCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_CHAR_UUID(0x0a, 0x00)};
|
|
||||||
ble_uuid128_t msRepeatCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_CHAR_UUID(0x0b, 0x00)};
|
|
||||||
ble_uuid128_t msShuffleCharUuid {.u = {.type = BLE_UUID_TYPE_128}, .value = MUSIC_SERVICE_CHAR_UUID(0x0c, 0x00)};
|
|
||||||
|
|
||||||
struct ble_gatt_chr_def characteristicDefinition[14];
|
struct ble_gatt_chr_def characteristicDefinition[14];
|
||||||
struct ble_gatt_svc_def serviceDefinition[2];
|
struct ble_gatt_svc_def serviceDefinition[2];
|
||||||
|
|
||||||
uint16_t eventHandle;
|
uint16_t eventHandle {};
|
||||||
|
|
||||||
std::string artistName;
|
std::string artistName {"Waiting for"};
|
||||||
std::string albumName;
|
std::string albumName {};
|
||||||
std::string trackName;
|
std::string trackName {"track information.."};
|
||||||
|
|
||||||
bool playing;
|
bool playing {false};
|
||||||
|
|
||||||
int trackProgress;
|
int trackProgress {0};
|
||||||
int trackLength;
|
int trackLength {0};
|
||||||
int trackNumber;
|
int trackNumber {};
|
||||||
int tracksTotal;
|
int tracksTotal {};
|
||||||
|
|
||||||
float playbackSpeed;
|
float playbackSpeed {1.0f};
|
||||||
|
|
||||||
bool repeat;
|
bool repeat {false};
|
||||||
bool shuffle;
|
bool shuffle {false};
|
||||||
|
|
||||||
Pinetime::System::SystemTask& m_system;
|
Pinetime::System::SystemTask& m_system;
|
||||||
};
|
};
|
||||||
|
|
197
src/components/fs/FS.cpp
Normal file
197
src/components/fs/FS.cpp
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
#include "FS.h"
|
||||||
|
#include <cstring>
|
||||||
|
#include <littlefs/lfs.h>
|
||||||
|
#include <lvgl/lvgl.h>
|
||||||
|
|
||||||
|
using namespace Pinetime::Controllers;
|
||||||
|
|
||||||
|
FS::FS(Pinetime::Drivers::SpiNorFlash& driver) :
|
||||||
|
flashDriver{ driver },
|
||||||
|
lfsConfig{
|
||||||
|
.context = this,
|
||||||
|
.read = SectorRead,
|
||||||
|
.prog = SectorProg,
|
||||||
|
.erase = SectorErase,
|
||||||
|
.sync = SectorSync,
|
||||||
|
|
||||||
|
.read_size = 16,
|
||||||
|
.prog_size = 8,
|
||||||
|
.block_size = blockSize,
|
||||||
|
.block_count = size / blockSize,
|
||||||
|
.block_cycles = 1000u,
|
||||||
|
|
||||||
|
.cache_size = 16,
|
||||||
|
.lookahead_size = 16,
|
||||||
|
|
||||||
|
.name_max = 50,
|
||||||
|
.attr_max = 50,
|
||||||
|
}
|
||||||
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
void FS::Init() {
|
||||||
|
|
||||||
|
// try mount
|
||||||
|
int err = lfs_mount(&lfs, &lfsConfig);
|
||||||
|
|
||||||
|
// reformat if we can't mount the filesystem
|
||||||
|
// this should only happen on the first boot
|
||||||
|
if (err != LFS_ERR_OK) {
|
||||||
|
lfs_format(&lfs, &lfsConfig);
|
||||||
|
err = lfs_mount(&lfs, &lfsConfig);
|
||||||
|
if (err != LFS_ERR_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef PINETIME_IS_RECOVERY
|
||||||
|
VerifyResource();
|
||||||
|
LVGLFileSystemInit();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FS::VerifyResource() {
|
||||||
|
// validate the resource metadata
|
||||||
|
resourcesValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) {
|
||||||
|
return lfs_file_open(&lfs, file_p, fileName, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FS::FileClose(lfs_file_t* file_p) {
|
||||||
|
return lfs_file_close(&lfs, file_p);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FS::FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size) {
|
||||||
|
return lfs_file_read(&lfs, file_p, buff, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FS::FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size) {
|
||||||
|
return lfs_file_write(&lfs, file_p, buff, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FS::FileSeek(lfs_file_t* file_p, uint32_t pos) {
|
||||||
|
return lfs_file_seek(&lfs, file_p, pos, LFS_SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
int FS::FileDelete(const char* fileName) {
|
||||||
|
return lfs_remove(&lfs, fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int FS::DirCreate(const char* path) {
|
||||||
|
return lfs_mkdir(&lfs, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete directory and all files inside
|
||||||
|
int FS::DirDelete(const char* path) {
|
||||||
|
|
||||||
|
lfs_dir_t lfs_dir;
|
||||||
|
lfs_info entryInfo;
|
||||||
|
|
||||||
|
int err;
|
||||||
|
err = lfs_dir_open(&lfs, &lfs_dir, path);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
while (lfs_dir_read(&lfs, &lfs_dir, &entryInfo)) {
|
||||||
|
lfs_remove(&lfs, entryInfo.name);
|
||||||
|
}
|
||||||
|
lfs_dir_close(&lfs, &lfs_dir);
|
||||||
|
return LFS_ERR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
----------- Interface between littlefs and SpiNorFlash -----------
|
||||||
|
|
||||||
|
*/
|
||||||
|
int FS::SectorSync(const struct lfs_config* c) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FS::SectorErase(const struct lfs_config* c, lfs_block_t block) {
|
||||||
|
Pinetime::Controllers::FS& lfs = *(static_cast<Pinetime::Controllers::FS*>(c->context));
|
||||||
|
const size_t address = startAddress + (block * blockSize);
|
||||||
|
lfs.flashDriver.SectorErase(address);
|
||||||
|
return lfs.flashDriver.EraseFailed() ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FS::SectorProg(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, const void* buffer, lfs_size_t size) {
|
||||||
|
Pinetime::Controllers::FS& lfs = *(static_cast<Pinetime::Controllers::FS*>(c->context));
|
||||||
|
const size_t address = startAddress + (block * blockSize) + off;
|
||||||
|
lfs.flashDriver.Write(address, (uint8_t*) buffer, size);
|
||||||
|
return lfs.flashDriver.ProgramFailed() ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int FS::SectorRead(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, lfs_size_t size) {
|
||||||
|
Pinetime::Controllers::FS& lfs = *(static_cast<Pinetime::Controllers::FS*>(c->context));
|
||||||
|
const size_t address = startAddress + (block * blockSize) + off;
|
||||||
|
lfs.flashDriver.Read(address, static_cast<uint8_t*>(buffer), size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
----------- LVGL filesystem integration -----------
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
lv_fs_res_t lvglOpen(lv_fs_drv_t* drv, void* file_p, const char* path, lv_fs_mode_t mode) {
|
||||||
|
|
||||||
|
lfs_file_t* file = static_cast<lfs_file_t*>(file_p);
|
||||||
|
FS* filesys = static_cast<FS*>(drv->user_data);
|
||||||
|
filesys->FileOpen(file, path, LFS_O_RDONLY);
|
||||||
|
|
||||||
|
if (file->type == 0) {
|
||||||
|
return LV_FS_RES_FS_ERR;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return LV_FS_RES_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_fs_res_t lvglClose(lv_fs_drv_t* drv, void* file_p) {
|
||||||
|
FS* filesys = static_cast<FS*>(drv->user_data);
|
||||||
|
lfs_file_t* file = static_cast<lfs_file_t*>(file_p);
|
||||||
|
filesys->FileClose(file);
|
||||||
|
|
||||||
|
return LV_FS_RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_fs_res_t lvglRead(lv_fs_drv_t* drv, void* file_p, void* buf, uint32_t btr, uint32_t* br) {
|
||||||
|
FS* filesys = static_cast<FS*>(drv->user_data);
|
||||||
|
lfs_file_t* file = static_cast<lfs_file_t*>(file_p);
|
||||||
|
filesys->FileRead(file, static_cast<uint8_t*>(buf), btr);
|
||||||
|
*br = btr;
|
||||||
|
return LV_FS_RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_fs_res_t lvglSeek(lv_fs_drv_t* drv, void* file_p, uint32_t pos) {
|
||||||
|
FS* filesys = static_cast<FS*>(drv->user_data);
|
||||||
|
lfs_file_t* file = static_cast<lfs_file_t*>(file_p);
|
||||||
|
filesys->FileSeek(file, pos);
|
||||||
|
return LV_FS_RES_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FS::LVGLFileSystemInit() {
|
||||||
|
|
||||||
|
lv_fs_drv_t fs_drv;
|
||||||
|
lv_fs_drv_init(&fs_drv);
|
||||||
|
|
||||||
|
fs_drv.file_size = sizeof(lfs_file_t);
|
||||||
|
fs_drv.letter = 'F';
|
||||||
|
fs_drv.open_cb = lvglOpen;
|
||||||
|
fs_drv.close_cb = lvglClose;
|
||||||
|
fs_drv.read_cb = lvglRead;
|
||||||
|
fs_drv.seek_cb = lvglSeek;
|
||||||
|
|
||||||
|
fs_drv.user_data = this;
|
||||||
|
|
||||||
|
lv_fs_drv_register(&fs_drv);
|
||||||
|
|
||||||
|
}
|
71
src/components/fs/FS.h
Normal file
71
src/components/fs/FS.h
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include "drivers/SpiNorFlash.h"
|
||||||
|
#include <littlefs/lfs.h>
|
||||||
|
|
||||||
|
namespace Pinetime {
|
||||||
|
namespace Controllers {
|
||||||
|
class FS {
|
||||||
|
public:
|
||||||
|
FS(Pinetime::Drivers::SpiNorFlash&);
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void LVGLFileSystemInit();
|
||||||
|
|
||||||
|
int FileOpen(lfs_file_t* file_p, const char* fileName, const int flags);
|
||||||
|
int FileClose(lfs_file_t* file_p);
|
||||||
|
int FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size);
|
||||||
|
int FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size);
|
||||||
|
int FileSeek(lfs_file_t* file_p, uint32_t pos);
|
||||||
|
|
||||||
|
int FileDelete(const char* fileName);
|
||||||
|
|
||||||
|
int DirCreate(const char* path);
|
||||||
|
int DirDelete(const char* path);
|
||||||
|
|
||||||
|
void VerifyResource();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Pinetime::Drivers::SpiNorFlash& flashDriver;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* External Flash MAP (4 MBytes)
|
||||||
|
*
|
||||||
|
* 0x000000 +---------------------------------------+
|
||||||
|
* | Bootloader Assets |
|
||||||
|
* | 256 KBytes |
|
||||||
|
* | |
|
||||||
|
* 0x040000 +---------------------------------------+
|
||||||
|
* | OTA |
|
||||||
|
* | 464 KBytes |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* 0x0B4000 +---------------------------------------+
|
||||||
|
* | File System |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* | |
|
||||||
|
* 0x400000 +---------------------------------------+
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static constexpr size_t startAddress = 0x0B4000;
|
||||||
|
static constexpr size_t size = 0x3C0000;
|
||||||
|
static constexpr size_t blockSize = 4096;
|
||||||
|
|
||||||
|
bool resourcesValid = false;
|
||||||
|
const struct lfs_config lfsConfig;
|
||||||
|
|
||||||
|
lfs_t lfs;
|
||||||
|
|
||||||
|
static int SectorSync(const struct lfs_config* c);
|
||||||
|
static int SectorErase(const struct lfs_config* c, lfs_block_t block);
|
||||||
|
static int SectorProg(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, const void* buffer, lfs_size_t size);
|
||||||
|
static int SectorRead(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,108 +4,44 @@
|
||||||
|
|
||||||
using namespace Pinetime::Controllers;
|
using namespace Pinetime::Controllers;
|
||||||
|
|
||||||
struct SettingsHeader {
|
Settings::Settings(Pinetime::Controllers::FS& fs) : fs {fs} {
|
||||||
uint8_t isActive; // 0xF1 = Block is active, 0xF0 = Block is inactive
|
|
||||||
uint16_t version; // Current version, to verify if the saved data is for the current Version
|
|
||||||
};
|
|
||||||
|
|
||||||
#define HEADER_SIZE sizeof(SettingsHeader)
|
|
||||||
|
|
||||||
Settings::Settings(Pinetime::Drivers::SpiNorFlash& spiNorFlash) : spiNorFlash {spiNorFlash} {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::Init() {
|
void Settings::Init() {
|
||||||
|
|
||||||
// Load default settings from Flash
|
// Load default settings from Flash
|
||||||
LoadSettingsFromFlash();
|
LoadSettingsFromFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::SaveSettings() {
|
void Settings::SaveSettings() {
|
||||||
|
|
||||||
// verify if is necessary to save
|
// verify if is necessary to save
|
||||||
if (settingsChanged) {
|
if (settingsChanged) {
|
||||||
SaveSettingsToFlash();
|
SaveSettingsToFile();
|
||||||
}
|
}
|
||||||
settingsChanged = false;
|
settingsChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Settings::FindHeader() {
|
void Settings::LoadSettingsFromFile() {
|
||||||
SettingsHeader settingsHeader;
|
SettingsData bufferSettings;
|
||||||
uint8_t bufferHead[sizeof(settingsHeader)];
|
lfs_file_t settingsFile;
|
||||||
|
|
||||||
for (uint8_t block = 0; block < 10; block++) {
|
if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) {
|
||||||
|
return;
|
||||||
spiNorFlash.Read(settingsBaseAddr + (block * 0x1000), bufferHead, sizeof(settingsHeader));
|
|
||||||
std::memcpy(&settingsHeader, bufferHead, sizeof(settingsHeader));
|
|
||||||
if (settingsHeader.isActive == 0xF1 && settingsHeader.version == settingsVersion) {
|
|
||||||
settingsFlashBlock = block;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
fs.FileRead(&settingsFile, reinterpret_cast<uint8_t*>(&bufferSettings), sizeof(settings));
|
||||||
}
|
fs.FileClose(&settingsFile);
|
||||||
|
if ( bufferSettings.version == settingsVersion ) {
|
||||||
void Settings::ReadSettingsData() {
|
settings = bufferSettings;
|
||||||
uint8_t bufferSettings[sizeof(settings)];
|
|
||||||
spiNorFlash.Read(settingsBaseAddr + (settingsFlashBlock * 0x1000) + HEADER_SIZE, bufferSettings, sizeof(settings));
|
|
||||||
std::memcpy(&settings, bufferSettings, sizeof(settings));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::EraseBlock() {
|
|
||||||
|
|
||||||
spiNorFlash.SectorErase(settingsBaseAddr + (settingsFlashBlock * 0x1000));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::SetHeader(bool state) {
|
|
||||||
SettingsHeader settingsHeader;
|
|
||||||
uint8_t bufferHead[sizeof(settingsHeader)];
|
|
||||||
settingsHeader.isActive = state ? 0xF1 : 0xF0;
|
|
||||||
settingsHeader.version = settingsVersion;
|
|
||||||
|
|
||||||
std::memcpy(bufferHead, &settingsHeader, sizeof(settingsHeader));
|
|
||||||
spiNorFlash.Write(settingsBaseAddr + (settingsFlashBlock * 0x1000), bufferHead, sizeof(settingsHeader));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::SaveSettingsData() {
|
|
||||||
uint8_t bufferSettings[sizeof(settings)];
|
|
||||||
std::memcpy(bufferSettings, &settings, sizeof(settings));
|
|
||||||
spiNorFlash.Write(settingsBaseAddr + (settingsFlashBlock * 0x1000) + HEADER_SIZE, bufferSettings, sizeof(settings));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Settings::LoadSettingsFromFlash() {
|
|
||||||
|
|
||||||
if (settingsFlashBlock == 99) {
|
|
||||||
// Find current Block, if can't find use default settings and set block to 0 ans save !
|
|
||||||
if (FindHeader()) {
|
|
||||||
ReadSettingsData();
|
|
||||||
} else {
|
|
||||||
SaveSettingsToFlash();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Read Settings from flash...
|
|
||||||
// never used :)
|
|
||||||
ReadSettingsData();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::SaveSettingsToFlash() {
|
void Settings::SaveSettingsToFile() {
|
||||||
|
lfs_file_t settingsFile;
|
||||||
|
|
||||||
// calculate where to save...
|
if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) {
|
||||||
// mark current to inactive
|
return;
|
||||||
// erase the new location and save
|
|
||||||
// set settingsFlashBlock
|
|
||||||
|
|
||||||
// if first time hever, only saves to block 0 and set settingsFlashBlock
|
|
||||||
|
|
||||||
if (settingsFlashBlock != 99) {
|
|
||||||
SetHeader(false);
|
|
||||||
}
|
}
|
||||||
|
fs.FileWrite(&settingsFile, reinterpret_cast<uint8_t*>(&settings), sizeof(settings));
|
||||||
settingsFlashBlock++;
|
fs.FileClose(&settingsFile);
|
||||||
if (settingsFlashBlock > 9)
|
|
||||||
settingsFlashBlock = 0;
|
|
||||||
|
|
||||||
EraseBlock();
|
|
||||||
SetHeader(true);
|
|
||||||
SaveSettingsData();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,26 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include "components/datetime/DateTimeController.h"
|
#include "components/datetime/DateTimeController.h"
|
||||||
#include "components/brightness/BrightnessController.h"
|
#include "components/brightness/BrightnessController.h"
|
||||||
#include "drivers/SpiNorFlash.h"
|
#include "components/fs/FS.h"
|
||||||
#include "drivers/Cst816s.h"
|
#include "drivers/Cst816s.h"
|
||||||
|
|
||||||
namespace Pinetime {
|
namespace Pinetime {
|
||||||
namespace Controllers {
|
namespace Controllers {
|
||||||
class Settings {
|
class Settings {
|
||||||
public:
|
public:
|
||||||
enum class ClockType { H24, H12 };
|
enum class ClockType : uint8_t { H24, H12 };
|
||||||
enum class Vibration { ON, OFF };
|
enum class Vibration : uint8_t { ON, OFF };
|
||||||
enum class WakeUpMode { None, SingleTap, DoubleTap, RaiseWrist };
|
enum class WakeUpMode : uint8_t { None, SingleTap, DoubleTap, RaiseWrist };
|
||||||
|
|
||||||
Settings(Pinetime::Drivers::SpiNorFlash& spiNorFlash);
|
Settings(Pinetime::Controllers::FS& fs);
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
void SaveSettings();
|
void SaveSettings();
|
||||||
|
|
||||||
void SetClockFace(uint8_t face) {
|
void SetClockFace(uint8_t face) {
|
||||||
if (face != settings.clockFace)
|
if (face != settings.clockFace) {
|
||||||
settingsChanged = true;
|
settingsChanged = true;
|
||||||
|
}
|
||||||
settings.clockFace = face;
|
settings.clockFace = face;
|
||||||
};
|
};
|
||||||
uint8_t GetClockFace() const {
|
uint8_t GetClockFace() const {
|
||||||
|
@ -69,8 +70,9 @@ namespace Pinetime {
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetClockType(ClockType clocktype) {
|
void SetClockType(ClockType clocktype) {
|
||||||
if (clocktype != settings.clockType)
|
if (clocktype != settings.clockType) {
|
||||||
settingsChanged = true;
|
settingsChanged = true;
|
||||||
|
}
|
||||||
settings.clockType = clocktype;
|
settings.clockType = clocktype;
|
||||||
};
|
};
|
||||||
ClockType GetClockType() const {
|
ClockType GetClockType() const {
|
||||||
|
@ -78,8 +80,9 @@ namespace Pinetime {
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetVibrationStatus(Vibration status) {
|
void SetVibrationStatus(Vibration status) {
|
||||||
if (status != settings.vibrationStatus)
|
if (status != settings.vibrationStatus) {
|
||||||
settingsChanged = true;
|
settingsChanged = true;
|
||||||
|
}
|
||||||
settings.vibrationStatus = status;
|
settings.vibrationStatus = status;
|
||||||
};
|
};
|
||||||
Vibration GetVibrationStatus() const {
|
Vibration GetVibrationStatus() const {
|
||||||
|
@ -87,8 +90,9 @@ namespace Pinetime {
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetScreenTimeOut(uint32_t timeout) {
|
void SetScreenTimeOut(uint32_t timeout) {
|
||||||
if (timeout != settings.screenTimeOut)
|
if (timeout != settings.screenTimeOut) {
|
||||||
settingsChanged = true;
|
settingsChanged = true;
|
||||||
|
}
|
||||||
settings.screenTimeOut = timeout;
|
settings.screenTimeOut = timeout;
|
||||||
};
|
};
|
||||||
uint32_t GetScreenTimeOut() const {
|
uint32_t GetScreenTimeOut() const {
|
||||||
|
@ -96,8 +100,9 @@ namespace Pinetime {
|
||||||
};
|
};
|
||||||
|
|
||||||
void setWakeUpMode(WakeUpMode wakeUp) {
|
void setWakeUpMode(WakeUpMode wakeUp) {
|
||||||
if (wakeUp != settings.wakeUpMode)
|
if (wakeUp != settings.wakeUpMode) {
|
||||||
settingsChanged = true;
|
settingsChanged = true;
|
||||||
|
}
|
||||||
settings.wakeUpMode = wakeUp;
|
settings.wakeUpMode = wakeUp;
|
||||||
};
|
};
|
||||||
WakeUpMode getWakeUpMode() const {
|
WakeUpMode getWakeUpMode() const {
|
||||||
|
@ -105,8 +110,9 @@ namespace Pinetime {
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetBrightness(Controllers::BrightnessController::Levels level) {
|
void SetBrightness(Controllers::BrightnessController::Levels level) {
|
||||||
if (level != settings.brightLevel)
|
if (level != settings.brightLevel) {
|
||||||
settingsChanged = true;
|
settingsChanged = true;
|
||||||
|
}
|
||||||
settings.brightLevel = level;
|
settings.brightLevel = level;
|
||||||
};
|
};
|
||||||
Controllers::BrightnessController::Levels GetBrightness() const {
|
Controllers::BrightnessController::Levels GetBrightness() const {
|
||||||
|
@ -114,17 +120,24 @@ namespace Pinetime {
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetStepsGoal( uint32_t goal ) {
|
void SetStepsGoal( uint32_t goal ) {
|
||||||
if ( goal != settings.stepsGoal )
|
if ( goal != settings.stepsGoal ) {
|
||||||
settingsChanged = true;
|
settingsChanged = true;
|
||||||
|
}
|
||||||
settings.stepsGoal = goal;
|
settings.stepsGoal = goal;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t GetStepsGoal() const { return settings.stepsGoal; };
|
uint32_t GetStepsGoal() const { return settings.stepsGoal; };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Pinetime::Drivers::SpiNorFlash& spiNorFlash;
|
Pinetime::Controllers::FS& fs;
|
||||||
|
|
||||||
|
static constexpr uint32_t settingsVersion = 0x0001;
|
||||||
struct SettingsData {
|
struct SettingsData {
|
||||||
|
|
||||||
|
uint32_t version = settingsVersion;
|
||||||
|
uint32_t stepsGoal = 10000;
|
||||||
|
uint32_t screenTimeOut = 15000;
|
||||||
|
|
||||||
ClockType clockType = ClockType::H24;
|
ClockType clockType = ClockType::H24;
|
||||||
Vibration vibrationStatus = Vibration::ON;
|
Vibration vibrationStatus = Vibration::ON;
|
||||||
|
|
||||||
|
@ -134,9 +147,6 @@ namespace Pinetime {
|
||||||
uint8_t PTSColorBar = 11;
|
uint8_t PTSColorBar = 11;
|
||||||
uint8_t PTSColorBG = 3;
|
uint8_t PTSColorBG = 3;
|
||||||
|
|
||||||
uint32_t stepsGoal = 10000;
|
|
||||||
uint32_t screenTimeOut = 15000;
|
|
||||||
|
|
||||||
WakeUpMode wakeUpMode = WakeUpMode::None;
|
WakeUpMode wakeUpMode = WakeUpMode::None;
|
||||||
|
|
||||||
Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium;
|
Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium;
|
||||||
|
@ -148,20 +158,8 @@ namespace Pinetime {
|
||||||
uint8_t appMenu = 0;
|
uint8_t appMenu = 0;
|
||||||
uint8_t settingsMenu = 0;
|
uint8_t settingsMenu = 0;
|
||||||
|
|
||||||
// There are 10 blocks of reserved flash to save settings
|
void LoadSettingsFromFile();
|
||||||
// to minimize wear, the recording is done in a rotating way by the 10 blocks
|
void SaveSettingsToFile();
|
||||||
uint8_t settingsFlashBlock = 99; // default to indicate it needs to find the active block
|
|
||||||
|
|
||||||
static constexpr uint32_t settingsBaseAddr = 0x3F6000; // Flash Settings Location
|
|
||||||
static constexpr uint16_t settingsVersion = 0x0100; // Flash Settings Version
|
|
||||||
|
|
||||||
bool FindHeader();
|
|
||||||
void ReadSettingsData();
|
|
||||||
void EraseBlock();
|
|
||||||
void SetHeader(bool state);
|
|
||||||
void SaveSettingsData();
|
|
||||||
void LoadSettingsFromFlash();
|
|
||||||
void SaveSettingsToFlash();
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -342,7 +342,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
|
||||||
ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None);
|
ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None);
|
||||||
break;
|
break;
|
||||||
case Apps::StopWatch:
|
case Apps::StopWatch:
|
||||||
currentScreen = std::make_unique<Screens::StopWatch>(this);
|
currentScreen = std::make_unique<Screens::StopWatch>(this, *systemTask);
|
||||||
break;
|
break;
|
||||||
case Apps::Twos:
|
case Apps::Twos:
|
||||||
currentScreen = std::make_unique<Screens::Twos>(this);
|
currentScreen = std::make_unique<Screens::Twos>(this);
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* Do not enable font compression and horizontal subpixel hinting
|
* Do not enable font compression and horizontal subpixel hinting
|
||||||
* Load the file `JetBrainsMono-Bold.tff` (use the file in this repo to ensure the version matches) and specify the following range : `0x20-0x7f, 0x410-0x44f`
|
* Load the file `JetBrainsMono-Bold.tff` (use the file in this repo to ensure the version matches) and specify the following range : `0x20-0x7f, 0x410-0x44f`
|
||||||
* Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following
|
* Add a 2nd font, load the file `FontAwesome5-Solid+Brands+Regular.woff` and specify the following
|
||||||
range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf029, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252`
|
range : `0xf293, 0xf294, 0xf244, 0xf240, 0xf242, 0xf243, 0xf241, 0xf54b, 0xf21e, 0xf1e6, 0xf54b, 0xf017, 0xf129, 0xf03a, 0xf185, 0xf560, 0xf001, 0xf3fd, 0xf069, 0xf1fc, 0xf45d, 0xf59f, 0xf5a0, 0xf029, 0xf027, 0xf028, 0xf6a9, 0xf04b, 0xf04c, 0xf048, 0xf051, 0xf095, 0xf3dd, 0xf04d, 0xf2f2, 0xf024, 0xf252, 0xf569`
|
||||||
* Click on Convert, and download the file `jetbrains_mono_bold_20.c` and copy it in `src/DisplayApp/Fonts`
|
* Click on Convert, and download the file `jetbrains_mono_bold_20.c` and copy it in `src/DisplayApp/Fonts`
|
||||||
* Add the font .c file path to src/CMakeLists.txt
|
* Add the font .c file path to src/CMakeLists.txt
|
||||||
* Add an LV_FONT_DECLARE line in src/libs/lv_conf.h
|
* Add an LV_FONT_DECLARE line in src/libs/lv_conf.h
|
||||||
|
|
|
@ -979,6 +979,16 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
|
||||||
0x1f, 0xf0, 0x0, 0xfe, 0x0, 0x7, 0xc0, 0x0,
|
0x1f, 0xf0, 0x0, 0xfe, 0x0, 0x7, 0xc0, 0x0,
|
||||||
0x38, 0x0, 0x1, 0x0, 0x0,
|
0x38, 0x0, 0x1, 0x0, 0x0,
|
||||||
|
|
||||||
|
/* U+F569 "" */
|
||||||
|
0x0, 0x0, 0x4, 0x0, 0x0, 0x3c, 0x0, 0x0,
|
||||||
|
0xf0, 0x0, 0x7, 0xc0, 0x1f, 0xfe, 0x3, 0xff,
|
||||||
|
0xfe, 0xf, 0x87, 0xfe, 0x38, 0x3e, 0xe, 0xc0,
|
||||||
|
0xf8, 0x7, 0x81, 0xc0, 0xf, 0x0, 0x0, 0x1f,
|
||||||
|
0x80, 0x0, 0xff, 0xe0, 0xf, 0xff, 0xff, 0xff,
|
||||||
|
0xf9, 0xff, 0xf3, 0xf3, 0xe3, 0xe7, 0xe7, 0xc7,
|
||||||
|
0xce, 0xcf, 0x8f, 0x98, 0x9f, 0x1f, 0x20, 0x3e,
|
||||||
|
0x3e, 0x0, 0x4, 0x60, 0x0,
|
||||||
|
|
||||||
/* U+F59F "" */
|
/* U+F59F "" */
|
||||||
0x0, 0x78, 0x0, 0x7, 0xf8, 0x0, 0x1f, 0xe0,
|
0x0, 0x78, 0x0, 0x7, 0xf8, 0x0, 0x1f, 0xe0,
|
||||||
0x0, 0xff, 0xc0, 0x3, 0xff, 0x0, 0xf, 0xfc,
|
0x0, 0xff, 0xc0, 0x3, 0xff, 0x0, 0xf, 0xfc,
|
||||||
|
@ -1204,9 +1214,10 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
|
||||||
{.bitmap_index = 3750, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -2},
|
{.bitmap_index = 3750, .adv_w = 320, .box_w = 20, .box_h = 20, .ofs_x = 0, .ofs_y = -2},
|
||||||
{.bitmap_index = 3800, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
|
{.bitmap_index = 3800, .adv_w = 400, .box_w = 25, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
|
||||||
{.bitmap_index = 3860, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
|
{.bitmap_index = 3860, .adv_w = 320, .box_w = 20, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
|
||||||
{.bitmap_index = 3913, .adv_w = 360, .box_w = 22, .box_h = 20, .ofs_x = 0, .ofs_y = -2},
|
{.bitmap_index = 3913, .adv_w = 360, .box_w = 23, .box_h = 21, .ofs_x = 0, .ofs_y = -3},
|
||||||
{.bitmap_index = 3968, .adv_w = 360, .box_w = 22, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
|
{.bitmap_index = 3974, .adv_w = 360, .box_w = 22, .box_h = 20, .ofs_x = 0, .ofs_y = -2},
|
||||||
{.bitmap_index = 4021, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 0}
|
{.bitmap_index = 4029, .adv_w = 360, .box_w = 22, .box_h = 19, .ofs_x = 0, .ofs_y = -2},
|
||||||
|
{.bitmap_index = 4082, .adv_w = 320, .box_w = 20, .box_h = 15, .ofs_x = 0, .ofs_y = 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*---------------------
|
/*---------------------
|
||||||
|
@ -1218,7 +1229,7 @@ static const uint16_t unicode_list_2[] = {
|
||||||
0x4a, 0x4b, 0x4c, 0x50, 0x68, 0x94, 0x128, 0x184,
|
0x4a, 0x4b, 0x4c, 0x50, 0x68, 0x94, 0x128, 0x184,
|
||||||
0x1e5, 0x1fb, 0x21d, 0x23f, 0x240, 0x241, 0x242, 0x243,
|
0x1e5, 0x1fb, 0x21d, 0x23f, 0x240, 0x241, 0x242, 0x243,
|
||||||
0x251, 0x292, 0x293, 0x2f1, 0x3dc, 0x3fc, 0x45c, 0x54a,
|
0x251, 0x292, 0x293, 0x2f1, 0x3dc, 0x3fc, 0x45c, 0x54a,
|
||||||
0x55f, 0x59e, 0x59f, 0x6a8
|
0x55f, 0x568, 0x59e, 0x59f, 0x6a8
|
||||||
};
|
};
|
||||||
|
|
||||||
/*Collect the unicode lists and glyph_id offsets*/
|
/*Collect the unicode lists and glyph_id offsets*/
|
||||||
|
@ -1234,7 +1245,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] =
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.range_start = 61441, .range_length = 1705, .glyph_id_start = 160,
|
.range_start = 61441, .range_length = 1705, .glyph_id_start = 160,
|
||||||
.unicode_list = unicode_list_2, .glyph_id_ofs_list = NULL, .list_length = 36, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
|
.unicode_list = unicode_list_2, .glyph_id_ofs_list = NULL, .list_length = 37, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ std::unique_ptr<Screen> ApplicationList::CreateScreen2() {
|
||||||
{Symbols::paddle, Apps::Paddle},
|
{Symbols::paddle, Apps::Paddle},
|
||||||
{"2", Apps::Twos},
|
{"2", Apps::Twos},
|
||||||
{"M", Apps::Motion},
|
{"M", Apps::Motion},
|
||||||
{"b", Apps::Metronome},
|
{Symbols::drum, Apps::Metronome},
|
||||||
{"", Apps::None},
|
{"", Apps::None},
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
|
|
@ -46,16 +46,9 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont
|
||||||
lv_label_set_align(percent, LV_LABEL_ALIGN_LEFT);
|
lv_label_set_align(percent, LV_LABEL_ALIGN_LEFT);
|
||||||
lv_obj_align(percent, nullptr, LV_ALIGN_CENTER, 0, -60);
|
lv_obj_align(percent, nullptr, LV_ALIGN_CENTER, 0, -60);
|
||||||
|
|
||||||
// hack to not use the flot functions from printf
|
|
||||||
uint8_t batteryVoltageBytes[2];
|
|
||||||
batteryVoltageBytes[1] = static_cast<uint8_t>(batteryVoltage); // truncate whole numbers
|
|
||||||
batteryVoltageBytes[0] =
|
|
||||||
static_cast<uint8_t>((batteryVoltage - batteryVoltageBytes[1]) * 100); // remove whole part of flt and shift 2 places over
|
|
||||||
//
|
|
||||||
|
|
||||||
voltage = lv_label_create(lv_scr_act(), nullptr);
|
voltage = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_obj_set_style_local_text_color(voltage, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xC6A600));
|
lv_obj_set_style_local_text_color(voltage, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0xC6A600));
|
||||||
lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltageBytes[1], batteryVoltageBytes[0]);
|
lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltage / 1000, batteryVoltage % 1000 / 10);
|
||||||
lv_label_set_align(voltage, LV_LABEL_ALIGN_CENTER);
|
lv_label_set_align(voltage, LV_LABEL_ALIGN_CENTER);
|
||||||
lv_obj_align(voltage, nullptr, LV_ALIGN_CENTER, 0, 95);
|
lv_obj_align(voltage, nullptr, LV_ALIGN_CENTER, 0, 95);
|
||||||
|
|
||||||
|
@ -109,16 +102,16 @@ void BatteryInfo::UpdateScreen() {
|
||||||
if (batteryPercent >= 0) {
|
if (batteryPercent >= 0) {
|
||||||
if (batteryController.IsCharging() and batteryPercent < 100) {
|
if (batteryController.IsCharging() and batteryPercent < 100) {
|
||||||
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED);
|
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED);
|
||||||
lv_label_set_text_static(status, "Battery charging");
|
lv_label_set_text_static(status, "Charging");
|
||||||
} else if (batteryPercent == 100) {
|
} else if (batteryPercent == 100) {
|
||||||
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_BLUE);
|
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_BLUE);
|
||||||
lv_label_set_text_static(status, "Battery is fully charged");
|
lv_label_set_text_static(status, "Fully charged");
|
||||||
} else if (batteryPercent < 10) {
|
} else if (batteryPercent < 10) {
|
||||||
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
|
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
|
||||||
lv_label_set_text_static(status, "Battery is low");
|
lv_label_set_text_static(status, "Battery low");
|
||||||
} else {
|
} else {
|
||||||
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_GREEN);
|
lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_GREEN);
|
||||||
lv_label_set_text_static(status, "Battery discharging");
|
lv_label_set_text_static(status, "Discharging");
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_label_set_text_fmt(percent, "%02i%%", batteryPercent);
|
lv_label_set_text_fmt(percent, "%02i%%", batteryPercent);
|
||||||
|
@ -129,13 +122,7 @@ void BatteryInfo::UpdateScreen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_obj_align(status, charging_bar, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
|
lv_obj_align(status, charging_bar, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
|
||||||
// hack to not use the flot functions from printf
|
lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltage / 1000, batteryVoltage % 1000 / 10);
|
||||||
uint8_t batteryVoltageBytes[2];
|
|
||||||
batteryVoltageBytes[1] = static_cast<uint8_t>(batteryVoltage); // truncate whole numbers
|
|
||||||
batteryVoltageBytes[0] =
|
|
||||||
static_cast<uint8_t>((batteryVoltage - batteryVoltageBytes[1]) * 100); // remove whole part of flt and shift 2 places over
|
|
||||||
//
|
|
||||||
lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltageBytes[1], batteryVoltageBytes[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BatteryInfo::Refresh() {
|
bool BatteryInfo::Refresh() {
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace Pinetime {
|
||||||
|
|
||||||
int8_t animation = 0;
|
int8_t animation = 0;
|
||||||
int8_t batteryPercent = -1;
|
int8_t batteryPercent = -1;
|
||||||
float batteryVoltage = 0.0f;
|
uint16_t batteryVoltage = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,30 +16,18 @@ namespace {
|
||||||
|
|
||||||
FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::FirmwareValidator& validator)
|
FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::FirmwareValidator& validator)
|
||||||
: Screen {app}, validator {validator} {
|
: Screen {app}, validator {validator} {
|
||||||
labelVersionInfo = lv_label_create(lv_scr_act(), nullptr);
|
labelVersion = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_obj_align(labelVersionInfo, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0);
|
lv_label_set_text_fmt(labelVersion,
|
||||||
lv_label_set_text(labelVersionInfo, "Version : ");
|
"Version : %d.%d.%d\n"
|
||||||
lv_label_set_align(labelVersionInfo, LV_LABEL_ALIGN_LEFT);
|
"ShortRef : %s",
|
||||||
|
Version::Major(),
|
||||||
labelVersionValue = lv_label_create(lv_scr_act(), nullptr);
|
Version::Minor(),
|
||||||
lv_obj_align(labelVersionValue, labelVersionInfo, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
|
Version::Patch(),
|
||||||
lv_label_set_recolor(labelVersionValue, true);
|
Version::GitCommitHash());
|
||||||
sprintf(version, "%ld.%ld.%ld", Version::Major(), Version::Minor(), Version::Patch());
|
lv_obj_align(labelVersion, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0);
|
||||||
lv_label_set_text(labelVersionValue, version);
|
|
||||||
|
|
||||||
labelShortRefInfo = lv_label_create(lv_scr_act(), nullptr);
|
|
||||||
lv_obj_align(labelShortRefInfo, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 25);
|
|
||||||
lv_label_set_text(labelShortRefInfo, "ShortRef : ");
|
|
||||||
lv_label_set_align(labelShortRefInfo, LV_LABEL_ALIGN_LEFT);
|
|
||||||
|
|
||||||
labelShortRefValue = lv_label_create(lv_scr_act(), nullptr);
|
|
||||||
lv_obj_align(labelShortRefValue, labelShortRefInfo, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
|
|
||||||
lv_label_set_recolor(labelShortRefValue, true);
|
|
||||||
sprintf(shortref, "%s", Version::GitCommitHash());
|
|
||||||
lv_label_set_text(labelShortRefValue, shortref);
|
|
||||||
|
|
||||||
labelIsValidated = lv_label_create(lv_scr_act(), nullptr);
|
labelIsValidated = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_obj_align(labelIsValidated, nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 50);
|
lv_obj_align(labelIsValidated, labelVersion, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
|
||||||
lv_label_set_recolor(labelIsValidated, true);
|
lv_label_set_recolor(labelIsValidated, true);
|
||||||
lv_label_set_long_mode(labelIsValidated, LV_LABEL_LONG_BREAK);
|
lv_label_set_long_mode(labelIsValidated, LV_LABEL_LONG_BREAK);
|
||||||
lv_obj_set_width(labelIsValidated, 240);
|
lv_obj_set_width(labelIsValidated, 240);
|
||||||
|
|
|
@ -23,12 +23,7 @@ namespace Pinetime {
|
||||||
private:
|
private:
|
||||||
Pinetime::Controllers::FirmwareValidator& validator;
|
Pinetime::Controllers::FirmwareValidator& validator;
|
||||||
|
|
||||||
lv_obj_t* labelVersionInfo;
|
lv_obj_t* labelVersion;
|
||||||
lv_obj_t* labelVersionValue;
|
|
||||||
lv_obj_t* labelShortRefInfo;
|
|
||||||
lv_obj_t* labelShortRefValue;
|
|
||||||
char version[9];
|
|
||||||
char shortref[9];
|
|
||||||
lv_obj_t* labelIsValidated;
|
lv_obj_t* labelIsValidated;
|
||||||
lv_obj_t* buttonValidate;
|
lv_obj_t* buttonValidate;
|
||||||
lv_obj_t* labelButtonValidate;
|
lv_obj_t* labelButtonValidate;
|
||||||
|
|
|
@ -163,10 +163,10 @@ Notifications::NotificationItem::NotificationItem(const char* title,
|
||||||
lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
lv_obj_set_style_local_border_width(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||||
|
|
||||||
lv_obj_set_pos(container1, 0, 50);
|
lv_obj_set_pos(container1, 0, 50);
|
||||||
lv_obj_set_width(container1, 240);
|
lv_obj_set_size(container1, LV_HOR_RES, 190);
|
||||||
lv_obj_set_height(container1, 190);
|
|
||||||
|
|
||||||
lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT);
|
lv_cont_set_layout(container1, LV_LAYOUT_COLUMN_LEFT);
|
||||||
|
lv_cont_set_fit(container1, LV_FIT_NONE);
|
||||||
|
|
||||||
lv_obj_t* alert_count = lv_label_create(lv_scr_act(), nullptr);
|
lv_obj_t* alert_count = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_label_set_text_fmt(alert_count, "%i/%i", notifNr, notifNb);
|
lv_label_set_text_fmt(alert_count, "%i/%i", notifNr, notifNb);
|
||||||
|
@ -198,6 +198,7 @@ Notifications::NotificationItem::NotificationItem(const char* title,
|
||||||
lv_label_set_text(alert_subject, msg);
|
lv_label_set_text(alert_subject, msg);
|
||||||
} break;
|
} break;
|
||||||
case Controllers::NotificationManager::Categories::IncomingCall: {
|
case Controllers::NotificationManager::Categories::IncomingCall: {
|
||||||
|
lv_obj_set_height(container1, 108);
|
||||||
lv_obj_t* alert_subject = lv_label_create(container1, nullptr);
|
lv_obj_t* alert_subject = lv_label_create(container1, nullptr);
|
||||||
lv_obj_set_style_local_text_color(alert_subject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE);
|
lv_obj_set_style_local_text_color(alert_subject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_ORANGE);
|
||||||
lv_label_set_long_mode(alert_subject, LV_LABEL_LONG_BREAK);
|
lv_label_set_long_mode(alert_subject, LV_LABEL_LONG_BREAK);
|
||||||
|
@ -210,38 +211,29 @@ Notifications::NotificationItem::NotificationItem(const char* title,
|
||||||
lv_obj_set_width(alert_caller, LV_HOR_RES - 20);
|
lv_obj_set_width(alert_caller, LV_HOR_RES - 20);
|
||||||
lv_label_set_text(alert_caller, msg);
|
lv_label_set_text(alert_caller, msg);
|
||||||
|
|
||||||
lv_obj_t* callBtnContainer = lv_cont_create(container1, NULL);
|
bt_accept = lv_btn_create(lv_scr_act(), nullptr);
|
||||||
lv_obj_set_width(callBtnContainer, 240);
|
|
||||||
lv_obj_set_height(callBtnContainer, 90);
|
|
||||||
lv_cont_set_layout(callBtnContainer, LV_LAYOUT_ROW_MID);
|
|
||||||
|
|
||||||
lv_obj_set_style_local_bg_color(callBtnContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x222222));
|
|
||||||
lv_obj_set_style_local_pad_all(callBtnContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
|
||||||
lv_obj_set_style_local_margin_top(callBtnContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 40);
|
|
||||||
lv_obj_set_style_local_margin_left(callBtnContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, -8);
|
|
||||||
lv_obj_set_style_local_pad_inner(callBtnContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 5);
|
|
||||||
lv_obj_set_style_local_border_width(callBtnContainer, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, 0);
|
|
||||||
|
|
||||||
bt_accept = lv_btn_create(callBtnContainer, nullptr);
|
|
||||||
bt_accept->user_data = this;
|
bt_accept->user_data = this;
|
||||||
lv_obj_set_event_cb(bt_accept, AcceptIncomingCallEventHandler);
|
lv_obj_set_event_cb(bt_accept, AcceptIncomingCallEventHandler);
|
||||||
lv_obj_set_size(bt_accept, (LV_HOR_RES / 3) - 5, 80);
|
lv_obj_set_size(bt_accept, 76, 76);
|
||||||
|
lv_obj_align(bt_accept, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
|
||||||
label_accept = lv_label_create(bt_accept, nullptr);
|
label_accept = lv_label_create(bt_accept, nullptr);
|
||||||
lv_label_set_text(label_accept, Symbols::phone);
|
lv_label_set_text(label_accept, Symbols::phone);
|
||||||
lv_obj_set_style_local_bg_color(bt_accept, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
|
lv_obj_set_style_local_bg_color(bt_accept, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
|
||||||
|
|
||||||
bt_reject = lv_btn_create(callBtnContainer, nullptr);
|
bt_reject = lv_btn_create(lv_scr_act(), nullptr);
|
||||||
bt_reject->user_data = this;
|
bt_reject->user_data = this;
|
||||||
lv_obj_set_event_cb(bt_reject, RejectIncomingCallEventHandler);
|
lv_obj_set_event_cb(bt_reject, RejectIncomingCallEventHandler);
|
||||||
lv_obj_set_size(bt_reject, (LV_HOR_RES / 3) - 5, 80);
|
lv_obj_set_size(bt_reject, 76, 76);
|
||||||
|
lv_obj_align(bt_reject, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
||||||
label_reject = lv_label_create(bt_reject, nullptr);
|
label_reject = lv_label_create(bt_reject, nullptr);
|
||||||
lv_label_set_text(label_reject, Symbols::phoneSlash);
|
lv_label_set_text(label_reject, Symbols::phoneSlash);
|
||||||
lv_obj_set_style_local_bg_color(bt_reject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
|
lv_obj_set_style_local_bg_color(bt_reject, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED);
|
||||||
|
|
||||||
bt_mute = lv_btn_create(callBtnContainer, nullptr);
|
bt_mute = lv_btn_create(lv_scr_act(), nullptr);
|
||||||
bt_mute->user_data = this;
|
bt_mute->user_data = this;
|
||||||
lv_obj_set_event_cb(bt_mute, MuteIncomingCallEventHandler);
|
lv_obj_set_event_cb(bt_mute, MuteIncomingCallEventHandler);
|
||||||
lv_obj_set_size(bt_mute, (LV_HOR_RES / 3) - 5, 80);
|
lv_obj_set_size(bt_mute, 76, 76);
|
||||||
|
lv_obj_align(bt_mute, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
|
||||||
label_mute = lv_label_create(bt_mute, nullptr);
|
label_mute = lv_label_create(bt_mute, nullptr);
|
||||||
lv_label_set_text(label_mute, Symbols::volumMute);
|
lv_label_set_text(label_mute, Symbols::volumMute);
|
||||||
lv_obj_set_style_local_bg_color(bt_mute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
|
lv_obj_set_style_local_bg_color(bt_mute, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
|
||||||
|
|
|
@ -4,98 +4,31 @@
|
||||||
|
|
||||||
using namespace Pinetime::Applications::Screens;
|
using namespace Pinetime::Applications::Screens;
|
||||||
|
|
||||||
namespace {
|
|
||||||
const uint8_t paddle_map[] = {
|
|
||||||
0xfc, 0xfe, 0xfc, 0xff, /*Color of index 0*/
|
|
||||||
0xff, 0xff, 0xff, 0xff, /*Color of index 1*/
|
|
||||||
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint8_t ball_map[] = {
|
|
||||||
0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed,
|
|
||||||
0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed,
|
|
||||||
0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed,
|
|
||||||
0x6f, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed,
|
|
||||||
0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0x6f, 0xed, 0x6f, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed,
|
|
||||||
0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed,
|
|
||||||
0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed,
|
|
||||||
0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed,
|
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed,
|
|
||||||
0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed, 0x6f, 0xed,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Paddle::Paddle(Pinetime::Applications::DisplayApp* app, Pinetime::Components::LittleVgl& lvgl) : Screen(app), lvgl {lvgl} {
|
Paddle::Paddle(Pinetime::Applications::DisplayApp* app, Pinetime::Components::LittleVgl& lvgl) : Screen(app), lvgl {lvgl} {
|
||||||
app->SetTouchMode(DisplayApp::TouchModes::Polling);
|
app->SetTouchMode(DisplayApp::TouchModes::Polling);
|
||||||
|
|
||||||
|
background = lv_obj_create(lv_scr_act(), nullptr);
|
||||||
|
lv_obj_set_size(background, LV_HOR_RES + 1, LV_VER_RES);
|
||||||
|
lv_obj_set_pos(background, -1, 0);
|
||||||
|
lv_obj_set_style_local_radius(background, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||||
|
lv_obj_set_style_local_bg_color(background, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
|
||||||
|
lv_obj_set_style_local_border_color(background, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||||
|
lv_obj_set_style_local_border_width(background, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 1);
|
||||||
|
|
||||||
points = lv_label_create(lv_scr_act(), nullptr);
|
points = lv_label_create(lv_scr_act(), nullptr);
|
||||||
|
lv_obj_set_style_local_text_font(points, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
|
||||||
lv_label_set_text(points, "0000");
|
lv_label_set_text(points, "0000");
|
||||||
lv_obj_set_style_local_text_color(points, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x444444));
|
lv_obj_align(points, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 10);
|
||||||
lv_obj_align(points, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 0);
|
|
||||||
|
|
||||||
paddle.header.always_zero = 0;
|
paddle = lv_obj_create(lv_scr_act(), nullptr);
|
||||||
paddle.header.w = 4;
|
lv_obj_set_style_local_bg_color(paddle, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||||
paddle.header.h = 60;
|
lv_obj_set_style_local_radius(paddle, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 0);
|
||||||
paddle.data_size = 68;
|
lv_obj_set_size(paddle, 4, 60);
|
||||||
paddle.header.cf = LV_IMG_CF_INDEXED_1BIT;
|
|
||||||
paddle.data = paddle_map;
|
|
||||||
paddle_image = lv_img_create(lv_scr_act(), nullptr);
|
|
||||||
lv_img_set_src(paddle_image, &paddle);
|
|
||||||
|
|
||||||
ball.header.always_zero = 0;
|
ball = lv_obj_create(lv_scr_act(), nullptr);
|
||||||
ball.header.w = 24;
|
lv_obj_set_style_local_bg_color(ball, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||||
ball.header.h = 24;
|
lv_obj_set_style_local_radius(ball, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE);
|
||||||
ball.data_size = 24 * 24 * LV_COLOR_SIZE / 8;
|
lv_obj_set_size(ball, ballSize, ballSize);
|
||||||
ball.header.cf = LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED;
|
|
||||||
ball.data = ball_map;
|
|
||||||
ball_image = lv_img_create(lv_scr_act(), nullptr);
|
|
||||||
lv_img_set_src(ball_image, &ball);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Paddle::~Paddle() {
|
Paddle::~Paddle() {
|
||||||
|
@ -105,41 +38,37 @@ Paddle::~Paddle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Paddle::Refresh() {
|
bool Paddle::Refresh() {
|
||||||
if ((counter++ % 5) == 0) {
|
ballX += dx;
|
||||||
counter = 0;
|
ballY += dy;
|
||||||
|
|
||||||
ballX += dx;
|
lv_obj_set_pos(ball, ballX, ballY);
|
||||||
ballY += dy;
|
|
||||||
|
|
||||||
lv_obj_set_pos(ball_image, ballX, ballY);
|
// checks if it has touched the sides (floor and ceiling)
|
||||||
|
if (ballY <= 1 || ballY >= LV_VER_RES - ballSize - 2) {
|
||||||
|
dy *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
// checks if it has touched the sides (floor and ceiling)
|
// checks if it has touched the side (left side)
|
||||||
if (ballY <= 0 || ballY >= 215) {
|
if (ballX >= LV_VER_RES - ballSize - 1) {
|
||||||
dy *= -1;
|
dx *= -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if it has touched the side (left side)
|
// checks if it is in the position of the paddle
|
||||||
if (ballX >= 215) {
|
if (dx < 0 && ballX <= 4) {
|
||||||
dx *= -1;
|
if (ballX >= -ballSize / 4) {
|
||||||
}
|
if (ballY <= (paddlePos + 30 - ballSize / 4) && ballY >= (paddlePos - 30 - ballSize + ballSize / 4)) {
|
||||||
|
|
||||||
// checks if it is in the position of the paddle
|
|
||||||
if (ballY <= (paddleBottomY + 16) && ballY >= (paddleTopY - 8)) {
|
|
||||||
if (ballX >= 0 && ballX < 4) {
|
|
||||||
lv_obj_set_pos(ball_image, 5, ballY);
|
|
||||||
dx *= -1;
|
dx *= -1;
|
||||||
score++;
|
score++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// checks if it has gone behind the paddle
|
// checks if it has gone behind the paddle
|
||||||
else if (ballX <= -40) {
|
else if (ballX <= -ballSize * 2) {
|
||||||
ballX = 107;
|
ballX = (LV_HOR_RES - ballSize) / 2;
|
||||||
ballY = 107;
|
ballY = (LV_VER_RES - ballSize) / 2;
|
||||||
score = 0;
|
score = 0;
|
||||||
}
|
}
|
||||||
lv_label_set_text_fmt(points, "%04d", score);
|
|
||||||
}
|
}
|
||||||
|
lv_label_set_text_fmt(points, "%04d", score);
|
||||||
return running;
|
return running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,11 +77,8 @@ bool Paddle::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Paddle::OnTouchEvent(uint16_t x, uint16_t y) {
|
bool Paddle::OnTouchEvent(uint16_t x, uint16_t y) {
|
||||||
lv_obj_set_pos(
|
// sets the center paddle pos. (30px offset) with the the y_coordinate of the finger
|
||||||
paddle_image,
|
lv_obj_set_pos(paddle, 0, y - 30);
|
||||||
0,
|
paddlePos = y;
|
||||||
y - 30); // sets the center paddle pos. (30px offset) with the the y_coordinate of the finger and defaults the x_coordinate to 0
|
|
||||||
paddleTopY = y - 30; // refreshes the upper extreme of the paddle
|
|
||||||
paddleBottomY = y + 30; // refreshes the lower extreme of the paddle
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,24 +24,22 @@ namespace Pinetime {
|
||||||
private:
|
private:
|
||||||
Pinetime::Components::LittleVgl& lvgl;
|
Pinetime::Components::LittleVgl& lvgl;
|
||||||
|
|
||||||
int paddleBottomY = 90; // bottom extreme of the paddle
|
const uint8_t ballSize = 16;
|
||||||
int paddleTopY = 150; // top extreme of the paddle
|
|
||||||
|
|
||||||
int ballX = 107; // Initial x_coordinate for the ball (12px offset from the center to counteract the ball's 24px size)
|
uint16_t paddlePos = 30; // Paddle center
|
||||||
int ballY = 107; // Initial y_coordinate for the ball
|
|
||||||
|
|
||||||
int dx = 2; // Velocity of the ball in the x_coordinate
|
int16_t ballX = (LV_HOR_RES - ballSize) / 2;
|
||||||
int dy = 3; // Velocity of the ball in the y_coordinate
|
int16_t ballY = (LV_VER_RES - ballSize) / 2;
|
||||||
|
|
||||||
int counter = 0; // init Frame refresh limit counter
|
int8_t dx = 2; // Velocity of the ball in the x_coordinate
|
||||||
int score = 0;
|
int8_t dy = 3; // Velocity of the ball in the y_coordinate
|
||||||
|
|
||||||
lv_img_dsc_t paddle;
|
uint16_t score = 0;
|
||||||
lv_img_dsc_t ball;
|
|
||||||
|
|
||||||
lv_obj_t* points;
|
lv_obj_t* points;
|
||||||
lv_obj_t* paddle_image; // pointer to paddle image
|
lv_obj_t* paddle;
|
||||||
lv_obj_t* ball_image; // pointer to ball image
|
lv_obj_t* ball;
|
||||||
|
lv_obj_t* background;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,8 +186,8 @@ PineTimeStyle::PineTimeStyle(DisplayApp* app,
|
||||||
lv_obj_align(stepGauge, sidebar, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
lv_obj_align(stepGauge, sidebar, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
|
||||||
lv_gauge_set_scale(stepGauge, 360, 11, 0);
|
lv_gauge_set_scale(stepGauge, 360, 11, 0);
|
||||||
lv_gauge_set_angle_offset(stepGauge, 180);
|
lv_gauge_set_angle_offset(stepGauge, 180);
|
||||||
lv_gauge_set_critical_value(stepGauge, (settingsController.GetStepsGoal() / 100));
|
lv_gauge_set_critical_value(stepGauge, 100);
|
||||||
lv_gauge_set_range(stepGauge, 0, (settingsController.GetStepsGoal() / 100));
|
lv_gauge_set_range(stepGauge, 0, 100);
|
||||||
lv_gauge_set_value(stepGauge, 0, 0);
|
lv_gauge_set_value(stepGauge, 0, 0);
|
||||||
|
|
||||||
lv_obj_set_style_local_pad_right(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 3);
|
lv_obj_set_style_local_pad_right(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, 3);
|
||||||
|
@ -335,7 +335,7 @@ bool PineTimeStyle::Refresh() {
|
||||||
stepCount = motionController.NbSteps();
|
stepCount = motionController.NbSteps();
|
||||||
motionSensorOk = motionController.IsSensorOk();
|
motionSensorOk = motionController.IsSensorOk();
|
||||||
if (stepCount.IsUpdated() || motionSensorOk.IsUpdated()) {
|
if (stepCount.IsUpdated() || motionSensorOk.IsUpdated()) {
|
||||||
lv_gauge_set_value(stepGauge, 0, (stepCount.Get() / 100));
|
lv_gauge_set_value(stepGauge, 0, (stepCount.Get() / (settingsController.GetStepsGoal() / 100)));
|
||||||
lv_obj_realign(stepGauge);
|
lv_obj_realign(stepGauge);
|
||||||
if (stepCount.Get() > settingsController.GetStepsGoal()) {
|
if (stepCount.Get() > settingsController.GetStepsGoal()) {
|
||||||
lv_obj_set_style_local_line_color(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
lv_obj_set_style_local_line_color(stepGauge, LV_GAUGE_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_WHITE);
|
||||||
|
|
|
@ -41,16 +41,15 @@ Steps::Steps(
|
||||||
|
|
||||||
lv_obj_t * lstepsGoal = lv_label_create(lv_scr_act(), nullptr);
|
lv_obj_t * lstepsGoal = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_obj_set_style_local_text_color(lstepsGoal, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_CYAN);
|
lv_obj_set_style_local_text_color(lstepsGoal, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_CYAN);
|
||||||
lv_label_set_text_fmt(lstepsGoal,"Goal\n%i", settingsController.GetStepsGoal());
|
lv_label_set_text_fmt(lstepsGoal, "Goal\n%lu", settingsController.GetStepsGoal());
|
||||||
lv_label_set_align(lstepsGoal, LV_LABEL_ALIGN_CENTER);
|
lv_label_set_align(lstepsGoal, LV_LABEL_ALIGN_CENTER);
|
||||||
lv_obj_align(lstepsGoal, lSteps, LV_ALIGN_OUT_BOTTOM_MID, 0, 60);
|
lv_obj_align(lstepsGoal, lSteps, LV_ALIGN_OUT_BOTTOM_MID, 0, 60);
|
||||||
|
|
||||||
lv_obj_t * backgroundLabel = lv_label_create(lv_scr_act(), nullptr);
|
lv_obj_t* backgroundLabel = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP);
|
lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP);
|
||||||
lv_obj_set_size(backgroundLabel, 240, 240);
|
lv_obj_set_size(backgroundLabel, 240, 240);
|
||||||
lv_obj_set_pos(backgroundLabel, 0, 0);
|
lv_obj_set_pos(backgroundLabel, 0, 0);
|
||||||
lv_label_set_text_static(backgroundLabel, "");
|
lv_label_set_text_static(backgroundLabel, "");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Steps::~Steps() {
|
Steps::~Steps() {
|
||||||
|
@ -61,12 +60,10 @@ bool Steps::Refresh() {
|
||||||
|
|
||||||
stepsCount = motionController.NbSteps();
|
stepsCount = motionController.NbSteps();
|
||||||
|
|
||||||
lv_label_set_text_fmt(lSteps,"%li", stepsCount);
|
lv_label_set_text_fmt(lSteps, "%li", stepsCount);
|
||||||
lv_obj_align(lSteps, nullptr, LV_ALIGN_CENTER, 0, -20);
|
lv_obj_align(lSteps, nullptr, LV_ALIGN_CENTER, 0, -20);
|
||||||
|
|
||||||
lv_arc_set_value(stepsArc, int16_t(500 * stepsCount / settingsController.GetStepsGoal()));
|
lv_arc_set_value(stepsArc, int16_t(500 * stepsCount / settingsController.GetStepsGoal()));
|
||||||
|
|
||||||
return running;
|
return running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -45,17 +45,16 @@ static void stop_lap_event_handler(lv_obj_t* obj, lv_event_t event) {
|
||||||
stopWatch->stopLapBtnEventHandler(event);
|
stopWatch->stopLapBtnEventHandler(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
StopWatch::StopWatch(DisplayApp* app)
|
StopWatch::StopWatch(DisplayApp* app, System::SystemTask& systemTask)
|
||||||
: Screen(app),
|
: Screen(app),
|
||||||
|
systemTask {systemTask},
|
||||||
running {true},
|
running {true},
|
||||||
currentState {States::Init},
|
currentState {States::Init},
|
||||||
currentEvent {Events::Stop},
|
|
||||||
startTime {},
|
startTime {},
|
||||||
oldTimeElapsed {},
|
oldTimeElapsed {},
|
||||||
currentTimeSeparated {},
|
currentTimeSeparated {},
|
||||||
lapBuffer {},
|
lapBuffer {},
|
||||||
lapNr {},
|
lapNr {} {
|
||||||
lapPressed {false} {
|
|
||||||
|
|
||||||
time = lv_label_create(lv_scr_act(), nullptr);
|
time = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76);
|
lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76);
|
||||||
|
@ -105,128 +104,100 @@ StopWatch::StopWatch(DisplayApp* app)
|
||||||
}
|
}
|
||||||
|
|
||||||
StopWatch::~StopWatch() {
|
StopWatch::~StopWatch() {
|
||||||
|
systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping);
|
||||||
lv_obj_clean(lv_scr_act());
|
lv_obj_clean(lv_scr_act());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StopWatch::reset() {
|
||||||
|
currentState = States::Init;
|
||||||
|
oldTimeElapsed = 0;
|
||||||
|
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
|
||||||
|
lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
|
||||||
|
|
||||||
|
lv_label_set_text(time, "00:00");
|
||||||
|
lv_label_set_text(msecTime, "00");
|
||||||
|
|
||||||
|
lv_label_set_text(lapOneText, "");
|
||||||
|
lv_label_set_text(lapTwoText, "");
|
||||||
|
lapBuffer.clearBuffer();
|
||||||
|
lapNr = 0;
|
||||||
|
lv_obj_set_state(btnStopLap, LV_STATE_DISABLED);
|
||||||
|
lv_obj_set_state(txtStopLap, LV_STATE_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StopWatch::start() {
|
||||||
|
lv_obj_set_state(btnStopLap, LV_STATE_DEFAULT);
|
||||||
|
lv_obj_set_state(txtStopLap, LV_STATE_DEFAULT);
|
||||||
|
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
|
||||||
|
lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
|
||||||
|
lv_label_set_text(txtPlayPause, Symbols::pause);
|
||||||
|
lv_label_set_text(txtStopLap, Symbols::lapsFlag);
|
||||||
|
startTime = xTaskGetTickCount();
|
||||||
|
currentState = States::Running;
|
||||||
|
systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StopWatch::pause() {
|
||||||
|
startTime = 0;
|
||||||
|
// Store the current time elapsed in cache
|
||||||
|
oldTimeElapsed += timeElapsed;
|
||||||
|
currentState = States::Halted;
|
||||||
|
lv_label_set_text(txtPlayPause, Symbols::play);
|
||||||
|
lv_label_set_text(txtStopLap, Symbols::stop);
|
||||||
|
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
|
||||||
|
lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
|
||||||
|
systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping);
|
||||||
|
}
|
||||||
|
|
||||||
bool StopWatch::Refresh() {
|
bool StopWatch::Refresh() {
|
||||||
// @startuml CHIP8_state
|
if (currentState == States::Running) {
|
||||||
// State "Init" as init
|
timeElapsed = calculateDelta(startTime, xTaskGetTickCount());
|
||||||
// State "Running" as run
|
currentTimeSeparated = convertTicksToTimeSegments((oldTimeElapsed + timeElapsed));
|
||||||
// State "Halted" as halt
|
|
||||||
|
|
||||||
// [*] --> init
|
lv_label_set_text_fmt(time, "%02d:%02d", currentTimeSeparated.mins, currentTimeSeparated.secs);
|
||||||
// init -> run : press play
|
lv_label_set_text_fmt(msecTime, "%02d", currentTimeSeparated.hundredths);
|
||||||
// run -> run : press lap
|
|
||||||
// run --> halt : press pause
|
|
||||||
// halt --> run : press play
|
|
||||||
// halt --> init : press stop
|
|
||||||
// @enduml
|
|
||||||
// Copy paste the above plantuml text to visualize the state diagram
|
|
||||||
switch (currentState) {
|
|
||||||
// Init state when an user first opens the app
|
|
||||||
// and when a stop/reset button is pressed
|
|
||||||
case States::Init: {
|
|
||||||
// The initial default value
|
|
||||||
lv_label_set_text(time, "00:00");
|
|
||||||
lv_label_set_text(msecTime, "00");
|
|
||||||
|
|
||||||
lv_label_set_text(lapOneText, "");
|
|
||||||
lv_label_set_text(lapTwoText, "");
|
|
||||||
lapBuffer.clearBuffer();
|
|
||||||
lapNr = 0;
|
|
||||||
|
|
||||||
if (currentEvent == Events::Play) {
|
|
||||||
lv_obj_set_state(btnStopLap, LV_STATE_DEFAULT);
|
|
||||||
lv_obj_set_state(txtStopLap, LV_STATE_DEFAULT);
|
|
||||||
|
|
||||||
startTime = xTaskGetTickCount();
|
|
||||||
currentState = States::Running;
|
|
||||||
} else {
|
|
||||||
lv_obj_set_state(btnStopLap, LV_STATE_DISABLED);
|
|
||||||
lv_obj_set_state(txtStopLap, LV_STATE_DISABLED);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case States::Running: {
|
|
||||||
lv_label_set_text(txtPlayPause, Symbols::pause);
|
|
||||||
lv_label_set_text(txtStopLap, Symbols::lapsFlag);
|
|
||||||
|
|
||||||
const auto timeElapsed = calculateDelta(startTime, xTaskGetTickCount());
|
|
||||||
currentTimeSeparated = convertTicksToTimeSegments((oldTimeElapsed + timeElapsed));
|
|
||||||
|
|
||||||
lv_label_set_text_fmt(time, "%02d:%02d", currentTimeSeparated.mins, currentTimeSeparated.secs);
|
|
||||||
lv_label_set_text_fmt(msecTime, "%02d", currentTimeSeparated.hundredths);
|
|
||||||
|
|
||||||
if (lapPressed == true) {
|
|
||||||
if (lapBuffer[1]) {
|
|
||||||
lv_label_set_text_fmt(
|
|
||||||
lapOneText, "#%2d %2d:%02d.%02d", (lapNr - 1), lapBuffer[1]->mins, lapBuffer[1]->secs, lapBuffer[1]->hundredths);
|
|
||||||
}
|
|
||||||
if (lapBuffer[0]) {
|
|
||||||
lv_label_set_text_fmt(
|
|
||||||
lapTwoText, "#%2d %2d:%02d.%02d", lapNr, lapBuffer[0]->mins, lapBuffer[0]->secs, lapBuffer[0]->hundredths);
|
|
||||||
}
|
|
||||||
// Reset the bool to avoid setting the text in each cycle until there is a change
|
|
||||||
lapPressed = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentEvent == Events::Pause) {
|
|
||||||
// Reset the start time
|
|
||||||
startTime = 0;
|
|
||||||
// Store the current time elapsed in cache
|
|
||||||
oldTimeElapsed += timeElapsed;
|
|
||||||
currentState = States::Halted;
|
|
||||||
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
|
|
||||||
lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW);
|
|
||||||
} else {
|
|
||||||
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
|
|
||||||
lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case States::Halted: {
|
|
||||||
lv_label_set_text(txtPlayPause, Symbols::play);
|
|
||||||
lv_label_set_text(txtStopLap, Symbols::stop);
|
|
||||||
|
|
||||||
if (currentEvent == Events::Play) {
|
|
||||||
startTime = xTaskGetTickCount();
|
|
||||||
currentState = States::Running;
|
|
||||||
}
|
|
||||||
if (currentEvent == Events::Stop) {
|
|
||||||
currentState = States::Init;
|
|
||||||
oldTimeElapsed = 0;
|
|
||||||
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
|
|
||||||
lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return running;
|
return running;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopWatch::playPauseBtnEventHandler(lv_event_t event) {
|
void StopWatch::playPauseBtnEventHandler(lv_event_t event) {
|
||||||
if (event == LV_EVENT_CLICKED) {
|
if (event != LV_EVENT_PRESSED) {
|
||||||
if (currentState == States::Init) {
|
return;
|
||||||
currentEvent = Events::Play;
|
}
|
||||||
} else {
|
if (currentState == States::Init) {
|
||||||
// Simple Toggle for play/pause
|
start();
|
||||||
currentEvent = (currentEvent == Events::Play ? Events::Pause : Events::Play);
|
} else if (currentState == States::Running) {
|
||||||
}
|
pause();
|
||||||
|
} else if (currentState == States::Halted) {
|
||||||
|
start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopWatch::stopLapBtnEventHandler(lv_event_t event) {
|
void StopWatch::stopLapBtnEventHandler(lv_event_t event) {
|
||||||
if (event == LV_EVENT_CLICKED) {
|
if (event != LV_EVENT_PRESSED) {
|
||||||
// If running, then this button is used to save laps
|
return;
|
||||||
if (currentState == States::Running) {
|
}
|
||||||
lapBuffer.addLaps(currentTimeSeparated);
|
// If running, then this button is used to save laps
|
||||||
lapNr++;
|
if (currentState == States::Running) {
|
||||||
lapPressed = true;
|
lapBuffer.addLaps(currentTimeSeparated);
|
||||||
|
lapNr++;
|
||||||
} else if (currentState == States::Halted) {
|
if (lapBuffer[1]) {
|
||||||
currentEvent = Events::Stop;
|
lv_label_set_text_fmt(
|
||||||
} else {
|
lapOneText, "#%2d %2d:%02d.%02d", (lapNr - 1), lapBuffer[1]->mins, lapBuffer[1]->secs, lapBuffer[1]->hundredths);
|
||||||
// Not possible to reach here. Do nothing.
|
|
||||||
}
|
}
|
||||||
|
if (lapBuffer[0]) {
|
||||||
|
lv_label_set_text_fmt(lapTwoText, "#%2d %2d:%02d.%02d", lapNr, lapBuffer[0]->mins, lapBuffer[0]->secs, lapBuffer[0]->hundredths);
|
||||||
|
}
|
||||||
|
} else if (currentState == States::Halted) {
|
||||||
|
reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StopWatch::OnButtonPushed() {
|
||||||
|
if (currentState == States::Running) {
|
||||||
|
pause();
|
||||||
|
} else {
|
||||||
|
running = false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -8,13 +8,12 @@
|
||||||
#include "portmacro_cmsis.h"
|
#include "portmacro_cmsis.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include "systemtask/SystemTask.h"
|
||||||
|
|
||||||
namespace Pinetime::Applications::Screens {
|
namespace Pinetime::Applications::Screens {
|
||||||
|
|
||||||
enum class States { Init, Running, Halted };
|
enum class States { Init, Running, Halted };
|
||||||
|
|
||||||
enum class Events { Play, Pause, Stop };
|
|
||||||
|
|
||||||
struct TimeSeparated_t {
|
struct TimeSeparated_t {
|
||||||
int mins;
|
int mins;
|
||||||
int secs;
|
int secs;
|
||||||
|
@ -63,23 +62,28 @@ namespace Pinetime::Applications::Screens {
|
||||||
|
|
||||||
class StopWatch : public Screen {
|
class StopWatch : public Screen {
|
||||||
public:
|
public:
|
||||||
StopWatch(DisplayApp* app);
|
StopWatch(DisplayApp* app, System::SystemTask& systemTask);
|
||||||
~StopWatch() override;
|
~StopWatch() override;
|
||||||
bool Refresh() override;
|
bool Refresh() override;
|
||||||
|
|
||||||
void playPauseBtnEventHandler(lv_event_t event);
|
void playPauseBtnEventHandler(lv_event_t event);
|
||||||
void stopLapBtnEventHandler(lv_event_t event);
|
void stopLapBtnEventHandler(lv_event_t event);
|
||||||
|
bool OnButtonPushed() override;
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
void start();
|
||||||
|
void pause();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Pinetime::System::SystemTask& systemTask;
|
||||||
|
TickType_t timeElapsed;
|
||||||
bool running;
|
bool running;
|
||||||
States currentState;
|
States currentState;
|
||||||
Events currentEvent;
|
|
||||||
TickType_t startTime;
|
TickType_t startTime;
|
||||||
TickType_t oldTimeElapsed;
|
TickType_t oldTimeElapsed;
|
||||||
TimeSeparated_t currentTimeSeparated; // Holds Mins, Secs, millisecs
|
TimeSeparated_t currentTimeSeparated; // Holds Mins, Secs, millisecs
|
||||||
LapTextBuffer_t<2> lapBuffer;
|
LapTextBuffer_t<2> lapBuffer;
|
||||||
int lapNr;
|
int lapNr = 0;
|
||||||
bool lapPressed;
|
|
||||||
lv_obj_t *time, *msecTime, *btnPlayPause, *btnStopLap, *txtPlayPause, *txtStopLap;
|
lv_obj_t *time, *msecTime, *btnPlayPause, *btnStopLap, *txtPlayPause, *txtStopLap;
|
||||||
lv_obj_t *lapOneText, *lapTwoText;
|
lv_obj_t *lapOneText, *lapTwoText;
|
||||||
};
|
};
|
||||||
|
|
|
@ -40,6 +40,7 @@ namespace Pinetime {
|
||||||
static constexpr const char* stopWatch = "\xEF\x8B\xB2";
|
static constexpr const char* stopWatch = "\xEF\x8B\xB2";
|
||||||
static constexpr const char* hourGlass = "\xEF\x89\x92";
|
static constexpr const char* hourGlass = "\xEF\x89\x92";
|
||||||
static constexpr const char* lapsFlag = "\xEF\x80\xA4";
|
static constexpr const char* lapsFlag = "\xEF\x80\xA4";
|
||||||
|
static constexpr const char* drum = "\xEF\x95\xA9";
|
||||||
|
|
||||||
// lv_font_sys_48.c
|
// lv_font_sys_48.c
|
||||||
static constexpr const char* settings = "\xEE\xA4\x82"; // e902
|
static constexpr const char* settings = "\xEE\xA4\x82"; // e902
|
||||||
|
|
|
@ -104,8 +104,6 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen1() {
|
||||||
|
|
||||||
std::unique_ptr<Screen> SystemInfo::CreateScreen2() {
|
std::unique_ptr<Screen> SystemInfo::CreateScreen2() {
|
||||||
auto batteryPercent = static_cast<uint8_t>(batteryController.PercentRemaining());
|
auto batteryPercent = static_cast<uint8_t>(batteryController.PercentRemaining());
|
||||||
float batteryVoltage = batteryController.Voltage();
|
|
||||||
|
|
||||||
auto resetReason = [this]() {
|
auto resetReason = [this]() {
|
||||||
switch (watchdog.ResetReason()) {
|
switch (watchdog.ResetReason()) {
|
||||||
case Drivers::Watchdog::ResetReasons::Watchdog:
|
case Drivers::Watchdog::ResetReasons::Watchdog:
|
||||||
|
@ -144,18 +142,13 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen2() {
|
||||||
uptimeSeconds = uptimeSeconds % secondsInAMinute;
|
uptimeSeconds = uptimeSeconds % secondsInAMinute;
|
||||||
// TODO handle more than 100 days of uptime
|
// TODO handle more than 100 days of uptime
|
||||||
|
|
||||||
// hack to not use the flot functions from printf
|
|
||||||
uint8_t batteryVoltageBytes[2];
|
|
||||||
batteryVoltageBytes[1] = static_cast<uint8_t>(batteryVoltage); // truncate whole numbers
|
|
||||||
batteryVoltageBytes[0] = static_cast<uint8_t>((batteryVoltage - batteryVoltageBytes[1]) * 100); // remove whole part of flt and shift 2 places over
|
|
||||||
|
|
||||||
lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr);
|
lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr);
|
||||||
lv_label_set_recolor(label, true);
|
lv_label_set_recolor(label, true);
|
||||||
lv_label_set_text_fmt(label,
|
lv_label_set_text_fmt(label,
|
||||||
"#444444 Date# %02d/%02d/%04d\n"
|
"#444444 Date# %02d/%02d/%04d\n"
|
||||||
"#444444 Time# %02d:%02d:%02d\n"
|
"#444444 Time# %02d:%02d:%02d\n"
|
||||||
"#444444 Uptime#\n %02lud %02lu:%02lu:%02lu\n"
|
"#444444 Uptime#\n %02lud %02lu:%02lu:%02lu\n"
|
||||||
"#444444 Battery# %d%%/%1i.%02iv\n"
|
"#444444 Battery# %d%%/%03imV\n"
|
||||||
"#444444 Backlight# %s\n"
|
"#444444 Backlight# %s\n"
|
||||||
"#444444 Last reset# %s\n"
|
"#444444 Last reset# %s\n"
|
||||||
"#444444 Accel.# %s\n",
|
"#444444 Accel.# %s\n",
|
||||||
|
@ -170,8 +163,7 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen2() {
|
||||||
uptimeMinutes,
|
uptimeMinutes,
|
||||||
uptimeSeconds,
|
uptimeSeconds,
|
||||||
batteryPercent,
|
batteryPercent,
|
||||||
batteryVoltageBytes[1],
|
batteryController.Voltage(),
|
||||||
batteryVoltageBytes[0],
|
|
||||||
brightnessController.ToString(),
|
brightnessController.ToString(),
|
||||||
resetReason,
|
resetReason,
|
||||||
ToString(motionController.DeviceType()));
|
ToString(motionController.DeviceType()));
|
||||||
|
@ -192,22 +184,22 @@ std::unique_ptr<Screen> SystemInfo::CreateScreen3() {
|
||||||
"\n"
|
"\n"
|
||||||
"#444444 LVGL Memory#\n"
|
"#444444 LVGL Memory#\n"
|
||||||
" #444444 used# %d (%d%%)\n"
|
" #444444 used# %d (%d%%)\n"
|
||||||
" #444444 max used# %d\n"
|
" #444444 max used# %lu\n"
|
||||||
" #444444 frag# %d%%\n"
|
" #444444 frag# %d%%\n"
|
||||||
" #444444 free# %d"
|
" #444444 free# %d"
|
||||||
"\n"
|
"\n"
|
||||||
"#444444 Steps# %li",
|
"#444444 Steps# %i",
|
||||||
bleAddr[5],
|
bleAddr[5],
|
||||||
bleAddr[4],
|
bleAddr[4],
|
||||||
bleAddr[3],
|
bleAddr[3],
|
||||||
bleAddr[2],
|
bleAddr[2],
|
||||||
bleAddr[1],
|
bleAddr[1],
|
||||||
bleAddr[0],
|
bleAddr[0],
|
||||||
(int) mon.total_size - mon.free_size,
|
static_cast<int>(mon.total_size - mon.free_size),
|
||||||
mon.used_pct,
|
mon.used_pct,
|
||||||
mon.max_used,
|
mon.max_used,
|
||||||
mon.frag_pct,
|
mon.frag_pct,
|
||||||
(int) mon.free_biggest_size,
|
static_cast<int>(mon.free_biggest_size),
|
||||||
0);
|
0);
|
||||||
lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0);
|
lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0);
|
||||||
return std::make_unique<Screens::Label>(2, 5, app, label);
|
return std::make_unique<Screens::Label>(2, 5, app, label);
|
||||||
|
|
|
@ -63,7 +63,7 @@ Timer::Timer(DisplayApp* app, Controllers::TimerController& timerController)
|
||||||
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
|
lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
|
||||||
|
|
||||||
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
|
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
|
||||||
lv_label_set_text_fmt(time, "%02d:%02d", seconds / 60, seconds % 60);
|
lv_label_set_text_fmt(time, "%02lu:%02lu", seconds / 60, seconds % 60);
|
||||||
|
|
||||||
lv_obj_align(time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -20);
|
lv_obj_align(time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -20);
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ Timer::~Timer() {
|
||||||
bool Timer::Refresh() {
|
bool Timer::Refresh() {
|
||||||
if (timerController.IsRunning()) {
|
if (timerController.IsRunning()) {
|
||||||
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
|
uint32_t seconds = timerController.GetTimeRemaining() / 1000;
|
||||||
lv_label_set_text_fmt(time, "%02d:%02d", seconds / 60, seconds % 60);
|
lv_label_set_text_fmt(time, "%02lu:%02lu", seconds / 60, seconds % 60);
|
||||||
}
|
}
|
||||||
return running;
|
return running;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,27 +5,44 @@
|
||||||
#include "Symbols.h"
|
#include "Symbols.h"
|
||||||
#include "NotificationIcon.h"
|
#include "NotificationIcon.h"
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
LV_IMG_DECLARE(bg_clock);
|
LV_IMG_DECLARE(bg_clock);
|
||||||
|
|
||||||
using namespace Pinetime::Applications::Screens;
|
using namespace Pinetime::Applications::Screens;
|
||||||
|
|
||||||
#define HOUR_LENGTH 70
|
namespace {
|
||||||
#define MINUTE_LENGTH 90
|
|
||||||
#define SECOND_LENGTH 110
|
|
||||||
#define PI 3.14159265358979323846
|
|
||||||
|
|
||||||
// ##
|
constexpr auto HOUR_LENGTH = 70;
|
||||||
static int16_t coordinate_x_relocate(int16_t x) {
|
constexpr auto MINUTE_LENGTH = 90;
|
||||||
return ((x) + LV_HOR_RES / 2);
|
constexpr auto SECOND_LENGTH = 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);
|
||||||
|
|
||||||
|
int16_t cosine(int16_t angle) {
|
||||||
|
return _lv_trigo_sin(angle + 90);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ##
|
int16_t sine(int16_t angle) {
|
||||||
static int16_t coordinate_y_relocate(int16_t y) {
|
return _lv_trigo_sin(angle);
|
||||||
return (((y) -LV_HOR_RES / 2) < 0) ? (0 - ((y) -LV_HOR_RES / 2)) : ((y) -LV_HOR_RES / 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int16_t coordinate_x_relocate(int16_t x) {
|
||||||
|
return (x + LV_HOR_RES / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t coordinate_y_relocate(int16_t y) {
|
||||||
|
return std::abs(y - LV_HOR_RES / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
lv_point_t coordinate_relocate(int16_t radius, int16_t angle) {
|
||||||
|
return lv_point_t{
|
||||||
|
.x = coordinate_x_relocate(radius * static_cast<int32_t>(sine(angle)) / LV_TRIG_SCALE),
|
||||||
|
.y = coordinate_y_relocate(radius * static_cast<int32_t>(cosine(angle)) / LV_TRIG_SCALE)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app,
|
WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app,
|
||||||
Controllers::DateTime& dateTimeController,
|
Controllers::DateTime& dateTimeController,
|
||||||
Controllers::Battery& batteryController,
|
Controllers::Battery& batteryController,
|
||||||
|
@ -123,15 +140,12 @@ void WatchFaceAnalog::UpdateClock() {
|
||||||
second = dateTimeController.Seconds();
|
second = dateTimeController.Seconds();
|
||||||
|
|
||||||
if (sMinute != minute) {
|
if (sMinute != minute) {
|
||||||
minute_point[0].x = coordinate_x_relocate(30 * sin(minute * 6 * PI / 180));
|
auto const angle = minute * 6;
|
||||||
minute_point[0].y = coordinate_y_relocate(30 * cos(minute * 6 * PI / 180));
|
minute_point[0] = coordinate_relocate(30, angle);
|
||||||
minute_point[1].x = coordinate_x_relocate(MINUTE_LENGTH * sin(minute * 6 * PI / 180));
|
minute_point[1] = coordinate_relocate(MINUTE_LENGTH, angle);
|
||||||
minute_point[1].y = coordinate_y_relocate(MINUTE_LENGTH * cos(minute * 6 * PI / 180));
|
|
||||||
|
|
||||||
minute_point_trace[0].x = coordinate_x_relocate(5 * sin(minute * 6 * PI / 180));
|
minute_point_trace[0] = coordinate_relocate(5, angle);
|
||||||
minute_point_trace[0].y = coordinate_y_relocate(5 * cos(minute * 6 * PI / 180));
|
minute_point_trace[1] = coordinate_relocate(31, angle);
|
||||||
minute_point_trace[1].x = coordinate_x_relocate(31 * sin(minute * 6 * PI / 180));
|
|
||||||
minute_point_trace[1].y = coordinate_y_relocate(31 * cos(minute * 6 * PI / 180));
|
|
||||||
|
|
||||||
lv_line_set_points(minute_body, minute_point, 2);
|
lv_line_set_points(minute_body, minute_point, 2);
|
||||||
lv_line_set_points(minute_body_trace, minute_point_trace, 2);
|
lv_line_set_points(minute_body_trace, minute_point_trace, 2);
|
||||||
|
@ -140,15 +154,13 @@ void WatchFaceAnalog::UpdateClock() {
|
||||||
if (sHour != hour || sMinute != minute) {
|
if (sHour != hour || sMinute != minute) {
|
||||||
sHour = hour;
|
sHour = hour;
|
||||||
sMinute = minute;
|
sMinute = minute;
|
||||||
hour_point[0].x = coordinate_x_relocate(30 * sin((((hour > 12 ? hour - 12 : hour) * 30) + (minute * 0.5)) * PI / 180));
|
auto const angle = (hour * 30 + minute / 2);
|
||||||
hour_point[0].y = coordinate_y_relocate(30 * cos((((hour > 12 ? hour - 12 : hour) * 30) + (minute * 0.5)) * PI / 180));
|
|
||||||
hour_point[1].x = coordinate_x_relocate(HOUR_LENGTH * sin((((hour > 12 ? hour - 12 : hour) * 30) + (minute * 0.5)) * PI / 180));
|
|
||||||
hour_point[1].y = coordinate_y_relocate(HOUR_LENGTH * cos((((hour > 12 ? hour - 12 : hour) * 30) + (minute * 0.5)) * PI / 180));
|
|
||||||
|
|
||||||
hour_point_trace[0].x = coordinate_x_relocate(5 * sin((((hour > 12 ? hour - 12 : hour) * 30) + (minute * 0.5)) * PI / 180));
|
hour_point[0] = coordinate_relocate(30, angle);
|
||||||
hour_point_trace[0].y = coordinate_y_relocate(5 * cos((((hour > 12 ? hour - 12 : hour) * 30) + (minute * 0.5)) * PI / 180));
|
hour_point[1] = coordinate_relocate(HOUR_LENGTH, angle);
|
||||||
hour_point_trace[1].x = coordinate_x_relocate(31 * sin((((hour > 12 ? hour - 12 : hour) * 30) + (minute * 0.5)) * PI / 180));
|
|
||||||
hour_point_trace[1].y = coordinate_y_relocate(31 * cos((((hour > 12 ? hour - 12 : hour) * 30) + (minute * 0.5)) * PI / 180));
|
hour_point_trace[0] = coordinate_relocate(5, angle);
|
||||||
|
hour_point_trace[1] = coordinate_relocate(31, angle);
|
||||||
|
|
||||||
lv_line_set_points(hour_body, hour_point, 2);
|
lv_line_set_points(hour_body, hour_point, 2);
|
||||||
lv_line_set_points(hour_body_trace, hour_point_trace, 2);
|
lv_line_set_points(hour_body_trace, hour_point_trace, 2);
|
||||||
|
@ -156,10 +168,10 @@ void WatchFaceAnalog::UpdateClock() {
|
||||||
|
|
||||||
if (sSecond != second) {
|
if (sSecond != second) {
|
||||||
sSecond = second;
|
sSecond = second;
|
||||||
second_point[0].x = coordinate_x_relocate(20 * sin((180 + second * 6) * PI / 180));
|
auto const angle = second * 6;
|
||||||
second_point[0].y = coordinate_y_relocate(20 * cos((180 + second * 6) * PI / 180));
|
|
||||||
second_point[1].x = coordinate_x_relocate(SECOND_LENGTH * sin(second * 6 * PI / 180));
|
second_point[0] = coordinate_relocate(-20, angle);
|
||||||
second_point[1].y = coordinate_y_relocate(SECOND_LENGTH * cos(second * 6 * PI / 180));
|
second_point[1] = coordinate_relocate(SECOND_LENGTH, angle);
|
||||||
lv_line_set_points(second_body, second_point, 2);
|
lv_line_set_points(second_body, second_point, 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ SettingSteps::SettingSteps(
|
||||||
|
|
||||||
stepValue = lv_label_create(lv_scr_act(), NULL);
|
stepValue = lv_label_create(lv_scr_act(), NULL);
|
||||||
lv_obj_set_style_local_text_font(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
|
lv_obj_set_style_local_text_font(stepValue, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_42);
|
||||||
lv_label_set_text_fmt(stepValue,"%i", settingsController.GetStepsGoal());
|
lv_label_set_text_fmt(stepValue, "%lu", settingsController.GetStepsGoal());
|
||||||
lv_label_set_align(stepValue, LV_LABEL_ALIGN_CENTER);
|
lv_label_set_align(stepValue, LV_LABEL_ALIGN_CENTER);
|
||||||
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_CENTER, 0, -10);
|
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_CENTER, 0, -10);
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ void SettingSteps::UpdateSelected(lv_obj_t *object, lv_event_t event) {
|
||||||
value += 1000;
|
value += 1000;
|
||||||
if ( value <= 500000 ) {
|
if ( value <= 500000 ) {
|
||||||
settingsController.SetStepsGoal(value);
|
settingsController.SetStepsGoal(value);
|
||||||
lv_label_set_text_fmt(stepValue,"%i", settingsController.GetStepsGoal());
|
lv_label_set_text_fmt(stepValue, "%lu", settingsController.GetStepsGoal());
|
||||||
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_CENTER, 0, -10);
|
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_CENTER, 0, -10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ void SettingSteps::UpdateSelected(lv_obj_t *object, lv_event_t event) {
|
||||||
value -= 1000;
|
value -= 1000;
|
||||||
if ( value >= 1000 ) {
|
if ( value >= 1000 ) {
|
||||||
settingsController.SetStepsGoal(value);
|
settingsController.SetStepsGoal(value);
|
||||||
lv_label_set_text_fmt(stepValue,"%i", settingsController.GetStepsGoal());
|
lv_label_set_text_fmt(stepValue, "%lu", settingsController.GetStepsGoal());
|
||||||
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_CENTER, 0, -10);
|
lv_obj_align(stepValue, lv_scr_act(), LV_ALIGN_CENTER, 0, -10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
src/libs/littlefs
Submodule
1
src/libs/littlefs
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit ead50807f1ca3fdf2da00b77a0ce02651ded2d13
|
|
@ -204,7 +204,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */
|
||||||
|
|
||||||
/* 1: Enable file system (might be required for images */
|
/* 1: Enable file system (might be required for images */
|
||||||
// TODO: Enable FS
|
// TODO: Enable FS
|
||||||
#define LV_USE_FILESYSTEM 0
|
#define LV_USE_FILESYSTEM 1
|
||||||
#if LV_USE_FILESYSTEM
|
#if LV_USE_FILESYSTEM
|
||||||
/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/
|
/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/
|
||||||
typedef void * lv_fs_drv_user_data_t;
|
typedef void * lv_fs_drv_user_data_t;
|
||||||
|
@ -236,7 +236,7 @@ typedef void * lv_fs_drv_user_data_t;
|
||||||
* With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.
|
* With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.
|
||||||
* However the opened images might consume additional RAM.
|
* However the opened images might consume additional RAM.
|
||||||
* LV_IMG_CACHE_DEF_SIZE must be >= 1 */
|
* LV_IMG_CACHE_DEF_SIZE must be >= 1 */
|
||||||
#define LV_IMG_CACHE_DEF_SIZE 1
|
#define LV_IMG_CACHE_DEF_SIZE 6
|
||||||
|
|
||||||
/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/
|
/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/
|
||||||
typedef void* lv_img_decoder_user_data_t;
|
typedef void* lv_img_decoder_user_data_t;
|
||||||
|
|
13
src/main.cpp
13
src/main.cpp
|
@ -35,6 +35,7 @@
|
||||||
#include "components/motor/MotorController.h"
|
#include "components/motor/MotorController.h"
|
||||||
#include "components/datetime/DateTimeController.h"
|
#include "components/datetime/DateTimeController.h"
|
||||||
#include "components/heartrate/HeartRateController.h"
|
#include "components/heartrate/HeartRateController.h"
|
||||||
|
#include "components/fs/FS.h"
|
||||||
#include "drivers/Spi.h"
|
#include "drivers/Spi.h"
|
||||||
#include "drivers/SpiMaster.h"
|
#include "drivers/SpiMaster.h"
|
||||||
#include "drivers/SpiNorFlash.h"
|
#include "drivers/SpiNorFlash.h"
|
||||||
|
@ -108,10 +109,6 @@ void ble_manager_set_ble_disconnection_callback(void (*disconnection)());
|
||||||
static constexpr uint8_t pinTouchIrq = 28;
|
static constexpr uint8_t pinTouchIrq = 28;
|
||||||
static constexpr uint8_t pinPowerPresentIrq = 19;
|
static constexpr uint8_t pinPowerPresentIrq = 19;
|
||||||
|
|
||||||
Pinetime::Controllers::Settings settingsController {spiNorFlash};
|
|
||||||
|
|
||||||
Pinetime::Controllers::MotorController motorController {settingsController};
|
|
||||||
|
|
||||||
Pinetime::Controllers::HeartRateController heartRateController;
|
Pinetime::Controllers::HeartRateController heartRateController;
|
||||||
Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController);
|
Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController);
|
||||||
|
|
||||||
|
@ -122,6 +119,11 @@ Pinetime::Controllers::NotificationManager notificationManager;
|
||||||
Pinetime::Controllers::MotionController motionController;
|
Pinetime::Controllers::MotionController motionController;
|
||||||
Pinetime::Controllers::TimerController timerController;
|
Pinetime::Controllers::TimerController timerController;
|
||||||
|
|
||||||
|
Pinetime::Controllers::FS fs {spiNorFlash};
|
||||||
|
Pinetime::Controllers::Settings settingsController {fs};
|
||||||
|
Pinetime::Controllers::MotorController motorController {settingsController};
|
||||||
|
|
||||||
|
|
||||||
Pinetime::Applications::DisplayApp displayApp(lcd,
|
Pinetime::Applications::DisplayApp displayApp(lcd,
|
||||||
lvgl,
|
lvgl,
|
||||||
touchPanel,
|
touchPanel,
|
||||||
|
@ -155,7 +157,8 @@ Pinetime::System::SystemTask systemTask(spi,
|
||||||
settingsController,
|
settingsController,
|
||||||
heartRateController,
|
heartRateController,
|
||||||
displayApp,
|
displayApp,
|
||||||
heartRateApp);
|
heartRateApp,
|
||||||
|
fs);
|
||||||
|
|
||||||
void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
|
void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) {
|
||||||
if (pin == pinTouchIrq) {
|
if (pin == pinTouchIrq) {
|
||||||
|
|
|
@ -59,7 +59,8 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi,
|
||||||
Controllers::Settings& settingsController,
|
Controllers::Settings& settingsController,
|
||||||
Pinetime::Controllers::HeartRateController& heartRateController,
|
Pinetime::Controllers::HeartRateController& heartRateController,
|
||||||
Pinetime::Applications::DisplayApp& displayApp,
|
Pinetime::Applications::DisplayApp& displayApp,
|
||||||
Pinetime::Applications::HeartRateTask& heartRateApp)
|
Pinetime::Applications::HeartRateTask& heartRateApp,
|
||||||
|
Pinetime::Controllers::FS& fs)
|
||||||
: spi {spi},
|
: spi {spi},
|
||||||
lcd {lcd},
|
lcd {lcd},
|
||||||
spiNorFlash {spiNorFlash},
|
spiNorFlash {spiNorFlash},
|
||||||
|
@ -77,10 +78,11 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi,
|
||||||
motionSensor {motionSensor},
|
motionSensor {motionSensor},
|
||||||
settingsController {settingsController},
|
settingsController {settingsController},
|
||||||
heartRateController{heartRateController},
|
heartRateController{heartRateController},
|
||||||
nimbleController(*this, bleController, dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController),
|
|
||||||
motionController{motionController},
|
motionController{motionController},
|
||||||
displayApp{displayApp},
|
displayApp{displayApp},
|
||||||
heartRateApp(heartRateApp) {
|
heartRateApp(heartRateApp),
|
||||||
|
fs{fs},
|
||||||
|
nimbleController(*this, bleController, dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +109,9 @@ void SystemTask::Work() {
|
||||||
spi.Init();
|
spi.Init();
|
||||||
spiNorFlash.Init();
|
spiNorFlash.Init();
|
||||||
spiNorFlash.Wakeup();
|
spiNorFlash.Wakeup();
|
||||||
|
|
||||||
|
fs.Init();
|
||||||
|
|
||||||
nimbleController.Init();
|
nimbleController.Init();
|
||||||
nimbleController.StartAdvertising();
|
nimbleController.StartAdvertising();
|
||||||
brightnessController.Init();
|
brightnessController.Init();
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#include "components/ble/NotificationManager.h"
|
#include "components/ble/NotificationManager.h"
|
||||||
#include "components/motor/MotorController.h"
|
#include "components/motor/MotorController.h"
|
||||||
#include "components/timer/TimerController.h"
|
#include "components/timer/TimerController.h"
|
||||||
|
#include "components/fs/FS.h"
|
||||||
|
|
||||||
#ifdef PINETIME_IS_RECOVERY
|
#ifdef PINETIME_IS_RECOVERY
|
||||||
#include "displayapp/DisplayAppRecovery.h"
|
#include "displayapp/DisplayAppRecovery.h"
|
||||||
#include "displayapp/DummyLittleVgl.h"
|
#include "displayapp/DummyLittleVgl.h"
|
||||||
|
@ -59,7 +61,8 @@ namespace Pinetime {
|
||||||
Controllers::Settings& settingsController,
|
Controllers::Settings& settingsController,
|
||||||
Pinetime::Controllers::HeartRateController& heartRateController,
|
Pinetime::Controllers::HeartRateController& heartRateController,
|
||||||
Pinetime::Applications::DisplayApp& displayApp,
|
Pinetime::Applications::DisplayApp& displayApp,
|
||||||
Pinetime::Applications::HeartRateTask& heartRateApp);
|
Pinetime::Applications::HeartRateTask& heartRateApp,
|
||||||
|
Pinetime::Controllers::FS& fs);
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
void PushMessage(Messages msg);
|
void PushMessage(Messages msg);
|
||||||
|
@ -103,13 +106,14 @@ namespace Pinetime {
|
||||||
Pinetime::Drivers::Bma421& motionSensor;
|
Pinetime::Drivers::Bma421& motionSensor;
|
||||||
Pinetime::Controllers::Settings& settingsController;
|
Pinetime::Controllers::Settings& settingsController;
|
||||||
Pinetime::Controllers::HeartRateController& heartRateController;
|
Pinetime::Controllers::HeartRateController& heartRateController;
|
||||||
Pinetime::Controllers::NimbleController nimbleController;
|
|
||||||
Controllers::BrightnessController brightnessController;
|
Controllers::BrightnessController brightnessController;
|
||||||
Pinetime::Controllers::MotionController& motionController;
|
Pinetime::Controllers::MotionController& motionController;
|
||||||
|
|
||||||
Pinetime::Applications::DisplayApp& displayApp;
|
Pinetime::Applications::DisplayApp& displayApp;
|
||||||
Pinetime::Applications::HeartRateTask& heartRateApp;
|
Pinetime::Applications::HeartRateTask& heartRateApp;
|
||||||
|
Pinetime::Controllers::FS& fs;
|
||||||
|
Pinetime::Controllers::NimbleController nimbleController;
|
||||||
|
|
||||||
static constexpr uint8_t pinSpiSck = 2;
|
static constexpr uint8_t pinSpiSck = 2;
|
||||||
static constexpr uint8_t pinSpiMosi = 3;
|
static constexpr uint8_t pinSpiMosi = 3;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user