Skip to content

Commit 45a24db

Browse files
authored
Merge pull request #94 from adafruit/UC8197
add UC8197 driver
2 parents 9c88f82 + cd138e9 commit 45a24db

File tree

6 files changed

+246
-8
lines changed

6 files changed

+246
-8
lines changed

adafruit_epd/uc8179.py

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
# SPDX-FileCopyrightText: 2025 Liz Clark for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
"""
6+
`adafruit_epd.uc8179` - Adafruit UC8179 - ePaper display driver
7+
====================================================================================
8+
CircuitPython driver for Adafruit UC8179 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+
# UC8179 commands
34+
_UC8179_PANELSETTING = const(0x00)
35+
_UC8179_POWERSETTING = const(0x01)
36+
_UC8179_POWEROFF = const(0x02)
37+
_UC8179_POWERON = const(0x04)
38+
_UC8179_DEEPSLEEP = const(0x07)
39+
_UC8179_WRITE_RAM1 = const(0x10)
40+
_UC8179_DATASTOP = const(0x11)
41+
_UC8179_DISPLAYREFRESH = const(0x12)
42+
_UC8179_WRITE_RAM2 = const(0x13)
43+
_UC8179_DUALSPI = const(0x15)
44+
_UC8179_WRITE_VCOM = const(0x50)
45+
_UC8179_TCON = const(0x60)
46+
_UC8179_TRES = const(0x61)
47+
_UC8179_GET_STATUS = const(0x71)
48+
49+
BUSY_WAIT = const(500) # milliseconds
50+
51+
52+
class Adafruit_UC8179(Adafruit_EPD):
53+
"""driver class for Adafruit UC8179 ePaper display breakouts"""
54+
55+
def __init__(
56+
self,
57+
width: int,
58+
height: int,
59+
spi: SPI,
60+
*,
61+
cs_pin: DigitalInOut,
62+
dc_pin: DigitalInOut,
63+
sramcs_pin: DigitalInOut,
64+
rst_pin: DigitalInOut,
65+
busy_pin: DigitalInOut,
66+
) -> None:
67+
# Adjust height to be divisible by 8 (direct from Arduino)
68+
if (height % 8) != 0:
69+
height += 8 - (height % 8)
70+
71+
super().__init__(width, height, spi, cs_pin, dc_pin, sramcs_pin, rst_pin, busy_pin)
72+
73+
# Calculate buffer sizes exactly as Arduino does: width * height / 8
74+
self._buffer1_size = width * height // 8
75+
self._buffer2_size = self._buffer1_size
76+
77+
if sramcs_pin:
78+
# Using external SRAM
79+
self._buffer1 = self.sram.get_view(0)
80+
self._buffer2 = self.sram.get_view(self._buffer1_size)
81+
else:
82+
# Using internal RAM
83+
self._buffer1 = bytearray(self._buffer1_size)
84+
self._buffer2 = bytearray(self._buffer2_size)
85+
86+
# Create frame buffers
87+
self._framebuf1 = adafruit_framebuf.FrameBuffer(
88+
self._buffer1,
89+
width,
90+
height,
91+
buf_format=adafruit_framebuf.MHMSB,
92+
)
93+
self._framebuf2 = adafruit_framebuf.FrameBuffer(
94+
self._buffer2,
95+
width,
96+
height,
97+
buf_format=adafruit_framebuf.MHMSB,
98+
)
99+
100+
# Set up which frame buffer is which color
101+
self.set_black_buffer(0, True)
102+
self.set_color_buffer(1, False)
103+
104+
# UC8179 uses single byte transactions
105+
self._single_byte_tx = False
106+
107+
# Default refresh delay (from Adafruit_EPD base class in Arduino)
108+
self.default_refresh_delay = 15 # seconds
109+
# pylint: enable=too-many-arguments
110+
111+
def begin(self, reset: bool = True) -> None:
112+
"""Begin communication with the display and set basic settings"""
113+
if reset:
114+
self.hardware_reset()
115+
self.power_down()
116+
117+
def busy_wait(self) -> None:
118+
"""Wait for display to be done with current task, either by polling the
119+
busy pin, or pausing"""
120+
if self._busy:
121+
# Wait for busy pin to go HIGH
122+
while not self._busy.value:
123+
self.command(_UC8179_GET_STATUS)
124+
time.sleep(0.1)
125+
else:
126+
# No busy pin, just wait
127+
time.sleep(BUSY_WAIT / 1000.0)
128+
# Additional delay after busy signal
129+
time.sleep(0.2)
130+
131+
def power_up(self) -> None:
132+
"""Power up the display in preparation for writing RAM and updating"""
133+
self.hardware_reset()
134+
135+
# Power setting
136+
self.command(
137+
_UC8179_POWERSETTING,
138+
bytearray(
139+
[
140+
0x07, # VGH=20V
141+
0x07, # VGL=-20V
142+
0x3F, # VDH=15V
143+
0x3F, # VDL=-15V
144+
]
145+
),
146+
)
147+
148+
# Power on
149+
self.command(_UC8179_POWERON)
150+
time.sleep(0.1) # 100ms delay
151+
self.busy_wait()
152+
153+
# Panel setting
154+
self.command(_UC8179_PANELSETTING, bytearray([0b011111])) # BW OTP LUT
155+
156+
# Resolution setting
157+
self.command(
158+
_UC8179_TRES,
159+
bytearray(
160+
[self._width >> 8, self._width & 0xFF, self._height >> 8, self._height & 0xFF]
161+
),
162+
)
163+
164+
# Dual SPI setting
165+
self.command(_UC8179_DUALSPI, bytearray([0x00]))
166+
167+
# VCOM setting
168+
self.command(_UC8179_WRITE_VCOM, bytearray([0x10, 0x07]))
169+
170+
# TCON setting
171+
self.command(_UC8179_TCON, bytearray([0x22]))
172+
173+
def power_down(self) -> None:
174+
"""Power down the display - required when not actively displaying!"""
175+
self.command(_UC8179_POWEROFF)
176+
self.busy_wait()
177+
178+
# Only deep sleep if we have a reset pin to wake it up
179+
if self._rst:
180+
self.command(_UC8179_DEEPSLEEP, bytearray([0x05]))
181+
time.sleep(0.1)
182+
183+
def update(self) -> None:
184+
"""Update the display from internal memory"""
185+
self.command(_UC8179_DISPLAYREFRESH)
186+
time.sleep(0.1) # 100ms delay
187+
self.busy_wait()
188+
189+
if not self._busy:
190+
# If no busy pin, use default refresh delay
191+
time.sleep(self.default_refresh_delay)
192+
193+
def write_ram(self, index: Literal[0, 1]) -> int:
194+
"""Send the one byte command for starting the RAM write process. Returns
195+
the byte read at the same time over SPI. index is the RAM buffer, can be
196+
0 or 1 for tri-color displays."""
197+
if index == 0:
198+
return self.command(_UC8179_WRITE_RAM1, end=False)
199+
if index == 1:
200+
return self.command(_UC8179_WRITE_RAM2, end=False)
201+
raise RuntimeError("RAM index must be 0 or 1")
202+
203+
def set_ram_address(self, x: int, y: int) -> None: # noqa: PLR6301, F841
204+
"""Set the RAM address location, not used on this chipset but required by
205+
the superclass"""
206+
# Not used in UC8179 chip
207+
pass
208+
209+
def set_ram_window(self, x1: int, y1: int, x2: int, y2: int) -> None: # noqa: PLR6301, F841
210+
"""Set the RAM window, not used on this chipset but required by
211+
the superclass"""
212+
# Not used in UC8179 chip
213+
pass

examples/epd_bitmap.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from adafruit_epd.ssd1681 import Adafruit_SSD1681
1717
from adafruit_epd.ssd1683 import Adafruit_SSD1683
1818
from adafruit_epd.uc8151d import Adafruit_UC8151D
19+
from adafruit_epd.uc8179 import Adafruit_UC8179
1920

2021
# create the spi device and pins we will need
2122
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
@@ -35,6 +36,8 @@
3536
# display = Adafruit_EK79686(176, 264, # 2.7" Tri-color display
3637
# display = Adafruit_IL0373(152, 152, # 1.54" Tri-color display
3738
# display = Adafruit_UC8151D(128, 296, # 2.9" mono flexible display
39+
# display = Adafruit_UC8179(648, 480, # 5.83" mono 648x480 display
40+
# display = Adafruit_UC8179(800, 480, # 7.5" mono 800x480 display
3841
# display = Adafruit_IL0373(128, 296, # 2.9" Tri-color display IL0373
3942
# display = Adafruit_SSD1680(128, 296, # 2.9" Tri-color display SSD1680
4043
# display = Adafruit_SSD1683(400, 300, # 4.2" 300x400 Tri-Color display
@@ -50,7 +53,9 @@
5053
busy_pin=busy,
5154
)
5255

53-
# IF YOU HAVE A 2.13" FLEXIBLE DISPLAY uncomment these lines!
56+
# IF YOU HAVE A 2.13" FLEXIBLE DISPLAY OR!
57+
# UC8179 5.83" or 7.5" displays
58+
# uncomment these lines!
5459
# display.set_black_buffer(1, False)
5560
# display.set_color_buffer(1, False)
5661

examples/epd_blinka.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from adafruit_epd.ssd1681 import Adafruit_SSD1681
2020
from adafruit_epd.ssd1683 import Adafruit_SSD1683
2121
from adafruit_epd.uc8151d import Adafruit_UC8151D
22+
from adafruit_epd.uc8179 import Adafruit_UC8179
2223

2324
# create the spi device and pins we will need
2425
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
@@ -41,6 +42,8 @@
4142
# display = Adafruit_EK79686(176, 264, # 2.7" Tri-color display
4243
# display = Adafruit_IL0373(152, 152, # 1.54" Tri-color display
4344
# display = Adafruit_UC8151D(128, 296, # 2.9" mono flexible display
45+
# display = Adafruit_UC8179(648, 480, # 5.83" mono 648x480 display
46+
# display = Adafruit_UC8179(800, 480, # 7.5" mono 800x480 display
4447
# display = Adafruit_IL0373(128, 296, # 2.9" Tri-color display
4548
# display = Adafruit_IL0398(400, 300, # 4.2" Tri-color display
4649
# display = Adafruit_IL0373(104, 212, # 2.13" Tri-color display
@@ -55,7 +58,9 @@
5558
busy_pin=busy,
5659
)
5760

58-
# IF YOU HAVE A 2.13" FLEXIBLE DISPLAY uncomment these lines!
61+
# IF YOU HAVE A 2.13" FLEXIBLE DISPLAY OR!
62+
# UC8179 5.83" or 7.5" displays
63+
# uncomment these lines!
5964
# display.set_black_buffer(1, False)
6065
# display.set_color_buffer(1, False)
6166

examples/epd_pillow_demo.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from adafruit_epd.ssd1681 import Adafruit_SSD1681
2323
from adafruit_epd.ssd1683 import Adafruit_SSD1683
2424
from adafruit_epd.uc8151d import Adafruit_UC8151D
25+
from adafruit_epd.uc8179 import Adafruit_UC8179
2526

2627
# First define some color constants
2728
WHITE = (0xFF, 0xFF, 0xFF)
@@ -50,13 +51,15 @@
5051
# display = Adafruit_SSD1680(122, 250, # 2.13" HD Tri-color or mono display
5152
# display = Adafruit_SSD1680Z(122, 250, # Newer 2.13" mono display
5253
# display = Adafruit_SSD1681(200, 200, # 1.54" HD Tri-color display
53-
# display = Adafruit_SSD1683(400, 300, # 4.2" 300x400 Tri-Color display
5454
# display = Adafruit_IL91874(176, 264, # 2.7" Tri-color display
5555
# display = Adafruit_EK79686(176, 264, # 2.7" Tri-color display
5656
# display = Adafruit_IL0373(152, 152, # 1.54" Tri-color display
5757
# display = Adafruit_UC8151D(128, 296, # 2.9" mono flexible display
58+
# display = Adafruit_UC8179(648, 480, # 5.83" mono 648x480 display
59+
# display = Adafruit_UC8179(800, 480, # 7.5" mono 800x480 display
5860
# display = Adafruit_IL0373(128, 296, # 2.9" Tri-color display IL0373
5961
# display = Adafruit_SSD1680(128, 296, # 2.9" Tri-color display SSD1680
62+
# display = Adafruit_SSD1683(400, 300, # 4.2" 300x400 Tri-Color display
6063
# display = Adafruit_IL0398(400, 300, # 4.2" Tri-color display
6164
display = Adafruit_IL0373(
6265
104,
@@ -69,7 +72,9 @@
6972
busy_pin=busy,
7073
)
7174

72-
# IF YOU HAVE A 2.13" FLEXIBLE DISPLAY uncomment these lines!
75+
# IF YOU HAVE A 2.13" FLEXIBLE DISPLAY OR!
76+
# UC8179 5.83" or 7.5" displays
77+
# uncomment these lines!
7378
# display.set_black_buffer(1, False)
7479
# display.set_color_buffer(1, False)
7580

examples/epd_pillow_image.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from adafruit_epd.ssd1681 import Adafruit_SSD1681
2525
from adafruit_epd.ssd1683 import Adafruit_SSD1683
2626
from adafruit_epd.uc8151d import Adafruit_UC8151D
27+
from adafruit_epd.uc8179 import Adafruit_UC8179
2728

2829
# create the spi device and pins we will need
2930
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
@@ -40,13 +41,15 @@
4041
# display = Adafruit_SSD1680(122, 250, # 2.13" HD Tri-color or mono display
4142
# display = Adafruit_SSD1680Z(122, 250, # Newer 2.13" mono display
4243
# display = Adafruit_SSD1681(200, 200, # 1.54" HD Tri-color display
43-
# display = Adafruit_SSD1683(400, 300, # 4.2" 300x400 Tri-Color display
4444
# display = Adafruit_IL91874(176, 264, # 2.7" Tri-color display
4545
# display = Adafruit_EK79686(176, 264, # 2.7" Tri-color display
4646
# display = Adafruit_IL0373(152, 152, # 1.54" Tri-color display
4747
# display = Adafruit_UC8151D(128, 296, # 2.9" mono flexible display
48+
# display = Adafruit_UC8179(648, 480, # 5.83" mono 648x480 display
49+
# display = Adafruit_UC8179(800, 480, # 7.5" mono 800x480 display
4850
# display = Adafruit_IL0373(128, 296, # 2.9" Tri-color display IL0373
4951
# display = Adafruit_SSD1680(128, 296, # 2.9" Tri-color display SSD1680
52+
# display = Adafruit_SSD1683(400, 300, # 4.2" 300x400 Tri-Color display
5053
# display = Adafruit_IL0398(400, 300, # 4.2" Tri-color display
5154
display = Adafruit_IL0373(
5255
104,
@@ -59,7 +62,9 @@
5962
busy_pin=busy,
6063
)
6164

62-
# IF YOU HAVE A 2.13" FLEXIBLE DISPLAY uncomment these lines!
65+
# IF YOU HAVE A 2.13" FLEXIBLE DISPLAY OR!
66+
# UC8179 5.83" or 7.5" displays
67+
# uncomment these lines!
6368
# display.set_black_buffer(1, False)
6469
# display.set_color_buffer(1, False)
6570

examples/epd_simpletest.py

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

2122
# create the spi device and pins we will need
2223
spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
@@ -34,13 +35,15 @@
3435
# display = Adafruit_SSD1680(122, 250, # 2.13" HD Tri-color display
3536
# display = Adafruit_SSD1681(200, 200, # 1.54" HD Tri-color display
3637
# display = Adafruit_SSD1681(200, 200, # 1.54" HD Tri-color display
37-
# display = Adafruit_SSD1683(400, 300, # 4.2" 300x400 Tri-Color display
3838
# display = Adafruit_IL91874(176, 264, # 2.7" Tri-color display
3939
# display = Adafruit_EK79686(176, 264, # 2.7" Tri-color display
4040
# display = Adafruit_IL0373(152, 152, # 1.54" Tri-color display
4141
# display = Adafruit_UC8151D(128, 296, # 2.9" mono flexible display
42+
# display = Adafruit_UC8179(648, 480, # 5.83" mono 648x480 display
43+
# display = Adafruit_UC8179(800, 480, # 7.5" mono 800x480 display
4244
# display = Adafruit_IL0373(128, 296, # 2.9" Tri-color display IL0373
4345
# display = Adafruit_SSD1680(128, 296, # 2.9" Tri-color display SSD1680
46+
# display = Adafruit_SSD1683(400, 300, # 4.2" 300x400 Tri-Color display
4447
# display = Adafruit_IL0398(400, 300, # 4.2" Tri-color display
4548
display = Adafruit_IL0373(
4649
104,
@@ -53,7 +56,9 @@
5356
busy_pin=busy,
5457
)
5558

56-
# IF YOU HAVE A 2.13" FLEXIBLE DISPLAY uncomment these lines!
59+
# IF YOU HAVE A 2.13" FLEXIBLE DISPLAY OR!
60+
# UC8179 5.83" or 7.5" displays
61+
# uncomment these lines!
5762
# display.set_black_buffer(1, False)
5863
# display.set_color_buffer(1, False)
5964

0 commit comments

Comments
 (0)