From fc61d180d9fe042163b6c6fc0522d6527ad5a379 Mon Sep 17 00:00:00 2001 From: Scott Allen Date: Mon, 17 Apr 2017 17:01:10 -0400 Subject: [PATCH] Add displayOff() and displayOn() functions displayOff() puts the display in low power mode. displayOn() re-initializes the display after displayOff() is used. The SPI initialization code was separated from the display initialization code to facilitate the new functions. --- keywords.txt | 2 ++ src/Arduboy2Core.cpp | 35 ++++++++++++++++++++++++++++------- src/Arduboy2Core.h | 30 ++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 7 deletions(-) diff --git a/keywords.txt b/keywords.txt index a9d50bd..f5092e5 100644 --- a/keywords.txt +++ b/keywords.txt @@ -30,6 +30,8 @@ collide KEYWORD2 cpuLoad KEYWORD2 digitalWriteRGB KEYWORD2 display KEYWORD2 +displayOff KEYWORD2 +displayOn KEYWORD2 drawBitmap KEYWORD2 drawChar KEYWORD2 drawCircle KEYWORD2 diff --git a/src/Arduboy2Core.cpp b/src/Arduboy2Core.cpp index ada4611..b9c6a82 100644 --- a/src/Arduboy2Core.cpp +++ b/src/Arduboy2Core.cpp @@ -84,6 +84,7 @@ void Arduboy2Core::boot() ADMUX = RAND_SEED_IN_ADMUX; bootPins(); + bootSPI(); bootOLED(); bootPowerSaving(); } @@ -192,15 +193,10 @@ void Arduboy2Core::bootPins() void Arduboy2Core::bootOLED() { - // init SPI - // master, mode 0, MSB first, CPU clock / 2 (8MHz) - SPCR = _BV(SPE) | _BV(MSTR); - SPSR = _BV(SPI2X); - // reset the display - delay(2); // reset pin should be low here. let it stay low a while + delay(5); // reset pin should be low here. let it stay low a while bitSet(RST_PORT, RST_BIT); // set high to come out of reset - delay(10); // wait a while + delay(5); // wait a while // select the display (permanently, since nothing else is using SPI) bitClear(CS_PORT, CS_BIT); @@ -224,6 +220,14 @@ void Arduboy2Core::LCDCommandMode() bitClear(DC_PORT, DC_BIT); } +// Initialize the SPI interface for the display +void Arduboy2Core::bootSPI() +{ +// master, mode 0, MSB first, CPU clock / 2 (8MHz) + SPCR = _BV(SPE) | _BV(MSTR); + SPSR = _BV(SPI2X); +} + // Write to the SPI bus (MOSI pin) void Arduboy2Core::SPItransfer(uint8_t data) { @@ -270,6 +274,23 @@ void Arduboy2Core::bootPowerSaving() // All other bits will be written with 0 so will be enabled } +// Shut down the display +void Arduboy2Core::displayOff() +{ + LCDCommandMode(); + SPItransfer(0xAE); // display off + SPItransfer(0x8D); // charge pump: + SPItransfer(0x10); // disable + delay(250); + bitClear(RST_PORT, RST_BIT); // set display reset pin low (reset state) +} + +// Restart the display after a displayOff() +void Arduboy2Core::displayOn() +{ + bootOLED(); +} + uint8_t Arduboy2Core::width() { return WIDTH; } uint8_t Arduboy2Core::height() { return HEIGHT; } diff --git a/src/Arduboy2Core.h b/src/Arduboy2Core.h index 2a2f699..944c7aa 100644 --- a/src/Arduboy2Core.h +++ b/src/Arduboy2Core.h @@ -311,6 +311,35 @@ class Arduboy2Core */ void static SPItransfer(uint8_t data); + /** \brief + * Turn the display off. + * + * \details + * The display will clear and be put into a low power mode. This can be + * used to extend battery life when a game is paused or when a sketch + * doesn't require anything to be displayed for a relatively long period + * of time. + * + * \see displayOn() + */ + void static displayOff(); + + /** \brief + * Turn the display on. + * + * \details + * Used to power up and reinitialize the display after calling + * `displayOff()`. + * + * \note + * The previous call to `displayOff()` will have caused the display's + * buffer contents to be lost. The display will have to be re-painted, + * which is usually done by calling `display()`. + * + * \see displayOff() + */ + void static displayOn(); + /** \brief * Get the width of the display in pixels. * @@ -650,6 +679,7 @@ class Arduboy2Core protected: // internals void static setCPUSpeed8MHz(); + void static bootSPI(); void static bootOLED(); void static bootPins(); void static bootPowerSaving();