diff --git a/CMakeLists.txt b/CMakeLists.txt index adb1754b28..a215180da2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose Debug or Release") project(pinetime VERSION 1.11.0 LANGUAGES C CXX ASM) set(CMAKE_C_STANDARD 99) -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 20) # set(CMAKE_GENERATOR "Unix Makefiles") set(CMAKE_C_EXTENSIONS OFF) diff --git a/README.md b/README.md index 6fd4158600..b8c31b2d96 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Fast open-source firmware for the [PineTime smartwatch](https://www.pine64.org/p ## Development - [InfiniTime Vision](doc/InfiniTimeVision.md) -- [Rough structure of the code](doc/code/Intro.md) +- [Introduction to the code](doc/code/Intro.md) - [How to implement an application](doc/code/Apps.md) - [Generate the fonts and symbols](src/displayapp/fonts/README.md) - [Tips on designing an app UI](doc/ui_guidelines.md) diff --git a/doc/code/Intro.md b/doc/code/Intro.md index 34adc5fa6c..0089e20d06 100644 --- a/doc/code/Intro.md +++ b/doc/code/Intro.md @@ -47,3 +47,88 @@ For more detail see the [Apps page](./Apps.md) ## Bluetooth Header files with short documentation for the functions are inside [libs/mynewt-nimble/nimble/host/include/host/](/src/libs/mynewt-nimble/nimble/host/include/host/). + +## Hardware abstraction and device drivers + +Until version 1.12, InfiniTime did not provide any kind of hardware abstraction : the drivers were written specifically for the PineTime, and there was no easy way to provide any alternative implementation to support variants of the PineTime or for the integration in [InfiniSim](https://github.com/InfiniTimeOrg/InfiniSim). + +In [InfiniTime 1.12](https://github.com/InfiniTimeOrg/InfiniTime/releases/tag/1.12.0), we implemented a new design that allows to easily choose **at build time** a specific implementation for multiple device drivers (Display, heart rate sensor, motion sensor, SPI, flash memory, touch panel, TWI and Watchdog). + +This new design makes the code much cleaner in InfiniSim and allows the port of InfiniTime on other hardware (ex : many PineTime variants like the Colmi P8) more easily. + +This hardware abstraction is based on C++ `concepts` and a proxy object that enables 'static polymorphism'. It means that the actual implementations of the drivers are known at **build time** and that there's no `virtual` calls at runtime. + +Here's an overview of the design : + +```c++ +namespace Pinetime { + namespace Drivers { + template + concept IsDevice = { /* ... */ }; + + namespace Interface { + template + requires IsDevice + class Device { + public: + explicit Device(T& impl) : impl {impl} {} + /* ... */ + private: + T& impl; + }; + } + + using Device = Interface::Device; + } +} + +int main() { + /* ... */ + + Pinetime::Drivers::Category::Device deviceImpl { /* ctor arguments specific to this implementation of Device */ }; + Pinetime::Drivers::Device device {deviceImpl}; + + /* ... */ +} + +``` + +The concept `Pinetime::Drivers::IsDevice` describes the interface a class that implements a `Device` must expose. + +The template class `Pinetime::Drivers::Interface::Device` is the "proxy" objects that allows the build time polymorphism. + +`Pinetime::Drivers::Device` is aliased to `Pinetime::Drivers::Interface::Device`. This allows to remove the template argument so that the rest of the application does not need to handle it. Those aliases are defined in header files located in `port/`. This is the only place where `#ifdef`s are needed. + +The actual drivers are implemented in specific namespaces (`Pinetime::Drivers::MCU::Device` or `Pinetime::Drivers::Category::Device`). + +To declare a new driver in the code, you'll first need to instantiate an actual implementation of the driver and then give the reference to this instance to the corresponding proxy object. Here is an example with the display driver: + +```c++ +// Actual implementation of the SPI bus for the NRF52 MCU +Pinetime::Drivers::Nrf52::SpiMaster spiImpl {Pinetime::Drivers::Nrf52::SpiMaster::SpiModule::SPI0, + {Pinetime::Drivers::Nrf52::SpiMaster::BitOrder::Msb_Lsb, + Pinetime::Drivers::Nrf52::SpiMaster::Modes::Mode3, + Pinetime::Drivers::Nrf52::SpiMaster::Frequencies::Freq8Mhz, + Pinetime::PinMap::SpiSck, + Pinetime::PinMap::SpiMosi, + Pinetime::PinMap::SpiMiso}}; + +// Proxy object +Pinetime::Drivers::SpiMaster spi {spiImpl}; + +// Actual implementation of the SpiMaster drivers (it handles the chip select pin) +Pinetime::Drivers::Nrf52::Spi lcdSpiIpmpl {spiImpl, Pinetime::PinMap::SpiLcdCsn}; + +// Proxy object +Pinetime::Drivers::Spi lcdSpi {lcdSpiIpmpl}; + +// Actual implementation of the display driver (ST7789 display controller) +Pinetime::Drivers::Displays::St7789 lcdImpl {lcdSpi, Pinetime::PinMap::LcdDataCommand}; + +// Proxy object +Pinetime::Drivers::Display lcd{lcdImpl}; + +Pinetime::System::SystemTask systemTask(spi, lcd /* ... */); +``` + +Once the initialization is done, the application does not need to know the actual implementation of the drivers, all calls to the drivers will go through the proxy objects. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e59c0d814b..31b5cb2a08 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -435,15 +435,16 @@ list(APPEND SOURCE_FILES ## main.cpp - drivers/St7789.cpp - drivers/SpiNorFlash.cpp - drivers/SpiMaster.cpp - drivers/Spi.cpp - drivers/Watchdog.cpp + drivers/displays/St7789.cpp + drivers/nrf52/SpiMaster.cpp + drivers/nrf52/Spi.cpp + drivers/nrf52/TwiMaster.cpp + drivers/spiFlash/SpiNorFlash.cpp + drivers/nrf52/Watchdog.cpp drivers/DebugPins.cpp drivers/InternalFlash.cpp - drivers/Hrs3300.cpp - drivers/Bma421.cpp + drivers/heartRateSensors/Hrs3300.cpp + drivers/motionSensors/Bma421.cpp drivers/Bma421_C/bma4.c drivers/Bma421_C/bma423.c components/battery/BatteryController.cpp @@ -474,7 +475,7 @@ list(APPEND SOURCE_FILES components/timer/TimerController.cpp components/alarm/AlarmController.cpp components/fs/FS.cpp - drivers/Cst816s.cpp + drivers/touchpanels/Cst816s.cpp FreeRTOS/port.c FreeRTOS/port_cmsis_systick.c FreeRTOS/port_cmsis.c @@ -484,7 +485,6 @@ list(APPEND SOURCE_FILES systemtask/SystemTask.cpp systemtask/SystemMonitor.cpp - drivers/TwiMaster.cpp heartratetask/HeartRateTask.cpp components/heartrate/Ppg.cpp @@ -502,15 +502,16 @@ list(APPEND RECOVERY_SOURCE_FILES displayapp/DisplayAppRecovery.cpp main.cpp - drivers/St7789.cpp - drivers/SpiNorFlash.cpp - drivers/SpiMaster.cpp - drivers/Spi.cpp - drivers/Watchdog.cpp + drivers/displays/St7789.cpp + drivers/nrf52/SpiMaster.cpp + drivers/nrf52/Spi.cpp + drivers/nrf52/TwiMaster.cpp + drivers/spiFlash/SpiNorFlash.cpp + drivers/nrf52/Watchdog.cpp drivers/DebugPins.cpp drivers/InternalFlash.cpp - drivers/Hrs3300.cpp - drivers/Bma421.cpp + drivers/heartRateSensors/Hrs3300.cpp + drivers/motionSensors/Bma421.cpp drivers/Bma421_C/bma4.c drivers/Bma421_C/bma423.c components/battery/BatteryController.cpp @@ -539,14 +540,13 @@ list(APPEND RECOVERY_SOURCE_FILES components/settings/Settings.cpp components/timer/TimerController.cpp components/alarm/AlarmController.cpp - drivers/Cst816s.cpp + drivers/touchpanels/Cst816s.cpp FreeRTOS/port.c FreeRTOS/port_cmsis_systick.c FreeRTOS/port_cmsis.c systemtask/SystemTask.cpp systemtask/SystemMonitor.cpp - drivers/TwiMaster.cpp components/gfx/Gfx.cpp components/rle/RleDecoder.cpp components/heartrate/HeartRateController.cpp @@ -566,15 +566,16 @@ list(APPEND RECOVERYLOADER_SOURCE_FILES FreeRTOS/port_cmsis_systick.c FreeRTOS/port_cmsis.c - drivers/SpiNorFlash.cpp - drivers/SpiMaster.cpp - drivers/Spi.cpp + drivers/nrf52/SpiMaster.cpp + drivers/nrf52/Spi.cpp + drivers/nrf52/TwiMaster.cpp + drivers/spiFlash/SpiNorFlash.cpp logging/NrfLogger.cpp components/rle/RleDecoder.cpp components/gfx/Gfx.cpp - drivers/St7789.cpp + drivers/displays/St7789.cpp components/brightness/BrightnessController.cpp recoveryLoader.cpp @@ -617,16 +618,18 @@ set(INCLUDE_FILES displayapp/widgets/Counter.h displayapp/widgets/PageIndicator.h displayapp/widgets/StatusIcons.h - drivers/St7789.h + drivers/displays/St7789.h drivers/SpiNorFlash.h - drivers/SpiMaster.h - drivers/Spi.h + drivers/nrf52/SpiMaster.h + drivers/nrf52/Spi.h + drivers/nrf52/TwiMaster.h + drivers/spiFlash/SpiNorFlash.h drivers/Watchdog.h drivers/DebugPins.h drivers/InternalFlash.h - drivers/Hrs3300.h + drivers/heartRateSensors/Hrs3300.h drivers/PinMap.h - drivers/Bma421.h + drivers/motionSensors/Bma421.h drivers/Bma421_C/bma4.c drivers/Bma421_C/bma423.c components/battery/BatteryController.h @@ -655,7 +658,7 @@ set(INCLUDE_FILES components/settings/Settings.h components/timer/TimerController.h components/alarm/AlarmController.h - drivers/Cst816s.h + drivers/touchpanels/Cst816s.h FreeRTOS/portmacro.h FreeRTOS/portmacro_cmsis.h libs/date/include/date/tz.h @@ -687,6 +690,7 @@ include_directories( . ../ libs/ + port/ FreeRTOS/ libs/date/include libs/mynewt-nimble/porting/npl/freertos/include diff --git a/src/components/ble/DfuService.h b/src/components/ble/DfuService.h index 4708a4a607..d4aed37080 100644 --- a/src/components/ble/DfuService.h +++ b/src/components/ble/DfuService.h @@ -9,13 +9,12 @@ #undef max #undef min +#include "port/SpiNorFlash.h" + namespace Pinetime { namespace System { class SystemTask; } - namespace Drivers { - class SpiNorFlash; - } namespace Controllers { class Ble; diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 000231fe71..e323461a82 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -25,10 +25,6 @@ #include "components/fs/FS.h" namespace Pinetime { - namespace Drivers { - class SpiNorFlash; - } - namespace System { class SystemTask; } diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h index 87fcdc23f4..9890f5050e 100644 --- a/src/components/fs/FS.h +++ b/src/components/fs/FS.h @@ -2,6 +2,7 @@ #include #include "drivers/SpiNorFlash.h" +#include "port/SpiNorFlash.h" #include namespace Pinetime { diff --git a/src/components/gfx/Gfx.cpp b/src/components/gfx/Gfx.cpp index 3eaaa3fecc..6c51a1cdd4 100644 --- a/src/components/gfx/Gfx.cpp +++ b/src/components/gfx/Gfx.cpp @@ -1,8 +1,8 @@ #include "components/gfx/Gfx.h" -#include "drivers/St7789.h" +#include "drivers/displays/St7789.h" using namespace Pinetime::Components; -Gfx::Gfx(Pinetime::Drivers::St7789& lcd) : lcd {lcd} { +Gfx::Gfx(Pinetime::Drivers::Displays::St7789& lcd) : lcd {lcd} { } void Gfx::Init() { diff --git a/src/components/gfx/Gfx.h b/src/components/gfx/Gfx.h index 54c4a8b778..51fcdfe99e 100644 --- a/src/components/gfx/Gfx.h +++ b/src/components/gfx/Gfx.h @@ -8,12 +8,14 @@ namespace Pinetime { namespace Drivers { - class St7789; + namespace Displays { + class St7789; + } } namespace Components { class Gfx : public Pinetime::Drivers::BufferProvider { public: - explicit Gfx(Drivers::St7789& lcd); + explicit Gfx(Drivers::Displays::St7789& lcd); void Init(); void ClearScreen(); void DrawString(uint8_t x, uint8_t y, uint16_t color, const char* text, const FONT_INFO* p_font, bool wrap); @@ -49,7 +51,7 @@ namespace Pinetime { volatile State state; uint16_t buffer[width]; // 1 line buffer - Drivers::St7789& lcd; + Drivers::Displays::St7789& lcd; void SetBackgroundColor(uint16_t color); void WaitTransferFinished() const; diff --git a/src/components/motion/MotionController.cpp b/src/components/motion/MotionController.cpp index 7dd321271c..19f14f108d 100644 --- a/src/components/motion/MotionController.cpp +++ b/src/components/motion/MotionController.cpp @@ -69,12 +69,12 @@ int32_t MotionController::currentShakeSpeed() { void MotionController::IsSensorOk(bool isOk) { isSensorOk = isOk; } -void MotionController::Init(Pinetime::Drivers::Bma421::DeviceTypes types) { +void MotionController::Init(Pinetime::Drivers::MotionSensors::DeviceTypes types) { switch (types) { - case Drivers::Bma421::DeviceTypes::BMA421: + case Drivers::MotionSensors::DeviceTypes::BMA421: this->deviceType = DeviceTypes::BMA421; break; - case Drivers::Bma421::DeviceTypes::BMA425: + case Drivers::MotionSensors::DeviceTypes::BMA425: this->deviceType = DeviceTypes::BMA425; break; default: diff --git a/src/components/motion/MotionController.h b/src/components/motion/MotionController.h index f80b11b994..717946c509 100644 --- a/src/components/motion/MotionController.h +++ b/src/components/motion/MotionController.h @@ -1,7 +1,8 @@ #pragma once #include -#include +#include +#include #include namespace Pinetime { @@ -48,7 +49,7 @@ namespace Pinetime { return deviceType; } - void Init(Pinetime::Drivers::Bma421::DeviceTypes types); + void Init(Pinetime::Drivers::MotionSensors::DeviceTypes types); void SetService(Pinetime::Controllers::MotionService* service); private: diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 108e380d69..a6003d9e3d 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -30,9 +30,6 @@ #include "displayapp/screens/PassKey.h" #include "displayapp/screens/Error.h" -#include "drivers/Cst816s.h" -#include "drivers/St7789.h" -#include "drivers/Watchdog.h" #include "systemtask/SystemTask.h" #include "systemtask/Messages.h" @@ -60,9 +57,9 @@ namespace { } } -DisplayApp::DisplayApp(Drivers::St7789& lcd, +DisplayApp::DisplayApp(Drivers::Display& lcd, Components::LittleVgl& lvgl, - Drivers::Cst816S& touchPanel, + Pinetime::Drivers::TouchPanel& touchPanel, Controllers::Battery& batteryController, Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h index 4c54e22739..b6ac6db0f8 100644 --- a/src/displayapp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -23,8 +23,6 @@ namespace Pinetime { namespace Drivers { - class St7789; - class Cst816S; class WatchdogView; } namespace Controllers { @@ -47,9 +45,9 @@ namespace Pinetime { enum class States { Idle, Running }; enum class FullRefreshDirections { None, Up, Down, Left, Right, LeftAnim, RightAnim }; - DisplayApp(Drivers::St7789& lcd, + DisplayApp(Drivers::Display& lcd, Components::LittleVgl& lvgl, - Drivers::Cst816S&, + Pinetime::Drivers::TouchPanel&, Controllers::Battery& batteryController, Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, @@ -74,9 +72,9 @@ namespace Pinetime { void Register(Pinetime::System::SystemTask* systemTask); private: - Pinetime::Drivers::St7789& lcd; + Pinetime::Drivers::Display& lcd; Pinetime::Components::LittleVgl& lvgl; - Pinetime::Drivers::Cst816S& touchPanel; + Pinetime::Drivers::TouchPanel& touchPanel; Pinetime::Controllers::Battery& batteryController; Pinetime::Controllers::Ble& bleController; Pinetime::Controllers::DateTime& dateTimeController; diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index e553aa8794..00b9fe0762 100644 --- a/src/displayapp/DisplayAppRecovery.cpp +++ b/src/displayapp/DisplayAppRecovery.cpp @@ -10,9 +10,9 @@ using namespace Pinetime::Applications; -DisplayApp::DisplayApp(Drivers::St7789& lcd, +DisplayApp::DisplayApp(Drivers::Display& lcd, Components::LittleVgl& lvgl, - Drivers::Cst816S& touchPanel, + Drivers::TouchPanel& touchPanel, Controllers::Battery& batteryController, Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, diff --git a/src/displayapp/DisplayAppRecovery.h b/src/displayapp/DisplayAppRecovery.h index 7d4f0fd0c0..55826ae3ed 100644 --- a/src/displayapp/DisplayAppRecovery.h +++ b/src/displayapp/DisplayAppRecovery.h @@ -1,12 +1,10 @@ #pragma once #include #include -#include #include #include #include #include "components/gfx/Gfx.h" -#include "drivers/Cst816s.h" #include #include #include @@ -15,11 +13,11 @@ #include "displayapp/Apps.h" #include "displayapp/Messages.h" #include "displayapp/DummyLittleVgl.h" +#include "port/TouchPanel.h" +#include "port/Display.h" namespace Pinetime { namespace Drivers { - class St7789; - class Cst816S; class WatchdogView; } namespace Controllers { @@ -45,9 +43,9 @@ namespace Pinetime { namespace Applications { class DisplayApp { public: - DisplayApp(Drivers::St7789& lcd, + DisplayApp(Drivers::Display& lcd, Components::LittleVgl& lvgl, - Drivers::Cst816S&, + Drivers::TouchPanel&, Controllers::Battery& batteryController, Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, @@ -76,7 +74,7 @@ namespace Pinetime { void DisplayOtaProgress(uint8_t percent, uint16_t color); void InitHw(); void Refresh(); - Pinetime::Drivers::St7789& lcd; + Pinetime::Drivers::Display& lcd; Controllers::Ble& bleController; static constexpr uint8_t queueSize = 10; diff --git a/src/displayapp/DummyLittleVgl.h b/src/displayapp/DummyLittleVgl.h index 05355a9730..baab7e59c7 100644 --- a/src/displayapp/DummyLittleVgl.h +++ b/src/displayapp/DummyLittleVgl.h @@ -3,15 +3,16 @@ #include #include #include -#include -#include + +#include "port/TouchPanel.h" +#include "port/Display.h" namespace Pinetime { namespace Components { class LittleVgl { public: enum class FullRefreshDirections { None, Up, Down }; - LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel) { + LittleVgl(Pinetime::Drivers::Display& lcd, Pinetime::Drivers::TouchPanel & touchPanel) { } LittleVgl(const LittleVgl&) = delete; diff --git a/src/displayapp/LittleVgl.cpp b/src/displayapp/LittleVgl.cpp index d5f31848c4..7eef851006 100644 --- a/src/displayapp/LittleVgl.cpp +++ b/src/displayapp/LittleVgl.cpp @@ -4,8 +4,6 @@ #include #include //#include -#include "drivers/Cst816s.h" -#include "drivers/St7789.h" using namespace Pinetime::Components; @@ -31,7 +29,7 @@ bool touchpad_read(lv_indev_drv_t* indev_drv, lv_indev_data_t* data) { return lvgl->GetTouchPadInfo(data); } -LittleVgl::LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel) : lcd {lcd}, touchPanel {touchPanel} { +LittleVgl::LittleVgl(Pinetime::Drivers::Display& lcd, Pinetime::Drivers::TouchPanel& touchPanel) : lcd {lcd}, touchPanel {touchPanel} { } void LittleVgl::Init() { diff --git a/src/displayapp/LittleVgl.h b/src/displayapp/LittleVgl.h index 4582616533..d6db792e33 100644 --- a/src/displayapp/LittleVgl.h +++ b/src/displayapp/LittleVgl.h @@ -1,18 +1,15 @@ #pragma once #include +#include "port/TouchPanel.h" +#include "port/Display.h" namespace Pinetime { - namespace Drivers { - class Cst816S; - class St7789; - } - namespace Components { class LittleVgl { public: enum class FullRefreshDirections { None, Up, Down, Left, Right, LeftAnim, RightAnim }; - LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel); + LittleVgl(Pinetime::Drivers::Display& lcd, Pinetime::Drivers::TouchPanel& touchPanel); LittleVgl(const LittleVgl&) = delete; LittleVgl& operator=(const LittleVgl&) = delete; @@ -39,8 +36,8 @@ namespace Pinetime { void InitTouchpad(); void InitTheme(); - Pinetime::Drivers::St7789& lcd; - Pinetime::Drivers::Cst816S& touchPanel; + Pinetime::Drivers::Display& lcd; + Pinetime::Drivers::TouchPanel& touchPanel; lv_disp_buf_t disp_buf_2; lv_color_t buf2_1[LV_HOR_RES_MAX * 4]; diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index 01c351955e..aa6643983d 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -11,7 +11,7 @@ #include "components/brightness/BrightnessController.h" #include "components/datetime/DateTimeController.h" #include "components/motion/MotionController.h" -#include "drivers/Watchdog.h" +#include "drivers/WatchdogView.h" #include "displayapp/InfiniTimeTheme.h" using namespace Pinetime::Applications::Screens; @@ -37,7 +37,7 @@ SystemInfo::SystemInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Ble& bleController, Pinetime::Drivers::WatchdogView& watchdog, Pinetime::Controllers::MotionController& motionController, - Pinetime::Drivers::Cst816S& touchPanel) + Pinetime::Drivers::TouchPanel& touchPanel) : Screen(app), dateTimeController {dateTimeController}, batteryController {batteryController}, @@ -101,23 +101,23 @@ std::unique_ptr SystemInfo::CreateScreen2() { auto batteryPercent = batteryController.PercentRemaining(); auto resetReason = [this]() { switch (watchdog.ResetReason()) { - case Drivers::Watchdog::ResetReasons::Watchdog: + case Drivers::Watchdogs::ResetReasons::Watchdog: return "wtdg"; - case Drivers::Watchdog::ResetReasons::HardReset: + case Drivers::Watchdogs::ResetReasons::HardReset: return "hardr"; - case Drivers::Watchdog::ResetReasons::NFC: + case Drivers::Watchdogs::ResetReasons::NFC: return "nfc"; - case Drivers::Watchdog::ResetReasons::SoftReset: + case Drivers::Watchdogs::ResetReasons::SoftReset: return "softr"; - case Drivers::Watchdog::ResetReasons::CpuLockup: + case Drivers::Watchdogs::ResetReasons::CpuLockup: return "cpulock"; - case Drivers::Watchdog::ResetReasons::SystemOff: + case Drivers::Watchdogs::ResetReasons::SystemOff: return "off"; - case Drivers::Watchdog::ResetReasons::LpComp: + case Drivers::Watchdogs::ResetReasons::LpComp: return "lpcomp"; - case Drivers::Watchdog::ResetReasons::DebugInterface: + case Drivers::Watchdogs::ResetReasons::DebugInterface: return "dbg"; - case Drivers::Watchdog::ResetReasons::ResetPin: + case Drivers::Watchdogs::ResetReasons::ResetPin: return "rst"; default: return "?"; diff --git a/src/displayapp/screens/SystemInfo.h b/src/displayapp/screens/SystemInfo.h index a382ed8f50..9efaea3f29 100644 --- a/src/displayapp/screens/SystemInfo.h +++ b/src/displayapp/screens/SystemInfo.h @@ -29,7 +29,7 @@ namespace Pinetime { Pinetime::Controllers::Ble& bleController, Pinetime::Drivers::WatchdogView& watchdog, Pinetime::Controllers::MotionController& motionController, - Pinetime::Drivers::Cst816S& touchPanel); + Pinetime::Drivers::TouchPanel& touchPanel); ~SystemInfo() override; bool OnTouchEvent(TouchEvents event) override; @@ -40,7 +40,7 @@ namespace Pinetime { Pinetime::Controllers::Ble& bleController; Pinetime::Drivers::WatchdogView& watchdog; Pinetime::Controllers::MotionController& motionController; - Pinetime::Drivers::Cst816S& touchPanel; + Pinetime::Drivers::TouchPanel& touchPanel; ScreenList<5> screens; diff --git a/src/drivers/Bma421.h b/src/drivers/Bma421.h deleted file mode 100644 index ac5c707ffc..0000000000 --- a/src/drivers/Bma421.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once -#include - -namespace Pinetime { - namespace Drivers { - class TwiMaster; - class Bma421 { - public: - enum class DeviceTypes : uint8_t { Unknown, BMA421, BMA425 }; - struct Values { - uint32_t steps; - int16_t x; - int16_t y; - int16_t z; - }; - Bma421(TwiMaster& twiMaster, uint8_t twiAddress); - Bma421(const Bma421&) = delete; - Bma421& operator=(const Bma421&) = delete; - Bma421(Bma421&&) = delete; - Bma421& operator=(Bma421&&) = delete; - - /// The chip freezes the TWI bus after the softreset operation. Softreset is separated from the - /// Init() method to allow the caller to uninit and then reinit the TWI device after the softreset. - void SoftReset(); - void Init(); - Values Process(); - void ResetStepCounter(); - - void Read(uint8_t registerAddress, uint8_t* buffer, size_t size); - void Write(uint8_t registerAddress, const uint8_t* data, size_t size); - - bool IsOk() const; - DeviceTypes DeviceType() const; - - private: - void Reset(); - - TwiMaster& twiMaster; - uint8_t deviceAddress = 0x18; - struct bma4_dev bma; - bool isOk = false; - bool isResetOk = false; - DeviceTypes deviceType = DeviceTypes::Unknown; - }; - } -} \ No newline at end of file diff --git a/src/drivers/Cst816s.h b/src/drivers/Cst816s.h deleted file mode 100644 index 9d426c9db9..0000000000 --- a/src/drivers/Cst816s.h +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include "drivers/TwiMaster.h" - -namespace Pinetime { - namespace Drivers { - class Cst816S { - public: - enum class Gestures : uint8_t { - None = 0x00, - SlideDown = 0x01, - SlideUp = 0x02, - SlideLeft = 0x03, - SlideRight = 0x04, - SingleTap = 0x05, - DoubleTap = 0x0B, - LongPress = 0x0C - }; - struct TouchInfos { - uint16_t x = 0; - uint16_t y = 0; - Gestures gesture = Gestures::None; - bool touching = false; - bool isValid = false; - }; - - Cst816S(TwiMaster& twiMaster, uint8_t twiAddress); - Cst816S(const Cst816S&) = delete; - Cst816S& operator=(const Cst816S&) = delete; - Cst816S(Cst816S&&) = delete; - Cst816S& operator=(Cst816S&&) = delete; - - bool Init(); - TouchInfos GetTouchInfo(); - void Sleep(); - void Wakeup(); - - uint8_t GetChipId() const { - return chipId; - } - uint8_t GetVendorId() const { - return vendorId; - } - uint8_t GetFwVersion() const { - return fwVersion; - } - - private: - bool CheckDeviceIds(); - - // Unused/Unavailable commented out - static constexpr uint8_t gestureIndex = 1; - static constexpr uint8_t touchPointNumIndex = 2; - // static constexpr uint8_t touchEventIndex = 3; - static constexpr uint8_t touchXHighIndex = 3; - static constexpr uint8_t touchXLowIndex = 4; - // static constexpr uint8_t touchIdIndex = 5; - static constexpr uint8_t touchYHighIndex = 5; - static constexpr uint8_t touchYLowIndex = 6; - // static constexpr uint8_t touchStep = 6; - // static constexpr uint8_t touchXYIndex = 7; - // static constexpr uint8_t touchMiscIndex = 8; - - static constexpr uint8_t maxX = 240; - static constexpr uint8_t maxY = 240; - - TwiMaster& twiMaster; - uint8_t twiAddress; - - uint8_t chipId; - uint8_t vendorId; - uint8_t fwVersion; - }; - - } -} diff --git a/src/drivers/Display.h b/src/drivers/Display.h new file mode 100644 index 0000000000..06a7116c18 --- /dev/null +++ b/src/drivers/Display.h @@ -0,0 +1,68 @@ +#pragma once +#include +#include +#include + +namespace Pinetime { + namespace Drivers { + template + concept IsDisplay = requires(DisplayImpl display, uint16_t line, uint16_t coord, uint32_t color, uint16_t dimension, const uint8_t* data, size_t size) { + { display.Init() }; + { display.Uninit() }; + { display.DrawPixel(coord, coord, color) }; + { display.VerticalScrollDefinition(line, line, line) }; + { display.VerticalScrollStartAddress(line) }; + { display.DrawBuffer(coord, coord, dimension, dimension, data, size) }; + { display.Sleep() }; + { display.Wakeup() }; + }; + + namespace Interface { + template + requires IsDisplay + class Display { + public: + explicit Display(T& impl) : impl {impl} {} + Display(const Display&) = delete; + Display& operator=(const Display&) = delete; + Display(Display&&) = delete; + Display& operator=(Display&&) = delete; + + void Init() { + impl.Init(); + } + + void Uninit() { + impl.Uninit(); + } + + void DrawPixel(uint16_t x, uint16_t y, uint32_t color) { + impl.DrawPixel(x, y, color); + } + + void VerticalScrollDefinition(uint16_t topFixedLines, uint16_t scrollLines, uint16_t bottomFixedLines) { + impl.VerticalScrollDefinition(topFixedLines, scrollLines, bottomFixedLines); + } + + void VerticalScrollStartAddress(uint16_t line) { + impl.VerticalScrollStartAddress(line); + } + + void DrawBuffer(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t* data, size_t size) { + impl.DrawBuffer(x, y, width, height, data, size); + } + + void Sleep() { + impl.Sleep(); + } + + void Wakeup() { + impl.Wakeup(); + } + + private: + T& impl; + }; + } + } +} diff --git a/src/drivers/HeartRateSensor.h b/src/drivers/HeartRateSensor.h new file mode 100644 index 0000000000..b49cf1336f --- /dev/null +++ b/src/drivers/HeartRateSensor.h @@ -0,0 +1,63 @@ +#pragma once +#include +#include +#include + +namespace Pinetime { + namespace Drivers { + template + concept IsHeartRateSensor = requires(HeartRateSensorImpl sensor, uint8_t gain, uint8_t drive) { + { sensor.Init() }; + { sensor.Enable() }; + { sensor.Disable() }; + { sensor.ReadHrs() } -> std::same_as; + { sensor.ReadAls() } -> std::same_as; + { sensor.SetGain(gain) }; + { sensor.SetDrive(drive) }; + }; + + namespace Interface { + template + requires IsHeartRateSensor + class HeartRateSensor { + public: + explicit HeartRateSensor(T& impl) : impl {impl} {} + HeartRateSensor(const HeartRateSensor&) = delete; + HeartRateSensor& operator=(const HeartRateSensor&) = delete; + HeartRateSensor(HeartRateSensor&&) = delete; + HeartRateSensor& operator=(HeartRateSensor&&) = delete; + + void Init() { + impl.Init(); + } + + void Enable() { + impl.Enable(); + } + + void Disable() { + impl.Disable(); + } + + uint32_t ReadHrs() { + return impl.ReadHrs(); + } + + uint32_t ReadAls() { + return impl.ReadAls(); + } + + void SetGain(uint8_t gain) { + impl.SetGain(gain); + } + + void SetDrive(uint8_t drive) { + impl.SetDrive(drive); + } + + private: + T& impl; + }; + } + } +} diff --git a/src/drivers/Hrs3300.h b/src/drivers/Hrs3300.h deleted file mode 100644 index 8bbdc69a40..0000000000 --- a/src/drivers/Hrs3300.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "drivers/TwiMaster.h" - -namespace Pinetime { - namespace Drivers { - class Hrs3300 { - public: - enum class Registers : uint8_t { - Id = 0x00, - Enable = 0x01, - EnableHen = 0x80, - C1dataM = 0x08, - C0DataM = 0x09, - C0DataH = 0x0a, - PDriver = 0x0c, - C1dataH = 0x0d, - C1dataL = 0x0e, - C0dataL = 0x0f, - Res = 0x16, - Hgain = 0x17 - }; - - Hrs3300(TwiMaster& twiMaster, uint8_t twiAddress); - Hrs3300(const Hrs3300&) = delete; - Hrs3300& operator=(const Hrs3300&) = delete; - Hrs3300(Hrs3300&&) = delete; - Hrs3300& operator=(Hrs3300&&) = delete; - - void Init(); - void Enable(); - void Disable(); - uint32_t ReadHrs(); - uint32_t ReadAls(); - void SetGain(uint8_t gain); - void SetDrive(uint8_t drive); - - private: - TwiMaster& twiMaster; - uint8_t twiAddress; - - void WriteRegister(uint8_t reg, uint8_t data); - uint8_t ReadRegister(uint8_t reg); - }; - } -} diff --git a/src/drivers/MotionSensor.h b/src/drivers/MotionSensor.h new file mode 100644 index 0000000000..30f77d9aac --- /dev/null +++ b/src/drivers/MotionSensor.h @@ -0,0 +1,78 @@ +#pragma once +#include +#include +#include + +namespace Pinetime { + namespace Drivers { + namespace MotionSensors { + enum class DeviceTypes : uint8_t { Unknown, BMA421, BMA425 }; + struct Values { + uint32_t steps; + int16_t x; + int16_t y; + int16_t z; + }; + } + + template + concept IsMotionSensor = requires(motionSensorImpl sensor, uint8_t registerAddress, uint8_t* data, uint8_t* constData, size_t size) { + { sensor.SoftReset() }; + { sensor.Init() }; + { sensor.Process() }; + { sensor.ResetStepCounter() }; + { sensor.IsOk() }; + { sensor.DeviceType() }; + { sensor.Read(registerAddress, data, size) }; + { sensor.Write(registerAddress, constData, size) }; + }; + + namespace Interface { + template + requires IsMotionSensor + class MotionSensor { + public: + explicit MotionSensor(T& impl) : impl {impl} {} + MotionSensor(const MotionSensor&) = delete; + MotionSensor& operator=(const MotionSensor&) = delete; + MotionSensor(MotionSensor&&) = delete; + MotionSensor& operator=(MotionSensor&&) = delete; + + void SoftReset() { + return impl.SoftReset(); + } + + void Init() { + impl.Init(); + } + + MotionSensors::Values Process() { + return impl.Process(); + } + + void ResetStepCounter() { + return impl.ResetStepCounter(); + } + + void Read(uint8_t registerAddress, uint8_t* buffer, size_t size) { + impl.Read(registerAddress, buffer, size); + } + + void Write(uint8_t registerAddress, const uint8_t* data, size_t size) { + impl.Write(registerAddress, data, size); + } + + bool IsOk() const { + return impl.IsOk(); + } + + MotionSensors::DeviceTypes DeviceType() const { + return impl.DeviceType(); + } + + private: + T& impl; + }; + } + } +} diff --git a/src/drivers/Spi.h b/src/drivers/Spi.h index 9b6a30f43b..bfd9e8a5b2 100644 --- a/src/drivers/Spi.h +++ b/src/drivers/Spi.h @@ -1,28 +1,55 @@ #pragma once #include #include -#include "drivers/SpiMaster.h" +#include +#include namespace Pinetime { namespace Drivers { - class Spi { - public: - Spi(SpiMaster& spiMaster, uint8_t pinCsn); - Spi(const Spi&) = delete; - Spi& operator=(const Spi&) = delete; - Spi(Spi&&) = delete; - Spi& operator=(Spi&&) = delete; - - bool Init(); - bool Write(const uint8_t* data, size_t size); - bool Read(uint8_t* cmd, size_t cmdSize, uint8_t* data, size_t dataSize); - bool WriteCmdAndBuffer(const uint8_t* cmd, size_t cmdSize, const uint8_t* data, size_t dataSize); - void Sleep(); - void Wakeup(); - - private: - SpiMaster& spiMaster; - uint8_t pinCsn; - }; + template + concept IsSpi = requires(SpiImpl s, const uint8_t* constData, uint8_t* data, const uint8_t* constCommand, uint8_t* command, size_t size) { + { s.Write(constData, size) } -> std::same_as; + { s.Read(command, size, data, size) } -> std::same_as; + }; + + namespace Interface { + template + requires IsSpi + class Spi { + public: + explicit Spi(T& spi) : impl {spi} { } + Spi(const Spi&) = delete; + Spi& operator=(const Spi&) = delete; + Spi(Spi&&) = delete; + Spi& operator=(Spi&&) = delete; + + bool Init() { + return impl.Init(); + } + + bool Write(const uint8_t* data, size_t size) { + return impl.Write(data, size); + } + + bool Read(uint8_t* cmd, size_t cmdSize, uint8_t* data, size_t dataSize) { + return impl.Read(cmd, cmdSize, data, dataSize); + } + + bool WriteCmdAndBuffer(const uint8_t* cmd, size_t cmdSize, const uint8_t* data, size_t dataSize) { + return impl.WriteCmdAndBuffer(cmd, cmdSize, data, dataSize); + } + + void Sleep() { + impl.Sleep(); + } + + void Wakeup() { + impl.Wakeup(); + } + + private: + T& impl; + }; + } } } diff --git a/src/drivers/SpiMaster.h b/src/drivers/SpiMaster.h index 5ea624f255..b28c456ebf 100644 --- a/src/drivers/SpiMaster.h +++ b/src/drivers/SpiMaster.h @@ -1,65 +1,69 @@ #pragma once #include #include - -#include -#include -#include +#include namespace Pinetime { namespace Drivers { - class SpiMaster { - public: - enum class SpiModule : uint8_t { SPI0, SPI1 }; - enum class BitOrder : uint8_t { Msb_Lsb, Lsb_Msb }; - enum class Modes : uint8_t { Mode0, Mode1, Mode2, Mode3 }; - enum class Frequencies : uint8_t { Freq8Mhz }; - struct Parameters { - BitOrder bitOrder; - Modes mode; - Frequencies Frequency; - uint8_t pinSCK; - uint8_t pinMOSI; - uint8_t pinMISO; + template + concept IsSpiMaster = + requires(SpiImpl spi, uint8_t pin, const uint8_t* constData, uint8_t* data, const uint8_t* constCommand, uint8_t* command, size_t size) { + { spi.Init() } -> std::same_as; + { spi.Write(pin, constData, size) } -> std::same_as; + { spi.Read(pin, command, size, data, size) } -> std::same_as; + { spi.WriteCmdAndBuffer(pin, constCommand, size, constData, size) } -> std::same_as; + { spi.OnStartedEvent() }; + { spi.OnEndEvent() }; + { spi.Sleep() }; + { spi.Wakeup() }; }; - SpiMaster(const SpiModule spi, const Parameters& params); - SpiMaster(const SpiMaster&) = delete; - SpiMaster& operator=(const SpiMaster&) = delete; - SpiMaster(SpiMaster&&) = delete; - SpiMaster& operator=(SpiMaster&&) = delete; + namespace Interface { + template + requires IsSpiMaster + class SpiMaster { + public: + explicit SpiMaster(T& spiMaster) : impl {spiMaster} { } + SpiMaster(const SpiMaster&) = delete; + SpiMaster& operator=(const SpiMaster&) = delete; + SpiMaster(SpiMaster&&) = delete; + SpiMaster& operator=(SpiMaster&&) = delete; + + bool Init() { + return impl.Init(); + } - bool Init(); - bool Write(uint8_t pinCsn, const uint8_t* data, size_t size); - bool Read(uint8_t pinCsn, uint8_t* cmd, size_t cmdSize, uint8_t* data, size_t dataSize); + bool Write(uint8_t pinCsn, const uint8_t* data, size_t size) { + return impl.Write(pinCsn, data, size); + } - bool WriteCmdAndBuffer(uint8_t pinCsn, const uint8_t* cmd, size_t cmdSize, const uint8_t* data, size_t dataSize); + bool Read(uint8_t pinCsn, uint8_t* cmd, size_t cmdSize, uint8_t* data, size_t dataSize) { + return impl.Read(pinCsn, cmd, cmdSize, data, dataSize); + } - void OnStartedEvent(); - void OnEndEvent(); + bool WriteCmdAndBuffer(uint8_t pinCsn, const uint8_t* cmd, size_t cmdSize, const uint8_t* data, size_t dataSize) { + return impl.WriteCmdAndBuffer(pinCsn, cmd, cmdSize, data, dataSize); + } - void Sleep(); - void Wakeup(); + void OnStartedEvent() { + impl.OnStartedEvent(); + } - private: - void SetupWorkaroundForFtpan58(NRF_SPIM_Type* spim, uint32_t ppi_channel, uint32_t gpiote_channel); - void DisableWorkaroundForFtpan58(NRF_SPIM_Type* spim, uint32_t ppi_channel, uint32_t gpiote_channel); - void PrepareTx(const volatile uint32_t bufferAddress, const volatile size_t size); - void PrepareRx(const volatile uint32_t cmdAddress, - const volatile size_t cmdSize, - const volatile uint32_t bufferAddress, - const volatile size_t size); + void OnEndEvent() { + impl.OnEndEvent(); + } - NRF_SPIM_Type* spiBaseAddress; - uint8_t pinCsn; + void Sleep() { + impl.Sleep(); + } - SpiMaster::SpiModule spi; - SpiMaster::Parameters params; + void Wakeup() { + impl.Wakeup(); + } - volatile uint32_t currentBufferAddr = 0; - volatile size_t currentBufferSize = 0; - volatile TaskHandle_t taskToNotify; - SemaphoreHandle_t mutex = nullptr; - }; + private: + T& impl; + }; + } } } diff --git a/src/drivers/SpiNorFlash.h b/src/drivers/SpiNorFlash.h index ad4d090756..e9d41c996b 100644 --- a/src/drivers/SpiNorFlash.h +++ b/src/drivers/SpiNorFlash.h @@ -1,60 +1,116 @@ #pragma once + #include #include +#include namespace Pinetime { namespace Drivers { - class Spi; - class SpiNorFlash { - public: - explicit SpiNorFlash(Spi& spi); - SpiNorFlash(const SpiNorFlash&) = delete; - SpiNorFlash& operator=(const SpiNorFlash&) = delete; - SpiNorFlash(SpiNorFlash&&) = delete; - SpiNorFlash& operator=(SpiNorFlash&&) = delete; - - struct __attribute__((packed)) Identification { - uint8_t manufacturer = 0; - uint8_t type = 0; - uint8_t density = 0; - }; + template + concept IsFlashMemory = requires(MemoryImpl memory, uint32_t address, uint8_t* buffer, const uint8_t* constBuffer, size_t size) { + { memory.ReadIdentification() }; + { memory.ReadStatusRegister() } -> std::same_as; + { memory.ReadConfigurationRegister() } -> std::same_as; + { memory.WriteInProgress() } -> std::same_as; + { memory.WriteEnabled() } -> std::same_as; + { memory.Read(address, buffer, size) }; + { memory.Write(address, constBuffer, size) }; + { memory.WriteEnable() }; + { memory.SectorErase(address) }; + { memory.ReadSecurityRegister() } -> std::same_as; + { memory.ProgramFailed() } -> std::same_as; + { memory.EraseFailed() } -> std::same_as; + { memory.Init() }; + { memory.Uninit() }; + { memory.Sleep() }; + { memory.Wakeup() }; + }; - Identification ReadIdentificaion(); - uint8_t ReadStatusRegister(); - bool WriteInProgress(); - bool WriteEnabled(); - uint8_t ReadConfigurationRegister(); - void Read(uint32_t address, uint8_t* buffer, size_t size); - void Write(uint32_t address, const uint8_t* buffer, size_t size); - void WriteEnable(); - void SectorErase(uint32_t sectorAddress); - uint8_t ReadSecurityRegister(); - bool ProgramFailed(); - bool EraseFailed(); - - void Init(); - void Uninit(); - - void Sleep(); - void Wakeup(); - - private: - enum class Commands : uint8_t { - PageProgram = 0x02, - Read = 0x03, - ReadStatusRegister = 0x05, - WriteEnable = 0x06, - ReadConfigurationRegister = 0x15, - SectorErase = 0x20, - ReadSecurityRegister = 0x2B, - ReadIdentification = 0x9F, - ReleaseFromDeepPowerDown = 0xAB, - DeepPowerDown = 0xB9 - }; - static constexpr uint16_t pageSize = 256; + namespace Interface { + template + requires IsFlashMemory + class SpiNorFlash { + public: + explicit SpiNorFlash(T& spi) : impl {spi} { + } + SpiNorFlash(const SpiNorFlash&) = delete; + SpiNorFlash& operator=(const SpiNorFlash&) = delete; + SpiNorFlash(SpiNorFlash&&) = delete; + SpiNorFlash& operator=(SpiNorFlash&&) = delete; + + struct __attribute__((packed)) Identification { + uint8_t manufacturer = 0; + uint8_t type = 0; + uint8_t density = 0; + }; + + Identification ReadIdentificaion() { + return impl.ReadIdentificaion(); + } + + uint8_t ReadStatusRegister() { + return impl.ReadStatusRegister(); + } + + bool WriteInProgress() { + return impl.WriteInProgress(); + } + + bool WriteEnabled() { + return impl.WriteEnabled(); + } + + uint8_t ReadConfigurationRegister() { + return impl.ReadConfigurationRegister(); + } + + void Read(uint32_t address, uint8_t* buffer, size_t size) { + impl.Read(address, buffer, size); + } + + void Write(uint32_t address, const uint8_t* buffer, size_t size) { + impl.Write(address, buffer, size); + } - Spi& spi; - Identification device_id; - }; + void WriteEnable() { + return impl.WriteEnable(); + } + + void SectorErase(uint32_t sectorAddress) { + impl.SectorErase(sectorAddress); + } + + uint8_t ReadSecurityRegister() { + return impl.ReadSecurityRegister(); + } + + bool ProgramFailed() { + return impl.ProgramFailed(); + } + + bool EraseFailed() { + return impl.EraseFailed(); + } + + void Init() { + impl.Init(); + } + + void Uninit() { + impl.Uninit(); + } + + void Sleep() { + impl.Sleep(); + } + + void Wakeup() { + impl.Wakeup(); + } + + private: + T& impl; + }; + } } } diff --git a/src/drivers/St7789.h b/src/drivers/St7789.h deleted file mode 100644 index 8c2ac0936d..0000000000 --- a/src/drivers/St7789.h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once -#include -#include - -namespace Pinetime { - namespace Drivers { - class Spi; - class St7789 { - public: - explicit St7789(Spi& spi, uint8_t pinDataCommand); - St7789(const St7789&) = delete; - St7789& operator=(const St7789&) = delete; - St7789(St7789&&) = delete; - St7789& operator=(St7789&&) = delete; - - void Init(); - void Uninit(); - void DrawPixel(uint16_t x, uint16_t y, uint32_t color); - - void VerticalScrollDefinition(uint16_t topFixedLines, uint16_t scrollLines, uint16_t bottomFixedLines); - void VerticalScrollStartAddress(uint16_t line); - - void DrawBuffer(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t* data, size_t size); - - void Sleep(); - void Wakeup(); - - private: - Spi& spi; - uint8_t pinDataCommand; - uint8_t verticalScrollingStartAddress = 0; - - void HardwareReset(); - void SoftwareReset(); - void SleepOut(); - void SleepIn(); - void ColMod(); - void MemoryDataAccessControl(); - void DisplayInversionOn(); - void NormalModeOn(); - void WriteToRam(); - void DisplayOn(); - void DisplayOff(); - - void SetAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); - void SetVdv(); - void WriteCommand(uint8_t cmd); - void WriteSpi(const uint8_t* data, size_t size); - - enum class Commands : uint8_t { - SoftwareReset = 0x01, - SleepIn = 0x10, - SleepOut = 0x11, - NormalModeOn = 0x13, - DisplayInversionOn = 0x21, - DisplayOff = 0x28, - DisplayOn = 0x29, - ColumnAddressSet = 0x2a, - RowAddressSet = 0x2b, - WriteToRam = 0x2c, - MemoryDataAccessControl = 0x36, - VerticalScrollDefinition = 0x33, - VerticalScrollStartAddress = 0x37, - ColMod = 0x3a, - VdvSet = 0xc4, - }; - void WriteData(uint8_t data); - void ColumnAddressSet(); - - static constexpr uint16_t Width = 240; - static constexpr uint16_t Height = 320; - void RowAddressSet(); - }; - } -} diff --git a/src/drivers/TouchPanel.h b/src/drivers/TouchPanel.h new file mode 100644 index 0000000000..5a6b9ffcef --- /dev/null +++ b/src/drivers/TouchPanel.h @@ -0,0 +1,83 @@ +#pragma once +#include +#include +#include + +namespace Pinetime { + namespace Drivers { + template + concept IsTouchPanel = requires(touchpanelImpl touchpanel) { + { touchpanel.Init() }; + { touchpanel.GetTouchInfo() }; + { touchpanel.Sleep() }; + { touchpanel.Wakeup() }; + { touchpanel.GetChipId() }; + { touchpanel.GetVendorId() }; + { touchpanel.GetFwVersion() }; + }; + + namespace TouchPanels { + enum class Gestures : uint8_t { + None = 0x00, + SlideDown = 0x01, + SlideUp = 0x02, + SlideLeft = 0x03, + SlideRight = 0x04, + SingleTap = 0x05, + DoubleTap = 0x0B, + LongPress = 0x0C + }; + struct TouchInfos { + uint16_t x = 0; + uint16_t y = 0; + Gestures gesture = Gestures::None; + bool touching = false; + bool isValid = false; + }; + } + + namespace Interface { + template + requires IsTouchPanel + class Touchpanel { + public: + explicit Touchpanel(T& impl) : impl {impl} {} + Touchpanel(const Touchpanel&) = delete; + Touchpanel& operator=(const Touchpanel&) = delete; + Touchpanel(Touchpanel&&) = delete; + Touchpanel& operator=(Touchpanel&&) = delete; + + bool Init() { + return impl.Init(); + } + + TouchPanels::TouchInfos GetTouchInfo() { + return impl.GetTouchInfo(); + } + + void Sleep() { + impl.Sleep(); + } + + void Wakeup() { + impl.Wakeup(); + } + + uint8_t GetChipId() const { + return impl.GetChipId(); + } + + uint8_t GetVendorId() const { + return impl.GetVendorId(); + } + + uint8_t GetFwVersion() const { + return impl.GetFwVersion(); + } + + private: + T& impl; + }; + } + } +} diff --git a/src/drivers/TwiMaster.h b/src/drivers/TwiMaster.h index 30ac6c5f92..0035c9db93 100644 --- a/src/drivers/TwiMaster.h +++ b/src/drivers/TwiMaster.h @@ -1,41 +1,55 @@ #pragma once -#include -#include -#include // NRF_TWIM_Type +#include +#include #include namespace Pinetime { namespace Drivers { - class TwiMaster { - public: - enum class ErrorCodes { NoError, TransactionFailed }; - - TwiMaster(NRF_TWIM_Type* module, uint32_t frequency, uint8_t pinSda, uint8_t pinScl); - - void Init(); - ErrorCodes Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* buffer, size_t size); - ErrorCodes Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size); - - void Sleep(); - void Wakeup(); - - private: - ErrorCodes Read(uint8_t deviceAddress, uint8_t* buffer, size_t size, bool stop); - ErrorCodes Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop); - void FixHwFreezed(); - void ConfigurePins() const; - - NRF_TWIM_Type* twiBaseAddress; - SemaphoreHandle_t mutex = nullptr; - NRF_TWIM_Type* module; - uint32_t frequency; - uint8_t pinSda; - uint8_t pinScl; - static constexpr uint8_t maxDataSize {16}; - static constexpr uint8_t registerSize {1}; - uint8_t internalBuffer[maxDataSize + registerSize]; - uint32_t txStartedCycleCount = 0; - static constexpr uint32_t HwFreezedDelay {161000}; - }; + template + concept IsTwi = requires(TwiImpl twi, uint8_t deviceAddress, uint8_t registerAddress, uint8_t* data, const uint8_t* constData, size_t size) { + { twi.Init() }; + { twi.Write(deviceAddress, registerAddress, constData, size) }; + { twi.Read(deviceAddress, registerAddress, data, size) }; + { twi.Sleep() }; + { twi.Wakeup() }; + }; + + namespace Interface { + template + requires IsTwi + class TwiMaster { + public: + explicit TwiMaster(T& impl) : impl {impl} {} + TwiMaster(const TwiMaster&) = delete; + TwiMaster& operator=(const TwiMaster&) = delete; + TwiMaster(TwiMaster&&) = delete; + TwiMaster& operator=(TwiMaster&&) = delete; + + enum class ErrorCodes { NoError, TransactionFailed }; + + void Init() { + impl.Init(); + } + + ErrorCodes Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* buffer, size_t size) { + return static_cast(impl.Read(deviceAddress, registerAddress, buffer, size)); + } + + ErrorCodes Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size) { + return static_cast(impl.Write(deviceAddress, registerAddress, data, size)); + } + + void Sleep() { + impl.Sleep(); + } + + void Wakeup() { + impl.WakeUp(); + } + + private: + T& impl; + }; + } } } diff --git a/src/drivers/Watchdog.cpp b/src/drivers/Watchdog.cpp deleted file mode 100644 index d0907a6502..0000000000 --- a/src/drivers/Watchdog.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "drivers/Watchdog.h" -#include -using namespace Pinetime::Drivers; - -void Watchdog::Setup(uint8_t timeoutSeconds) { - NRF_WDT->CONFIG &= ~(WDT_CONFIG_SLEEP_Msk << WDT_CONFIG_SLEEP_Pos); - NRF_WDT->CONFIG |= (WDT_CONFIG_HALT_Run << WDT_CONFIG_SLEEP_Pos); - - NRF_WDT->CONFIG &= ~(WDT_CONFIG_HALT_Msk << WDT_CONFIG_HALT_Pos); - NRF_WDT->CONFIG |= (WDT_CONFIG_HALT_Pause << WDT_CONFIG_HALT_Pos); - - /* timeout (s) = (CRV + 1) / 32768 */ - // JF : 7500 = 7.5s - uint32_t crv = (((timeoutSeconds * 1000u) << 15u) / 1000) - 1; - NRF_WDT->CRV = crv; - - /* Enable reload requests */ - NRF_WDT->RREN = (WDT_RREN_RR0_Enabled << WDT_RREN_RR0_Pos); - - resetReason = ActualResetReason(); -} - -void Watchdog::Start() { - NRF_WDT->TASKS_START = 1; -} - -void Watchdog::Kick() { - NRF_WDT->RR[0] = WDT_RR_RR_Reload; -} - -Watchdog::ResetReasons Watchdog::ActualResetReason() const { - uint32_t reason = NRF_POWER->RESETREAS; - NRF_POWER->RESETREAS = 0xffffffff; - - if (reason & 0x01u) - return ResetReasons::ResetPin; - if ((reason >> 1u) & 0x01u) - return ResetReasons::Watchdog; - if ((reason >> 2u) & 0x01u) - return ResetReasons::SoftReset; - if ((reason >> 3u) & 0x01u) - return ResetReasons::CpuLockup; - if ((reason >> 16u) & 0x01u) - return ResetReasons::SystemOff; - if ((reason >> 17u) & 0x01u) - return ResetReasons::LpComp; - if ((reason) &0x01u) - return ResetReasons::DebugInterface; - if ((reason >> 19u) & 0x01u) - return ResetReasons::NFC; - return ResetReasons::HardReset; -} - -const char* Watchdog::ResetReasonToString(Watchdog::ResetReasons reason) { - switch (reason) { - case ResetReasons::ResetPin: - return "Reset pin"; - case ResetReasons::Watchdog: - return "Watchdog"; - case ResetReasons::DebugInterface: - return "Debug interface"; - case ResetReasons::LpComp: - return "LPCOMP"; - case ResetReasons::SystemOff: - return "System OFF"; - case ResetReasons::CpuLockup: - return "CPU Lock-up"; - case ResetReasons::SoftReset: - return "Soft reset"; - case ResetReasons::NFC: - return "NFC"; - case ResetReasons::HardReset: - return "Hard reset"; - default: - return "Unknown"; - } -} diff --git a/src/drivers/Watchdog.h b/src/drivers/Watchdog.h index 03807d61b2..56a4f3d8b6 100644 --- a/src/drivers/Watchdog.h +++ b/src/drivers/Watchdog.h @@ -1,34 +1,75 @@ #pragma once +#include #include namespace Pinetime { namespace Drivers { - class Watchdog { - public: + namespace Watchdogs { enum class ResetReasons { ResetPin, Watchdog, SoftReset, CpuLockup, SystemOff, LpComp, DebugInterface, NFC, HardReset }; - void Setup(uint8_t timeoutSeconds); - void Start(); - void Kick(); - ResetReasons ResetReason() const { - return resetReason; - } - static const char* ResetReasonToString(ResetReasons reason); - - private: - ResetReasons resetReason; - ResetReasons ActualResetReason() const; - }; - - class WatchdogView { - public: - WatchdogView(const Watchdog& watchdog) : watchdog {watchdog} { - } - Watchdog::ResetReasons ResetReason() const { - return watchdog.ResetReason(); - } - - private: - const Watchdog& watchdog; - }; + } + + template + concept IsWatchdog = requires(WatchdogImpl watchdog) { + { watchdog.Start() }; + { watchdog.Kick() }; + { watchdog.ResetReason() } -> std::same_as; + }; + + namespace Interface { + template + requires IsWatchdog + class Watchdog { + public: + explicit Watchdog(T& impl) : impl {impl} {} + Watchdog(const Watchdog&) = delete; + Watchdog& operator=(const Watchdog&) = delete; + Watchdog(Watchdog&&) = delete; + Watchdog& operator=(Watchdog&&) = delete; + + void Setup(uint8_t timeoutSeconds) { + impl.Setup(timeoutSeconds); + } + + void Start() { + impl.Start(); + } + + void Kick() { + impl.Kick(); + } + + Watchdogs::ResetReasons ResetReason() const { + return impl.ResetReason(); + } + + static const char* ResetReasonToString(Watchdogs::ResetReasons reason) { + switch (reason) { + case Watchdogs::ResetReasons::ResetPin: + return "Reset pin"; + case Watchdogs::ResetReasons::Watchdog: + return "Watchdog"; + case Watchdogs::ResetReasons::DebugInterface: + return "Debug interface"; + case Watchdogs::ResetReasons::LpComp: + return "LPCOMP"; + case Watchdogs::ResetReasons::SystemOff: + return "System OFF"; + case Watchdogs::ResetReasons::CpuLockup: + return "CPU Lock-up"; + case Watchdogs::ResetReasons::SoftReset: + return "Soft reset"; + case Watchdogs::ResetReasons::NFC: + return "NFC"; + case Watchdogs::ResetReasons::HardReset: + return "Hard reset"; + default: + return "Unknown"; + } + } + + private: + T& impl; + }; + } } } diff --git a/src/drivers/WatchdogView.h b/src/drivers/WatchdogView.h new file mode 100644 index 0000000000..ed42aadb3f --- /dev/null +++ b/src/drivers/WatchdogView.h @@ -0,0 +1,20 @@ +#pragma once +#include + +namespace Pinetime { + namespace Drivers { + class WatchdogView { + public: + explicit WatchdogView(const Watchdog& watchdog) : watchdog {watchdog} { + } + + Watchdogs::ResetReasons ResetReason() const { + return watchdog.ResetReason(); + } + + private: + const Watchdog& watchdog; + }; + } +} + diff --git a/src/drivers/St7789.cpp b/src/drivers/displays/St7789.cpp similarity index 98% rename from src/drivers/St7789.cpp rename to src/drivers/displays/St7789.cpp index cfd5bd2ce4..32328125a7 100644 --- a/src/drivers/St7789.cpp +++ b/src/drivers/displays/St7789.cpp @@ -1,10 +1,10 @@ -#include "drivers/St7789.h" +#include "St7789.h" #include #include #include #include "drivers/Spi.h" -using namespace Pinetime::Drivers; +using namespace Pinetime::Drivers::Displays; St7789::St7789(Spi& spi, uint8_t pinDataCommand) : spi {spi}, pinDataCommand {pinDataCommand} { } diff --git a/src/drivers/displays/St7789.h b/src/drivers/displays/St7789.h new file mode 100644 index 0000000000..09db5ee639 --- /dev/null +++ b/src/drivers/displays/St7789.h @@ -0,0 +1,78 @@ +#pragma once +#include "drivers/Spi.h" +#include +#include +#include "port/Spi.h" + +namespace Pinetime { + namespace Drivers { + namespace Displays { + class St7789 { + public: + explicit St7789(Spi& spi, uint8_t pinDataCommand); + St7789(const St7789&) = delete; + St7789& operator=(const St7789&) = delete; + St7789(St7789&&) = delete; + St7789& operator=(St7789&&) = delete; + + void Init(); + void Uninit(); + void DrawPixel(uint16_t x, uint16_t y, uint32_t color); + + void VerticalScrollDefinition(uint16_t topFixedLines, uint16_t scrollLines, uint16_t bottomFixedLines); + void VerticalScrollStartAddress(uint16_t line); + + void DrawBuffer(uint16_t x, uint16_t y, uint16_t width, uint16_t height, const uint8_t* data, size_t size); + + void Sleep(); + void Wakeup(); + + private: + Spi& spi; + uint8_t pinDataCommand; + uint8_t verticalScrollingStartAddress = 0; + + void HardwareReset(); + void SoftwareReset(); + void SleepOut(); + void SleepIn(); + void ColMod(); + void MemoryDataAccessControl(); + void DisplayInversionOn(); + void NormalModeOn(); + void WriteToRam(); + void DisplayOn(); + void DisplayOff(); + + void SetAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1); + void SetVdv(); + void WriteCommand(uint8_t cmd); + void WriteSpi(const uint8_t* data, size_t size); + + enum class Commands : uint8_t { + SoftwareReset = 0x01, + SleepIn = 0x10, + SleepOut = 0x11, + NormalModeOn = 0x13, + DisplayInversionOn = 0x21, + DisplayOff = 0x28, + DisplayOn = 0x29, + ColumnAddressSet = 0x2a, + RowAddressSet = 0x2b, + WriteToRam = 0x2c, + MemoryDataAccessControl = 0x36, + VerticalScrollDefinition = 0x33, + VerticalScrollStartAddress = 0x37, + ColMod = 0x3a, + VdvSet = 0xc4, + }; + void WriteData(uint8_t data); + void ColumnAddressSet(); + + static constexpr uint16_t Width = 240; + static constexpr uint16_t Height = 320; + void RowAddressSet(); + }; + } + } +} diff --git a/src/drivers/Hrs3300.cpp b/src/drivers/heartRateSensors/Hrs3300.cpp similarity index 97% rename from src/drivers/Hrs3300.cpp rename to src/drivers/heartRateSensors/Hrs3300.cpp index ec620af2ce..e329bb4792 100644 --- a/src/drivers/Hrs3300.cpp +++ b/src/drivers/heartRateSensors/Hrs3300.cpp @@ -4,7 +4,7 @@ C++ port Copyright (C) 2021 Jean-François Milants */ -#include "drivers/Hrs3300.h" +#include "Hrs3300.h" #include #include @@ -12,7 +12,7 @@ #include #include -using namespace Pinetime::Drivers; +using namespace Pinetime::Drivers::HeartRateSensors; /** Driver for the HRS3300 heart rate sensor. * Original implementation from wasp-os : https://github.com/daniel-thompson/wasp-os/blob/master/wasp/drivers/hrs3300.py */ diff --git a/src/drivers/heartRateSensors/Hrs3300.h b/src/drivers/heartRateSensors/Hrs3300.h new file mode 100644 index 0000000000..43ec44f748 --- /dev/null +++ b/src/drivers/heartRateSensors/Hrs3300.h @@ -0,0 +1,49 @@ +#pragma once + +#include "drivers/TwiMaster.h" +#include "port/TwiMaster.h" + +namespace Pinetime { + namespace Drivers { + namespace HeartRateSensors { + class Hrs3300 { + public: + enum class Registers : uint8_t { + Id = 0x00, + Enable = 0x01, + EnableHen = 0x80, + C1dataM = 0x08, + C0DataM = 0x09, + C0DataH = 0x0a, + PDriver = 0x0c, + C1dataH = 0x0d, + C1dataL = 0x0e, + C0dataL = 0x0f, + Res = 0x16, + Hgain = 0x17 + }; + + Hrs3300(TwiMaster& twiMaster, uint8_t twiAddress); + Hrs3300(const Hrs3300&) = delete; + Hrs3300& operator=(const Hrs3300&) = delete; + Hrs3300(Hrs3300&&) = delete; + Hrs3300& operator=(Hrs3300&&) = delete; + + void Init(); + void Enable(); + void Disable(); + uint32_t ReadHrs(); + uint32_t ReadAls(); + void SetGain(uint8_t gain); + void SetDrive(uint8_t drive); + + private: + TwiMaster& twiMaster; + uint8_t twiAddress; + + void WriteRegister(uint8_t reg, uint8_t data); + uint8_t ReadRegister(uint8_t reg); + }; + } + } +} diff --git a/src/drivers/Bma421.cpp b/src/drivers/motionSensors/Bma421.cpp similarity index 89% rename from src/drivers/Bma421.cpp rename to src/drivers/motionSensors/Bma421.cpp index 539cc8d1d3..8335bca18d 100644 --- a/src/drivers/Bma421.cpp +++ b/src/drivers/motionSensors/Bma421.cpp @@ -1,10 +1,10 @@ -#include "drivers/Bma421.h" +#include "Bma421.h" #include #include #include "drivers/TwiMaster.h" #include -using namespace Pinetime::Drivers; +using namespace Pinetime::Drivers::MotionSensors; namespace { int8_t user_i2c_read(uint8_t reg_addr, uint8_t* reg_data, uint32_t length, void* intf_ptr) { @@ -44,13 +44,13 @@ void Bma421::Init() { switch (bma.chip_id) { case BMA423_CHIP_ID: - deviceType = DeviceTypes::BMA421; + deviceType = MotionSensors::DeviceTypes::BMA421; break; case BMA425_CHIP_ID: - deviceType = DeviceTypes::BMA425; + deviceType = MotionSensors::DeviceTypes::BMA425; break; default: - deviceType = DeviceTypes::Unknown; + deviceType = MotionSensors::DeviceTypes::Unknown; break; } @@ -99,7 +99,7 @@ void Bma421::Write(uint8_t registerAddress, const uint8_t* data, size_t size) { twiMaster.Write(deviceAddress, registerAddress, data, size); } -Bma421::Values Bma421::Process() { +Pinetime::Drivers::MotionSensors::Values Bma421::Process() { if (not isOk) return {}; struct bma4_accel data; @@ -133,6 +133,6 @@ void Bma421::SoftReset() { nrf_delay_ms(1); } } -Bma421::DeviceTypes Bma421::DeviceType() const { +Pinetime::Drivers::MotionSensors::DeviceTypes Bma421::DeviceType() const { return deviceType; } diff --git a/src/drivers/motionSensors/Bma421.h b/src/drivers/motionSensors/Bma421.h new file mode 100644 index 0000000000..7660c3a2d3 --- /dev/null +++ b/src/drivers/motionSensors/Bma421.h @@ -0,0 +1,50 @@ +#pragma once +#include "drivers/TwiMaster.h" +#include "port/TwiMaster.h" +#include "drivers/MotionSensor.h" +#include + +namespace Pinetime { + namespace Drivers { + namespace MotionSensors { + class Bma421 { + public: + enum class DeviceTypes : uint8_t { Unknown, BMA421, BMA425 }; + struct Values { + uint32_t steps; + int16_t x; + int16_t y; + int16_t z; + }; + Bma421(TwiMaster& twiMaster, uint8_t twiAddress); + Bma421(const Bma421&) = delete; + Bma421& operator=(const Bma421&) = delete; + Bma421(Bma421&&) = delete; + Bma421& operator=(Bma421&&) = delete; + + /// The chip freezes the TWI bus after the softreset operation. Softreset is separated from the + /// Init() method to allow the caller to uninit and then reinit the TWI device after the softreset. + void SoftReset(); + void Init(); + MotionSensors::Values Process(); + void ResetStepCounter(); + + void Read(uint8_t registerAddress, uint8_t* buffer, size_t size); + void Write(uint8_t registerAddress, const uint8_t* data, size_t size); + + bool IsOk() const; + MotionSensors::DeviceTypes DeviceType() const; + + private: + void Reset(); + + TwiMaster& twiMaster; + uint8_t deviceAddress = 0x18; + struct bma4_dev bma; + bool isOk = false; + bool isResetOk = false; + MotionSensors::DeviceTypes deviceType = MotionSensors::DeviceTypes::Unknown; + }; + } + } +} \ No newline at end of file diff --git a/src/drivers/Spi.cpp b/src/drivers/nrf52/Spi.cpp similarity index 92% rename from src/drivers/Spi.cpp rename to src/drivers/nrf52/Spi.cpp index e477622b6f..4197ecfa06 100644 --- a/src/drivers/Spi.cpp +++ b/src/drivers/nrf52/Spi.cpp @@ -1,8 +1,8 @@ -#include "drivers/Spi.h" +#include "drivers/nrf52/Spi.h" #include #include -using namespace Pinetime::Drivers; +using namespace Pinetime::Drivers::Nrf52; Spi::Spi(SpiMaster& spiMaster, uint8_t pinCsn) : spiMaster {spiMaster}, pinCsn {pinCsn} { nrf_gpio_cfg_output(pinCsn); diff --git a/src/drivers/nrf52/Spi.h b/src/drivers/nrf52/Spi.h new file mode 100644 index 0000000000..1891fe0a97 --- /dev/null +++ b/src/drivers/nrf52/Spi.h @@ -0,0 +1,30 @@ +#pragma once +#include +#include +#include "drivers/nrf52/SpiMaster.h" + +namespace Pinetime { + namespace Drivers { + namespace Nrf52 { + class Spi { + public: + Spi(Pinetime::Drivers::Nrf52::SpiMaster& spiMaster, uint8_t pinCsn); + Spi(const Spi&) = delete; + Spi& operator=(const Spi&) = delete; + Spi(Spi&&) = delete; + Spi& operator=(Spi&&) = delete; + + bool Init(); + bool Write(const uint8_t* data, size_t size); + bool Read(uint8_t* cmd, size_t cmdSize, uint8_t* data, size_t dataSize); + bool WriteCmdAndBuffer(const uint8_t* cmd, size_t cmdSize, const uint8_t* data, size_t dataSize); + void Sleep(); + void Wakeup(); + + private: + Pinetime::Drivers::Nrf52::SpiMaster& spiMaster; + uint8_t pinCsn; + }; + } + } +} diff --git a/src/drivers/SpiMaster.cpp b/src/drivers/nrf52/SpiMaster.cpp similarity index 99% rename from src/drivers/SpiMaster.cpp rename to src/drivers/nrf52/SpiMaster.cpp index 38f72fee62..2f4da4b90d 100644 --- a/src/drivers/SpiMaster.cpp +++ b/src/drivers/nrf52/SpiMaster.cpp @@ -1,10 +1,10 @@ -#include "drivers/SpiMaster.h" +#include "SpiMaster.h" #include #include #include #include -using namespace Pinetime::Drivers; +using namespace Pinetime::Drivers::Nrf52; SpiMaster::SpiMaster(const SpiMaster::SpiModule spi, const SpiMaster::Parameters& params) : spi {spi}, params {params} { } diff --git a/src/drivers/nrf52/SpiMaster.h b/src/drivers/nrf52/SpiMaster.h new file mode 100644 index 0000000000..affaddfd17 --- /dev/null +++ b/src/drivers/nrf52/SpiMaster.h @@ -0,0 +1,67 @@ +#pragma once +#include +#include + +#include +#include +#include + +namespace Pinetime { + namespace Drivers { + namespace Nrf52 { + class SpiMaster { + public: + enum class SpiModule : uint8_t { SPI0, SPI1 }; + enum class BitOrder : uint8_t { Msb_Lsb, Lsb_Msb }; + enum class Modes : uint8_t { Mode0, Mode1, Mode2, Mode3 }; + enum class Frequencies : uint8_t { Freq8Mhz }; + struct Parameters { + BitOrder bitOrder; + Modes mode; + Frequencies Frequency; + uint8_t pinSCK; + uint8_t pinMOSI; + uint8_t pinMISO; + }; + + SpiMaster(const SpiModule spi, const Parameters& params); + SpiMaster(const SpiMaster&) = delete; + SpiMaster& operator=(const SpiMaster&) = delete; + SpiMaster(SpiMaster&&) = delete; + SpiMaster& operator=(SpiMaster&&) = delete; + + bool Init(); + bool Write(uint8_t pinCsn, const uint8_t* data, size_t size); + bool Read(uint8_t pinCsn, uint8_t* cmd, size_t cmdSize, uint8_t* data, size_t dataSize); + + bool WriteCmdAndBuffer(uint8_t pinCsn, const uint8_t* cmd, size_t cmdSize, const uint8_t* data, size_t dataSize); + + void OnStartedEvent(); + void OnEndEvent(); + + void Sleep(); + void Wakeup(); + + private: + void SetupWorkaroundForFtpan58(NRF_SPIM_Type* spim, uint32_t ppi_channel, uint32_t gpiote_channel); + void DisableWorkaroundForFtpan58(NRF_SPIM_Type* spim, uint32_t ppi_channel, uint32_t gpiote_channel); + void PrepareTx(const volatile uint32_t bufferAddress, const volatile size_t size); + void PrepareRx(const volatile uint32_t cmdAddress, + const volatile size_t cmdSize, + const volatile uint32_t bufferAddress, + const volatile size_t size); + + NRF_SPIM_Type* spiBaseAddress; + uint8_t pinCsn; + + SpiMaster::SpiModule spi; + SpiMaster::Parameters params; + + volatile uint32_t currentBufferAddr = 0; + volatile size_t currentBufferSize = 0; + volatile TaskHandle_t taskToNotify; + SemaphoreHandle_t mutex = nullptr; + }; + } + } +} diff --git a/src/drivers/TwiMaster.cpp b/src/drivers/nrf52/TwiMaster.cpp similarity index 98% rename from src/drivers/TwiMaster.cpp rename to src/drivers/nrf52/TwiMaster.cpp index 25d23c28ce..179a01d321 100644 --- a/src/drivers/TwiMaster.cpp +++ b/src/drivers/nrf52/TwiMaster.cpp @@ -1,9 +1,9 @@ -#include "drivers/TwiMaster.h" +#include "drivers/nrf52/TwiMaster.h" #include #include #include -using namespace Pinetime::Drivers; +using namespace Pinetime::Drivers::Nrf52; // TODO use shortcut to automatically send STOP when receive LastTX, for example // TODO use DMA/IRQ diff --git a/src/drivers/nrf52/TwiMaster.h b/src/drivers/nrf52/TwiMaster.h new file mode 100644 index 0000000000..64b4e63a19 --- /dev/null +++ b/src/drivers/nrf52/TwiMaster.h @@ -0,0 +1,44 @@ +#pragma once +#include +#include +#include // NRF_TWIM_Type +#include +#include "drivers/TwiMaster.h" + +namespace Pinetime { + namespace Drivers { + namespace Nrf52 { + class TwiMaster { + public: + enum class ErrorCodes { NoError, TransactionFailed }; + + TwiMaster(NRF_TWIM_Type* module, uint32_t frequency, uint8_t pinSda, uint8_t pinScl); + + void Init(); + ErrorCodes Read(uint8_t deviceAddress, uint8_t registerAddress, uint8_t* buffer, size_t size); + ErrorCodes Write(uint8_t deviceAddress, uint8_t registerAddress, const uint8_t* data, size_t size); + + void Sleep(); + void Wakeup(); + + private: + ErrorCodes Read(uint8_t deviceAddress, uint8_t* buffer, size_t size, bool stop); + ErrorCodes Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop); + void FixHwFreezed(); + void ConfigurePins() const; + + NRF_TWIM_Type* twiBaseAddress; + SemaphoreHandle_t mutex = nullptr; + NRF_TWIM_Type* module; + uint32_t frequency; + uint8_t pinSda; + uint8_t pinScl; + static constexpr uint8_t maxDataSize {16}; + static constexpr uint8_t registerSize {1}; + uint8_t internalBuffer[maxDataSize + registerSize]; + uint32_t txStartedCycleCount = 0; + static constexpr uint32_t HwFreezedDelay {161000}; + }; + } + } +} diff --git a/src/drivers/nrf52/Watchdog.cpp b/src/drivers/nrf52/Watchdog.cpp new file mode 100644 index 0000000000..50845158b4 --- /dev/null +++ b/src/drivers/nrf52/Watchdog.cpp @@ -0,0 +1,52 @@ +#include "Watchdog.h" +#include +using namespace Pinetime::Drivers::Nrf52; + +void Watchdog::Setup(uint8_t timeoutSeconds) { + NRF_WDT->CONFIG &= ~(WDT_CONFIG_SLEEP_Msk << WDT_CONFIG_SLEEP_Pos); + NRF_WDT->CONFIG |= (WDT_CONFIG_HALT_Run << WDT_CONFIG_SLEEP_Pos); + + NRF_WDT->CONFIG &= ~(WDT_CONFIG_HALT_Msk << WDT_CONFIG_HALT_Pos); + NRF_WDT->CONFIG |= (WDT_CONFIG_HALT_Pause << WDT_CONFIG_HALT_Pos); + + /* timeout (s) = (CRV + 1) / 32768 */ + // JF : 7500 = 7.5s + uint32_t crv = (((timeoutSeconds * 1000u) << 15u) / 1000) - 1; + NRF_WDT->CRV = crv; + + /* Enable reload requests */ + NRF_WDT->RREN = (WDT_RREN_RR0_Enabled << WDT_RREN_RR0_Pos); + + resetReason = ActualResetReason(); +} + +void Watchdog::Start() { + NRF_WDT->TASKS_START = 1; +} + +void Watchdog::Kick() { + NRF_WDT->RR[0] = WDT_RR_RR_Reload; +} + +Pinetime::Drivers::Watchdogs::ResetReasons Watchdog::ActualResetReason() const { + uint32_t reason = NRF_POWER->RESETREAS; + NRF_POWER->RESETREAS = 0xffffffff; + + if (reason & 0x01u) + return Watchdogs::ResetReasons::ResetPin; + if ((reason >> 1u) & 0x01u) + return Watchdogs::ResetReasons::Watchdog; + if ((reason >> 2u) & 0x01u) + return Watchdogs::ResetReasons::SoftReset; + if ((reason >> 3u) & 0x01u) + return Watchdogs::ResetReasons::CpuLockup; + if ((reason >> 16u) & 0x01u) + return Watchdogs::ResetReasons::SystemOff; + if ((reason >> 17u) & 0x01u) + return Watchdogs::ResetReasons::LpComp; + if ((reason) &0x01u) + return Watchdogs::ResetReasons::DebugInterface; + if ((reason >> 19u) & 0x01u) + return Watchdogs::ResetReasons::NFC; + return Watchdogs::ResetReasons::HardReset; +} diff --git a/src/drivers/nrf52/Watchdog.h b/src/drivers/nrf52/Watchdog.h new file mode 100644 index 0000000000..92f19f5252 --- /dev/null +++ b/src/drivers/nrf52/Watchdog.h @@ -0,0 +1,24 @@ +#pragma once +#include "drivers/Watchdog.h" +#include + +namespace Pinetime { + namespace Drivers { + namespace Nrf52 { + class Watchdog { + public: + enum class ResetReasons { ResetPin, Watchdog, SoftReset, CpuLockup, SystemOff, LpComp, DebugInterface, NFC, HardReset }; + void Setup(uint8_t timeoutSeconds); + void Start(); + void Kick(); + Watchdogs::ResetReasons ResetReason() const { + return resetReason; + } + + private: + Watchdogs::ResetReasons resetReason; + Watchdogs::ResetReasons ActualResetReason() const; + }; + } + } +} diff --git a/src/drivers/SpiNorFlash.cpp b/src/drivers/spiFlash/SpiNorFlash.cpp similarity index 93% rename from src/drivers/SpiNorFlash.cpp rename to src/drivers/spiFlash/SpiNorFlash.cpp index 28f82fe6c4..40015590ad 100644 --- a/src/drivers/SpiNorFlash.cpp +++ b/src/drivers/spiFlash/SpiNorFlash.cpp @@ -1,16 +1,16 @@ -#include "drivers/SpiNorFlash.h" +#include "drivers/spiFlash/SpiNorFlash.h" #include #include #include #include "drivers/Spi.h" -using namespace Pinetime::Drivers; +using namespace Pinetime::Drivers::SpiFlash; -SpiNorFlash::SpiNorFlash(Spi& spi) : spi {spi} { +SpiNorFlash::SpiNorFlash(Pinetime::Drivers::Spi& spi) : spi {spi} { } void SpiNorFlash::Init() { - device_id = ReadIdentificaion(); + device_id = ReadIdentification(); NRF_LOG_INFO("[SpiNorFlash] Manufacturer : %d, Memory type : %d, memory density : %d", device_id.manufacturer, device_id.type, @@ -32,7 +32,7 @@ void SpiNorFlash::Wakeup() { uint8_t cmd[cmdSize] = {static_cast(Commands::ReleaseFromDeepPowerDown), 0x01, 0x02, 0x03}; uint8_t id = 0; spi.Read(reinterpret_cast(&cmd), cmdSize, &id, 1); - auto devId = device_id = ReadIdentificaion(); + auto devId = device_id = ReadIdentification(); if (devId.type != device_id.type) { NRF_LOG_INFO("[SpiNorFlash] ID on Wakeup: Failed"); } else { @@ -41,7 +41,7 @@ void SpiNorFlash::Wakeup() { NRF_LOG_INFO("[SpiNorFlash] Wakeup") } -SpiNorFlash::Identification SpiNorFlash::ReadIdentificaion() { +SpiNorFlash::Identification SpiNorFlash::ReadIdentification() { auto cmd = static_cast(Commands::ReadIdentification); Identification identification; spi.Read(&cmd, 1, reinterpret_cast(&identification), sizeof(Identification)); diff --git a/src/drivers/spiFlash/SpiNorFlash.h b/src/drivers/spiFlash/SpiNorFlash.h new file mode 100644 index 0000000000..d730fb2e55 --- /dev/null +++ b/src/drivers/spiFlash/SpiNorFlash.h @@ -0,0 +1,63 @@ +#pragma once +#include "drivers/Spi.h" +#include "port/Spi.h" +#include +#include + +namespace Pinetime { + namespace Drivers { + namespace SpiFlash { + class SpiNorFlash { + public: + explicit SpiNorFlash(Pinetime::Drivers::Spi& spi); + SpiNorFlash(const SpiNorFlash&) = delete; + SpiNorFlash& operator=(const SpiNorFlash&) = delete; + SpiNorFlash(SpiNorFlash&&) = delete; + SpiNorFlash& operator=(SpiNorFlash&&) = delete; + + struct __attribute__((packed)) Identification { + uint8_t manufacturer = 0; + uint8_t type = 0; + uint8_t density = 0; + }; + + Identification ReadIdentification(); + uint8_t ReadStatusRegister(); + bool WriteInProgress(); + bool WriteEnabled(); + uint8_t ReadConfigurationRegister(); + void Read(uint32_t address, uint8_t* buffer, size_t size); + void Write(uint32_t address, const uint8_t* buffer, size_t size); + void WriteEnable(); + void SectorErase(uint32_t sectorAddress); + uint8_t ReadSecurityRegister(); + bool ProgramFailed(); + bool EraseFailed(); + + void Init(); + void Uninit(); + + void Sleep(); + void Wakeup(); + + private: + enum class Commands : uint8_t { + PageProgram = 0x02, + Read = 0x03, + ReadStatusRegister = 0x05, + WriteEnable = 0x06, + ReadConfigurationRegister = 0x15, + SectorErase = 0x20, + ReadSecurityRegister = 0x2B, + ReadIdentification = 0x9F, + ReleaseFromDeepPowerDown = 0xAB, + DeepPowerDown = 0xB9 + }; + static constexpr uint16_t pageSize = 256; + + Pinetime::Drivers::Spi& spi; + Identification device_id; + }; + } + } +} diff --git a/src/drivers/Cst816s.cpp b/src/drivers/touchpanels/Cst816s.cpp similarity index 95% rename from src/drivers/Cst816s.cpp rename to src/drivers/touchpanels/Cst816s.cpp index cf10c895f5..a55b5ae220 100644 --- a/src/drivers/Cst816s.cpp +++ b/src/drivers/touchpanels/Cst816s.cpp @@ -1,11 +1,11 @@ -#include "drivers/Cst816s.h" +#include "Cst816s.h" #include #include #include #include #include "drivers/PinMap.h" -using namespace Pinetime::Drivers; +using namespace Pinetime::Drivers::TouchPanels; /* References : * This implementation is based on this article : @@ -59,8 +59,8 @@ bool Cst816S::Init() { return true; } -Cst816S::TouchInfos Cst816S::GetTouchInfo() { - Cst816S::TouchInfos info; +TouchInfos Cst816S::GetTouchInfo() { + TouchInfos info; uint8_t touchData[7]; auto ret = twiMaster.Read(twiAddress, 0, touchData, sizeof(touchData)); @@ -77,7 +77,7 @@ Cst816S::TouchInfos Cst816S::GetTouchInfo() { uint8_t yHigh = touchData[touchYHighIndex] & 0x0f; uint8_t yLow = touchData[touchYLowIndex]; uint16_t y = (yHigh << 8) | yLow; - Gestures gesture = static_cast(touchData[gestureIndex]); + auto gesture = static_cast(touchData[gestureIndex]); // Validity check if (x >= maxX || y >= maxY || diff --git a/src/drivers/touchpanels/Cst816s.h b/src/drivers/touchpanels/Cst816s.h new file mode 100644 index 0000000000..70d6ee16cf --- /dev/null +++ b/src/drivers/touchpanels/Cst816s.h @@ -0,0 +1,60 @@ +#pragma once +#include +#include "port/TwiMaster.h" +#include "drivers/TouchPanel.h" + +namespace Pinetime { + namespace Drivers { + namespace TouchPanels{ + class Cst816S { + public: + Cst816S(TwiMaster& twiMaster, uint8_t twiAddress); + Cst816S(const Cst816S&) = delete; + Cst816S& operator=(const Cst816S&) = delete; + Cst816S(Cst816S&&) = delete; + Cst816S& operator=(Cst816S&&) = delete; + + bool Init(); + TouchPanels::TouchInfos GetTouchInfo(); + void Sleep(); + void Wakeup(); + + uint8_t GetChipId() const { + return chipId; + } + uint8_t GetVendorId() const { + return vendorId; + } + uint8_t GetFwVersion() const { + return fwVersion; + } + + private: + bool CheckDeviceIds(); + + // Unused/Unavailable commented out + static constexpr uint8_t gestureIndex = 1; + static constexpr uint8_t touchPointNumIndex = 2; + // static constexpr uint8_t touchEventIndex = 3; + static constexpr uint8_t touchXHighIndex = 3; + static constexpr uint8_t touchXLowIndex = 4; + // static constexpr uint8_t touchIdIndex = 5; + static constexpr uint8_t touchYHighIndex = 5; + static constexpr uint8_t touchYLowIndex = 6; + // static constexpr uint8_t touchStep = 6; + // static constexpr uint8_t touchXYIndex = 7; + // static constexpr uint8_t touchMiscIndex = 8; + + static constexpr uint8_t maxX = 240; + static constexpr uint8_t maxY = 240; + + TwiMaster& twiMaster; + uint8_t twiAddress; + + uint8_t chipId; + uint8_t vendorId; + uint8_t fwVersion; + }; + } + } +} diff --git a/src/heartratetask/HeartRateTask.cpp b/src/heartratetask/HeartRateTask.cpp index bc22762469..72bd11a76c 100644 --- a/src/heartratetask/HeartRateTask.cpp +++ b/src/heartratetask/HeartRateTask.cpp @@ -1,11 +1,11 @@ #include "heartratetask/HeartRateTask.h" -#include +#include #include #include using namespace Pinetime::Applications; -HeartRateTask::HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller) +HeartRateTask::HeartRateTask(Drivers::HeartRateSensor & heartRateSensor, Controllers::HeartRateController& controller) : heartRateSensor {heartRateSensor}, controller {controller}, ppg {} { } diff --git a/src/heartratetask/HeartRateTask.h b/src/heartratetask/HeartRateTask.h index 0796dc74dd..8ed310f89d 100644 --- a/src/heartratetask/HeartRateTask.h +++ b/src/heartratetask/HeartRateTask.h @@ -3,11 +3,9 @@ #include #include #include +#include "port/HeartRateSensor.h" namespace Pinetime { - namespace Drivers { - class Hrs3300; - } namespace Controllers { class HeartRateController; } @@ -17,7 +15,7 @@ namespace Pinetime { enum class Messages : uint8_t { GoToSleep, WakeUp, StartMeasurement, StopMeasurement }; enum class States { Idle, Running }; - explicit HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller); + explicit HeartRateTask(Drivers::HeartRateSensor& heartRateSensor, Controllers::HeartRateController& controller); void Start(); void Work(); void PushMessage(Messages msg); @@ -30,7 +28,7 @@ namespace Pinetime { TaskHandle_t taskHandle; QueueHandle_t messageQueue; States state = States::Running; - Drivers::Hrs3300& heartRateSensor; + Drivers::HeartRateSensor& heartRateSensor; Controllers::HeartRateController& controller; Controllers::Ppg ppg; bool measurementStarted = false; diff --git a/src/main.cpp b/src/main.cpp index ad7a07dc98..1e4da37b1a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -25,8 +25,8 @@ #include #include #include -#include -#include +#include +#include #include "BootloaderVersion.h" #include "components/battery/BatteryController.h" @@ -37,15 +37,17 @@ #include "components/datetime/DateTimeController.h" #include "components/heartrate/HeartRateController.h" #include "components/fs/FS.h" -#include "drivers/Spi.h" -#include "drivers/SpiMaster.h" +#include "drivers/nrf52/Spi.h" +#include "drivers/nrf52/SpiMaster.h" #include "drivers/SpiNorFlash.h" -#include "drivers/St7789.h" +#include "drivers/displays/St7789.h" #include "drivers/TwiMaster.h" -#include "drivers/Cst816s.h" +#include "drivers/touchpanels/Cst816s.h" #include "drivers/PinMap.h" #include "systemtask/SystemTask.h" #include "drivers/PinMap.h" +#include "drivers/Watchdog.h" +#include "drivers/WatchdogView.h" #include "touchhandler/TouchHandler.h" #include "buttonhandler/ButtonHandler.h" @@ -57,30 +59,45 @@ Pinetime::Logging::NrfLogger logger; Pinetime::Logging::DummyLogger logger; #endif +#include "port/TouchPanel.h" +#include "port/MotionSensor.h" +#include "port/HeartRateSensor.h" +#include "port/Watchdog.h" +#include "port/Display.h" + static constexpr uint8_t touchPanelTwiAddress = 0x15; static constexpr uint8_t motionSensorTwiAddress = 0x18; static constexpr uint8_t heartRateSensorTwiAddress = 0x44; -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::Drivers::Nrf52::SpiMaster spiImpl {Pinetime::Drivers::Nrf52::SpiMaster::SpiModule::SPI0, + {Pinetime::Drivers::Nrf52::SpiMaster::BitOrder::Msb_Lsb, + Pinetime::Drivers::Nrf52::SpiMaster::Modes::Mode3, + Pinetime::Drivers::Nrf52::SpiMaster::Frequencies::Freq8Mhz, Pinetime::PinMap::SpiSck, Pinetime::PinMap::SpiMosi, Pinetime::PinMap::SpiMiso}}; -Pinetime::Drivers::Spi lcdSpi {spi, Pinetime::PinMap::SpiLcdCsn}; -Pinetime::Drivers::St7789 lcd {lcdSpi, Pinetime::PinMap::LcdDataCommand}; +Pinetime::Drivers::SpiMaster spi {spiImpl}; + +Pinetime::Drivers::Nrf52::Spi lcdSpiIpmpl {spiImpl, Pinetime::PinMap::SpiLcdCsn}; +Pinetime::Drivers::Spi lcdSpi {lcdSpiIpmpl}; +Pinetime::Drivers::Displays::St7789 lcdImpl {lcdSpi, Pinetime::PinMap::LcdDataCommand}; +Pinetime::Drivers::Display lcd{lcdImpl}; -Pinetime::Drivers::Spi flashSpi {spi, Pinetime::PinMap::SpiFlashCsn}; -Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; +Pinetime::Drivers::Nrf52::Spi flashSpiImpl {spiImpl, Pinetime::PinMap::SpiFlashCsn}; +Pinetime::Drivers::Spi flashSpi {flashSpiImpl}; + +Pinetime::Drivers::SpiFlash::SpiNorFlash spiNorFlashImpl{flashSpi}; +Pinetime::Drivers::SpiNorFlash spiNorFlash {spiNorFlashImpl}; // 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::Cst816S touchPanel {twiMaster, touchPanelTwiAddress}; +Pinetime::Drivers::Nrf52::TwiMaster twiMasterImpl {NRF_TWIM1, MaxTwiFrequencyWithoutHardwareBug, Pinetime::PinMap::TwiSda, Pinetime::PinMap::TwiScl}; +Pinetime::Drivers::TwiMaster twiMaster{twiMasterImpl}; +Pinetime::Drivers::TouchPanels::Cst816S touchPanelImpl {twiMaster, touchPanelTwiAddress}; +Pinetime::Drivers::TouchPanel touchPanel {touchPanelImpl}; #ifdef PINETIME_IS_RECOVERY #include "displayapp/DummyLittleVgl.h" #include "displayapp/DisplayAppRecovery.h" @@ -90,8 +107,11 @@ Pinetime::Drivers::Cst816S touchPanel {twiMaster, touchPanelTwiAddress}; #endif Pinetime::Components::LittleVgl lvgl {lcd, touchPanel}; -Pinetime::Drivers::Bma421 motionSensor {twiMaster, motionSensorTwiAddress}; -Pinetime::Drivers::Hrs3300 heartRateSensor {twiMaster, heartRateSensorTwiAddress}; +Pinetime::Drivers::MotionSensors::Bma421 motionSensorImpl {twiMaster, motionSensorTwiAddress}; +Pinetime::Drivers::MotionSensor motionSensor {motionSensorImpl}; + +Pinetime::Drivers::HeartRateSensors::Hrs3300 heartRateSensorImpl {twiMaster, heartRateSensorTwiAddress}; +Pinetime::Drivers::HeartRateSensor heartRateSensor{heartRateSensorImpl}; TimerHandle_t debounceTimer; TimerHandle_t debounceChargeTimer; @@ -106,8 +126,9 @@ Pinetime::Controllers::Settings settingsController {fs}; Pinetime::Controllers::MotorController motorController {}; Pinetime::Controllers::DateTime dateTimeController {settingsController}; -Pinetime::Drivers::Watchdog watchdog; -Pinetime::Drivers::WatchdogView watchdogView(watchdog); +Pinetime::Drivers::Nrf52::Watchdog watchdogImpl; +Pinetime::Drivers::Watchdog watchdog{watchdogImpl}; +Pinetime::Drivers::WatchdogView watchdogView{watchdog}; Pinetime::Controllers::NotificationManager notificationManager; Pinetime::Controllers::MotionController motionController; Pinetime::Controllers::TimerController timerController; diff --git a/src/port/Display.h b/src/port/Display.h new file mode 100644 index 0000000000..f7151272dc --- /dev/null +++ b/src/port/Display.h @@ -0,0 +1,16 @@ +#pragma once +#include "drivers/Display.h" + +#ifdef TARGET_DEVICE_PINETIME + #include +#endif + +namespace Pinetime { + namespace Drivers { +#ifdef TARGET_DEVICE_PINETIME + using Display = Interface::Display; +#else + #error "No target device specified!" +#endif + } +} diff --git a/src/port/HeartRateSensor.h b/src/port/HeartRateSensor.h new file mode 100644 index 0000000000..b28e7d5631 --- /dev/null +++ b/src/port/HeartRateSensor.h @@ -0,0 +1,16 @@ +#pragma once +#include "drivers/HeartRateSensor.h" + +#ifdef TARGET_DEVICE_PINETIME + #include +#endif + +namespace Pinetime { + namespace Drivers { +#ifdef TARGET_DEVICE_PINETIME + using HeartRateSensor = Interface::HeartRateSensor; +#else + #error "No target device specified!" +#endif + } +} diff --git a/src/port/MotionSensor.h b/src/port/MotionSensor.h new file mode 100644 index 0000000000..f6d51f457e --- /dev/null +++ b/src/port/MotionSensor.h @@ -0,0 +1,16 @@ +#pragma once +#include "drivers/MotionSensor.h" + +#ifdef TARGET_DEVICE_PINETIME + #include +#endif + +namespace Pinetime { + namespace Drivers { +#ifdef TARGET_DEVICE_PINETIME + using MotionSensor = Interface::MotionSensor; +#else + #error "No target device specified!" +#endif + } +} diff --git a/src/port/Spi.h b/src/port/Spi.h new file mode 100644 index 0000000000..4e56849b0d --- /dev/null +++ b/src/port/Spi.h @@ -0,0 +1,16 @@ +#pragma once +#include "drivers/Spi.h" + +#ifdef TARGET_DEVICE_PINETIME + #include +#endif + +namespace Pinetime { + namespace Drivers { +#ifdef TARGET_DEVICE_PINETIME + using Spi = Interface::Spi; +#else + #error "No target device specified!" +#endif + } +} diff --git a/src/port/SpiMaster.h b/src/port/SpiMaster.h new file mode 100644 index 0000000000..57e528b10a --- /dev/null +++ b/src/port/SpiMaster.h @@ -0,0 +1,16 @@ +#pragma once +#include "drivers/SpiMaster.h" + +#ifdef TARGET_DEVICE_PINETIME + #include +#endif + +namespace Pinetime { + namespace Drivers { +#ifdef TARGET_DEVICE_PINETIME + using SpiMaster = Interface::SpiMaster; +#else + #error "No target device specified!" +#endif + } +} diff --git a/src/port/SpiNorFlash.h b/src/port/SpiNorFlash.h new file mode 100644 index 0000000000..6830ae6f52 --- /dev/null +++ b/src/port/SpiNorFlash.h @@ -0,0 +1,16 @@ +#pragma once +#include "drivers/SpiNorFlash.h" + +#ifdef TARGET_DEVICE_PINETIME + #include +#endif + +namespace Pinetime { + namespace Drivers { +#ifdef TARGET_DEVICE_PINETIME + using SpiNorFlash = Interface::SpiNorFlash; +#else + #error "No target device specified!" +#endif + } +} diff --git a/src/port/TouchPanel.h b/src/port/TouchPanel.h new file mode 100644 index 0000000000..d1df252b98 --- /dev/null +++ b/src/port/TouchPanel.h @@ -0,0 +1,16 @@ +#pragma once +#include "drivers/TouchPanel.h" + +#ifdef TARGET_DEVICE_PINETIME + #include +#endif + +namespace Pinetime { + namespace Drivers { +#ifdef TARGET_DEVICE_PINETIME + using TouchPanel = Interface::Touchpanel; +#else + #error "No target device specified!" +#endif + } +} diff --git a/src/port/TwiMaster.h b/src/port/TwiMaster.h new file mode 100644 index 0000000000..9134f03378 --- /dev/null +++ b/src/port/TwiMaster.h @@ -0,0 +1,16 @@ +#pragma once +#include "drivers/TwiMaster.h" + +#ifdef TARGET_DEVICE_PINETIME + #include +#endif + +namespace Pinetime { + namespace Drivers { +#ifdef TARGET_DEVICE_PINETIME + using TwiMaster = Interface::TwiMaster; +#else + #error "No target device specified!" +#endif + } +} diff --git a/src/port/Watchdog.h b/src/port/Watchdog.h new file mode 100644 index 0000000000..ff66ac6602 --- /dev/null +++ b/src/port/Watchdog.h @@ -0,0 +1,16 @@ +#pragma once +#include "drivers/Watchdog.h" + +#ifdef TARGET_DEVICE_PINETIME + #include +#endif + +namespace Pinetime { + namespace Drivers { +#ifdef TARGET_DEVICE_PINETIME + using Watchdog = Interface::Watchdog; +#else + #error "No target device specified!" +#endif + } +} diff --git a/src/recoveryLoader.cpp b/src/recoveryLoader.cpp index 27a79d9c73..9ad2c1d4d6 100644 --- a/src/recoveryLoader.cpp +++ b/src/recoveryLoader.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include #include "recoveryImage.h" @@ -28,6 +28,10 @@ Pinetime::Logging::NrfLogger logger; Pinetime::Logging::DummyLogger logger; #endif +#include "port/SpiMaster.h" +#include "port/SpiNorFlash.h" +#include "port/Spi.h" + static constexpr uint8_t displayWidth = 240; static constexpr uint8_t displayHeight = 240; static constexpr uint8_t bytesPerPixel = 2; @@ -35,18 +39,25 @@ static constexpr uint8_t bytesPerPixel = 2; static constexpr uint16_t colorWhite = 0xFFFF; static constexpr uint16_t colorGreen = 0xE007; -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}; -Pinetime::Drivers::SpiNorFlash spiNorFlash {flashSpi}; - -Pinetime::Drivers::Spi lcdSpi {spi, Pinetime::PinMap::SpiLcdCsn}; -Pinetime::Drivers::St7789 lcd {lcdSpi, Pinetime::PinMap::LcdDataCommand}; +Pinetime::Drivers::Nrf52::SpiMaster spiImpl {Pinetime::Drivers::Nrf52::SpiMaster::SpiModule::SPI0, + {Pinetime::Drivers::Nrf52::SpiMaster::BitOrder::Msb_Lsb, + Pinetime::Drivers::Nrf52::SpiMaster::Modes::Mode3, + Pinetime::Drivers::Nrf52::SpiMaster::Frequencies::Freq8Mhz, + Pinetime::PinMap::SpiSck, + Pinetime::PinMap::SpiMosi, + Pinetime::PinMap::SpiMiso}}; + +Pinetime::Drivers::SpiMaster spi {spiImpl}; + +Pinetime::Drivers::Nrf52::Spi lcdSpiIpmpl {spiImpl, Pinetime::PinMap::SpiLcdCsn}; +Pinetime::Drivers::Spi lcdSpi {lcdSpiIpmpl}; +Pinetime::Drivers::Displays::St7789 lcd {lcdSpi, Pinetime::PinMap::LcdDataCommand}; + +Pinetime::Drivers::Nrf52::Spi flashSpiImpl {spiImpl, Pinetime::PinMap::SpiFlashCsn}; +Pinetime::Drivers::Spi flashSpi {flashSpiImpl}; + +Pinetime::Drivers::SpiFlash::SpiNorFlash spiNorFlashImpl{flashSpi}; +Pinetime::Drivers::SpiNorFlash spiNorFlash {spiNorFlashImpl}; Pinetime::Components::Gfx gfx {lcd}; Pinetime::Controllers::BrightnessController brightnessController; diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index ef631af74e..6265df1539 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -6,19 +6,10 @@ #include "components/battery/BatteryController.h" #include "components/ble/BleController.h" #include "displayapp/TouchEvents.h" -#include "drivers/Cst816s.h" -#include "drivers/St7789.h" -#include "drivers/InternalFlash.h" -#include "drivers/SpiMaster.h" -#include "drivers/SpiNorFlash.h" -#include "drivers/TwiMaster.h" -#include "drivers/Hrs3300.h" #include "drivers/PinMap.h" #include "main.h" #include "BootErrors.h" -#include - using namespace Pinetime::System; namespace { @@ -47,10 +38,10 @@ void MeasureBatteryTimerCallback(TimerHandle_t xTimer) { } SystemTask::SystemTask(Drivers::SpiMaster& spi, - Drivers::St7789& lcd, + Drivers::Display& lcd, Pinetime::Drivers::SpiNorFlash& spiNorFlash, Drivers::TwiMaster& twiMaster, - Drivers::Cst816S& touchPanel, + Pinetime::Drivers::TouchPanel& touchPanel, Components::LittleVgl& lvgl, Controllers::Battery& batteryController, Controllers::Ble& bleController, @@ -60,9 +51,9 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, Drivers::Watchdog& watchdog, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::MotorController& motorController, - Pinetime::Drivers::Hrs3300& heartRateSensor, + Pinetime::Drivers::HeartRateSensor& heartRateSensor, Pinetime::Controllers::MotionController& motionController, - Pinetime::Drivers::Bma421& motionSensor, + Pinetime::Drivers::MotionSensor& motionSensor, Controllers::Settings& settingsController, Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Applications::DisplayApp& displayApp, diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index d1e4a004f9..d42a1ed4af 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -8,9 +8,10 @@ #include #include #include -#include +#include #include #include +#include #include "systemtask/SystemMonitor.h" #include "components/ble/NimbleController.h" @@ -34,17 +35,14 @@ #include "drivers/Watchdog.h" #include "systemtask/Messages.h" +#include "port/SpiMaster.h" +#include "port/MotionSensor.h" +#include "port/HeartRateSensor.h" +#include "port/Watchdog.h" +#include "port/Display.h" extern std::chrono::time_point NoInit_BackUpTime; namespace Pinetime { - namespace Drivers { - class Cst816S; - class SpiMaster; - class SpiNorFlash; - class St7789; - class TwiMaster; - class Hrs3300; - } namespace Controllers { class Battery; class TouchHandler; @@ -55,10 +53,10 @@ namespace Pinetime { public: enum class SystemTaskState { Sleeping, Running, GoingToSleep, WakingUp }; SystemTask(Drivers::SpiMaster& spi, - Drivers::St7789& lcd, + Drivers::Display& lcd, Pinetime::Drivers::SpiNorFlash& spiNorFlash, Drivers::TwiMaster& twiMaster, - Drivers::Cst816S& touchPanel, + Pinetime::Drivers::TouchPanel& touchPanel, Components::LittleVgl& lvgl, Controllers::Battery& batteryController, Controllers::Ble& bleController, @@ -68,9 +66,9 @@ namespace Pinetime { Drivers::Watchdog& watchdog, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::MotorController& motorController, - Pinetime::Drivers::Hrs3300& heartRateSensor, + Pinetime::Drivers::HeartRateSensor& heartRateSensor, Pinetime::Controllers::MotionController& motionController, - Pinetime::Drivers::Bma421& motionSensor, + Pinetime::Drivers::MotionSensor& motionSensor, Controllers::Settings& settingsController, Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Applications::DisplayApp& displayApp, @@ -99,10 +97,10 @@ namespace Pinetime { TaskHandle_t taskHandle; Pinetime::Drivers::SpiMaster& spi; - Pinetime::Drivers::St7789& lcd; + Pinetime::Drivers::Display& lcd; Pinetime::Drivers::SpiNorFlash& spiNorFlash; Pinetime::Drivers::TwiMaster& twiMaster; - Pinetime::Drivers::Cst816S& touchPanel; + Pinetime::Drivers::TouchPanel& touchPanel; Pinetime::Components::LittleVgl& lvgl; Pinetime::Controllers::Battery& batteryController; @@ -114,8 +112,8 @@ namespace Pinetime { Pinetime::Drivers::Watchdog& watchdog; Pinetime::Controllers::NotificationManager& notificationManager; Pinetime::Controllers::MotorController& motorController; - Pinetime::Drivers::Hrs3300& heartRateSensor; - Pinetime::Drivers::Bma421& motionSensor; + Pinetime::Drivers::HeartRateSensor& heartRateSensor; + Pinetime::Drivers::MotionSensor& motionSensor; Pinetime::Controllers::Settings& settingsController; Pinetime::Controllers::HeartRateController& heartRateController; Pinetime::Controllers::MotionController& motionController; diff --git a/src/touchhandler/TouchHandler.cpp b/src/touchhandler/TouchHandler.cpp index 0e4fb5414a..1a49d6792f 100644 --- a/src/touchhandler/TouchHandler.cpp +++ b/src/touchhandler/TouchHandler.cpp @@ -9,30 +9,30 @@ using namespace Pinetime::Controllers; using namespace Pinetime::Applications; namespace { - TouchEvents ConvertGesture(Pinetime::Drivers::Cst816S::Gestures gesture) { + TouchEvents ConvertGesture(Pinetime::Drivers::TouchPanels::Gestures gesture) { switch (gesture) { - case Pinetime::Drivers::Cst816S::Gestures::SingleTap: + case Pinetime::Drivers::TouchPanels::Gestures::SingleTap: return TouchEvents::Tap; - case Pinetime::Drivers::Cst816S::Gestures::LongPress: + case Pinetime::Drivers::TouchPanels::Gestures::LongPress: return TouchEvents::LongTap; - case Pinetime::Drivers::Cst816S::Gestures::DoubleTap: + case Pinetime::Drivers::TouchPanels::Gestures::DoubleTap: return TouchEvents::DoubleTap; - case Pinetime::Drivers::Cst816S::Gestures::SlideRight: + case Pinetime::Drivers::TouchPanels::Gestures::SlideRight: return TouchEvents::SwipeRight; - case Pinetime::Drivers::Cst816S::Gestures::SlideLeft: + case Pinetime::Drivers::TouchPanels::Gestures::SlideLeft: return TouchEvents::SwipeLeft; - case Pinetime::Drivers::Cst816S::Gestures::SlideDown: + case Pinetime::Drivers::TouchPanels::Gestures::SlideDown: return TouchEvents::SwipeDown; - case Pinetime::Drivers::Cst816S::Gestures::SlideUp: + case Pinetime::Drivers::TouchPanels::Gestures::SlideUp: return TouchEvents::SwipeUp; - case Pinetime::Drivers::Cst816S::Gestures::None: + case Pinetime::Drivers::TouchPanels::Gestures::None: default: return TouchEvents::None; } } } -TouchHandler::TouchHandler(Drivers::Cst816S& touchPanel, Components::LittleVgl& lvgl) : touchPanel {touchPanel}, lvgl {lvgl} { +TouchHandler::TouchHandler(Pinetime::Drivers::TouchPanel& touchPanel, Components::LittleVgl& lvgl) : touchPanel {touchPanel}, lvgl {lvgl} { } void TouchHandler::CancelTap() { @@ -55,13 +55,13 @@ bool TouchHandler::GetNewTouchInfo() { return false; } - if (info.gesture != Pinetime::Drivers::Cst816S::Gestures::None) { + if (info.gesture != Pinetime::Drivers::TouchPanels::Gestures::None) { if (gestureReleased) { - if (info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideDown || - info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideLeft || - info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideUp || - info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideRight || - info.gesture == Pinetime::Drivers::Cst816S::Gestures::LongPress) { + if (info.gesture == Pinetime::Drivers::TouchPanels::Gestures::SlideDown || + info.gesture == Pinetime::Drivers::TouchPanels::Gestures::SlideLeft || + info.gesture == Pinetime::Drivers::TouchPanels::Gestures::SlideUp || + info.gesture == Pinetime::Drivers::TouchPanels::Gestures::SlideRight || + info.gesture == Pinetime::Drivers::TouchPanels::Gestures::LongPress) { if (info.touching) { gesture = ConvertGesture(info.gesture); gestureReleased = false; diff --git a/src/touchhandler/TouchHandler.h b/src/touchhandler/TouchHandler.h index 332041e5a4..aa47b190c5 100644 --- a/src/touchhandler/TouchHandler.h +++ b/src/touchhandler/TouchHandler.h @@ -1,18 +1,16 @@ #pragma once -#include "drivers/Cst816s.h" +#include "port/TouchPanel.h" #include "displayapp/TouchEvents.h" namespace Pinetime { namespace Components { class LittleVgl; } - namespace Drivers { - class Cst816S; - } + namespace Controllers { class TouchHandler { public: - explicit TouchHandler(Drivers::Cst816S&, Components::LittleVgl&); + explicit TouchHandler(Pinetime::Drivers::TouchPanel&, Components::LittleVgl&); void CancelTap(); bool GetNewTouchInfo(); void UpdateLvglTouchPoint(); @@ -29,8 +27,8 @@ namespace Pinetime { Pinetime::Applications::TouchEvents GestureGet(); private: - Pinetime::Drivers::Cst816S::TouchInfos info; - Pinetime::Drivers::Cst816S& touchPanel; + Pinetime::Drivers::TouchPanels::TouchInfos info; + Pinetime::Drivers::TouchPanel& touchPanel; Pinetime::Components::LittleVgl& lvgl; Pinetime::Applications::TouchEvents gesture; bool isCancelled = false;