Adafruit_CircuitPython_SSD1683/adafruit_ssd1683.py
Scott Shawcroft 0940405abf
Some checks failed
Build CI / test (push) Has been cancelled
Initial support for two 4.2" screens
2025-08-06 16:17:49 -07:00

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,
)