Skip to content

EPaperDisplay sequences are limited to less than 128 bytes due to DELAY byte implementation #5850

@dkulinski

Description

@dkulinski

CircuitPython version

Adafruit CircuitPython 7.1.0 on 2021-12-28; Adafruit ItsyBitsy RP2040 with rp2040
Board ID:adafruit_itsybitsy_rp2040

Code/REPL

"""
`dkulinsk_ws2in9v2`
================================================================================
CircuitPython `displayio` driver for Waveshare 2.9in V2 Display
* Author(s): Daniel Kulinski
Implementation Notes
--------------------
**Hardware:**
* `WaveShare 2.9" Black and White eInk Display <https://https://www.waveshare.com/wiki/2.9inch_e-Paper_Module>`_
**Software and Dependencies:**
* Adafruit CircuitPython firmware for the supported boards:
  https://github.com/adafruit/circuitpython/releases
"""


import displayio
import digitalio
import board

__version__ = "0.0.0"
__repo__ = ""

_START_SEQUENCE = (
    b'\x12\x00' # Software Reset
    b'\x01\x03\x27\x01\x00' # Driver output control
    b'\x11\x01\x03' # data entry mode
    b'\x44\x02\x00\x0F' # Set Window X RAM
    b'\x45\x04\x00\x00\x27\x01' # Set Window Y RAM
    b'\x21\x02\x00\x80' # Display update control
    b'\x4E\x01\x00' # Set Cursor X
    b'\x4F\x02\x00\x00' # Set Cursor Y
    b'\x80\x99\x66\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x10\x66\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x80\x66\x00\x00\x00\x00\x00\x00\x40\x00\x00\x00\x10\x66\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x08\x00\x00\x00\x00\x02\x0A\x0A\x00\x0A\x0A\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x14\x08\x00\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x44\x44\x44\x44\x44\x44\x00\x00\x00' # LUT
    b'\x3f\x01\x22'
    b'\x03\x01\x17' # gate voltage
    b'\x04\x03\x41\x00\x32' # source voltage
    b'\x2c\x01\x36' # VCOM
    )

_STOP_SEQUENCE = b'\x10\x01\x01'

class WS2IN9V2(displayio.EPaperDisplay):
    r"""WS2IN9V2 driver
    :param bus: The data bus the display is on
    :param \**kwargs:
        See below
    :Keyword Arguments:
        * *width* (``int``) --
          Display width
        * *height* (``int``) --
          Display height
        * *rotation* (``int``) --
          Display rotation
        * *busy_pin* (``microcontroller.Pin``) --
          Busy to read for busy state
    """

    def __init__(self, bus, **kwargs):
        stop_sequence = bytearray(_STOP_SEQUENCE)
        try:
            bus.reset()
        except RuntimeError:
            # No reset pin defined, so no deep sleeping
            stop_sequence = b""

        start_sequence = bytearray(_START_SEQUENCE)
        width = kwargs['width']
        height = kwargs['height']
        board_busy_pin = kwargs.get("busy_pin",None)
        if "rotation" in kwargs and kwargs["rotation"] % 180 != 90:
            width, height = height, width
        start_sequence[13] = (width - 1) & 0xFF
        start_sequence[14] = ((width - 1) >> 8) & 0xFF

        super().__init__(
            bus,
            start_sequence,
            stop_sequence,
            **kwargs,
            ram_width=250,
            ram_height=296,
            busy_state=True,
            write_black_ram_command=0x24,
            write_color_ram_command=0x26,
            black_bits_inverted=False,
            set_column_window_command=0x44,
            set_row_window_command=0x45,
            set_current_column_command=0x4E,
            set_current_row_command=0x4F,
            refresh_display_command=0x20,
            colstart=1,
            always_toggle_chip_select=True,
            grayscale=True,
        )

"""
Simple text script for Adafruit 2.13" 212x104 tri-color display
Supported products:
  * Adafruit 2.13" Tri-Color Display Breakout
  * Adafruit 2.13" Tri-Color Display FeatherWing
    https://www.adafruit.com/product/4086 (breakout) or
    https://www.adafruit.com/product/4128 (FeatherWing)

  This program requires the adafruit_il0373 library and the
  adafruit_display_text library in the CIRCUITPY /lib folder
  for CircuitPython 5.0 and above which has displayio support.
"""

import time
import board
import digitalio
import displayio
import dkulinski_ws2in9v2
import terminalio
from adafruit_display_text import label

BLACK = 0x00
WHITE = 0xFF

# Change text colors, choose from the following values:
# BLACK, WHITE

FOREGROUND_COLOR = WHITE
BACKGROUND_COLOR = BLACK

# Used to ensure the display is free in CircuitPython
displayio.release_displays()

# Define the pins needed for display use
# This pinout is for a Feather M4 and may be different for other boards
spi = board.SPI()  # Uses SCK and MOSI
epd_cs = board.D9
epd_dc = board.D10
epd_reset = board.D11
epd_busy = board.D12

# Create the displayio connection to the display pins
display_bus = displayio.FourWire(spi, command=epd_dc, chip_select=epd_cs,
                                 reset=epd_reset, baudrate=1000000)
time.sleep(1)  # Wait a bit

# Create the display object
DISPLAY_WIDTH = 128
DISPLAY_HEIGHT = 296

display = dkulinski_ws2in9v2.WS2IN9V2(
    display_bus,
    width=DISPLAY_WIDTH,
    height=DISPLAY_HEIGHT,
    rotation=0,
    busy_pin=board.D12,
    )

# Create a display group for our screen objects
g = displayio.Group()

# Set a background
background_bitmap = displayio.Bitmap(DISPLAY_WIDTH, DISPLAY_HEIGHT, 1)
# Map colors in a palette
palette = displayio.Palette(1)
palette[0] = BACKGROUND_COLOR

# Create a Tilegrid with the background and put in the displayio group
t = displayio.TileGrid(background_bitmap, pixel_shader=palette)
g.append(t)

# Draw simple text using the built-in font into a displayio group
text_group = displayio.Group(scale=2, x=20, y=40)
text = "Hello World!"
text_area = label.Label(terminalio.FONT, text=text, color=FOREGROUND_COLOR)
text_group.append(text_area)  # Add this text to the text group
g.append(text_group)

# Place the display group on the screen
display.show(g)

# Refresh the display to have everything show on the display
# NOTE: Do not refresh eInk displays more often than 180 seconds!
display.refresh()
time.sleep(120)
display.show(g)
display.refresh()

while True:
    pass

Behavior

No error message but display fails to initialize correctly because of the long LUT. This is for a Waveshare 2.9 inch v2 grayscale EPaperDisplay which is using the SSD1680 driver.

Description

When checking the SPI stream it is obvious that the bitwise AND of the delay byte is interfering with the LUT length.

Additional information

After talking with tannewt on Discord, he suggested adding a boolean for a two byte array length and defaulting this to false. I had worked on this but my C skills are lacking and my expression always evaluates to false regardless of what I set in my code (branch is here: https://github.com/dkulinski/circuitpython/commit/6d4e90cbcc0f11a7f68c718cffd9d5cfa89130ec ). I wanted to open an official bug report on this issue.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions