Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added SSD1680 Support #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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).
6 changes: 3 additions & 3 deletions examples/hello_js/mos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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!
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we keep this file unchanged?
all examples are currently configured to use SSD1675 and there's no necessity to change this

- ["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!
Expand Down
135 changes: 70 additions & 65 deletions include/Adafruit_EPD.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <SPI.h>
#include <Adafruit_GFX.h>
#include <SPI.h>

#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

/**************************************************************************/
/*!
Expand All @@ -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();
Expand Down Expand Up @@ -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_ */
58 changes: 58 additions & 0 deletions include/Adafruit_SSD1680.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#ifndef LIB_ADAFRUIT_SSD1680
#define LIB_ADAFRUIT_SSD1680

#include <Arduino.h>

#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
3 changes: 2 additions & 1 deletion mos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"}]
Expand Down Expand Up @@ -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
Expand Down
Loading