From 28abeae21bb370c45d26912bba4737a1cc6ddca7 Mon Sep 17 00:00:00 2001 From: hubmartin Date: Mon, 2 Aug 2021 21:37:48 +0200 Subject: [PATCH 01/40] DRAFT: Put gpio pins to separate file --- src/CMakeLists.txt | 1 + src/components/battery/BatteryController.h | 3 ++- src/drivers/Cst816s.h | 3 ++- src/drivers/PinMap.h | 25 ++++++++++++++++++++++ src/systemtask/SystemTask.h | 3 ++- 5 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 src/drivers/PinMap.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 40e1f2a554..24b5ae4ac1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -615,6 +615,7 @@ set(INCLUDE_FILES drivers/DebugPins.h drivers/InternalFlash.h drivers/Hrs3300.h + drivers/PinMap.h drivers/Bma421.h drivers/Bma421_C/bma4.c drivers/Bma421_C/bma423.c diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 1333ad0e77..cd66ff8f14 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -3,6 +3,7 @@ #include #include #include +#include namespace Pinetime { namespace Controllers { @@ -72,7 +73,7 @@ namespace Pinetime { static constexpr uint8_t percentRemainingSamples = 5; CircBuffer percentRemainingBuffer {}; - static constexpr uint32_t chargingPin = 12; + static constexpr uint32_t chargingPin = PINMAP_CHARGING_PIN; static constexpr uint32_t powerPresentPin = 19; static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7; uint16_t voltage = 0; diff --git a/src/drivers/Cst816s.h b/src/drivers/Cst816s.h index 14c296eaba..fa53907aa9 100644 --- a/src/drivers/Cst816s.h +++ b/src/drivers/Cst816s.h @@ -1,6 +1,7 @@ #pragma once #include "TwiMaster.h" +#include namespace Pinetime { namespace Drivers { @@ -40,7 +41,7 @@ namespace Pinetime { private: static constexpr uint8_t pinIrq = 28; - static constexpr uint8_t pinReset = 10; + static constexpr uint8_t pinReset = PINMAP_CST816S_RESET_PIN; static constexpr uint8_t lastTouchId = 0x0f; static constexpr uint8_t touchPointNumIndex = 2; static constexpr uint8_t touchMiscIndex = 8; diff --git a/src/drivers/PinMap.h b/src/drivers/PinMap.h new file mode 100644 index 0000000000..61bb10e496 --- /dev/null +++ b/src/drivers/PinMap.h @@ -0,0 +1,25 @@ +#pragma once + +#ifdef WATCH_P8 + +// BatteryController.h +#define PINMAP_CHARGING_PIN 19 + +// Cst816s.h +#define PINMAP_CST816S_RESET_PIN 13 + +// SystemTask.h +#define PINMAP_BUTTON_PIN 17 + +#else + +// BatteryController.h +#define PINMAP_CHARGING_PIN 12 + +// Cst816s.h +#define PINMAP_CST816S_RESET_PIN 10 + +// SystemTask.h +#define PINMAP_BUTTON_PIN 13 + +#endif \ No newline at end of file diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index ba4342987b..2756f77415 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "SystemMonitor.h" @@ -120,7 +121,7 @@ namespace Pinetime { static constexpr uint8_t pinSpiMiso = 4; static constexpr uint8_t pinSpiCsn = 25; static constexpr uint8_t pinLcdDataCommand = 18; - static constexpr uint8_t pinButton = 13; + static constexpr uint8_t pinButton = PINMAP_BUTTON_PIN; static constexpr uint8_t pinTouchIrq = 28; static constexpr uint8_t pinPowerPresentIrq = 19; From f244c960d3848096b60f735e705819f05a0459d7 Mon Sep 17 00:00:00 2001 From: Martin Hub Date: Tue, 3 Aug 2021 17:41:34 +0200 Subject: [PATCH 02/40] Update ota-gadgetbridge-nrfconnect.md --- doc/gettingStarted/ota-gadgetbridge-nrfconnect.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md b/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md index 1187a9b745..2f2dd55e97 100644 --- a/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md +++ b/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md @@ -88,6 +88,10 @@ If you are using OpenOCD with a STLinkV2, you can find more info [on this page]( ### Using Gadgetbridge Good news! Gadgetbridge **automatically** synchronizes the time when connecting to your PineTime! +### Using any Chromium-based web browser +You can use it from your PC, Mac, Android. Browsers now have BLE support. +https://hubmartin.github.io/WebBLEWatch/ + ### Using NRFConnect You must enable the **CTS** *GATT server* into NRFConnect so that InfiniTime can synchronize the time with your smartphone. From 2992f4afd286d26068bba0afdd9337ab6d96aa15 Mon Sep 17 00:00:00 2001 From: Martin Hub Date: Tue, 3 Aug 2021 17:56:02 +0200 Subject: [PATCH 03/40] Add FW validation note after DFU flash --- doc/gettingStarted/ota-gadgetbridge-nrfconnect.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md b/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md index 1187a9b745..86bbab8692 100644 --- a/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md +++ b/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md @@ -47,6 +47,8 @@ Read carefully the warning and tap **Install**: Wait for the transfer to finish. Your PineTime should reset and reboot with the new version of InfiniTime! +Don't forget to **validate** your firmware. In the InfiniTime go to the settings (swipe right, select gear icon) and Firmware option and click **validate**. Otherwise after reboot the previous firmware will be used. + ![Gadgetbridge 5](gadgetbridge5.jpg) ### Using NRFConnect @@ -64,6 +66,8 @@ Select **Distribution packet (ZIP)**: Browse to the DFU file you downloaded previously, the DFU transfer will start automatically. When the transfer is finished, your PineTime will reset and restart on the new version of InfiniTime! +Don't forget to **validate** your firmware. In the InfiniTime go to the settings (swipe right, select gear icon) and Firmware option and click **validate**. Otherwise after reboot the previous firmware will be used. + ![NRFConnect 3](nrfconnect3.jpg) ## How to flash InfiniTime using the SWD interface From c30e54c7b743f7c6364d35412d74ba9be8dc3c04 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Tue, 3 Aug 2021 19:49:54 +0300 Subject: [PATCH 04/40] Make it easier for new people to find instructions --- README.md | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index d9de40029f..af91616c94 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,15 @@ -# PineTime +## New to InfiniTime? -[![Build PineTime Firmware](https://github.com/JF002/InfiniTime/workflows/Build%20PineTime%20Firmware/badge.svg?branch=master)](https://github.com/JF002/InfiniTime/actions) - -> The PineTime is a free and open source smartwatch capable of running custom-built open operating systems. Some of the notable features include a heart rate monitor, a week-long battery as well as a capacitive touch IPS display that is legible in direct sunlight. It is a fully community driven side-project, which means that it will ultimately be up to the developers and end-users to determine when they deem the PineTime ready to ship. - -> We envision the PineTime as a companion for not only your PinePhone but also for your favorite devices — any phone, tablet, or even PC. - -*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 heart rate sensor, and a vibration motor. + - [Getting started with InfiniTime 1.0 (quick user guide, update bootloader and InfiniTime,...)](doc/gettingStarted/gettingStarted-1.0.md) + - [Flash, upgrade (OTA), time synchronization,...](doc/gettingStarted/ota-gadgetbridge-nrfconnect.md) # InfiniTime +[![Build PineTime Firmware](https://github.com/JF002/InfiniTime/workflows/Build%20PineTime%20Firmware/badge.svg?branch=master)](https://github.com/JF002/InfiniTime/actions) + ![InfiniTime logo](images/infinitime-logo.jpg "InfiniTime Logo") -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](https://www.pine64.org/pinetime/) : - Code written in **modern C++**; - Build system based on **CMake**; @@ -75,11 +70,6 @@ As of now, here is the list of achievements of this project: ## Documentation -### Getting started - - - [Getting started with InfiniTime 1.0 (quick user guide, update bootloader and InfiniTime,...)](doc/gettingStarted/gettingStarted-1.0.md) - - [Flash, upgrade (OTA), time synchronization,...](doc/gettingStarted/ota-gadgetbridge-nrfconnect.md) - ### Develop - [Generate the fonts and symbols](src/displayapp/fonts/README.md) From 285ac9e4c86f6f1fb96130d2df038fff7ec49ad5 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Tue, 3 Aug 2021 19:51:58 +0300 Subject: [PATCH 05/40] Move getting started slightly lower --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index af91616c94..a6f0d3a659 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,3 @@ -## New to InfiniTime? - - - [Getting started with InfiniTime 1.0 (quick user guide, update bootloader and InfiniTime,...)](doc/gettingStarted/gettingStarted-1.0.md) - - [Flash, upgrade (OTA), time synchronization,...](doc/gettingStarted/ota-gadgetbridge-nrfconnect.md) - # InfiniTime [![Build PineTime Firmware](https://github.com/JF002/InfiniTime/workflows/Build%20PineTime%20Firmware/badge.svg?branch=master)](https://github.com/JF002/InfiniTime/actions) @@ -17,6 +12,11 @@ The goal of this project is to design an open-source firmware for the [Pinetime - Using **[LittleVGL/LVGL 7](https://lvgl.io/)** as UI library... - ... and **[NimBLE 1.3.0](https://github.com/apache/mynewt-nimble)** as BLE stack. +## New to InfiniTime? + + - [Getting started with InfiniTime 1.0 (quick user guide, update bootloader and InfiniTime,...)](doc/gettingStarted/gettingStarted-1.0.md) + - [Flash, upgrade (OTA), time synchronization,...](doc/gettingStarted/ota-gadgetbridge-nrfconnect.md) + ## Overview ![Pinetime screens](images/1.0.0/collage.png "PinetimeScreens") From b7aa04e1f55096d754a7cc291f02f3430f5a3cd9 Mon Sep 17 00:00:00 2001 From: hubmartin Date: Tue, 3 Aug 2021 20:32:23 +0200 Subject: [PATCH 06/40] PinMap with namespace and constexpr --- src/components/battery/BatteryController.cpp | 6 +-- src/components/battery/BatteryController.h | 2 - .../brightness/BrightnessController.cpp | 32 ++++++++-------- .../brightness/BrightnessController.h | 3 -- src/components/motor/MotorController.cpp | 9 +++-- src/components/motor/MotorController.h | 1 - src/drivers/Cst816s.cpp | 13 ++++--- src/drivers/Cst816s.h | 3 -- src/drivers/PinMap.h | 37 +++++++++++++++++++ src/main.cpp | 29 +++++---------- src/recoveryLoader.cpp | 19 ++++------ src/systemtask/SystemTask.cpp | 20 +++++----- src/systemtask/SystemTask.h | 9 ----- 13 files changed, 96 insertions(+), 87 deletions(-) diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index fa476ea302..d543ccd947 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -12,12 +12,12 @@ Battery::Battery() { } void Battery::Init() { - nrf_gpio_cfg_input(chargingPin, static_cast GPIO_PIN_CNF_PULL_Pullup); + nrf_gpio_cfg_input(PinMap::Charging, static_cast GPIO_PIN_CNF_PULL_Pullup); } void Battery::Update() { - isCharging = !nrf_gpio_pin_read(chargingPin); - isPowerPresent = !nrf_gpio_pin_read(powerPresentPin); + isCharging = !nrf_gpio_pin_read(PinMap::Charging); + isPowerPresent = !nrf_gpio_pin_read(PinMap::PowerPresent); if (isReading) { return; diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index cd66ff8f14..993ef6c5c2 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -73,8 +73,6 @@ namespace Pinetime { static constexpr uint8_t percentRemainingSamples = 5; CircBuffer percentRemainingBuffer {}; - static constexpr uint32_t chargingPin = PINMAP_CHARGING_PIN; - static constexpr uint32_t powerPresentPin = 19; static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7; uint16_t voltage = 0; int percentRemaining = -1; diff --git a/src/components/brightness/BrightnessController.cpp b/src/components/brightness/BrightnessController.cpp index 8ad987d1f4..350dfeeb07 100644 --- a/src/components/brightness/BrightnessController.cpp +++ b/src/components/brightness/BrightnessController.cpp @@ -1,13 +1,13 @@ #include "BrightnessController.h" #include #include "displayapp/screens/Symbols.h" - +#include "drivers/PinMap.h" using namespace Pinetime::Controllers; void BrightnessController::Init() { - nrf_gpio_cfg_output(pinLcdBacklight1); - nrf_gpio_cfg_output(pinLcdBacklight2); - nrf_gpio_cfg_output(pinLcdBacklight3); + nrf_gpio_cfg_output(PinMap::LcdBacklight1); + nrf_gpio_cfg_output(PinMap::LcdBacklight2); + nrf_gpio_cfg_output(PinMap::LcdBacklight3); Set(level); } @@ -16,24 +16,24 @@ void BrightnessController::Set(BrightnessController::Levels level) { switch (level) { default: case Levels::High: - nrf_gpio_pin_clear(pinLcdBacklight1); - nrf_gpio_pin_clear(pinLcdBacklight2); - nrf_gpio_pin_clear(pinLcdBacklight3); + nrf_gpio_pin_clear(PinMap::LcdBacklight1); + nrf_gpio_pin_clear(PinMap::LcdBacklight2); + nrf_gpio_pin_clear(PinMap::LcdBacklight3); break; case Levels::Medium: - nrf_gpio_pin_clear(pinLcdBacklight1); - nrf_gpio_pin_clear(pinLcdBacklight2); - nrf_gpio_pin_set(pinLcdBacklight3); + nrf_gpio_pin_clear(PinMap::LcdBacklight1); + nrf_gpio_pin_clear(PinMap::LcdBacklight2); + nrf_gpio_pin_set(PinMap::LcdBacklight3); break; case Levels::Low: - nrf_gpio_pin_clear(pinLcdBacklight1); - nrf_gpio_pin_set(pinLcdBacklight2); - nrf_gpio_pin_set(pinLcdBacklight3); + nrf_gpio_pin_clear(PinMap::LcdBacklight1); + nrf_gpio_pin_set(PinMap::LcdBacklight2); + nrf_gpio_pin_set(PinMap::LcdBacklight3); break; case Levels::Off: - nrf_gpio_pin_set(pinLcdBacklight1); - nrf_gpio_pin_set(pinLcdBacklight2); - nrf_gpio_pin_set(pinLcdBacklight3); + nrf_gpio_pin_set(PinMap::LcdBacklight1); + nrf_gpio_pin_set(PinMap::LcdBacklight2); + nrf_gpio_pin_set(PinMap::LcdBacklight3); break; } } diff --git a/src/components/brightness/BrightnessController.h b/src/components/brightness/BrightnessController.h index c47158a910..0d7ac2ffa6 100644 --- a/src/components/brightness/BrightnessController.h +++ b/src/components/brightness/BrightnessController.h @@ -22,9 +22,6 @@ namespace Pinetime { const char* ToString(); private: - static constexpr uint8_t pinLcdBacklight1 = 14; - static constexpr uint8_t pinLcdBacklight2 = 22; - static constexpr uint8_t pinLcdBacklight3 = 23; Levels level = Levels::High; Levels backupLevel = Levels::High; }; diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index 3afa0cedd8..1f20936874 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -2,6 +2,7 @@ #include #include "systemtask/SystemTask.h" #include "app_timer.h" +#include "drivers/PinMap.h" APP_TIMER_DEF(vibTimer); @@ -11,8 +12,8 @@ MotorController::MotorController(Controllers::Settings& settingsController) : se } void MotorController::Init() { - nrf_gpio_cfg_output(pinMotor); - nrf_gpio_pin_set(pinMotor); + nrf_gpio_cfg_output(PinMap::Motor); + nrf_gpio_pin_set(PinMap::Motor); app_timer_create(&vibTimer, APP_TIMER_MODE_SINGLE_SHOT, vibrate); } @@ -21,11 +22,11 @@ void MotorController::SetDuration(uint8_t motorDuration) { if (settingsController.GetVibrationStatus() == Controllers::Settings::Vibration::OFF) return; - nrf_gpio_pin_clear(pinMotor); + nrf_gpio_pin_clear(PinMap::Motor); /* Start timer for motorDuration miliseconds and timer triggers vibrate() when it finishes*/ app_timer_start(vibTimer, APP_TIMER_TICKS(motorDuration), NULL); } void MotorController::vibrate(void* p_context) { - nrf_gpio_pin_set(pinMotor); + nrf_gpio_pin_set(PinMap::Motor); } \ No newline at end of file diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index df61af7849..00cd193768 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -6,7 +6,6 @@ namespace Pinetime { namespace Controllers { - static constexpr uint8_t pinMotor = 16; class MotorController { public: diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp index fd9792b3f4..b039ab0fd2 100644 --- a/src/drivers/Cst816s.cpp +++ b/src/drivers/Cst816s.cpp @@ -3,6 +3,7 @@ #include #include #include +#include "drivers/PinMap.h" using namespace Pinetime::Drivers; @@ -18,12 +19,12 @@ Cst816S::Cst816S(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaste } void Cst816S::Init() { - nrf_gpio_cfg_output(pinReset); - nrf_gpio_pin_set(pinReset); + nrf_gpio_cfg_output(PinMap::Cst816sReset); + nrf_gpio_pin_set(PinMap::Cst816sReset); vTaskDelay(50); - nrf_gpio_pin_clear(pinReset); + nrf_gpio_pin_clear(PinMap::Cst816sReset); vTaskDelay(5); - nrf_gpio_pin_set(pinReset); + nrf_gpio_pin_set(PinMap::Cst816sReset); vTaskDelay(50); // Wake the touchpanel up @@ -78,9 +79,9 @@ Cst816S::TouchInfos Cst816S::GetTouchInfo() { } void Cst816S::Sleep() { - nrf_gpio_pin_clear(pinReset); + nrf_gpio_pin_clear(PinMap::Cst816sReset); vTaskDelay(5); - nrf_gpio_pin_set(pinReset); + nrf_gpio_pin_set(PinMap::Cst816sReset); vTaskDelay(50); static constexpr uint8_t sleepValue = 0x03; twiMaster.Write(twiAddress, 0xA5, &sleepValue, 1); diff --git a/src/drivers/Cst816s.h b/src/drivers/Cst816s.h index fa53907aa9..b621510494 100644 --- a/src/drivers/Cst816s.h +++ b/src/drivers/Cst816s.h @@ -1,7 +1,6 @@ #pragma once #include "TwiMaster.h" -#include namespace Pinetime { namespace Drivers { @@ -40,8 +39,6 @@ namespace Pinetime { void Wakeup(); private: - static constexpr uint8_t pinIrq = 28; - static constexpr uint8_t pinReset = PINMAP_CST816S_RESET_PIN; static constexpr uint8_t lastTouchId = 0x0f; static constexpr uint8_t touchPointNumIndex = 2; static constexpr uint8_t touchMiscIndex = 8; diff --git a/src/drivers/PinMap.h b/src/drivers/PinMap.h index 61bb10e496..117cf11fb9 100644 --- a/src/drivers/PinMap.h +++ b/src/drivers/PinMap.h @@ -1,5 +1,42 @@ #pragma once +namespace Pinetime { + namespace PinMap { + #define WATCH_P8 + #ifdef WATCH_P8 + static constexpr uint8_t Charging = 19; + static constexpr uint8_t Cst816sReset = 13; + static constexpr uint8_t Button = 17; + #else + static constexpr uint8_t Charging = 12; + static constexpr uint8_t Cst816sReset = 10; + static constexpr uint8_t Button = 13; + #endif + + static constexpr uint8_t Cst816sIrq = 28; + static constexpr uint8_t PowerPresent = 19; + + static constexpr uint8_t Motor = 16; + + static constexpr uint8_t LcdBacklight1 = 14; + static constexpr uint8_t LcdBacklight2 = 22; + static constexpr uint8_t LcdBacklight3 = 23; + + static constexpr uint8_t SpiSck = 2; + static constexpr uint8_t SpiMosi = 3; + static constexpr uint8_t SpiMiso = 4; + + static constexpr uint8_t SpiFlashCsn = 5; + static constexpr uint8_t SpiLcdCsn = 25; + static constexpr uint8_t LcdDataCommand = 18; + + static constexpr uint8_t TwiScl = 7; + static constexpr uint8_t TwiSda = 6; + + } +} + + #ifdef WATCH_P8 // BatteryController.h diff --git a/src/main.cpp b/src/main.cpp index ffbba5e765..408ce4375a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -42,6 +42,7 @@ #include "drivers/St7789.h" #include "drivers/TwiMaster.h" #include "drivers/Cst816s.h" +#include "drivers/PinMap.h" #include "systemtask/SystemTask.h" #if NRF_LOG_ENABLED @@ -52,14 +53,6 @@ Pinetime::Logging::NrfLogger logger; Pinetime::Logging::DummyLogger logger; #endif -static constexpr uint8_t pinSpiSck = 2; -static constexpr uint8_t pinSpiMosi = 3; -static constexpr uint8_t pinSpiMiso = 4; -static constexpr uint8_t pinSpiFlashCsn = 5; -static constexpr uint8_t pinLcdCsn = 25; -static constexpr uint8_t pinLcdDataCommand = 18; -static constexpr uint8_t pinTwiScl = 7; -static constexpr uint8_t pinTwiSda = 6; static constexpr uint8_t touchPanelTwiAddress = 0x15; static constexpr uint8_t motionSensorTwiAddress = 0x18; static constexpr uint8_t heartRateSensorTwiAddress = 0x44; @@ -68,14 +61,14 @@ Pinetime::Drivers::SpiMaster spi {Pinetime::Drivers::SpiMaster::SpiModule::SPI0, {Pinetime::Drivers::SpiMaster::BitOrder::Msb_Lsb, Pinetime::Drivers::SpiMaster::Modes::Mode3, Pinetime::Drivers::SpiMaster::Frequencies::Freq8Mhz, - pinSpiSck, - pinSpiMosi, - pinSpiMiso}}; + Pinetime::PinMap::SpiSck, + Pinetime::PinMap::SpiMosi, + Pinetime::PinMap::SpiMiso}}; -Pinetime::Drivers::Spi lcdSpi {spi, pinLcdCsn}; -Pinetime::Drivers::St7789 lcd {lcdSpi, pinLcdDataCommand}; +Pinetime::Drivers::Spi lcdSpi {spi, Pinetime::PinMap::SpiLcdCsn}; +Pinetime::Drivers::St7789 lcd {lcdSpi, Pinetime::PinMap::LcdDataCommand}; -Pinetime::Drivers::Spi flashSpi {spi, pinSpiFlashCsn}; +Pinetime::Drivers::Spi flashSpi {spi, Pinetime::PinMap::SpiFlashCsn}; Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; // The TWI device should work @ up to 400Khz but there is a HW bug which prevent it from @@ -83,7 +76,7 @@ Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; // at ~390Khz with correct timings. static constexpr uint32_t MaxTwiFrequencyWithoutHardwareBug {0x06200000}; Pinetime::Drivers::TwiMaster twiMaster {Pinetime::Drivers::TwiMaster::Modules::TWIM1, - Pinetime::Drivers::TwiMaster::Parameters {MaxTwiFrequencyWithoutHardwareBug, pinTwiSda, pinTwiScl}}; + Pinetime::Drivers::TwiMaster::Parameters {MaxTwiFrequencyWithoutHardwareBug, Pinetime::PinMap::TwiSda, Pinetime::PinMap::TwiScl}}; Pinetime::Drivers::Cst816S touchPanel {twiMaster, touchPanelTwiAddress}; #ifdef PINETIME_IS_RECOVERY static constexpr bool isFactory = true; @@ -106,8 +99,6 @@ Pinetime::Controllers::Battery batteryController; Pinetime::Controllers::Ble bleController; void ble_manager_set_ble_connection_callback(void (*connection)()); void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); -static constexpr uint8_t pinTouchIrq = 28; -static constexpr uint8_t pinPowerPresentIrq = 19; Pinetime::Controllers::HeartRateController heartRateController; Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController); @@ -161,14 +152,14 @@ Pinetime::System::SystemTask systemTask(spi, fs); void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { - if (pin == pinTouchIrq) { + if (pin == Pinetime::PinMap::Cst816sIrq) { systemTask.OnTouchEvent(); return; } BaseType_t xHigherPriorityTaskWoken = pdFALSE; - if (pin == pinPowerPresentIrq and action == NRF_GPIOTE_POLARITY_TOGGLE) { + if (pin == Pinetime::PinMap::PowerPresent and action == NRF_GPIOTE_POLARITY_TOGGLE) { xTimerStartFromISR(debounceChargeTimer, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); return; diff --git a/src/recoveryLoader.cpp b/src/recoveryLoader.cpp index 9818179dee..acec14c8ad 100644 --- a/src/recoveryLoader.cpp +++ b/src/recoveryLoader.cpp @@ -15,6 +15,7 @@ #include #include #include "recoveryImage.h" +#include "drivers/PinMap.h" #include "displayapp/icons/infinitime/infinitime-nb.c" #include "components/rle/RleDecoder.h" @@ -27,12 +28,6 @@ Pinetime::Logging::NrfLogger logger; Pinetime::Logging::DummyLogger logger; #endif -static constexpr uint8_t pinSpiSck = 2; -static constexpr uint8_t pinSpiMosi = 3; -static constexpr uint8_t pinSpiMiso = 4; -static constexpr uint8_t pinSpiFlashCsn = 5; -static constexpr uint8_t pinLcdCsn = 25; -static constexpr uint8_t pinLcdDataCommand = 18; static constexpr uint8_t displayWidth = 240; static constexpr uint8_t displayHeight = 240; @@ -45,14 +40,14 @@ Pinetime::Drivers::SpiMaster spi {Pinetime::Drivers::SpiMaster::SpiModule::SPI0, {Pinetime::Drivers::SpiMaster::BitOrder::Msb_Lsb, Pinetime::Drivers::SpiMaster::Modes::Mode3, Pinetime::Drivers::SpiMaster::Frequencies::Freq8Mhz, - pinSpiSck, - pinSpiMosi, - pinSpiMiso}}; -Pinetime::Drivers::Spi flashSpi {spi, pinSpiFlashCsn}; + Pinetime::PinMap::SpiSck, + Pinetime::PinMap::SpiMosi, + Pinetime::PinMap::SpiMiso}}; +Pinetime::Drivers::Spi flashSpi {spi, Pinetime::PinMap::SpiFlashCsn}; Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; -Pinetime::Drivers::Spi lcdSpi {spi, pinLcdCsn}; -Pinetime::Drivers::St7789 lcd {lcdSpi, pinLcdDataCommand}; +Pinetime::Drivers::Spi lcdSpi {spi, Pinetime::PinMap::SpiLcdCsn}; +Pinetime::Drivers::St7789 lcd {lcdSpi, Pinetime::PinMap::LcdDataCommand}; Pinetime::Components::Gfx gfx {lcd}; Pinetime::Controllers::BrightnessController brightnessController; diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 8915ce7448..e03a57bd4d 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -21,8 +21,10 @@ #include "drivers/SpiNorFlash.h" #include "drivers/TwiMaster.h" #include "drivers/Hrs3300.h" +#include "drivers/PinMap.h" #include "main.h" + #include using namespace Pinetime::System; @@ -149,7 +151,7 @@ void SystemTask::Work() { heartRateSensor.Disable(); heartRateApp.Start(); - nrf_gpio_cfg_sense_input(pinButton, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pulldown, (nrf_gpio_pin_sense_t) GPIO_PIN_CNF_SENSE_High); + nrf_gpio_cfg_sense_input(PinMap::Button, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pulldown, (nrf_gpio_pin_sense_t) GPIO_PIN_CNF_SENSE_High); nrf_gpio_cfg_output(15); nrf_gpio_pin_set(15); @@ -160,9 +162,9 @@ void SystemTask::Work() { pinConfig.sense = (nrf_gpiote_polarity_t) NRF_GPIOTE_POLARITY_HITOLO; pinConfig.pull = (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pulldown; - nrfx_gpiote_in_init(pinButton, &pinConfig, nrfx_gpiote_evt_handler); + nrfx_gpiote_in_init(PinMap::Button, &pinConfig, nrfx_gpiote_evt_handler); - nrf_gpio_cfg_sense_input(pinTouchIrq, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pullup, (nrf_gpio_pin_sense_t) GPIO_PIN_CNF_SENSE_Low); + nrf_gpio_cfg_sense_input(PinMap::Cst816sIrq, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pullup, (nrf_gpio_pin_sense_t) GPIO_PIN_CNF_SENSE_Low); pinConfig.skip_gpio_setup = true; pinConfig.hi_accuracy = false; @@ -170,19 +172,19 @@ void SystemTask::Work() { pinConfig.sense = (nrf_gpiote_polarity_t) NRF_GPIOTE_POLARITY_HITOLO; pinConfig.pull = (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pullup; - nrfx_gpiote_in_init(pinTouchIrq, &pinConfig, nrfx_gpiote_evt_handler); + nrfx_gpiote_in_init(PinMap::Cst816sIrq, &pinConfig, nrfx_gpiote_evt_handler); pinConfig.sense = NRF_GPIOTE_POLARITY_TOGGLE; pinConfig.pull = NRF_GPIO_PIN_NOPULL; pinConfig.is_watcher = false; pinConfig.hi_accuracy = false; pinConfig.skip_gpio_setup = true; - nrfx_gpiote_in_init(pinPowerPresentIrq, &pinConfig, nrfx_gpiote_evt_handler); + nrfx_gpiote_in_init(PinMap::PowerPresent, &pinConfig, nrfx_gpiote_evt_handler); - if (nrf_gpio_pin_read(pinPowerPresentIrq)) { - nrf_gpio_cfg_sense_input(pinPowerPresentIrq, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW); + if (nrf_gpio_pin_read(PinMap::PowerPresent)) { + nrf_gpio_cfg_sense_input(PinMap::PowerPresent, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW); } else { - nrf_gpio_cfg_sense_input(pinPowerPresentIrq, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH); + nrf_gpio_cfg_sense_input(PinMap::PowerPresent, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH); } idleTimer = xTimerCreate("idleTimer", pdMS_TO_TICKS(2000), pdFALSE, this, IdleTimerCallback); @@ -354,7 +356,7 @@ void SystemTask::Work() { monitor.Process(); uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); dateTimeController.UpdateTime(systick_counter); - if (!nrf_gpio_pin_read(pinButton)) + if (!nrf_gpio_pin_read(PinMap::Button)) watchdog.Kick(); } // Clear diagnostic suppression diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index 2756f77415..e4da6b1a54 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -116,15 +116,6 @@ namespace Pinetime { Pinetime::Controllers::FS& fs; Pinetime::Controllers::NimbleController nimbleController; - static constexpr uint8_t pinSpiSck = 2; - static constexpr uint8_t pinSpiMosi = 3; - static constexpr uint8_t pinSpiMiso = 4; - static constexpr uint8_t pinSpiCsn = 25; - static constexpr uint8_t pinLcdDataCommand = 18; - static constexpr uint8_t pinButton = PINMAP_BUTTON_PIN; - static constexpr uint8_t pinTouchIrq = 28; - static constexpr uint8_t pinPowerPresentIrq = 19; - static void Process(void* instance); void Work(); void ReloadIdleTimer(); From b3e6da75148fcb54fdb5fe02f6bdc7d7d3905e98 Mon Sep 17 00:00:00 2001 From: hubmartin Date: Tue, 3 Aug 2021 20:40:27 +0200 Subject: [PATCH 07/40] Cleanup, set Pinetime as default --- src/components/battery/BatteryController.cpp | 1 + src/components/battery/BatteryController.h | 1 - src/drivers/PinMap.h | 58 ++++++-------------- 3 files changed, 18 insertions(+), 42 deletions(-) diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index d543ccd947..e2fce7f3c4 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -1,4 +1,5 @@ #include "BatteryController.h" +#include "drivers/PinMap.h" #include #include #include diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 993ef6c5c2..5c7fa1f4a0 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -3,7 +3,6 @@ #include #include #include -#include namespace Pinetime { namespace Controllers { diff --git a/src/drivers/PinMap.h b/src/drivers/PinMap.h index 117cf11fb9..c8b091f1cf 100644 --- a/src/drivers/PinMap.h +++ b/src/drivers/PinMap.h @@ -2,61 +2,37 @@ namespace Pinetime { namespace PinMap { - #define WATCH_P8 + #ifdef WATCH_P8 + // COLMI P8 static constexpr uint8_t Charging = 19; static constexpr uint8_t Cst816sReset = 13; static constexpr uint8_t Button = 17; #else + // Pinetime static constexpr uint8_t Charging = 12; static constexpr uint8_t Cst816sReset = 10; static constexpr uint8_t Button = 13; #endif - static constexpr uint8_t Cst816sIrq = 28; - static constexpr uint8_t PowerPresent = 19; + static constexpr uint8_t Cst816sIrq = 28; + static constexpr uint8_t PowerPresent = 19; - static constexpr uint8_t Motor = 16; + static constexpr uint8_t Motor = 16; - static constexpr uint8_t LcdBacklight1 = 14; - static constexpr uint8_t LcdBacklight2 = 22; - static constexpr uint8_t LcdBacklight3 = 23; + static constexpr uint8_t LcdBacklight1 = 14; + static constexpr uint8_t LcdBacklight2 = 22; + static constexpr uint8_t LcdBacklight3 = 23; - static constexpr uint8_t SpiSck = 2; - static constexpr uint8_t SpiMosi = 3; - static constexpr uint8_t SpiMiso = 4; + static constexpr uint8_t SpiSck = 2; + static constexpr uint8_t SpiMosi = 3; + static constexpr uint8_t SpiMiso = 4; - static constexpr uint8_t SpiFlashCsn = 5; - static constexpr uint8_t SpiLcdCsn = 25; - static constexpr uint8_t LcdDataCommand = 18; - - static constexpr uint8_t TwiScl = 7; - static constexpr uint8_t TwiSda = 6; + static constexpr uint8_t SpiFlashCsn = 5; + static constexpr uint8_t SpiLcdCsn = 25; + static constexpr uint8_t LcdDataCommand = 18; + static constexpr uint8_t TwiScl = 7; + static constexpr uint8_t TwiSda = 6; } } - - -#ifdef WATCH_P8 - -// BatteryController.h -#define PINMAP_CHARGING_PIN 19 - -// Cst816s.h -#define PINMAP_CST816S_RESET_PIN 13 - -// SystemTask.h -#define PINMAP_BUTTON_PIN 17 - -#else - -// BatteryController.h -#define PINMAP_CHARGING_PIN 12 - -// Cst816s.h -#define PINMAP_CST816S_RESET_PIN 10 - -// SystemTask.h -#define PINMAP_BUTTON_PIN 13 - -#endif \ No newline at end of file From abd8f343e48bdfa1dc4c8604d843a5c2d8071bc0 Mon Sep 17 00:00:00 2001 From: hubmartin Date: Wed, 4 Aug 2021 14:43:04 +0200 Subject: [PATCH 08/40] Rename backlight level pins --- .../brightness/BrightnessController.cpp | 30 +++++++++---------- src/drivers/PinMap.h | 6 ++-- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/components/brightness/BrightnessController.cpp b/src/components/brightness/BrightnessController.cpp index 350dfeeb07..6c524679c1 100644 --- a/src/components/brightness/BrightnessController.cpp +++ b/src/components/brightness/BrightnessController.cpp @@ -5,9 +5,9 @@ using namespace Pinetime::Controllers; void BrightnessController::Init() { - nrf_gpio_cfg_output(PinMap::LcdBacklight1); - nrf_gpio_cfg_output(PinMap::LcdBacklight2); - nrf_gpio_cfg_output(PinMap::LcdBacklight3); + nrf_gpio_cfg_output(PinMap::LcdBacklightLow); + nrf_gpio_cfg_output(PinMap::LcdBacklightMedium); + nrf_gpio_cfg_output(PinMap::LcdBacklightHigh); Set(level); } @@ -16,24 +16,24 @@ void BrightnessController::Set(BrightnessController::Levels level) { switch (level) { default: case Levels::High: - nrf_gpio_pin_clear(PinMap::LcdBacklight1); - nrf_gpio_pin_clear(PinMap::LcdBacklight2); - nrf_gpio_pin_clear(PinMap::LcdBacklight3); + nrf_gpio_pin_clear(PinMap::LcdBacklightLow); + nrf_gpio_pin_clear(PinMap::LcdBacklightMedium); + nrf_gpio_pin_clear(PinMap::LcdBacklightHigh); break; case Levels::Medium: - nrf_gpio_pin_clear(PinMap::LcdBacklight1); - nrf_gpio_pin_clear(PinMap::LcdBacklight2); - nrf_gpio_pin_set(PinMap::LcdBacklight3); + nrf_gpio_pin_clear(PinMap::LcdBacklightLow); + nrf_gpio_pin_clear(PinMap::LcdBacklightMedium); + nrf_gpio_pin_set(PinMap::LcdBacklightHigh); break; case Levels::Low: - nrf_gpio_pin_clear(PinMap::LcdBacklight1); - nrf_gpio_pin_set(PinMap::LcdBacklight2); - nrf_gpio_pin_set(PinMap::LcdBacklight3); + nrf_gpio_pin_clear(PinMap::LcdBacklightLow); + nrf_gpio_pin_set(PinMap::LcdBacklightMedium); + nrf_gpio_pin_set(PinMap::LcdBacklightHigh); break; case Levels::Off: - nrf_gpio_pin_set(PinMap::LcdBacklight1); - nrf_gpio_pin_set(PinMap::LcdBacklight2); - nrf_gpio_pin_set(PinMap::LcdBacklight3); + nrf_gpio_pin_set(PinMap::LcdBacklightLow); + nrf_gpio_pin_set(PinMap::LcdBacklightMedium); + nrf_gpio_pin_set(PinMap::LcdBacklightHigh); break; } } diff --git a/src/drivers/PinMap.h b/src/drivers/PinMap.h index c8b091f1cf..57964020c6 100644 --- a/src/drivers/PinMap.h +++ b/src/drivers/PinMap.h @@ -20,9 +20,9 @@ namespace Pinetime { static constexpr uint8_t Motor = 16; - static constexpr uint8_t LcdBacklight1 = 14; - static constexpr uint8_t LcdBacklight2 = 22; - static constexpr uint8_t LcdBacklight3 = 23; + static constexpr uint8_t LcdBacklightLow = 14; + static constexpr uint8_t LcdBacklightMedium = 22; + static constexpr uint8_t LcdBacklightHigh = 23; static constexpr uint8_t SpiSck = 2; static constexpr uint8_t SpiMosi = 3; From 23bde0d18e99a344b95b5f1507350e186659eec2 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Sat, 14 Aug 2021 21:18:11 +0300 Subject: [PATCH 09/40] Make battery reading periodic. Add events. Disable pullup --- src/components/battery/BatteryController.cpp | 11 +++--- src/components/battery/BatteryController.h | 7 ++-- src/displayapp/DisplayApp.cpp | 3 -- src/displayapp/Messages.h | 1 - src/displayapp/screens/BatteryInfo.cpp | 3 -- src/systemtask/Messages.h | 4 ++- src/systemtask/SystemTask.cpp | 35 +++++++++++--------- src/systemtask/SystemTask.h | 6 ++-- 8 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index f8a64ecd18..aa038c5ded 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -9,10 +9,7 @@ Battery* Battery::instance = nullptr; Battery::Battery() { instance = this; -} - -void Battery::Init() { - nrf_gpio_cfg_input(chargingPin, static_cast GPIO_PIN_CNF_PULL_Pullup); + nrf_gpio_cfg_input(chargingPin, static_cast GPIO_PIN_CNF_PULL_Disabled); } void Battery::Update() { @@ -75,5 +72,11 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { nrfx_saadc_uninit(); isReading = false; + + systemTask->PushMessage(System::Messages::BatteryMeasurementDone); } } + +void Battery::Register(Pinetime::System::SystemTask* systemTask) { + this->systemTask = systemTask; +} diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 6f09b737a3..ad304eba41 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -1,8 +1,7 @@ #pragma once #include #include -#include -#include +#include namespace Pinetime { namespace Controllers { @@ -11,8 +10,8 @@ namespace Pinetime { public: Battery(); - void Init(); void Update(); + void Register(System::SystemTask* systemTask); uint8_t PercentRemaining() const { return percentRemaining; @@ -49,6 +48,8 @@ namespace Pinetime { static void AdcCallbackStatic(nrfx_saadc_evt_t const* event); bool isReading = false; + + Pinetime::System::SystemTask* systemTask = nullptr; }; } } diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index d4a73f5ee7..c6e9466814 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -194,9 +194,6 @@ void DisplayApp::Refresh() { // clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected : // Screens::Clock::BleConnectionStates::NotConnected); break; - case Messages::UpdateBatteryLevel: - batteryController.Update(); - break; case Messages::NewNotification: LoadApp(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down); break; diff --git a/src/displayapp/Messages.h b/src/displayapp/Messages.h index 322505e6fe..8e4884db08 100644 --- a/src/displayapp/Messages.h +++ b/src/displayapp/Messages.h @@ -7,7 +7,6 @@ namespace Pinetime { GoToRunning, UpdateDateTime, UpdateBleConnection, - UpdateBatteryLevel, TouchEvent, ButtonPushed, NewNotification, diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index 0ab47ebfff..31cde071ee 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -59,9 +59,6 @@ BatteryInfo::~BatteryInfo() { } void BatteryInfo::UpdateScreen() { - - batteryController.Update(); - batteryPercent = batteryController.PercentRemaining(); batteryVoltage = batteryController.Voltage(); diff --git a/src/systemtask/Messages.h b/src/systemtask/Messages.h index 3a195e2d41..ebe6a2b14f 100644 --- a/src/systemtask/Messages.h +++ b/src/systemtask/Messages.h @@ -20,7 +20,9 @@ namespace Pinetime { EnableSleeping, DisableSleeping, OnNewDay, - OnChargingEvent + OnChargingEvent, + MeasureBatteryTimerExpired, + BatteryMeasurementDone, }; } } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 8915ce7448..7ef6fc61f3 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -47,6 +47,11 @@ void IdleTimerCallback(TimerHandle_t xTimer) { sysTask->OnIdle(); } +void MeasureBatteryTimerCallback(TimerHandle_t xTimer) { + auto* sysTask = static_cast(pvTimerGetTimerID(xTimer)); + sysTask->PushMessage(Pinetime::System::Messages::MeasureBatteryTimerExpired); +} + SystemTask::SystemTask(Drivers::SpiMaster& spi, Drivers::St7789& lcd, Pinetime::Drivers::SpiNorFlash& spiNorFlash, @@ -126,7 +131,8 @@ void SystemTask::Work() { twiMaster.Init(); touchPanel.Init(); dateTimeController.Register(this); - batteryController.Init(); + batteryController.Register(this); + batteryController.Update(); motorController.Init(); motionSensor.SoftReset(); timerController.Register(this); @@ -143,8 +149,6 @@ void SystemTask::Work() { displayApp.Register(this); displayApp.Start(); - displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); - heartRateSensor.Init(); heartRateSensor.Disable(); heartRateApp.Start(); @@ -187,7 +191,9 @@ void SystemTask::Work() { idleTimer = xTimerCreate("idleTimer", pdMS_TO_TICKS(2000), pdFALSE, this, IdleTimerCallback); dimTimer = xTimerCreate("dimTimer", pdMS_TO_TICKS(settingsController.GetScreenTimeOut() - 2000), pdFALSE, this, DimTimerCallback); + measureBatteryTimer = xTimerCreate("measureBattery", batteryMeasurementPeriod, pdTRUE, this, MeasureBatteryTimerCallback); xTimerStart(dimTimer, 0); + xTimerStart(measureBatteryTimer, portMAX_DELAY); // Suppress endless loop diagnostic #pragma clang diagnostic push @@ -197,11 +203,6 @@ void SystemTask::Work() { uint8_t msg; if (xQueueReceive(systemTasksMsgQueue, &msg, 100)) { - - batteryController.Update(); - // the battery does not emit events when changing charge levels, so we piggyback - // on any system event to read and update the current values - Messages message = static_cast(msg); switch (message) { case Messages::EnableSleeping: @@ -232,7 +233,6 @@ void SystemTask::Work() { lcd.Wakeup(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToRunning); - displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp); isSleeping = false; @@ -326,8 +326,18 @@ void SystemTask::Work() { stepCounterMustBeReset = true; break; case Messages::OnChargingEvent: + batteryController.Update(); motorController.SetDuration(15); - // Battery level is updated on every message - there's no need to do anything + break; + case Messages::MeasureBatteryTimerExpired: + sendBatteryNotification = true; + batteryController.Update(); + break; + case Messages::BatteryMeasurementDone: + if (sendBatteryNotification) { + sendBatteryNotification = false; + nimbleController.NotifyBatteryLevel(batteryController.PercentRemaining()); + } break; default: @@ -346,11 +356,6 @@ void SystemTask::Work() { } } - if (xTaskGetTickCount() - batteryNotificationTick > batteryNotificationPeriod) { - nimbleController.NotifyBatteryLevel(batteryController.PercentRemaining()); - batteryNotificationTick = xTaskGetTickCount(); - } - monitor.Process(); uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); dateTimeController.UpdateTime(systick_counter); diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index ba4342987b..14c7ec71df 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -131,13 +131,15 @@ namespace Pinetime { uint8_t bleDiscoveryTimer = 0; TimerHandle_t dimTimer; TimerHandle_t idleTimer; + TimerHandle_t measureBatteryTimer; + bool sendBatteryNotification = false; bool doNotGoToSleep = false; void GoToRunning(); void UpdateMotion(); bool stepCounterMustBeReset = false; - static constexpr TickType_t batteryNotificationPeriod = 1000 * 60 * 10; // 1 tick ~= 1ms. 1ms * 60 * 10 = 10 minutes - TickType_t batteryNotificationTick = 0; + static constexpr TickType_t batteryMeasurementPeriod = pdMS_TO_TICKS(10 * 60 * 1000); + TickType_t lastBatteryNotificationTime = 0; #if configUSE_TRACE_FACILITY == 1 SystemMonitor monitor; From 55f8908769aab970413b249cb26acdaf22c79ada Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Tue, 17 Aug 2021 23:53:57 +0000 Subject: [PATCH 10/40] Make Clock Persistant. --- gcc_nrf52.ld | 11 ++++++++++- src/components/datetime/DateTimeController.cpp | 7 ++++++- src/components/datetime/DateTimeController.h | 2 ++ src/main.cpp | 11 ++++++++++- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/gcc_nrf52.ld b/gcc_nrf52.ld index 98e133aa72..b40dc06b33 100644 --- a/gcc_nrf52.ld +++ b/gcc_nrf52.ld @@ -3,14 +3,23 @@ SEARCH_DIR(.) GROUP(-lgcc -lc -lnosys) +NO_INIT_SIZE = 0x100; +RAM_MAX = 64K; MEMORY { FLASH (rx) : ORIGIN = 0x00000, LENGTH = 0x78000 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = RAM_MAX - NO_INIT_SIZE + NOINIT (rwx): ORIGIN = ORIGIN(RAM) + LENGTH(RAM), LENGTH = NO_INIT_SIZE } SECTIONS { + noinit (NOLOAD): + { + PROVIDE(__start_noinit_data = .); + KEEP(*(.noinit)) + PROVIDE(__stop_noinit_data = .); + } >NOINIT } SECTIONS diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp index d6aa83c844..77c5be4e4c 100644 --- a/src/components/datetime/DateTimeController.cpp +++ b/src/components/datetime/DateTimeController.cpp @@ -5,6 +5,10 @@ using namespace Pinetime::Controllers; +void DateTime::SetCurrentTime(std::chrono::time_point t) { + this->currentDateTime = t; +} + void DateTime::SetTime( uint16_t year, uint8_t month, uint8_t day, uint8_t dayOfWeek, uint8_t hour, uint8_t minute, uint8_t second, uint32_t systickCounter) { std::tm tm = { @@ -67,11 +71,12 @@ void DateTime::UpdateTime(uint32_t systickCounter) { // Notify new day to SystemTask if (hour == 0 and not isMidnightAlreadyNotified) { isMidnightAlreadyNotified = true; - if(systemTask != nullptr) + if (systemTask != nullptr) systemTask->PushMessage(System::Messages::OnNewDay); } else if (hour != 0) { isMidnightAlreadyNotified = false; } + BackUpTime = currentDateTime; } const char* DateTime::MonthShortToString() { diff --git a/src/components/datetime/DateTimeController.h b/src/components/datetime/DateTimeController.h index 265d6e9def..ed7b0861ca 100644 --- a/src/components/datetime/DateTimeController.h +++ b/src/components/datetime/DateTimeController.h @@ -2,6 +2,7 @@ #include #include +extern std::chrono::time_point BackUpTime; namespace Pinetime { namespace System { @@ -74,6 +75,7 @@ namespace Pinetime { } void Register(System::SystemTask* systemTask); + void SetCurrentTime(std::chrono::time_point t); private: uint16_t year = 0; diff --git a/src/main.cpp b/src/main.cpp index d301be6711..9c384a8b6e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -124,7 +124,6 @@ Pinetime::Controllers::FS fs {spiNorFlash}; Pinetime::Controllers::Settings settingsController {fs}; Pinetime::Controllers::MotorController motorController {settingsController}; - Pinetime::Applications::DisplayApp displayApp(lcd, lvgl, touchPanel, @@ -161,6 +160,9 @@ Pinetime::System::SystemTask systemTask(spi, heartRateApp, fs); +uint32_t MAGIC_RAM __attribute__((section(".noinit"))); +std::chrono::time_point BackUpTime __attribute__((section(".noinit"))); + void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { if (pin == pinTouchIrq) { systemTask.OnTouchEvent(); @@ -321,6 +323,13 @@ int main(void) { // retrieve version stored by bootloader Pinetime::BootloaderVersion::SetVersion(NRF_TIMER2->CC[0]); + // Check Magic Ram and reset lost variables + if (MAGIC_RAM == 0xDEADBEEF) { + dateTimeController.SetCurrentTime(BackUpTime); + } else { + MAGIC_RAM = 0xDEADBEEF; + } + lvgl.Init(); systemTask.Start(); From 16502b788f19458b472de74173d92f01aba30b5f Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 19 Aug 2021 00:14:42 +0000 Subject: [PATCH 11/40] Add MCUBOOT linker changes use better linker constant names --- gcc_nrf52-mcuboot.ld | 12 +++++++++++- gcc_nrf52.ld | 9 +++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/gcc_nrf52-mcuboot.ld b/gcc_nrf52-mcuboot.ld index 0746f4911f..b1413f16c2 100644 --- a/gcc_nrf52-mcuboot.ld +++ b/gcc_nrf52-mcuboot.ld @@ -3,14 +3,24 @@ SEARCH_DIR(.) GROUP(-lgcc -lc -lnosys) +NOINIT_SIZE = 0x100; +RAM_SIZE = 64K; + MEMORY { FLASH (rx) : ORIGIN = 0x08020, LENGTH = 0x78000 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000 + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = RAM_SIZE - NOINIT_SIZE + NOINIT (rwx): ORIGIN = ORIGIN(RAM) + LENGTH(RAM), LENGTH = NOINIT_SIZE } SECTIONS { + noinit (NOLOAD): + { + PROVIDE(__start_noinit_data = .); + KEEP(*(.noinit)) + PROVIDE(__stop_noinit_data = .); + } >NOINIT } SECTIONS diff --git a/gcc_nrf52.ld b/gcc_nrf52.ld index b40dc06b33..705c3d3b9c 100644 --- a/gcc_nrf52.ld +++ b/gcc_nrf52.ld @@ -3,13 +3,14 @@ SEARCH_DIR(.) GROUP(-lgcc -lc -lnosys) -NO_INIT_SIZE = 0x100; -RAM_MAX = 64K; +NOINIT_SIZE = 0x100; +RAM_SIZE = 64K; + MEMORY { FLASH (rx) : ORIGIN = 0x00000, LENGTH = 0x78000 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = RAM_MAX - NO_INIT_SIZE - NOINIT (rwx): ORIGIN = ORIGIN(RAM) + LENGTH(RAM), LENGTH = NO_INIT_SIZE + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = RAM_SIZE - NOINIT_SIZE + NOINIT (rwx): ORIGIN = ORIGIN(RAM) + LENGTH(RAM), LENGTH = NOINIT_SIZE } SECTIONS From 2dd7b8ba2c0c8f756eddd9c86a40497f1b7f7537 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 19 Aug 2021 00:44:22 +0000 Subject: [PATCH 12/40] Add clearing of noinit segment on bad word Code readability cleanup --- src/components/datetime/DateTimeController.cpp | 2 +- src/components/datetime/DateTimeController.h | 2 +- src/main.cpp | 15 ++++++++++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp index 77c5be4e4c..49953388c8 100644 --- a/src/components/datetime/DateTimeController.cpp +++ b/src/components/datetime/DateTimeController.cpp @@ -76,7 +76,7 @@ void DateTime::UpdateTime(uint32_t systickCounter) { } else if (hour != 0) { isMidnightAlreadyNotified = false; } - BackUpTime = currentDateTime; + NoInit_BackUpTime = currentDateTime; } const char* DateTime::MonthShortToString() { diff --git a/src/components/datetime/DateTimeController.h b/src/components/datetime/DateTimeController.h index ed7b0861ca..a20f71c1b3 100644 --- a/src/components/datetime/DateTimeController.h +++ b/src/components/datetime/DateTimeController.h @@ -2,7 +2,7 @@ #include #include -extern std::chrono::time_point BackUpTime; +extern std::chrono::time_point NoInit_BackUpTime; namespace Pinetime { namespace System { diff --git a/src/main.cpp b/src/main.cpp index 9c384a8b6e..d5da4283bf 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -160,8 +160,12 @@ Pinetime::System::SystemTask systemTask(spi, heartRateApp, fs); -uint32_t MAGIC_RAM __attribute__((section(".noinit"))); -std::chrono::time_point BackUpTime __attribute__((section(".noinit"))); +extern uint32_t __start_noinit_data; +extern uint32_t __stop_noinit_data; +static constexpr uint32_t NoInit_MagicValue = 0xDEADBEEF; +uint32_t NoInit_MagicWord __attribute__((section(".noinit"))); +std::chrono::time_point NoInit_BackUpTime __attribute__((section(".noinit"))); + void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { if (pin == pinTouchIrq) { @@ -324,10 +328,11 @@ int main(void) { Pinetime::BootloaderVersion::SetVersion(NRF_TIMER2->CC[0]); // Check Magic Ram and reset lost variables - if (MAGIC_RAM == 0xDEADBEEF) { - dateTimeController.SetCurrentTime(BackUpTime); + if (NoInit_MagicWord == NoInit_MagicValue) { + dateTimeController.SetCurrentTime(NoInit_BackUpTime); } else { - MAGIC_RAM = 0xDEADBEEF; + memset(&__start_noinit_data,0,(uintptr_t)&__stop_noinit_data-(uintptr_t)&__start_noinit_data); + NoInit_MagicWord = NoInit_MagicValue; } lvgl.Init(); From 4f6d7e2c6386ed584a54a513c811cb77b5d320e1 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 19 Aug 2021 00:51:12 +0000 Subject: [PATCH 13/40] Move Backup to the system task. --- src/components/datetime/DateTimeController.cpp | 1 - src/components/datetime/DateTimeController.h | 1 - src/systemtask/SystemTask.cpp | 1 + src/systemtask/SystemTask.h | 1 + 4 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp index 49953388c8..6e426825c8 100644 --- a/src/components/datetime/DateTimeController.cpp +++ b/src/components/datetime/DateTimeController.cpp @@ -76,7 +76,6 @@ void DateTime::UpdateTime(uint32_t systickCounter) { } else if (hour != 0) { isMidnightAlreadyNotified = false; } - NoInit_BackUpTime = currentDateTime; } const char* DateTime::MonthShortToString() { diff --git a/src/components/datetime/DateTimeController.h b/src/components/datetime/DateTimeController.h index a20f71c1b3..061c303f99 100644 --- a/src/components/datetime/DateTimeController.h +++ b/src/components/datetime/DateTimeController.h @@ -2,7 +2,6 @@ #include #include -extern std::chrono::time_point NoInit_BackUpTime; namespace Pinetime { namespace System { diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 3553f449fd..add591e7ad 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -353,6 +353,7 @@ void SystemTask::Work() { monitor.Process(); uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); dateTimeController.UpdateTime(systick_counter); + NoInit_BackUpTime = dateTimeController.CurrentDateTime(); if (!nrf_gpio_pin_read(pinButton)) watchdog.Kick(); } diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index ba4342987b..9293fd7898 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -30,6 +30,7 @@ #include "drivers/Watchdog.h" #include "Messages.h" +extern std::chrono::time_point NoInit_BackUpTime; namespace Pinetime { namespace Drivers { class Cst816S; From c9dedfd402c67078ce53ad661889be841633f468 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 19 Aug 2021 00:51:42 +0000 Subject: [PATCH 14/40] Add some VSCODE stuff to gitignore... Allow settings to stop naggin me that it has added assosiation types --- .gitignore | 6 ++++- .vscode/settings.json | 52 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6de76a9e20..39fb672bc8 100644 --- a/.gitignore +++ b/.gitignore @@ -38,4 +38,8 @@ Testing/Temporary/ **/.DS_Store # Windows -**/thumbs.db \ No newline at end of file +**/thumbs.db + +#VSCODE +.vscode/.cortex-debug.registers.state.json +.vscode/.cortex-debug.peripherals.state.json diff --git a/.vscode/settings.json b/.vscode/settings.json index 8f0e63f460..f1cc3a8176 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,5 +5,55 @@ "-DNRF5_SDK_PATH=${env:NRF5_SDK_PATH}", ], "cmake.generator": "Unix Makefiles", - "clang-tidy.buildPath": "build/compile_commands.json" + "clang-tidy.buildPath": "build/compile_commands.json", + "files.associations": { + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "limits": "cpp", + "new": "cpp", + "ostream": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp" + } } From 2b30ff4fc6a1835bdc5a94f8754cfd366885c4c0 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Thu, 19 Aug 2021 11:12:34 +0300 Subject: [PATCH 15/40] Remove unused variables --- src/displayapp/DisplayApp.cpp | 3 --- src/displayapp/screens/Notifications.cpp | 2 +- src/displayapp/screens/Notifications.h | 8 -------- src/main.cpp | 7 +------ 4 files changed, 2 insertions(+), 18 deletions(-) diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 5150162a93..e79fa61a9f 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -136,9 +136,6 @@ void DisplayApp::InitHw() { brightnessController.Set(settingsController.GetBrightness()); } -uint32_t acc = 0; -uint32_t count = 0; -bool toggle = true; void DisplayApp::Refresh() { TickType_t queueTimeout; TickType_t delta; diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index c061c1469d..c95edb451e 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -150,7 +150,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, uint8_t notifNb, Modes mode, Pinetime::Controllers::AlertNotificationService& alertNotificationService) - : notifNr {notifNr}, notifNb {notifNb}, mode {mode}, alertNotificationService {alertNotificationService} { + : mode {mode}, alertNotificationService {alertNotificationService} { lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL); lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x222222)); diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index a02d9b465a..ff9993435d 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -43,21 +43,13 @@ namespace Pinetime { void OnCallButtonEvent(lv_obj_t*, lv_event_t event); private: - uint8_t notifNr = 0; - uint8_t notifNb = 0; - char pageText[4]; - lv_obj_t* container1; - lv_obj_t* t1; - lv_obj_t* l1; - lv_obj_t* l2; lv_obj_t* bt_accept; lv_obj_t* bt_mute; lv_obj_t* bt_reject; lv_obj_t* label_accept; lv_obj_t* label_mute; lv_obj_t* label_reject; - lv_obj_t* bottomPlaceholder; Modes mode; Pinetime::Controllers::AlertNotificationService& alertNotificationService; bool running = true; diff --git a/src/main.cpp b/src/main.cpp index d301be6711..d420fcdf8b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -87,16 +87,13 @@ Pinetime::Drivers::TwiMaster twiMaster {Pinetime::Drivers::TwiMaster::Modules::T Pinetime::Drivers::TwiMaster::Parameters {MaxTwiFrequencyWithoutHardwareBug, pinTwiSda, pinTwiScl}}; Pinetime::Drivers::Cst816S touchPanel {twiMaster, touchPanelTwiAddress}; #ifdef PINETIME_IS_RECOVERY -static constexpr bool isFactory = true; #include "displayapp/DummyLittleVgl.h" #include "displayapp/DisplayAppRecovery.h" -Pinetime::Components::LittleVgl lvgl {lcd, touchPanel}; #else -static constexpr bool isFactory = false; #include "displayapp/LittleVgl.h" #include "displayapp/DisplayApp.h" -Pinetime::Components::LittleVgl lvgl {lcd, touchPanel}; #endif +Pinetime::Components::LittleVgl lvgl {lcd, touchPanel}; Pinetime::Drivers::Bma421 motionSensor {twiMaster, motionSensorTwiAddress}; Pinetime::Drivers::Hrs3300 heartRateSensor {twiMaster, heartRateSensorTwiAddress}; @@ -105,8 +102,6 @@ TimerHandle_t debounceTimer; TimerHandle_t debounceChargeTimer; Pinetime::Controllers::Battery batteryController; Pinetime::Controllers::Ble bleController; -void ble_manager_set_ble_connection_callback(void (*connection)()); -void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); static constexpr uint8_t pinTouchIrq = 28; static constexpr uint8_t pinPowerPresentIrq = 19; From 51c5257548efe678ec8e18d8cdea2476672f1238 Mon Sep 17 00:00:00 2001 From: hubmartin Date: Sun, 22 Aug 2021 22:17:57 +0200 Subject: [PATCH 16/40] Update startup SCL toggling pinmap definitions --- src/main.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7131c680b8..4d16a6d5e5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -45,6 +45,7 @@ #include "drivers/Cst816s.h" #include "drivers/PinMap.h" #include "systemtask/SystemTask.h" +#include "drivers/PinMap.h" #if NRF_LOG_ENABLED #include "logging/NrfLogger.h" @@ -293,18 +294,18 @@ int main(void) { nrf_drv_clock_init(); // Unblock i2c? - nrf_gpio_cfg(pinTwiScl, + nrf_gpio_cfg(Pinetime::PinMap::TwiScl, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0D1, NRF_GPIO_PIN_NOSENSE); - nrf_gpio_pin_set(pinTwiScl); + nrf_gpio_pin_set(Pinetime::PinMap::TwiScl); for (uint8_t i = 0; i < 16; i++) { - nrf_gpio_pin_toggle(pinTwiScl); + nrf_gpio_pin_toggle(Pinetime::PinMap::TwiScl); nrf_delay_us(5); } - nrf_gpio_cfg_default(pinTwiScl); + nrf_gpio_cfg_default(Pinetime::PinMap::TwiScl); debounceTimer = xTimerCreate("debounceTimer", 200, pdFALSE, (void*) 0, DebounceTimerCallback); debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, (void*) 0, DebounceTimerChargeCallback); From 110c82c225c22685a3f0b7d1d75566a929516637 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Mon, 23 Aug 2021 20:13:26 +0000 Subject: [PATCH 17/40] Move noinit to after BSS segment, Now dynamically allocates noinit area size stores it after the bss before the heap and stack. --- gcc_nrf52-mcuboot.ld | 14 +++++--------- gcc_nrf52.ld | 15 ++++++--------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/gcc_nrf52-mcuboot.ld b/gcc_nrf52-mcuboot.ld index b1413f16c2..81b318c56b 100644 --- a/gcc_nrf52-mcuboot.ld +++ b/gcc_nrf52-mcuboot.ld @@ -3,25 +3,21 @@ SEARCH_DIR(.) GROUP(-lgcc -lc -lnosys) -NOINIT_SIZE = 0x100; -RAM_SIZE = 64K; - MEMORY { FLASH (rx) : ORIGIN = 0x08020, LENGTH = 0x78000 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = RAM_SIZE - NOINIT_SIZE - NOINIT (rwx): ORIGIN = ORIGIN(RAM) + LENGTH(RAM), LENGTH = NOINIT_SIZE + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K } SECTIONS { - noinit (NOLOAD): + .noinit(NOLOAD): { PROVIDE(__start_noinit_data = .); - KEEP(*(.noinit)) + *(.noinit) PROVIDE(__stop_noinit_data = .); - } >NOINIT -} + } > RAM +} INSERT AFTER .bss SECTIONS { diff --git a/gcc_nrf52.ld b/gcc_nrf52.ld index 705c3d3b9c..f9bc5b681f 100644 --- a/gcc_nrf52.ld +++ b/gcc_nrf52.ld @@ -3,25 +3,21 @@ SEARCH_DIR(.) GROUP(-lgcc -lc -lnosys) -NOINIT_SIZE = 0x100; -RAM_SIZE = 64K; - MEMORY { FLASH (rx) : ORIGIN = 0x00000, LENGTH = 0x78000 - RAM (rwx) : ORIGIN = 0x20000000, LENGTH = RAM_SIZE - NOINIT_SIZE - NOINIT (rwx): ORIGIN = ORIGIN(RAM) + LENGTH(RAM), LENGTH = NOINIT_SIZE + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K } SECTIONS { - noinit (NOLOAD): + .noinit(NOLOAD): { PROVIDE(__start_noinit_data = .); - KEEP(*(.noinit)) + *(.noinit) PROVIDE(__stop_noinit_data = .); - } >NOINIT -} + } > RAM +} INSERT AFTER .bss SECTIONS { @@ -54,6 +50,7 @@ SECTIONS PROVIDE(__stop_log_filter_data = .); } > RAM + } INSERT AFTER .data; SECTIONS From d7293a44dfa6de8cb6ad25c259d33ca07bde3426 Mon Sep 17 00:00:00 2001 From: Fabien Benetou Date: Thu, 26 Aug 2021 15:11:20 +0200 Subject: [PATCH 18/40] Infini-iOS --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 6549ece98d..86f1b9dda0 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,7 @@ As of now, here is the list of achievements of this project: * [Amazfish](https://openrepos.net/content/piggz/amazfish) (on SailfishOS and Linux) * [Siglo](https://github.com/alexr4535/siglo) (on Linux) * **[Experimental]** [WebBLEWatch](https://hubmartin.github.io/WebBLEWatch/) Synchronize time directly from your web browser. [video](https://youtu.be/IakiuhVDdrY) + * **[Experimental]** [Infini-iOS](https://github.com/xan-m/Infini-iOS) (on iOS) - OTA (Over-the-air) update via BLE - [Bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader) based on [MCUBoot](https://juullabs-oss.github.io/mcuboot/) From b45d7c372d960051d048e4123335af6dacf88297 Mon Sep 17 00:00:00 2001 From: Colin Kinloch Date: Thu, 26 Aug 2021 19:42:02 +0100 Subject: [PATCH 19/40] Correct change test for wake up mode setting --- src/components/settings/Settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 93d6d21760..0ff1cb8acc 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -78,7 +78,7 @@ namespace Pinetime { }; void setWakeUpMode(WakeUpMode wakeUp, bool enabled) { - if (!isWakeUpModeOn(wakeUp)) { + if (enabled != isWakeUpModeOn(wakeUp)) { settingsChanged = true; } settings.wakeUpMode.set(static_cast(wakeUp), enabled); From be31f417db1937032ae440e1cf68cb2971284713 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sun, 29 Aug 2021 15:50:04 -0500 Subject: [PATCH 20/40] WIP Refactor ble advertising Refactor ble advertising based on ble standards and conventions. Changes are based on the bleprph example code, bluetooth docs, and nimble docs. --- src/CMakeLists.txt | 11 ++- src/components/ble/NimbleController.cpp | 98 +++++++++++++++---------- src/components/ble/NimbleController.h | 2 + src/systemtask/SystemTask.cpp | 2 - 4 files changed, 67 insertions(+), 46 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f72f50c9a4..c7eda52d74 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -92,6 +92,9 @@ set(SDK_SOURCE_FILES set(TINYCRYPT_SRC libs/mynewt-nimble/ext/tinycrypt/src/aes_encrypt.c libs/mynewt-nimble/ext/tinycrypt/src/utils.c + libs/mynewt-nimble/ext/tinycrypt/src/cmac_mode.c + libs/mynewt-nimble/ext/tinycrypt/src/ecc.c + libs/mynewt-nimble/ext/tinycrypt/src/ecc_dh.c ) set(NIMBLE_SRC @@ -104,6 +107,10 @@ set(NIMBLE_SRC libs/mynewt-nimble/nimble/host/src/ble_l2cap.c libs/mynewt-nimble/nimble/host/src/ble_hs_mbuf.c libs/mynewt-nimble/nimble/host/src/ble_sm.c + libs/mynewt-nimble/nimble/host/src/ble_sm_cmd.c + libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c + libs/mynewt-nimble/nimble/host/src/ble_sm_alg.c + libs/mynewt-nimble/nimble/host/src/ble_sm_sc.c libs/mynewt-nimble/nimble/host/src/ble_gap.c libs/mynewt-nimble/nimble/host/src/ble_gatts.c libs/mynewt-nimble/nimble/host/src/ble_gattc.c @@ -127,10 +134,6 @@ set(NIMBLE_SRC libs/mynewt-nimble/nimble/host/src/ble_hs_atomic.c libs/mynewt-nimble/nimble/host/src/ble_hs_adv.c libs/mynewt-nimble/nimble/host/src/ble_hs_flow.c - libs/mynewt-nimble/nimble/host/src/ble_sm.c - libs/mynewt-nimble/nimble/host/src/ble_sm_cmd.c - libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c - libs/mynewt-nimble/nimble/host/src/ble_sm_alg.c libs/mynewt-nimble/nimble/host/src/ble_hs_mqueue.c libs/mynewt-nimble/nimble/host/src/ble_hs_stop.c libs/mynewt-nimble/nimble/host/src/ble_hs_startup.c diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 5eb227bf00..4de8fff9d1 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -42,6 +42,19 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, serviceDiscovery({¤tTimeClient, &alertNotificationClient}) { } +void nimble_on_reset(int reason) { + NRF_LOG_INFO("Resetting state; reason=%d\n", reason); +} + +void nimble_on_sync(void) { + int rc; + + rc = ble_hs_util_ensure_addr(0); + ASSERT(rc == 0); + + nptr->StartAdvertising(); +} + int GAPEventCallback(struct ble_gap_event* event, void* arg) { auto nimbleController = static_cast(arg); return nimbleController->OnGAPEvent(event); @@ -51,6 +64,10 @@ void NimbleController::Init() { while (!ble_hs_synced()) { } + nptr = this; + ble_hs_cfg.reset_cb = nimble_on_reset; + ble_hs_cfg.sync_cb = nimble_on_sync; + ble_svc_gap_init(); ble_svc_gatt_init(); @@ -64,28 +81,31 @@ void NimbleController::Init() { batteryInformationService.Init(); immediateAlertService.Init(); heartRateService.Init(); - int res; - res = ble_hs_util_ensure_addr(0); - ASSERT(res == 0); - res = ble_hs_id_infer_auto(0, &addrType); - ASSERT(res == 0); - res = ble_svc_gap_device_name_set(deviceName); - ASSERT(res == 0); + + int rc; + rc = ble_hs_util_ensure_addr(0); + ASSERT(rc == 0); + rc = ble_hs_id_infer_auto(0, &addrType); + ASSERT(rc == 0); + rc = ble_svc_gap_device_name_set(deviceName); + ASSERT(rc == 0); + rc = ble_svc_gap_device_appearance_set(0xC2); + ASSERT(rc == 0); Pinetime::Controllers::Ble::BleAddress address; - res = ble_hs_id_copy_addr(addrType, address.data(), nullptr); - ASSERT(res == 0); + rc = ble_hs_id_copy_addr(addrType, address.data(), nullptr); + ASSERT(rc == 0); bleController.AddressType((addrType == 0) ? Ble::AddressTypes::Public : Ble::AddressTypes::Random); bleController.Address(std::move(address)); - res = ble_gatts_start(); - ASSERT(res == 0); + rc = ble_gatts_start(); + ASSERT(rc == 0); + + if (!ble_gap_adv_active() && !bleController.IsConnected()) + StartAdvertising(); } void NimbleController::StartAdvertising() { - if (bleController.IsConnected() || ble_gap_conn_active() || ble_gap_adv_active()) - return; - - ble_svc_gap_device_name_set(deviceName); + int rc; /* set adv parameters */ struct ble_gap_adv_params adv_params; @@ -104,9 +124,6 @@ void NimbleController::StartAdvertising() { adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; - // fields.uuids128 = BLE_UUID128(BLE_UUID128_DECLARE( - // 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - // 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff)); fields.uuids128 = &dfuServiceUuid; fields.num_uuids128 = 1; fields.uuids128_is_complete = 1; @@ -116,27 +133,24 @@ void NimbleController::StartAdvertising() { rsp_fields.name_len = strlen(deviceName); rsp_fields.name_is_complete = 1; - ble_gap_adv_set_fields(&fields); - // ASSERT(res == 0); // TODO this one sometimes fails with error 22 (notsync) + rc = ble_gap_adv_set_fields(&fields); + ASSERT(rc == 0); - ble_gap_adv_rsp_set_fields(&rsp_fields); - // ASSERT(res == 0); + rc = ble_gap_adv_rsp_set_fields(&rsp_fields); + ASSERT(rc == 0); - ble_gap_adv_start(addrType, NULL, 180000, &adv_params, GAPEventCallback, this); - // ASSERT(res == 0);// TODO I've disabled these ASSERT as they sometime asserts and reset the mcu. - // For now, the advertising is restarted as soon as it ends. There may be a race condition - // that prevent the advertising from restarting reliably. - // I remove the assert to prevent this uncesseray crash, but in the long term, the management of - // the advertising should be improve (better error handling, and advertise for 3 minutes after - // the application has been woken up, for example. + rc = ble_gap_adv_start(addrType, NULL, 5000, &adv_params, GAPEventCallback, this); + ASSERT(rc == 0); } int NimbleController::OnGAPEvent(ble_gap_event* event) { switch (event->type) { case BLE_GAP_EVENT_ADV_COMPLETE: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_ADV_COMPLETE"); - NRF_LOG_INFO("advertise complete; reason=%dn status=%d", event->adv_complete.reason, event->connect.status); + NRF_LOG_INFO("reason=%d; status=%d", event->adv_complete.reason, event->connect.status); + StartAdvertising(); break; + case BLE_GAP_EVENT_CONNECT: { NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_CONNECT"); @@ -145,18 +159,19 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { if (event->connect.status != 0) { /* Connection failed; resume advertising. */ - StartAdvertising(); bleController.Disconnect(); + StartAdvertising(); } else { + connectionHandle = event->connect.conn_handle; bleController.Connect(); systemTask.PushMessage(Pinetime::System::Messages::BleConnected); - connectionHandle = event->connect.conn_handle; - // Service discovery is deffered via systemtask + // Service discovery is deferred via systemtask } } break; + case BLE_GAP_EVENT_DISCONNECT: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_DISCONNECT"); - NRF_LOG_INFO("disconnect; reason=%d", event->disconnect.reason); + NRF_LOG_INFO("disconnect reason=%d", event->disconnect.reason); /* Connection terminated; resume advertising. */ currentTimeClient.Reset(); @@ -165,15 +180,18 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { bleController.Disconnect(); StartAdvertising(); break; + case BLE_GAP_EVENT_CONN_UPDATE: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_CONN_UPDATE"); /* The central has updated the connection parameters. */ - NRF_LOG_INFO("connection updated; status=%d ", event->conn_update.status); + NRF_LOG_INFO("update status=%d ", event->conn_update.status); break; + case BLE_GAP_EVENT_ENC_CHANGE: /* Encryption has been enabled or disabled for this connection. */ NRF_LOG_INFO("encryption change event; status=%d ", event->enc_change.status); - return 0; + break; + case BLE_GAP_EVENT_SUBSCRIBE: NRF_LOG_INFO("subscribe event; conn_handle=%d attr_handle=%d " "reason=%d prevn=%d curn=%d previ=%d curi=???\n", @@ -183,10 +201,11 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { event->subscribe.prev_notify, event->subscribe.cur_notify, event->subscribe.prev_indicate); - return 0; + break; + case BLE_GAP_EVENT_MTU: NRF_LOG_INFO("mtu update event; conn_handle=%d cid=%d mtu=%d\n", event->mtu.conn_handle, event->mtu.channel_id, event->mtu.value); - return 0; + break; case BLE_GAP_EVENT_REPEAT_PAIRING: { /* We already have a bond with the peer, but it is attempting to @@ -217,8 +236,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { notifSize); alertNotificationClient.OnNotification(event); - return 0; - } + } break; /* Attribute data is contained in event->notify_rx.attr_data. */ default: diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 0cfe983c6b..078d6158a9 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -101,5 +101,7 @@ namespace Pinetime { ServiceDiscovery serviceDiscovery; }; + + static NimbleController* nptr; } } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 3553f449fd..2dff9254b9 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -120,7 +120,6 @@ void SystemTask::Work() { fs.Init(); nimbleController.Init(); - nimbleController.StartAdvertising(); lcd.Init(); twiMaster.Init(); @@ -226,7 +225,6 @@ void SystemTask::Work() { touchPanel.Wakeup(); } - nimbleController.StartAdvertising(); xTimerStart(dimTimer, 0); spiNorFlash.Wakeup(); lcd.Wakeup(); From 00a3f84ea764e5da5d982e7603ece1e574306850 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Mon, 30 Aug 2021 23:17:16 -0500 Subject: [PATCH 21/40] Completely reset connection state on fail --- src/components/ble/NimbleController.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 4de8fff9d1..8b4f3ea835 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -159,6 +159,9 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { if (event->connect.status != 0) { /* Connection failed; resume advertising. */ + currentTimeClient.Reset(); + alertNotificationClient.Reset(); + connectionHandle = BLE_HS_CONN_HANDLE_NONE; bleController.Disconnect(); StartAdvertising(); } else { From d69a8e84fa1906a661738ea034eae5f5f37c25bf Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Wed, 1 Sep 2021 22:48:01 -0500 Subject: [PATCH 22/40] Fix race condition, connect->disconnect->discovery --- src/components/ble/NimbleController.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 8b4f3ea835..0f48609546 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -250,7 +250,9 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { } void NimbleController::StartDiscovery() { - serviceDiscovery.StartDiscovery(connectionHandle); + if (connectionHandle != BLE_HS_CONN_HANDLE_NONE) { + serviceDiscovery.StartDiscovery(connectionHandle); + } } uint16_t NimbleController::connHandle() { From 3e1fe687b82d4df237b7b355fa31cb88713193fc Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Wed, 1 Sep 2021 22:50:56 -0500 Subject: [PATCH 23/40] Fix styles issues - no change to functionality --- src/components/ble/NimbleController.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 0f48609546..8e0fe75656 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -151,7 +151,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { StartAdvertising(); break; - case BLE_GAP_EVENT_CONNECT: { + case BLE_GAP_EVENT_CONNECT: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_CONNECT"); /* A new connection was established or a connection attempt failed. */ @@ -170,7 +170,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { systemTask.PushMessage(Pinetime::System::Messages::BleConnected); // Service discovery is deferred via systemtask } - } break; + break; case BLE_GAP_EVENT_DISCONNECT: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_DISCONNECT"); @@ -207,7 +207,8 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { break; case BLE_GAP_EVENT_MTU: - NRF_LOG_INFO("mtu update event; conn_handle=%d cid=%d mtu=%d\n", event->mtu.conn_handle, event->mtu.channel_id, event->mtu.value); + NRF_LOG_INFO("mtu update event; conn_handle=%d cid=%d mtu=%d\n", + event->mtu.conn_handle, event->mtu.channel_id, event->mtu.value); break; case BLE_GAP_EVENT_REPEAT_PAIRING: { @@ -224,8 +225,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should * continue with the pairing operation. */ - } - return BLE_GAP_REPEAT_PAIRING_RETRY; + } return BLE_GAP_REPEAT_PAIRING_RETRY; case BLE_GAP_EVENT_NOTIFY_RX: { /* Peer sent us a notification or indication. */ @@ -260,7 +260,7 @@ uint16_t NimbleController::connHandle() { } void NimbleController::NotifyBatteryLevel(uint8_t level) { - if(connectionHandle != BLE_HS_CONN_HANDLE_NONE) { + if (connectionHandle != BLE_HS_CONN_HANDLE_NONE) { batteryInformationService.NotifyBatteryLevel(connectionHandle, level); } } From bd1a571399923014c6411dc7f4677078ee54d0f5 Mon Sep 17 00:00:00 2001 From: Itai Nelken <70802936+Itai-Nelken@users.noreply.github.com> Date: Thu, 2 Sep 2021 23:20:25 +0300 Subject: [PATCH 24/40] Update Settings.cpp --- src/displayapp/screens/settings/Settings.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/displayapp/screens/settings/Settings.cpp b/src/displayapp/screens/settings/Settings.cpp index f82b03c1a1..e3319f030a 100644 --- a/src/displayapp/screens/settings/Settings.cpp +++ b/src/displayapp/screens/settings/Settings.cpp @@ -50,8 +50,8 @@ std::unique_ptr Settings::CreateScreen2() { std::array applications {{ {Symbols::shoe, "Steps", Apps::SettingSteps}, {Symbols::batteryHalf, "Battery", Apps::BatteryInfo}, + {Symbols::paintbrush, "PTS Colors", Apps::SettingPineTimeStyle}, {Symbols::check, "Firmware", Apps::FirmwareValidation}, - {Symbols::list, "About", Apps::SysInfo}, }}; return std::make_unique(1, 3, app, settingsController, applications); @@ -60,7 +60,7 @@ std::unique_ptr Settings::CreateScreen2() { std::unique_ptr Settings::CreateScreen3() { std::array applications {{ - {Symbols::paintbrush, "PTS Colors", Apps::SettingPineTimeStyle}, + {Symbols::list, "About", Apps::SysInfo}, {Symbols::none, "None", Apps::None}, {Symbols::none, "None", Apps::None}, {Symbols::none, "None", Apps::None}, From 28fdc376b23ee2cd87a3ed8925b44a2f6e614ebf Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 2 Sep 2021 23:01:12 +0000 Subject: [PATCH 25/40] Add some comments --- src/main.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index d5da4283bf..5d304bc4a6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -160,9 +160,12 @@ Pinetime::System::SystemTask systemTask(spi, heartRateApp, fs); +/* Variable Declarations for variables in noinit SRAM + Increment NoInit_MagicValue upon adding variables to this area +*/ extern uint32_t __start_noinit_data; extern uint32_t __stop_noinit_data; -static constexpr uint32_t NoInit_MagicValue = 0xDEADBEEF; +static constexpr uint32_t NoInit_MagicValue = 0xDEAD0000; uint32_t NoInit_MagicWord __attribute__((section(".noinit"))); std::chrono::time_point NoInit_BackUpTime __attribute__((section(".noinit"))); @@ -327,10 +330,11 @@ int main(void) { // retrieve version stored by bootloader Pinetime::BootloaderVersion::SetVersion(NRF_TIMER2->CC[0]); - // Check Magic Ram and reset lost variables + if (NoInit_MagicWord == NoInit_MagicValue) { dateTimeController.SetCurrentTime(NoInit_BackUpTime); } else { + //Clear Memory to known state memset(&__start_noinit_data,0,(uintptr_t)&__stop_noinit_data-(uintptr_t)&__start_noinit_data); NoInit_MagicWord = NoInit_MagicValue; } From c32ba844e04017a3fd31444c384deb3542bd76be Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sat, 4 Sep 2021 15:26:50 -0500 Subject: [PATCH 26/40] Linear decrease of advert rate to conserve battery Start advertising aggressively when powered on then slow down linearly over 75 seconds. This will conserve battery by not advertising rapidly the whole time we are seeking a connection. The slowest rate is approximately once every 4.5 seconds to balance responsiveness and battery life. We use a fixed advertising duration of 5 seconds and start with a 62.5 ms advertising interval. Every 5 seconds (the advertising duration) we step up to a larger advertising interval (slower advertising). We continue to increase the advertising interval linearly for 75 seconds from the start of advertising. At 75 seconds we have an advertising interval of 4.44 seconds which we keep until connected. A reboot will restart the sequence. When we receive a disconnect event we restart the sequence with fast advertising and then slow down as described above. Note that we are not using the BLE high duty cycle setting to change the advertising rate. The rate is managed by repeatedly setting the minimum and maximum intervals. The linear rate of decrease and the slowest interval size were determined experimentally by the author. The 5.3 Core spec suggests that you not advertise slower than once every 1.2 seconds to preserve responsiveness but we ignored that suggestion. --- src/components/ble/NimbleController.cpp | 5 +++++ src/components/ble/NimbleController.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 8e0fe75656..bebca2d352 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -122,6 +122,8 @@ void NimbleController::StartAdvertising() { adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + adv_params.itvl_min = advInterval; + adv_params.itvl_max = advInterval + 100; fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; fields.uuids128 = &dfuServiceUuid; @@ -148,6 +150,8 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { case BLE_GAP_EVENT_ADV_COMPLETE: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_ADV_COMPLETE"); NRF_LOG_INFO("reason=%d; status=%d", event->adv_complete.reason, event->connect.status); + if (advInterval < 7100) + advInterval += 500; StartAdvertising(); break; @@ -181,6 +185,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { alertNotificationClient.Reset(); connectionHandle = BLE_HS_CONN_HANDLE_NONE; bleController.Disconnect(); + advInterval = 100; StartAdvertising(); break; diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 078d6158a9..79761108dc 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -94,6 +94,7 @@ namespace Pinetime { uint8_t addrType; // 1 = Random, 0 = PUBLIC uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; + uint16_t advInterval = 100; // multiplied by 0.625ms, must be in 32..16384 ble_uuid128_t dfuServiceUuid { .u {.type = BLE_UUID_TYPE_128}, From 4820b2ffe8be0b8d1abefd307a4c0fe6d4d41a73 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sun, 5 Sep 2021 15:52:01 -0500 Subject: [PATCH 27/40] Revert "Linear decrease of advert rate to conserve battery" This reverts commit c32ba844e04017a3fd31444c384deb3542bd76be. --- src/components/ble/NimbleController.cpp | 5 ----- src/components/ble/NimbleController.h | 1 - 2 files changed, 6 deletions(-) diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index bebca2d352..8e0fe75656 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -122,8 +122,6 @@ void NimbleController::StartAdvertising() { adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; - adv_params.itvl_min = advInterval; - adv_params.itvl_max = advInterval + 100; fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; fields.uuids128 = &dfuServiceUuid; @@ -150,8 +148,6 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { case BLE_GAP_EVENT_ADV_COMPLETE: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_ADV_COMPLETE"); NRF_LOG_INFO("reason=%d; status=%d", event->adv_complete.reason, event->connect.status); - if (advInterval < 7100) - advInterval += 500; StartAdvertising(); break; @@ -185,7 +181,6 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { alertNotificationClient.Reset(); connectionHandle = BLE_HS_CONN_HANDLE_NONE; bleController.Disconnect(); - advInterval = 100; StartAdvertising(); break; diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 79761108dc..078d6158a9 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -94,7 +94,6 @@ namespace Pinetime { uint8_t addrType; // 1 = Random, 0 = PUBLIC uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; - uint16_t advInterval = 100; // multiplied by 0.625ms, must be in 32..16384 ble_uuid128_t dfuServiceUuid { .u {.type = BLE_UUID_TYPE_128}, From 22571d4b384e40d647cd994202956f08ed32d925 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sun, 5 Sep 2021 15:53:20 -0500 Subject: [PATCH 28/40] Advertise fast for at least 30 secs then slow down On power up, advertise aggressively for at least 30 seconds then switch to a longer interval to conserve battery life. This fast/slow pattern is designed to balance connection response time and battery life. When a disconnect event is received restart the fast/slow pattern. When a failed connect event is received, restart the fast/slow pattern. When the screen is activated and ble is not connected, restart the fast/slow pattern. This pattern is consistent with Apple's BLE developer standards (QA 1931). --- src/components/ble/NimbleController.cpp | 13 ++++++++++++- src/components/ble/NimbleController.h | 5 +++++ src/systemtask/SystemTask.cpp | 3 +++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 8e0fe75656..226f669440 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -122,6 +122,15 @@ void NimbleController::StartAdvertising() { adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + /* fast advertise for 30 sec */ + if (fastAdvCount < 15) { + adv_params.itvl_min = 32; + adv_params.itvl_max = 47; + fastAdvCount++; + } else { + adv_params.itvl_min = 1636; + adv_params.itvl_max = 1651; + } fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; fields.uuids128 = &dfuServiceUuid; @@ -139,7 +148,7 @@ void NimbleController::StartAdvertising() { rc = ble_gap_adv_rsp_set_fields(&rsp_fields); ASSERT(rc == 0); - rc = ble_gap_adv_start(addrType, NULL, 5000, &adv_params, GAPEventCallback, this); + rc = ble_gap_adv_start(addrType, NULL, 2000, &adv_params, GAPEventCallback, this); ASSERT(rc == 0); } @@ -163,6 +172,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { alertNotificationClient.Reset(); connectionHandle = BLE_HS_CONN_HANDLE_NONE; bleController.Disconnect(); + fastAdvCount = 0; StartAdvertising(); } else { connectionHandle = event->connect.conn_handle; @@ -181,6 +191,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { alertNotificationClient.Reset(); connectionHandle = BLE_HS_CONN_HANDLE_NONE; bleController.Disconnect(); + fastAdvCount = 0; StartAdvertising(); break; diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 078d6158a9..473bb1aff6 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -72,6 +72,10 @@ namespace Pinetime { uint16_t connHandle(); void NotifyBatteryLevel(uint8_t level); + void RestartFastAdv() { + fastAdvCount = 0; + } + private: static constexpr const char* deviceName = "InfiniTime"; Pinetime::System::SystemTask& systemTask; @@ -94,6 +98,7 @@ namespace Pinetime { uint8_t addrType; // 1 = Random, 0 = PUBLIC uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; + uint8_t fastAdvCount = 0; ble_uuid128_t dfuServiceUuid { .u {.type = BLE_UUID_TYPE_128}, diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 2dff9254b9..41f346aecc 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -233,6 +233,9 @@ void SystemTask::Work() { displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp); + if (!bleController.IsConnected()) + nimbleController.RestartFastAdv(); + isSleeping = false; isWakingUp = false; isDimmed = false; From 3cc00771fa6528433b2ec4d787dc6bfefd948390 Mon Sep 17 00:00:00 2001 From: NeroBurner Date: Fri, 10 Sep 2021 23:42:49 +0200 Subject: [PATCH 29/40] Run CI on master and develop branch The documentation https://github.com/JF002/InfiniTime/blob/develop/doc/contribute.md#how-to-submit-a-pull-request- tells us to make pull requests against `develop` branch. Update the CI to run on those pull requests to have a check if the PR breaks something unintentionally. --- .github/workflows/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4744eaef7d..bd24359a56 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,13 +9,13 @@ name: Build PineTime Firmware # When to run this Workflow... on: - # Run this Workflow when files are updated (Pushed) in the "master" Branch + # Run this Workflow when files are updated (Pushed) in the "master" and "develop" Branch push: - branches: [ master ] + branches: [ master, develop ] - # Also run this Workflow when a Pull Request is created or updated in the "master" Branch + # Also run this Workflow when a Pull Request is created or updated in the "master" and "develop" Branch pull_request: - branches: [ master ] + branches: [ master, develop ] # Steps to run for the Workflow jobs: From 1fb5757655c1cdf0e93f03ad27869e8c043d69f0 Mon Sep 17 00:00:00 2001 From: Mark Russell Date: Fri, 10 Sep 2021 18:40:13 -0400 Subject: [PATCH 30/40] Created basic alarm app --- src/CMakeLists.txt | 5 + src/components/alarm/AlarmController.cpp | 118 +++++++++++ src/components/alarm/AlarmController.h | 50 +++++ src/components/motor/MotorController.cpp | 6 + src/components/motor/MotorController.h | 1 + src/displayapp/Apps.h | 1 + src/displayapp/DisplayApp.cpp | 13 ++ src/displayapp/DisplayApp.h | 4 + src/displayapp/Messages.h | 3 +- src/displayapp/screens/Alarm.cpp | 225 +++++++++++++++++++++ src/displayapp/screens/Alarm.h | 31 +++ src/displayapp/screens/ApplicationList.cpp | 2 +- src/main.cpp | 3 + src/systemtask/Messages.h | 4 +- src/systemtask/SystemTask.cpp | 14 ++ src/systemtask/SystemTask.h | 3 + 16 files changed, 480 insertions(+), 3 deletions(-) create mode 100644 src/components/alarm/AlarmController.cpp create mode 100644 src/components/alarm/AlarmController.h create mode 100644 src/displayapp/screens/Alarm.cpp create mode 100644 src/displayapp/screens/Alarm.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a7242903b8..ccade83e30 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -418,6 +418,7 @@ list(APPEND SOURCE_FILES displayapp/screens/BatteryInfo.cpp displayapp/screens/Steps.cpp displayapp/screens/Timer.cpp + displayapp/screens/Alarm.cpp displayapp/Colors.cpp ## Settings @@ -474,6 +475,7 @@ list(APPEND SOURCE_FILES components/motor/MotorController.cpp components/settings/Settings.cpp components/timer/TimerController.cpp + components/alarm/AlarmController.cpp components/fs/FS.cpp drivers/Cst816s.cpp FreeRTOS/port.c @@ -540,6 +542,7 @@ list(APPEND RECOVERY_SOURCE_FILES components/firmwarevalidator/FirmwareValidator.cpp components/settings/Settings.cpp components/timer/TimerController.cpp + components/alarm/AlarmController.cpp drivers/Cst816s.cpp FreeRTOS/port.c FreeRTOS/port_cmsis_systick.c @@ -612,6 +615,7 @@ set(INCLUDE_FILES displayapp/screens/Metronome.h displayapp/screens/Motion.h displayapp/screens/Timer.h + displayapp/screens/Alarm.h displayapp/Colors.h drivers/St7789.h drivers/SpiNorFlash.h @@ -643,6 +647,7 @@ set(INCLUDE_FILES components/ble/HeartRateService.h components/settings/Settings.h components/timer/TimerController.h + components/alarm/AlarmController.h drivers/Cst816s.h FreeRTOS/portmacro.h FreeRTOS/portmacro_cmsis.h diff --git a/src/components/alarm/AlarmController.cpp b/src/components/alarm/AlarmController.cpp new file mode 100644 index 0000000000..5097936f59 --- /dev/null +++ b/src/components/alarm/AlarmController.cpp @@ -0,0 +1,118 @@ +// +// Created by mrussell on 30.08.21. +// +// Copied from Florian's Timer app + +#include "AlarmController.h" +#include "systemtask/SystemTask.h" +#include "app_timer.h" +#include "task.h" +#include + +using namespace Pinetime::Controllers; +using namespace std::chrono_literals; + +AlarmController::AlarmController(Controllers::DateTime& dateTimeController) : dateTimeController {dateTimeController} { +} + +APP_TIMER_DEF(alarmAppTimer); + +namespace { + void SetOffAlarm(void* p_context) { + auto* controller = static_cast(p_context); + if (controller != nullptr) + controller->SetOffAlarmNow(); + } +} + +void AlarmController::Init() { + app_timer_create(&alarmAppTimer, APP_TIMER_MODE_SINGLE_SHOT, SetOffAlarm); +} + +void AlarmController::SetAlarm(uint8_t alarmHr, uint8_t alarmMin) { + hours = alarmHr; + minutes = alarmMin; + state = AlarmState::Set; + scheduleAlarm(); +} + +void AlarmController::scheduleAlarm() { + // Determine the next time the alarm needs to go off and set the app_timer + app_timer_stop(alarmAppTimer); + + auto now = dateTimeController.CurrentDateTime(); + alarmTime = now; + time_t ttAlarmTime = std::chrono::system_clock::to_time_t(alarmTime); + tm* tmAlarmTime = std::localtime(&ttAlarmTime); + + // If the time being set has already passed today,the alarm should be set for tomorrow + if (hours < dateTimeController.Hours() || (hours == dateTimeController.Hours() && minutes <= dateTimeController.Minutes())) { + tmAlarmTime->tm_mday += 1; + // tm_wday doesn't update automatically + tmAlarmTime->tm_wday = (tmAlarmTime->tm_wday + 1) % 7; + } + + tmAlarmTime->tm_hour = hours; + tmAlarmTime->tm_min = minutes; + tmAlarmTime->tm_sec = 0; + + // if alarm is in weekday-only mode, make sure it shifts to the next weekday + if (recurrence == RecurType::Weekdays) { + if (tmAlarmTime->tm_wday == 0) { // Sunday, shift 1 day + tmAlarmTime->tm_mday += 1; + } else if (tmAlarmTime->tm_wday == 6) { // Saturday, shift 2 days + tmAlarmTime->tm_mday += 2; + } + } + tmAlarmTime->tm_isdst = -1; // use system timezone setting to determine DST + + // now can convert back to a time_point + alarmTime = std::chrono::system_clock::from_time_t(std::mktime(tmAlarmTime)); + auto mSecToAlarm = std::chrono::duration_cast(alarmTime - now).count(); + app_timer_start(alarmAppTimer, APP_TIMER_TICKS(mSecToAlarm), this); +} + +uint32_t AlarmController::SecondsToAlarm() { + return std::chrono::duration_cast(alarmTime - dateTimeController.CurrentDateTime()).count(); +} + +void AlarmController::DisableAlarm() { + app_timer_stop(alarmAppTimer); + state = AlarmState::Not_Set; +} + +void AlarmController::SetOffAlarmNow() { + state = AlarmState::Alerting; + if (systemTask != nullptr) { + systemTask->PushMessage(System::Messages::SetOffAlarm); + } +} + +void AlarmController::StopAlerting() { + if (systemTask != nullptr) { + systemTask->PushMessage(System::Messages::StopRinging); + } + + // Alarm state is off unless this is a recurring alarm + if (recurrence == RecurType::None) { + state = AlarmState::Not_Set; + } else { + state = AlarmState::Set; + // set next instance + scheduleAlarm(); + } +} + +void AlarmController::ToggleRecurrence() { + if (recurrence == AlarmController::RecurType::None) { + recurrence = AlarmController::RecurType::Daily; + } else if (recurrence == AlarmController::RecurType::Daily) { + recurrence = AlarmController::RecurType::Weekdays; + } else { + recurrence = AlarmController::RecurType::None; + } +} + +void AlarmController::Register(Pinetime::System::SystemTask* systemTask) { + this->systemTask = systemTask; +} diff --git a/src/components/alarm/AlarmController.h b/src/components/alarm/AlarmController.h new file mode 100644 index 0000000000..22259da820 --- /dev/null +++ b/src/components/alarm/AlarmController.h @@ -0,0 +1,50 @@ +#pragma once + +#include +#include "app_timer.h" +#include "components/datetime/DateTimeController.h" + +namespace Pinetime { + namespace System { + class SystemTask; + } + namespace Controllers { + class AlarmController { + public: + AlarmController(Controllers::DateTime& dateTimeController); + + void Init(); + void SetAlarm(uint8_t alarmHr, uint8_t alarmMin); + void DisableAlarm(); + void SetOffAlarmNow(); + uint32_t SecondsToAlarm(); + void StopAlerting(); + void Register(System::SystemTask* systemTask); + enum class AlarmState { Not_Set, Set, Alerting }; + enum class RecurType { None, Daily, Weekdays }; + void ToggleRecurrence(); + uint8_t Hours() const { + return hours; + } + uint8_t Minutes() const { + return minutes; + } + AlarmState State() const { + return state; + } + RecurType Recurrence() const { + return recurrence; + } + + private: + Controllers::DateTime& dateTimeController; + System::SystemTask* systemTask = nullptr; + uint8_t hours; + uint8_t minutes; + std::chrono::time_point alarmTime; + AlarmState state = AlarmState::Not_Set; + RecurType recurrence = RecurType::None; + void scheduleAlarm(); + }; + } +} \ No newline at end of file diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index b25e6bc829..5ade19e44a 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -42,6 +42,12 @@ void MotorController::StartRinging() { app_timer_start(longVibTimer, APP_TIMER_TICKS(1000), this); } +// This function is the same as StartRinging(), but will ring even if notifications are turned off in Settings +void MotorController::StartRingingDisregardSettings() { + Ring(this); + app_timer_start(longVibTimer, APP_TIMER_TICKS(1000), this); +} + void MotorController::StopRinging() { app_timer_stop(longVibTimer); nrf_gpio_pin_set(pinMotor); diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index d2c9fe5f2c..d3b96b07c2 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -15,6 +15,7 @@ namespace Pinetime { void RunForDuration(uint8_t motorDuration); void StartRinging(); static void StopRinging(); + void StartRingingDisregardSettings(); private: static void Ring(void* p_context); diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index dd51fdb4a0..e3aca8cf00 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -12,6 +12,7 @@ namespace Pinetime { NotificationsPreview, Notifications, Timer, + Alarm, FlashLight, BatteryInfo, Music, diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index d6100ececd..33c67e229c 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include "components/battery/BatteryController.h" #include "components/ble/BleController.h" #include "components/datetime/DateTimeController.h" @@ -90,6 +91,7 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, Pinetime::Controllers::MotorController& motorController, Pinetime::Controllers::MotionController& motionController, Pinetime::Controllers::TimerController& timerController, + Pinetime::Controllers::AlarmController& alarmController, Pinetime::Controllers::TouchHandler& touchHandler) : lcd {lcd}, lvgl {lvgl}, @@ -104,6 +106,7 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, motorController {motorController}, motionController {motionController}, timerController {timerController}, + alarmController {alarmController}, touchHandler {touchHandler} { } @@ -208,6 +211,13 @@ void DisplayApp::Refresh() { LoadApp(Apps::Timer, DisplayApp::FullRefreshDirections::Down); } break; + case Messages::AlarmTriggered: + if (currentApp == Apps::Alarm) { + auto* alarm = static_cast(currentScreen.get()); + alarm->SetAlerting(); + } else { + LoadApp(Apps::Alarm, DisplayApp::FullRefreshDirections::None); + } case Messages::TouchEvent: { if (state != States::Running) { break; @@ -340,6 +350,9 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) case Apps::Timer: currentScreen = std::make_unique(this, timerController); break; + case Apps::Alarm: + currentScreen = std::make_unique(this, alarmController); + break; // Settings case Apps::QuickSettings: diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h index 96951d1c5d..4254523ad9 100644 --- a/src/displayapp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -14,7 +14,9 @@ #include "components/settings/Settings.h" #include "displayapp/screens/Screen.h" #include "components/timer/TimerController.h" +#include "components/alarm/AlarmController.h" #include "touchhandler/TouchHandler.h" + #include "Messages.h" namespace Pinetime { @@ -57,6 +59,7 @@ namespace Pinetime { Pinetime::Controllers::MotorController& motorController, Pinetime::Controllers::MotionController& motionController, Pinetime::Controllers::TimerController& timerController, + Pinetime::Controllers::AlarmController& alarmController, Pinetime::Controllers::TouchHandler& touchHandler); void Start(); void PushMessage(Display::Messages msg); @@ -82,6 +85,7 @@ namespace Pinetime { Pinetime::Controllers::MotorController& motorController; Pinetime::Controllers::MotionController& motionController; Pinetime::Controllers::TimerController& timerController; + Pinetime::Controllers::AlarmController& alarmController; Pinetime::Controllers::TouchHandler& touchHandler; Pinetime::Controllers::FirmwareValidator validator; diff --git a/src/displayapp/Messages.h b/src/displayapp/Messages.h index 322505e6fe..c23cdfe3f7 100644 --- a/src/displayapp/Messages.h +++ b/src/displayapp/Messages.h @@ -15,7 +15,8 @@ namespace Pinetime { BleFirmwareUpdateStarted, UpdateTimeOut, DimScreen, - RestoreBrightness + RestoreBrightness, + AlarmTriggered }; } } diff --git a/src/displayapp/screens/Alarm.cpp b/src/displayapp/screens/Alarm.cpp new file mode 100644 index 0000000000..e122cabd02 --- /dev/null +++ b/src/displayapp/screens/Alarm.cpp @@ -0,0 +1,225 @@ +#include "Alarm.h" +#include "Screen.h" +#include "Symbols.h" + +using namespace Pinetime::Applications::Screens; +using Pinetime::Controllers::AlarmController; + +static void btnEventHandler(lv_obj_t* obj, lv_event_t event) { + Alarm* screen = static_cast(obj->user_data); + screen->OnButtonEvent(obj, event); +} + +Alarm::Alarm(DisplayApp* app, Controllers::AlarmController& alarmController) + : Screen(app), running {true}, alarmController {alarmController} { + + time = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76); + lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); + + alarmHours = alarmController.Hours(); + alarmMinutes = alarmController.Minutes(); + lv_label_set_text_fmt(time, "%02lu:%02lu", alarmHours, alarmMinutes); + + lv_obj_align(time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -20); + + btnHoursUp = lv_btn_create(lv_scr_act(), nullptr); + btnHoursUp->user_data = this; + lv_obj_set_event_cb(btnHoursUp, btnEventHandler); + lv_obj_align(btnHoursUp, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 20, -80); + lv_obj_set_height(btnHoursUp, 40); + lv_obj_set_width(btnHoursUp, 60); + txtHrUp = lv_label_create(btnHoursUp, nullptr); + lv_label_set_text(txtHrUp, "+"); + + btnHoursDown = lv_btn_create(lv_scr_act(), nullptr); + btnHoursDown->user_data = this; + lv_obj_set_event_cb(btnHoursDown, btnEventHandler); + lv_obj_align(btnHoursDown, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 20, +40); + lv_obj_set_height(btnHoursDown, 40); + lv_obj_set_width(btnHoursDown, 60); + txtHrDown = lv_label_create(btnHoursDown, nullptr); + lv_label_set_text(txtHrDown, "-"); + + btnMinutesUp = lv_btn_create(lv_scr_act(), nullptr); + btnMinutesUp->user_data = this; + lv_obj_set_event_cb(btnMinutesUp, btnEventHandler); + lv_obj_align(btnMinutesUp, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, 10, -80); + lv_obj_set_height(btnMinutesUp, 40); + lv_obj_set_width(btnMinutesUp, 60); + txtMinUp = lv_label_create(btnMinutesUp, nullptr); + lv_label_set_text(txtMinUp, "+"); + + btnMinutesDown = lv_btn_create(lv_scr_act(), nullptr); + btnMinutesDown->user_data = this; + lv_obj_set_event_cb(btnMinutesDown, btnEventHandler); + lv_obj_align(btnMinutesDown, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, 10, +40); + lv_obj_set_height(btnMinutesDown, 40); + lv_obj_set_width(btnMinutesDown, 60); + txtMinDown = lv_label_create(btnMinutesDown, nullptr); + lv_label_set_text(txtMinDown, "-"); + + btnEnable = lv_btn_create(lv_scr_act(), nullptr); + btnEnable->user_data = this; + lv_obj_set_event_cb(btnEnable, btnEventHandler); + lv_obj_align(btnEnable, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 3, -10); + lv_obj_set_height(btnEnable, 40); + txtEnable = lv_label_create(btnEnable, nullptr); + setEnableButtonState(); + + btnRecur = lv_btn_create(lv_scr_act(), nullptr); + btnRecur->user_data = this; + lv_obj_set_event_cb(btnRecur, btnEventHandler); + lv_obj_align(btnRecur, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -3, -10); + lv_obj_set_height(btnRecur, 40); + txtRecur = lv_label_create(btnRecur, nullptr); + setRecurButtonState(); + + btnInfo = lv_btn_create(lv_scr_act(), nullptr); + btnInfo->user_data = this; + lv_obj_set_event_cb(btnInfo, btnEventHandler); + lv_obj_align(btnInfo, lv_scr_act(), LV_ALIGN_CENTER, 30, -80); + lv_obj_set_height(btnInfo, 40); + lv_obj_set_width(btnInfo, 30); + txtInfo = lv_label_create(btnInfo, nullptr); + lv_label_set_text(txtInfo, "i"); +} + +Alarm::~Alarm() { + lv_obj_clean(lv_scr_act()); +} + +void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { + using Pinetime::Controllers::AlarmController; + if (event == LV_EVENT_CLICKED) { + if (obj == btnEnable) { + if (alarmController.State() == AlarmController::AlarmState::Alerting) { + alarmController.StopAlerting(); + } else if (alarmController.State() == AlarmController::AlarmState::Set) { + alarmController.DisableAlarm(); + } else { + alarmController.SetAlarm(alarmHours, alarmMinutes); + } + setEnableButtonState(); + return; + } + if (obj == btnInfo) { + showInfo(); + return; + } + if (obj == btnMessage) { + lv_obj_del(txtMessage); + lv_obj_del(btnMessage); + txtMessage = nullptr; + btnMessage = nullptr; + return; + } + // If any other button was pressed, disable the alarm + // this is to make it clear that the alarm won't be set until it is turned back on + // this avoids calling the AlarmController to change the alarm time every time the user hits minute-up or minute-down; + // can just do it once when the alarm is re-enabled + if (alarmController.State() == AlarmController::AlarmState::Set) { + alarmController.DisableAlarm(); + setEnableButtonState(); + } + if (obj == btnMinutesUp) { + if (alarmMinutes >= 59) { + alarmMinutes = 0; + } else { + alarmMinutes++; + } + lv_label_set_text_fmt(time, "%02d:%02d", alarmHours, alarmMinutes); + return; + } + if (obj == btnMinutesDown) { + if (alarmMinutes == 0) { + alarmMinutes = 59; + } else { + alarmMinutes--; + } + lv_label_set_text_fmt(time, "%02d:%02d", alarmHours, alarmMinutes); + return; + } + if (obj == btnHoursUp) { + if (alarmHours >= 23) { + alarmHours = 0; + } else { + alarmHours++; + } + lv_label_set_text_fmt(time, "%02d:%02d", alarmHours, alarmMinutes); + return; + } + if (obj == btnHoursDown) { + if (alarmHours == 0) { + alarmHours = 23; + } else { + alarmHours--; + } + lv_label_set_text_fmt(time, "%02d:%02d", alarmHours, alarmMinutes); + return; + } + if (obj == btnRecur) { + alarmController.ToggleRecurrence(); + setRecurButtonState(); + } + } +} + +void Alarm::SetAlerting() { + setEnableButtonState(); +} + +void Alarm::setEnableButtonState() { + switch (alarmController.State()) { + case AlarmController::AlarmState::Set: + lv_label_set_text(txtEnable, "ON"); + lv_obj_set_style_local_bg_color(btnEnable, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN); + break; + case AlarmController::AlarmState::Not_Set: + lv_label_set_text(txtEnable, "OFF"); + lv_obj_set_style_local_bg_color(btnEnable, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); + break; + case AlarmController::AlarmState::Alerting: + lv_label_set_text(txtEnable, Symbols::stop); + lv_obj_set_style_local_bg_color(btnEnable, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_RED); + } +} + +void Alarm::showInfo() { + btnMessage = lv_btn_create(lv_scr_act(), nullptr); + btnMessage->user_data = this; + lv_obj_set_event_cb(btnMessage, btnEventHandler); + lv_obj_set_height(btnMessage, 200); + lv_obj_set_width(btnMessage, 150); + lv_obj_align(btnMessage, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); + txtMessage = lv_label_create(btnMessage, nullptr); + lv_obj_set_style_local_bg_color(btnMessage, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_NAVY); + + if (alarmController.State() == AlarmController::AlarmState::Set) { + auto timeToAlarm = alarmController.SecondsToAlarm(); + + auto daysToAlarm = timeToAlarm / 86400; + auto hrsToAlarm = (timeToAlarm % 86400) / 3600; + auto minToAlarm = (timeToAlarm % 3600) / 60; + auto secToAlarm = timeToAlarm % 60; + + lv_label_set_text_fmt( + txtMessage, "Time to\nalarm:\n%2d Days\n%2d Hours\n%2d Minutes\n%2d Seconds", daysToAlarm, hrsToAlarm, minToAlarm, secToAlarm); + } else { + lv_label_set_text(txtMessage, "Alarm\nis not\nset."); + } +} + +void Alarm::setRecurButtonState() { + using Pinetime::Controllers::AlarmController; + switch (alarmController.Recurrence()) { + case AlarmController::RecurType::None: + lv_label_set_text(txtRecur, "ONCE"); + break; + case AlarmController::RecurType::Daily: + lv_label_set_text(txtRecur, "DAILY"); + break; + case AlarmController::RecurType::Weekdays: + lv_label_set_text(txtRecur, "WKDAYS"); + } +} \ No newline at end of file diff --git a/src/displayapp/screens/Alarm.h b/src/displayapp/screens/Alarm.h new file mode 100644 index 0000000000..30bcb73eed --- /dev/null +++ b/src/displayapp/screens/Alarm.h @@ -0,0 +1,31 @@ +#pragma once + +#include "Screen.h" +#include "systemtask/SystemTask.h" +#include "../LittleVgl.h" +#include "components/alarm/AlarmController.h" + +namespace Pinetime::Applications::Screens { + class Alarm : public Screen { + public: + Alarm(DisplayApp* app, Controllers::AlarmController& alarmController); + ~Alarm() override; + void SetAlerting(); + void OnButtonEvent(lv_obj_t* obj, lv_event_t event); + + private: + bool running; + uint8_t alarmHours = 0; + uint8_t alarmMinutes = 0; + Controllers::AlarmController& alarmController; + + lv_obj_t *time, *btnEnable, *txtEnable, *btnMinutesUp, *btnMinutesDown, *btnHoursUp, *btnHoursDown, *txtMinUp, *txtMinDown, *txtHrUp, + *txtHrDown, *btnRecur, *txtRecur, *btnMessage, *txtMessage, *btnInfo, *txtInfo; + + enum class EnableButtonState { On, Off, Alerting }; + void setEnableButtonState(); + void setRecurButtonState(); + void setAlarm(); + void showInfo(); + }; +} \ No newline at end of file diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp index 6e7bbb74d1..5c582f6014 100644 --- a/src/displayapp/screens/ApplicationList.cpp +++ b/src/displayapp/screens/ApplicationList.cpp @@ -58,7 +58,7 @@ std::unique_ptr ApplicationList::CreateScreen2() { {"2", Apps::Twos}, {Symbols::chartLine, Apps::Motion}, {Symbols::drum, Apps::Metronome}, - {"", Apps::None}, + {Symbols::clock, Apps::Alarm}, }}; return std::make_unique(1, 2, app, settingsController, batteryController, dateTimeController, applications); diff --git a/src/main.cpp b/src/main.cpp index 79e2ad8692..6a7f5eb342 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -119,6 +119,7 @@ Pinetime::Drivers::WatchdogView watchdogView(watchdog); Pinetime::Controllers::NotificationManager notificationManager; Pinetime::Controllers::MotionController motionController; Pinetime::Controllers::TimerController timerController; +Pinetime::Controllers::AlarmController alarmController {dateTimeController}; Pinetime::Controllers::TouchHandler touchHandler(touchPanel, lvgl); Pinetime::Controllers::FS fs {spiNorFlash}; @@ -139,6 +140,7 @@ Pinetime::Applications::DisplayApp displayApp(lcd, motorController, motionController, timerController, + alarmController, touchHandler); Pinetime::System::SystemTask systemTask(spi, @@ -151,6 +153,7 @@ Pinetime::System::SystemTask systemTask(spi, bleController, dateTimeController, timerController, + alarmController, watchdog, notificationManager, motorController, diff --git a/src/systemtask/Messages.h b/src/systemtask/Messages.h index 3a195e2d41..93fcf9407a 100644 --- a/src/systemtask/Messages.h +++ b/src/systemtask/Messages.h @@ -20,7 +20,9 @@ namespace Pinetime { EnableSleeping, DisableSleeping, OnNewDay, - OnChargingEvent + OnChargingEvent, + SetOffAlarm, + StopRinging }; } } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 0617b0ced0..98685c316f 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -57,6 +57,7 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, Controllers::TimerController& timerController, + Controllers::AlarmController& alarmController, Drivers::Watchdog& watchdog, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::MotorController& motorController, @@ -79,6 +80,7 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, bleController {bleController}, dateTimeController {dateTimeController}, timerController {timerController}, + alarmController {alarmController}, watchdog {watchdog}, notificationManager {notificationManager}, motorController {motorController}, @@ -132,6 +134,8 @@ void SystemTask::Work() { motionSensor.SoftReset(); timerController.Register(this); timerController.Init(); + alarmController.Register(this); + alarmController.Init(); // Reset the TWI device because the motion sensor chip most probably crashed it... twiMaster.Sleep(); @@ -275,6 +279,16 @@ void SystemTask::Work() { motorController.RunForDuration(35); displayApp.PushMessage(Pinetime::Applications::Display::Messages::TimerDone); break; + case Messages::SetOffAlarm: + if (isSleeping && !isWakingUp) { + GoToRunning(); + } + motorController.StartRingingDisregardSettings(); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::AlarmTriggered); + break; + case Messages::StopRinging: + motorController.StopRinging(); + break; case Messages::BleConnected: ReloadIdleTimer(); isBleDiscoveryTimerRunning = true; diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index 0266ba8a06..cbd98d26cd 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -16,6 +16,7 @@ #include "components/ble/NotificationManager.h" #include "components/motor/MotorController.h" #include "components/timer/TimerController.h" +#include "components/alarm/AlarmController.h" #include "components/fs/FS.h" #include "touchhandler/TouchHandler.h" @@ -56,6 +57,7 @@ namespace Pinetime { Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, Controllers::TimerController& timerController, + Controllers::AlarmController& alarmController, Drivers::Watchdog& watchdog, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::MotorController& motorController, @@ -100,6 +102,7 @@ namespace Pinetime { Pinetime::Controllers::Ble& bleController; Pinetime::Controllers::DateTime& dateTimeController; Pinetime::Controllers::TimerController& timerController; + Pinetime::Controllers::AlarmController& alarmController; QueueHandle_t systemTasksMsgQueue; std::atomic isSleeping {false}; std::atomic isGoingToSleep {false}; From e614af1c4a53e943256b3b2acee4bfe7d7204bbf Mon Sep 17 00:00:00 2001 From: hubmartin Date: Mon, 13 Sep 2021 11:41:51 +0200 Subject: [PATCH 31/40] Add WATCH_COLMI_P8 option to cmake & docs --- CMakeLists.txt | 9 +++++++++ doc/buildAndProgram.md | 1 + 2 files changed, 10 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index cc41a08744..f2402e5790 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,14 @@ if(BUILD_DFU) set(BUILD_DFU true) endif() +option(WATCH_COLMI_P8 "Build for the Colmi P8" OFF) +set(TARGET_DEVICE "PineTime") + +if(WATCH_COLMI_P8) + set(TARGET_DEVICE "Colmi P8") + add_definitions(-DWATCH_P8) +endif() + set(PROJECT_GIT_COMMIT_HASH "") execute_process(COMMAND git rev-parse --short HEAD @@ -68,6 +76,7 @@ message(" * Version : " ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${P message(" * Toolchain : " ${ARM_NONE_EABI_TOOLCHAIN_PATH}) message(" * GitRef(S) : " ${PROJECT_GIT_COMMIT_HASH}) message(" * NRF52 SDK : " ${NRF5_SDK_PATH}) +message(" * Target device : " ${TARGET_DEVICE}) set(PROGRAMMER "???") if(USE_JLINK) message(" * Programmer/debugger : JLINK") diff --git a/doc/buildAndProgram.md b/doc/buildAndProgram.md index 87b6dd9a5d..e97bb30d51 100644 --- a/doc/buildAndProgram.md +++ b/doc/buildAndProgram.md @@ -28,6 +28,7 @@ CMake configures the project according to variables you specify the command line **GDB_CLIENT_BIN_PATH**|Path to arm-none-eabi-gdb executable. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_BIN_PATH=/home/jf/nrf52/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-gdb` **GDB_CLIENT_TARGET_REMOTE**|Target remote connection string. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_TARGET_REMOTE=/dev/ttyACM0` **BUILD_DFU (\*\*)**|Build DFU files while building (needs [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil)).|`-DBUILD_DFU=1` +**WATCH_COLMI_P8**|Use pin configuration for Colmi P8 watch|`-DWATCH_COLMI_P8=1` ####(**) Note about **CMAKE_BUILD_TYPE**: By default, this variable is set to *Release*. It compiles the code with size and speed optimizations. We use this value for all the binaries we publish when we [release](https://github.com/JF002/InfiniTime/releases) new versions of InfiniTime. From 84a93b54410681ce1aaae80ba7a7e6d3300dcfa1 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Tue, 14 Sep 2021 04:02:53 +1000 Subject: [PATCH 32/40] docs: Fix a few typos (#606) * docs: Fix a few typos There are small typos in: - doc/versioning.md - src/components/ble/NimbleController.cpp - src/libs/mynewt-nimble/CODING_STANDARDS.md - src/libs/mynewt-nimble/docs/btshell/btshell_GAP.rst - src/systemtask/SystemTask.cpp Fixes: - Should read `milliseconds` rather than `miliseconds`. - Should read `unnecessary` rather than `uncesseray`. - Should read `target` rather than `tharget`. - Should read `project` rather than `projct`. - Should read `preferred` rather than `prefered`. - Should read `functioning` rather than `functionning`. - Should read `forever` rather than `forver`. - Should read `existing` rather than `exisiting`. --- cmake-nRF5x/readme.md | 2 +- doc/versioning.md | 2 +- src/components/ble/NimbleController.cpp | 2 +- src/systemtask/SystemTask.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake-nRF5x/readme.md b/cmake-nRF5x/readme.md index 2ce76892db..0127a2e6e5 100755 --- a/cmake-nRF5x/readme.md +++ b/cmake-nRF5x/readme.md @@ -98,7 +98,7 @@ The script makes use of the following tools: After setup you can use cmake as usual: -1. Generate the actual build files (out-of-source builds are strongly recomended): +1. Generate the actual build files (out-of-source builds are strongly recommended): ```commandline cmake -H. -B"cmake-build" -G "Unix Makefiles" diff --git a/doc/versioning.md b/doc/versioning.md index b08af71479..48e05043f0 100644 --- a/doc/versioning.md +++ b/doc/versioning.md @@ -3,4 +3,4 @@ The versioning of this project is based on [Semantic versionning](https://semver - 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 + - 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 functioning firmware suited for the final user. \ No newline at end of file diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 5eb227bf00..bde9b076cb 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -126,7 +126,7 @@ void NimbleController::StartAdvertising() { // ASSERT(res == 0);// TODO I've disabled these ASSERT as they sometime asserts and reset the mcu. // For now, the advertising is restarted as soon as it ends. There may be a race condition // that prevent the advertising from restarting reliably. - // I remove the assert to prevent this uncesseray crash, but in the long term, the management of + // I remove the assert to prevent this unnecessary crash, but in the long term, the management of // the advertising should be improve (better error handling, and advertise for 3 minutes after // the application has been woken up, for example. } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index d9434b3496..690a453da4 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -350,7 +350,7 @@ void SystemTask::Work() { if (bleDiscoveryTimer == 0) { isBleDiscoveryTimerRunning = false; // Services discovery is deffered from 3 seconds to avoid the conflicts between the host communicating with the - // tharget and vice-versa. I'm not sure if this is the right way to handle this... + // target and vice-versa. I'm not sure if this is the right way to handle this... nimbleController.StartDiscovery(); } else { bleDiscoveryTimer--; From 6356c7f276d09ab32d6f1c1338dac0b00a602232 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Milants?= Date: Mon, 13 Sep 2021 20:35:51 +0200 Subject: [PATCH 33/40] Fix DisplayAppRecovery : fix include error by forward declaring Controllers in header file. --- src/displayapp/DisplayAppRecovery.cpp | 1 + src/displayapp/DisplayAppRecovery.h | 32 ++++++++++++++++----------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index 17612ef057..7a20262988 100644 --- a/src/displayapp/DisplayAppRecovery.cpp +++ b/src/displayapp/DisplayAppRecovery.cpp @@ -5,6 +5,7 @@ #include #include #include "displayapp/icons/infinitime/infinitime-nb.c" +#include "components/ble/BleController.h" using namespace Pinetime::Applications; diff --git a/src/displayapp/DisplayAppRecovery.h b/src/displayapp/DisplayAppRecovery.h index 8b2bc7f515..4184ea49da 100644 --- a/src/displayapp/DisplayAppRecovery.h +++ b/src/displayapp/DisplayAppRecovery.h @@ -6,32 +6,38 @@ #include #include #include "components/gfx/Gfx.h" -#include "components/battery/BatteryController.h" -#include "components/brightness/BrightnessController.h" -#include "components/ble/BleController.h" -#include "components/datetime/DateTimeController.h" -#include "components/ble/NotificationManager.h" -#include "components/firmwarevalidator/FirmwareValidator.h" #include "drivers/Cst816s.h" #include #include -#include -#include #include -#include #include "TouchEvents.h" #include "Apps.h" #include "Messages.h" #include "DummyLittleVgl.h" -#include "components/timer/TimerController.h" namespace Pinetime { - namespace System { - class SystemTask; - }; + namespace Drivers { + class St7789; + class Cst816S; + class WatchdogView; + } namespace Controllers { + class Settings; + class Battery; + class Ble; + class DateTime; + class NotificationManager; + class HeartRateController; + class MotionController; class TouchHandler; + class MotorController; + class TimerController; } + + namespace System { + class SystemTask; + }; + namespace Applications { class DisplayApp { public: From bfe13d9d6849cf37f2d5a011990af85a1b503672 Mon Sep 17 00:00:00 2001 From: Mark Russell Date: Mon, 13 Sep 2021 15:26:28 -0400 Subject: [PATCH 34/40] Fixes based on code reviews (formatting, UI code) --- src/components/alarm/AlarmController.cpp | 49 ++++++------- src/components/alarm/AlarmController.h | 26 +++++-- src/displayapp/screens/Alarm.cpp | 88 +++++++++++++++--------- src/displayapp/screens/Alarm.h | 56 ++++++++++----- src/systemtask/SystemTask.cpp | 3 +- 5 files changed, 133 insertions(+), 89 deletions(-) diff --git a/src/components/alarm/AlarmController.cpp b/src/components/alarm/AlarmController.cpp index 5097936f59..31a3191263 100644 --- a/src/components/alarm/AlarmController.cpp +++ b/src/components/alarm/AlarmController.cpp @@ -1,8 +1,16 @@ -// -// Created by mrussell on 30.08.21. -// -// Copied from Florian's Timer app - +/* Copyright (C) 2021 JF, Adam Pigg, Avamander + This file is part of InfiniTime. + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ #include "AlarmController.h" #include "systemtask/SystemTask.h" #include "app_timer.h" @@ -25,18 +33,19 @@ namespace { } } -void AlarmController::Init() { +void AlarmController::Init(System::SystemTask* systemTask) { app_timer_create(&alarmAppTimer, APP_TIMER_MODE_SINGLE_SHOT, SetOffAlarm); + this->systemTask = systemTask; } void AlarmController::SetAlarm(uint8_t alarmHr, uint8_t alarmMin) { hours = alarmHr; minutes = alarmMin; state = AlarmState::Set; - scheduleAlarm(); + ScheduleAlarm(); } -void AlarmController::scheduleAlarm() { +void AlarmController::ScheduleAlarm() { // Determine the next time the alarm needs to go off and set the app_timer app_timer_stop(alarmAppTimer); @@ -83,15 +92,11 @@ void AlarmController::DisableAlarm() { void AlarmController::SetOffAlarmNow() { state = AlarmState::Alerting; - if (systemTask != nullptr) { - systemTask->PushMessage(System::Messages::SetOffAlarm); - } + systemTask->PushMessage(System::Messages::SetOffAlarm); } void AlarmController::StopAlerting() { - if (systemTask != nullptr) { - systemTask->PushMessage(System::Messages::StopRinging); - } + systemTask->PushMessage(System::Messages::StopRinging); // Alarm state is off unless this is a recurring alarm if (recurrence == RecurType::None) { @@ -99,20 +104,6 @@ void AlarmController::StopAlerting() { } else { state = AlarmState::Set; // set next instance - scheduleAlarm(); + ScheduleAlarm(); } } - -void AlarmController::ToggleRecurrence() { - if (recurrence == AlarmController::RecurType::None) { - recurrence = AlarmController::RecurType::Daily; - } else if (recurrence == AlarmController::RecurType::Daily) { - recurrence = AlarmController::RecurType::Weekdays; - } else { - recurrence = AlarmController::RecurType::None; - } -} - -void AlarmController::Register(Pinetime::System::SystemTask* systemTask) { - this->systemTask = systemTask; -} diff --git a/src/components/alarm/AlarmController.h b/src/components/alarm/AlarmController.h index 22259da820..140c9c8042 100644 --- a/src/components/alarm/AlarmController.h +++ b/src/components/alarm/AlarmController.h @@ -1,3 +1,16 @@ +/* Copyright (C) 2021 JF, Adam Pigg, Avamander + This file is part of InfiniTime. + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ #pragma once #include @@ -13,16 +26,14 @@ namespace Pinetime { public: AlarmController(Controllers::DateTime& dateTimeController); - void Init(); + void Init(System::SystemTask* systemTask); void SetAlarm(uint8_t alarmHr, uint8_t alarmMin); void DisableAlarm(); void SetOffAlarmNow(); uint32_t SecondsToAlarm(); void StopAlerting(); - void Register(System::SystemTask* systemTask); enum class AlarmState { Not_Set, Set, Alerting }; enum class RecurType { None, Daily, Weekdays }; - void ToggleRecurrence(); uint8_t Hours() const { return hours; } @@ -35,6 +46,9 @@ namespace Pinetime { RecurType Recurrence() const { return recurrence; } + void SetRecurrence(RecurType recurType) { + recurrence = recurType; + } private: Controllers::DateTime& dateTimeController; @@ -42,9 +56,9 @@ namespace Pinetime { uint8_t hours; uint8_t minutes; std::chrono::time_point alarmTime; - AlarmState state = AlarmState::Not_Set; + AlarmState state = AlarmState::Not_Set; RecurType recurrence = RecurType::None; - void scheduleAlarm(); + void ScheduleAlarm(); }; } -} \ No newline at end of file +} diff --git a/src/displayapp/screens/Alarm.cpp b/src/displayapp/screens/Alarm.cpp index e122cabd02..a2bb5c625a 100644 --- a/src/displayapp/screens/Alarm.cpp +++ b/src/displayapp/screens/Alarm.cpp @@ -1,3 +1,16 @@ +/* Copyright (C) 2021 JF, Adam Pigg, Avamander + This file is part of InfiniTime. + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ #include "Alarm.h" #include "Screen.h" #include "Symbols.h" @@ -21,66 +34,61 @@ Alarm::Alarm(DisplayApp* app, Controllers::AlarmController& alarmController) alarmMinutes = alarmController.Minutes(); lv_label_set_text_fmt(time, "%02lu:%02lu", alarmHours, alarmMinutes); - lv_obj_align(time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -20); + lv_obj_align(time, lv_scr_act(), LV_ALIGN_CENTER, 0, -25); btnHoursUp = lv_btn_create(lv_scr_act(), nullptr); btnHoursUp->user_data = this; lv_obj_set_event_cb(btnHoursUp, btnEventHandler); - lv_obj_align(btnHoursUp, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 20, -80); - lv_obj_set_height(btnHoursUp, 40); - lv_obj_set_width(btnHoursUp, 60); + lv_obj_set_size(btnHoursUp, 60, 40); + lv_obj_align(btnHoursUp, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 20, -85); txtHrUp = lv_label_create(btnHoursUp, nullptr); lv_label_set_text(txtHrUp, "+"); btnHoursDown = lv_btn_create(lv_scr_act(), nullptr); btnHoursDown->user_data = this; lv_obj_set_event_cb(btnHoursDown, btnEventHandler); - lv_obj_align(btnHoursDown, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 20, +40); - lv_obj_set_height(btnHoursDown, 40); - lv_obj_set_width(btnHoursDown, 60); + lv_obj_set_size(btnHoursDown, 60, 40); + lv_obj_align(btnHoursDown, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 20, 35); txtHrDown = lv_label_create(btnHoursDown, nullptr); lv_label_set_text(txtHrDown, "-"); btnMinutesUp = lv_btn_create(lv_scr_act(), nullptr); btnMinutesUp->user_data = this; lv_obj_set_event_cb(btnMinutesUp, btnEventHandler); - lv_obj_align(btnMinutesUp, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, 10, -80); - lv_obj_set_height(btnMinutesUp, 40); - lv_obj_set_width(btnMinutesUp, 60); + lv_obj_set_size(btnMinutesUp, 60, 40); + lv_obj_align(btnMinutesUp, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -20, -85); txtMinUp = lv_label_create(btnMinutesUp, nullptr); lv_label_set_text(txtMinUp, "+"); btnMinutesDown = lv_btn_create(lv_scr_act(), nullptr); btnMinutesDown->user_data = this; lv_obj_set_event_cb(btnMinutesDown, btnEventHandler); - lv_obj_align(btnMinutesDown, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, 10, +40); - lv_obj_set_height(btnMinutesDown, 40); - lv_obj_set_width(btnMinutesDown, 60); + lv_obj_set_size(btnMinutesDown, 60, 40); + lv_obj_align(btnMinutesDown, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -20, 35); txtMinDown = lv_label_create(btnMinutesDown, nullptr); lv_label_set_text(txtMinDown, "-"); btnEnable = lv_btn_create(lv_scr_act(), nullptr); btnEnable->user_data = this; lv_obj_set_event_cb(btnEnable, btnEventHandler); - lv_obj_align(btnEnable, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 3, -10); - lv_obj_set_height(btnEnable, 40); + lv_obj_set_size(btnEnable, 115, 50); + lv_obj_align(btnEnable, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); txtEnable = lv_label_create(btnEnable, nullptr); - setEnableButtonState(); + SetEnableButtonState(); btnRecur = lv_btn_create(lv_scr_act(), nullptr); btnRecur->user_data = this; lv_obj_set_event_cb(btnRecur, btnEventHandler); - lv_obj_align(btnRecur, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -3, -10); - lv_obj_set_height(btnRecur, 40); + lv_obj_set_size(btnRecur, 115, 50); + lv_obj_align(btnRecur, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); txtRecur = lv_label_create(btnRecur, nullptr); - setRecurButtonState(); + SetRecurButtonState(); btnInfo = lv_btn_create(lv_scr_act(), nullptr); btnInfo->user_data = this; lv_obj_set_event_cb(btnInfo, btnEventHandler); - lv_obj_align(btnInfo, lv_scr_act(), LV_ALIGN_CENTER, 30, -80); - lv_obj_set_height(btnInfo, 40); - lv_obj_set_width(btnInfo, 30); + lv_obj_set_size(btnInfo, 50, 40); + lv_obj_align(btnInfo, lv_scr_act(), LV_ALIGN_CENTER, 0, -85); txtInfo = lv_label_create(btnInfo, nullptr); lv_label_set_text(txtInfo, "i"); } @@ -100,11 +108,11 @@ void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { } else { alarmController.SetAlarm(alarmHours, alarmMinutes); } - setEnableButtonState(); + SetEnableButtonState(); return; } if (obj == btnInfo) { - showInfo(); + ShowInfo(); return; } if (obj == btnMessage) { @@ -120,7 +128,7 @@ void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { // can just do it once when the alarm is re-enabled if (alarmController.State() == AlarmController::AlarmState::Set) { alarmController.DisableAlarm(); - setEnableButtonState(); + SetEnableButtonState(); } if (obj == btnMinutesUp) { if (alarmMinutes >= 59) { @@ -159,17 +167,16 @@ void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { return; } if (obj == btnRecur) { - alarmController.ToggleRecurrence(); - setRecurButtonState(); + ToggleRecurrence(); } } } void Alarm::SetAlerting() { - setEnableButtonState(); + SetEnableButtonState(); } -void Alarm::setEnableButtonState() { +void Alarm::SetEnableButtonState() { switch (alarmController.State()) { case AlarmController::AlarmState::Set: lv_label_set_text(txtEnable, "ON"); @@ -185,7 +192,7 @@ void Alarm::setEnableButtonState() { } } -void Alarm::showInfo() { +void Alarm::ShowInfo() { btnMessage = lv_btn_create(lv_scr_act(), nullptr); btnMessage->user_data = this; lv_obj_set_event_cb(btnMessage, btnEventHandler); @@ -210,7 +217,7 @@ void Alarm::showInfo() { } } -void Alarm::setRecurButtonState() { +void Alarm::SetRecurButtonState() { using Pinetime::Controllers::AlarmController; switch (alarmController.Recurrence()) { case AlarmController::RecurType::None: @@ -220,6 +227,21 @@ void Alarm::setRecurButtonState() { lv_label_set_text(txtRecur, "DAILY"); break; case AlarmController::RecurType::Weekdays: - lv_label_set_text(txtRecur, "WKDAYS"); + lv_label_set_text(txtRecur, "MON-FRI"); } -} \ No newline at end of file +} + +void Alarm::ToggleRecurrence() { + using Pinetime::Controllers::AlarmController; + switch (alarmController.Recurrence()) { + case AlarmController::RecurType::None: + alarmController.SetRecurrence(AlarmController::RecurType::Daily); + break; + case AlarmController::RecurType::Daily: + alarmController.SetRecurrence(AlarmController::RecurType::Weekdays); + break; + case AlarmController::RecurType::Weekdays: + alarmController.SetRecurrence(AlarmController::RecurType::None); + } + SetRecurButtonState(); +} diff --git a/src/displayapp/screens/Alarm.h b/src/displayapp/screens/Alarm.h index 30bcb73eed..43bbc6f2b4 100644 --- a/src/displayapp/screens/Alarm.h +++ b/src/displayapp/screens/Alarm.h @@ -1,3 +1,16 @@ +/* Copyright (C) 2021 JF, Adam Pigg, Avamander + This file is part of InfiniTime. + InfiniTime is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + InfiniTime is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ #pragma once #include "Screen.h" @@ -5,27 +18,32 @@ #include "../LittleVgl.h" #include "components/alarm/AlarmController.h" -namespace Pinetime::Applications::Screens { - class Alarm : public Screen { - public: - Alarm(DisplayApp* app, Controllers::AlarmController& alarmController); - ~Alarm() override; - void SetAlerting(); - void OnButtonEvent(lv_obj_t* obj, lv_event_t event); +namespace Pinetime { + namespace Applications { + namespace Screens { + class Alarm : public Screen { + public: + Alarm(DisplayApp* app, Controllers::AlarmController& alarmController); + ~Alarm() override; + void SetAlerting(); + void OnButtonEvent(lv_obj_t* obj, lv_event_t event); - private: - bool running; - uint8_t alarmHours = 0; - uint8_t alarmMinutes = 0; - Controllers::AlarmController& alarmController; + private: + bool running; + uint8_t alarmHours = 0; + uint8_t alarmMinutes = 0; + Controllers::AlarmController& alarmController; - lv_obj_t *time, *btnEnable, *txtEnable, *btnMinutesUp, *btnMinutesDown, *btnHoursUp, *btnHoursDown, *txtMinUp, *txtMinDown, *txtHrUp, - *txtHrDown, *btnRecur, *txtRecur, *btnMessage, *txtMessage, *btnInfo, *txtInfo; + lv_obj_t *time, *btnEnable, *txtEnable, *btnMinutesUp, *btnMinutesDown, *btnHoursUp, *btnHoursDown, *txtMinUp, *txtMinDown, + *txtHrUp, *txtHrDown, *btnRecur, *txtRecur, *btnMessage, *txtMessage, *btnInfo, *txtInfo; - enum class EnableButtonState { On, Off, Alerting }; - void setEnableButtonState(); - void setRecurButtonState(); - void setAlarm(); - void showInfo(); + enum class EnableButtonState { On, Off, Alerting }; + void SetEnableButtonState(); + void SetRecurButtonState(); + void SetAlarm(); + void ShowInfo(); + void ToggleRecurrence(); + }; + }; }; } \ No newline at end of file diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 98685c316f..9ec2059011 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -134,8 +134,7 @@ void SystemTask::Work() { motionSensor.SoftReset(); timerController.Register(this); timerController.Init(); - alarmController.Register(this); - alarmController.Init(); + alarmController.Init(this); // Reset the TWI device because the motion sensor chip most probably crashed it... twiMaster.Sleep(); From 2bf339a3f8319d68dfe657a53020c1f7977c4eb7 Mon Sep 17 00:00:00 2001 From: Mark Russell Date: Mon, 13 Sep 2021 16:05:35 -0400 Subject: [PATCH 35/40] License header fix, add missing braces --- src/components/alarm/AlarmController.cpp | 9 +++++++-- src/components/alarm/AlarmController.h | 6 +++++- src/displayapp/screens/Alarm.cpp | 6 +++++- src/displayapp/screens/Alarm.h | 6 +++++- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/components/alarm/AlarmController.cpp b/src/components/alarm/AlarmController.cpp index 31a3191263..2532a4a1c3 100644 --- a/src/components/alarm/AlarmController.cpp +++ b/src/components/alarm/AlarmController.cpp @@ -1,13 +1,17 @@ -/* Copyright (C) 2021 JF, Adam Pigg, Avamander +/* Copyright (C) 2021 mruss77, Florian + This file is part of InfiniTime. + InfiniTime is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + InfiniTime is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -28,8 +32,9 @@ APP_TIMER_DEF(alarmAppTimer); namespace { void SetOffAlarm(void* p_context) { auto* controller = static_cast(p_context); - if (controller != nullptr) + if (controller != nullptr) { controller->SetOffAlarmNow(); + } } } diff --git a/src/components/alarm/AlarmController.h b/src/components/alarm/AlarmController.h index 140c9c8042..7c43b89e0c 100644 --- a/src/components/alarm/AlarmController.h +++ b/src/components/alarm/AlarmController.h @@ -1,13 +1,17 @@ -/* Copyright (C) 2021 JF, Adam Pigg, Avamander +/* Copyright (C) 2021 mruss77, Florian + This file is part of InfiniTime. + InfiniTime is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + InfiniTime is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + You should have received a copy of the GNU General Public License along with this program. If not, see . */ diff --git a/src/displayapp/screens/Alarm.cpp b/src/displayapp/screens/Alarm.cpp index a2bb5c625a..70d95fe823 100644 --- a/src/displayapp/screens/Alarm.cpp +++ b/src/displayapp/screens/Alarm.cpp @@ -1,13 +1,17 @@ -/* Copyright (C) 2021 JF, Adam Pigg, Avamander +/* Copyright (C) 2021 mruss77, Florian + This file is part of InfiniTime. + InfiniTime is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + InfiniTime is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + You should have received a copy of the GNU General Public License along with this program. If not, see . */ diff --git a/src/displayapp/screens/Alarm.h b/src/displayapp/screens/Alarm.h index 43bbc6f2b4..b36f7f98d5 100644 --- a/src/displayapp/screens/Alarm.h +++ b/src/displayapp/screens/Alarm.h @@ -1,13 +1,17 @@ -/* Copyright (C) 2021 JF, Adam Pigg, Avamander +/* Copyright (C) 2021 mruss77, Florian + This file is part of InfiniTime. + InfiniTime is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + InfiniTime is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + You should have received a copy of the GNU General Public License along with this program. If not, see . */ From f89780f3323042ce9a83f78aa9017c56f0fb62e9 Mon Sep 17 00:00:00 2001 From: Reinhold Gschweicher Date: Mon, 13 Sep 2021 22:32:22 +0200 Subject: [PATCH 36/40] Remove unused include in MotoController.h Remove the unused include `app_timer.h` in `MotorController.h` --- src/components/motor/MotorController.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index 1d8fcc95a6..cf78088ec3 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -1,7 +1,6 @@ #pragma once #include -#include "app_timer.h" #include "components/settings/Settings.h" namespace Pinetime { From f857a757a7184726093a7085cdb3d74b728a22e4 Mon Sep 17 00:00:00 2001 From: Mark Russell Date: Thu, 16 Sep 2021 15:38:31 -0400 Subject: [PATCH 37/40] Fixes per Riksu9000's feedback --- src/components/alarm/AlarmController.cpp | 6 +++--- src/components/alarm/AlarmController.h | 8 +++---- src/components/motor/MotorController.cpp | 6 ------ src/components/motor/MotorController.h | 1 - src/displayapp/screens/Alarm.cpp | 27 +++++++++++++----------- src/displayapp/screens/Alarm.h | 7 +++--- src/systemtask/SystemTask.cpp | 2 +- 7 files changed, 27 insertions(+), 30 deletions(-) diff --git a/src/components/alarm/AlarmController.cpp b/src/components/alarm/AlarmController.cpp index 2532a4a1c3..67ca05a968 100644 --- a/src/components/alarm/AlarmController.cpp +++ b/src/components/alarm/AlarmController.cpp @@ -43,11 +43,9 @@ void AlarmController::Init(System::SystemTask* systemTask) { this->systemTask = systemTask; } -void AlarmController::SetAlarm(uint8_t alarmHr, uint8_t alarmMin) { +void AlarmController::SetAlarmTime(uint8_t alarmHr, uint8_t alarmMin) { hours = alarmHr; minutes = alarmMin; - state = AlarmState::Set; - ScheduleAlarm(); } void AlarmController::ScheduleAlarm() { @@ -84,6 +82,8 @@ void AlarmController::ScheduleAlarm() { alarmTime = std::chrono::system_clock::from_time_t(std::mktime(tmAlarmTime)); auto mSecToAlarm = std::chrono::duration_cast(alarmTime - now).count(); app_timer_start(alarmAppTimer, APP_TIMER_TICKS(mSecToAlarm), this); + + state = AlarmState::Set; } uint32_t AlarmController::SecondsToAlarm() { diff --git a/src/components/alarm/AlarmController.h b/src/components/alarm/AlarmController.h index 7c43b89e0c..bf85d43140 100644 --- a/src/components/alarm/AlarmController.h +++ b/src/components/alarm/AlarmController.h @@ -31,7 +31,8 @@ namespace Pinetime { AlarmController(Controllers::DateTime& dateTimeController); void Init(System::SystemTask* systemTask); - void SetAlarm(uint8_t alarmHr, uint8_t alarmMin); + void SetAlarmTime(uint8_t alarmHr, uint8_t alarmMin); + void ScheduleAlarm(); void DisableAlarm(); void SetOffAlarmNow(); uint32_t SecondsToAlarm(); @@ -57,12 +58,11 @@ namespace Pinetime { private: Controllers::DateTime& dateTimeController; System::SystemTask* systemTask = nullptr; - uint8_t hours; - uint8_t minutes; + uint8_t hours = 7; + uint8_t minutes = 0; std::chrono::time_point alarmTime; AlarmState state = AlarmState::Not_Set; RecurType recurrence = RecurType::None; - void ScheduleAlarm(); }; } } diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index 5ade19e44a..b25e6bc829 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -42,12 +42,6 @@ void MotorController::StartRinging() { app_timer_start(longVibTimer, APP_TIMER_TICKS(1000), this); } -// This function is the same as StartRinging(), but will ring even if notifications are turned off in Settings -void MotorController::StartRingingDisregardSettings() { - Ring(this); - app_timer_start(longVibTimer, APP_TIMER_TICKS(1000), this); -} - void MotorController::StopRinging() { app_timer_stop(longVibTimer); nrf_gpio_pin_set(pinMotor); diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index d3b96b07c2..d2c9fe5f2c 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -15,7 +15,6 @@ namespace Pinetime { void RunForDuration(uint8_t motorDuration); void StartRinging(); static void StopRinging(); - void StartRingingDisregardSettings(); private: static void Ring(void* p_context); diff --git a/src/displayapp/screens/Alarm.cpp b/src/displayapp/screens/Alarm.cpp index 70d95fe823..959cb0b26d 100644 --- a/src/displayapp/screens/Alarm.cpp +++ b/src/displayapp/screens/Alarm.cpp @@ -46,7 +46,7 @@ Alarm::Alarm(DisplayApp* app, Controllers::AlarmController& alarmController) lv_obj_set_size(btnHoursUp, 60, 40); lv_obj_align(btnHoursUp, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 20, -85); txtHrUp = lv_label_create(btnHoursUp, nullptr); - lv_label_set_text(txtHrUp, "+"); + lv_label_set_text_static(txtHrUp, "+"); btnHoursDown = lv_btn_create(lv_scr_act(), nullptr); btnHoursDown->user_data = this; @@ -54,7 +54,7 @@ Alarm::Alarm(DisplayApp* app, Controllers::AlarmController& alarmController) lv_obj_set_size(btnHoursDown, 60, 40); lv_obj_align(btnHoursDown, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 20, 35); txtHrDown = lv_label_create(btnHoursDown, nullptr); - lv_label_set_text(txtHrDown, "-"); + lv_label_set_text_static(txtHrDown, "-"); btnMinutesUp = lv_btn_create(lv_scr_act(), nullptr); btnMinutesUp->user_data = this; @@ -62,7 +62,7 @@ Alarm::Alarm(DisplayApp* app, Controllers::AlarmController& alarmController) lv_obj_set_size(btnMinutesUp, 60, 40); lv_obj_align(btnMinutesUp, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -20, -85); txtMinUp = lv_label_create(btnMinutesUp, nullptr); - lv_label_set_text(txtMinUp, "+"); + lv_label_set_text_static(txtMinUp, "+"); btnMinutesDown = lv_btn_create(lv_scr_act(), nullptr); btnMinutesDown->user_data = this; @@ -70,7 +70,7 @@ Alarm::Alarm(DisplayApp* app, Controllers::AlarmController& alarmController) lv_obj_set_size(btnMinutesDown, 60, 40); lv_obj_align(btnMinutesDown, lv_scr_act(), LV_ALIGN_IN_RIGHT_MID, -20, 35); txtMinDown = lv_label_create(btnMinutesDown, nullptr); - lv_label_set_text(txtMinDown, "-"); + lv_label_set_text_static(txtMinDown, "-"); btnEnable = lv_btn_create(lv_scr_act(), nullptr); btnEnable->user_data = this; @@ -94,7 +94,7 @@ Alarm::Alarm(DisplayApp* app, Controllers::AlarmController& alarmController) lv_obj_set_size(btnInfo, 50, 40); lv_obj_align(btnInfo, lv_scr_act(), LV_ALIGN_CENTER, 0, -85); txtInfo = lv_label_create(btnInfo, nullptr); - lv_label_set_text(txtInfo, "i"); + lv_label_set_text_static(txtInfo, "i"); } Alarm::~Alarm() { @@ -110,7 +110,7 @@ void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { } else if (alarmController.State() == AlarmController::AlarmState::Set) { alarmController.DisableAlarm(); } else { - alarmController.SetAlarm(alarmHours, alarmMinutes); + alarmController.ScheduleAlarm(); } SetEnableButtonState(); return; @@ -128,8 +128,6 @@ void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { } // If any other button was pressed, disable the alarm // this is to make it clear that the alarm won't be set until it is turned back on - // this avoids calling the AlarmController to change the alarm time every time the user hits minute-up or minute-down; - // can just do it once when the alarm is re-enabled if (alarmController.State() == AlarmController::AlarmState::Set) { alarmController.DisableAlarm(); SetEnableButtonState(); @@ -140,7 +138,7 @@ void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { } else { alarmMinutes++; } - lv_label_set_text_fmt(time, "%02d:%02d", alarmHours, alarmMinutes); + UpdateAlarmTime(); return; } if (obj == btnMinutesDown) { @@ -149,7 +147,7 @@ void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { } else { alarmMinutes--; } - lv_label_set_text_fmt(time, "%02d:%02d", alarmHours, alarmMinutes); + UpdateAlarmTime(); return; } if (obj == btnHoursUp) { @@ -158,7 +156,7 @@ void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { } else { alarmHours++; } - lv_label_set_text_fmt(time, "%02d:%02d", alarmHours, alarmMinutes); + UpdateAlarmTime(); return; } if (obj == btnHoursDown) { @@ -167,7 +165,7 @@ void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { } else { alarmHours--; } - lv_label_set_text_fmt(time, "%02d:%02d", alarmHours, alarmMinutes); + UpdateAlarmTime(); return; } if (obj == btnRecur) { @@ -176,6 +174,11 @@ void Alarm::OnButtonEvent(lv_obj_t* obj, lv_event_t event) { } } +void Alarm::UpdateAlarmTime() { + lv_label_set_text_fmt(time, "%02d:%02d", alarmHours, alarmMinutes); + alarmController.SetAlarmTime(alarmHours, alarmMinutes); +} + void Alarm::SetAlerting() { SetEnableButtonState(); } diff --git a/src/displayapp/screens/Alarm.h b/src/displayapp/screens/Alarm.h index b36f7f98d5..abf97ebaa1 100644 --- a/src/displayapp/screens/Alarm.h +++ b/src/displayapp/screens/Alarm.h @@ -34,8 +34,8 @@ namespace Pinetime { private: bool running; - uint8_t alarmHours = 0; - uint8_t alarmMinutes = 0; + uint8_t alarmHours; + uint8_t alarmMinutes; Controllers::AlarmController& alarmController; lv_obj_t *time, *btnEnable, *txtEnable, *btnMinutesUp, *btnMinutesDown, *btnHoursUp, *btnHoursDown, *txtMinUp, *txtMinDown, @@ -47,7 +47,8 @@ namespace Pinetime { void SetAlarm(); void ShowInfo(); void ToggleRecurrence(); + void UpdateAlarmTime(); }; }; }; -} \ No newline at end of file +} diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 9ec2059011..534f551092 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -282,7 +282,7 @@ void SystemTask::Work() { if (isSleeping && !isWakingUp) { GoToRunning(); } - motorController.StartRingingDisregardSettings(); + motorController.StartRinging(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::AlarmTriggered); break; case Messages::StopRinging: From 1d43adcdfa7bd15ba45c0c9d7c59c0ff99176b9c Mon Sep 17 00:00:00 2001 From: Mark Russell Date: Thu, 16 Sep 2021 16:01:25 -0400 Subject: [PATCH 38/40] Merge upstream --- .github/workflows/main.yml | 8 +- CMakeLists.txt | 9 ++ README.md | 25 ++-- cmake-nRF5x/readme.md | 2 +- doc/buildAndProgram.md | 1 + .../ota-gadgetbridge-nrfconnect.md | 8 ++ doc/versioning.md | 2 +- src/CMakeLists.txt | 12 +- src/components/battery/BatteryController.cpp | 16 ++- src/components/battery/BatteryController.h | 9 +- src/components/ble/NimbleController.cpp | 125 +++++++++++------- src/components/ble/NimbleController.h | 7 + .../brightness/BrightnessController.cpp | 32 ++--- .../brightness/BrightnessController.h | 3 - src/components/motor/MotorController.cpp | 11 +- src/components/motor/MotorController.h | 2 - src/components/settings/Settings.h | 2 +- src/displayapp/DisplayApp.cpp | 6 - src/displayapp/DisplayAppRecovery.cpp | 1 + src/displayapp/DisplayAppRecovery.h | 32 +++-- src/displayapp/Messages.h | 1 - src/displayapp/screens/BatteryInfo.cpp | 2 - src/displayapp/screens/Notifications.cpp | 2 +- src/displayapp/screens/Notifications.h | 8 -- src/displayapp/screens/settings/Settings.cpp | 4 +- src/drivers/Cst816s.cpp | 13 +- src/drivers/Cst816s.h | 3 - src/drivers/PinMap.h | 38 ++++++ src/main.cpp | 47 +++---- src/recoveryLoader.cpp | 19 +-- src/systemtask/Messages.h | 4 +- src/systemtask/SystemTask.cpp | 62 +++++---- src/systemtask/SystemTask.h | 16 +-- 33 files changed, 300 insertions(+), 232 deletions(-) create mode 100644 src/drivers/PinMap.h diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4744eaef7d..bd24359a56 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,13 +9,13 @@ name: Build PineTime Firmware # When to run this Workflow... on: - # Run this Workflow when files are updated (Pushed) in the "master" Branch + # Run this Workflow when files are updated (Pushed) in the "master" and "develop" Branch push: - branches: [ master ] + branches: [ master, develop ] - # Also run this Workflow when a Pull Request is created or updated in the "master" Branch + # Also run this Workflow when a Pull Request is created or updated in the "master" and "develop" Branch pull_request: - branches: [ master ] + branches: [ master, develop ] # Steps to run for the Workflow jobs: diff --git a/CMakeLists.txt b/CMakeLists.txt index cc41a08744..f2402e5790 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,14 @@ if(BUILD_DFU) set(BUILD_DFU true) endif() +option(WATCH_COLMI_P8 "Build for the Colmi P8" OFF) +set(TARGET_DEVICE "PineTime") + +if(WATCH_COLMI_P8) + set(TARGET_DEVICE "Colmi P8") + add_definitions(-DWATCH_P8) +endif() + set(PROJECT_GIT_COMMIT_HASH "") execute_process(COMMAND git rev-parse --short HEAD @@ -68,6 +76,7 @@ message(" * Version : " ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${P message(" * Toolchain : " ${ARM_NONE_EABI_TOOLCHAIN_PATH}) message(" * GitRef(S) : " ${PROJECT_GIT_COMMIT_HASH}) message(" * NRF52 SDK : " ${NRF5_SDK_PATH}) +message(" * Target device : " ${TARGET_DEVICE}) set(PROGRAMMER "???") if(USE_JLINK) message(" * Programmer/debugger : JLINK") diff --git a/README.md b/README.md index 6549ece98d..0d5cad934a 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,10 @@ -# PineTime +# InfiniTime [![Build PineTime Firmware](https://github.com/JF002/InfiniTime/workflows/Build%20PineTime%20Firmware/badge.svg?branch=master)](https://github.com/JF002/InfiniTime/actions) -> The PineTime is a free and open source smartwatch capable of running custom-built open operating systems. Some of the notable features include a heart rate monitor, a week-long battery as well as a capacitive touch IPS display that is legible in direct sunlight. It is a fully community driven side-project, which means that it will ultimately be up to the developers and end-users to determine when they deem the PineTime ready to ship. - -> We envision the PineTime as a companion for not only your PinePhone but also for your favorite devices — any phone, tablet, or even PC. - -*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 heart rate sensor, and a vibration motor. - -# InfiniTime - ![InfiniTime logo](images/infinitime-logo.jpg "InfiniTime Logo") -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](https://www.pine64.org/pinetime/) : - Code written in **modern C++**; - Build system based on **CMake**; @@ -22,6 +12,11 @@ The goal of this project is to design an open-source firmware for the Pinetime s - Using **[LittleVGL/LVGL 7](https://lvgl.io/)** as UI library... - ... and **[NimBLE 1.3.0](https://github.com/apache/mynewt-nimble)** as BLE stack. +## New to InfiniTime? + + - [Getting started with InfiniTime 1.0 (quick user guide, update bootloader and InfiniTime,...)](doc/gettingStarted/gettingStarted-1.0.md) + - [Flash, upgrade (OTA), time synchronization,...](doc/gettingStarted/ota-gadgetbridge-nrfconnect.md) + ## Overview ![Pinetime screens](images/1.0.0/collage.png "PinetimeScreens") @@ -70,16 +65,12 @@ As of now, here is the list of achievements of this project: * [Amazfish](https://openrepos.net/content/piggz/amazfish) (on SailfishOS and Linux) * [Siglo](https://github.com/alexr4535/siglo) (on Linux) * **[Experimental]** [WebBLEWatch](https://hubmartin.github.io/WebBLEWatch/) Synchronize time directly from your web browser. [video](https://youtu.be/IakiuhVDdrY) + * **[Experimental]** [Infini-iOS](https://github.com/xan-m/Infini-iOS) (on iOS) - OTA (Over-the-air) update via BLE - [Bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader) based on [MCUBoot](https://juullabs-oss.github.io/mcuboot/) ## Documentation -### Getting started - - - [Getting started with InfiniTime 1.0 (quick user guide, update bootloader and InfiniTime,...)](doc/gettingStarted/gettingStarted-1.0.md) - - [Flash, upgrade (OTA), time synchronization,...](doc/gettingStarted/ota-gadgetbridge-nrfconnect.md) - ### Develop - [Generate the fonts and symbols](src/displayapp/fonts/README.md) diff --git a/cmake-nRF5x/readme.md b/cmake-nRF5x/readme.md index 2ce76892db..0127a2e6e5 100755 --- a/cmake-nRF5x/readme.md +++ b/cmake-nRF5x/readme.md @@ -98,7 +98,7 @@ The script makes use of the following tools: After setup you can use cmake as usual: -1. Generate the actual build files (out-of-source builds are strongly recomended): +1. Generate the actual build files (out-of-source builds are strongly recommended): ```commandline cmake -H. -B"cmake-build" -G "Unix Makefiles" diff --git a/doc/buildAndProgram.md b/doc/buildAndProgram.md index 87b6dd9a5d..e97bb30d51 100644 --- a/doc/buildAndProgram.md +++ b/doc/buildAndProgram.md @@ -28,6 +28,7 @@ CMake configures the project according to variables you specify the command line **GDB_CLIENT_BIN_PATH**|Path to arm-none-eabi-gdb executable. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_BIN_PATH=/home/jf/nrf52/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-gdb` **GDB_CLIENT_TARGET_REMOTE**|Target remote connection string. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_TARGET_REMOTE=/dev/ttyACM0` **BUILD_DFU (\*\*)**|Build DFU files while building (needs [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil)).|`-DBUILD_DFU=1` +**WATCH_COLMI_P8**|Use pin configuration for Colmi P8 watch|`-DWATCH_COLMI_P8=1` ####(**) Note about **CMAKE_BUILD_TYPE**: By default, this variable is set to *Release*. It compiles the code with size and speed optimizations. We use this value for all the binaries we publish when we [release](https://github.com/JF002/InfiniTime/releases) new versions of InfiniTime. diff --git a/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md b/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md index 1187a9b745..ffc27ed87b 100644 --- a/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md +++ b/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md @@ -47,6 +47,8 @@ Read carefully the warning and tap **Install**: Wait for the transfer to finish. Your PineTime should reset and reboot with the new version of InfiniTime! +Don't forget to **validate** your firmware. In the InfiniTime go to the settings (swipe right, select gear icon) and Firmware option and click **validate**. Otherwise after reboot the previous firmware will be used. + ![Gadgetbridge 5](gadgetbridge5.jpg) ### Using NRFConnect @@ -64,6 +66,8 @@ Select **Distribution packet (ZIP)**: Browse to the DFU file you downloaded previously, the DFU transfer will start automatically. When the transfer is finished, your PineTime will reset and restart on the new version of InfiniTime! +Don't forget to **validate** your firmware. In the InfiniTime go to the settings (swipe right, select gear icon) and Firmware option and click **validate**. Otherwise after reboot the previous firmware will be used. + ![NRFConnect 3](nrfconnect3.jpg) ## How to flash InfiniTime using the SWD interface @@ -88,6 +92,10 @@ If you are using OpenOCD with a STLinkV2, you can find more info [on this page]( ### Using Gadgetbridge Good news! Gadgetbridge **automatically** synchronizes the time when connecting to your PineTime! +### Using any Chromium-based web browser +You can use it from your PC, Mac, Android. Browsers now have BLE support. +https://hubmartin.github.io/WebBLEWatch/ + ### Using NRFConnect You must enable the **CTS** *GATT server* into NRFConnect so that InfiniTime can synchronize the time with your smartphone. diff --git a/doc/versioning.md b/doc/versioning.md index b08af71479..48e05043f0 100644 --- a/doc/versioning.md +++ b/doc/versioning.md @@ -3,4 +3,4 @@ The versioning of this project is based on [Semantic versionning](https://semver - 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 + - 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 functioning firmware suited for the final user. \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ccade83e30..37ee0848bd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -92,6 +92,9 @@ set(SDK_SOURCE_FILES set(TINYCRYPT_SRC libs/mynewt-nimble/ext/tinycrypt/src/aes_encrypt.c libs/mynewt-nimble/ext/tinycrypt/src/utils.c + libs/mynewt-nimble/ext/tinycrypt/src/cmac_mode.c + libs/mynewt-nimble/ext/tinycrypt/src/ecc.c + libs/mynewt-nimble/ext/tinycrypt/src/ecc_dh.c ) set(NIMBLE_SRC @@ -104,6 +107,10 @@ set(NIMBLE_SRC libs/mynewt-nimble/nimble/host/src/ble_l2cap.c libs/mynewt-nimble/nimble/host/src/ble_hs_mbuf.c libs/mynewt-nimble/nimble/host/src/ble_sm.c + libs/mynewt-nimble/nimble/host/src/ble_sm_cmd.c + libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c + libs/mynewt-nimble/nimble/host/src/ble_sm_alg.c + libs/mynewt-nimble/nimble/host/src/ble_sm_sc.c libs/mynewt-nimble/nimble/host/src/ble_gap.c libs/mynewt-nimble/nimble/host/src/ble_gatts.c libs/mynewt-nimble/nimble/host/src/ble_gattc.c @@ -127,10 +134,6 @@ set(NIMBLE_SRC libs/mynewt-nimble/nimble/host/src/ble_hs_atomic.c libs/mynewt-nimble/nimble/host/src/ble_hs_adv.c libs/mynewt-nimble/nimble/host/src/ble_hs_flow.c - libs/mynewt-nimble/nimble/host/src/ble_sm.c - libs/mynewt-nimble/nimble/host/src/ble_sm_cmd.c - libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c - libs/mynewt-nimble/nimble/host/src/ble_sm_alg.c libs/mynewt-nimble/nimble/host/src/ble_hs_mqueue.c libs/mynewt-nimble/nimble/host/src/ble_hs_stop.c libs/mynewt-nimble/nimble/host/src/ble_hs_startup.c @@ -625,6 +628,7 @@ set(INCLUDE_FILES drivers/DebugPins.h drivers/InternalFlash.h drivers/Hrs3300.h + drivers/PinMap.h drivers/Bma421.h drivers/Bma421_C/bma4.c drivers/Bma421_C/bma423.c diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index f8a64ecd18..4ef20a2452 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -1,4 +1,5 @@ #include "BatteryController.h" +#include "drivers/PinMap.h" #include #include #include @@ -9,15 +10,12 @@ Battery* Battery::instance = nullptr; Battery::Battery() { instance = this; -} - -void Battery::Init() { - nrf_gpio_cfg_input(chargingPin, static_cast GPIO_PIN_CNF_PULL_Pullup); + nrf_gpio_cfg_input(PinMap::Charging, static_cast GPIO_PIN_CNF_PULL_Disabled); } void Battery::Update() { - isCharging = !nrf_gpio_pin_read(chargingPin); - isPowerPresent = !nrf_gpio_pin_read(powerPresentPin); + isCharging = !nrf_gpio_pin_read(PinMap::Charging); + isPowerPresent = !nrf_gpio_pin_read(PinMap::PowerPresent); if (isReading) { return; @@ -75,5 +73,11 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { nrfx_saadc_uninit(); isReading = false; + + systemTask->PushMessage(System::Messages::BatteryMeasurementDone); } } + +void Battery::Register(Pinetime::System::SystemTask* systemTask) { + this->systemTask = systemTask; +} diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 6f09b737a3..8af27ea8ae 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -1,8 +1,7 @@ #pragma once #include #include -#include -#include +#include namespace Pinetime { namespace Controllers { @@ -11,8 +10,8 @@ namespace Pinetime { public: Battery(); - void Init(); void Update(); + void Register(System::SystemTask* systemTask); uint8_t PercentRemaining() const { return percentRemaining; @@ -34,8 +33,6 @@ namespace Pinetime { static Battery* instance; nrf_saadc_value_t saadc_value; - static constexpr uint32_t chargingPin = 12; - static constexpr uint32_t powerPresentPin = 19; static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7; uint16_t voltage = 0; uint8_t percentRemaining = 0; @@ -49,6 +46,8 @@ namespace Pinetime { static void AdcCallbackStatic(nrfx_saadc_evt_t const* event); bool isReading = false; + + Pinetime::System::SystemTask* systemTask = nullptr; }; } } diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 5eb227bf00..879421e7aa 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -42,6 +42,19 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, serviceDiscovery({¤tTimeClient, &alertNotificationClient}) { } +void nimble_on_reset(int reason) { + NRF_LOG_INFO("Resetting state; reason=%d\n", reason); +} + +void nimble_on_sync(void) { + int rc; + + rc = ble_hs_util_ensure_addr(0); + ASSERT(rc == 0); + + nptr->StartAdvertising(); +} + int GAPEventCallback(struct ble_gap_event* event, void* arg) { auto nimbleController = static_cast(arg); return nimbleController->OnGAPEvent(event); @@ -51,6 +64,10 @@ void NimbleController::Init() { while (!ble_hs_synced()) { } + nptr = this; + ble_hs_cfg.reset_cb = nimble_on_reset; + ble_hs_cfg.sync_cb = nimble_on_sync; + ble_svc_gap_init(); ble_svc_gatt_init(); @@ -64,28 +81,31 @@ void NimbleController::Init() { batteryInformationService.Init(); immediateAlertService.Init(); heartRateService.Init(); - int res; - res = ble_hs_util_ensure_addr(0); - ASSERT(res == 0); - res = ble_hs_id_infer_auto(0, &addrType); - ASSERT(res == 0); - res = ble_svc_gap_device_name_set(deviceName); - ASSERT(res == 0); + + int rc; + rc = ble_hs_util_ensure_addr(0); + ASSERT(rc == 0); + rc = ble_hs_id_infer_auto(0, &addrType); + ASSERT(rc == 0); + rc = ble_svc_gap_device_name_set(deviceName); + ASSERT(rc == 0); + rc = ble_svc_gap_device_appearance_set(0xC2); + ASSERT(rc == 0); Pinetime::Controllers::Ble::BleAddress address; - res = ble_hs_id_copy_addr(addrType, address.data(), nullptr); - ASSERT(res == 0); + rc = ble_hs_id_copy_addr(addrType, address.data(), nullptr); + ASSERT(rc == 0); bleController.AddressType((addrType == 0) ? Ble::AddressTypes::Public : Ble::AddressTypes::Random); bleController.Address(std::move(address)); - res = ble_gatts_start(); - ASSERT(res == 0); + rc = ble_gatts_start(); + ASSERT(rc == 0); + + if (!ble_gap_adv_active() && !bleController.IsConnected()) + StartAdvertising(); } void NimbleController::StartAdvertising() { - if (bleController.IsConnected() || ble_gap_conn_active() || ble_gap_adv_active()) - return; - - ble_svc_gap_device_name_set(deviceName); + int rc; /* set adv parameters */ struct ble_gap_adv_params adv_params; @@ -102,11 +122,17 @@ void NimbleController::StartAdvertising() { adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; + /* fast advertise for 30 sec */ + if (fastAdvCount < 15) { + adv_params.itvl_min = 32; + adv_params.itvl_max = 47; + fastAdvCount++; + } else { + adv_params.itvl_min = 1636; + adv_params.itvl_max = 1651; + } fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; - // fields.uuids128 = BLE_UUID128(BLE_UUID128_DECLARE( - // 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - // 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff)); fields.uuids128 = &dfuServiceUuid; fields.num_uuids128 = 1; fields.uuids128_is_complete = 1; @@ -116,28 +142,25 @@ void NimbleController::StartAdvertising() { rsp_fields.name_len = strlen(deviceName); rsp_fields.name_is_complete = 1; - ble_gap_adv_set_fields(&fields); - // ASSERT(res == 0); // TODO this one sometimes fails with error 22 (notsync) + rc = ble_gap_adv_set_fields(&fields); + ASSERT(rc == 0); - ble_gap_adv_rsp_set_fields(&rsp_fields); - // ASSERT(res == 0); + rc = ble_gap_adv_rsp_set_fields(&rsp_fields); + ASSERT(rc == 0); - ble_gap_adv_start(addrType, NULL, 180000, &adv_params, GAPEventCallback, this); - // ASSERT(res == 0);// TODO I've disabled these ASSERT as they sometime asserts and reset the mcu. - // For now, the advertising is restarted as soon as it ends. There may be a race condition - // that prevent the advertising from restarting reliably. - // I remove the assert to prevent this uncesseray crash, but in the long term, the management of - // the advertising should be improve (better error handling, and advertise for 3 minutes after - // the application has been woken up, for example. + rc = ble_gap_adv_start(addrType, NULL, 2000, &adv_params, GAPEventCallback, this); + ASSERT(rc == 0); } int NimbleController::OnGAPEvent(ble_gap_event* event) { switch (event->type) { case BLE_GAP_EVENT_ADV_COMPLETE: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_ADV_COMPLETE"); - NRF_LOG_INFO("advertise complete; reason=%dn status=%d", event->adv_complete.reason, event->connect.status); + NRF_LOG_INFO("reason=%d; status=%d", event->adv_complete.reason, event->connect.status); + StartAdvertising(); break; - case BLE_GAP_EVENT_CONNECT: { + + case BLE_GAP_EVENT_CONNECT: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_CONNECT"); /* A new connection was established or a connection attempt failed. */ @@ -145,35 +168,44 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { if (event->connect.status != 0) { /* Connection failed; resume advertising. */ - StartAdvertising(); + currentTimeClient.Reset(); + alertNotificationClient.Reset(); + connectionHandle = BLE_HS_CONN_HANDLE_NONE; bleController.Disconnect(); + fastAdvCount = 0; + StartAdvertising(); } else { + connectionHandle = event->connect.conn_handle; bleController.Connect(); systemTask.PushMessage(Pinetime::System::Messages::BleConnected); - connectionHandle = event->connect.conn_handle; - // Service discovery is deffered via systemtask + // Service discovery is deferred via systemtask } - } break; + break; + case BLE_GAP_EVENT_DISCONNECT: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_DISCONNECT"); - NRF_LOG_INFO("disconnect; reason=%d", event->disconnect.reason); + NRF_LOG_INFO("disconnect reason=%d", event->disconnect.reason); /* Connection terminated; resume advertising. */ currentTimeClient.Reset(); alertNotificationClient.Reset(); connectionHandle = BLE_HS_CONN_HANDLE_NONE; bleController.Disconnect(); + fastAdvCount = 0; StartAdvertising(); break; + case BLE_GAP_EVENT_CONN_UPDATE: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_CONN_UPDATE"); /* The central has updated the connection parameters. */ - NRF_LOG_INFO("connection updated; status=%d ", event->conn_update.status); + NRF_LOG_INFO("update status=%d ", event->conn_update.status); break; + case BLE_GAP_EVENT_ENC_CHANGE: /* Encryption has been enabled or disabled for this connection. */ NRF_LOG_INFO("encryption change event; status=%d ", event->enc_change.status); - return 0; + break; + case BLE_GAP_EVENT_SUBSCRIBE: NRF_LOG_INFO("subscribe event; conn_handle=%d attr_handle=%d " "reason=%d prevn=%d curn=%d previ=%d curi=???\n", @@ -183,10 +215,12 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { event->subscribe.prev_notify, event->subscribe.cur_notify, event->subscribe.prev_indicate); - return 0; + break; + case BLE_GAP_EVENT_MTU: - NRF_LOG_INFO("mtu update event; conn_handle=%d cid=%d mtu=%d\n", event->mtu.conn_handle, event->mtu.channel_id, event->mtu.value); - return 0; + NRF_LOG_INFO("mtu update event; conn_handle=%d cid=%d mtu=%d\n", + event->mtu.conn_handle, event->mtu.channel_id, event->mtu.value); + break; case BLE_GAP_EVENT_REPEAT_PAIRING: { /* We already have a bond with the peer, but it is attempting to @@ -217,8 +251,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { notifSize); alertNotificationClient.OnNotification(event); - return 0; - } + } break; /* Attribute data is contained in event->notify_rx.attr_data. */ default: @@ -229,7 +262,9 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { } void NimbleController::StartDiscovery() { - serviceDiscovery.StartDiscovery(connectionHandle); + if (connectionHandle != BLE_HS_CONN_HANDLE_NONE) { + serviceDiscovery.StartDiscovery(connectionHandle); + } } uint16_t NimbleController::connHandle() { @@ -237,7 +272,7 @@ uint16_t NimbleController::connHandle() { } void NimbleController::NotifyBatteryLevel(uint8_t level) { - if(connectionHandle != BLE_HS_CONN_HANDLE_NONE) { + if (connectionHandle != BLE_HS_CONN_HANDLE_NONE) { batteryInformationService.NotifyBatteryLevel(connectionHandle, level); } } diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 0cfe983c6b..473bb1aff6 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -72,6 +72,10 @@ namespace Pinetime { uint16_t connHandle(); void NotifyBatteryLevel(uint8_t level); + void RestartFastAdv() { + fastAdvCount = 0; + } + private: static constexpr const char* deviceName = "InfiniTime"; Pinetime::System::SystemTask& systemTask; @@ -94,6 +98,7 @@ namespace Pinetime { uint8_t addrType; // 1 = Random, 0 = PUBLIC uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; + uint8_t fastAdvCount = 0; ble_uuid128_t dfuServiceUuid { .u {.type = BLE_UUID_TYPE_128}, @@ -101,5 +106,7 @@ namespace Pinetime { ServiceDiscovery serviceDiscovery; }; + + static NimbleController* nptr; } } diff --git a/src/components/brightness/BrightnessController.cpp b/src/components/brightness/BrightnessController.cpp index 8ad987d1f4..6c524679c1 100644 --- a/src/components/brightness/BrightnessController.cpp +++ b/src/components/brightness/BrightnessController.cpp @@ -1,13 +1,13 @@ #include "BrightnessController.h" #include #include "displayapp/screens/Symbols.h" - +#include "drivers/PinMap.h" using namespace Pinetime::Controllers; void BrightnessController::Init() { - nrf_gpio_cfg_output(pinLcdBacklight1); - nrf_gpio_cfg_output(pinLcdBacklight2); - nrf_gpio_cfg_output(pinLcdBacklight3); + nrf_gpio_cfg_output(PinMap::LcdBacklightLow); + nrf_gpio_cfg_output(PinMap::LcdBacklightMedium); + nrf_gpio_cfg_output(PinMap::LcdBacklightHigh); Set(level); } @@ -16,24 +16,24 @@ void BrightnessController::Set(BrightnessController::Levels level) { switch (level) { default: case Levels::High: - nrf_gpio_pin_clear(pinLcdBacklight1); - nrf_gpio_pin_clear(pinLcdBacklight2); - nrf_gpio_pin_clear(pinLcdBacklight3); + nrf_gpio_pin_clear(PinMap::LcdBacklightLow); + nrf_gpio_pin_clear(PinMap::LcdBacklightMedium); + nrf_gpio_pin_clear(PinMap::LcdBacklightHigh); break; case Levels::Medium: - nrf_gpio_pin_clear(pinLcdBacklight1); - nrf_gpio_pin_clear(pinLcdBacklight2); - nrf_gpio_pin_set(pinLcdBacklight3); + nrf_gpio_pin_clear(PinMap::LcdBacklightLow); + nrf_gpio_pin_clear(PinMap::LcdBacklightMedium); + nrf_gpio_pin_set(PinMap::LcdBacklightHigh); break; case Levels::Low: - nrf_gpio_pin_clear(pinLcdBacklight1); - nrf_gpio_pin_set(pinLcdBacklight2); - nrf_gpio_pin_set(pinLcdBacklight3); + nrf_gpio_pin_clear(PinMap::LcdBacklightLow); + nrf_gpio_pin_set(PinMap::LcdBacklightMedium); + nrf_gpio_pin_set(PinMap::LcdBacklightHigh); break; case Levels::Off: - nrf_gpio_pin_set(pinLcdBacklight1); - nrf_gpio_pin_set(pinLcdBacklight2); - nrf_gpio_pin_set(pinLcdBacklight3); + nrf_gpio_pin_set(PinMap::LcdBacklightLow); + nrf_gpio_pin_set(PinMap::LcdBacklightMedium); + nrf_gpio_pin_set(PinMap::LcdBacklightHigh); break; } } diff --git a/src/components/brightness/BrightnessController.h b/src/components/brightness/BrightnessController.h index c47158a910..0d7ac2ffa6 100644 --- a/src/components/brightness/BrightnessController.h +++ b/src/components/brightness/BrightnessController.h @@ -22,9 +22,6 @@ namespace Pinetime { const char* ToString(); private: - static constexpr uint8_t pinLcdBacklight1 = 14; - static constexpr uint8_t pinLcdBacklight2 = 22; - static constexpr uint8_t pinLcdBacklight3 = 23; Levels level = Levels::High; Levels backupLevel = Levels::High; }; diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index b25e6bc829..42057a860d 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -2,6 +2,7 @@ #include #include "systemtask/SystemTask.h" #include "app_timer.h" +#include "drivers/PinMap.h" APP_TIMER_DEF(shortVibTimer); APP_TIMER_DEF(longVibTimer); @@ -12,8 +13,8 @@ MotorController::MotorController(Controllers::Settings& settingsController) : se } void MotorController::Init() { - nrf_gpio_cfg_output(pinMotor); - nrf_gpio_pin_set(pinMotor); + nrf_gpio_cfg_output(PinMap::Motor); + nrf_gpio_pin_set(PinMap::Motor); app_timer_init(); app_timer_create(&shortVibTimer, APP_TIMER_MODE_SINGLE_SHOT, StopMotor); @@ -30,7 +31,7 @@ void MotorController::RunForDuration(uint8_t motorDuration) { return; } - nrf_gpio_pin_clear(pinMotor); + nrf_gpio_pin_clear(PinMap::Motor); app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), nullptr); } @@ -44,9 +45,9 @@ void MotorController::StartRinging() { void MotorController::StopRinging() { app_timer_stop(longVibTimer); - nrf_gpio_pin_set(pinMotor); + nrf_gpio_pin_set(PinMap::Motor); } void MotorController::StopMotor(void* p_context) { - nrf_gpio_pin_set(pinMotor); + nrf_gpio_pin_set(PinMap::Motor); } diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index d2c9fe5f2c..cf78088ec3 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -1,12 +1,10 @@ #pragma once #include -#include "app_timer.h" #include "components/settings/Settings.h" namespace Pinetime { namespace Controllers { - static constexpr uint8_t pinMotor = 16; class MotorController { public: diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index a294ab7840..a54ba9760e 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -114,7 +114,7 @@ namespace Pinetime { }; void setWakeUpMode(WakeUpMode wakeUp, bool enabled) { - if (!isWakeUpModeOn(wakeUp)) { + if (enabled != isWakeUpModeOn(wakeUp)) { settingsChanged = true; } settings.wakeUpMode.set(static_cast(wakeUp), enabled); diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 33c67e229c..9d47310197 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -139,9 +139,6 @@ void DisplayApp::InitHw() { brightnessController.Set(settingsController.GetBrightness()); } -uint32_t acc = 0; -uint32_t count = 0; -bool toggle = true; void DisplayApp::Refresh() { TickType_t queueTimeout; TickType_t delta; @@ -197,9 +194,6 @@ void DisplayApp::Refresh() { // clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected : // Screens::Clock::BleConnectionStates::NotConnected); break; - case Messages::UpdateBatteryLevel: - batteryController.Update(); - break; case Messages::NewNotification: LoadApp(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down); break; diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index 17612ef057..7a20262988 100644 --- a/src/displayapp/DisplayAppRecovery.cpp +++ b/src/displayapp/DisplayAppRecovery.cpp @@ -5,6 +5,7 @@ #include #include #include "displayapp/icons/infinitime/infinitime-nb.c" +#include "components/ble/BleController.h" using namespace Pinetime::Applications; diff --git a/src/displayapp/DisplayAppRecovery.h b/src/displayapp/DisplayAppRecovery.h index 8b2bc7f515..4184ea49da 100644 --- a/src/displayapp/DisplayAppRecovery.h +++ b/src/displayapp/DisplayAppRecovery.h @@ -6,32 +6,38 @@ #include #include #include "components/gfx/Gfx.h" -#include "components/battery/BatteryController.h" -#include "components/brightness/BrightnessController.h" -#include "components/ble/BleController.h" -#include "components/datetime/DateTimeController.h" -#include "components/ble/NotificationManager.h" -#include "components/firmwarevalidator/FirmwareValidator.h" #include "drivers/Cst816s.h" #include #include -#include -#include #include -#include #include "TouchEvents.h" #include "Apps.h" #include "Messages.h" #include "DummyLittleVgl.h" -#include "components/timer/TimerController.h" namespace Pinetime { - namespace System { - class SystemTask; - }; + namespace Drivers { + class St7789; + class Cst816S; + class WatchdogView; + } namespace Controllers { + class Settings; + class Battery; + class Ble; + class DateTime; + class NotificationManager; + class HeartRateController; + class MotionController; class TouchHandler; + class MotorController; + class TimerController; } + + namespace System { + class SystemTask; + }; + namespace Applications { class DisplayApp { public: diff --git a/src/displayapp/Messages.h b/src/displayapp/Messages.h index c23cdfe3f7..d48b646fe0 100644 --- a/src/displayapp/Messages.h +++ b/src/displayapp/Messages.h @@ -7,7 +7,6 @@ namespace Pinetime { GoToRunning, UpdateDateTime, UpdateBleConnection, - UpdateBatteryLevel, TouchEvent, ButtonPushed, NewNotification, diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index 91c2651236..ad9af15344 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -55,8 +55,6 @@ BatteryInfo::~BatteryInfo() { void BatteryInfo::Refresh() { - batteryController.Update(); - batteryPercent = batteryController.PercentRemaining(); batteryVoltage = batteryController.Voltage(); diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 22eb290e8e..417dff00d2 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -152,7 +152,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, uint8_t notifNb, Modes mode, Pinetime::Controllers::AlertNotificationService& alertNotificationService) - : notifNr {notifNr}, notifNb {notifNb}, mode {mode}, alertNotificationService {alertNotificationService} { + : mode {mode}, alertNotificationService {alertNotificationService} { lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL); lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x222222)); diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index f6f8b4c35b..0b5271e72f 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -43,21 +43,13 @@ namespace Pinetime { void OnCallButtonEvent(lv_obj_t*, lv_event_t event); private: - uint8_t notifNr = 0; - uint8_t notifNb = 0; - char pageText[4]; - lv_obj_t* container1; - lv_obj_t* t1; - lv_obj_t* l1; - lv_obj_t* l2; lv_obj_t* bt_accept; lv_obj_t* bt_mute; lv_obj_t* bt_reject; lv_obj_t* label_accept; lv_obj_t* label_mute; lv_obj_t* label_reject; - lv_obj_t* bottomPlaceholder; Modes mode; Pinetime::Controllers::AlertNotificationService& alertNotificationService; bool running = true; diff --git a/src/displayapp/screens/settings/Settings.cpp b/src/displayapp/screens/settings/Settings.cpp index f82b03c1a1..e3319f030a 100644 --- a/src/displayapp/screens/settings/Settings.cpp +++ b/src/displayapp/screens/settings/Settings.cpp @@ -50,8 +50,8 @@ std::unique_ptr Settings::CreateScreen2() { std::array applications {{ {Symbols::shoe, "Steps", Apps::SettingSteps}, {Symbols::batteryHalf, "Battery", Apps::BatteryInfo}, + {Symbols::paintbrush, "PTS Colors", Apps::SettingPineTimeStyle}, {Symbols::check, "Firmware", Apps::FirmwareValidation}, - {Symbols::list, "About", Apps::SysInfo}, }}; return std::make_unique(1, 3, app, settingsController, applications); @@ -60,7 +60,7 @@ std::unique_ptr Settings::CreateScreen2() { std::unique_ptr Settings::CreateScreen3() { std::array applications {{ - {Symbols::paintbrush, "PTS Colors", Apps::SettingPineTimeStyle}, + {Symbols::list, "About", Apps::SysInfo}, {Symbols::none, "None", Apps::None}, {Symbols::none, "None", Apps::None}, {Symbols::none, "None", Apps::None}, diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp index b8f8e45df9..1ff163b0c2 100644 --- a/src/drivers/Cst816s.cpp +++ b/src/drivers/Cst816s.cpp @@ -3,6 +3,7 @@ #include #include #include +#include "drivers/PinMap.h" using namespace Pinetime::Drivers; @@ -18,12 +19,12 @@ Cst816S::Cst816S(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaste } void Cst816S::Init() { - nrf_gpio_cfg_output(pinReset); - nrf_gpio_pin_set(pinReset); + nrf_gpio_cfg_output(PinMap::Cst816sReset); + nrf_gpio_pin_set(PinMap::Cst816sReset); vTaskDelay(50); - nrf_gpio_pin_clear(pinReset); + nrf_gpio_pin_clear(PinMap::Cst816sReset); vTaskDelay(5); - nrf_gpio_pin_set(pinReset); + nrf_gpio_pin_set(PinMap::Cst816sReset); vTaskDelay(50); // Wake the touchpanel up @@ -80,9 +81,9 @@ Cst816S::TouchInfos Cst816S::GetTouchInfo() { } void Cst816S::Sleep() { - nrf_gpio_pin_clear(pinReset); + nrf_gpio_pin_clear(PinMap::Cst816sReset); vTaskDelay(5); - nrf_gpio_pin_set(pinReset); + nrf_gpio_pin_set(PinMap::Cst816sReset); vTaskDelay(50); static constexpr uint8_t sleepValue = 0x03; twiMaster.Write(twiAddress, 0xA5, &sleepValue, 1); diff --git a/src/drivers/Cst816s.h b/src/drivers/Cst816s.h index d4c17bb823..7b46c5d582 100644 --- a/src/drivers/Cst816s.h +++ b/src/drivers/Cst816s.h @@ -36,9 +36,6 @@ namespace Pinetime { void Wakeup(); private: - static constexpr uint8_t pinIrq = 28; - static constexpr uint8_t pinReset = 10; - // Unused/Unavailable commented out static constexpr uint8_t gestureIndex = 1; static constexpr uint8_t touchPointNumIndex = 2; diff --git a/src/drivers/PinMap.h b/src/drivers/PinMap.h new file mode 100644 index 0000000000..57964020c6 --- /dev/null +++ b/src/drivers/PinMap.h @@ -0,0 +1,38 @@ +#pragma once + +namespace Pinetime { + namespace PinMap { + + #ifdef WATCH_P8 + // COLMI P8 + static constexpr uint8_t Charging = 19; + static constexpr uint8_t Cst816sReset = 13; + static constexpr uint8_t Button = 17; + #else + // Pinetime + static constexpr uint8_t Charging = 12; + static constexpr uint8_t Cst816sReset = 10; + static constexpr uint8_t Button = 13; + #endif + + static constexpr uint8_t Cst816sIrq = 28; + static constexpr uint8_t PowerPresent = 19; + + static constexpr uint8_t Motor = 16; + + static constexpr uint8_t LcdBacklightLow = 14; + static constexpr uint8_t LcdBacklightMedium = 22; + static constexpr uint8_t LcdBacklightHigh = 23; + + static constexpr uint8_t SpiSck = 2; + static constexpr uint8_t SpiMosi = 3; + static constexpr uint8_t SpiMiso = 4; + + static constexpr uint8_t SpiFlashCsn = 5; + static constexpr uint8_t SpiLcdCsn = 25; + static constexpr uint8_t LcdDataCommand = 18; + + static constexpr uint8_t TwiScl = 7; + static constexpr uint8_t TwiSda = 6; + } +} diff --git a/src/main.cpp b/src/main.cpp index 6a7f5eb342..7d4f0858c5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,7 +43,9 @@ #include "drivers/St7789.h" #include "drivers/TwiMaster.h" #include "drivers/Cst816s.h" +#include "drivers/PinMap.h" #include "systemtask/SystemTask.h" +#include "drivers/PinMap.h" #include "touchhandler/TouchHandler.h" #if NRF_LOG_ENABLED @@ -54,14 +56,6 @@ Pinetime::Logging::NrfLogger logger; Pinetime::Logging::DummyLogger logger; #endif -static constexpr uint8_t pinSpiSck = 2; -static constexpr uint8_t pinSpiMosi = 3; -static constexpr uint8_t pinSpiMiso = 4; -static constexpr uint8_t pinSpiFlashCsn = 5; -static constexpr uint8_t pinLcdCsn = 25; -static constexpr uint8_t pinLcdDataCommand = 18; -static constexpr uint8_t pinTwiScl = 7; -static constexpr uint8_t pinTwiSda = 6; static constexpr uint8_t touchPanelTwiAddress = 0x15; static constexpr uint8_t motionSensorTwiAddress = 0x18; static constexpr uint8_t heartRateSensorTwiAddress = 0x44; @@ -70,33 +64,30 @@ Pinetime::Drivers::SpiMaster spi {Pinetime::Drivers::SpiMaster::SpiModule::SPI0, {Pinetime::Drivers::SpiMaster::BitOrder::Msb_Lsb, Pinetime::Drivers::SpiMaster::Modes::Mode3, Pinetime::Drivers::SpiMaster::Frequencies::Freq8Mhz, - pinSpiSck, - pinSpiMosi, - pinSpiMiso}}; + Pinetime::PinMap::SpiSck, + Pinetime::PinMap::SpiMosi, + Pinetime::PinMap::SpiMiso}}; -Pinetime::Drivers::Spi lcdSpi {spi, pinLcdCsn}; -Pinetime::Drivers::St7789 lcd {lcdSpi, pinLcdDataCommand}; +Pinetime::Drivers::Spi lcdSpi {spi, Pinetime::PinMap::SpiLcdCsn}; +Pinetime::Drivers::St7789 lcd {lcdSpi, Pinetime::PinMap::LcdDataCommand}; -Pinetime::Drivers::Spi flashSpi {spi, pinSpiFlashCsn}; +Pinetime::Drivers::Spi flashSpi {spi, Pinetime::PinMap::SpiFlashCsn}; Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; // The TWI device should work @ up to 400Khz but there is a HW bug which prevent it from // respecting correct timings. According to erratas heet, this magic value makes it run // at ~390Khz with correct timings. static constexpr uint32_t MaxTwiFrequencyWithoutHardwareBug {0x06200000}; -Pinetime::Drivers::TwiMaster twiMaster {NRF_TWIM1, MaxTwiFrequencyWithoutHardwareBug, pinTwiSda, pinTwiScl}; +Pinetime::Drivers::TwiMaster twiMaster {NRF_TWIM1, MaxTwiFrequencyWithoutHardwareBug, Pinetime::PinMap::TwiSda, Pinetime::PinMap::TwiScl}; Pinetime::Drivers::Cst816S touchPanel {twiMaster, touchPanelTwiAddress}; #ifdef PINETIME_IS_RECOVERY -static constexpr bool isFactory = true; #include "displayapp/DummyLittleVgl.h" #include "displayapp/DisplayAppRecovery.h" -Pinetime::Components::LittleVgl lvgl {lcd, touchPanel}; #else -static constexpr bool isFactory = false; #include "displayapp/LittleVgl.h" #include "displayapp/DisplayApp.h" -Pinetime::Components::LittleVgl lvgl {lcd, touchPanel}; #endif +Pinetime::Components::LittleVgl lvgl {lcd, touchPanel}; Pinetime::Drivers::Bma421 motionSensor {twiMaster, motionSensorTwiAddress}; Pinetime::Drivers::Hrs3300 heartRateSensor {twiMaster, heartRateSensorTwiAddress}; @@ -105,10 +96,8 @@ TimerHandle_t debounceTimer; TimerHandle_t debounceChargeTimer; Pinetime::Controllers::Battery batteryController; Pinetime::Controllers::Ble bleController; -void ble_manager_set_ble_connection_callback(void (*connection)()); -void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); -static constexpr uint8_t pinTouchIrq = 28; -static constexpr uint8_t pinPowerPresentIrq = 19; +static constexpr uint8_t pinTouchIrq = Pinetime::PinMap::Cst816sIrq; +static constexpr uint8_t pinPowerPresentIrq = Pinetime::PinMap::PowerPresent; Pinetime::Controllers::HeartRateController heartRateController; Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController); @@ -168,14 +157,14 @@ Pinetime::System::SystemTask systemTask(spi, touchHandler); void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { - if (pin == pinTouchIrq) { + if (pin == Pinetime::PinMap::Cst816sIrq) { systemTask.OnTouchEvent(); return; } BaseType_t xHigherPriorityTaskWoken = pdFALSE; - if (pin == pinPowerPresentIrq and action == NRF_GPIOTE_POLARITY_TOGGLE) { + if (pin == Pinetime::PinMap::PowerPresent and action == NRF_GPIOTE_POLARITY_TOGGLE) { xTimerStartFromISR(debounceChargeTimer, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); return; @@ -308,18 +297,18 @@ int main(void) { nrf_drv_clock_init(); // Unblock i2c? - nrf_gpio_cfg(pinTwiScl, + nrf_gpio_cfg(Pinetime::PinMap::TwiScl, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0D1, NRF_GPIO_PIN_NOSENSE); - nrf_gpio_pin_set(pinTwiScl); + nrf_gpio_pin_set(Pinetime::PinMap::TwiScl); for (uint8_t i = 0; i < 16; i++) { - nrf_gpio_pin_toggle(pinTwiScl); + nrf_gpio_pin_toggle(Pinetime::PinMap::TwiScl); nrf_delay_us(5); } - nrf_gpio_cfg_default(pinTwiScl); + nrf_gpio_cfg_default(Pinetime::PinMap::TwiScl); debounceTimer = xTimerCreate("debounceTimer", 200, pdFALSE, (void*) 0, DebounceTimerCallback); debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, (void*) 0, DebounceTimerChargeCallback); diff --git a/src/recoveryLoader.cpp b/src/recoveryLoader.cpp index 9818179dee..acec14c8ad 100644 --- a/src/recoveryLoader.cpp +++ b/src/recoveryLoader.cpp @@ -15,6 +15,7 @@ #include #include #include "recoveryImage.h" +#include "drivers/PinMap.h" #include "displayapp/icons/infinitime/infinitime-nb.c" #include "components/rle/RleDecoder.h" @@ -27,12 +28,6 @@ Pinetime::Logging::NrfLogger logger; Pinetime::Logging::DummyLogger logger; #endif -static constexpr uint8_t pinSpiSck = 2; -static constexpr uint8_t pinSpiMosi = 3; -static constexpr uint8_t pinSpiMiso = 4; -static constexpr uint8_t pinSpiFlashCsn = 5; -static constexpr uint8_t pinLcdCsn = 25; -static constexpr uint8_t pinLcdDataCommand = 18; static constexpr uint8_t displayWidth = 240; static constexpr uint8_t displayHeight = 240; @@ -45,14 +40,14 @@ Pinetime::Drivers::SpiMaster spi {Pinetime::Drivers::SpiMaster::SpiModule::SPI0, {Pinetime::Drivers::SpiMaster::BitOrder::Msb_Lsb, Pinetime::Drivers::SpiMaster::Modes::Mode3, Pinetime::Drivers::SpiMaster::Frequencies::Freq8Mhz, - pinSpiSck, - pinSpiMosi, - pinSpiMiso}}; -Pinetime::Drivers::Spi flashSpi {spi, pinSpiFlashCsn}; + Pinetime::PinMap::SpiSck, + Pinetime::PinMap::SpiMosi, + Pinetime::PinMap::SpiMiso}}; +Pinetime::Drivers::Spi flashSpi {spi, Pinetime::PinMap::SpiFlashCsn}; Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; -Pinetime::Drivers::Spi lcdSpi {spi, pinLcdCsn}; -Pinetime::Drivers::St7789 lcd {lcdSpi, pinLcdDataCommand}; +Pinetime::Drivers::Spi lcdSpi {spi, Pinetime::PinMap::SpiLcdCsn}; +Pinetime::Drivers::St7789 lcd {lcdSpi, Pinetime::PinMap::LcdDataCommand}; Pinetime::Components::Gfx gfx {lcd}; Pinetime::Controllers::BrightnessController brightnessController; diff --git a/src/systemtask/Messages.h b/src/systemtask/Messages.h index 93fcf9407a..bd1de234c2 100644 --- a/src/systemtask/Messages.h +++ b/src/systemtask/Messages.h @@ -22,7 +22,9 @@ namespace Pinetime { OnNewDay, OnChargingEvent, SetOffAlarm, - StopRinging + StopRinging, + MeasureBatteryTimerExpired, + BatteryMeasurementDone, }; } } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 534f551092..24ee4bda3e 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -21,8 +21,10 @@ #include "drivers/SpiNorFlash.h" #include "drivers/TwiMaster.h" #include "drivers/Hrs3300.h" +#include "drivers/PinMap.h" #include "main.h" + #include using namespace Pinetime::System; @@ -47,6 +49,11 @@ void IdleTimerCallback(TimerHandle_t xTimer) { sysTask->OnIdle(); } +void MeasureBatteryTimerCallback(TimerHandle_t xTimer) { + auto* sysTask = static_cast(pvTimerGetTimerID(xTimer)); + sysTask->PushMessage(Pinetime::System::Messages::MeasureBatteryTimerExpired); +} + SystemTask::SystemTask(Drivers::SpiMaster& spi, Drivers::St7789& lcd, Pinetime::Drivers::SpiNorFlash& spiNorFlash, @@ -123,13 +130,13 @@ void SystemTask::Work() { fs.Init(); nimbleController.Init(); - nimbleController.StartAdvertising(); lcd.Init(); twiMaster.Init(); touchPanel.Init(); dateTimeController.Register(this); - batteryController.Init(); + batteryController.Register(this); + batteryController.Update(); motorController.Init(); motionSensor.SoftReset(); timerController.Register(this); @@ -147,13 +154,11 @@ void SystemTask::Work() { displayApp.Register(this); displayApp.Start(); - displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); - heartRateSensor.Init(); heartRateSensor.Disable(); heartRateApp.Start(); - nrf_gpio_cfg_sense_input(pinButton, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pulldown, (nrf_gpio_pin_sense_t) GPIO_PIN_CNF_SENSE_High); + nrf_gpio_cfg_sense_input(PinMap::Button, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pulldown, (nrf_gpio_pin_sense_t) GPIO_PIN_CNF_SENSE_High); nrf_gpio_cfg_output(15); nrf_gpio_pin_set(15); @@ -164,9 +169,9 @@ void SystemTask::Work() { pinConfig.sense = (nrf_gpiote_polarity_t) NRF_GPIOTE_POLARITY_HITOLO; pinConfig.pull = (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pulldown; - nrfx_gpiote_in_init(pinButton, &pinConfig, nrfx_gpiote_evt_handler); + nrfx_gpiote_in_init(PinMap::Button, &pinConfig, nrfx_gpiote_evt_handler); - nrf_gpio_cfg_sense_input(pinTouchIrq, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pullup, (nrf_gpio_pin_sense_t) GPIO_PIN_CNF_SENSE_Low); + nrf_gpio_cfg_sense_input(PinMap::Cst816sIrq, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pullup, (nrf_gpio_pin_sense_t) GPIO_PIN_CNF_SENSE_Low); pinConfig.skip_gpio_setup = true; pinConfig.hi_accuracy = false; @@ -174,24 +179,26 @@ void SystemTask::Work() { pinConfig.sense = (nrf_gpiote_polarity_t) NRF_GPIOTE_POLARITY_HITOLO; pinConfig.pull = (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pullup; - nrfx_gpiote_in_init(pinTouchIrq, &pinConfig, nrfx_gpiote_evt_handler); + nrfx_gpiote_in_init(PinMap::Cst816sIrq, &pinConfig, nrfx_gpiote_evt_handler); pinConfig.sense = NRF_GPIOTE_POLARITY_TOGGLE; pinConfig.pull = NRF_GPIO_PIN_NOPULL; pinConfig.is_watcher = false; pinConfig.hi_accuracy = false; pinConfig.skip_gpio_setup = true; - nrfx_gpiote_in_init(pinPowerPresentIrq, &pinConfig, nrfx_gpiote_evt_handler); + nrfx_gpiote_in_init(PinMap::PowerPresent, &pinConfig, nrfx_gpiote_evt_handler); - if (nrf_gpio_pin_read(pinPowerPresentIrq)) { - nrf_gpio_cfg_sense_input(pinPowerPresentIrq, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW); + if (nrf_gpio_pin_read(PinMap::PowerPresent)) { + nrf_gpio_cfg_sense_input(PinMap::PowerPresent, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW); } else { - nrf_gpio_cfg_sense_input(pinPowerPresentIrq, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH); + nrf_gpio_cfg_sense_input(PinMap::PowerPresent, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH); } idleTimer = xTimerCreate("idleTimer", pdMS_TO_TICKS(2000), pdFALSE, this, IdleTimerCallback); dimTimer = xTimerCreate("dimTimer", pdMS_TO_TICKS(settingsController.GetScreenTimeOut() - 2000), pdFALSE, this, DimTimerCallback); + measureBatteryTimer = xTimerCreate("measureBattery", batteryMeasurementPeriod, pdTRUE, this, MeasureBatteryTimerCallback); xTimerStart(dimTimer, 0); + xTimerStart(measureBatteryTimer, portMAX_DELAY); // Suppress endless loop diagnostic #pragma clang diagnostic push @@ -201,11 +208,6 @@ void SystemTask::Work() { uint8_t msg; if (xQueueReceive(systemTasksMsgQueue, &msg, 100)) { - - batteryController.Update(); - // the battery does not emit events when changing charge levels, so we piggyback - // on any system event to read and update the current values - Messages message = static_cast(msg); switch (message) { case Messages::EnableSleeping: @@ -229,15 +231,16 @@ void SystemTask::Work() { touchPanel.Wakeup(); } - nimbleController.StartAdvertising(); xTimerStart(dimTimer, 0); spiNorFlash.Wakeup(); lcd.Wakeup(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToRunning); - displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp); + if (!bleController.IsConnected()) + nimbleController.RestartFastAdv(); + isSleeping = false; isWakingUp = false; isDimmed = false; @@ -340,8 +343,18 @@ void SystemTask::Work() { stepCounterMustBeReset = true; break; case Messages::OnChargingEvent: + batteryController.Update(); motorController.RunForDuration(15); - // Battery level is updated on every message - there's no need to do anything + break; + case Messages::MeasureBatteryTimerExpired: + sendBatteryNotification = true; + batteryController.Update(); + break; + case Messages::BatteryMeasurementDone: + if (sendBatteryNotification) { + sendBatteryNotification = false; + nimbleController.NotifyBatteryLevel(batteryController.PercentRemaining()); + } break; default: @@ -353,22 +366,17 @@ void SystemTask::Work() { if (bleDiscoveryTimer == 0) { isBleDiscoveryTimerRunning = false; // Services discovery is deffered from 3 seconds to avoid the conflicts between the host communicating with the - // tharget and vice-versa. I'm not sure if this is the right way to handle this... + // target and vice-versa. I'm not sure if this is the right way to handle this... nimbleController.StartDiscovery(); } else { bleDiscoveryTimer--; } } - if (xTaskGetTickCount() - batteryNotificationTick > batteryNotificationPeriod) { - nimbleController.NotifyBatteryLevel(batteryController.PercentRemaining()); - batteryNotificationTick = xTaskGetTickCount(); - } - monitor.Process(); uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); dateTimeController.UpdateTime(systick_counter); - if (!nrf_gpio_pin_read(pinButton)) + if (!nrf_gpio_pin_read(PinMap::Button)) watchdog.Kick(); } // Clear diagnostic suppression diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index cbd98d26cd..9e7e5e8ce5 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "SystemMonitor.h" @@ -123,15 +124,6 @@ namespace Pinetime { Pinetime::Controllers::TouchHandler& touchHandler; Pinetime::Controllers::NimbleController nimbleController; - static constexpr uint8_t pinSpiSck = 2; - static constexpr uint8_t pinSpiMosi = 3; - static constexpr uint8_t pinSpiMiso = 4; - static constexpr uint8_t pinSpiCsn = 25; - static constexpr uint8_t pinLcdDataCommand = 18; - static constexpr uint8_t pinButton = 13; - static constexpr uint8_t pinTouchIrq = 28; - static constexpr uint8_t pinPowerPresentIrq = 19; - static void Process(void* instance); void Work(); void ReloadIdleTimer(); @@ -139,13 +131,15 @@ namespace Pinetime { uint8_t bleDiscoveryTimer = 0; TimerHandle_t dimTimer; TimerHandle_t idleTimer; + TimerHandle_t measureBatteryTimer; + bool sendBatteryNotification = false; bool doNotGoToSleep = false; void GoToRunning(); void UpdateMotion(); bool stepCounterMustBeReset = false; - static constexpr TickType_t batteryNotificationPeriod = 1000 * 60 * 10; // 1 tick ~= 1ms. 1ms * 60 * 10 = 10 minutes - TickType_t batteryNotificationTick = 0; + static constexpr TickType_t batteryMeasurementPeriod = pdMS_TO_TICKS(10 * 60 * 1000); + TickType_t lastBatteryNotificationTime = 0; #if configUSE_TRACE_FACILITY == 1 SystemMonitor monitor; From cdf99b08f42c3826a8608d756bc7cda0a476ed98 Mon Sep 17 00:00:00 2001 From: Mark Russell Date: Thu, 16 Sep 2021 16:12:20 -0400 Subject: [PATCH 39/40] Revert "Merge upstream" This reverts commit 1d43adcdfa7bd15ba45c0c9d7c59c0ff99176b9c. --- .github/workflows/main.yml | 8 +- CMakeLists.txt | 9 -- README.md | 25 ++-- cmake-nRF5x/readme.md | 2 +- doc/buildAndProgram.md | 1 - .../ota-gadgetbridge-nrfconnect.md | 8 -- doc/versioning.md | 2 +- src/CMakeLists.txt | 12 +- src/components/battery/BatteryController.cpp | 16 +-- src/components/battery/BatteryController.h | 9 +- src/components/ble/NimbleController.cpp | 125 +++++++----------- src/components/ble/NimbleController.h | 7 - .../brightness/BrightnessController.cpp | 32 ++--- .../brightness/BrightnessController.h | 3 + src/components/motor/MotorController.cpp | 11 +- src/components/motor/MotorController.h | 2 + src/components/settings/Settings.h | 2 +- src/displayapp/DisplayApp.cpp | 6 + src/displayapp/DisplayAppRecovery.cpp | 1 - src/displayapp/DisplayAppRecovery.h | 32 ++--- src/displayapp/Messages.h | 1 + src/displayapp/screens/BatteryInfo.cpp | 2 + src/displayapp/screens/Notifications.cpp | 2 +- src/displayapp/screens/Notifications.h | 8 ++ src/displayapp/screens/settings/Settings.cpp | 4 +- src/drivers/Cst816s.cpp | 13 +- src/drivers/Cst816s.h | 3 + src/drivers/PinMap.h | 38 ------ src/main.cpp | 47 ++++--- src/recoveryLoader.cpp | 19 ++- src/systemtask/Messages.h | 4 +- src/systemtask/SystemTask.cpp | 62 ++++----- src/systemtask/SystemTask.h | 16 ++- 33 files changed, 232 insertions(+), 300 deletions(-) delete mode 100644 src/drivers/PinMap.h diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bd24359a56..4744eaef7d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,13 +9,13 @@ name: Build PineTime Firmware # When to run this Workflow... on: - # Run this Workflow when files are updated (Pushed) in the "master" and "develop" Branch + # Run this Workflow when files are updated (Pushed) in the "master" Branch push: - branches: [ master, develop ] + branches: [ master ] - # Also run this Workflow when a Pull Request is created or updated in the "master" and "develop" Branch + # Also run this Workflow when a Pull Request is created or updated in the "master" Branch pull_request: - branches: [ master, develop ] + branches: [ master ] # Steps to run for the Workflow jobs: diff --git a/CMakeLists.txt b/CMakeLists.txt index f2402e5790..cc41a08744 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,14 +51,6 @@ if(BUILD_DFU) set(BUILD_DFU true) endif() -option(WATCH_COLMI_P8 "Build for the Colmi P8" OFF) -set(TARGET_DEVICE "PineTime") - -if(WATCH_COLMI_P8) - set(TARGET_DEVICE "Colmi P8") - add_definitions(-DWATCH_P8) -endif() - set(PROJECT_GIT_COMMIT_HASH "") execute_process(COMMAND git rev-parse --short HEAD @@ -76,7 +68,6 @@ message(" * Version : " ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${P message(" * Toolchain : " ${ARM_NONE_EABI_TOOLCHAIN_PATH}) message(" * GitRef(S) : " ${PROJECT_GIT_COMMIT_HASH}) message(" * NRF52 SDK : " ${NRF5_SDK_PATH}) -message(" * Target device : " ${TARGET_DEVICE}) set(PROGRAMMER "???") if(USE_JLINK) message(" * Programmer/debugger : JLINK") diff --git a/README.md b/README.md index 0d5cad934a..6549ece98d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,20 @@ -# InfiniTime +# PineTime [![Build PineTime Firmware](https://github.com/JF002/InfiniTime/workflows/Build%20PineTime%20Firmware/badge.svg?branch=master)](https://github.com/JF002/InfiniTime/actions) +> The PineTime is a free and open source smartwatch capable of running custom-built open operating systems. Some of the notable features include a heart rate monitor, a week-long battery as well as a capacitive touch IPS display that is legible in direct sunlight. It is a fully community driven side-project, which means that it will ultimately be up to the developers and end-users to determine when they deem the PineTime ready to ship. + +> We envision the PineTime as a companion for not only your PinePhone but also for your favorite devices — any phone, tablet, or even PC. + +*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 heart rate sensor, and a vibration motor. + +# InfiniTime + ![InfiniTime logo](images/infinitime-logo.jpg "InfiniTime Logo") -The goal of this project is to design an open-source firmware for the [Pinetime smartwatch](https://www.pine64.org/pinetime/) : +The goal of this project is to design an open-source firmware for the Pinetime smartwatch : - Code written in **modern C++**; - Build system based on **CMake**; @@ -12,11 +22,6 @@ The goal of this project is to design an open-source firmware for the [Pinetime - Using **[LittleVGL/LVGL 7](https://lvgl.io/)** as UI library... - ... and **[NimBLE 1.3.0](https://github.com/apache/mynewt-nimble)** as BLE stack. -## New to InfiniTime? - - - [Getting started with InfiniTime 1.0 (quick user guide, update bootloader and InfiniTime,...)](doc/gettingStarted/gettingStarted-1.0.md) - - [Flash, upgrade (OTA), time synchronization,...](doc/gettingStarted/ota-gadgetbridge-nrfconnect.md) - ## Overview ![Pinetime screens](images/1.0.0/collage.png "PinetimeScreens") @@ -65,12 +70,16 @@ As of now, here is the list of achievements of this project: * [Amazfish](https://openrepos.net/content/piggz/amazfish) (on SailfishOS and Linux) * [Siglo](https://github.com/alexr4535/siglo) (on Linux) * **[Experimental]** [WebBLEWatch](https://hubmartin.github.io/WebBLEWatch/) Synchronize time directly from your web browser. [video](https://youtu.be/IakiuhVDdrY) - * **[Experimental]** [Infini-iOS](https://github.com/xan-m/Infini-iOS) (on iOS) - OTA (Over-the-air) update via BLE - [Bootloader](https://github.com/JF002/pinetime-mcuboot-bootloader) based on [MCUBoot](https://juullabs-oss.github.io/mcuboot/) ## Documentation +### Getting started + + - [Getting started with InfiniTime 1.0 (quick user guide, update bootloader and InfiniTime,...)](doc/gettingStarted/gettingStarted-1.0.md) + - [Flash, upgrade (OTA), time synchronization,...](doc/gettingStarted/ota-gadgetbridge-nrfconnect.md) + ### Develop - [Generate the fonts and symbols](src/displayapp/fonts/README.md) diff --git a/cmake-nRF5x/readme.md b/cmake-nRF5x/readme.md index 0127a2e6e5..2ce76892db 100755 --- a/cmake-nRF5x/readme.md +++ b/cmake-nRF5x/readme.md @@ -98,7 +98,7 @@ The script makes use of the following tools: After setup you can use cmake as usual: -1. Generate the actual build files (out-of-source builds are strongly recommended): +1. Generate the actual build files (out-of-source builds are strongly recomended): ```commandline cmake -H. -B"cmake-build" -G "Unix Makefiles" diff --git a/doc/buildAndProgram.md b/doc/buildAndProgram.md index e97bb30d51..87b6dd9a5d 100644 --- a/doc/buildAndProgram.md +++ b/doc/buildAndProgram.md @@ -28,7 +28,6 @@ CMake configures the project according to variables you specify the command line **GDB_CLIENT_BIN_PATH**|Path to arm-none-eabi-gdb executable. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_BIN_PATH=/home/jf/nrf52/gcc-arm-none-eabi-9-2019-q4-major/bin/arm-none-eabi-gdb` **GDB_CLIENT_TARGET_REMOTE**|Target remote connection string. Used only if `USE_GDB_CLIENT` is 1.|`-DGDB_CLIENT_TARGET_REMOTE=/dev/ttyACM0` **BUILD_DFU (\*\*)**|Build DFU files while building (needs [adafruit-nrfutil](https://github.com/adafruit/Adafruit_nRF52_nrfutil)).|`-DBUILD_DFU=1` -**WATCH_COLMI_P8**|Use pin configuration for Colmi P8 watch|`-DWATCH_COLMI_P8=1` ####(**) Note about **CMAKE_BUILD_TYPE**: By default, this variable is set to *Release*. It compiles the code with size and speed optimizations. We use this value for all the binaries we publish when we [release](https://github.com/JF002/InfiniTime/releases) new versions of InfiniTime. diff --git a/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md b/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md index ffc27ed87b..1187a9b745 100644 --- a/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md +++ b/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md @@ -47,8 +47,6 @@ Read carefully the warning and tap **Install**: Wait for the transfer to finish. Your PineTime should reset and reboot with the new version of InfiniTime! -Don't forget to **validate** your firmware. In the InfiniTime go to the settings (swipe right, select gear icon) and Firmware option and click **validate**. Otherwise after reboot the previous firmware will be used. - ![Gadgetbridge 5](gadgetbridge5.jpg) ### Using NRFConnect @@ -66,8 +64,6 @@ Select **Distribution packet (ZIP)**: Browse to the DFU file you downloaded previously, the DFU transfer will start automatically. When the transfer is finished, your PineTime will reset and restart on the new version of InfiniTime! -Don't forget to **validate** your firmware. In the InfiniTime go to the settings (swipe right, select gear icon) and Firmware option and click **validate**. Otherwise after reboot the previous firmware will be used. - ![NRFConnect 3](nrfconnect3.jpg) ## How to flash InfiniTime using the SWD interface @@ -92,10 +88,6 @@ If you are using OpenOCD with a STLinkV2, you can find more info [on this page]( ### Using Gadgetbridge Good news! Gadgetbridge **automatically** synchronizes the time when connecting to your PineTime! -### Using any Chromium-based web browser -You can use it from your PC, Mac, Android. Browsers now have BLE support. -https://hubmartin.github.io/WebBLEWatch/ - ### Using NRFConnect You must enable the **CTS** *GATT server* into NRFConnect so that InfiniTime can synchronize the time with your smartphone. diff --git a/doc/versioning.md b/doc/versioning.md index 48e05043f0..b08af71479 100644 --- a/doc/versioning.md +++ b/doc/versioning.md @@ -3,4 +3,4 @@ The versioning of this project is based on [Semantic versionning](https://semver - 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 functioning firmware suited for the final user. \ No newline at end of file + - 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 37ee0848bd..ccade83e30 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -92,9 +92,6 @@ set(SDK_SOURCE_FILES set(TINYCRYPT_SRC libs/mynewt-nimble/ext/tinycrypt/src/aes_encrypt.c libs/mynewt-nimble/ext/tinycrypt/src/utils.c - libs/mynewt-nimble/ext/tinycrypt/src/cmac_mode.c - libs/mynewt-nimble/ext/tinycrypt/src/ecc.c - libs/mynewt-nimble/ext/tinycrypt/src/ecc_dh.c ) set(NIMBLE_SRC @@ -107,10 +104,6 @@ set(NIMBLE_SRC libs/mynewt-nimble/nimble/host/src/ble_l2cap.c libs/mynewt-nimble/nimble/host/src/ble_hs_mbuf.c libs/mynewt-nimble/nimble/host/src/ble_sm.c - libs/mynewt-nimble/nimble/host/src/ble_sm_cmd.c - libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c - libs/mynewt-nimble/nimble/host/src/ble_sm_alg.c - libs/mynewt-nimble/nimble/host/src/ble_sm_sc.c libs/mynewt-nimble/nimble/host/src/ble_gap.c libs/mynewt-nimble/nimble/host/src/ble_gatts.c libs/mynewt-nimble/nimble/host/src/ble_gattc.c @@ -134,6 +127,10 @@ set(NIMBLE_SRC libs/mynewt-nimble/nimble/host/src/ble_hs_atomic.c libs/mynewt-nimble/nimble/host/src/ble_hs_adv.c libs/mynewt-nimble/nimble/host/src/ble_hs_flow.c + libs/mynewt-nimble/nimble/host/src/ble_sm.c + libs/mynewt-nimble/nimble/host/src/ble_sm_cmd.c + libs/mynewt-nimble/nimble/host/src/ble_sm_lgcy.c + libs/mynewt-nimble/nimble/host/src/ble_sm_alg.c libs/mynewt-nimble/nimble/host/src/ble_hs_mqueue.c libs/mynewt-nimble/nimble/host/src/ble_hs_stop.c libs/mynewt-nimble/nimble/host/src/ble_hs_startup.c @@ -628,7 +625,6 @@ set(INCLUDE_FILES drivers/DebugPins.h drivers/InternalFlash.h drivers/Hrs3300.h - drivers/PinMap.h drivers/Bma421.h drivers/Bma421_C/bma4.c drivers/Bma421_C/bma423.c diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index 4ef20a2452..f8a64ecd18 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -1,5 +1,4 @@ #include "BatteryController.h" -#include "drivers/PinMap.h" #include #include #include @@ -10,12 +9,15 @@ Battery* Battery::instance = nullptr; Battery::Battery() { instance = this; - nrf_gpio_cfg_input(PinMap::Charging, static_cast GPIO_PIN_CNF_PULL_Disabled); +} + +void Battery::Init() { + nrf_gpio_cfg_input(chargingPin, static_cast GPIO_PIN_CNF_PULL_Pullup); } void Battery::Update() { - isCharging = !nrf_gpio_pin_read(PinMap::Charging); - isPowerPresent = !nrf_gpio_pin_read(PinMap::PowerPresent); + isCharging = !nrf_gpio_pin_read(chargingPin); + isPowerPresent = !nrf_gpio_pin_read(powerPresentPin); if (isReading) { return; @@ -73,11 +75,5 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { nrfx_saadc_uninit(); isReading = false; - - systemTask->PushMessage(System::Messages::BatteryMeasurementDone); } } - -void Battery::Register(Pinetime::System::SystemTask* systemTask) { - this->systemTask = systemTask; -} diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 8af27ea8ae..6f09b737a3 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -1,7 +1,8 @@ #pragma once #include #include -#include +#include +#include namespace Pinetime { namespace Controllers { @@ -10,8 +11,8 @@ namespace Pinetime { public: Battery(); + void Init(); void Update(); - void Register(System::SystemTask* systemTask); uint8_t PercentRemaining() const { return percentRemaining; @@ -33,6 +34,8 @@ namespace Pinetime { static Battery* instance; nrf_saadc_value_t saadc_value; + static constexpr uint32_t chargingPin = 12; + static constexpr uint32_t powerPresentPin = 19; static constexpr nrf_saadc_input_t batteryVoltageAdcInput = NRF_SAADC_INPUT_AIN7; uint16_t voltage = 0; uint8_t percentRemaining = 0; @@ -46,8 +49,6 @@ namespace Pinetime { static void AdcCallbackStatic(nrfx_saadc_evt_t const* event); bool isReading = false; - - Pinetime::System::SystemTask* systemTask = nullptr; }; } } diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 879421e7aa..5eb227bf00 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -42,19 +42,6 @@ NimbleController::NimbleController(Pinetime::System::SystemTask& systemTask, serviceDiscovery({¤tTimeClient, &alertNotificationClient}) { } -void nimble_on_reset(int reason) { - NRF_LOG_INFO("Resetting state; reason=%d\n", reason); -} - -void nimble_on_sync(void) { - int rc; - - rc = ble_hs_util_ensure_addr(0); - ASSERT(rc == 0); - - nptr->StartAdvertising(); -} - int GAPEventCallback(struct ble_gap_event* event, void* arg) { auto nimbleController = static_cast(arg); return nimbleController->OnGAPEvent(event); @@ -64,10 +51,6 @@ void NimbleController::Init() { while (!ble_hs_synced()) { } - nptr = this; - ble_hs_cfg.reset_cb = nimble_on_reset; - ble_hs_cfg.sync_cb = nimble_on_sync; - ble_svc_gap_init(); ble_svc_gatt_init(); @@ -81,31 +64,28 @@ void NimbleController::Init() { batteryInformationService.Init(); immediateAlertService.Init(); heartRateService.Init(); - - int rc; - rc = ble_hs_util_ensure_addr(0); - ASSERT(rc == 0); - rc = ble_hs_id_infer_auto(0, &addrType); - ASSERT(rc == 0); - rc = ble_svc_gap_device_name_set(deviceName); - ASSERT(rc == 0); - rc = ble_svc_gap_device_appearance_set(0xC2); - ASSERT(rc == 0); + int res; + res = ble_hs_util_ensure_addr(0); + ASSERT(res == 0); + res = ble_hs_id_infer_auto(0, &addrType); + ASSERT(res == 0); + res = ble_svc_gap_device_name_set(deviceName); + ASSERT(res == 0); Pinetime::Controllers::Ble::BleAddress address; - rc = ble_hs_id_copy_addr(addrType, address.data(), nullptr); - ASSERT(rc == 0); + res = ble_hs_id_copy_addr(addrType, address.data(), nullptr); + ASSERT(res == 0); bleController.AddressType((addrType == 0) ? Ble::AddressTypes::Public : Ble::AddressTypes::Random); bleController.Address(std::move(address)); - rc = ble_gatts_start(); - ASSERT(rc == 0); - - if (!ble_gap_adv_active() && !bleController.IsConnected()) - StartAdvertising(); + res = ble_gatts_start(); + ASSERT(res == 0); } void NimbleController::StartAdvertising() { - int rc; + if (bleController.IsConnected() || ble_gap_conn_active() || ble_gap_adv_active()) + return; + + ble_svc_gap_device_name_set(deviceName); /* set adv parameters */ struct ble_gap_adv_params adv_params; @@ -122,17 +102,11 @@ void NimbleController::StartAdvertising() { adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN; - /* fast advertise for 30 sec */ - if (fastAdvCount < 15) { - adv_params.itvl_min = 32; - adv_params.itvl_max = 47; - fastAdvCount++; - } else { - adv_params.itvl_min = 1636; - adv_params.itvl_max = 1651; - } fields.flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP; + // fields.uuids128 = BLE_UUID128(BLE_UUID128_DECLARE( + // 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + // 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff)); fields.uuids128 = &dfuServiceUuid; fields.num_uuids128 = 1; fields.uuids128_is_complete = 1; @@ -142,25 +116,28 @@ void NimbleController::StartAdvertising() { rsp_fields.name_len = strlen(deviceName); rsp_fields.name_is_complete = 1; - rc = ble_gap_adv_set_fields(&fields); - ASSERT(rc == 0); + ble_gap_adv_set_fields(&fields); + // ASSERT(res == 0); // TODO this one sometimes fails with error 22 (notsync) - rc = ble_gap_adv_rsp_set_fields(&rsp_fields); - ASSERT(rc == 0); + ble_gap_adv_rsp_set_fields(&rsp_fields); + // ASSERT(res == 0); - rc = ble_gap_adv_start(addrType, NULL, 2000, &adv_params, GAPEventCallback, this); - ASSERT(rc == 0); + ble_gap_adv_start(addrType, NULL, 180000, &adv_params, GAPEventCallback, this); + // ASSERT(res == 0);// TODO I've disabled these ASSERT as they sometime asserts and reset the mcu. + // For now, the advertising is restarted as soon as it ends. There may be a race condition + // that prevent the advertising from restarting reliably. + // I remove the assert to prevent this uncesseray crash, but in the long term, the management of + // the advertising should be improve (better error handling, and advertise for 3 minutes after + // the application has been woken up, for example. } int NimbleController::OnGAPEvent(ble_gap_event* event) { switch (event->type) { case BLE_GAP_EVENT_ADV_COMPLETE: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_ADV_COMPLETE"); - NRF_LOG_INFO("reason=%d; status=%d", event->adv_complete.reason, event->connect.status); - StartAdvertising(); + NRF_LOG_INFO("advertise complete; reason=%dn status=%d", event->adv_complete.reason, event->connect.status); break; - - case BLE_GAP_EVENT_CONNECT: + case BLE_GAP_EVENT_CONNECT: { NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_CONNECT"); /* A new connection was established or a connection attempt failed. */ @@ -168,44 +145,35 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { if (event->connect.status != 0) { /* Connection failed; resume advertising. */ - currentTimeClient.Reset(); - alertNotificationClient.Reset(); - connectionHandle = BLE_HS_CONN_HANDLE_NONE; - bleController.Disconnect(); - fastAdvCount = 0; StartAdvertising(); + bleController.Disconnect(); } else { - connectionHandle = event->connect.conn_handle; bleController.Connect(); systemTask.PushMessage(Pinetime::System::Messages::BleConnected); - // Service discovery is deferred via systemtask + connectionHandle = event->connect.conn_handle; + // Service discovery is deffered via systemtask } - break; - + } break; case BLE_GAP_EVENT_DISCONNECT: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_DISCONNECT"); - NRF_LOG_INFO("disconnect reason=%d", event->disconnect.reason); + NRF_LOG_INFO("disconnect; reason=%d", event->disconnect.reason); /* Connection terminated; resume advertising. */ currentTimeClient.Reset(); alertNotificationClient.Reset(); connectionHandle = BLE_HS_CONN_HANDLE_NONE; bleController.Disconnect(); - fastAdvCount = 0; StartAdvertising(); break; - case BLE_GAP_EVENT_CONN_UPDATE: NRF_LOG_INFO("Advertising event : BLE_GAP_EVENT_CONN_UPDATE"); /* The central has updated the connection parameters. */ - NRF_LOG_INFO("update status=%d ", event->conn_update.status); + NRF_LOG_INFO("connection updated; status=%d ", event->conn_update.status); break; - case BLE_GAP_EVENT_ENC_CHANGE: /* Encryption has been enabled or disabled for this connection. */ NRF_LOG_INFO("encryption change event; status=%d ", event->enc_change.status); - break; - + return 0; case BLE_GAP_EVENT_SUBSCRIBE: NRF_LOG_INFO("subscribe event; conn_handle=%d attr_handle=%d " "reason=%d prevn=%d curn=%d previ=%d curi=???\n", @@ -215,12 +183,10 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { event->subscribe.prev_notify, event->subscribe.cur_notify, event->subscribe.prev_indicate); - break; - + return 0; case BLE_GAP_EVENT_MTU: - NRF_LOG_INFO("mtu update event; conn_handle=%d cid=%d mtu=%d\n", - event->mtu.conn_handle, event->mtu.channel_id, event->mtu.value); - break; + NRF_LOG_INFO("mtu update event; conn_handle=%d cid=%d mtu=%d\n", event->mtu.conn_handle, event->mtu.channel_id, event->mtu.value); + return 0; case BLE_GAP_EVENT_REPEAT_PAIRING: { /* We already have a bond with the peer, but it is attempting to @@ -251,7 +217,8 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { notifSize); alertNotificationClient.OnNotification(event); - } break; + return 0; + } /* Attribute data is contained in event->notify_rx.attr_data. */ default: @@ -262,9 +229,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { } void NimbleController::StartDiscovery() { - if (connectionHandle != BLE_HS_CONN_HANDLE_NONE) { - serviceDiscovery.StartDiscovery(connectionHandle); - } + serviceDiscovery.StartDiscovery(connectionHandle); } uint16_t NimbleController::connHandle() { @@ -272,7 +237,7 @@ uint16_t NimbleController::connHandle() { } void NimbleController::NotifyBatteryLevel(uint8_t level) { - if (connectionHandle != BLE_HS_CONN_HANDLE_NONE) { + if(connectionHandle != BLE_HS_CONN_HANDLE_NONE) { batteryInformationService.NotifyBatteryLevel(connectionHandle, level); } } diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 473bb1aff6..0cfe983c6b 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -72,10 +72,6 @@ namespace Pinetime { uint16_t connHandle(); void NotifyBatteryLevel(uint8_t level); - void RestartFastAdv() { - fastAdvCount = 0; - } - private: static constexpr const char* deviceName = "InfiniTime"; Pinetime::System::SystemTask& systemTask; @@ -98,7 +94,6 @@ namespace Pinetime { uint8_t addrType; // 1 = Random, 0 = PUBLIC uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; - uint8_t fastAdvCount = 0; ble_uuid128_t dfuServiceUuid { .u {.type = BLE_UUID_TYPE_128}, @@ -106,7 +101,5 @@ namespace Pinetime { ServiceDiscovery serviceDiscovery; }; - - static NimbleController* nptr; } } diff --git a/src/components/brightness/BrightnessController.cpp b/src/components/brightness/BrightnessController.cpp index 6c524679c1..8ad987d1f4 100644 --- a/src/components/brightness/BrightnessController.cpp +++ b/src/components/brightness/BrightnessController.cpp @@ -1,13 +1,13 @@ #include "BrightnessController.h" #include #include "displayapp/screens/Symbols.h" -#include "drivers/PinMap.h" + using namespace Pinetime::Controllers; void BrightnessController::Init() { - nrf_gpio_cfg_output(PinMap::LcdBacklightLow); - nrf_gpio_cfg_output(PinMap::LcdBacklightMedium); - nrf_gpio_cfg_output(PinMap::LcdBacklightHigh); + nrf_gpio_cfg_output(pinLcdBacklight1); + nrf_gpio_cfg_output(pinLcdBacklight2); + nrf_gpio_cfg_output(pinLcdBacklight3); Set(level); } @@ -16,24 +16,24 @@ void BrightnessController::Set(BrightnessController::Levels level) { switch (level) { default: case Levels::High: - nrf_gpio_pin_clear(PinMap::LcdBacklightLow); - nrf_gpio_pin_clear(PinMap::LcdBacklightMedium); - nrf_gpio_pin_clear(PinMap::LcdBacklightHigh); + nrf_gpio_pin_clear(pinLcdBacklight1); + nrf_gpio_pin_clear(pinLcdBacklight2); + nrf_gpio_pin_clear(pinLcdBacklight3); break; case Levels::Medium: - nrf_gpio_pin_clear(PinMap::LcdBacklightLow); - nrf_gpio_pin_clear(PinMap::LcdBacklightMedium); - nrf_gpio_pin_set(PinMap::LcdBacklightHigh); + nrf_gpio_pin_clear(pinLcdBacklight1); + nrf_gpio_pin_clear(pinLcdBacklight2); + nrf_gpio_pin_set(pinLcdBacklight3); break; case Levels::Low: - nrf_gpio_pin_clear(PinMap::LcdBacklightLow); - nrf_gpio_pin_set(PinMap::LcdBacklightMedium); - nrf_gpio_pin_set(PinMap::LcdBacklightHigh); + nrf_gpio_pin_clear(pinLcdBacklight1); + nrf_gpio_pin_set(pinLcdBacklight2); + nrf_gpio_pin_set(pinLcdBacklight3); break; case Levels::Off: - nrf_gpio_pin_set(PinMap::LcdBacklightLow); - nrf_gpio_pin_set(PinMap::LcdBacklightMedium); - nrf_gpio_pin_set(PinMap::LcdBacklightHigh); + nrf_gpio_pin_set(pinLcdBacklight1); + nrf_gpio_pin_set(pinLcdBacklight2); + nrf_gpio_pin_set(pinLcdBacklight3); break; } } diff --git a/src/components/brightness/BrightnessController.h b/src/components/brightness/BrightnessController.h index 0d7ac2ffa6..c47158a910 100644 --- a/src/components/brightness/BrightnessController.h +++ b/src/components/brightness/BrightnessController.h @@ -22,6 +22,9 @@ namespace Pinetime { const char* ToString(); private: + static constexpr uint8_t pinLcdBacklight1 = 14; + static constexpr uint8_t pinLcdBacklight2 = 22; + static constexpr uint8_t pinLcdBacklight3 = 23; Levels level = Levels::High; Levels backupLevel = Levels::High; }; diff --git a/src/components/motor/MotorController.cpp b/src/components/motor/MotorController.cpp index 42057a860d..b25e6bc829 100644 --- a/src/components/motor/MotorController.cpp +++ b/src/components/motor/MotorController.cpp @@ -2,7 +2,6 @@ #include #include "systemtask/SystemTask.h" #include "app_timer.h" -#include "drivers/PinMap.h" APP_TIMER_DEF(shortVibTimer); APP_TIMER_DEF(longVibTimer); @@ -13,8 +12,8 @@ MotorController::MotorController(Controllers::Settings& settingsController) : se } void MotorController::Init() { - nrf_gpio_cfg_output(PinMap::Motor); - nrf_gpio_pin_set(PinMap::Motor); + nrf_gpio_cfg_output(pinMotor); + nrf_gpio_pin_set(pinMotor); app_timer_init(); app_timer_create(&shortVibTimer, APP_TIMER_MODE_SINGLE_SHOT, StopMotor); @@ -31,7 +30,7 @@ void MotorController::RunForDuration(uint8_t motorDuration) { return; } - nrf_gpio_pin_clear(PinMap::Motor); + nrf_gpio_pin_clear(pinMotor); app_timer_start(shortVibTimer, APP_TIMER_TICKS(motorDuration), nullptr); } @@ -45,9 +44,9 @@ void MotorController::StartRinging() { void MotorController::StopRinging() { app_timer_stop(longVibTimer); - nrf_gpio_pin_set(PinMap::Motor); + nrf_gpio_pin_set(pinMotor); } void MotorController::StopMotor(void* p_context) { - nrf_gpio_pin_set(PinMap::Motor); + nrf_gpio_pin_set(pinMotor); } diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index cf78088ec3..d2c9fe5f2c 100644 --- a/src/components/motor/MotorController.h +++ b/src/components/motor/MotorController.h @@ -1,10 +1,12 @@ #pragma once #include +#include "app_timer.h" #include "components/settings/Settings.h" namespace Pinetime { namespace Controllers { + static constexpr uint8_t pinMotor = 16; class MotorController { public: diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index a54ba9760e..a294ab7840 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -114,7 +114,7 @@ namespace Pinetime { }; void setWakeUpMode(WakeUpMode wakeUp, bool enabled) { - if (enabled != isWakeUpModeOn(wakeUp)) { + if (!isWakeUpModeOn(wakeUp)) { settingsChanged = true; } settings.wakeUpMode.set(static_cast(wakeUp), enabled); diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 9d47310197..33c67e229c 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -139,6 +139,9 @@ void DisplayApp::InitHw() { brightnessController.Set(settingsController.GetBrightness()); } +uint32_t acc = 0; +uint32_t count = 0; +bool toggle = true; void DisplayApp::Refresh() { TickType_t queueTimeout; TickType_t delta; @@ -194,6 +197,9 @@ void DisplayApp::Refresh() { // clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected : // Screens::Clock::BleConnectionStates::NotConnected); break; + case Messages::UpdateBatteryLevel: + batteryController.Update(); + break; case Messages::NewNotification: LoadApp(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down); break; diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index 7a20262988..17612ef057 100644 --- a/src/displayapp/DisplayAppRecovery.cpp +++ b/src/displayapp/DisplayAppRecovery.cpp @@ -5,7 +5,6 @@ #include #include #include "displayapp/icons/infinitime/infinitime-nb.c" -#include "components/ble/BleController.h" using namespace Pinetime::Applications; diff --git a/src/displayapp/DisplayAppRecovery.h b/src/displayapp/DisplayAppRecovery.h index 4184ea49da..8b2bc7f515 100644 --- a/src/displayapp/DisplayAppRecovery.h +++ b/src/displayapp/DisplayAppRecovery.h @@ -6,38 +6,32 @@ #include #include #include "components/gfx/Gfx.h" +#include "components/battery/BatteryController.h" +#include "components/brightness/BrightnessController.h" +#include "components/ble/BleController.h" +#include "components/datetime/DateTimeController.h" +#include "components/ble/NotificationManager.h" +#include "components/firmwarevalidator/FirmwareValidator.h" #include "drivers/Cst816s.h" #include #include +#include +#include #include +#include #include "TouchEvents.h" #include "Apps.h" #include "Messages.h" #include "DummyLittleVgl.h" +#include "components/timer/TimerController.h" namespace Pinetime { - namespace Drivers { - class St7789; - class Cst816S; - class WatchdogView; - } - namespace Controllers { - class Settings; - class Battery; - class Ble; - class DateTime; - class NotificationManager; - class HeartRateController; - class MotionController; - class TouchHandler; - class MotorController; - class TimerController; - } - namespace System { class SystemTask; }; - + namespace Controllers { + class TouchHandler; + } namespace Applications { class DisplayApp { public: diff --git a/src/displayapp/Messages.h b/src/displayapp/Messages.h index d48b646fe0..c23cdfe3f7 100644 --- a/src/displayapp/Messages.h +++ b/src/displayapp/Messages.h @@ -7,6 +7,7 @@ namespace Pinetime { GoToRunning, UpdateDateTime, UpdateBleConnection, + UpdateBatteryLevel, TouchEvent, ButtonPushed, NewNotification, diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index ad9af15344..91c2651236 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -55,6 +55,8 @@ BatteryInfo::~BatteryInfo() { void BatteryInfo::Refresh() { + batteryController.Update(); + batteryPercent = batteryController.PercentRemaining(); batteryVoltage = batteryController.Voltage(); diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 417dff00d2..22eb290e8e 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -152,7 +152,7 @@ Notifications::NotificationItem::NotificationItem(const char* title, uint8_t notifNb, Modes mode, Pinetime::Controllers::AlertNotificationService& alertNotificationService) - : mode {mode}, alertNotificationService {alertNotificationService} { + : notifNr {notifNr}, notifNb {notifNb}, mode {mode}, alertNotificationService {alertNotificationService} { lv_obj_t* container1 = lv_cont_create(lv_scr_act(), NULL); lv_obj_set_style_local_bg_color(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, lv_color_hex(0x222222)); diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index 0b5271e72f..f6f8b4c35b 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -43,13 +43,21 @@ namespace Pinetime { void OnCallButtonEvent(lv_obj_t*, lv_event_t event); private: + uint8_t notifNr = 0; + uint8_t notifNb = 0; + char pageText[4]; + lv_obj_t* container1; + lv_obj_t* t1; + lv_obj_t* l1; + lv_obj_t* l2; lv_obj_t* bt_accept; lv_obj_t* bt_mute; lv_obj_t* bt_reject; lv_obj_t* label_accept; lv_obj_t* label_mute; lv_obj_t* label_reject; + lv_obj_t* bottomPlaceholder; Modes mode; Pinetime::Controllers::AlertNotificationService& alertNotificationService; bool running = true; diff --git a/src/displayapp/screens/settings/Settings.cpp b/src/displayapp/screens/settings/Settings.cpp index e3319f030a..f82b03c1a1 100644 --- a/src/displayapp/screens/settings/Settings.cpp +++ b/src/displayapp/screens/settings/Settings.cpp @@ -50,8 +50,8 @@ std::unique_ptr Settings::CreateScreen2() { std::array applications {{ {Symbols::shoe, "Steps", Apps::SettingSteps}, {Symbols::batteryHalf, "Battery", Apps::BatteryInfo}, - {Symbols::paintbrush, "PTS Colors", Apps::SettingPineTimeStyle}, {Symbols::check, "Firmware", Apps::FirmwareValidation}, + {Symbols::list, "About", Apps::SysInfo}, }}; return std::make_unique(1, 3, app, settingsController, applications); @@ -60,7 +60,7 @@ std::unique_ptr Settings::CreateScreen2() { std::unique_ptr Settings::CreateScreen3() { std::array applications {{ - {Symbols::list, "About", Apps::SysInfo}, + {Symbols::paintbrush, "PTS Colors", Apps::SettingPineTimeStyle}, {Symbols::none, "None", Apps::None}, {Symbols::none, "None", Apps::None}, {Symbols::none, "None", Apps::None}, diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp index 1ff163b0c2..b8f8e45df9 100644 --- a/src/drivers/Cst816s.cpp +++ b/src/drivers/Cst816s.cpp @@ -3,7 +3,6 @@ #include #include #include -#include "drivers/PinMap.h" using namespace Pinetime::Drivers; @@ -19,12 +18,12 @@ Cst816S::Cst816S(TwiMaster& twiMaster, uint8_t twiAddress) : twiMaster {twiMaste } void Cst816S::Init() { - nrf_gpio_cfg_output(PinMap::Cst816sReset); - nrf_gpio_pin_set(PinMap::Cst816sReset); + nrf_gpio_cfg_output(pinReset); + nrf_gpio_pin_set(pinReset); vTaskDelay(50); - nrf_gpio_pin_clear(PinMap::Cst816sReset); + nrf_gpio_pin_clear(pinReset); vTaskDelay(5); - nrf_gpio_pin_set(PinMap::Cst816sReset); + nrf_gpio_pin_set(pinReset); vTaskDelay(50); // Wake the touchpanel up @@ -81,9 +80,9 @@ Cst816S::TouchInfos Cst816S::GetTouchInfo() { } void Cst816S::Sleep() { - nrf_gpio_pin_clear(PinMap::Cst816sReset); + nrf_gpio_pin_clear(pinReset); vTaskDelay(5); - nrf_gpio_pin_set(PinMap::Cst816sReset); + nrf_gpio_pin_set(pinReset); vTaskDelay(50); static constexpr uint8_t sleepValue = 0x03; twiMaster.Write(twiAddress, 0xA5, &sleepValue, 1); diff --git a/src/drivers/Cst816s.h b/src/drivers/Cst816s.h index 7b46c5d582..d4c17bb823 100644 --- a/src/drivers/Cst816s.h +++ b/src/drivers/Cst816s.h @@ -36,6 +36,9 @@ namespace Pinetime { void Wakeup(); private: + static constexpr uint8_t pinIrq = 28; + static constexpr uint8_t pinReset = 10; + // Unused/Unavailable commented out static constexpr uint8_t gestureIndex = 1; static constexpr uint8_t touchPointNumIndex = 2; diff --git a/src/drivers/PinMap.h b/src/drivers/PinMap.h deleted file mode 100644 index 57964020c6..0000000000 --- a/src/drivers/PinMap.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -namespace Pinetime { - namespace PinMap { - - #ifdef WATCH_P8 - // COLMI P8 - static constexpr uint8_t Charging = 19; - static constexpr uint8_t Cst816sReset = 13; - static constexpr uint8_t Button = 17; - #else - // Pinetime - static constexpr uint8_t Charging = 12; - static constexpr uint8_t Cst816sReset = 10; - static constexpr uint8_t Button = 13; - #endif - - static constexpr uint8_t Cst816sIrq = 28; - static constexpr uint8_t PowerPresent = 19; - - static constexpr uint8_t Motor = 16; - - static constexpr uint8_t LcdBacklightLow = 14; - static constexpr uint8_t LcdBacklightMedium = 22; - static constexpr uint8_t LcdBacklightHigh = 23; - - static constexpr uint8_t SpiSck = 2; - static constexpr uint8_t SpiMosi = 3; - static constexpr uint8_t SpiMiso = 4; - - static constexpr uint8_t SpiFlashCsn = 5; - static constexpr uint8_t SpiLcdCsn = 25; - static constexpr uint8_t LcdDataCommand = 18; - - static constexpr uint8_t TwiScl = 7; - static constexpr uint8_t TwiSda = 6; - } -} diff --git a/src/main.cpp b/src/main.cpp index 7d4f0858c5..6a7f5eb342 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -43,9 +43,7 @@ #include "drivers/St7789.h" #include "drivers/TwiMaster.h" #include "drivers/Cst816s.h" -#include "drivers/PinMap.h" #include "systemtask/SystemTask.h" -#include "drivers/PinMap.h" #include "touchhandler/TouchHandler.h" #if NRF_LOG_ENABLED @@ -56,6 +54,14 @@ Pinetime::Logging::NrfLogger logger; Pinetime::Logging::DummyLogger logger; #endif +static constexpr uint8_t pinSpiSck = 2; +static constexpr uint8_t pinSpiMosi = 3; +static constexpr uint8_t pinSpiMiso = 4; +static constexpr uint8_t pinSpiFlashCsn = 5; +static constexpr uint8_t pinLcdCsn = 25; +static constexpr uint8_t pinLcdDataCommand = 18; +static constexpr uint8_t pinTwiScl = 7; +static constexpr uint8_t pinTwiSda = 6; static constexpr uint8_t touchPanelTwiAddress = 0x15; static constexpr uint8_t motionSensorTwiAddress = 0x18; static constexpr uint8_t heartRateSensorTwiAddress = 0x44; @@ -64,30 +70,33 @@ Pinetime::Drivers::SpiMaster spi {Pinetime::Drivers::SpiMaster::SpiModule::SPI0, {Pinetime::Drivers::SpiMaster::BitOrder::Msb_Lsb, Pinetime::Drivers::SpiMaster::Modes::Mode3, Pinetime::Drivers::SpiMaster::Frequencies::Freq8Mhz, - Pinetime::PinMap::SpiSck, - Pinetime::PinMap::SpiMosi, - Pinetime::PinMap::SpiMiso}}; + pinSpiSck, + pinSpiMosi, + pinSpiMiso}}; -Pinetime::Drivers::Spi lcdSpi {spi, Pinetime::PinMap::SpiLcdCsn}; -Pinetime::Drivers::St7789 lcd {lcdSpi, Pinetime::PinMap::LcdDataCommand}; +Pinetime::Drivers::Spi lcdSpi {spi, pinLcdCsn}; +Pinetime::Drivers::St7789 lcd {lcdSpi, pinLcdDataCommand}; -Pinetime::Drivers::Spi flashSpi {spi, Pinetime::PinMap::SpiFlashCsn}; +Pinetime::Drivers::Spi flashSpi {spi, pinSpiFlashCsn}; Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; // The TWI device should work @ up to 400Khz but there is a HW bug which prevent it from // respecting correct timings. According to erratas heet, this magic value makes it run // at ~390Khz with correct timings. static constexpr uint32_t MaxTwiFrequencyWithoutHardwareBug {0x06200000}; -Pinetime::Drivers::TwiMaster twiMaster {NRF_TWIM1, MaxTwiFrequencyWithoutHardwareBug, Pinetime::PinMap::TwiSda, Pinetime::PinMap::TwiScl}; +Pinetime::Drivers::TwiMaster twiMaster {NRF_TWIM1, MaxTwiFrequencyWithoutHardwareBug, pinTwiSda, pinTwiScl}; Pinetime::Drivers::Cst816S touchPanel {twiMaster, touchPanelTwiAddress}; #ifdef PINETIME_IS_RECOVERY +static constexpr bool isFactory = true; #include "displayapp/DummyLittleVgl.h" #include "displayapp/DisplayAppRecovery.h" +Pinetime::Components::LittleVgl lvgl {lcd, touchPanel}; #else +static constexpr bool isFactory = false; #include "displayapp/LittleVgl.h" #include "displayapp/DisplayApp.h" -#endif Pinetime::Components::LittleVgl lvgl {lcd, touchPanel}; +#endif Pinetime::Drivers::Bma421 motionSensor {twiMaster, motionSensorTwiAddress}; Pinetime::Drivers::Hrs3300 heartRateSensor {twiMaster, heartRateSensorTwiAddress}; @@ -96,8 +105,10 @@ TimerHandle_t debounceTimer; TimerHandle_t debounceChargeTimer; Pinetime::Controllers::Battery batteryController; Pinetime::Controllers::Ble bleController; -static constexpr uint8_t pinTouchIrq = Pinetime::PinMap::Cst816sIrq; -static constexpr uint8_t pinPowerPresentIrq = Pinetime::PinMap::PowerPresent; +void ble_manager_set_ble_connection_callback(void (*connection)()); +void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); +static constexpr uint8_t pinTouchIrq = 28; +static constexpr uint8_t pinPowerPresentIrq = 19; Pinetime::Controllers::HeartRateController heartRateController; Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController); @@ -157,14 +168,14 @@ Pinetime::System::SystemTask systemTask(spi, touchHandler); void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { - if (pin == Pinetime::PinMap::Cst816sIrq) { + if (pin == pinTouchIrq) { systemTask.OnTouchEvent(); return; } BaseType_t xHigherPriorityTaskWoken = pdFALSE; - if (pin == Pinetime::PinMap::PowerPresent and action == NRF_GPIOTE_POLARITY_TOGGLE) { + if (pin == pinPowerPresentIrq and action == NRF_GPIOTE_POLARITY_TOGGLE) { xTimerStartFromISR(debounceChargeTimer, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); return; @@ -297,18 +308,18 @@ int main(void) { nrf_drv_clock_init(); // Unblock i2c? - nrf_gpio_cfg(Pinetime::PinMap::TwiScl, + nrf_gpio_cfg(pinTwiScl, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_DISCONNECT, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0D1, NRF_GPIO_PIN_NOSENSE); - nrf_gpio_pin_set(Pinetime::PinMap::TwiScl); + nrf_gpio_pin_set(pinTwiScl); for (uint8_t i = 0; i < 16; i++) { - nrf_gpio_pin_toggle(Pinetime::PinMap::TwiScl); + nrf_gpio_pin_toggle(pinTwiScl); nrf_delay_us(5); } - nrf_gpio_cfg_default(Pinetime::PinMap::TwiScl); + nrf_gpio_cfg_default(pinTwiScl); debounceTimer = xTimerCreate("debounceTimer", 200, pdFALSE, (void*) 0, DebounceTimerCallback); debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, (void*) 0, DebounceTimerChargeCallback); diff --git a/src/recoveryLoader.cpp b/src/recoveryLoader.cpp index acec14c8ad..9818179dee 100644 --- a/src/recoveryLoader.cpp +++ b/src/recoveryLoader.cpp @@ -15,7 +15,6 @@ #include #include #include "recoveryImage.h" -#include "drivers/PinMap.h" #include "displayapp/icons/infinitime/infinitime-nb.c" #include "components/rle/RleDecoder.h" @@ -28,6 +27,12 @@ Pinetime::Logging::NrfLogger logger; Pinetime::Logging::DummyLogger logger; #endif +static constexpr uint8_t pinSpiSck = 2; +static constexpr uint8_t pinSpiMosi = 3; +static constexpr uint8_t pinSpiMiso = 4; +static constexpr uint8_t pinSpiFlashCsn = 5; +static constexpr uint8_t pinLcdCsn = 25; +static constexpr uint8_t pinLcdDataCommand = 18; static constexpr uint8_t displayWidth = 240; static constexpr uint8_t displayHeight = 240; @@ -40,14 +45,14 @@ Pinetime::Drivers::SpiMaster spi {Pinetime::Drivers::SpiMaster::SpiModule::SPI0, {Pinetime::Drivers::SpiMaster::BitOrder::Msb_Lsb, Pinetime::Drivers::SpiMaster::Modes::Mode3, Pinetime::Drivers::SpiMaster::Frequencies::Freq8Mhz, - Pinetime::PinMap::SpiSck, - Pinetime::PinMap::SpiMosi, - Pinetime::PinMap::SpiMiso}}; -Pinetime::Drivers::Spi flashSpi {spi, Pinetime::PinMap::SpiFlashCsn}; + pinSpiSck, + pinSpiMosi, + pinSpiMiso}}; +Pinetime::Drivers::Spi flashSpi {spi, pinSpiFlashCsn}; Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; -Pinetime::Drivers::Spi lcdSpi {spi, Pinetime::PinMap::SpiLcdCsn}; -Pinetime::Drivers::St7789 lcd {lcdSpi, Pinetime::PinMap::LcdDataCommand}; +Pinetime::Drivers::Spi lcdSpi {spi, pinLcdCsn}; +Pinetime::Drivers::St7789 lcd {lcdSpi, pinLcdDataCommand}; Pinetime::Components::Gfx gfx {lcd}; Pinetime::Controllers::BrightnessController brightnessController; diff --git a/src/systemtask/Messages.h b/src/systemtask/Messages.h index bd1de234c2..93fcf9407a 100644 --- a/src/systemtask/Messages.h +++ b/src/systemtask/Messages.h @@ -22,9 +22,7 @@ namespace Pinetime { OnNewDay, OnChargingEvent, SetOffAlarm, - StopRinging, - MeasureBatteryTimerExpired, - BatteryMeasurementDone, + StopRinging }; } } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 24ee4bda3e..534f551092 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -21,10 +21,8 @@ #include "drivers/SpiNorFlash.h" #include "drivers/TwiMaster.h" #include "drivers/Hrs3300.h" -#include "drivers/PinMap.h" #include "main.h" - #include using namespace Pinetime::System; @@ -49,11 +47,6 @@ void IdleTimerCallback(TimerHandle_t xTimer) { sysTask->OnIdle(); } -void MeasureBatteryTimerCallback(TimerHandle_t xTimer) { - auto* sysTask = static_cast(pvTimerGetTimerID(xTimer)); - sysTask->PushMessage(Pinetime::System::Messages::MeasureBatteryTimerExpired); -} - SystemTask::SystemTask(Drivers::SpiMaster& spi, Drivers::St7789& lcd, Pinetime::Drivers::SpiNorFlash& spiNorFlash, @@ -130,13 +123,13 @@ void SystemTask::Work() { fs.Init(); nimbleController.Init(); + nimbleController.StartAdvertising(); lcd.Init(); twiMaster.Init(); touchPanel.Init(); dateTimeController.Register(this); - batteryController.Register(this); - batteryController.Update(); + batteryController.Init(); motorController.Init(); motionSensor.SoftReset(); timerController.Register(this); @@ -154,11 +147,13 @@ void SystemTask::Work() { displayApp.Register(this); displayApp.Start(); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); + heartRateSensor.Init(); heartRateSensor.Disable(); heartRateApp.Start(); - nrf_gpio_cfg_sense_input(PinMap::Button, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pulldown, (nrf_gpio_pin_sense_t) GPIO_PIN_CNF_SENSE_High); + nrf_gpio_cfg_sense_input(pinButton, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pulldown, (nrf_gpio_pin_sense_t) GPIO_PIN_CNF_SENSE_High); nrf_gpio_cfg_output(15); nrf_gpio_pin_set(15); @@ -169,9 +164,9 @@ void SystemTask::Work() { pinConfig.sense = (nrf_gpiote_polarity_t) NRF_GPIOTE_POLARITY_HITOLO; pinConfig.pull = (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pulldown; - nrfx_gpiote_in_init(PinMap::Button, &pinConfig, nrfx_gpiote_evt_handler); + nrfx_gpiote_in_init(pinButton, &pinConfig, nrfx_gpiote_evt_handler); - nrf_gpio_cfg_sense_input(PinMap::Cst816sIrq, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pullup, (nrf_gpio_pin_sense_t) GPIO_PIN_CNF_SENSE_Low); + nrf_gpio_cfg_sense_input(pinTouchIrq, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pullup, (nrf_gpio_pin_sense_t) GPIO_PIN_CNF_SENSE_Low); pinConfig.skip_gpio_setup = true; pinConfig.hi_accuracy = false; @@ -179,26 +174,24 @@ void SystemTask::Work() { pinConfig.sense = (nrf_gpiote_polarity_t) NRF_GPIOTE_POLARITY_HITOLO; pinConfig.pull = (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pullup; - nrfx_gpiote_in_init(PinMap::Cst816sIrq, &pinConfig, nrfx_gpiote_evt_handler); + nrfx_gpiote_in_init(pinTouchIrq, &pinConfig, nrfx_gpiote_evt_handler); pinConfig.sense = NRF_GPIOTE_POLARITY_TOGGLE; pinConfig.pull = NRF_GPIO_PIN_NOPULL; pinConfig.is_watcher = false; pinConfig.hi_accuracy = false; pinConfig.skip_gpio_setup = true; - nrfx_gpiote_in_init(PinMap::PowerPresent, &pinConfig, nrfx_gpiote_evt_handler); + nrfx_gpiote_in_init(pinPowerPresentIrq, &pinConfig, nrfx_gpiote_evt_handler); - if (nrf_gpio_pin_read(PinMap::PowerPresent)) { - nrf_gpio_cfg_sense_input(PinMap::PowerPresent, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW); + if (nrf_gpio_pin_read(pinPowerPresentIrq)) { + nrf_gpio_cfg_sense_input(pinPowerPresentIrq, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW); } else { - nrf_gpio_cfg_sense_input(PinMap::PowerPresent, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH); + nrf_gpio_cfg_sense_input(pinPowerPresentIrq, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH); } idleTimer = xTimerCreate("idleTimer", pdMS_TO_TICKS(2000), pdFALSE, this, IdleTimerCallback); dimTimer = xTimerCreate("dimTimer", pdMS_TO_TICKS(settingsController.GetScreenTimeOut() - 2000), pdFALSE, this, DimTimerCallback); - measureBatteryTimer = xTimerCreate("measureBattery", batteryMeasurementPeriod, pdTRUE, this, MeasureBatteryTimerCallback); xTimerStart(dimTimer, 0); - xTimerStart(measureBatteryTimer, portMAX_DELAY); // Suppress endless loop diagnostic #pragma clang diagnostic push @@ -208,6 +201,11 @@ void SystemTask::Work() { uint8_t msg; if (xQueueReceive(systemTasksMsgQueue, &msg, 100)) { + + batteryController.Update(); + // the battery does not emit events when changing charge levels, so we piggyback + // on any system event to read and update the current values + Messages message = static_cast(msg); switch (message) { case Messages::EnableSleeping: @@ -231,16 +229,15 @@ void SystemTask::Work() { touchPanel.Wakeup(); } + nimbleController.StartAdvertising(); xTimerStart(dimTimer, 0); spiNorFlash.Wakeup(); lcd.Wakeup(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToRunning); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp); - if (!bleController.IsConnected()) - nimbleController.RestartFastAdv(); - isSleeping = false; isWakingUp = false; isDimmed = false; @@ -343,18 +340,8 @@ void SystemTask::Work() { stepCounterMustBeReset = true; break; case Messages::OnChargingEvent: - batteryController.Update(); motorController.RunForDuration(15); - break; - case Messages::MeasureBatteryTimerExpired: - sendBatteryNotification = true; - batteryController.Update(); - break; - case Messages::BatteryMeasurementDone: - if (sendBatteryNotification) { - sendBatteryNotification = false; - nimbleController.NotifyBatteryLevel(batteryController.PercentRemaining()); - } + // Battery level is updated on every message - there's no need to do anything break; default: @@ -366,17 +353,22 @@ void SystemTask::Work() { if (bleDiscoveryTimer == 0) { isBleDiscoveryTimerRunning = false; // Services discovery is deffered from 3 seconds to avoid the conflicts between the host communicating with the - // target and vice-versa. I'm not sure if this is the right way to handle this... + // tharget and vice-versa. I'm not sure if this is the right way to handle this... nimbleController.StartDiscovery(); } else { bleDiscoveryTimer--; } } + if (xTaskGetTickCount() - batteryNotificationTick > batteryNotificationPeriod) { + nimbleController.NotifyBatteryLevel(batteryController.PercentRemaining()); + batteryNotificationTick = xTaskGetTickCount(); + } + monitor.Process(); uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); dateTimeController.UpdateTime(systick_counter); - if (!nrf_gpio_pin_read(PinMap::Button)) + if (!nrf_gpio_pin_read(pinButton)) watchdog.Kick(); } // Clear diagnostic suppression diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index 9e7e5e8ce5..cbd98d26cd 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -8,7 +8,6 @@ #include #include #include -#include #include #include "SystemMonitor.h" @@ -124,6 +123,15 @@ namespace Pinetime { Pinetime::Controllers::TouchHandler& touchHandler; Pinetime::Controllers::NimbleController nimbleController; + static constexpr uint8_t pinSpiSck = 2; + static constexpr uint8_t pinSpiMosi = 3; + static constexpr uint8_t pinSpiMiso = 4; + static constexpr uint8_t pinSpiCsn = 25; + static constexpr uint8_t pinLcdDataCommand = 18; + static constexpr uint8_t pinButton = 13; + static constexpr uint8_t pinTouchIrq = 28; + static constexpr uint8_t pinPowerPresentIrq = 19; + static void Process(void* instance); void Work(); void ReloadIdleTimer(); @@ -131,15 +139,13 @@ namespace Pinetime { uint8_t bleDiscoveryTimer = 0; TimerHandle_t dimTimer; TimerHandle_t idleTimer; - TimerHandle_t measureBatteryTimer; - bool sendBatteryNotification = false; bool doNotGoToSleep = false; void GoToRunning(); void UpdateMotion(); bool stepCounterMustBeReset = false; - static constexpr TickType_t batteryMeasurementPeriod = pdMS_TO_TICKS(10 * 60 * 1000); - TickType_t lastBatteryNotificationTime = 0; + static constexpr TickType_t batteryNotificationPeriod = 1000 * 60 * 10; // 1 tick ~= 1ms. 1ms * 60 * 10 = 10 minutes + TickType_t batteryNotificationTick = 0; #if configUSE_TRACE_FACILITY == 1 SystemMonitor monitor; From 7af7db74cde6e8ab23e2e261049cf14396e1e682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Milants?= Date: Sat, 18 Sep 2021 17:20:33 +0200 Subject: [PATCH 40/40] Fix DisplayAppRecovery : add AlarmController to ctor(). --- src/displayapp/DisplayAppRecovery.cpp | 1 + src/displayapp/DisplayAppRecovery.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index 7a20262988..a42d81a2e5 100644 --- a/src/displayapp/DisplayAppRecovery.cpp +++ b/src/displayapp/DisplayAppRecovery.cpp @@ -22,6 +22,7 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, Pinetime::Controllers::MotorController& motorController, Pinetime::Controllers::MotionController& motionController, Pinetime::Controllers::TimerController& timerController, + Pinetime::Controllers::AlarmController& alarmController, Pinetime::Controllers::TouchHandler& touchHandler) : lcd {lcd}, bleController {bleController} { diff --git a/src/displayapp/DisplayAppRecovery.h b/src/displayapp/DisplayAppRecovery.h index 4184ea49da..425e0acad4 100644 --- a/src/displayapp/DisplayAppRecovery.h +++ b/src/displayapp/DisplayAppRecovery.h @@ -32,6 +32,7 @@ namespace Pinetime { class TouchHandler; class MotorController; class TimerController; + class AlarmController; } namespace System { @@ -54,6 +55,7 @@ namespace Pinetime { Pinetime::Controllers::MotorController& motorController, Pinetime::Controllers::MotionController& motionController, Pinetime::Controllers::TimerController& timerController, + Pinetime::Controllers::AlarmController& alarmController, Pinetime::Controllers::TouchHandler& touchHandler); void Start(); void PushMessage(Pinetime::Applications::Display::Messages msg);