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

black/white e-Paper/e-Ink display driver #12509

Merged
merged 4 commits into from
Feb 4, 2023
Merged

Conversation

silkeh
Copy link
Contributor

@silkeh silkeh commented Oct 19, 2019

Contribution description

This PR adds a driver for black/white e-paper/e-ink SPI display drivers/controllers, including:

  • Default parameters for the IL3829 (tested)
  • Default parameters for the SSD1673 (see boards: add support for Phytec 'reel board' #11096, untested)
  • Header files containing RIOT logos. These were generated using png2c.
    Some questions:
    • Should I move these to a generally available directory?
    • What should the copyright notice be?
  • Tests for the display driver. A video with the full test can be found here.

With the right parameters, this driver should work with most black and white e-paper display drivers. This has only been tested with the IL3829, which is commonly used in 1.54 inch black and white e-Paper displays like this one.

This PR is based on #11078 with some major rework to get it all in a more generic package.

Testing procedure

A test program is included (tests/driver_il3829).
Modify the makefile for a microcontroller/display combination you have and go for it.

Issues/PRs references

This is a complete rework based on the feedback from #11078.

@benpicco benpicco added Area: drivers Area: Device drivers Type: new feature The issue requests / The PR implemements a new feature for RIOT labels Oct 21, 2019
@silkeh
Copy link
Contributor Author

silkeh commented Feb 1, 2020

@bergzand ping!

@bergzand
Copy link
Member

bergzand commented Feb 1, 2020

@aabadie You have a proposal on a unified display driver API right? Would it be possible for you to give this driver a review at some point?

@Citrullin
Copy link
Contributor

Citrullin commented Feb 2, 2020

@bergzand Where is the proposal for the driver? I would like to know, if this also fits into my needs :)

@bergzand
Copy link
Member

bergzand commented Feb 2, 2020

@Citrullin There is a start of it in #13124 but I don't think there is a dedicated PR or issue yet

@aabadie
Copy link
Contributor

aabadie commented Feb 2, 2020

Where is the proposal for the driver?

It's in e3fb86e and e7cbd70 from #13124 but it's still very minimal (only one map function exposed by the generic API). I'm planning to add getter/setter functions to be able to control/access internal states/parameters of the display drivers from higher level functions (like lvgl for example).
If you think the API is useful, I can split it out from #13124 and open a dedicated PR.

@silkeh
Copy link
Contributor Author

silkeh commented Apr 1, 2020

I have updated the PR with an implementation of disp_dev, some minor fixes and a rebase on master.

@silkeh silkeh force-pushed the pr/epd-il3829 branch 2 times, most recently from dc4401b to 2a02586 Compare April 1, 2020 15:21
@Citrullin
Copy link
Contributor

Citrullin commented May 8, 2020

@silkeh I started working on it as well. I need to split up your code in order to make it work with the IL0373. For example the variable values in epd_bw_spi_internal.h are different for the IL0373. There are some fixed values, which needs to get variables.

Where is the proposal for the driver?

It's in e3fb86e and e7cbd70 from #13124 but it's still very minimal (only one map function exposed by the generic API). I'm planning to add getter/setter functions to be able to control/access internal states/parameters of the display drivers from higher level functions (like lvgl for example).
If you think the API is useful, I can split it out from #13124 and open a dedicated PR.

Looks similar to SAUL. I think that is something we can work on.

@silkeh
Copy link
Contributor Author

silkeh commented Oct 19, 2020

@aabadie, @bergzand: ping! 🎂

@jeandudey
Copy link
Contributor

Finally made it work on an esp32-wroom-32 board with the following patch (with a previous git rebase master):

0001-fixup-epd_bw_spi-add-generic-black-and-white-SPI-e-P.patch
From d7a2b5f36b52b13970758371017d6d6f559d451c Mon Sep 17 00:00:00 2001
From: Jean Pierre Dudey <me@jeandudey.tech>
Date: Mon, 2 Nov 2020 11:14:47 +0100
Subject: [PATCH] fixup! epd_bw_spi: add generic black and white SPI e-Paper
 display driver

---
 drivers/epd_bw_spi/epd_bw_spi.c               | 23 +++++++++++-------
 .../epd_bw_spi/include/epd_bw_spi_params.h    | 24 ++++++++++++++++++-
 drivers/include/epd_bw_spi.h                  |  7 ++++++
 3 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/drivers/epd_bw_spi/epd_bw_spi.c b/drivers/epd_bw_spi/epd_bw_spi.c
index c1c407a40..6f76537a3 100644
--- a/drivers/epd_bw_spi/epd_bw_spi.c
+++ b/drivers/epd_bw_spi/epd_bw_spi.c
@@ -64,7 +64,7 @@ void epd_bw_spi_wait(epd_bw_spi_params_t *p, uint32_t usec)
         while (gpio_read(p->busy_pin)) {}
     }
     else {
-        DEBUG("[epd_bw_spi] wait: for %lu microseconds\n", usec);
+        DEBUG("[epd_bw_spi] wait: for %"PRIu32"microseconds\n", usec);
         xtimer_usleep(usec);
     }
 }
@@ -114,9 +114,10 @@ int epd_bw_spi_init(epd_bw_spi_t *dev,
 
 void epd_bw_spi_display_init(epd_bw_spi_t *dev)
 {
+    epd_bw_spi_hwreset(dev);
+
     le_uint16_t y_data[2] = { 0 };
     uint8_t y_size;
-
     if (dev->controller.size_y <= 255) {
         y_data[0].u8[0] = dev->size_y - 1;
         y_size = 2;
@@ -179,7 +180,7 @@ void epd_bw_spi_deactivate(epd_bw_spi_t *dev)
 void epd_bw_spi_init_full(epd_bw_spi_t *dev)
 {
     epd_bw_spi_display_init(dev);
-    epd_bw_spi_set_area(dev, 0, 200, 0, 200);
+    epd_bw_spi_set_area(dev, 0, dev->size_x, 0, dev->size_y);
     epd_bw_spi_write_cmd(&dev->params, EPD_BW_SPI_CMD_WRITE_LUT_REGISTER,
                          dev->controller.lut_full, dev->controller.lut_size);
 }
@@ -301,18 +302,24 @@ void epd_bw_spi_sleep(epd_bw_spi_t *dev)
 }
 
 void epd_bw_spi_wake(epd_bw_spi_t *dev)
+{
+    epd_bw_spi_hwreset(dev);
+
+    /* Turn off sleep mode */
+    uint8_t data[] = { 0x00 };
+    epd_bw_spi_write_cmd(&dev->params, EPD_BW_SPI_CMD_DEEP_SLEEP_MODE, data, 1);
+    epd_bw_spi_wait(&dev->params, EPD_BW_SPI_WAIT_RESET);
+}
+
+void epd_bw_spi_hwreset(epd_bw_spi_t *dev)
 {
     /* Give a low pulse on the reset pin */
     if (dev->params.rst_pin != GPIO_UNDEF) {
         gpio_clear(dev->params.rst_pin);
         xtimer_usleep(EPD_BW_SPI_WAIT_RESET);
         gpio_set(dev->params.rst_pin);
+        xtimer_usleep(EPD_BW_SPI_WAIT_RESET);
     }
-
-    /* Turn off sleep mode */
-    uint8_t data[] = { 0x00 };
-    epd_bw_spi_write_cmd(&dev->params, EPD_BW_SPI_CMD_DEEP_SLEEP_MODE, data, 1);
-    epd_bw_spi_wait(&dev->params, EPD_BW_SPI_WAIT_RESET);
 }
 
 void epd_bw_spi_swreset(epd_bw_spi_t *dev)
diff --git a/drivers/epd_bw_spi/include/epd_bw_spi_params.h b/drivers/epd_bw_spi/include/epd_bw_spi_params.h
index a0590ff40..544ad0a27 100644
--- a/drivers/epd_bw_spi/include/epd_bw_spi_params.h
+++ b/drivers/epd_bw_spi/include/epd_bw_spi_params.h
@@ -37,7 +37,7 @@ extern "C" {
 #define EPD_BW_SPI_PARAM_SPI_CLK    (SPI_CLK_5MHZ)
 #endif
 #ifndef EPD_BW_SPI_PARAM_CS
-#define EPD_BW_SPI_PARAM_CS         (GPIO_UNDEF)
+#define EPD_BW_SPI_PARAM_CS         (SPI_CS_UNDEF)
 #endif
 #ifndef EPD_BW_SPI_PARAM_DC
 #define EPD_BW_SPI_PARAM_DC         (GPIO_UNDEF)
@@ -84,6 +84,15 @@ static const uint8_t epd_bw_spi_il3829_lut_default_part[] = {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x13, 0x14, 0x44, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
+/**
+ * @brief   Waveform lookup table for a full display refresh for SSD1608
+ *          (HINK-E0154A05 e-Paper).
+ */
+static const uint8_t epd_bw_spi_ssd1608_hink_e0154a05_lut_default_full[] = {
+    0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22, 0x66, 0x69,
+    0x69, 0x59, 0x58, 0x99, 0x99, 0x88, 0x00, 0x00, 0x00, 0x00,
+    0xF8, 0xB4, 0x13, 0x51, 0x35, 0x51, 0x51, 0x19, 0x01, 0x00 };
+
 /**
  * @brief    Configuration for IL3829 e-paper display controller
  */
@@ -108,6 +117,19 @@ static const uint8_t epd_bw_spi_il3829_lut_default_part[] = {
         .lut_part = epd_bw_spi_il3829_lut_default_part, \
 }
 
+/**
+ * @brief   Configuration for SSD1608 (HINK-E0154A05) e-paper display controller
+ */
+#define EPD_BW_SPI_CONTROLLER_SSD1608_HINK_E0154A05 { \
+        .vcom = 0xA8, \
+        .size_x = 240, \
+        .size_y = 320, \
+        .lut_size = sizeof epd_bw_spi_ssd1608_hink_e0154a05_lut_default_full, \
+        .lut_full = epd_bw_spi_ssd1608_hink_e0154a05_lut_default_full, \
+        /* NOTE: uses this one of IL3829 for partial updates */ \
+        .lut_part = epd_bw_spi_il3829_lut_default_part, \
+}
+
 /**
  * @brief    Default controller definition
  */
diff --git a/drivers/include/epd_bw_spi.h b/drivers/include/epd_bw_spi.h
index a64165771..8f6767ed3 100644
--- a/drivers/include/epd_bw_spi.h
+++ b/drivers/include/epd_bw_spi.h
@@ -233,6 +233,13 @@ void epd_bw_spi_sleep(epd_bw_spi_t *dev);
  */
 void epd_bw_spi_wake(epd_bw_spi_t *dev);
 
+/**
+ * @brief   Perform a hardware reset of the device.
+ *
+ * This will make the IC registers to be on POR values.
+ */
+void epd_bw_spi_hwreset(epd_bw_spi_t *dev);
+
 /**
  * @brief   Perform a soft reset of the device.
  *
-- 
2.17.1

With the example code of tests/driver_epd_bw_spi:

include ../Makefile.tests_common

BOARD ?= nucleo-f411re

USEMODULE += xtimer
USEMODULE += epd_bw_spi

CFLAGS += -DDISPLAY_X=200
CFLAGS += -DDISPLAY_Y=200
CFLAGS += -DEPD_BW_SPI_CONTROLLER=EPD_BW_SPI_CONTROLLER_SSD1608_HINK_E0154A05
CFLAGS += -DEPD_BW_SPI_PARAM_CS=GPIO23
CFLAGS += -DEPD_BW_SPI_PARAM_DC=GPIO16
CFLAGS += -DEPD_BW_SPI_PARAM_RST=GPIO17
CFLAGS += -DEPD_BW_SPI_PARAM_BUSY=GPIO21

CFLAGS += -DSPI0_MOSI=GPIO18
CFLAGS += -DSPI0_SCK=GPIO5
CFLAGS += -DSPI0_CS=GPIO23

include $(RIOTBASE)/Makefile.include

image

@Citrullin
Copy link
Contributor

Citrullin commented Nov 2, 2020

@jeandudey This is still an open topic, because it makes more sense to have an unified display API for this. It would be great to get some input on it: #14054, #14051 and #13787

@aabadie aabadie dismissed their stale review February 1, 2023 21:16

outdated

@bergzand bergzand removed CI: no fast fail don't abort PR build after first error State: waiting for maintainer State: Action by a maintainer is required labels Feb 2, 2023
Copy link
Member

@bergzand bergzand left a comment

Choose a reason for hiding this comment

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

Ack, thank you for the contribution and your patience with this PR!

bors merge

bors bot added a commit that referenced this pull request Feb 2, 2023
12509: black/white e-Paper/e-Ink display driver r=bergzand a=silkeh



Co-authored-by: Silke Hofstra <silke@slxh.eu>
@bors
Copy link
Contributor

bors bot commented Feb 2, 2023

Build failed:

@bergzand bergzand added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR CI: no fast fail don't abort PR build after first error and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Feb 2, 2023
@bergzand
Copy link
Member

bergzand commented Feb 2, 2023

Both test applications need a file called Makefile.ci with the following content:

BOARD_INSUFFICIENT_MEMORY := \
    arduino-duemilanove \
    arduino-nano \
    arduino-uno \
    atmega328p-xplained-mini \
    atmega328 \
    #

Feel free to force push these changes

@bergzand
Copy link
Member

bergzand commented Feb 2, 2023

Lets try this again

bors merge

bors bot added a commit that referenced this pull request Feb 2, 2023
12509: black/white e-Paper/e-Ink display driver r=bergzand a=silkeh



Co-authored-by: Silke Hofstra <silke@slxh.eu>
@bors
Copy link
Contributor

bors bot commented Feb 2, 2023

Build failed:

@@ -0,0 +1,7 @@
BOARD_INSUFFICIENT_MEMORY := \
Copy link
Contributor

Choose a reason for hiding this comment

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

You can generate this with

make create-Makefile.ci

Copy link
Member

@bergzand bergzand left a comment

Choose a reason for hiding this comment

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

Thanks,

Bors merge

@bors
Copy link
Contributor

bors bot commented Feb 3, 2023

🕐 Waiting for PR status (GitHub check) to be set, probably by CI. Bors will automatically try to run when all required PR statuses are set.

@bergzand bergzand added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR CI: no fast fail don't abort PR build after first error labels Feb 3, 2023
@bergzand
Copy link
Member

bergzand commented Feb 4, 2023

Bors merge

@bors
Copy link
Contributor

bors bot commented Feb 4, 2023

Build succeeded:

@bors bors bot merged commit f3a487b into RIOT-OS:master Feb 4, 2023
@bergzand
Copy link
Member

bergzand commented Feb 4, 2023

Thanks for the effort you put into this @silkeh

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: drivers Area: Device drivers Area: tests Area: tests and testing framework Area: tools Area: Supplementary tools CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.