Skip to content

Commit 9c88f82

Browse files
authored
Merge pull request #95 from adafruit/ssd1883
add ssd1683, update ssd1680z
2 parents dc6bda8 + 7c669c7 commit 9c88f82

File tree

7 files changed

+277
-5
lines changed

7 files changed

+277
-5
lines changed

adafruit_epd/ssd1680.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ def power_up(self):
242242

243243
self.command(
244244
_SSD1680_DRIVER_CONTROL,
245-
bytearray([self._height, (self._height) >> 8, 0x00]),
245+
bytearray([self._height & 0xFF, (self._height) >> 8, 0x00]),
246246
)
247247
self.command(_SSD1680_DATA_MODE, bytearray([0x03]))
248248

@@ -251,19 +251,19 @@ def power_up(self):
251251
self.command(_SSD1680_GATE_VOLTAGE, bytearray([0x17]))
252252
self.command(_SSD1680_SOURCE_VOLTAGE, bytearray([0x41, 0x00, 0x32]))
253253

254-
self.command(_SSD1680_SET_RAMXPOS, bytearray([0x00, (self._width // 8)]))
254+
self.command(_SSD1680_SET_RAMXPOS, bytearray([0x00, (self._width // 8) - 1]))
255255
self.command(
256256
_SSD1680_SET_RAMYPOS,
257-
bytearray([0x00, 0x00, self._height, (self._height) >> 8]),
257+
bytearray([0x00, 0x00, (self._height - 1) & 0xFF, (self._height - 1) >> 8]),
258258
)
259259

260260
# Set border waveform
261261
self.command(_SSD1680_WRITE_BORDER, bytearray([0x05]))
262262

263263
# Set ram X count
264-
self.command(_SSD1680_SET_RAMXCOUNT, bytearray([0x01]))
264+
self.command(_SSD1680_SET_RAMXCOUNT, bytearray([0x00]))
265265
# Set ram Y count
266-
self.command(_SSD1680_SET_RAMYCOUNT, bytearray([self._height, 0]))
266+
self.command(_SSD1680_SET_RAMYCOUNT, bytearray([0x00, 0x00]))
267267
self.busy_wait()
268268

269269
def update(self):

adafruit_epd/ssd1683.py

Lines changed: 262 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
# SPDX-FileCopyrightText: 2025 Liz Clark for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
"""
6+
`adafruit_epd.ssd1683` - Adafruit SSD1683 - ePaper display driver
7+
====================================================================================
8+
CircuitPython driver for Adafruit SSD1683 display breakouts
9+
* Author(s): Liz Clark
10+
"""
11+
12+
import time
13+
14+
import adafruit_framebuf
15+
from micropython import const
16+
17+
from adafruit_epd.epd import Adafruit_EPD
18+
19+
try:
20+
"""Needed for type annotations"""
21+
import typing
22+
23+
from busio import SPI
24+
from digitalio import DigitalInOut
25+
from typing_extensions import Literal
26+
27+
except ImportError:
28+
pass
29+
30+
__version__ = "0.0.0+auto.0"
31+
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_EPD.git"
32+
33+
# Command constants
34+
_SSD1683_DRIVER_CONTROL = const(0x01)
35+
_SSD1683_GATE_VOLTAGE = const(0x03)
36+
_SSD1683_SOURCE_VOLTAGE = const(0x04)
37+
_SSD1683_PROGOTP_INITIAL = const(0x08)
38+
_SSD1683_PROGREG_INITIAL = const(0x09)
39+
_SSD1683_READREG_INITIAL = const(0x0A)
40+
_SSD1683_BOOST_SOFTSTART = const(0x0C)
41+
_SSD1683_DEEP_SLEEP = const(0x10)
42+
_SSD1683_DATA_MODE = const(0x11)
43+
_SSD1683_SW_RESET = const(0x12)
44+
_SSD1683_HV_READY = const(0x14)
45+
_SSD1683_VCI_DETECT = const(0x15)
46+
_SSD1683_PROGRAM_WSOTP = const(0x16)
47+
_SSD1683_PROGRAM_AUTO = const(0x17)
48+
_SSD1683_TEMP_CONTROL = const(0x18)
49+
_SSD1683_TEMP_WRITE = const(0x1A)
50+
_SSD1683_TEMP_READ = const(0x1B)
51+
_SSD1683_TEMP_CONTROLEXT = const(0x1C)
52+
_SSD1683_MASTER_ACTIVATE = const(0x20)
53+
_SSD1683_DISP_CTRL1 = const(0x21)
54+
_SSD1683_DISP_CTRL2 = const(0x22)
55+
_SSD1683_WRITE_RAM1 = const(0x24)
56+
_SSD1683_WRITE_RAM2 = const(0x26)
57+
_SSD1683_READ_RAM1 = const(0x27)
58+
_SSD1683_SENSE_VCOM = const(0x28)
59+
_SSD1683_SENSEDUR_VCOM = const(0x29)
60+
_SSD1683_PROGOTP_VCOM = const(0x2A)
61+
_SSD1683_WRITE_VCOM = const(0x2C)
62+
_SSD1683_READ_OTP = const(0x2D)
63+
_SSD1683_READ_USERID = const(0x2E)
64+
_SSD1683_READ_STATUS = const(0x2F)
65+
_SSD1683_WRITE_LUT = const(0x32)
66+
_SSD1683_WRITE_BORDER = const(0x3C)
67+
_SSD1683_END_OPTION = const(0x3F)
68+
_SSD1683_SET_RAMXPOS = const(0x44)
69+
_SSD1683_SET_RAMYPOS = const(0x45)
70+
_SSD1683_SET_RAMXCOUNT = const(0x4E)
71+
_SSD1683_SET_RAMYCOUNT = const(0x4F)
72+
73+
# Other constants
74+
_EPD_RAM_BW = const(0x10)
75+
_EPD_RAM_RED = const(0x13)
76+
_BUSY_WAIT = const(500)
77+
78+
79+
class Adafruit_SSD1683(Adafruit_EPD):
80+
"""driver class for Adafruit SSD1683 ePaper display breakouts"""
81+
82+
def __init__(
83+
self,
84+
width: int,
85+
height: int,
86+
spi: SPI,
87+
*,
88+
cs_pin: DigitalInOut,
89+
dc_pin: DigitalInOut,
90+
sramcs_pin: DigitalInOut,
91+
rst_pin: DigitalInOut,
92+
busy_pin: DigitalInOut,
93+
) -> None:
94+
super().__init__(width, height, spi, cs_pin, dc_pin, sramcs_pin, rst_pin, busy_pin)
95+
96+
stride = width
97+
if stride % 8 != 0:
98+
stride += 8 - stride % 8
99+
100+
self._buffer1_size = int(stride * height / 8)
101+
self._buffer2_size = self._buffer1_size
102+
103+
if sramcs_pin:
104+
self._buffer1 = self.sram.get_view(0)
105+
self._buffer2 = self.sram.get_view(self._buffer1_size)
106+
else:
107+
self._buffer1 = bytearray(self._buffer1_size)
108+
self._buffer2 = bytearray(self._buffer2_size)
109+
110+
self._framebuf1 = adafruit_framebuf.FrameBuffer(
111+
self._buffer1, width, height, buf_format=adafruit_framebuf.MHMSB
112+
)
113+
self._framebuf2 = adafruit_framebuf.FrameBuffer(
114+
self._buffer2, width, height, buf_format=adafruit_framebuf.MHMSB
115+
)
116+
self.set_black_buffer(0, True)
117+
self.set_color_buffer(1, False)
118+
119+
# Set single byte transactions flag
120+
self._single_byte_tx = True
121+
122+
# Set the display update value
123+
self._display_update_val = 0xF7
124+
125+
# Default initialization sequence (tri-color mode)
126+
self._default_init_code = bytes(
127+
[
128+
_SSD1683_SW_RESET,
129+
0, # Software reset
130+
0xFF,
131+
50, # Wait for busy (50ms delay)
132+
_SSD1683_WRITE_BORDER,
133+
1, # Border waveform control
134+
0x05, # Border color/waveform
135+
_SSD1683_TEMP_CONTROL,
136+
1, # Temperature control
137+
0x80, # Read temp
138+
_SSD1683_DATA_MODE,
139+
1, # Data entry mode
140+
0x03, # Y decrement, X increment
141+
0xFE, # End of initialization
142+
]
143+
)
144+
145+
def begin(self, reset: bool = True) -> None:
146+
"""Begin communication with the display and set basic settings"""
147+
if reset:
148+
self.hardware_reset()
149+
self.power_down()
150+
151+
def busy_wait(self) -> None:
152+
"""Wait for display to be done with current task, either by polling the
153+
busy pin, or pausing"""
154+
if self._busy:
155+
while self._busy.value: # wait for busy low
156+
time.sleep(0.01)
157+
else:
158+
time.sleep(_BUSY_WAIT / 1000.0) # Convert ms to seconds
159+
160+
def power_up(self) -> None:
161+
"""Power up the display in preparation for writing RAM and updating"""
162+
self.hardware_reset()
163+
time.sleep(0.1)
164+
self.busy_wait()
165+
166+
# Use custom init code if provided, otherwise use default
167+
init_code = self._default_init_code
168+
if hasattr(self, "_epd_init_code") and self._epd_init_code is not None:
169+
init_code = self._epd_init_code
170+
171+
# Send initialization sequence
172+
self._send_command_list(init_code)
173+
174+
# Set RAM window
175+
self.set_ram_window(0, 0, (self._width // 8) - 1, self._height - 1)
176+
177+
# Set RAM address to start position
178+
self.set_ram_address(0, 0)
179+
180+
# Set LUT if we have one
181+
if hasattr(self, "_epd_lut_code") and self._epd_lut_code:
182+
self._send_command_list(self._epd_lut_code)
183+
184+
# Set display size and driver output control
185+
_b0 = (self._height - 1) & 0xFF
186+
_b1 = ((self._height - 1) >> 8) & 0xFF
187+
_b2 = 0x00
188+
self.command(_SSD1683_DRIVER_CONTROL, bytearray([_b0, _b1, _b2]))
189+
190+
def power_down(self) -> None:
191+
"""Power down the display - required when not actively displaying!"""
192+
# Only deep sleep if we can get out of it
193+
if self._rst:
194+
# deep sleep
195+
self.command(_SSD1683_DEEP_SLEEP, bytearray([0x01]))
196+
time.sleep(0.1)
197+
else:
198+
self.command(_SSD1683_SW_RESET)
199+
self.busy_wait()
200+
201+
def update(self) -> None:
202+
"""Update the display from internal memory"""
203+
# display update sequence
204+
self.command(_SSD1683_DISP_CTRL2, bytearray([self._display_update_val]))
205+
self.command(_SSD1683_MASTER_ACTIVATE)
206+
self.busy_wait()
207+
208+
if not self._busy:
209+
time.sleep(1) # wait 1 second
210+
211+
def write_ram(self, index: Literal[0, 1]) -> int:
212+
"""Send the one byte command for starting the RAM write process. Returns
213+
the byte read at the same time over SPI. index is the RAM buffer, can be
214+
0 or 1 for tri-color displays."""
215+
if index == 0:
216+
return self.command(_SSD1683_WRITE_RAM1, end=False)
217+
if index == 1:
218+
return self.command(_SSD1683_WRITE_RAM2, end=False)
219+
raise RuntimeError("RAM index must be 0 or 1")
220+
221+
def set_ram_address(self, x: int, y: int) -> None:
222+
"""Set the RAM address location"""
223+
# set RAM x address count
224+
self.command(_SSD1683_SET_RAMXCOUNT, bytearray([x & 0xFF]))
225+
226+
# set RAM y address count
227+
self.command(_SSD1683_SET_RAMYCOUNT, bytearray([y & 0xFF, (y >> 8) & 0xFF]))
228+
229+
def set_ram_window(self, x1: int, y1: int, x2: int, y2: int) -> None:
230+
"""Set the RAM window for partial updates"""
231+
# Set ram X start/end position
232+
self.command(_SSD1683_SET_RAMXPOS, bytearray([x1 & 0xFF, x2 & 0xFF]))
233+
234+
# Set ram Y start/end position
235+
self.command(
236+
_SSD1683_SET_RAMYPOS,
237+
bytearray([y1 & 0xFF, (y1 >> 8) & 0xFF, y2 & 0xFF, (y2 >> 8) & 0xFF]),
238+
)
239+
240+
def _send_command_list(self, init_sequence: bytes) -> None:
241+
"""Send a sequence of commands from an initialization list"""
242+
i = 0
243+
while i < len(init_sequence):
244+
cmd = init_sequence[i]
245+
i += 1
246+
247+
if cmd == 0xFE: # End marker
248+
break
249+
elif cmd == 0xFF: # Delay marker
250+
if i < len(init_sequence):
251+
delay_ms = init_sequence[i]
252+
i += 1
253+
time.sleep(delay_ms / 1000.0)
254+
elif i < len(init_sequence):
255+
num_args = init_sequence[i]
256+
i += 1
257+
if num_args > 0 and (i + num_args) <= len(init_sequence):
258+
args = init_sequence[i : i + num_args]
259+
self.command(cmd, bytearray(args))
260+
i += num_args
261+
else:
262+
self.command(cmd)

examples/epd_bitmap.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from adafruit_epd.ssd1675 import Adafruit_SSD1675
1515
from adafruit_epd.ssd1680 import Adafruit_SSD1680
1616
from adafruit_epd.ssd1681 import Adafruit_SSD1681
17+
from adafruit_epd.ssd1683 import Adafruit_SSD1683
1718
from adafruit_epd.uc8151d import Adafruit_UC8151D
1819

1920
# create the spi device and pins we will need
@@ -36,6 +37,7 @@
3637
# display = Adafruit_UC8151D(128, 296, # 2.9" mono flexible display
3738
# display = Adafruit_IL0373(128, 296, # 2.9" Tri-color display IL0373
3839
# display = Adafruit_SSD1680(128, 296, # 2.9" Tri-color display SSD1680
40+
# display = Adafruit_SSD1683(400, 300, # 4.2" 300x400 Tri-Color display
3941
# display = Adafruit_IL0398(400, 300, # 4.2" Tri-color display
4042
display = Adafruit_IL0373(
4143
104,

examples/epd_blinka.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from adafruit_epd.ssd1675b import Adafruit_SSD1675B
1818
from adafruit_epd.ssd1680 import Adafruit_SSD1680
1919
from adafruit_epd.ssd1681 import Adafruit_SSD1681
20+
from adafruit_epd.ssd1683 import Adafruit_SSD1683
2021
from adafruit_epd.uc8151d import Adafruit_UC8151D
2122

2223
# create the spi device and pins we will need
@@ -35,6 +36,7 @@
3536
# display = Adafruit_SSD1680(122, 250, # 2.13" HD Tri-color display
3637
# display = Adafruit_SSD1681(200, 200, # 1.54" HD Tri-color display
3738
# display = Adafruit_SSD1675(122, 250, # 2.13" HD mono display
39+
# display = Adafruit_SSD1683(400, 300, # 4.2" 300x400 Tri-Color display
3840
# display = Adafruit_IL91874(176, 264, # 2.7" Tri-color display
3941
# display = Adafruit_EK79686(176, 264, # 2.7" Tri-color display
4042
# display = Adafruit_IL0373(152, 152, # 1.54" Tri-color display

examples/epd_pillow_demo.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from adafruit_epd.ssd1675 import Adafruit_SSD1675
2121
from adafruit_epd.ssd1680 import Adafruit_SSD1680, Adafruit_SSD1680Z
2222
from adafruit_epd.ssd1681 import Adafruit_SSD1681
23+
from adafruit_epd.ssd1683 import Adafruit_SSD1683
2324
from adafruit_epd.uc8151d import Adafruit_UC8151D
2425

2526
# First define some color constants
@@ -49,6 +50,7 @@
4950
# display = Adafruit_SSD1680(122, 250, # 2.13" HD Tri-color or mono display
5051
# display = Adafruit_SSD1680Z(122, 250, # Newer 2.13" mono display
5152
# display = Adafruit_SSD1681(200, 200, # 1.54" HD Tri-color display
53+
# display = Adafruit_SSD1683(400, 300, # 4.2" 300x400 Tri-Color display
5254
# display = Adafruit_IL91874(176, 264, # 2.7" Tri-color display
5355
# display = Adafruit_EK79686(176, 264, # 2.7" Tri-color display
5456
# display = Adafruit_IL0373(152, 152, # 1.54" Tri-color display

examples/epd_pillow_image.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from adafruit_epd.ssd1675 import Adafruit_SSD1675
2323
from adafruit_epd.ssd1680 import Adafruit_SSD1680, Adafruit_SSD1680Z
2424
from adafruit_epd.ssd1681 import Adafruit_SSD1681
25+
from adafruit_epd.ssd1683 import Adafruit_SSD1683
2526
from adafruit_epd.uc8151d import Adafruit_UC8151D
2627

2728
# create the spi device and pins we will need
@@ -39,6 +40,7 @@
3940
# display = Adafruit_SSD1680(122, 250, # 2.13" HD Tri-color or mono display
4041
# display = Adafruit_SSD1680Z(122, 250, # Newer 2.13" mono display
4142
# display = Adafruit_SSD1681(200, 200, # 1.54" HD Tri-color display
43+
# display = Adafruit_SSD1683(400, 300, # 4.2" 300x400 Tri-Color display
4244
# display = Adafruit_IL91874(176, 264, # 2.7" Tri-color display
4345
# display = Adafruit_EK79686(176, 264, # 2.7" Tri-color display
4446
# display = Adafruit_IL0373(152, 152, # 1.54" Tri-color display

examples/epd_simpletest.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from adafruit_epd.ssd1675 import Adafruit_SSD1675
1616
from adafruit_epd.ssd1680 import Adafruit_SSD1680, Adafruit_SSD1680Z
1717
from adafruit_epd.ssd1681 import Adafruit_SSD1681
18+
from adafruit_epd.ssd1683 import Adafruit_SSD1683
1819
from adafruit_epd.uc8151d import Adafruit_UC8151D
1920

2021
# create the spi device and pins we will need
@@ -33,6 +34,7 @@
3334
# display = Adafruit_SSD1680(122, 250, # 2.13" HD Tri-color display
3435
# display = Adafruit_SSD1681(200, 200, # 1.54" HD Tri-color display
3536
# display = Adafruit_SSD1681(200, 200, # 1.54" HD Tri-color display
37+
# display = Adafruit_SSD1683(400, 300, # 4.2" 300x400 Tri-Color display
3638
# display = Adafruit_IL91874(176, 264, # 2.7" Tri-color display
3739
# display = Adafruit_EK79686(176, 264, # 2.7" Tri-color display
3840
# display = Adafruit_IL0373(152, 152, # 1.54" Tri-color display

0 commit comments

Comments
 (0)