126 lines
3.8 KiB
Python
126 lines
3.8 KiB
Python
# SPDX-FileCopyrightText: 2017 Scott Shawcroft, written for Adafruit Industries
|
|
# SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
"""
|
|
`adafruit_ssd1683`
|
|
================================================================================
|
|
|
|
CircuitPython `displayio` driver for SSD1683-based ePaper displays
|
|
|
|
|
|
* Author(s): Scott Shawcroft
|
|
|
|
Implementation Notes
|
|
--------------------
|
|
|
|
**Hardware:**
|
|
|
|
.. todo:: Add links to any specific hardware product page(s), or category page(s).
|
|
Use unordered list & hyperlink rST inline format: "* `Link Text <url>`_"
|
|
|
|
**Software and Dependencies:**
|
|
|
|
* Adafruit CircuitPython firmware for the supported boards:
|
|
https://github.com/adafruit/circuitpython/releases
|
|
|
|
"""
|
|
|
|
from epaperdisplay import EPaperDisplay
|
|
|
|
try:
|
|
import typing
|
|
|
|
from fourwire import FourWire
|
|
except ImportError:
|
|
pass
|
|
|
|
|
|
__version__ = "0.0.0+auto.0"
|
|
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_SSD1683.git"
|
|
|
|
_START_SEQUENCE = (
|
|
b"\x12\x80\x00\x32" # soft reset and wait 50ms
|
|
b"\x21\x00\x02\x40\x00" # Display update control 1 & 2
|
|
b"\x3c\x00\x01\x05" # border waveform control
|
|
b"\x11\x00\x01\x03" # Ram data entry mode
|
|
b"\x18\x00\x01\x80" # temp control
|
|
b"\x01\x00\x03\x00\x00\x00" # driver output control
|
|
)
|
|
|
|
_DISPLAY_UPDATE_MODE = b"\x22\x00\x01\xf7" # display update mode
|
|
|
|
_STOP_SEQUENCE = b"\x10\x80\x01\x01\x64" # Deep Sleep
|
|
|
|
|
|
# pylint: disable=too-few-public-methods
|
|
class SSD1683(EPaperDisplay):
|
|
r"""SSD1683 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
|
|
"""
|
|
|
|
def __init__(
|
|
self, bus: FourWire, custom_lut: bytes = b"", **kwargs
|
|
) -> None:
|
|
stop_sequence = bytearray(_STOP_SEQUENCE)
|
|
try:
|
|
bus.reset()
|
|
except RuntimeError:
|
|
# No reset pin defined, so no deep sleeping
|
|
stop_sequence = b""
|
|
|
|
load_lut = b""
|
|
display_update_mode = bytearray(_DISPLAY_UPDATE_MODE)
|
|
if custom_lut:
|
|
load_lut = b"\x32" + len(custom_lut).to_bytes(2) + custom_lut
|
|
display_update_mode[-1] = 0xC7
|
|
|
|
start_sequence = bytearray(_START_SEQUENCE + load_lut + display_update_mode)
|
|
|
|
width = kwargs["width"]
|
|
height = kwargs["height"]
|
|
if "rotation" in kwargs and kwargs["rotation"] % 180 != 90:
|
|
width, height = height, width
|
|
|
|
if "highlight_color" in kwargs or "grayscale" in kwargs:
|
|
# Enable color RAM
|
|
start_sequence[7] = 0
|
|
if "highlight_color" in kwargs:
|
|
# Switch refresh mode
|
|
display_update_mode[-1] = 0xF7
|
|
start_sequence[len(_START_SEQUENCE)-3] = (width - 1) & 0xFF
|
|
start_sequence[len(_START_SEQUENCE)-2] = ((width - 1) >> 8) & 0xFF
|
|
|
|
super().__init__(
|
|
bus,
|
|
start_sequence,
|
|
stop_sequence,
|
|
**kwargs,
|
|
colstart=0,
|
|
# Although the docs say ram_width is in pixels, it determines the wrong
|
|
# number of bytes in the address. So, provide number of bytes.
|
|
ram_width=400 // 8,
|
|
ram_height=300,
|
|
busy_state=True,
|
|
write_black_ram_command=0x24,
|
|
write_color_ram_command=0x26,
|
|
set_column_window_command=0x44,
|
|
set_row_window_command=0x45,
|
|
set_current_column_command=0x4E,
|
|
set_current_row_command=0x4F,
|
|
refresh_display_command=0x20,
|
|
always_toggle_chip_select=False,
|
|
address_little_endian=True,
|
|
two_byte_sequence_length=True,
|
|
)
|