Merge branch 'develop' into patch-2
This commit is contained in:
commit
4f51d429a5
202
.github/workflows/c-cpp.yml
vendored
Normal file
202
.github/workflows/c-cpp.yml
vendored
Normal file
|
@ -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>
|
|
@ -1,5 +1,5 @@
|
||||||
cmake_minimum_required(VERSION 3.10)
|
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")
|
set(NRF_TARGET "nrf52")
|
||||||
|
|
||||||
|
|
20
README.md
20
README.md
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
*https://www.pine64.org/pinetime/*
|
*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.
|
||||||
|
|
||||||
The goal of this project is to design an open-source firmware for the Pinetime smartwatch :
|
The goal of this project is to design an open-source firmware for the Pinetime smartwatch :
|
||||||
|
|
||||||
|
@ -15,7 +15,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...
|
- 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.
|
- ... 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")
|
![Pinetime screens](images/0.7.0/montage.jpg "PinetimeScreens")
|
||||||
|
|
||||||
|
@ -23,15 +23,15 @@ As of now, here is the list of achievements of this project:
|
||||||
|
|
||||||
- Fast and optimized LCD driver
|
- Fast and optimized LCD driver
|
||||||
- BLE communication
|
- BLE communication
|
||||||
- Rich user interface via display, touchpanel and push button
|
- Rich user interface via display, touch panel and push button
|
||||||
- Time synchronisation via BLE
|
- Time synchronization via BLE
|
||||||
- Notification via BLE
|
- Notification via BLE
|
||||||
- Multiple 'apps' :
|
- 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
|
* Heart rate
|
||||||
* Motion
|
* Motion
|
||||||
* System info (displays various info : BLE MAC adress, build date/time, uptime, version,...)
|
* System info (displays various info : BLE MAC adress, build date/time, uptime, version, ...)
|
||||||
* Brightess (allows the user to configure the brightness of the display)
|
* Brightness (allows the user to configure the brightness of the display)
|
||||||
- Supported by 2 companion apps (development is ongoing):
|
- Supported by 2 companion apps (development is ongoing):
|
||||||
* [Gadgetbridge](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/branch/pinetime-jf) (on Android)
|
* [Gadgetbridge](https://codeberg.org/Freeyourgadget/Gadgetbridge/src/branch/pinetime-jf) (on Android)
|
||||||
* [Amazfish](https://openrepos.net/content/piggz/amazfish) (on SailfishOS)
|
* [Amazfish](https://openrepos.net/content/piggz/amazfish) (on SailfishOS)
|
||||||
|
@ -61,19 +61,19 @@ As of now, here is the list of achievements of this project:
|
||||||
|
|
||||||
## TODO - contribute
|
## 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:
|
Here a quick list out of my head of things to do for this project:
|
||||||
|
|
||||||
- Improve BLE communication stability and reliability
|
- Improve BLE communication stability and reliability
|
||||||
- Improve OTA and MCUBoot bootloader
|
- 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,...
|
- Add more BLE functionalities : call notifications, agenda, configuration, data logging,...
|
||||||
- Measure power consumption and improve battery life
|
- Measure power consumption and improve battery life
|
||||||
- Improve documentation, take better pictures and video than mine
|
- Improve documentation, take better pictures and video than mine
|
||||||
- Improve the UI
|
- 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/).
|
- 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).
|
- 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 :)
|
Do not hesitate to clone/fork the code, hack it and create pull-requests. I'll do my best to review and merge them :)
|
||||||
|
|
||||||
|
@ -84,6 +84,6 @@ 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.
|
- [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 as me : NimBLE, LittleVGL,… His help was invaluable too!
|
- [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, 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!
|
- [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 :)*
|
*If you feel like you should appear on this list, just get in touch with me or submit a PR :)*
|
||||||
|
|
|
@ -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.
|
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 :
|
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
|
- 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
|
- Power On/Off sequence
|
||||||
- System function commands : all the commands you can send to the controller.
|
- System function commands : all the commands you can send to the controller.
|
||||||
|
|
||||||
## One Pixel at a time
|
## One Pixel at a time
|
||||||
|
|
||||||
|
|
||||||
## Bulk transfert
|
## Bulk transfers
|
||||||
|
|
||||||
## DMA
|
## DMA
|
||||||
|
|
||||||
|
|
|
@ -336,6 +336,7 @@ list(APPEND SOURCE_FILES
|
||||||
DisplayApp/Screens/ScreenList.cpp
|
DisplayApp/Screens/ScreenList.cpp
|
||||||
DisplayApp/Screens/Label.cpp
|
DisplayApp/Screens/Label.cpp
|
||||||
DisplayApp/Screens/FirmwareUpdate.cpp
|
DisplayApp/Screens/FirmwareUpdate.cpp
|
||||||
|
DisplayApp/Screens/Music.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
drivers/St7789.cpp
|
drivers/St7789.cpp
|
||||||
drivers/SpiNorFlash.cpp
|
drivers/SpiNorFlash.cpp
|
||||||
|
@ -356,6 +357,7 @@ list(APPEND SOURCE_FILES
|
||||||
Components/Ble/DfuService.cpp
|
Components/Ble/DfuService.cpp
|
||||||
Components/Ble/CurrentTimeService.cpp
|
Components/Ble/CurrentTimeService.cpp
|
||||||
Components/Ble/AlertNotificationService.cpp
|
Components/Ble/AlertNotificationService.cpp
|
||||||
|
Components/Ble/MusicService.cpp
|
||||||
drivers/Cst816s.cpp
|
drivers/Cst816s.cpp
|
||||||
FreeRTOS/port.c
|
FreeRTOS/port.c
|
||||||
FreeRTOS/port_cmsis_systick.c
|
FreeRTOS/port_cmsis_systick.c
|
||||||
|
|
130
src/Components/Ble/MusicService.cpp
Normal file
130
src/Components/Ble/MusicService.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
|
92
src/Components/Ble/MusicService.h
Normal file
92
src/Components/Ble/MusicService.h
Normal file
|
@ -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;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <hal/nrf_rtc.h>
|
#include <hal/nrf_rtc.h>
|
||||||
|
|
||||||
#include "NimbleController.h"
|
#include "NimbleController.h"
|
||||||
|
#include "MusicService.h"
|
||||||
#include <services/gatt/ble_svc_gatt.h>
|
#include <services/gatt/ble_svc_gatt.h>
|
||||||
#include <services/gap/ble_svc_gap.h>
|
#include <services/gap/ble_svc_gap.h>
|
||||||
#include <host/util/util.h>
|
#include <host/util/util.h>
|
||||||
|
@ -35,7 +36,8 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask,
|
||||||
currentTimeClient{dateTimeController},
|
currentTimeClient{dateTimeController},
|
||||||
anService{systemTask, notificationManager},
|
anService{systemTask, notificationManager},
|
||||||
alertNotificationClient{systemTask, notificationManager},
|
alertNotificationClient{systemTask, notificationManager},
|
||||||
currentTimeService{dateTimeController} {
|
currentTimeService{dateTimeController},
|
||||||
|
musicService{systemTask} {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +82,7 @@ void NimbleController::Init() {
|
||||||
deviceInformationService.Init();
|
deviceInformationService.Init();
|
||||||
currentTimeClient.Init();
|
currentTimeClient.Init();
|
||||||
currentTimeService.Init();
|
currentTimeService.Init();
|
||||||
|
musicService.Init();
|
||||||
|
|
||||||
anService.Init();
|
anService.Init();
|
||||||
|
|
||||||
|
@ -326,5 +329,7 @@ void NimbleController::StartDiscovery() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t NimbleController::connHandle() {
|
||||||
|
return connectionHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "CurrentTimeClient.h"
|
#include "CurrentTimeClient.h"
|
||||||
#include "DfuService.h"
|
#include "DfuService.h"
|
||||||
#include "CurrentTimeService.h"
|
#include "CurrentTimeService.h"
|
||||||
|
#include "MusicService.h"
|
||||||
#include <host/ble_gap.h>
|
#include <host/ble_gap.h>
|
||||||
|
|
||||||
namespace Pinetime {
|
namespace Pinetime {
|
||||||
|
@ -15,6 +16,7 @@ namespace Pinetime {
|
||||||
}
|
}
|
||||||
namespace Controllers {
|
namespace Controllers {
|
||||||
class DateTime;
|
class DateTime;
|
||||||
|
|
||||||
class NimbleController {
|
class NimbleController {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -35,6 +37,11 @@ namespace Pinetime {
|
||||||
uint16_t characteristicValueHandle, const ble_gatt_dsc *descriptor);
|
uint16_t characteristicValueHandle, const ble_gatt_dsc *descriptor);
|
||||||
|
|
||||||
void StartDiscovery();
|
void StartDiscovery();
|
||||||
|
|
||||||
|
Pinetime::Controllers::MusicService& music() {return musicService;};
|
||||||
|
|
||||||
|
uint16_t connHandle();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr char* deviceName = "Pinetime-JF";
|
static constexpr char* deviceName = "Pinetime-JF";
|
||||||
Pinetime::System::SystemTask& systemTask;
|
Pinetime::System::SystemTask& systemTask;
|
||||||
|
@ -49,9 +56,10 @@ namespace Pinetime {
|
||||||
AlertNotificationService anService;
|
AlertNotificationService anService;
|
||||||
AlertNotificationClient alertNotificationClient;
|
AlertNotificationClient alertNotificationClient;
|
||||||
CurrentTimeService currentTimeService;
|
CurrentTimeService currentTimeService;
|
||||||
|
MusicService musicService;
|
||||||
|
|
||||||
uint8_t addrType; // 1 = Random, 0 = PUBLIC
|
uint8_t addrType; // 1 = Random, 0 = PUBLIC
|
||||||
uint16_t connectionHandle;
|
uint16_t connectionHandle = 0;
|
||||||
|
|
||||||
ble_uuid128_t dfuServiceUuid {
|
ble_uuid128_t dfuServiceUuid {
|
||||||
.u { .type = BLE_UUID_TYPE_128},
|
.u { .type = BLE_UUID_TYPE_128},
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <DisplayApp/Screens/Gauge.h>
|
#include <DisplayApp/Screens/Gauge.h>
|
||||||
#include <DisplayApp/Screens/Brightness.h>
|
#include <DisplayApp/Screens/Brightness.h>
|
||||||
#include <DisplayApp/Screens/ScreenList.h>
|
#include <DisplayApp/Screens/ScreenList.h>
|
||||||
|
#include <DisplayApp/Screens/Music.h>
|
||||||
#include <Components/Ble/NotificationManager.h>
|
#include <Components/Ble/NotificationManager.h>
|
||||||
#include <DisplayApp/Screens/FirmwareUpdate.h>
|
#include <DisplayApp/Screens/FirmwareUpdate.h>
|
||||||
#include "../SystemTask/SystemTask.h"
|
#include "../SystemTask/SystemTask.h"
|
||||||
|
@ -189,6 +190,7 @@ void DisplayApp::RunningState() {
|
||||||
case Apps::Meter: currentScreen.reset(new Screens::Meter(this)); break;
|
case Apps::Meter: currentScreen.reset(new Screens::Meter(this)); break;
|
||||||
case Apps::Gauge: currentScreen.reset(new Screens::Gauge(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::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;
|
nextApp = Apps::None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ namespace Pinetime {
|
||||||
void Start();
|
void Start();
|
||||||
void PushMessage(Messages msg);
|
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 StartApp(Apps app);
|
||||||
|
|
||||||
void SetFullRefresh(FullRefreshDirections direction);
|
void SetFullRefresh(FullRefreshDirections direction);
|
||||||
|
|
|
@ -19,6 +19,7 @@ Gauge::Gauge(Pinetime::Applications::DisplayApp *app) : Screen(app) {
|
||||||
style.text.color = LV_COLOR_WHITE;
|
style.text.color = LV_COLOR_WHITE;
|
||||||
style.line.color = LV_COLOR_RED; /*Line color after the critical value*/
|
style.line.color = LV_COLOR_RED; /*Line color after the critical value*/
|
||||||
|
|
||||||
|
|
||||||
/*Describe the color for the needles*/
|
/*Describe the color for the needles*/
|
||||||
|
|
||||||
needle_colors[0] = LV_COLOR_ORANGE;
|
needle_colors[0] = LV_COLOR_ORANGE;
|
||||||
|
|
125
src/DisplayApp/Screens/Music.cpp
Normal file
125
src/DisplayApp/Screens/Music.cpp
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
49
src/DisplayApp/Screens/Music.h
Normal file
49
src/DisplayApp/Screens/Music.h
Normal file
|
@ -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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -95,7 +95,7 @@ void Tile::StartMeterApp() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tile::StartGaugeApp() {
|
void Tile::StartGaugeApp() {
|
||||||
app->StartApp(DisplayApp::Apps::Gauge);
|
app->StartApp(DisplayApp::Apps::Music);
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <host/util/util.h>
|
#include <host/util/util.h>
|
||||||
#include <drivers/InternalFlash.h>
|
#include <drivers/InternalFlash.h>
|
||||||
#include "../main.h"
|
#include "../main.h"
|
||||||
|
#include "Components/Ble/NimbleController.h"
|
||||||
|
|
||||||
using namespace Pinetime::System;
|
using namespace Pinetime::System;
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,10 @@
|
||||||
#include <Components/Battery/BatteryController.h>
|
#include <Components/Battery/BatteryController.h>
|
||||||
#include <DisplayApp/DisplayApp.h>
|
#include <DisplayApp/DisplayApp.h>
|
||||||
#include <drivers/Watchdog.h>
|
#include <drivers/Watchdog.h>
|
||||||
#include <Components/Ble/NimbleController.h>
|
|
||||||
#include <drivers/SpiNorFlash.h>
|
#include <drivers/SpiNorFlash.h>
|
||||||
#include "SystemMonitor.h"
|
#include "SystemMonitor.h"
|
||||||
|
#include "Components/Ble/NimbleController.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
namespace Pinetime {
|
namespace Pinetime {
|
||||||
namespace System {
|
namespace System {
|
||||||
|
@ -37,6 +38,8 @@ namespace Pinetime {
|
||||||
|
|
||||||
void OnIdle();
|
void OnIdle();
|
||||||
|
|
||||||
|
Pinetime::Controllers::NimbleController& nimble() {return nimbleController;};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TaskHandle_t taskHandle;
|
TaskHandle_t taskHandle;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#include <sdk/integration/nrfx/nrfx_log.h>
|
#include <nrfx_log.h>
|
||||||
#include <sdk/modules/nrfx/hal/nrf_gpio.h>
|
#include <hal/nrf_gpio.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "TwiMaster.h"
|
#include "TwiMaster.h"
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user