summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/c-cpp.yml202
-rw-r--r--CMakeLists.txt2
-rw-r--r--README.md37
-rw-r--r--bootloader/README.md15
-rw-r--r--doc/SPI-LCD-driver.md6
-rw-r--r--doc/branches.md12
-rw-r--r--doc/contribute.md24
-rw-r--r--doc/filesInReleaseNotes.md56
-rw-r--r--doc/versioning.md6
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/Components/Ble/MusicService.cpp130
-rw-r--r--src/Components/Ble/MusicService.h92
-rw-r--r--src/Components/Ble/NimbleController.cpp9
-rw-r--r--src/Components/Ble/NimbleController.h10
-rw-r--r--src/DisplayApp/DisplayApp.cpp2
-rw-r--r--src/DisplayApp/DisplayApp.h2
-rw-r--r--src/DisplayApp/Screens/Gauge.cpp1
-rw-r--r--src/DisplayApp/Screens/Music.cpp125
-rw-r--r--src/DisplayApp/Screens/Music.h49
-rw-r--r--src/DisplayApp/Screens/Tile.cpp2
-rw-r--r--src/SystemTask/SystemTask.cpp1
-rw-r--r--src/SystemTask/SystemTask.h7
-rw-r--r--src/drivers/TwiMaster.cpp4
23 files changed, 767 insertions, 29 deletions
diff --git a/.github/workflows/c-cpp.yml b/.github/workflows/c-cpp.yml
new file mode 100644
index 00000000..0647089a
--- /dev/null
+++ b/.github/workflows/c-cpp.yml
@@ -0,0 +1,202 @@
+# GitHub Action to build FreeRTOS Firmware for PineTime Smart Watch
+# Based on https://github.com/lupyuen/pinetime-lab/blob/master/doc/buildAndProgram.md
+
+name: C/C++ CI
+
+# Run this workflow on every push and pull request on "master" branch
+on:
+ push:
+ branches: [ master ]
+ pull_request:
+ branches: [ master ]
+
+# Steps to be run for the workflow
+jobs:
+ build:
+
+ # Run these steps on Ubuntu
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Install cmake
+ uses: lukka/get-cmake@v3.18.0
+
+ - name: Check cache for Embedded Arm Toolchain arm-none-eabi-gcc
+ id: cache-toolchain
+ uses: actions/cache@v2
+ env:
+ cache-name: cache-toolchain
+ with:
+ path: ${{ runner.temp }}/arm-none-eabi
+ key: ${{ runner.os }}-build-${{ env.cache-name }}
+ restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}
+
+ - name: Install Embedded Arm Toolchain arm-none-eabi-gcc
+ if: steps.cache-toolchain.outputs.cache-hit != 'true' # Install toolchain if not found in cache
+ uses: fiam/arm-none-eabi-gcc@v1.0.2
+ with:
+ # GNU Embedded Toolchain for Arm release name, in the V-YYYY-qZ format (e.g. "9-2019-q4")
+ release: 8-2019-q3
+ # Directory to unpack GCC to. Defaults to a temporary directory.
+ directory: ${{ runner.temp }}/arm-none-eabi
+
+ - name: Check cache for nRF5 SDK
+ id: cache-nrf5sdk
+ uses: actions/cache@v2
+ env:
+ cache-name: cache-nrf5sdk
+ with:
+ path: ${{ runner.temp }}/nrf5_sdk
+ key: ${{ runner.os }}-build-${{ env.cache-name }}
+ restore-keys: ${{ runner.os }}-build-${{ env.cache-name }}
+
+ - name: Install nRF5 SDK
+ if: steps.cache-nrf5sdk.outputs.cache-hit != 'true' # Install SDK if not found in cache
+ run: cd ${{ runner.temp }} && curl https://developer.nordicsemi.com/nRF5_SDK/nRF5_SDK_v15.x.x/nRF5_SDK_15.3.0_59ac345.zip -o nrf5_sdk.zip && unzip nrf5_sdk.zip && mv nRF5_SDK_15.3.0_59ac345 nrf5_sdk
+
+ - name: Checkout source files
+ uses: actions/checkout@v2
+
+ - name: Show files
+ run: set ; pwd ; ls -l
+
+ - name: CMake
+ run: mkdir -p build && cd build && cmake -DARM_NONE_EABI_TOOLCHAIN_PATH=${{ runner.temp }}/arm-none-eabi -DNRF5_SDK_PATH=${{ runner.temp }}/nrf5_sdk -DUSE_OPENOCD=1 ../
+
+ - name: Make
+ # For debugging builds, remove option "-j" for clearer output. Add "--trace" to see details.
+ run: cd build && make -j pinetime-app
+
+ - name: Find output
+ run: find . -name pinetime-app.out
+
+ - name: Upload built firmware
+ uses: actions/upload-artifact@v2
+ with:
+ # Artifact name (optional)
+ name: pinetime-app.out
+ # A file, directory or wildcard pattern that describes what to upload
+ path: build/src/pinetime-app.out
+
+# Embedded Arm Toolchain and nRF5 SDK will only be cached if the build succeeds.
+# So make sure that the first build always succeeds, e.g. comment out the "Make" step.
+
+# Sample compile command:
+# [100%] Building CXX object src/CMakeFiles/pinetime-app.dir/drivers/TwiMaster.cpp.o
+# cd /home/runner/work/pinetime-lab/pinetime-lab/build/src && /home/runner/work/_temp/arm-none-eabi/bin/arm-none-eabi-c++ --sysroot=/home/runner/work/_temp/arm-none-eabi/bin \
+# -DBOARD_PCA10040 \
+# -DCONFIG_GPIO_AS_PINRESET \
+# -DDEBUG \
+# -DDEBUG_NRF_USER \
+# -DFREERTOS \
+# -DNIMBLE_CFG_CONTROLLER \
+# -DNRF52 \
+# -DNRF52832 \
+# -DNRF52832_XXAA \
+# -DNRF52_PAN_12 \
+# -DNRF52_PAN_15 \
+# -DNRF52_PAN_20 \
+# -DNRF52_PAN_31 \
+# -DNRF52_PAN_36 \
+# -DNRF52_PAN_51 \
+# -DNRF52_PAN_54 \
+# -DNRF52_PAN_55 \
+# -DNRF52_PAN_58 \
+# -DNRF52_PAN_64 \
+# -DNRF52_PAN_74 \
+# -DOS_CPUTIME_FREQ \
+# -D__HEAP_SIZE=8192 \
+# -D__STACK_SIZE=8192 \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/. \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/.. \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/FreeRTOS \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs/date/includes \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs/mynewt-nimble/porting/npl/freertos/include \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs/mynewt-nimble/nimble/include \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs/mynewt-nimble/porting/nimble/include \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs/mynewt-nimble/nimble/host/include \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs/mynewt-nimble/nimble/controller/include \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs/mynewt-nimble/nimble/transport/ram/include \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs/mynewt-nimble/nimble/drivers/nrf52/include \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs/mynewt-nimble/ext/tinycrypt/include \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs/mynewt-nimble/nimble/host/services/gap/include \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs/mynewt-nimble/nimble/host/services/gatt/include \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs/mynewt-nimble/nimble/host/util/include \
+# -I/home/runner/work/pinetime-lab/pinetime-lab/src/libs/mynewt-nimble/nimble/host/store/ram/include \
+# -I/home/runner/work/_temp/nrf5_sdk/components/drivers_nrf/nrf_soc_nosd \
+# -I/home/runner/work/_temp/nrf5_sdk/components \
+# -I/home/runner/work/_temp/nrf5_sdk/components/boards \
+# -I/home/runner/work/_temp/nrf5_sdk/components/softdevice/common \
+# -I/home/runner/work/_temp/nrf5_sdk/integration/nrfx \
+# -I/home/runner/work/_temp/nrf5_sdk/integration/nrfx/legacy \
+# -I/home/runner/work/_temp/nrf5_sdk/modules/nrfx \
+# -I/home/runner/work/_temp/nrf5_sdk/modules/nrfx/drivers/include \
+# -I/home/runner/work/_temp/nrf5_sdk/modules/nrfx/hal \
+# -I/home/runner/work/_temp/nrf5_sdk/modules/nrfx/mdk \
+# -I/home/runner/work/_temp/nrf5_sdk/external/freertos/source/include \
+# -I/home/runner/work/_temp/nrf5_sdk/components/toolchain/cmsis/include \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/atomic \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/atomic_fifo \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/atomic_flags \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/balloc \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/bootloader/ble_dfu \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/cli \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/crc16 \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/crc32 \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/crypto \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/csense \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/csense_drv \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/delay \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/ecc \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/experimental_section_vars \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/experimental_task_manager \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/fds \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/fstorage \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/gfx \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/gpiote \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/hardfault \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/hci \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/led_softblink \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/log \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/log/src \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/low_power_pwm \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/mem_manager \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/memobj \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/mpu \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/mutex \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/pwm \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/pwr_mgmt \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/queue \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/ringbuf \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/scheduler \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/sdcard \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/slip \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/sortlist \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/spi_mngr \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/stack_guard \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/strerror \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/svc \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/timer \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/usbd \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/usbd/class/audio \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/usbd/class/cdc \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/usbd/class/cdc/acm \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/usbd/class/hid \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/usbd/class/hid/generic \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/usbd/class/hid/kbd \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/usbd/class/hid/mouse \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/usbd/class/msc \
+# -I/home/runner/work/_temp/nrf5_sdk/components/libraries/util \
+# -I/home/runner/work/_temp/nrf5_sdk/external/segger_rtt \
+# -I/home/runner/work/_temp/nrf5_sdk/external/fprintf \
+# -I/home/runner/work/_temp/nrf5_sdk/external/thedotfactory_fonts -O3 \
+# -DNDEBUG -MP -MD -mthumb -mabi=aapcs -Wall -g3 \
+# -ffunction-sections -fdata-sections -fno-strict-aliasing -fno-builtin \
+# --short-enums -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 \
+# -Wreturn-type -Werror=return-type -O3 -std=gnu++11 \
+# -o CMakeFiles/pinetime-app.dir/drivers/TwiMaster.cpp.o \
+# -c /home/runner/work/pinetime-lab/pinetime-lab/src/drivers/TwiMaster.cpp
+
+# /home/runner/work/pinetime-lab/pinetime-lab/src/drivers/TwiMaster.cpp:1:10: fatal error: sdk/integration/nrfx/nrfx_log.h: No such file or directory
+# #include <sdk/integration/nrfx/nrfx_log.h>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ed8abfc9..e33040c3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.10)
-project(pinetime VERSION 0.7.1 LANGUAGES C CXX ASM)
+project(pinetime VERSION 0.8.0 LANGUAGES C CXX ASM)
set(NRF_TARGET "nrf52")
diff --git a/README.md b/README.md
index 025828a4..1a010c56 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
*https://www.pine64.org/pinetime/*
-The **Pinetime** smartwatch is built around the NRF52832 MCU (512KB Flash, 64KB RAM), a 240*240 LCD display driven by the ST7789 controller, an accelerometer, a heartrate sensor and a vibrator.
+The **Pinetime** smartwatch is built around the NRF52832 MCU (512KB Flash, 64KB RAM), a 240*240 LCD display driven by the ST7789 controller, an accelerometer, a heart rate sensor, and a vibration motor.
# InfiniTime
![InfiniTime logo](images/infinitime-logo.jpg "InfiniTime Logo")
@@ -19,7 +19,7 @@ The goal of this project is to design an open-source firmware for the Pinetime s
- Using **[LittleVGL/LVGL 6.1.2](https://lvgl.io/)** as UI library...
- ... and **[NimBLE 1.3.0](https://github.com/apache/mynewt-nimble)** as BLE stack.
-##Overview
+## Overview
![Pinetime screens](images/0.7.0/montage.jpg "PinetimeScreens")
@@ -27,29 +27,36 @@ As of now, here is the list of achievements of this project:
- Fast and optimized LCD driver
- BLE communication
- - Rich user interface via display, touchpanel and push button
- - Time synchronisation via BLE
+ - Rich user interface via display, touch panel and push button
+ - Time synchronization via BLE
- Notification via BLE
- Multiple 'apps' :
- * Clock (displays the date, time, battery level, ble connection status, heart rate and step count)
+ * Clock (displays the date, time, battery level, BLE connection status, heart rate and step count)
* Heart rate
* Motion
- * System info (displays various info : BLE MAC, build date/time, uptime, version,...)
- * Brightess (allows the user to configure the brightness of the display)
- - Supported by 2 companion apps (developpments ongoing):
+ * System info (displays various info : BLE MAC adress, build date/time, uptime, version, ...)
+ * Brightness (allows the user to configure the brightness of the display)
+ - Supported by 2 companion apps (development is ongoing):
* [Gadgetbridge](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/branch/pinetime-jf) (on Android)
* [Amazfish](https://openrepos.net/content/piggz/amazfish) (on SailfishOS)
- **[Experimental]** OTA (Over-the-air) update via BLE
- **[Experimental]** Bootloader based on [MCUBoot](https://juullabs-oss.github.io/mcuboot/)
## Documentation
+
### Build, flash and debug
+ - [Project branches](doc/branches.md)
+ - [Versioning](doc/versioning.md)
+ - [Files included in the release notes](doc/filesInReleaseNotes.md)
- [Build the project](doc/buildAndProgram.md)
- [Bootloader, OTA and DFU](./bootloader/README.md)
- [Stub using NRF52-DK](./doc/PinetimeStubWithNrf52DK.md)
- Logging with JLink RTT.
- Using files from the releases
-
+
+## Contribute
+ - [How to contribute ?](doc/contribute.md)
+
### API
- [BLE implementation and API](./doc/ble.md)
@@ -65,19 +72,19 @@ As of now, here is the list of achievements of this project:
## TODO - contribute
-This project is far from beeing finished, and there are still a lot of things to do for this project to become a firmware usable by the general public.
+This project is far from being finished, and there are still a lot of things to do for this project to become a firmware usable by the general public.
Here a quick list out of my head of things to do for this project:
- Improve BLE communication stability and reliability
- Improve OTA and MCUBoot bootloader
- - Add more functionalities : Alarm, chrono, configuration, activities, heart rate logging, games,...
+ - Add more functionalities : Alarm, chronometer, configuration, activities, heart rate logging, games,...
- Add more BLE functionalities : call notifications, agenda, configuration, data logging,...
- Measure power consumption and improve battery life
- Improve documentation, take better pictures and video than mine
- Improve the UI
- - Create companion app for multiple OSes (Linux, Android, IoS) and platforms (desktop, ARM, mobile). Do not forget the other devices from Pine64 like [the Pinephone](https://www.pine64.org/pinephone/) and the [Pinebook Pro](https://www.pine64.org/pinebook-pro/).
- - Design a simple CI (preferably selfhosted and easy to reproduce).
+ - Create companion app for multiple OSes (Linux, Android, iOS) and platforms (desktop, ARM, mobile). Do not forget the other devices from Pine64 like [the Pinephone](https://www.pine64.org/pinephone/) and the [Pinebook Pro](https://www.pine64.org/pinebook-pro/).
+ - Design a simple CI (preferably self-hosted and easy to reproduce).
Do not hesitate to clone/fork the code, hack it and create pull-requests. I'll do my best to review and merge them :)
@@ -96,7 +103,7 @@ I’m not working alone on this project. First, many people create PR for this p
Here are some people I would like to highlight:
- [Atc1441](https://github.com/atc1441/) : He works on an Arduino based firmware for the Pinetime and many other smartwatches based on similar hardware. He was of great help when I was implementing support for the BMA421 motion sensor and I²C driver.
- - [Koen](https://github.com/bosmoment) : He’s working on a firmware based on RiotOS. He integrated similar libs than me : NimBLE, LittleVGL,… His help was invaluable too!
- - [Lup Yuen Lee](https://github.com/lupyuen) : He is everywhere : he works on a Rust firmware, buils a MCUBoot based bootloader for the Pinetime, design a Flutter based companion app for smartphones and write a lot of articles about the Pinetime!
+ - [Koen](https://github.com/bosmoment) : He’s working on a firmware based on RiotOS. He integrated similar libs as me : NimBLE, LittleVGL,… His help was invaluable too!
+ - [Lup Yuen Lee](https://github.com/lupyuen) : He is everywhere: he works on a Rust firmware, builds a MCUBoot based bootloader for the Pinetime, designs a Flutter based companion app for smartphones and writes a lot of articles about the Pinetime!
*If you feel like you should appear on this list, just get in touch with me or submit a PR :)*
diff --git a/bootloader/README.md b/bootloader/README.md
index 7f6c25aa..efd9b6b1 100644
--- a/bootloader/README.md
+++ b/bootloader/README.md
@@ -1,4 +1,17 @@
-# Bootloader
+# About this bootloader
+This bootloader is mostly developed by [Lup Yuen](https://github.com/lupyuen). It is based on MCUBoot and Mynewt.
+
+The goal of this project is to provide a common bootloader for multiple (all?) Pinetime projects. It allows to upgrade the current bootloader and even replace the current application by another one that supports the same bootloader.
+
+As we wanted this bootloader to be as universal as possible, we decided that it should **not** integrate a BLE stack and provide OTA capabilities.
+
+Integrating a BLE stack for the OTA functionality would have used to much memory space and/or forced all the firmware developers to use the same BLE stack as the bootloader.
+
+When it is run, this bootloader looks in the SPI flash memory if a new firmware is available. It there is one, it *swaps* the current firmware with the new one (the new one is copied in the main flash memory, and the current one is copied in the SPI flash memory) and run the new one. If the new one fails to run properly, the bootloader is able to revert to the old one and mark the new one as not working.
+
+As this bootloader does not provide any OTA capability, it is not able to actually download a new version of the application. Providing OTA functionality is thus the responsability of the application firmware.
+
+# Using the bootlader
## Bootloader graphic
The bootloader loads a graphic (Pinetime logo) from the SPI Flash memory. If this graphic is not loaded in the memory, the LCD will display garbage (the content of the SPI flash memory).
diff --git a/doc/SPI-LCD-driver.md b/doc/SPI-LCD-driver.md
index 3c33c258..f787aab7 100644
--- a/doc/SPI-LCD-driver.md
+++ b/doc/SPI-LCD-driver.md
@@ -24,17 +24,17 @@ As I said in the introduction, the datasheet will be your bedside book during yo
The schematic of your board (the Pinetime schematics in this case) will also be very important, as you'll need to know how the LCD controller is physically connected to the MCU.
-How to read the datasheet? I recommand to read it from the beginning to the end (no joke) at least once. You certainly do not need to read everything in details, but it's good to know what information is available and where in the document. It'll be very useful during the developpment phase.
+How to read the datasheet? I recommend to read it from the beginning to the end (no joke) at least once. You certainly do not need to read everything in details, but it's good to know what information is available and where in the document. It'll be very useful during the development phase.
You'll want to read some part with more attention :
- Data color coding in 4-Line Serial Interface : how to send the pixel to be display to the controller
-- Display Data Ram : how is the memory organised
+- Display Data Ram : how is the memory organized
- Power On/Off sequence
- System function commands : all the commands you can send to the controller.
## One Pixel at a time
-## Bulk transfert
+## Bulk transfers
## DMA
diff --git a/doc/branches.md b/doc/branches.md
new file mode 100644
index 00000000..0fb8316d
--- /dev/null
+++ b/doc/branches.md
@@ -0,0 +1,12 @@
+# Branches
+The branching model of this project is based on the workflow named [Git flow](https://nvie.com/posts/a-successful-git-branching-model/).
+
+It is based on 2 main branches:
+ - **master** : this branch is always ready to be reployed. It means that at any time, we should be able to build the branch and release a new version of the application.
+ - **develop** : this branch contains the latest development that will be integrated in the next release once it's considered as stable.
+
+New features should be implemented in **feature branches** created from **develop**. When the feature is ready, a pull-request is created and it'll be merge into **develop** when it is succesfully reviewed and accepted.
+
+To release a new version of the application, when develop is considered stable, a **release** branch is created from **develop**. This can be considered as a *release candidate* branch. When everything is OK, this release branch is merged into **master** and the release is generated (a tag is applied to git, the release note is finalized, binaries are built,...) from **master**.
+
+Git flow also supports the creation of **hotfix** branches when a bug is discovered in a released version. The **hotfix** branch is created from **master** and will be used only to implement a fix to this bug. Multiple hotfix branches can be created for the same release if more than one bugs are discovered. \ No newline at end of file
diff --git a/doc/contribute.md b/doc/contribute.md
new file mode 100644
index 00000000..53c6ac06
--- /dev/null
+++ b/doc/contribute.md
@@ -0,0 +1,24 @@
+# How to contribute?
+## Report bugs
+You use your Pinetime and find a bug in the firmware? [Create an issue on Github](https://github.com/JF002/Pinetime/issues) explaining the bug, how to reproduce it, the version of the firmware you use...
+## Write and improve documentation
+Documentation might be incomplete, or not clear enough, and it is always possible to improve it with better wording, pictures, photo, video,...
+
+As the documentation is part of the source code, you can submit your improvements to the documentation by submitting a pull request (see below).
+## Fix bugs, add functionalities and improve the code
+You want to fix a bug, add a cool new functionality or improve the code? See *How to submit a pull request below*.
+## Spread the word
+Pinetime is a cool open source project that deserves to be know. Talk about it around you, on social networks, on your blog,... and let people know that we are working on an open-source firmware for a smartwatch!
+
+# How to submit a pull request ?
+Your contribution is more than welcome!
+
+If you want to fix a bug, add a functionality or improve the code, you'll first need to create a branch from the **develop** branch (see [this page about the branching model](./branches.md)). This branch is called a feature branch, and you should choose a name that explains what you are working on (ex: "add-doc-about-contributions"). In this branch, try to focus on only one topic, bug or feature. For example, if you created this branch to work on the UI of a specific application, do not commit modifications about the SPI driver. If you want to work on multiple topics, create one branch per topic.
+
+When your feature branch is ready, make sure it actually works and do not forget to write documentation about it if necessary.
+
+Then, you can submit a pull-request for review. Try to describe your pull request as much as possible: what did you do in this branch, how does it work, how is it designed, are there any limitations,... This will help the contributors to understand and review your code easily.
+
+Other contributors can post comments about the pull request, maybe ask for more info or adjustements in the code.
+
+Once the pull request is reviewed an accepted, it'll be merge in **develop** and will be released in the next release version of the firmware. \ No newline at end of file
diff --git a/doc/filesInReleaseNotes.md b/doc/filesInReleaseNotes.md
new file mode 100644
index 00000000..e9dadb24
--- /dev/null
+++ b/doc/filesInReleaseNotes.md
@@ -0,0 +1,56 @@
+# Using the releases
+For each new *stable* version of Pinetime, a [release note](https://github.com/JF002/Pinetime/releases) is created. It contains a description of the main changes in the release and some files you can use to flash the firmware in your Pinetime.
+
+This page describes the files from the release notes and how to use them.
+
+**NOTE :** the files included in different could be different. This page describes the release note of [version 0.7.1](https://github.com/JF002/Pinetime/releases/tag/0.7.1), which is the version that'll probably be pre-programmed at the factory for the next batch of Pinetime devkits.
+
+## Files included in the release note
+
+### Standalone firmware
+This firmware is standalone, meaning that it does not need a bootloader to actually run. It is intended to be flash at offset 0, meaning it will erase any bootloader that might be present in memory.
+
+ - **pinetime-app.out** : Output file of GCC containing debug symbols, useful is you want to debug the firmware using GDB.
+ - **pinetime-app.hex** : Firmware in Intel HEX file format. Easier to use because it contains the offset in memory where it must be flashed, you don't need to specify it.
+ - **pintime-app.bin** : Firmware in binary format. When programming it, you have to specify the offset (0x00) in memory where it must be flashed.
+ - **pinetime-app.map** : Map file containing all the symbols, addresses in memory,...
+
+**This firmware must be flashed at address 0x00 in the main flash memory**
+
+### Bootloader
+The bootloader is maintained by [lupyuen](https://github.com/lupyuen) and is a binary version of [this release](https://github.com/lupyuen/pinetime-rust-mynewt/releases/tag/v4.1.7).
+
+ - **bootloader.hex** : Firmware in Intel HEX file format.
+
+ **This firmware must be flashed at address 0x00 in the main flash memory**
+
+
+### Graphics firmware
+This firmware is a small utility firmware that writes the boot graphic in the external SPI flash memory. You need it if you want to use the [bootloader](../bootloader/README.md).
+
+ - **pinetime-graphics.out** : Output file of GCC containing debug symbols, useful is you want to debug the firmware using GDB.
+ - **pinetime-graphics.hex** : Firmware in Intel HEX file format. Easier to use because it contains the offset in memory where it must be flashed, you don't need to specify it.
+ - **pintime-graphics.bin** : Firmware in binary format. When programming it, you have to specify the offset (0x00) in memory where it must be flashed.
+ - **pinetime-graphics.map** : Map file containing all the symbols, addresses in memory,...
+
+**This firmware must be flashed at address 0x00 in the main flash memory**
+
+### Firmware with bootloader
+This firmware is intended to be used with our [MCUBoot-based bootloader](../bootloader/README.md).
+
+ - **pinetime-mcuboot-app-image.hex** : Firmware wrapped into an MCUBoot image. This is **the** file that must be flashed **@ 0x8000** into flash memory. If the [bootloader](../bootloader/README.md) has been successfully programmed, it should run this firmware after the next reset.
+
+The following files are not directly usable by the bootloader:
+
+ - **pinetime-mcuboot-app.bin** : Output file of GCC containing debug symbols, useful is you want to debug the firmware using GDB.
+ - **pinetime-mcuboot-app.hex** : Firmware in Intel HEX file format.
+ - **pinetime-mcuboot-app.bin** : Firmware in binary format.
+ - **pinetime-mcuboot-app.map** : Map file containing all the symbols, addresses in memory,...
+
+### OTA (Update the firmware Over-The-Air)
+Once the bootloader and application firmware are running, it is possible to update the current firmware or even replace it with another firmware **that uses the same bootloader based on MCUBoot**.
+
+**NOTE :** Use this file **only** if you programmed our [MCUBoot-based bootloader](../bootloader/README.md). This file is not compatible with other bootloaders like the one that is based on the closed source NRF SoftDevice !
+
+ - **pinetime-app-dfu.zip** : This is the file you must provide toNRFConnect to update the firmware over BLE.
+
diff --git a/doc/versioning.md b/doc/versioning.md
new file mode 100644
index 00000000..b08af714
--- /dev/null
+++ b/doc/versioning.md
@@ -0,0 +1,6 @@
+# Versioning
+The versioning of this project is based on [Semantic versionning](https://semver.org/) :
+
+ - The **patch** is incremented when we fix a bug on a **released** version (most of the time using a **hotfix** branch).
+ - The **minor** is incremented when we release a new version with new features. It corresponds to a merge of **develop** into **master**.
+ - The **major** should be incremented when a breaking change is made to the application. We still have to define what is a breaking change in the context of this project. For now, I suggest that it stays **0** until we have a fully functionning firmware suited for the final user. \ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e60c2cfe..2d6d6e8e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -336,6 +336,7 @@ list(APPEND SOURCE_FILES
DisplayApp/Screens/ScreenList.cpp
DisplayApp/Screens/Label.cpp
DisplayApp/Screens/FirmwareUpdate.cpp
+ DisplayApp/Screens/Music.cpp
main.cpp
drivers/St7789.cpp
drivers/SpiNorFlash.cpp
@@ -356,6 +357,7 @@ list(APPEND SOURCE_FILES
Components/Ble/DfuService.cpp
Components/Ble/CurrentTimeService.cpp
Components/Ble/AlertNotificationService.cpp
+ Components/Ble/MusicService.cpp
drivers/Cst816s.cpp
FreeRTOS/port.c
FreeRTOS/port_cmsis_systick.c
diff --git a/src/Components/Ble/MusicService.cpp b/src/Components/Ble/MusicService.cpp
new file mode 100644
index 00000000..5ec76697
--- /dev/null
+++ b/src/Components/Ble/MusicService.cpp
@@ -0,0 +1,130 @@
+#include <SystemTask/SystemTask.h>
+#include "MusicService.h"
+
+int MSCallback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg) {
+ auto musicService = static_cast<Pinetime::Controllers::MusicService*>(arg);
+ return musicService->OnCommand(conn_handle, attr_handle, ctxt);
+}
+
+Pinetime::Controllers::MusicService::MusicService(Pinetime::System::SystemTask &system) : m_system(system)
+{
+ msUuid.value[11] = msId[0];
+ msUuid.value[12] = msId[1];
+ msEventCharUuid.value[11] = msEventCharId[0];
+ msEventCharUuid.value[12] = msEventCharId[1];
+ msStatusCharUuid.value[11] = msStatusCharId[0];
+ msStatusCharUuid.value[12] = msStatusCharId[1];
+ msTrackCharUuid.value[11] = msTrackCharId[0];
+ msTrackCharUuid.value[12] = msTrackCharId[1];
+ msArtistCharUuid.value[11] = msArtistCharId[0];
+ msArtistCharUuid.value[12] = msArtistCharId[1];
+ msAlbumCharUuid.value[11] = msAlbumCharId[0];
+ msAlbumCharUuid.value[12] = msAlbumCharId[1];
+
+ characteristicDefinition[0] = { .uuid = (ble_uuid_t*)(&msEventCharUuid),
+ .access_cb = MSCallback,
+ .arg = this,
+ .flags = BLE_GATT_CHR_F_NOTIFY,
+ .val_handle = &m_eventHandle
+ };
+ characteristicDefinition[1] = { .uuid = (ble_uuid_t*)(&msStatusCharUuid),
+ .access_cb = MSCallback,
+ .arg = this,
+ .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ
+ };
+ characteristicDefinition[2] = { .uuid = (ble_uuid_t*)(&msTrackCharUuid),
+ .access_cb = MSCallback,
+ .arg = this,
+ .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ
+ };
+ characteristicDefinition[3] = { .uuid = (ble_uuid_t*)(&msArtistCharUuid),
+ .access_cb = MSCallback,
+ .arg = this,
+ .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ
+ };
+ characteristicDefinition[4] = { .uuid = (ble_uuid_t*)(&msAlbumCharUuid),
+ .access_cb = MSCallback,
+ .arg = this,
+ .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_READ
+ };
+ characteristicDefinition[5] = {0};
+
+ serviceDefinition[0] = {
+ .type = BLE_GATT_SVC_TYPE_PRIMARY,
+ .uuid = (ble_uuid_t *) &msUuid,
+ .characteristics = characteristicDefinition
+ };
+ serviceDefinition[1] = {0};
+
+ m_artist = "Waiting for";
+ m_album = "";
+ m_track = "track information...";
+}
+
+void Pinetime::Controllers::MusicService::Init()
+{
+ int res = 0;
+ res = ble_gatts_count_cfg(serviceDefinition);
+ ASSERT(res == 0);
+
+ res = ble_gatts_add_svcs(serviceDefinition);
+ ASSERT(res == 0);
+}
+
+int Pinetime::Controllers::MusicService::OnCommand(uint16_t conn_handle, uint16_t attr_handle,
+ struct ble_gatt_access_ctxt *ctxt) {
+
+ if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
+ size_t notifSize = OS_MBUF_PKTLEN(ctxt->om);
+ uint8_t data[notifSize + 1];
+ data[notifSize] = '\0';
+ os_mbuf_copydata(ctxt->om, 0, notifSize, data);
+ char *s = (char *) &data[0];
+ NRF_LOG_INFO("DATA : %s", s);
+ if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *)&msArtistCharUuid) == 0) {
+ m_artist = s;
+ } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *)&msTrackCharUuid) == 0) {
+ m_track = s;
+ } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *)&msAlbumCharUuid) == 0) {
+ m_album = s;
+ } else if (ble_uuid_cmp(ctxt->chr->uuid, (ble_uuid_t *)&msStatusCharUuid) == 0) {
+ m_status = s[0];
+ }
+ }
+ return 0;
+}
+
+std::string Pinetime::Controllers::MusicService::album()
+{
+ return m_album;
+}
+
+std::string Pinetime::Controllers::MusicService::artist()
+{
+ return m_artist;
+}
+
+std::string Pinetime::Controllers::MusicService::track()
+{
+ return m_track;
+}
+
+unsigned char Pinetime::Controllers::MusicService::status()
+{
+ return m_status;
+}
+
+void Pinetime::Controllers::MusicService::event(char event)
+{
+ auto *om = ble_hs_mbuf_from_flat(&event, 1);
+ int ret;
+
+ uint16_t connectionHandle = m_system.nimble().connHandle();
+
+ if (connectionHandle == 0 || connectionHandle == BLE_HS_CONN_HANDLE_NONE) {
+ return;
+ }
+
+ ret = ble_gattc_notify_custom(connectionHandle, m_eventHandle, om);
+}
+
diff --git a/src/Components/Ble/MusicService.h b/src/Components/Ble/MusicService.h
new file mode 100644
index 00000000..ab6db572
--- /dev/null
+++ b/src/Components/Ble/MusicService.h
@@ -0,0 +1,92 @@
+#pragma once
+
+#include <cstdint>
+#include <array>
+#include <host/ble_gap.h>
+#include <host/ble_uuid.h>
+#include <string>
+
+//c7e50000-78fc-48fe-8e23-43b37a1942d0
+#define MUSIC_SERVICE_UUID_BASE {0xd0, 0x42, 0x19, 0x3a, 0x3b, 0x43, 0x23, 0x8e, 0xfe, 0x48, 0xfc, 0x78, 0x00, 0x00, 0xe5, 0xc7}
+
+namespace Pinetime {
+ namespace System {
+ class SystemTask;
+ }
+ namespace Controllers {
+
+ class MusicService {
+ public:
+ MusicService(Pinetime::System::SystemTask &system);
+ void Init();
+ int OnCommand(uint16_t conn_handle, uint16_t attr_handle,
+ struct ble_gatt_access_ctxt *ctxt);
+
+ std::string artist();
+ std::string track();
+ std::string album();
+ unsigned char status();
+
+ void event(char event);
+
+ static const char EVENT_MUSIC_OPEN = 0xe0;
+ static const char EVENT_MUSIC_PLAY = 0x00;
+ static const char EVENT_MUSIC_PAUSE = 0x01;
+ static const char EVENT_MUSIC_NEXT = 0x03;
+ static const char EVENT_MUSIC_PREV = 0x04;
+ static const char EVENT_MUSIC_VOLUP = 0x05;
+ static const char EVENT_MUSIC_VOLDOWN = 0x06;
+ static const char STATUS_MUSIC_PAUSED = 0x00;
+ static const char STATUS_MUSIC_PLAYING = 0x01;
+
+ private:
+ static constexpr uint8_t msId[2] = {0x00, 0x01};
+ static constexpr uint8_t msEventCharId[2] = {0x00, 0x02};
+ static constexpr uint8_t msStatusCharId[2] = {0x00, 0x03};
+ static constexpr uint8_t msArtistCharId[2] = {0x00, 0x04};
+ static constexpr uint8_t msTrackCharId[2] = {0x00, 0x05};
+ static constexpr uint8_t msAlbumCharId[2] = {0x00, 0x06};
+
+ 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_UUID_BASE
+ };
+ ble_uuid128_t msStatusCharUuid {
+ .u = { .type = BLE_UUID_TYPE_128 },
+ .value = MUSIC_SERVICE_UUID_BASE
+ };
+ ble_uuid128_t msArtistCharUuid {
+ .u = { .type = BLE_UUID_TYPE_128 },
+ .value = MUSIC_SERVICE_UUID_BASE
+ };
+ ble_uuid128_t msTrackCharUuid {
+ .u = { .type = BLE_UUID_TYPE_128 },
+ .value = MUSIC_SERVICE_UUID_BASE
+ };
+ ble_uuid128_t msAlbumCharUuid {
+ .u = { .type = BLE_UUID_TYPE_128 },
+ .value = MUSIC_SERVICE_UUID_BASE
+ };
+
+ struct ble_gatt_chr_def characteristicDefinition[6];
+ struct ble_gatt_svc_def serviceDefinition[2];
+
+ uint16_t m_eventHandle;
+
+ std::string m_artist;
+ std::string m_album;
+ std::string m_track;
+
+ unsigned char m_status;
+
+ Pinetime::System::SystemTask& m_system;
+
+ };
+ }
+}
+
diff --git a/src/Components/Ble/NimbleController.cpp b/src/Components/Ble/NimbleController.cpp
index 561dbce4..d7bbd8be 100644
--- a/src/Components/Ble/NimbleController.cpp
+++ b/src/Components/Ble/NimbleController.cpp
@@ -6,6 +6,7 @@
#include <hal/nrf_rtc.h>
#include "NimbleController.h"
+#include "MusicService.h"
#include <services/gatt/ble_svc_gatt.h>
#include <services/gap/ble_svc_gap.h>
#include <host/util/util.h>
@@ -35,7 +36,8 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask,
currentTimeClient{dateTimeController},
anService{systemTask, notificationManager},
alertNotificationClient{systemTask, notificationManager},
- currentTimeService{dateTimeController} {
+ currentTimeService{dateTimeController},
+ musicService{systemTask} {
}
@@ -80,6 +82,7 @@ void NimbleController::Init() {
deviceInformationService.Init();
currentTimeClient.Init();
currentTimeService.Init();
+ musicService.Init();
anService.Init();
@@ -326,5 +329,7 @@ void NimbleController::StartDiscovery() {
}
-
+uint16_t NimbleController::connHandle() {
+ return connectionHandle;
+}
diff --git a/src/Components/Ble/NimbleController.h b/src/Components/Ble/NimbleController.h
index cf50d78d..dff93c87 100644
--- a/src/Components/Ble/NimbleController.h
+++ b/src/Components/Ble/NimbleController.h
@@ -7,6 +7,7 @@
#include "CurrentTimeClient.h"
#include "DfuService.h"
#include "CurrentTimeService.h"
+#include "MusicService.h"
#include <host/ble_gap.h>
namespace Pinetime {
@@ -15,6 +16,7 @@ namespace Pinetime {
}
namespace Controllers {
class DateTime;
+
class NimbleController {
public:
@@ -35,6 +37,11 @@ namespace Pinetime {
uint16_t characteristicValueHandle, const ble_gatt_dsc *descriptor);
void StartDiscovery();
+
+ Pinetime::Controllers::MusicService& music() {return musicService;};
+
+ uint16_t connHandle();
+
private:
static constexpr char* deviceName = "Pinetime-JF";
Pinetime::System::SystemTask& systemTask;
@@ -49,9 +56,10 @@ namespace Pinetime {
AlertNotificationService anService;
AlertNotificationClient alertNotificationClient;
CurrentTimeService currentTimeService;
+ MusicService musicService;
uint8_t addrType; // 1 = Random, 0 = PUBLIC
- uint16_t connectionHandle;
+ uint16_t connectionHandle = 0;
ble_uuid128_t dfuServiceUuid {
.u { .type = BLE_UUID_TYPE_128},
diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp
index 8e35ef55..46a96385 100644
--- a/src/DisplayApp/DisplayApp.cpp
+++ b/src/DisplayApp/DisplayApp.cpp
@@ -15,6 +15,7 @@
#include <DisplayApp/Screens/Gauge.h>
#include <DisplayApp/Screens/Brightness.h>
#include <DisplayApp/Screens/ScreenList.h>
+#include <DisplayApp/Screens/Music.h>
#include <Components/Ble/NotificationManager.h>
#include <DisplayApp/Screens/FirmwareUpdate.h>
#include "../SystemTask/SystemTask.h"
@@ -189,6 +190,7 @@ void DisplayApp::RunningState() {
case Apps::Meter: currentScreen.reset(new Screens::Meter(this)); break;
case Apps::Gauge: currentScreen.reset(new Screens::Gauge(this)); break;
case Apps::Brightness : currentScreen.reset(new Screens::Brightness(this, brightnessController)); break;
+ case Apps::Music : currentScreen.reset(new Screens::Music(this, systemTask.nimble().music())); break;
}
nextApp = Apps::None;
}
diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h
index 36f9315b..23f04937 100644
--- a/src/DisplayApp/DisplayApp.h
+++ b/src/DisplayApp/DisplayApp.h
@@ -42,7 +42,7 @@ namespace Pinetime {
void Start();
void PushMessage(Messages msg);
- enum class Apps {None, Launcher, Clock, SysInfo, Meter, Gauge, Brightness};
+ enum class Apps {None, Launcher, Clock, SysInfo, Meter, Gauge, Brightness, Music};
void StartApp(Apps app);
void SetFullRefresh(FullRefreshDirections direction);
diff --git a/src/DisplayApp/Screens/Gauge.cpp b/src/DisplayApp/Screens/Gauge.cpp
index 4c4cccd9..fd905231 100644
--- a/src/DisplayApp/Screens/Gauge.cpp
+++ b/src/DisplayApp/Screens/Gauge.cpp
@@ -19,6 +19,7 @@ Gauge::Gauge(Pinetime::Applications::DisplayApp *app) : Screen(app) {
style.text.color = LV_COLOR_WHITE;
style.line.color = LV_COLOR_RED; /*Line color after the critical value*/
+
/*Describe the color for the needles*/
needle_colors[0] = LV_COLOR_ORANGE;
diff --git a/src/DisplayApp/Screens/Music.cpp b/src/DisplayApp/Screens/Music.cpp
new file mode 100644
index 00000000..9b7d198b
--- /dev/null
+++ b/src/DisplayApp/Screens/Music.cpp
@@ -0,0 +1,125 @@
+#include <libs/lvgl/lvgl.h>
+#include "Music.h"
+
+using namespace Pinetime::Applications::Screens;
+extern lv_font_t jetbrains_mono_extrabold_compressed;
+extern lv_font_t jetbrains_mono_bold_20;
+
+static void event_handler(lv_obj_t * obj, lv_event_t event)
+{
+ Music* screen = static_cast<Music *>(obj->user_data);
+ screen->OnObjectEvent(obj, event);
+}
+
+Music::Music(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::MusicService &music) : Screen(app), musicService(music) {
+ lv_obj_t * label;
+
+ btnVolDown = lv_btn_create(lv_scr_act(), NULL);
+ btnVolDown->user_data = this;
+ lv_obj_set_event_cb(btnVolDown, event_handler);
+ lv_obj_align(btnVolDown, NULL, LV_ALIGN_IN_TOP_LEFT, 10, 10);
+ label = lv_label_create(btnVolDown, NULL);
+ lv_label_set_text(label, "v-");
+
+ btnVolUp = lv_btn_create(lv_scr_act(), NULL);
+ btnVolUp->user_data = this;
+ lv_obj_set_event_cb(btnVolUp, event_handler);
+ lv_obj_align(btnVolUp, NULL, LV_ALIGN_IN_TOP_RIGHT, -10, 10);
+ label = lv_label_create(btnVolUp, NULL);
+ lv_label_set_text(label, "v+");
+
+ btnPrev = lv_btn_create(lv_scr_act(), NULL);
+ btnPrev->user_data = this;
+ lv_obj_set_event_cb(btnPrev, event_handler);
+ lv_obj_set_size(btnPrev, LV_HOR_RES / 4, LV_VER_RES / 4);
+ lv_obj_align(btnPrev, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 10,-10);
+ label = lv_label_create(btnPrev, NULL);
+ lv_label_set_text(label, "<<");
+
+ btnPlayPause = lv_btn_create(lv_scr_act(), NULL);
+ btnPlayPause->user_data = this;
+ lv_obj_set_event_cb(btnPlayPause, event_handler);
+ lv_obj_set_size(btnPlayPause, LV_HOR_RES / 4, LV_VER_RES / 4);
+ lv_obj_align(btnPlayPause, NULL, LV_ALIGN_IN_BOTTOM_MID, 0,-10);
+ txtPlayPause = lv_label_create(btnPlayPause, NULL);
+ lv_label_set_text(txtPlayPause, ">");
+
+ btnNext = lv_btn_create(lv_scr_act(), NULL);
+ btnNext->user_data = this;
+ lv_obj_set_event_cb(btnNext, event_handler);
+ lv_obj_set_size(btnNext, LV_HOR_RES / 4, LV_VER_RES / 4);
+ lv_obj_align(btnNext, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, -10,-10);
+ label = lv_label_create(btnNext, NULL);
+ lv_label_set_text(label, ">>");
+
+ txtArtist = lv_label_create(lv_scr_act(), NULL);
+ lv_label_set_long_mode(txtArtist, LV_LABEL_LONG_SROLL);
+ lv_obj_align(txtArtist, NULL, LV_ALIGN_IN_LEFT_MID, 0,-20);
+ lv_label_set_text(txtArtist, "Artist Name");
+ lv_label_set_align(txtArtist, LV_LABEL_ALIGN_CENTER);
+ lv_obj_set_width(txtArtist, LV_HOR_RES);
+
+ txtTrack = lv_label_create(lv_scr_act(), NULL);
+ lv_label_set_long_mode(txtTrack, LV_LABEL_LONG_DOT);
+ lv_obj_align(txtTrack, NULL, LV_ALIGN_IN_LEFT_MID, 0,20);
+ lv_label_set_text(txtTrack, "This is a very long track name");
+ lv_label_set_align(txtTrack, LV_LABEL_ALIGN_CENTER);
+ lv_obj_set_width(txtTrack, LV_HOR_RES);
+
+ musicService.event(Controllers::MusicService::EVENT_MUSIC_OPEN);
+}
+
+Music::~Music() {
+ lv_obj_clean(lv_scr_act());
+}
+
+bool Music::OnButtonPushed() {
+ running = false;
+ return true;
+}
+
+bool Music::Refresh() {
+
+ if (m_artist != musicService.artist()) {
+ m_artist = musicService.artist();
+ lv_label_set_text(txtArtist, m_artist.data());
+ }
+ if (m_track != musicService.track()) {
+ m_track = musicService.track();
+ lv_label_set_text(txtTrack, m_track.data());
+ }
+ if (m_album != musicService.album()) {
+ m_album = musicService.album();
+ }
+ if (m_status != musicService.status()) {
+ m_status = musicService.status();
+ }
+ if (m_status == Pinetime::Controllers::MusicService::STATUS_MUSIC_PLAYING) {
+ lv_label_set_text(txtPlayPause, "||");
+ } else {
+ lv_label_set_text(txtPlayPause, ">");
+ }
+
+ return running;
+}
+
+void Music::OnObjectEvent(lv_obj_t* obj, lv_event_t event)
+{
+ if (event == LV_EVENT_CLICKED) {
+ if (obj == btnVolDown) {
+ musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLDOWN);
+ } else if (obj == btnVolUp) {
+ musicService.event(Controllers::MusicService::EVENT_MUSIC_VOLUP);
+ } else if (obj == btnPrev) {
+ musicService.event(Controllers::MusicService::EVENT_MUSIC_PREV);
+ } else if (obj == btnPlayPause) {
+ if (m_status == Pinetime::Controllers::MusicService::STATUS_MUSIC_PLAYING) {
+ musicService.event(Controllers::MusicService::EVENT_MUSIC_PAUSE);
+ } else {
+ musicService.event(Controllers::MusicService::EVENT_MUSIC_PLAY);
+ }
+ } else if (obj == btnNext) {
+ musicService.event(Controllers::MusicService::EVENT_MUSIC_NEXT);
+ }
+ }
+}
diff --git a/src/DisplayApp/Screens/Music.h b/src/DisplayApp/Screens/Music.h
new file mode 100644
index 00000000..95cac0f0
--- /dev/null
+++ b/src/DisplayApp/Screens/Music.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <cstdint>
+#include <chrono>
+#include <Components/Gfx/Gfx.h>
+#include "Screen.h"
+#include <bits/unique_ptr.h>
+#include <libs/lvgl/src/lv_core/lv_style.h>
+#include <libs/lvgl/src/lv_core/lv_obj.h>
+#include <Components/Battery/BatteryController.h>
+#include <Components/Ble/BleController.h>
+#include "../../Version.h"
+#include <Components/Ble/MusicService.h>
+#include <string>
+
+namespace Pinetime {
+ namespace Applications {
+ namespace Screens {
+
+ class Music : public Screen{
+ public:
+ Music(DisplayApp* app, Pinetime::Controllers::MusicService &music);
+ ~Music() override;
+
+ bool Refresh() override;
+ bool OnButtonPushed() override;
+
+ void OnObjectEvent(lv_obj_t* obj, lv_event_t event);
+
+ private:
+ lv_obj_t * btnPrev;
+ lv_obj_t * btnPlayPause;
+ lv_obj_t * btnNext;
+ lv_obj_t * btnVolDown;
+ lv_obj_t * btnVolUp;
+ lv_obj_t * txtArtist;
+ lv_obj_t * txtTrack;
+ lv_obj_t * txtPlayPause;
+
+ bool running = true;
+ Pinetime::Controllers::MusicService &musicService;
+ std::string m_artist;
+ std::string m_album;
+ std::string m_track;
+ unsigned char m_status;
+ };
+ }
+ }
+}
diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp
index 61e3c01d..c3a9d380 100644
--- a/src/DisplayApp/Screens/Tile.cpp
+++ b/src/DisplayApp/Screens/Tile.cpp
@@ -95,7 +95,7 @@ void Tile::StartMeterApp() {
}
void Tile::StartGaugeApp() {
- app->StartApp(DisplayApp::Apps::Gauge);
+ app->StartApp(DisplayApp::Apps::Music);
running = false;
}
diff --git a/src/SystemTask/SystemTask.cpp b/src/SystemTask/SystemTask.cpp
index 8f565860..9f57f6f6 100644
--- a/src/SystemTask/SystemTask.cpp
+++ b/src/SystemTask/SystemTask.cpp
@@ -12,6 +12,7 @@
#include <host/util/util.h>
#include <drivers/InternalFlash.h>
#include "../main.h"
+#include "Components/Ble/NimbleController.h"
using namespace Pinetime::System;
diff --git a/src/SystemTask/SystemTask.h b/src/SystemTask/SystemTask.h
index 8fa7e7d1..3e53baed 100644
--- a/src/SystemTask/SystemTask.h
+++ b/src/SystemTask/SystemTask.h
@@ -8,9 +8,10 @@
#include <Components/Battery/BatteryController.h>
#include <DisplayApp/DisplayApp.h>
#include <drivers/Watchdog.h>
-#include <Components/Ble/NimbleController.h>
#include <drivers/SpiNorFlash.h>
#include "SystemMonitor.h"
+#include "Components/Ble/NimbleController.h"
+#include "timers.h"
namespace Pinetime {
namespace System {
@@ -37,6 +38,8 @@ namespace Pinetime {
void OnIdle();
+ Pinetime::Controllers::NimbleController& nimble() {return nimbleController;};
+
private:
TaskHandle_t taskHandle;
@@ -84,4 +87,4 @@ namespace Pinetime {
#endif
};
}
-} \ No newline at end of file
+}
diff --git a/src/drivers/TwiMaster.cpp b/src/drivers/TwiMaster.cpp
index 5d8fcf6b..4a0c536d 100644
--- a/src/drivers/TwiMaster.cpp
+++ b/src/drivers/TwiMaster.cpp
@@ -1,5 +1,5 @@
-#include <sdk/integration/nrfx/nrfx_log.h>
-#include <sdk/modules/nrfx/hal/nrf_gpio.h>
+#include <nrfx_log.h>
+#include <hal/nrf_gpio.h>
#include <cstring>
#include "TwiMaster.h"