From 28abeae21bb370c45d26912bba4737a1cc6ddca7 Mon Sep 17 00:00:00 2001 From: hubmartin Date: Mon, 2 Aug 2021 21:37:48 +0200 Subject: DRAFT: Put gpio pins to separate file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 40e1f2a..24b5ae4 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 1333ad0..cd66ff8 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 14c296e..fa53907 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 0000000..61bb10e --- /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 ba43429..2756f77 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; -- cgit v0.10.2 From f244c960d3848096b60f735e705819f05a0459d7 Mon Sep 17 00:00:00 2001 From: Martin Hub Date: Tue, 3 Aug 2021 17:41:34 +0200 Subject: Update ota-gadgetbridge-nrfconnect.md diff --git a/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md b/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md index 1187a9b..2f2dd55 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. -- cgit v0.10.2 From 2992f4afd286d26068bba0afdd9337ab6d96aa15 Mon Sep 17 00:00:00 2001 From: Martin Hub Date: Tue, 3 Aug 2021 17:56:02 +0200 Subject: Add FW validation note after DFU flash diff --git a/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md b/doc/gettingStarted/ota-gadgetbridge-nrfconnect.md index 1187a9b..86bbab8 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 -- cgit v0.10.2 From c30e54c7b743f7c6364d35412d74ba9be8dc3c04 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Tue, 3 Aug 2021 19:49:54 +0300 Subject: Make it easier for new people to find instructions diff --git a/README.md b/README.md index d9de400..af91616 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) -- cgit v0.10.2 From 285ac9e4c86f6f1fb96130d2df038fff7ec49ad5 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Tue, 3 Aug 2021 19:51:58 +0300 Subject: Move getting started slightly lower diff --git a/README.md b/README.md index af91616..a6f0d3a 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") -- cgit v0.10.2 From b7aa04e1f55096d754a7cc291f02f3430f5a3cd9 Mon Sep 17 00:00:00 2001 From: hubmartin Date: Tue, 3 Aug 2021 20:32:23 +0200 Subject: PinMap with namespace and constexpr diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index fa476ea..d543ccd 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 cd66ff8..993ef6c 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 8ad987d..350dfee 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 c47158a..0d7ac2f 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 3afa0ce..1f20936 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 df61af7..00cd193 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 fd9792b..b039ab0 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 fa53907..b621510 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 61bb10e..117cf11 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 ffbba5e..408ce43 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 9818179..acec14c 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 8915ce7..e03a57b 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 2756f77..e4da6b1 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(); -- cgit v0.10.2 From b3e6da75148fcb54fdb5fe02f6bdc7d7d3905e98 Mon Sep 17 00:00:00 2001 From: hubmartin Date: Tue, 3 Aug 2021 20:40:27 +0200 Subject: Cleanup, set Pinetime as default diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index d543ccd..e2fce7f 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 993ef6c..5c7fa1f 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 117cf11..c8b091f 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 -- cgit v0.10.2 From abd8f343e48bdfa1dc4c8604d843a5c2d8071bc0 Mon Sep 17 00:00:00 2001 From: hubmartin Date: Wed, 4 Aug 2021 14:43:04 +0200 Subject: Rename backlight level pins diff --git a/src/components/brightness/BrightnessController.cpp b/src/components/brightness/BrightnessController.cpp index 350dfee..6c52467 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 c8b091f..5796402 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; -- cgit v0.10.2 From 23bde0d18e99a344b95b5f1507350e186659eec2 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Sat, 14 Aug 2021 21:18:11 +0300 Subject: Make battery reading periodic. Add events. Disable pullup diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index f8a64ec..aa038c5 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 6f09b73..ad304eb 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 d4a73f5..c6e9466 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 322505e..8e4884d 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 0ab47eb..31cde07 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 3a195e2..ebe6a2b 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 8915ce7..7ef6fc6 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 ba43429..14c7ec7 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; -- cgit v0.10.2 From 55f8908769aab970413b249cb26acdaf22c79ada Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Tue, 17 Aug 2021 23:53:57 +0000 Subject: Make Clock Persistant. diff --git a/gcc_nrf52.ld b/gcc_nrf52.ld index 98e133a..b40dc06 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 d6aa83c..77c5be4 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 265d6e9..ed7b086 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 d301be6..9c384a8 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(); -- cgit v0.10.2 From 16502b788f19458b472de74173d92f01aba30b5f Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 19 Aug 2021 00:14:42 +0000 Subject: Add MCUBOOT linker changes use better linker constant names diff --git a/gcc_nrf52-mcuboot.ld b/gcc_nrf52-mcuboot.ld index 0746f49..b1413f1 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 b40dc06..705c3d3 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 -- cgit v0.10.2 From 2dd7b8ba2c0c8f756eddd9c86a40497f1b7f7537 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 19 Aug 2021 00:44:22 +0000 Subject: Add clearing of noinit segment on bad word Code readability cleanup diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp index 77c5be4..4995338 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 ed7b086..a20f71c 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 9c384a8..d5da428 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(); -- cgit v0.10.2 From 4f6d7e2c6386ed584a54a513c811cb77b5d320e1 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 19 Aug 2021 00:51:12 +0000 Subject: Move Backup to the system task. diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp index 4995338..6e42682 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 a20f71c..061c303 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 3553f44..add591e 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 ba43429..9293fd7 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; -- cgit v0.10.2 From c9dedfd402c67078ce53ad661889be841633f468 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 19 Aug 2021 00:51:42 +0000 Subject: Add some VSCODE stuff to gitignore... Allow settings to stop naggin me that it has added assosiation types diff --git a/.gitignore b/.gitignore index 6de76a9..39fb672 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 8f0e63f..f1cc3a8 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" + } } -- cgit v0.10.2 From 2b30ff4fc6a1835bdc5a94f8754cfd366885c4c0 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Thu, 19 Aug 2021 11:12:34 +0300 Subject: Remove unused variables diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 5150162..e79fa61 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 c061c14..c95edb4 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 a02d9b4..ff99934 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 d301be6..d420fcd 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; -- cgit v0.10.2 From 51c5257548efe678ec8e18d8cdea2476672f1238 Mon Sep 17 00:00:00 2001 From: hubmartin Date: Sun, 22 Aug 2021 22:17:57 +0200 Subject: Update startup SCL toggling pinmap definitions diff --git a/src/main.cpp b/src/main.cpp index 7131c68..4d16a6d 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); -- cgit v0.10.2 From 110c82c225c22685a3f0b7d1d75566a929516637 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Mon, 23 Aug 2021 20:13:26 +0000 Subject: Move noinit to after BSS segment, Now dynamically allocates noinit area size stores it after the bss before the heap and stack. diff --git a/gcc_nrf52-mcuboot.ld b/gcc_nrf52-mcuboot.ld index b1413f1..81b318c 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 705c3d3..f9bc5b6 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 -- cgit v0.10.2 From d7293a44dfa6de8cb6ad25c259d33ca07bde3426 Mon Sep 17 00:00:00 2001 From: Fabien Benetou Date: Thu, 26 Aug 2021 15:11:20 +0200 Subject: Infini-iOS diff --git a/README.md b/README.md index 6549ece..86f1b9d 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/) -- cgit v0.10.2 From b45d7c372d960051d048e4123335af6dacf88297 Mon Sep 17 00:00:00 2001 From: Colin Kinloch Date: Thu, 26 Aug 2021 19:42:02 +0100 Subject: Correct change test for wake up mode setting diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 93d6d21..0ff1cb8 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); -- cgit v0.10.2 From be31f417db1937032ae440e1cf68cb2971284713 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sun, 29 Aug 2021 15:50:04 -0500 Subject: 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. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f72f50c..c7eda52 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 5eb227b..4de8fff 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 0cfe983..078d615 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 3553f44..2dff925 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(); -- cgit v0.10.2 From 00a3f84ea764e5da5d982e7603ece1e574306850 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Mon, 30 Aug 2021 23:17:16 -0500 Subject: Completely reset connection state on fail diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 4de8fff..8b4f3ea 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 { -- cgit v0.10.2 From d69a8e84fa1906a661738ea034eae5f5f37c25bf Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Wed, 1 Sep 2021 22:48:01 -0500 Subject: Fix race condition, connect->disconnect->discovery diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 8b4f3ea..0f48609 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() { -- cgit v0.10.2 From 3e1fe687b82d4df237b7b355fa31cb88713193fc Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Wed, 1 Sep 2021 22:50:56 -0500 Subject: Fix styles issues - no change to functionality diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 0f48609..8e0fe75 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); } } -- cgit v0.10.2 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: Update Settings.cpp diff --git a/src/displayapp/screens/settings/Settings.cpp b/src/displayapp/screens/settings/Settings.cpp index f82b03c..e3319f0 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}, -- cgit v0.10.2 From 28fdc376b23ee2cd87a3ed8925b44a2f6e614ebf Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 2 Sep 2021 23:01:12 +0000 Subject: Add some comments diff --git a/src/main.cpp b/src/main.cpp index d5da428..5d304bc 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; } -- cgit v0.10.2 From c32ba844e04017a3fd31444c384deb3542bd76be Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sat, 4 Sep 2021 15:26:50 -0500 Subject: 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. diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 8e0fe75..bebca2d 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 078d615..7976110 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}, -- cgit v0.10.2 From 4820b2ffe8be0b8d1abefd307a4c0fe6d4d41a73 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sun, 5 Sep 2021 15:52:01 -0500 Subject: Revert "Linear decrease of advert rate to conserve battery" This reverts commit c32ba844e04017a3fd31444c384deb3542bd76be. diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index bebca2d..8e0fe75 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 7976110..078d615 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}, -- cgit v0.10.2 From 22571d4b384e40d647cd994202956f08ed32d925 Mon Sep 17 00:00:00 2001 From: "James A. Jerkins" Date: Sun, 5 Sep 2021 15:53:20 -0500 Subject: 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). diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 8e0fe75..226f669 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 078d615..473bb1a 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 2dff925..41f346a 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; -- cgit v0.10.2 From 3cc00771fa6528433b2ec4d787dc6bfefd948390 Mon Sep 17 00:00:00 2001 From: NeroBurner Date: Fri, 10 Sep 2021 23:42:49 +0200 Subject: 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. diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4744eae..bd24359 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: -- cgit v0.10.2 From 1fb5757655c1cdf0e93f03ad27869e8c043d69f0 Mon Sep 17 00:00:00 2001 From: Mark Russell Date: Fri, 10 Sep 2021 18:40:13 -0400 Subject: Created basic alarm app diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a724290..ccade83 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 0000000..5097936 --- /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 0000000..22259da --- /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 b25e6bc..5ade19e 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 d2c9fe5..d3b96b0 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 dd51fdb..e3aca8c 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 d6100ec..33c67e2 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 96951d1..4254523 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 322505e..c23cdfe 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 0000000..e122cab --- /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 0000000..30bcb73 --- /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 6e7bbb7..5c582f6 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 79e2ad8..6a7f5eb 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 3a195e2..93fcf94 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 0617b0c..98685c3 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 0266ba8..cbd98d2 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}; -- cgit v0.10.2 From e614af1c4a53e943256b3b2acee4bfe7d7204bbf Mon Sep 17 00:00:00 2001 From: hubmartin Date: Mon, 13 Sep 2021 11:41:51 +0200 Subject: Add WATCH_COLMI_P8 option to cmake & docs diff --git a/CMakeLists.txt b/CMakeLists.txt index cc41a08..f2402e5 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 87b6dd9..e97bb30 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. -- cgit v0.10.2 From 84a93b54410681ce1aaae80ba7a7e6d3300dcfa1 Mon Sep 17 00:00:00 2001 From: Tim Gates Date: Tue, 14 Sep 2021 04:02:53 +1000 Subject: 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`. diff --git a/cmake-nRF5x/readme.md b/cmake-nRF5x/readme.md index 2ce7689..0127a2e 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 b08af71..48e0504 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 5eb227b..bde9b07 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 d9434b3..690a453 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--; -- cgit v0.10.2 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: Fix DisplayAppRecovery : fix include error by forward declaring Controllers in header file. diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index 17612ef..7a20262 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 8b2bc7f..4184ea4 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: -- cgit v0.10.2 From bfe13d9d6849cf37f2d5a011990af85a1b503672 Mon Sep 17 00:00:00 2001 From: Mark Russell Date: Mon, 13 Sep 2021 15:26:28 -0400 Subject: Fixes based on code reviews (formatting, UI code) diff --git a/src/components/alarm/AlarmController.cpp b/src/components/alarm/AlarmController.cpp index 5097936..31a3191 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 22259da..140c9c8 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 e122cab..a2bb5c6 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 30bcb73..43bbc6f 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 98685c3..9ec2059 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(); -- cgit v0.10.2 From 2bf339a3f8319d68dfe657a53020c1f7977c4eb7 Mon Sep 17 00:00:00 2001 From: Mark Russell Date: Mon, 13 Sep 2021 16:05:35 -0400 Subject: License header fix, add missing braces diff --git a/src/components/alarm/AlarmController.cpp b/src/components/alarm/AlarmController.cpp index 31a3191..2532a4a 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 140c9c8..7c43b89 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 a2bb5c6..70d95fe 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 43bbc6f..b36f7f9 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 . */ -- cgit v0.10.2 From f89780f3323042ce9a83f78aa9017c56f0fb62e9 Mon Sep 17 00:00:00 2001 From: Reinhold Gschweicher Date: Mon, 13 Sep 2021 22:32:22 +0200 Subject: Remove unused include in MotoController.h Remove the unused include `app_timer.h` in `MotorController.h` diff --git a/src/components/motor/MotorController.h b/src/components/motor/MotorController.h index 1d8fcc9..cf78088 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 { -- cgit v0.10.2 From 63477fc09616b5f7df0af17dd5d990a760ba2ae4 Mon Sep 17 00:00:00 2001 From: Reinhold Gschweicher Date: Mon, 13 Sep 2021 22:33:21 +0200 Subject: Fix unsigned/signed comparison warning in Metronome.cpp `xTaskGetTickCount()` returns a `TickType_t`, which is defined as an `uint32_t`. This is compared to the `bpm` variable, which is a `int16_t` in the range of 40 to 220 as defined in the constructor. ```cpp lv_arc_set_range(bpmArc, 40, 220); ``` Just assume that `bpm` is greater than 0, as this would result in a divison by zero or negative values, which would unintentionally underflow to a very large number. diff --git a/src/displayapp/screens/Metronome.cpp b/src/displayapp/screens/Metronome.cpp index 884a4a5..52cb851 100644 --- a/src/displayapp/screens/Metronome.cpp +++ b/src/displayapp/screens/Metronome.cpp @@ -78,7 +78,7 @@ Metronome::~Metronome() { void Metronome::Refresh() { if (metronomeStarted) { - if (xTaskGetTickCount() - startTime > 60 * configTICK_RATE_HZ / bpm) { + if (xTaskGetTickCount() - startTime > 60u * configTICK_RATE_HZ / static_cast(bpm)) { startTime += 60 * configTICK_RATE_HZ / bpm; counter--; if (counter == 0) { -- cgit v0.10.2 From f857a757a7184726093a7085cdb3d74b728a22e4 Mon Sep 17 00:00:00 2001 From: Mark Russell Date: Thu, 16 Sep 2021 15:38:31 -0400 Subject: Fixes per Riksu9000's feedback diff --git a/src/components/alarm/AlarmController.cpp b/src/components/alarm/AlarmController.cpp index 2532a4a..67ca05a 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 7c43b89..bf85d43 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 5ade19e..b25e6bc 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 d3b96b0..d2c9fe5 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 70d95fe..959cb0b 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 b36f7f9..abf97eb 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 9ec2059..534f551 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: -- cgit v0.10.2 From 1d43adcdfa7bd15ba45c0c9d7c59c0ff99176b9c Mon Sep 17 00:00:00 2001 From: Mark Russell Date: Thu, 16 Sep 2021 16:01:25 -0400 Subject: Merge upstream diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4744eae..bd24359 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 cc41a08..f2402e5 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 6549ece..0d5cad9 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 2ce7689..0127a2e 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 87b6dd9..e97bb30 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 1187a9b..ffc27ed 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 b08af71..48e0504 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 ccade83..37ee084 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 f8a64ec..4ef20a2 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 6f09b73..8af27ea 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 5eb227b..879421e 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 0cfe983..473bb1a 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 8ad987d..6c52467 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 c47158a..0d7ac2f 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 b25e6bc..42057a8 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 d2c9fe5..cf78088 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 a294ab7..a54ba97 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 33c67e2..9d47310 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 17612ef..7a20262 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 8b2bc7f..4184ea4 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 c23cdfe..d48b646 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 91c2651..ad9af15 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 22eb290..417dff0 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 f6f8b4c..0b5271e 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 f82b03c..e3319f0 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 b8f8e45..1ff163b 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 d4c17bb..7b46c5d 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 0000000..5796402 --- /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 6a7f5eb..7d4f085 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 9818179..acec14c 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 93fcf94..bd1de23 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 534f551..24ee4bd 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 cbd98d2..9e7e5e8 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; -- cgit v0.10.2 From cdf99b08f42c3826a8608d756bc7cda0a476ed98 Mon Sep 17 00:00:00 2001 From: Mark Russell Date: Thu, 16 Sep 2021 16:12:20 -0400 Subject: Revert "Merge upstream" This reverts commit 1d43adcdfa7bd15ba45c0c9d7c59c0ff99176b9c. diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bd24359..4744eae 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 f2402e5..cc41a08 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 0d5cad9..6549ece 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 0127a2e..2ce7689 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 e97bb30..87b6dd9 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 ffc27ed..1187a9b 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 48e0504..b08af71 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 37ee084..ccade83 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 4ef20a2..f8a64ec 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 8af27ea..6f09b73 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 879421e..5eb227b 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 473bb1a..0cfe983 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 6c52467..8ad987d 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 0d7ac2f..c47158a 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 42057a8..b25e6bc 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 cf78088..d2c9fe5 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 a54ba97..a294ab7 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 9d47310..33c67e2 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 7a20262..17612ef 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 4184ea4..8b2bc7f 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 d48b646..c23cdfe 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 ad9af15..91c2651 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 417dff0..22eb290 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 0b5271e..f6f8b4c 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 e3319f0..f82b03c 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 1ff163b..b8f8e45 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 7b46c5d..d4c17bb 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 5796402..0000000 --- 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 7d4f085..6a7f5eb 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 acec14c..9818179 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 bd1de23..93fcf94 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 24ee4bd..534f551 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 9e7e5e8..cbd98d2 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; -- cgit v0.10.2 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: Fix DisplayAppRecovery : add AlarmController to ctor(). diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index 7a20262..a42d81a 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 4184ea4..425e0ac 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); -- cgit v0.10.2 From f3b5da0049132f9b06ecc162039badc20e37d037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Milants?= Date: Sun, 19 Sep 2021 17:42:50 +0200 Subject: Fix the display of the date after a reset : when the date/time was restored from the noinit area, the date was displayed as "--" instead of the actual date. This issue was caused by DateTime::SetCurrentTime() that would not update the internal state of the class : dayOfWeek, Month, Year were not properly updated according to the current time. diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp index 6e42682..0756d38 100644 --- a/src/components/datetime/DateTimeController.cpp +++ b/src/components/datetime/DateTimeController.cpp @@ -7,6 +7,7 @@ using namespace Pinetime::Controllers; void DateTime::SetCurrentTime(std::chrono::time_point t) { this->currentDateTime = t; + UpdateTime(previousSystickCounter); // Update internal state without updating the time } void DateTime::SetTime( -- cgit v0.10.2