From c1f3a31b513e90b29f31f23ba24e5856837ea6d4 Mon Sep 17 00:00:00 2001 From: JF Date: Fri, 17 Jan 2020 22:16:45 +0100 Subject: Disable SPI, I²C, touch controller and display controller in sleep mode. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Re-enable them on wake up. Remove delays that were not needed in st7889 driver. Hopefully, it'll improve the battery life! --- src/Components/Gfx/Gfx.cpp | 8 ++++++++ src/Components/Gfx/Gfx.h | 3 +++ src/DisplayApp/DisplayApp.cpp | 5 +++++ src/drivers/Cst816s.cpp | 10 ++++++++++ src/drivers/Cst816s.h | 2 ++ src/drivers/SpiMaster.cpp | 17 +++++++++++++++++ src/drivers/SpiMaster.h | 6 ++++++ src/drivers/St7789.cpp | 29 ++++++++++++++++++++++++++--- src/drivers/St7789.h | 5 +++++ 9 files changed, 82 insertions(+), 3 deletions(-) diff --git a/src/Components/Gfx/Gfx.cpp b/src/Components/Gfx/Gfx.cpp index 3621b055..50516f7d 100644 --- a/src/Components/Gfx/Gfx.cpp +++ b/src/Components/Gfx/Gfx.cpp @@ -85,4 +85,12 @@ void Gfx::pixel_draw(uint8_t x, uint8_t y, uint16_t color) { lcd.DrawPixel(x, y, color); } +void Gfx::Sleep() { + lcd.Sleep(); +} + +void Gfx::Wakeup() { + lcd.Wakeup(); +} + diff --git a/src/Components/Gfx/Gfx.h b/src/Components/Gfx/Gfx.h index 4e3b49cf..bc450846 100644 --- a/src/Components/Gfx/Gfx.h +++ b/src/Components/Gfx/Gfx.h @@ -16,6 +16,9 @@ namespace Pinetime { void DrawChar(const FONT_INFO *font, uint8_t c, uint8_t *x, uint8_t y, uint16_t color); void FillRectangle(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint16_t color); + void Sleep(); + void Wakeup(); + private: Drivers::St7789& lcd; const uint8_t width = 240; diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 8bfb8b03..13661609 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -136,9 +136,14 @@ void DisplayApp::Refresh() { vTaskDelay(100); nrf_gpio_pin_set(14); lcd->DisplayOff(); + lcd->Sleep(); + touchPanel.Sleep(); state = States::Idle; break; case Messages::GoToRunning: + lcd->Wakeup(); + touchPanel.Wakeup(); + lcd->DisplayOn(); nrf_gpio_pin_clear(23); nrf_gpio_pin_clear(22); diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp index 8ed65876..67700f53 100644 --- a/src/drivers/Cst816s.cpp +++ b/src/drivers/Cst816s.cpp @@ -75,3 +75,13 @@ Cst816S::TouchInfos Cst816S::GetTouchInfo() { info.action = action; return info; } + +void Cst816S::Sleep() { + nrfx_twi_disable(&twi); + nrf_gpio_cfg_default(6); + nrf_gpio_cfg_default(7); +} + +void Cst816S::Wakeup() { + Init(); +} diff --git a/src/drivers/Cst816s.h b/src/drivers/Cst816s.h index fea33f40..0adb448b 100644 --- a/src/drivers/Cst816s.h +++ b/src/drivers/Cst816s.h @@ -19,6 +19,8 @@ namespace Pinetime { void Init(); void Probe(); TouchInfos GetTouchInfo(); + void Sleep(); + void Wakeup(); private: static constexpr uint8_t pinIrq = 28; static constexpr uint8_t pinReset = 10; diff --git a/src/drivers/SpiMaster.cpp b/src/drivers/SpiMaster.cpp index 076c764d..5e49f2a7 100644 --- a/src/drivers/SpiMaster.cpp +++ b/src/drivers/SpiMaster.cpp @@ -4,6 +4,9 @@ using namespace Pinetime::Drivers; bool SpiMaster::Init(const SpiMaster::SpiModule spi, const SpiMaster::Parameters ¶ms) { + configSpiModule = spi; + configParams = params; + /* Configure GPIO pins used for pselsck, pselmosi, pselmiso and pselss for SPI0 */ nrf_gpio_cfg_output(params.pinSCK); nrf_gpio_cfg_output(params.pinMOSI); @@ -86,3 +89,17 @@ bool SpiMaster::Write(const uint8_t *data, size_t size) { return true; } + +void SpiMaster::Sleep() { + while(NRF_SPI0->ENABLE != 0) { + NRF_SPI0->ENABLE = (SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos); + } + nrf_gpio_cfg_default(configParams.pinSCK); + nrf_gpio_cfg_default(configParams.pinMOSI); + nrf_gpio_cfg_default(configParams.pinMISO); + nrf_gpio_cfg_default(configParams.pinCSN); +} + +void SpiMaster::Wakeup() { + Init(configSpiModule, configParams); +} diff --git a/src/drivers/SpiMaster.h b/src/drivers/SpiMaster.h index 9f2208e0..4f39dc39 100644 --- a/src/drivers/SpiMaster.h +++ b/src/drivers/SpiMaster.h @@ -23,9 +23,15 @@ namespace Pinetime { bool Init(const SpiModule spi, const Parameters& params); bool Write(const uint8_t* data, size_t size); + void Sleep(); + void Wakeup(); + private: NRF_SPI_Type * spiBaseAddress; uint8_t pinCsn; + + SpiMaster::SpiModule configSpiModule; + SpiMaster::Parameters configParams; }; } } diff --git a/src/drivers/St7789.cpp b/src/drivers/St7789.cpp index 7c52f179..0bb7b7c9 100644 --- a/src/drivers/St7789.cpp +++ b/src/drivers/St7789.cpp @@ -48,7 +48,10 @@ void St7789::SoftwareReset() { void St7789::SleepOut() { WriteCommand(static_cast(Commands::SleepOut)); - nrf_delay_ms(500); +} + +void St7789::SleepIn() { + WriteCommand(static_cast(Commands::SleepIn)); } void St7789::ColMod() { @@ -90,7 +93,6 @@ void St7789::NormalModeOn() { void St7789::DisplayOn() { WriteCommand(static_cast(Commands::DisplayOn)); - nrf_delay_ms(500); } void St7789::FillRectangle(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color) { @@ -163,9 +165,30 @@ void St7789::NextDrawBuffer(const uint8_t *data, size_t size) { void St7789::HardwareReset() { nrf_gpio_pin_clear(26); - nrf_delay_ms(200); + nrf_delay_ms(10); nrf_gpio_pin_set(26); +} + +void St7789::Sleep() { + SleepIn(); + nrf_gpio_cfg_default(pinDataCommand); + spi.Sleep(); +} +void St7789::Wakeup() { + spi.Wakeup(); + + nrf_gpio_cfg_output(pinDataCommand); + // TODO why do we need to reset the controller? + SoftwareReset(); + SleepOut(); + ColMod(); + MemoryDataAccessControl(); + ColumnAddressSet(); + RowAddressSet(); + DisplayInversionOn(); + NormalModeOn(); + DisplayOn(); } diff --git a/src/drivers/St7789.h b/src/drivers/St7789.h index e6305b49..a32a96f9 100644 --- a/src/drivers/St7789.h +++ b/src/drivers/St7789.h @@ -19,6 +19,9 @@ namespace Pinetime { void DisplayOn(); void DisplayOff(); + void Sleep(); + void Wakeup(); + private: SpiMaster& spi; @@ -27,6 +30,7 @@ namespace Pinetime { void HardwareReset(); void SoftwareReset(); void SleepOut(); + void SleepIn(); void ColMod(); void MemoryDataAccessControl(); void DisplayInversionOn(); @@ -41,6 +45,7 @@ namespace Pinetime { enum class Commands : uint8_t { SoftwareReset = 0x01, + SleepIn = 0x10, SleepOut = 0x11, NormalModeOn = 0x13, DisplayInversionOn = 0x21, -- cgit v1.2.3