summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKieran Cawthray <kieranc@gmail.com>2021-08-12 21:26:51 +0200
committerKieran Cawthray <kieranc@gmail.com>2021-08-12 21:26:51 +0200
commit52ee25e551f506cdaadfb6a62feda1d2aaa8497b (patch)
tree6c5abc74c56400d222c105b9826fd5e58d3ce522
parent12aeb4688923a06d574b7aa7262626e7eab5b7f1 (diff)
parent643077341b14a52819cbaf02abbd5fb56cdeb802 (diff)
Merge remote-tracking branch 'upstream/develop' into pinetimestyle-colorpicker
-rw-r--r--.devcontainer/Dockerfile65
-rw-r--r--.devcontainer/README.md60
-rw-r--r--.devcontainer/build.sh78
-rw-r--r--.devcontainer/build_app.sh2
-rw-r--r--.devcontainer/create_build_openocd.sh3
-rw-r--r--.devcontainer/devcontainer.json36
-rw-r--r--.devcontainer/make_build_dir.sh2
-rw-r--r--.gitignore2
-rw-r--r--.vscode/c_cpp_properties.json20
-rw-r--r--.vscode/cmake-variants.json62
-rw-r--r--.vscode/extensions.json3
-rw-r--r--.vscode/launch.json46
-rw-r--r--.vscode/settings.json66
-rw-r--r--.vscode/tasks.json44
-rw-r--r--README.md1
-rw-r--r--doc/buildWithVScode.md42
-rw-r--r--src/components/battery/BatteryController.cpp32
-rw-r--r--src/components/battery/BatteryController.h43
-rw-r--r--src/components/datetime/DateTimeController.cpp20
-rw-r--r--src/displayapp/screens/BatteryIcon.cpp8
-rw-r--r--src/displayapp/screens/Clock.cpp20
-rw-r--r--src/displayapp/screens/Clock.h7
-rw-r--r--src/displayapp/screens/PineTimeStyle.cpp53
-rw-r--r--src/displayapp/screens/PineTimeStyle.h5
-rw-r--r--src/displayapp/screens/WatchFaceAnalog.cpp52
-rw-r--r--src/displayapp/screens/WatchFaceAnalog.h2
-rw-r--r--src/displayapp/screens/WatchFaceDigital.cpp45
-rw-r--r--src/displayapp/screens/WatchFaceDigital.h5
28 files changed, 554 insertions, 270 deletions
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 00000000..1dd68f24
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,65 @@
+FROM ubuntu:latest
+
+ARG DEBIAN_FRONTEND=noninteractive
+RUN apt-get update -qq \
+ && apt-get install -y \
+# x86_64 / generic packages
+ bash \
+ build-essential \
+ cmake \
+ git \
+ make \
+ python3 \
+ python3-pip \
+ tar \
+ unzip \
+ wget \
+ curl \
+ dos2unix \
+ clang-format-12 \
+ clang-tidy \
+ locales \
+ libncurses5 \
+# aarch64 packages
+ libffi-dev \
+ libssl-dev \
+ python3-dev \
+ rustc \
+ && rm -rf /var/cache/apt/* /var/lib/apt/lists/*;
+
+#SET LOCALE
+RUN locale-gen en_US.UTF-8
+ENV LANG en_US.UTF-8
+ENV LANGUAGE en_US:en
+ENV LC_ALL en_US.UTF-8
+
+RUN pip3 install adafruit-nrfutil
+# required for McuBoot
+RUN pip3 install setuptools_rust
+
+WORKDIR /opt/
+# build.sh knows how to compile but it problimatic on Win10
+COPY build.sh .
+RUN chmod +x build.sh
+# create_build_openocd.sh uses cmake to crate to build directory
+COPY create_build_openocd.sh .
+RUN chmod +x create_build_openocd.sh
+# Lets get each in a separate docker layer for better downloads
+# GCC
+# RUN bash -c "source /opt/build.sh; GetGcc;"
+RUN wget https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/gcc-arm-none-eabi-9-2020-q2-update-x86_64-linux.tar.bz2 -O - | tar -xj -C /opt
+# NrfSdk
+# RUN bash -c "source /opt/build.sh; GetNrfSdk;"
+RUN wget -q "https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/nRF5_SDK_15.3.0_59ac345.zip" -O /tmp/nRF5_SDK_15.3.0_59ac345
+RUN unzip -q /tmp/nRF5_SDK_15.3.0_59ac345 -d /opt
+RUN rm /tmp/nRF5_SDK_15.3.0_59ac345
+# McuBoot
+# RUN bash -c "source /opt/build.sh; GetMcuBoot;"
+RUN git clone https://github.com/JuulLabs-OSS/mcuboot.git
+RUN pip3 install -r ./mcuboot/scripts/requirements.txt
+
+RUN adduser infinitime
+
+ENV NRF5_SDK_PATH /opt/nRF5_SDK_15.3.0_59ac345
+ENV ARM_NONE_EABI_TOOLCHAIN_PATH /opt/gcc-arm-none-eabi-9-2020-q2-update
+ENV SOURCES_DIR /workspaces/InfiniTime
diff --git a/.devcontainer/README.md b/.devcontainer/README.md
new file mode 100644
index 00000000..1932a9d4
--- /dev/null
+++ b/.devcontainer/README.md
@@ -0,0 +1,60 @@
+# VS Code Dev Container
+This is a docker-based interactive development environment using VS Code and Docker Dev Containers removing the need to install any tools locally*
+
+
+
+## Requirements
+
+- VS Code
+ - [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension
+- Docker
+- OpenOCD - For debugging
+
+## Using
+
+### Code editing, and building.
+
+1. Clone InfiniTime and update submodules
+2. Launch VS Code
+3. Open InfiniTime directory,
+4. Allow VS Code to open folder with devcontainer.
+
+After this the environment will be built if you do not currently have a container setup, it will install all the necessary tools and extra VSCode extensions.
+
+In order to build InfiniTime we need to run the initial submodule init and CMake commands.
+
+#### Manually
+
+ You can use the VS Code terminal to run the CMake commands as outlined in the [build instructions](blob/develop/doc/buildAndProgram.md)
+
+#### Script
+
+The dev environment comes with some scripts to make this easier, They are located in /opt/.
+
+There are also VS Code tasks provided should you desire to use those.
+
+The task "update submodules" will update the git submodules
+
+
+
+### Build
+
+You can use the build.sh script located in /opt/
+
+CMake is also configured and controls for the CMake plugin are available in VS Code
+
+
+
+### Debugging
+
+Docker on windows does not support passing USB devices to the underlying WSL2 subsystem, To get around this we use OpenOCD in server mode running on the host.
+
+`openocd -f <yourinterface> -f <nrf52.cfg target file>`
+
+This will launch OpenOCD in server mode and attach it to the MCU.
+
+The default launch.json file expects OpenOCD to be listening on port 3333, edit if needed
+
+
+## Current Issues
+Currently WSL2 Has some real performance issues with IO on a windows host. Accessing files on the virtualized filesystem is much faster. Using VS Codes "clone in container" feature of the Remote - Containers will get around this. After the container is built you will need to update the submodules and follow the build instructions like normal \ No newline at end of file
diff --git a/.devcontainer/build.sh b/.devcontainer/build.sh
new file mode 100644
index 00000000..8f0d0fa9
--- /dev/null
+++ b/.devcontainer/build.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+(return 0 2>/dev/null) && SOURCED="true" || SOURCED="false"
+export LC_ALL=C.UTF-8
+export LANG=C.UTF-8
+set -x
+set -e
+
+# Default locations if the var isn't already set
+export TOOLS_DIR="${TOOLS_DIR:=/opt}"
+export SOURCES_DIR="${SOURCES_DIR:=/sources}"
+export BUILD_DIR="${BUILD_DIR:=$SOURCES_DIR/build}"
+export OUTPUT_DIR="${OUTPUT_DIR:=$BUILD_DIR/output}"
+
+export BUILD_TYPE=${BUILD_TYPE:=Release}
+export GCC_ARM_VER=${GCC_ARM_VER:="gcc-arm-none-eabi-9-2020-q2-update"}
+export NRF_SDK_VER=${NRF_SDK_VER:="nRF5_SDK_15.3.0_59ac345"}
+
+MACHINE="$(uname -m)"
+[[ "$MACHINE" == "arm64" ]] && MACHINE="aarch64"
+
+main() {
+ local target="$1"
+
+ mkdir -p "$TOOLS_DIR"
+
+ [[ ! -d "$TOOLS_DIR/$GCC_ARM_VER" ]] && GetGcc
+ [[ ! -d "$TOOLS_DIR/$NRF_SDK_VER" ]] && GetNrfSdk
+ [[ ! -d "$TOOLS_DIR/mcuboot" ]] && GetMcuBoot
+
+ mkdir -p "$BUILD_DIR"
+
+ CmakeGenerate
+ CmakeBuild $target
+ BUILD_RESULT=$?
+ if [ "$DISABLE_POSTBUILD" != "true" -a "$BUILD_RESULT" == 0 ]; then
+ source "$BUILD_DIR/post_build.sh"
+ fi
+}
+
+GetGcc() {
+ GCC_SRC="$GCC_ARM_VER-$MACHINE-linux.tar.bz"
+ wget -q https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2020q2/$GCC_SRC -O - | tar -xj -C $TOOLS_DIR/
+}
+
+GetMcuBoot() {
+ git clone https://github.com/JuulLabs-OSS/mcuboot.git "$TOOLS_DIR/mcuboot"
+ pip3 install -r "$TOOLS_DIR/mcuboot/scripts/requirements.txt"
+}
+
+GetNrfSdk() {
+ wget -q "https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/$NRF_SDK_VER.zip" -O /tmp/$NRF_SDK_VER
+ unzip -q /tmp/$NRF_SDK_VER -d "$TOOLS_DIR/"
+ rm /tmp/$NRF_SDK_VER
+}
+
+CmakeGenerate() {
+ # We can swap the CD and trailing SOURCES_DIR for -B and -S respectively
+ # once we go to newer CMake (Ubuntu 18.10 gives us CMake 3.10)
+ cd "$BUILD_DIR"
+
+ cmake -G "Unix Makefiles" \
+ -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
+ -DUSE_OPENOCD=1 \
+ -DARM_NONE_EABI_TOOLCHAIN_PATH="$TOOLS_DIR/$GCC_ARM_VER" \
+ -DNRF5_SDK_PATH="$TOOLS_DIR/$NRF_SDK_VER" \
+ "$SOURCES_DIR"
+ cmake -L -N .
+}
+
+CmakeBuild() {
+ local target="$1"
+ [[ -n "$target" ]] && target="--target $target"
+ if cmake --build "$BUILD_DIR" --config $BUILD_TYPE $target -- -j$(nproc)
+ then return 0; else return 1;
+ fi
+}
+
+[[ $SOURCED == "false" ]] && main "$@" || echo "Sourced!" \ No newline at end of file
diff --git a/.devcontainer/build_app.sh b/.devcontainer/build_app.sh
new file mode 100644
index 00000000..0f578cc6
--- /dev/null
+++ b/.devcontainer/build_app.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+cmake --build /workspaces/Pinetime/build --config Release -- -j6 pinetime-app \ No newline at end of file
diff --git a/.devcontainer/create_build_openocd.sh b/.devcontainer/create_build_openocd.sh
new file mode 100644
index 00000000..c5bff5c8
--- /dev/null
+++ b/.devcontainer/create_build_openocd.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+rm -rf build/
+cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Release -DUSE_OPENOCD=1 -DARM_NONE_EABI_TOOLCHAIN_PATH=/opt/gcc-arm-none-eabi-9-2020-q2-update -DNRF5_SDK_PATH=/opt/nRF5_SDK_15.3.0_59ac345 -S . -Bbuild \ No newline at end of file
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 00000000..778fe9cb
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,36 @@
+// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
+// https://github.com/microsoft/vscode-dev-containers/tree/v0.154.2/containers/cpp
+{
+ // "name": "Pinetime",
+ // "image": "feabhas/pinetime-dev"
+ "build": {
+ "dockerfile": "Dockerfile",
+ // Update 'VARIANT' to pick an Debian / Ubuntu OS version: debian-10, debian-9, ubuntu-20.04, ubuntu-18.04
+ // "args": { "VARIANT": "ubuntu-20.04" }
+ },
+ "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined"],
+
+ // Set *default* container specific settings.json values on container create.
+ "settings": {
+ "terminal.integrated.shell.linux": "/bin/bash"
+ },
+
+ // Add the IDs of extensions you want installed when the container is created.
+ "extensions": [
+ "ms-vscode.cpptools",
+ "ms-vscode.cmake-tools",
+ "marus25.cortex-debug",
+ "notskm.clang-tidy",
+ "mjohns.clang-format"
+ ],
+
+ // Use 'forwardPorts' to make a list of ports inside the container available locally.
+ // "forwardPorts": [],
+
+ // Use 'postCreateCommand' to run commands after the container is created.
+ // "postCreateCommand": "bash /opt/create_build_openocd.sh",
+
+ // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
+ // "remoteUser": "vscode"
+ "remoteUser": "infinitime"
+} \ No newline at end of file
diff --git a/.devcontainer/make_build_dir.sh b/.devcontainer/make_build_dir.sh
new file mode 100644
index 00000000..76240037
--- /dev/null
+++ b/.devcontainer/make_build_dir.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+cmake -G 'Unix Makefiles' -DCMAKE_BUILD_TYPE=Release -DUSE_OPENOCD=1 -DARM_NONE_EABI_TOOLCHAIN_PATH=/opt/gcc-arm-none-eabi-9-2020-q2-update -DNRF5_SDK_PATH=/opt/nRF5_SDK_15.3.0_59ac345 ${SOURCES_DIR}
diff --git a/.gitignore b/.gitignore
index 2f9ac181..6de76a9e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,7 @@
# CMake
cmake-build-*
-cmake-*
+cmake-*/
CMakeFiles
**/CMakeCache.txt
cmake_install.cmake
diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json
new file mode 100644
index 00000000..f8da48d5
--- /dev/null
+++ b/.vscode/c_cpp_properties.json
@@ -0,0 +1,20 @@
+{
+ "configurations": [
+ {
+ "name": "nrfCC",
+ "includePath": [
+ "${workspaceFolder}/**",
+ "${workspaceFolder}/src/**",
+ "${workspaceFolder}/src"
+ ],
+ "defines": [],
+ "compilerPath": "${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin/arm-none-eabi-gcc",
+ "cStandard": "c11",
+ "cppStandard": "c++14",
+ "intelliSenseMode": "linux-gcc-arm",
+ "configurationProvider": "ms-vscode.cpp-tools",
+ "compileCommands": "${workspaceFolder}/build/compile_commands.json"
+ }
+ ],
+ "version": 4
+} \ No newline at end of file
diff --git a/.vscode/cmake-variants.json b/.vscode/cmake-variants.json
new file mode 100644
index 00000000..9c95a631
--- /dev/null
+++ b/.vscode/cmake-variants.json
@@ -0,0 +1,62 @@
+{
+ "buildType": {
+ "default": "release",
+ "choices": {
+ "debug": {
+ "short": "Debug",
+ "long": "Emit debug information without performing optimizations",
+ "buildType": "Debug"
+ },
+ "release": {
+ "short": "Release",
+ "long": "Perform optimizations",
+ "buildType": "Release"
+ }
+ }
+ },
+ "programmer":{
+ "default": "OpenOCD",
+ "choices":{
+ "OpenOCD":{
+ "short":"OpenOCD",
+ "long": "Use OpenOCD",
+ "settings":{
+ "USE_OPENOCD":1
+ }
+ },
+ "JLink":{
+ "short":"JLink",
+ "long": "Use JLink",
+ "settings":{
+ "USE_JLINK":1
+ }
+ },
+ "GDB":{
+ "short":"GDB",
+ "long": "Use GDB",
+ "settings":{
+ "USE_GDB_CLIENT":1
+ }
+ }
+ }
+ },
+ "DFU": {
+ "default": "no",
+ "choices": {
+ "no": {
+ "short": "No DFU",
+ "long": "Do not build DFU",
+ "settings": {
+ "BUILD_DFU":"0"
+ }
+ },
+ "yes": {
+ "short": "Build DFU",
+ "long": "Build DFU",
+ "settings": {
+ "BUILD_DFU":"1"
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 00000000..1cc05268
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,3 @@
+{
+ "recommendations": ["ms-vscode.cpptools","ms-vscode.cmake-tools","marus25.cortex-debug"]
+} \ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 00000000..7cf3acd1
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,46 @@
+ {
+ "version": "0.1.0",
+ "configurations": [
+ {
+ "name": "Debug - Openocd docker Remote",
+ "type":"cortex-debug",
+ "cortex-debug.armToolchainPath":"${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin",
+ "cwd": "${workspaceRoot}",
+ "executable": "${command:cmake.launchTargetPath}",
+ "request": "launch",
+ "servertype": "external",
+ // This may need to be arm-none-eabi-gdb depending on your system
+ "gdbPath" : "${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin/arm-none-eabi-gdb",
+ // Connect to an already running OpenOCD instance
+ "gdbTarget": "host.docker.internal:3333",
+ "svdFile": "${workspaceRoot}/nrf52.svd",
+ "runToMain": true,
+ // Work around for stopping at main on restart
+ "postRestartCommands": [
+ "break main",
+ "continue"
+ ]
+ },
+ {
+ "name": "Debug - Openocd Local",
+ "type":"cortex-debug",
+ "cortex-debug.armToolchainPath":"${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin",
+ "cwd": "${workspaceRoot}",
+ "executable": "${command:cmake.launchTargetPath}",
+ "request": "launch",
+ "servertype": "openocd",
+ // This may need to be arm-none-eabi-gdb depending on your system
+ "gdbPath" : "${env:ARM_NONE_EABI_TOOLCHAIN_PATH}/bin/arm-none-eabi-gdb",
+ // Connect to an already running OpenOCD instance
+ "gdbTarget": "localhost:3333",
+ "svdFile": "${workspaceRoot}/nrf52.svd",
+ "runToMain": true,
+ // Work around for stopping at main on restart
+ "postRestartCommands": [
+ "break main",
+ "continue"
+ ]
+ }
+
+ ]
+} \ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 05b11756..8f0e63f4 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,59 +1,9 @@
{
- "files.associations": {
- "chrono": "cpp",
- "list": "cpp",
- "array": "cpp",
- "atomic": "cpp",
- "bit": "cpp",
- "*.tcc": "cpp",
- "cctype": "cpp",
- "charconv": "cpp",
- "clocale": "cpp",
- "cmath": "cpp",
- "condition_variable": "cpp",
- "cstdarg": "cpp",
- "cstddef": "cpp",
- "cstdint": "cpp",
- "cstdio": "cpp",
- "cstdlib": "cpp",
- "cstring": "cpp",
- "ctime": "cpp",
- "cwchar": "cpp",
- "cwctype": "cpp",
- "deque": "cpp",
- "unordered_map": "cpp",
- "vector": "cpp",
- "exception": "cpp",
- "algorithm": "cpp",
- "functional": "cpp",
- "iterator": "cpp",
- "memory": "cpp",
- "memory_resource": "cpp",
- "netfwd": "cpp",
- "numeric": "cpp",
- "optional": "cpp",
- "random": "cpp",
- "ratio": "cpp",
- "string": "cpp",
- "string_view": "cpp",
- "system_error": "cpp",
- "tuple": "cpp",
- "type_traits": "cpp",
- "utility": "cpp",
- "fstream": "cpp",
- "initializer_list": "cpp",
- "iosfwd": "cpp",
- "iostream": "cpp",
- "istream": "cpp",
- "limits": "cpp",
- "mutex": "cpp",
- "new": "cpp",
- "ostream": "cpp",
- "sstream": "cpp",
- "stdexcept": "cpp",
- "streambuf": "cpp",
- "thread": "cpp",
- "cinttypes": "cpp",
- "typeinfo": "cpp"
- }
-} \ No newline at end of file
+ "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools",
+ "cmake.configureArgs": [
+ "-DARM_NONE_EABI_TOOLCHAIN_PATH=${env:ARM_NONE_EABI_TOOLCHAIN_PATH}",
+ "-DNRF5_SDK_PATH=${env:NRF5_SDK_PATH}",
+ ],
+ "cmake.generator": "Unix Makefiles",
+ "clang-tidy.buildPath": "build/compile_commands.json"
+}
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
new file mode 100644
index 00000000..17f51f5e
--- /dev/null
+++ b/.vscode/tasks.json
@@ -0,0 +1,44 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "create openocd build",
+ "type": "shell",
+ "command": "/opt/create_build_openocd.sh",
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ },
+ "presentation": {
+ "reveal": "always",
+ "panel": "shared"
+ },
+ "problemMatcher": []
+ },
+ {
+ "label": "update submodules",
+ "type": "shell",
+ "command": "git submodule update --init",
+ "options": {
+ "cwd": "${workspaceFolder}"
+ },
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ },
+ "presentation": {
+ "reveal": "always",
+ "panel": "shared"
+ },
+ "problemMatcher": []
+ },
+ {
+ "label": "BuildInit",
+ "dependsOn": [
+ "update submodules",
+ "create openocd build"
+ ],
+ "problemMatcher": []
+ }
+ ]
+} \ No newline at end of file
diff --git a/README.md b/README.md
index d9de4002..6549ece9 100644
--- a/README.md
+++ b/README.md
@@ -93,6 +93,7 @@ As of now, here is the list of achievements of this project:
- [Build the project](doc/buildAndProgram.md)
- [Flash the firmware using OpenOCD and STLinkV2](doc/openOCD.md)
- [Build the project with Docker](doc/buildWithDocker.md)
+ - [Build the project with VSCode](doc/buildWithVScode.md)
- [Bootloader, OTA and DFU](./bootloader/README.md)
- [Stub using NRF52-DK](./doc/PinetimeStubWithNrf52DK.md)
- Logging with JLink RTT.
diff --git a/doc/buildWithVScode.md b/doc/buildWithVScode.md
new file mode 100644
index 00000000..c1df17b7
--- /dev/null
+++ b/doc/buildWithVScode.md
@@ -0,0 +1,42 @@
+# Build and Develop the project using VS Code
+
+The .VS Code folder contains configuration files for developing InfiniTime with VS Code. Effort was made to have these rely on Environment variables instead of hardcoded paths.
+
+## Environment Setup
+
+To support as many setups as possible the VS Code configuration files expect there to be certain environment variables to be set.
+
+ Variable | Description | Example
+----------|-------------|--------
+**ARM_NONE_EABI_TOOLCHAIN_PATH**|path to the toolchain directory|`export ARM_NONE_EABI_TOOLCHAIN_PATH=/opt/gcc-arm-none-eabi-9-2020-q2-update`
+**NRF5_SDK_PATH**|path to the NRF52 SDK|`export NRF5_SDK_PATH=/opt/nRF5_SDK_15.3.0_59ac345`
+
+## VS Code Extensions
+
+We leverage a few VS Code extensions for ease of development.
+
+#### Required Extensions
+
+- [C/C++](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) - C/C++ IntelliSense, debugging, and code browsing.
+- [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools) - Extended CMake support in Visual Studio Code
+
+#### Optional Extensions
+
+[Cortex-Debug](https://marketplace.visualstudio.com/items?itemName=marus25.cortex-debug) - ARM Cortex-M GDB Debugger support for VS Code
+
+Cortex-Debug is only required for interactive debugging using VS Codes built in GDB support.
+
+
+
+## VS Code/Docker DevContainer
+
+The .devcontainer folder contains the configuration and scripts for using a Docker dev container for building InfiniTime
+
+Using the [Remote-Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension is recommended. It will handle configuring the Docker virtual machine and setting everything up.
+
+More documentation is available in the [readme in .devcontainer](.devcontainer/readme.md)
+
+
+
+
+
diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp
index fa476ea3..f8a64ecd 100644
--- a/src/components/battery/BatteryController.cpp
+++ b/src/components/battery/BatteryController.cpp
@@ -23,7 +23,6 @@ void Battery::Update() {
return;
}
// Non blocking read
- samples = 0;
isReading = true;
SaadcInit();
@@ -40,9 +39,9 @@ void Battery::SaadcInit() {
nrf_saadc_channel_config_t adcChannelConfig = {.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
.resistor_n = NRF_SAADC_RESISTOR_DISABLED,
- .gain = NRF_SAADC_GAIN1_5,
+ .gain = NRF_SAADC_GAIN1_4,
.reference = NRF_SAADC_REFERENCE_INTERNAL,
- .acq_time = NRF_SAADC_ACQTIME_3US,
+ .acq_time = NRF_SAADC_ACQTIME_40US,
.mode = NRF_SAADC_MODE_SINGLE_ENDED,
.burst = NRF_SAADC_BURST_ENABLED,
.pin_p = batteryVoltageAdcInput,
@@ -60,22 +59,21 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) {
APP_ERROR_CHECK(nrfx_saadc_buffer_convert(&saadc_value, 1));
// A hardware voltage divider divides the battery voltage by 2
- // ADC gain is 1/5
- // thus adc_voltage = battery_voltage / 2 * gain = battery_voltage / 10
- // reference_voltage is 0.6V
+ // ADC gain is 1/4
+ // thus adc_voltage = battery_voltage / 2 * gain = battery_voltage / 8
+ // reference_voltage is 600mV
// p_event->data.done.p_buffer[0] = (adc_voltage / reference_voltage) * 1024
- voltage = p_event->data.done.p_buffer[0] * 6000 / 1024;
- percentRemaining = (voltage - battery_min) * 100 / (battery_max - battery_min);
- percentRemaining = std::max(percentRemaining, 0);
- percentRemaining = std::min(percentRemaining, 100);
- percentRemainingBuffer.Insert(percentRemaining);
-
- samples++;
- if (samples > percentRemainingSamples) {
- nrfx_saadc_uninit();
- isReading = false;
+ voltage = p_event->data.done.p_buffer[0] * (8 * 600) / 1024;
+
+ if (voltage > battery_max) {
+ percentRemaining = 100;
+ } else if (voltage < battery_min) {
+ percentRemaining = 0;
} else {
- nrfx_saadc_sample();
+ percentRemaining = (voltage - battery_min) * 100 / (battery_max - battery_min);
}
+
+ nrfx_saadc_uninit();
+ isReading = false;
}
}
diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h
index 1333ad0e..6f09b737 100644
--- a/src/components/battery/BatteryController.h
+++ b/src/components/battery/BatteryController.h
@@ -7,38 +7,6 @@
namespace Pinetime {
namespace Controllers {
- /** A simple circular buffer that can be used to average
- out the sensor values. The total capacity of the CircBuffer
- is given as the template parameter N.
- */
- template <int N> class CircBuffer {
- public:
- CircBuffer() : arr {}, sz {}, cap {N}, head {} {
- }
- /**
- insert member function overwrites the next data to the current
- HEAD and moves the HEAD to the newly inserted value.
- */
- void Insert(const uint8_t num) {
- head %= cap;
- arr[head++] = num;
- if (sz != cap) {
- sz++;
- }
- }
-
- uint8_t GetAverage() const {
- int sum = std::accumulate(arr.begin(), arr.end(), 0);
- return static_cast<uint8_t>(sum / sz);
- }
-
- private:
- std::array<uint8_t, N> arr; /**< internal array used to store the values*/
- uint8_t sz; /**< The current size of the array.*/
- uint8_t cap; /**< Total capacity of the CircBuffer.*/
- uint8_t head; /**< The current head of the CircBuffer*/
- };
-
class Battery {
public:
Battery();
@@ -47,10 +15,7 @@ namespace Pinetime {
void Update();
uint8_t PercentRemaining() const {
- auto avg = percentRemainingBuffer.GetAverage();
- avg = std::min(avg, static_cast<uint8_t>(100));
- avg = std::max(avg, static_cast<uint8_t>(0));
- return avg;
+ return percentRemaining;
}
uint16_t Voltage() const {
@@ -69,14 +34,11 @@ namespace Pinetime {
static Battery* instance;
nrf_saadc_value_t saadc_value;
- static constexpr uint8_t percentRemainingSamples = 5;
- CircBuffer<percentRemainingSamples> percentRemainingBuffer {};
-
static constexpr uint32_t chargingPin = 12;
static constexpr uint32_t powerPresentPin = 19;
static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7;
uint16_t voltage = 0;
- int percentRemaining = -1;
+ uint8_t percentRemaining = 0;
bool isCharging = false;
bool isPowerPresent = false;
@@ -87,7 +49,6 @@ namespace Pinetime {
static void AdcCallbackStatic(nrfx_saadc_evt_t const* event);
bool isReading = false;
- uint8_t samples = 0;
};
}
}
diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp
index 28a70abc..d6aa83c8 100644
--- a/src/components/datetime/DateTimeController.cpp
+++ b/src/components/datetime/DateTimeController.cpp
@@ -55,9 +55,9 @@ void DateTime::UpdateTime(uint32_t systickCounter) {
auto time = date::make_time(currentDateTime - dp);
auto yearMonthDay = date::year_month_day(dp);
- year = (int) yearMonthDay.year();
- month = static_cast<Months>((unsigned) yearMonthDay.month());
- day = (unsigned) yearMonthDay.day();
+ year = static_cast<int>(yearMonthDay.year());
+ month = static_cast<Months>(static_cast<unsigned>(yearMonthDay.month()));
+ day = static_cast<unsigned>(yearMonthDay.day());
dayOfWeek = static_cast<Days>(date::weekday(yearMonthDay).iso_encoding());
hour = time.hours().count();
@@ -75,31 +75,31 @@ void DateTime::UpdateTime(uint32_t systickCounter) {
}
const char* DateTime::MonthShortToString() {
- return DateTime::MonthsString[(uint8_t) month];
+ return DateTime::MonthsString[static_cast<uint8_t>(month)];
}
const char* DateTime::MonthShortToStringLow() {
- return DateTime::MonthsStringLow[(uint8_t) month];
+ return DateTime::MonthsStringLow[static_cast<uint8_t>(month)];
}
const char* DateTime::MonthsToStringLow() {
- return DateTime::MonthsLow[(uint8_t) month];
+ return DateTime::MonthsLow[static_cast<uint8_t>(month)];
}
const char* DateTime::DayOfWeekToString() {
- return DateTime::DaysString[(uint8_t) dayOfWeek];
+ return DateTime::DaysString[static_cast<uint8_t>(dayOfWeek)];
}
const char* DateTime::DayOfWeekShortToString() {
- return DateTime::DaysStringShort[(uint8_t) dayOfWeek];
+ return DateTime::DaysStringShort[static_cast<uint8_t>(dayOfWeek)];
}
const char* DateTime::DayOfWeekToStringLow() {
- return DateTime::DaysStringLow[(uint8_t) dayOfWeek];
+ return DateTime::DaysStringLow[static_cast<uint8_t>(dayOfWeek)];
}
const char* DateTime::DayOfWeekShortToStringLow() {
- return DateTime::DaysStringShortLow[(uint8_t) dayOfWeek];
+ return DateTime::DaysStringShortLow[static_cast<uint8_t>(dayOfWeek)];
}
void DateTime::Register(Pinetime::System::SystemTask* systemTask) {
diff --git a/src/displayapp/screens/BatteryIcon.cpp b/src/displayapp/screens/BatteryIcon.cpp
index bb6626a5..c67bcb23 100644
--- a/src/displayapp/screens/BatteryIcon.cpp
+++ b/src/displayapp/screens/BatteryIcon.cpp
@@ -5,13 +5,13 @@
using namespace Pinetime::Applications::Screens;
const char* BatteryIcon::GetBatteryIcon(uint8_t batteryPercent) {
- if (batteryPercent > 90)
+ if (batteryPercent > 87)
return Symbols::batteryFull;
- if (batteryPercent > 75)
+ if (batteryPercent > 62)
return Symbols::batteryThreeQuarter;
- if (batteryPercent > 50)
+ if (batteryPercent > 37)
return Symbols::batteryHalf;
- if (batteryPercent > 25)
+ if (batteryPercent > 12)
return Symbols::batteryOneQuarter;
return Symbols::batteryEmpty;
}
diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp
index e0684976..86afee0c 100644
--- a/src/displayapp/screens/Clock.cpp
+++ b/src/displayapp/screens/Clock.cpp
@@ -2,11 +2,6 @@
#include <date/date.h>
#include <lvgl/lvgl.h>
-#include <cstdio>
-#include "BatteryIcon.h"
-#include "BleIcon.h"
-#include "NotificationIcon.h"
-#include "Symbols.h"
#include "components/battery/BatteryController.h"
#include "components/motion/MotionController.h"
#include "components/ble/BleController.h"
@@ -88,17 +83,4 @@ std::unique_ptr<Screen> Clock::PineTimeStyleScreen() {
notificatioManager,
settingsController,
motionController);
-}
-
-/*
-// Examples for more watch faces
-std::unique_ptr<Screen> Clock::WatchFaceMinimalScreen() {
- return std::make_unique<Screens::WatchFaceMinimal>(app, dateTimeController, batteryController, bleController, notificatioManager,
-settingsController);
-}
-
-std::unique_ptr<Screen> Clock::WatchFaceCustomScreen() {
- return std::make_unique<Screens::WatchFaceCustom>(app, dateTimeController, batteryController, bleController, notificatioManager,
-settingsController);
-}
-*/ \ No newline at end of file
+} \ No newline at end of file
diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h
index a48feea1..7968cced 100644
--- a/src/displayapp/screens/Clock.h
+++ b/src/displayapp/screens/Clock.h
@@ -9,9 +9,6 @@
#include "components/datetime/DateTimeController.h"
namespace Pinetime {
- namespace Drivers {
- class BMA421;
- }
namespace Controllers {
class Settings;
class Battery;
@@ -51,10 +48,6 @@ namespace Pinetime {
std::unique_ptr<Screen> WatchFaceDigitalScreen();
std::unique_ptr<Screen> WatchFaceAnalogScreen();
std::unique_ptr<Screen> PineTimeStyleScreen();
-
- // Examples for more watch faces
- // std::unique_ptr<Screen> WatchFaceMinimalScreen();
- // std::unique_ptr<Screen> WatchFaceCustomScreen();
};
}
}
diff --git a/src/displayapp/screens/PineTimeStyle.cpp b/src/displayapp/screens/PineTimeStyle.cpp
index 337ceba9..04128b21 100644
--- a/src/displayapp/screens/PineTimeStyle.cpp
+++ b/src/displayapp/screens/PineTimeStyle.cpp
@@ -218,26 +218,17 @@ bool PineTimeStyle::Refresh() {
bleState = bleController.IsConnected();
if (bleState.IsUpdated()) {
- if (bleState.Get() == true) {
- lv_label_set_text(bleIcon, BleIcon::GetIcon(true));
- lv_obj_realign(bleIcon);
- } else {
- lv_label_set_text(bleIcon, BleIcon::GetIcon(false));
- }
+ lv_label_set_text(bleIcon, BleIcon::GetIcon(bleState.Get()));
+ lv_obj_realign(bleIcon);
}
notificationState = notificatioManager.AreNewNotificationsAvailable();
if (notificationState.IsUpdated()) {
- if (notificationState.Get() == true) {
- lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(true));
- lv_obj_realign(notificationIcon);
- } else {
- lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false));
- }
+ lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(notificationState.Get()));
+ lv_obj_realign(notificationIcon);
}
currentDateTime = dateTimeController.CurrentDateTime();
-
if (currentDateTime.IsUpdated()) {
auto newDateTime = currentDateTime.Get();
@@ -245,9 +236,9 @@ bool PineTimeStyle::Refresh() {
auto time = date::make_time(newDateTime - dp);
auto yearMonthDay = date::year_month_day(dp);
- auto year = (int) yearMonthDay.year();
- auto month = static_cast<Pinetime::Controllers::DateTime::Months>((unsigned) yearMonthDay.month());
- auto day = (unsigned) yearMonthDay.day();
+ auto year = static_cast<int>(yearMonthDay.year());
+ auto month = static_cast<Pinetime::Controllers::DateTime::Months>(static_cast<unsigned>(yearMonthDay.month()));
+ auto day = static_cast<unsigned>(yearMonthDay.day());
auto dayOfWeek = static_cast<Pinetime::Controllers::DateTime::Days>(date::weekday(yearMonthDay).iso_encoding());
int hour = time.hours().count();
@@ -258,9 +249,8 @@ bool PineTimeStyle::Refresh() {
char hoursChar[3];
char ampmChar[5];
-
if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) {
- sprintf(hoursChar, "%02d", hour);
+ sprintf(hoursChar, "%02d", hour);
} else {
if (hour == 0 && hour != 12) {
hour = 12;
@@ -277,41 +267,26 @@ bool PineTimeStyle::Refresh() {
sprintf(hoursChar, "%02d", hour);
}
- if (hoursChar[0] != displayedChar[0] || hoursChar[1] != displayedChar[1] || minutesChar[0] != displayedChar[2] ||
+ if (hoursChar[0] != displayedChar[0] or hoursChar[1] != displayedChar[1] or minutesChar[0] != displayedChar[2] or
minutesChar[1] != displayedChar[3]) {
displayedChar[0] = hoursChar[0];
displayedChar[1] = hoursChar[1];
displayedChar[2] = minutesChar[0];
displayedChar[3] = minutesChar[1];
- char hourStr[3];
- char minStr[3];
-
if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) {
lv_label_set_text(timeAMPM, ampmChar);
}
- // Display the time as 2 pairs of digits
- sprintf(hourStr, "%c%c", hoursChar[0], hoursChar[1]);
- lv_label_set_text(timeDD1, hourStr);
-
- sprintf(minStr, "%c%c", minutesChar[0], minutesChar[1]);
- lv_label_set_text(timeDD2, minStr);
+ lv_label_set_text_fmt(timeDD1, "%s", hoursChar);
+ lv_label_set_text_fmt(timeDD2, "%s", minutesChar);
}
if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) {
- char dayOfWeekStr[4];
- char dayStr[3];
- char monthStr[4];
-
- sprintf(dayOfWeekStr, "%s", dateTimeController.DayOfWeekShortToString());
- sprintf(dayStr, "%d", day);
- sprintf(monthStr, "%s", dateTimeController.MonthShortToString());
-
- lv_label_set_text(dateDayOfWeek, dayOfWeekStr);
- lv_label_set_text(dateDay, dayStr);
+ lv_label_set_text_fmt(dateDayOfWeek, "%s", dateTimeController.DayOfWeekShortToString());
+ lv_label_set_text_fmt(dateDay, "%d", day);
lv_obj_realign(dateDay);
- lv_label_set_text(dateMonth, monthStr);
+ lv_label_set_text_fmt(dateMonth, "%s", dateTimeController.MonthShortToString());
currentYear = year;
currentMonth = month;
diff --git a/src/displayapp/screens/PineTimeStyle.h b/src/displayapp/screens/PineTimeStyle.h
index 71b8b654..948f9929 100644
--- a/src/displayapp/screens/PineTimeStyle.h
+++ b/src/displayapp/screens/PineTimeStyle.h
@@ -32,8 +32,6 @@ namespace Pinetime {
bool Refresh() override;
- void OnObjectEvent(lv_obj_t* pObj, lv_event_t i);
-
private:
char displayedChar[5];
@@ -67,9 +65,6 @@ namespace Pinetime {
lv_obj_t* calendarBar2;
lv_obj_t* calendarCrossBar1;
lv_obj_t* calendarCrossBar2;
- lv_obj_t* heartbeatIcon;
- lv_obj_t* heartbeatValue;
- lv_obj_t* heartbeatBpm;
lv_obj_t* notificationIcon;
lv_obj_t* stepGauge;
lv_color_t needle_colors[1];
diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp
index f1889379..621929b8 100644
--- a/src/displayapp/screens/WatchFaceAnalog.cpp
+++ b/src/displayapp/screens/WatchFaceAnalog.cpp
@@ -10,38 +10,37 @@ LV_IMG_DECLARE(bg_clock);
using namespace Pinetime::Applications::Screens;
namespace {
-
-constexpr auto HOUR_LENGTH = 70;
-constexpr auto MINUTE_LENGTH = 90;
-constexpr auto SECOND_LENGTH = 110;
+constexpr int16_t HourLength = 70;
+constexpr int16_t MinuteLength = 90;
+constexpr int16_t SecondLength = 110;
// sin(90) = 1 so the value of _lv_trigo_sin(90) is the scaling factor
const auto LV_TRIG_SCALE = _lv_trigo_sin(90);
-int16_t cosine(int16_t angle) {
+int16_t Cosine(int16_t angle) {
return _lv_trigo_sin(angle + 90);
}
-int16_t sine(int16_t angle) {
+int16_t Sine(int16_t angle) {
return _lv_trigo_sin(angle);
}
-int16_t coordinate_x_relocate(int16_t x) {
+int16_t CoordinateXRelocate(int16_t x) {
return (x + LV_HOR_RES / 2);
}
-int16_t coordinate_y_relocate(int16_t y) {
+int16_t CoordinateYRelocate(int16_t y) {
return std::abs(y - LV_HOR_RES / 2);
}
-lv_point_t coordinate_relocate(int16_t radius, int16_t angle) {
+lv_point_t CoordinateRelocate(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)
+ .x = CoordinateXRelocate(radius * static_cast<int32_t>(Sine(angle)) / LV_TRIG_SCALE),
+ .y = CoordinateYRelocate(radius * static_cast<int32_t>(Cosine(angle)) / LV_TRIG_SCALE)
};
}
-} // namespace
+}
WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app,
Controllers::DateTime& dateTimeController,
@@ -123,7 +122,6 @@ WatchFaceAnalog::WatchFaceAnalog(Pinetime::Applications::DisplayApp* app,
}
WatchFaceAnalog::~WatchFaceAnalog() {
-
lv_style_reset(&hour_line_style);
lv_style_reset(&hour_line_style_trace);
lv_style_reset(&minute_line_style);
@@ -134,18 +132,17 @@ WatchFaceAnalog::~WatchFaceAnalog() {
}
void WatchFaceAnalog::UpdateClock() {
-
hour = dateTimeController.Hours();
minute = dateTimeController.Minutes();
second = dateTimeController.Seconds();
if (sMinute != minute) {
auto const angle = minute * 6;
- minute_point[0] = coordinate_relocate(30, angle);
- minute_point[1] = coordinate_relocate(MINUTE_LENGTH, angle);
+ minute_point[0] = CoordinateRelocate(30, angle);
+ minute_point[1] = CoordinateRelocate(MinuteLength, angle);
- minute_point_trace[0] = coordinate_relocate(5, angle);
- minute_point_trace[1] = coordinate_relocate(31, angle);
+ minute_point_trace[0] = CoordinateRelocate(5, angle);
+ minute_point_trace[1] = CoordinateRelocate(31, angle);
lv_line_set_points(minute_body, minute_point, 2);
lv_line_set_points(minute_body_trace, minute_point_trace, 2);
@@ -156,11 +153,11 @@ void WatchFaceAnalog::UpdateClock() {
sMinute = minute;
auto const angle = (hour * 30 + minute / 2);
- hour_point[0] = coordinate_relocate(30, angle);
- hour_point[1] = coordinate_relocate(HOUR_LENGTH, angle);
+ hour_point[0] = CoordinateRelocate(30, angle);
+ hour_point[1] = CoordinateRelocate(HourLength, angle);
- hour_point_trace[0] = coordinate_relocate(5, angle);
- hour_point_trace[1] = coordinate_relocate(31, angle);
+ hour_point_trace[0] = CoordinateRelocate(5, angle);
+ hour_point_trace[1] = CoordinateRelocate(31, angle);
lv_line_set_points(hour_body, hour_point, 2);
lv_line_set_points(hour_body_trace, hour_point_trace, 2);
@@ -170,8 +167,8 @@ void WatchFaceAnalog::UpdateClock() {
sSecond = second;
auto const angle = second * 6;
- second_point[0] = coordinate_relocate(-20, angle);
- second_point[1] = coordinate_relocate(SECOND_LENGTH, angle);
+ second_point[0] = CoordinateRelocate(-20, angle);
+ second_point[1] = CoordinateRelocate(SecondLength, angle);
lv_line_set_points(second_body, second_point, 2);
}
}
@@ -186,16 +183,12 @@ bool WatchFaceAnalog::Refresh() {
notificationState = notificationManager.AreNewNotificationsAvailable();
if (notificationState.IsUpdated()) {
- if (notificationState.Get() == true)
- lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(true));
- else
- lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false));
+ lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(notificationState.Get()));
}
currentDateTime = dateTimeController.CurrentDateTime();
if (currentDateTime.IsUpdated()) {
-
month = dateTimeController.Month();
day = dateTimeController.Day();
dayOfWeek = dateTimeController.DayOfWeek();
@@ -203,7 +196,6 @@ bool WatchFaceAnalog::Refresh() {
UpdateClock();
if ((month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) {
-
lv_label_set_text_fmt(label_date_day, "%s\n%02i", dateTimeController.DayOfWeekShortToString(), day);
currentMonth = month;
diff --git a/src/displayapp/screens/WatchFaceAnalog.h b/src/displayapp/screens/WatchFaceAnalog.h
index ac7f0ac5..5d8c6a24 100644
--- a/src/displayapp/screens/WatchFaceAnalog.h
+++ b/src/displayapp/screens/WatchFaceAnalog.h
@@ -58,14 +58,12 @@ namespace Pinetime {
lv_obj_t* minute_body_trace;
lv_obj_t* second_body;
- // ##
lv_point_t hour_point[2];
lv_point_t hour_point_trace[2];
lv_point_t minute_point[2];
lv_point_t minute_point_trace[2];
lv_point_t second_point[2];
- // ##
lv_style_t hour_line_style;
lv_style_t hour_line_style_trace;
lv_style_t minute_line_style;
diff --git a/src/displayapp/screens/WatchFaceDigital.cpp b/src/displayapp/screens/WatchFaceDigital.cpp
index f1285eaf..7a240f1f 100644
--- a/src/displayapp/screens/WatchFaceDigital.cpp
+++ b/src/displayapp/screens/WatchFaceDigital.cpp
@@ -12,9 +12,6 @@
#include "components/ble/NotificationManager.h"
#include "components/heartrate/HeartRateController.h"
#include "components/motion/MotionController.h"
-#include "components/settings/Settings.h"
-#include "../DisplayApp.h"
-
using namespace Pinetime::Applications::Screens;
WatchFaceDigital::WatchFaceDigital(DisplayApp* app,
@@ -36,12 +33,6 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app,
motionController {motionController} {
settingsController.SetClockFace(0);
- displayedChar[0] = 0;
- displayedChar[1] = 0;
- displayedChar[2] = 0;
- displayedChar[3] = 0;
- displayedChar[4] = 0;
-
batteryIcon = lv_label_create(lv_scr_act(), nullptr);
lv_label_set_text(batteryIcon, Symbols::batteryFull);
lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 2);
@@ -56,7 +47,7 @@ WatchFaceDigital::WatchFaceDigital(DisplayApp* app,
lv_label_set_text(bleIcon, Symbols::bluetooth);
lv_obj_align(bleIcon, batteryPlug, LV_ALIGN_OUT_LEFT_MID, -5, 0);
- notificationIcon = lv_label_create(lv_scr_act(), NULL);
+ notificationIcon = lv_label_create(lv_scr_act(), nullptr);
lv_obj_set_style_local_text_color(notificationIcon, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x00FF00));
lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false));
lv_obj_align(notificationIcon, nullptr, LV_ALIGN_IN_TOP_LEFT, 10, 0);
@@ -111,17 +102,13 @@ bool WatchFaceDigital::Refresh() {
if (batteryPercentRemaining.IsUpdated()) {
auto batteryPercent = batteryPercentRemaining.Get();
lv_label_set_text(batteryIcon, BatteryIcon::GetBatteryIcon(batteryPercent));
- auto isCharging = batteryController.IsCharging() || batteryController.IsPowerPresent();
+ auto isCharging = batteryController.IsCharging() or batteryController.IsPowerPresent();
lv_label_set_text(batteryPlug, BatteryIcon::GetPlugIcon(isCharging));
}
bleState = bleController.IsConnected();
if (bleState.IsUpdated()) {
- if (bleState.Get() == true) {
- lv_label_set_text(bleIcon, BleIcon::GetIcon(true));
- } else {
- lv_label_set_text(bleIcon, BleIcon::GetIcon(false));
- }
+ lv_label_set_text(bleIcon, BleIcon::GetIcon(bleState.Get()));
}
lv_obj_align(batteryIcon, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -5, 5);
lv_obj_align(batteryPlug, batteryIcon, LV_ALIGN_OUT_LEFT_MID, -5, 0);
@@ -129,10 +116,7 @@ bool WatchFaceDigital::Refresh() {
notificationState = notificatioManager.AreNewNotificationsAvailable();
if (notificationState.IsUpdated()) {
- if (notificationState.Get() == true)
- lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(true));
- else
- lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(false));
+ lv_label_set_text(notificationIcon, NotificationIcon::GetIcon(notificationState.Get()));
}
currentDateTime = dateTimeController.CurrentDateTime();
@@ -144,9 +128,9 @@ bool WatchFaceDigital::Refresh() {
auto time = date::make_time(newDateTime - dp);
auto yearMonthDay = date::year_month_day(dp);
- auto year = (int) yearMonthDay.year();
- auto month = static_cast<Pinetime::Controllers::DateTime::Months>((unsigned) yearMonthDay.month());
- auto day = (unsigned) yearMonthDay.day();
+ auto year = static_cast<int>(yearMonthDay.year());
+ auto month = static_cast<Pinetime::Controllers::DateTime::Months>(static_cast<unsigned>(yearMonthDay.month()));
+ auto day = static_cast<unsigned>(yearMonthDay.day());
auto dayOfWeek = static_cast<Pinetime::Controllers::DateTime::Days>(date::weekday(yearMonthDay).iso_encoding());
int hour = time.hours().count();
@@ -175,15 +159,13 @@ bool WatchFaceDigital::Refresh() {
sprintf(hoursChar, "%02d", hour);
}
- if (hoursChar[0] != displayedChar[0] || hoursChar[1] != displayedChar[1] || minutesChar[0] != displayedChar[2] ||
- minutesChar[1] != displayedChar[3]) {
+ if ((hoursChar[0] != displayedChar[0]) or (hoursChar[1] != displayedChar[1]) or (minutesChar[0] != displayedChar[2]) or
+ (minutesChar[1] != displayedChar[3])) {
displayedChar[0] = hoursChar[0];
displayedChar[1] = hoursChar[1];
displayedChar[2] = minutesChar[0];
displayedChar[3] = minutesChar[1];
- char timeStr[6];
-
if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) {
lv_label_set_text(label_time_ampm, ampmChar);
if (hoursChar[0] == '0') {
@@ -191,8 +173,7 @@ bool WatchFaceDigital::Refresh() {
}
}
- sprintf(timeStr, "%c%c:%c%c", hoursChar[0], hoursChar[1], minutesChar[0], minutesChar[1]);
- lv_label_set_text(label_time, timeStr);
+ lv_label_set_text_fmt(label_time, "%s:%s", hoursChar, minutesChar);
if (settingsController.GetClockType() == Controllers::Settings::ClockType::H12) {
lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, 0, 0);
@@ -202,13 +183,11 @@ bool WatchFaceDigital::Refresh() {
}
if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) {
- char dateStr[22];
if (settingsController.GetClockType() == Controllers::Settings::ClockType::H24) {
- sprintf(dateStr, "%s %d %s %d", dateTimeController.DayOfWeekShortToString(), day, dateTimeController.MonthShortToString(), year);
+ lv_label_set_text_fmt(label_date, "%s %d %s %d", dateTimeController.DayOfWeekShortToString(), day, dateTimeController.MonthShortToString(), year);
} else {
- sprintf(dateStr, "%s %s %d %d", dateTimeController.DayOfWeekShortToString(), dateTimeController.MonthShortToString(), day, year);
+ lv_label_set_text_fmt(label_date, "%s %s %d %d", dateTimeController.DayOfWeekShortToString(), dateTimeController.MonthShortToString(), day, year);
}
- lv_label_set_text(label_date, dateStr);
lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_CENTER, 0, 60);
currentYear = year;
diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h
index 76c8d3dc..6a6e1ac6 100644
--- a/src/displayapp/screens/WatchFaceDigital.h
+++ b/src/displayapp/screens/WatchFaceDigital.h
@@ -35,10 +35,8 @@ namespace Pinetime {
bool Refresh() override;
- void OnObjectEvent(lv_obj_t* pObj, lv_event_t i);
-
private:
- char displayedChar[5];
+ char displayedChar[5] {};
uint16_t currentYear = 1970;
Pinetime::Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown;
@@ -63,7 +61,6 @@ namespace Pinetime {
lv_obj_t* batteryPlug;
lv_obj_t* heartbeatIcon;
lv_obj_t* heartbeatValue;
- lv_obj_t* heartbeatBpm;
lv_obj_t* stepIcon;
lv_obj_t* stepValue;
lv_obj_t* notificationIcon;