diff --git a/README.md b/README.md index fe71220..f8abf53 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,14 @@ [![License](https://img.shields.io/github/license/bbilger/mgos-arduino-adafruit-epd.svg?maxAge=60&style=flat-square&color=blue)](LICENSE) ## Introduction + This is a port of or rather a wrapper around the [Adafruit EPD Library](https://github.com/adafruit/Adafruit_EPD) for [Mongoose OS](https://mongoose-os.com/). Please check [Adafruit EPD Library](https://github.com/adafruit/Adafruit_EPD) for additional information and also please note the original [README](README_ORIG.md). Notes: + - this was moved from [bbilger/mgos-arduino-adafruit-epd](https://github.com/bbilger/mgos-arduino-adafruit-epd) which was forked from [adafruit/Adafruit_EPD](https://github.com/adafruit/Adafruit_EPD) - EPD stands for e-paper display. @@ -64,21 +66,21 @@ epd.someMethod(...); It's optional to setup the display using the following config but unless you are using more than one display this if probably what you want. -| config | type | default | required | comment | -| ---------------------- | -------- | ------- | -------- | --------| -| aepd.enable | `bool` | `false` | - | If enabled, then the display will be setup automatically by the library and the reset of the config must be valid. | -| aepd.begin | `bool` | `true` | - | Calls `begin` on the display automatically on start. -| aepd.driver | `string` | `empty` | `true` | The driver to use for the connected display. At the moment the following drivers are implemented: "IL0373", "IL0398", "IL91874", "SSD1608", "SSD1675". | -| aepd.width | `int` | `-1` | `true` | Display width in pixels. | -| aepd.height | `int` | `-1` | `true` | Display height in pixels. | -| aepd.epd_spi_cs_index | `int` | `-1` | `true` | `spi.csX_gpio` index for the EDP, 0, 1 or 2. | -| aepd.sram_spi_cs_index | `int` | `-1` | `false` | `spi.csX_gpio index` for the SRAM, 0, 1 or 2, or -1 to not use SRAM. | -| aepd.epd_dc_gpio | `int` | `-1` | `true` | EPD DC GPIO. | -| aepd.epd_reset_gpio | `int` | `-1` | `false` | EPD reset GPIO or -1 | -| aepd.debug | `bool` | `false` | - | At the moment it only prevents a bootloop on misconfiguration. +| config | type | default | required | comment | +| ---------------------- | -------- | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| aepd.enable | `bool` | `false` | - | If enabled, then the display will be setup automatically by the library and the reset of the config must be valid. | +| aepd.begin | `bool` | `true` | - | Calls `begin` on the display automatically on start. | +| aepd.driver | `string` | `empty` | `true` | The driver to use for the connected display. At the moment the following drivers are implemented: "IL0373", "IL0398", "IL91874", "SSD1608", "SSD1680", "SSD1675". | +| aepd.width | `int` | `-1` | `true` | Display width in pixels. | +| aepd.height | `int` | `-1` | `true` | Display height in pixels. | +| aepd.epd_spi_cs_index | `int` | `-1` | `true` | `spi.csX_gpio` index for the EDP, 0, 1 or 2. | +| aepd.sram_spi_cs_index | `int` | `-1` | `false` | `spi.csX_gpio index` for the SRAM, 0, 1 or 2, or -1 to not use SRAM. | +| aepd.epd_dc_gpio | `int` | `-1` | `true` | EPD DC GPIO. | +| aepd.epd_reset_gpio | `int` | `-1` | `false` | EPD reset GPIO or -1 | +| aepd.debug | `bool` | `false` | - | At the moment it only prevents a bootloop on misconfiguration. | If you whish to not setup the display via configuration, then you can set it up in C via `mgos_aepd_create`, in C++ by directly instantiating a concrete subclass of `Adafruit_EPD` (e.g. `Adafruit_SSD1675`), and in JS you are on your own but you can for example "ffi" `mgos_aepd_create`. - ## License +## License This library is - like the original one - licensed under [MIT license](LICENSE). diff --git a/examples/hello_js/mos.yml b/examples/hello_js/mos.yml index 736a750..e141e0a 100644 --- a/examples/hello_js/mos.yml +++ b/examples/hello_js/mos.yml @@ -23,13 +23,13 @@ conds: - ["spi.miso_gpio", 19] - ["spi.sclk_gpio", 5] - ["spi.cs0_gpio", 15] # EPD - # - ["spi.cs1_gpio", 32] # SRAM - optional! + - ["spi.cs1_gpio", 32] # SRAM - optional! - ["aepd.enable", true] - ["aepd.width", 250] - ["aepd.height", 122] - - ["aepd.driver", "SSD1675"] + - ["aepd.driver", "SSD1680"] - ["aepd.epd_spi_cs_index", 0] - # - ["aepd.sram_spi_cs_index", 1] # SRAM - optional! + - ["aepd.sram_spi_cs_index", 1] # SRAM - optional! - ["aepd.epd_dc_gpio", 33] # esp8266 (feather wing) + EPD feather wing # => adjust if you use a diff setup! diff --git a/include/Adafruit_EPD.h b/include/Adafruit_EPD.h index 4b7130b..494c028 100644 --- a/include/Adafruit_EPD.h +++ b/include/Adafruit_EPD.h @@ -21,55 +21,60 @@ #define _Adafruit_EPD_H_ #if ARDUINO >= 100 - #include "Arduino.h" +#include "Arduino.h" #else - #include "WProgram.h" +#include "WProgram.h" #endif //#define EPD_DEBUG -#define RAMBUFSIZE 64 ///< size of the ram buffer +#define RAMBUFSIZE 64 ///< size of the ram buffer #if defined(__SAM3X8E__) - typedef volatile RwReg PortReg; ///< a port register for fast access - typedef uint32_t PortMask; ///< a port register mask for your pin - #define HAVE_PORTREG +typedef volatile RwReg PortReg; ///< a port register for fast access +typedef uint32_t PortMask; ///< a port register mask for your pin +#define HAVE_PORTREG #elif defined(ARDUINO_ARCH_SAMD) // not supported #elif defined(ESP8266) || defined(ESP32) || defined(ARDUINO_STM32_FEATHER) || defined(__arc__) - typedef volatile uint32_t PortReg; ///< a port register for fast access - typedef uint32_t PortMask; ///< a port register mask for your pin +typedef volatile uint32_t PortReg; ///< a port register for fast access +typedef uint32_t PortMask; ///< a port register mask for your pin #elif defined(__AVR__) - typedef volatile uint8_t PortReg; ///< a port register for fast access - typedef uint8_t PortMask; ///< a port register mask for your pin - #define HAVE_PORTREG +typedef volatile uint8_t PortReg; ///< a port register for fast access +typedef uint8_t PortMask; ///< a port register mask for your pin +#define HAVE_PORTREG #else - // chances are its 32 bit so assume that - typedef volatile uint32_t PortReg; ///< a port register for fast access - typedef uint32_t PortMask; ///< a port register mask for your pin +// chances are its 32 bit so assume that +typedef volatile uint32_t PortReg; ///< a port register for fast access +typedef uint32_t PortMask; ///< a port register mask for your pin #endif -#include "Adafruit_MCPSRAM.h" - -#include #include +#include + +#include "Adafruit_MCPSRAM.h" - /**************************************************************************/ +/**************************************************************************/ /*! @brief available EPD colors */ /**************************************************************************/ enum { - EPD_BLACK, ///< black color - EPD_WHITE, ///< white color - EPD_INVERSE, ///< invert color - EPD_RED, ///< red color - EPD_GRAY, ///< gray color ('red' on grayscale) - EPD_DARK, ///< darker color - EPD_LIGHT, ///< lighter color + EPD_BLACK, ///< black color + EPD_WHITE, ///< white color + EPD_INVERSE, ///< invert color + EPD_RED, ///< red color + EPD_GRAY, ///< gray color ('red' on grayscale) + EPD_DARK, ///< darker color + EPD_LIGHT, ///< lighter color }; -#define EPD_swap(a, b) { int16_t t = a; a = b; b = t; } ///< simple swap function +#define EPD_swap(a, b) \ + { \ + int16_t t = a; \ + a = b; \ + b = t; \ + } ///< simple swap function /**************************************************************************/ /*! @@ -78,12 +83,11 @@ enum { /**************************************************************************/ class Adafruit_EPD : public Adafruit_GFX { public: - Adafruit_EPD(int width, int height, int8_t SID, int8_t SCLK, int8_t DC, int8_t RST, int8_t CS, int8_t SRCS, int8_t MISO, int8_t BUSY = -1); Adafruit_EPD(int width, int height, int8_t DC, int8_t RST, int8_t CS, int8_t SRCS, int8_t BUSY = -1); ~Adafruit_EPD(); - void begin(bool reset=true); + void begin(bool reset = true); void drawPixel(int16_t x, int16_t y, uint16_t color); void clearBuffer(); void clearDisplay(); @@ -133,61 +137,62 @@ class Adafruit_EPD : public Adafruit_GFX { virtual void powerDown(void) = 0; void hardwareReset(void); - int8_t _sid_pin, ///< sid pin - _sclk_pin, ///< serial clock pin - _dc_pin, ///< data/command pin - _reset_pin, ///< reset pin - _cs_pin, ///< chip select pin - _busy_pin; ///< busy pin - static bool _isInTransaction; ///< true if SPI bus is in trasnfer state - bool singleByteTxns; ///< if true CS will go high after every data byte transferred - Adafruit_MCPSRAM sram; ///< the ram chip object if using off-chip ram - - bool blackInverted; ///< is black channel inverted - bool colorInverted; ///< is red channel inverted - uint16_t buffer1_size; ///< size of the primary buffer - uint16_t buffer2_size; ///< size of the secondary buffer - uint8_t *buffer1; ///< the pointer to the primary buffer if using on-chip ram - uint8_t *buffer2; ///< the pointer to the secondary buffer if using on-chip ram - uint8_t *color_buffer; ///< the pointer to the color buffer if using on-chip ram - uint8_t *black_buffer; ///< the pointer to the black buffer if using on-chip ram - uint16_t buffer1_addr; ///< The SRAM address offsets for the primary buffer - uint16_t buffer2_addr; ///< The SRAM address offsets for the secondary buffer + int8_t _sid_pin, ///< sid pin + _sclk_pin, ///< serial clock pin + _dc_pin, ///< data/command pin + _reset_pin, ///< reset pin + _cs_pin, ///< chip select pin + _busy_pin; ///< busy pin + static bool _isInTransaction; ///< true if SPI bus is in trasnfer state + bool singleByteTxns; ///< if true CS will go high after every data byte transferred + Adafruit_MCPSRAM sram; ///< the ram chip object if using off-chip ram + + bool blackInverted; ///< is black channel inverted + bool colorInverted; ///< is red channel inverted + uint16_t buffer1_size; ///< size of the primary buffer + uint16_t buffer2_size; ///< size of the secondary buffer + uint8_t *buffer1; ///< the pointer to the primary buffer if using on-chip ram + uint8_t *buffer2; ///< the pointer to the secondary buffer if using on-chip ram + uint8_t *color_buffer; ///< the pointer to the color buffer if using on-chip ram + uint8_t *black_buffer; ///< the pointer to the black buffer if using on-chip ram + uint16_t buffer1_addr; ///< The SRAM address offsets for the primary buffer + uint16_t buffer2_addr; ///< The SRAM address offsets for the secondary buffer uint16_t colorbuffer_addr; ///< The SRAM address offsets for the color buffer uint16_t blackbuffer_addr; ///< The SRAM address offsets for the black buffer void EPD_command(uint8_t c, const uint8_t *buf, uint16_t len); - uint8_t EPD_command(uint8_t c, bool end=true); + uint8_t EPD_command(uint8_t c, bool end = true); void EPD_data(const uint8_t *buf, uint16_t len); void EPD_data(uint8_t data); uint8_t SPItransfer(uint8_t c); - bool use_sram; ///< true if we are using an SRAM chip as a framebuffer - bool hwSPI; ///< true if using hardware SPI + bool use_sram; ///< true if we are using an SRAM chip as a framebuffer + bool hwSPI; ///< true if using hardware SPI #ifdef HAVE_PORTREG - PortReg *mosiport, ///< mosi port register - *clkport, ///< serial clock port register - *csport, ///< chip select port register - *dcport; ///< data/command port register - PortMask mosipinmask, ///< mosi pin mask - clkpinmask, ///< serial clock pin mask - cspinmask, ///< chip select pin mask - dcpinmask; ///< data / command pin mask + PortReg *mosiport, ///< mosi port register + *clkport, ///< serial clock port register + *csport, ///< chip select port register + *dcport; ///< data/command port register + PortMask mosipinmask, ///< mosi pin mask + clkpinmask, ///< serial clock pin mask + cspinmask, ///< chip select pin mask + dcpinmask; ///< data / command pin mask #endif - void csLow(); - void csHigh(); - void dcHigh(); - void dcLow(); + void csLow(); + void csHigh(); + void dcHigh(); + void dcLow(); }; /* -#include "Adafruit_IL0376F.h" #include "Adafruit_IL0371.h" +#include "Adafruit_IL0376F.h" */ +#include "Adafruit_IL0373.h" #include "Adafruit_IL0398.h" #include "Adafruit_IL91874.h" -#include "Adafruit_IL0373.h" #include "Adafruit_SSD1608.h" #include "Adafruit_SSD1675.h" +#include "Adafruit_SSD1680.h" #endif /* _Adafruit_EPD_H_ */ diff --git a/include/Adafruit_SSD1680.h b/include/Adafruit_SSD1680.h new file mode 100644 index 0000000..46e1caa --- /dev/null +++ b/include/Adafruit_SSD1680.h @@ -0,0 +1,58 @@ +#ifndef LIB_ADAFRUIT_SSD1680 +#define LIB_ADAFRUIT_SSD1680 + +#include + +#include "Adafruit_EPD.h" + +#define SSD1680_DRIVER_CONTROL 0x01 +#define SSD1680_GATE_VOLTAGE 0x03 +#define SSD1680_SOURCE_VOLTAGE 0x04 +#define SSD1680_PROGOTP_INITIAL 0x08 +#define SSD1680_PROGREG_INITIAL 0x09 +#define SSD1680_READREG_INITIAL 0x0A +#define SSD1680_BOOST_SOFTSTART 0x0C +#define SSD1680_DEEP_SLEEP 0x10 +#define SSD1680_DATA_MODE 0x11 +#define SSD1680_SW_RESET 0x12 +#define SSD1680_TEMP_CONTROL 0x18 +#define SSD1680_TEMP_WRITE 0x1A +#define SSD1680_MASTER_ACTIVATE 0x20 +#define SSD1680_DISP_CTRL1 0x21 +#define SSD1680_DISP_CTRL2 0x22 +#define SSD1680_WRITE_RAM1 0x24 +#define SSD1680_WRITE_RAM2 0x26 +#define SSD1680_WRITE_VCOM 0x2C +#define SSD1680_READ_OTP 0x2D +#define SSD1680_READ_STATUS 0x2F +#define SSD1680_WRITE_LUT 0x32 +#define SSD1680_WRITE_BORDER 0x3C +#define SSD1680_SET_RAMXPOS 0x44 +#define SSD1680_SET_RAMYPOS 0x45 +#define SSD1680_SET_RAMXCOUNT 0x4E +#define SSD1680_SET_RAMYCOUNT 0x4F + +/**************************************************************************/ +/*! + @brief Class for interfacing with SSD1680 EPD drivers +*/ +/**************************************************************************/ +class Adafruit_SSD1680 : public Adafruit_EPD { + public: + Adafruit_SSD1680(int width, int height, int16_t SID, int16_t SCLK, int16_t DC, int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO, int16_t BUSY = -1); + Adafruit_SSD1680(int width, int height, int16_t DC, int16_t RST, int16_t CS, int16_t SRCS, int16_t BUSY = -1); + + void begin(bool reset = true); + void powerUp(); + void update(); + void powerDown(); + + protected: + uint8_t writeRAMCommand(uint8_t index); + void setRAMAddress(uint16_t x, uint16_t y); + void busy_wait(); + + int8_t _xram_offset = 1; +}; + +#endif diff --git a/mos.yml b/mos.yml index 55b20ff..2520f0c 100644 --- a/mos.yml +++ b/mos.yml @@ -16,7 +16,7 @@ config_schema: - ["aepd.debug", "b", true, {title: "true"}] - ["aepd.enable", "b", false, {title: "enable the display when the library loads"}] - ["aepd.begin", "b", true, {title: "begin the display when the library loads"}] - - ["aepd.driver", "s", "", {title: "the driver IL0373, IL0398, IL91874, SSD1608 or SSD1675"}] + - ["aepd.driver", "s", "", {title: "the driver IL0373, IL0398, IL91874, SSD1608, SSD1680 or SSD1675"}] - ["aepd.width", "i", -1, {title: "display width in pixels"}] - ["aepd.height", "i", -1, {title: "display height in pixels"}] - ["aepd.epd_spi_cs_index", "i", -1, {title: "spi.csX_gpio index for the EDP, 0, 1 or 2"}] @@ -51,6 +51,7 @@ tags: - docs:drivers:IL0398 SPI - docs:drivers:IL91874 SPI - docs:drivers:SSD1608 SPI + - docs:drivers:SSD1680 SPI - docs:drivers:SSD1675 SPI # this must be disabled since Adafruit*.cpp contains quite some overloaded methods with named params diff --git a/src/Adafruit_SSD1680.cpp b/src/Adafruit_SSD1680.cpp new file mode 100644 index 0000000..79ac6e1 --- /dev/null +++ b/src/Adafruit_SSD1680.cpp @@ -0,0 +1,254 @@ +#include "Adafruit_SSD1680.h" + +#include "Adafruit_EPD.h" + +#define EPD_RAM_BW 0x10 +#define EPD_RAM_RED 0x13 + +#define BUSY_WAIT 500 + +// clang-format off + +const uint8_t ssd1680_default_init_code[] { + SSD1680_SW_RESET, 0, // soft reset + 0xFF, 20, // busy wait + SSD1680_DATA_MODE, 1, 0x03, // Ram data entry mode + SSD1680_WRITE_BORDER, 1, 0x05, // border color + + SSD1680_WRITE_VCOM, 1, 0x36, // Vcom Voltage + SSD1680_GATE_VOLTAGE, 1, 0x17, // Set gate voltage + SSD1680_SOURCE_VOLTAGE, 3, 0x41, 0x00, 0x32, // Set source voltage + + SSD1680_SET_RAMXCOUNT, 1, 1, + SSD1680_SET_RAMYCOUNT, 2, 0, 0, + 0xFE}; + +// clang-format on + +/**************************************************************************/ +/*! + @brief constructor if using external SRAM chip and software SPI + @param width the width of the display in pixels + @param height the height of the display in pixels + @param SID the SID pin to use + @param SCLK the SCLK pin to use + @param DC the data/command pin to use + @param RST the reset pin to use + @param CS the chip select pin to use + @param SRCS the SRAM chip select pin to use + @param MISO the MISO pin to use + @param BUSY the busy pin to use +*/ +/**************************************************************************/ +Adafruit_SSD1680::Adafruit_SSD1680(int width, int height, int16_t SID, int16_t SCLK, int16_t DC, int16_t RST, int16_t CS, int16_t SRCS, int16_t MISO, + int16_t BUSY) + : Adafruit_EPD(width, height, SID, SCLK, DC, RST, CS, SRCS, MISO, BUSY) { + if ((height % 8) != 0) { + height += 8 - (height % 8); + } + + buffer1_size = width * height / 8; + buffer2_size = buffer1_size; + + if (SRCS >= 0) { + use_sram = true; + buffer1_addr = 0; + buffer2_addr = buffer1_size; + buffer1 = buffer2 = NULL; + } else { + buffer1 = (uint8_t *) malloc(buffer1_size); + buffer2 = (uint8_t *) malloc(buffer2_size); + } + + singleByteTxns = true; +} + +// constructor for hardware SPI - we indicate DataCommand, ChipSelect, Reset + +/**************************************************************************/ +/*! + @brief constructor if using on-chip RAM and hardware SPI + @param width the width of the display in pixels + @param height the height of the display in pixels + @param DC the data/command pin to use + @param RST the reset pin to use + @param CS the chip select pin to use + @param SRCS the SRAM chip select pin to use + @param BUSY the busy pin to use +*/ +/**************************************************************************/ +Adafruit_SSD1680::Adafruit_SSD1680(int width, int height, int16_t DC, int16_t RST, int16_t CS, int16_t SRCS, int16_t BUSY) + : Adafruit_EPD(width, height, DC, RST, CS, SRCS, BUSY) { + if ((height % 8) != 0) { + height += 8 - (height % 8); + } + + buffer1_size = width * height / 8; + buffer2_size = buffer1_size; + + if (SRCS >= 0) { + use_sram = true; + buffer1_addr = 0; + buffer2_addr = buffer1_size; + buffer1 = buffer2 = NULL; + } else { + buffer1 = (uint8_t *) malloc(buffer1_size); + buffer2 = (uint8_t *) malloc(buffer2_size); + } + + singleByteTxns = true; +} + +/**************************************************************************/ +/*! + @brief wait for busy signal to end +*/ +/**************************************************************************/ +void Adafruit_SSD1680::busy_wait(void) { + if (_busy_pin >= 0) { + while (digitalRead(_busy_pin)) { // wait for busy low + delay(10); + } + } else { + delay(BUSY_WAIT); + } +} + +/**************************************************************************/ +/*! + @brief begin communication with and set up the display. + @param reset if true the reset pin will be toggled. +*/ +/**************************************************************************/ +void Adafruit_SSD1680::begin(bool reset) { + Adafruit_EPD::begin(reset); + setBlackBuffer(0, true); // black defaults to inverted + setColorBuffer(1, false); // red defaults to un inverted + powerDown(); +} + +/**************************************************************************/ +/*! + @brief signal the display to update +*/ +/**************************************************************************/ +void Adafruit_SSD1680::update() { + uint8_t buf[1]; + + // display update sequence + buf[0] = 0xF4; + EPD_command(SSD1680_DISP_CTRL2, buf, 1); + + EPD_command(SSD1680_MASTER_ACTIVATE); + busy_wait(); + + if (_busy_pin <= -1) { + delay(1000); + } +} + +/**************************************************************************/ +/*! + @brief start up the display +*/ +/**************************************************************************/ +void Adafruit_SSD1680::powerUp() { + uint8_t buf[5]; + + hardwareReset(); + delay(100); + busy_wait(); + + const uint8_t *init_code = ssd1680_default_init_code; + + uint8_t height = HEIGHT; + if ((height % 8) != 0) { + height += 8 - (height % 8); + } + + // Set ram X start/end postion + buf[0] = _xram_offset; + buf[1] = height / 8 - 1 + _xram_offset; + EPD_command(SSD1680_SET_RAMXPOS, buf, 2); + + // Set ram Y start/end postion + buf[0] = 0x00; + buf[1] = 0x00; + buf[2] = (WIDTH - 1); + buf[3] = (WIDTH - 1) >> 8; + EPD_command(SSD1680_SET_RAMYPOS, buf, 4); + + // Set LUT + /* + buf[0] = LUT_DATA[74]; + EPD_command(SSD1680_WRITE_LUT, buf, 1); + EPD_command(SSD1680_WRITE_LUT, LUT_DATA, 70); + */ + + // Set display size and driver output control + buf[0] = (WIDTH - 1); + buf[1] = (WIDTH - 1) >> 8; + buf[2] = 0x00; + EPD_command(SSD1680_DRIVER_CONTROL, buf, 3); +} + +/**************************************************************************/ +/*! + @brief wind down the display +*/ +/**************************************************************************/ +void Adafruit_SSD1680::powerDown() { + uint8_t buf[1]; + // Only deep sleep if we can get out of it + if (_reset_pin >= 0) { + // deep sleep + buf[0] = 0x01; + EPD_command(SSD1680_DEEP_SLEEP, buf, 1); + delay(100); + } else { + EPD_command(SSD1680_SW_RESET); + busy_wait(); + } +} + +/**************************************************************************/ +/*! + @brief Send the specific command to start writing to EPD display RAM + @param index The index for which buffer to write (0 or 1 or tri-color + displays) Ignored for monochrome displays. + @returns The byte that is read from SPI at the same time as sending the + command +*/ +/**************************************************************************/ +uint8_t Adafruit_SSD1680::writeRAMCommand(uint8_t index) { + if (index == 0) { + return EPD_command(SSD1680_WRITE_RAM1, false); + } + if (index == 1) { + return EPD_command(SSD1680_WRITE_RAM2, false); + } + return 0; +} + +/**************************************************************************/ +/*! + @brief Some displays require setting the RAM address pointer + @param x X address counter value + @param y Y address counter value +*/ +/**************************************************************************/ +void Adafruit_SSD1680::setRAMAddress(uint16_t x, uint16_t y) { + (void) x; + (void) y; + + uint8_t buf[2]; + + // set RAM x address count + buf[0] = _xram_offset; + EPD_command(SSD1680_SET_RAMXCOUNT, buf, 1); + + // set RAM y address count + buf[0] = 0; + buf[1] = 0; + EPD_command(SSD1680_SET_RAMYCOUNT, buf, 2); +} diff --git a/src/mgos_aepd.cpp b/src/mgos_aepd.cpp index 54eae2e..ed234fa 100644 --- a/src/mgos_aepd.cpp +++ b/src/mgos_aepd.cpp @@ -120,10 +120,13 @@ Adafruit_EPD *mgos_aepd_create(const struct mgos_config_aepd *cfg) { epd = new Adafruit_IL91874(width, height, epd_dc_gpio, epd_reset_gpio, epd_spi_cs_gpio, sram_spi_cs_gpio, epd_busy_gpio); } else if (strcmp(driver, "SSD1608") == 0) { epd = new Adafruit_SSD1608(width, height, epd_dc_gpio, epd_reset_gpio, epd_spi_cs_gpio, sram_spi_cs_gpio, epd_busy_gpio); + } else if (strcmp(driver, "SSD1680") == 0) { + epd = new Adafruit_SSD1680(width, height, epd_dc_gpio, epd_reset_gpio, epd_spi_cs_gpio, sram_spi_cs_gpio, epd_busy_gpio); } else if (strcmp(driver, "SSD1675") == 0) { epd = new Adafruit_SSD1675(width, height, epd_dc_gpio, epd_reset_gpio, epd_spi_cs_gpio, sram_spi_cs_gpio, epd_busy_gpio); } else { - LOG(LL_ERROR, ("[check aepd.driver valid] expected: one of [\"IL0373\", \"IL0398\", \"IL91874\", \"SSD1608\" or \"SSD1675\") but was %s", driver)); + LOG(LL_ERROR, + ("[check aepd.driver valid] expected: one of [\"IL0373\", \"IL0398\", \"IL91874\", \"SSD1608\" , \"SSD1680\"or \"SSD1675\") but was %s", driver)); return nullptr; }