Skip to content

Added requested type annotations to epd.py. #65

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
May 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f8cab12
Added type annotations.
sdomoszlai13 May 2, 2023
3f7e3d7
Fixed type annotations in accordance with code review.
sdomoszlai13 May 9, 2023
e4f301f
Added requested type annotations.
sdomoszlai13 May 9, 2023
507f786
Added requested type annotations to uc8151d.py
sdomoszlai13 May 10, 2023
f0e34c2
Added requested type annotations to ssd1681.py
sdomoszlai13 May 10, 2023
eb4391f
Added requested type annotations to ssd1680.py.
sdomoszlai13 May 10, 2023
3b7e9b4
Added requested type annotations to ssd1675b.py.
sdomoszlai13 May 10, 2023
077dd70
Added except clause.
sdomoszlai13 May 10, 2023
8342c3f
Added requested type annotations to ssd1675.py.
sdomoszlai13 May 10, 2023
f732181
Automatic formatting for ssd1680.py.
sdomoszlai13 May 10, 2023
22eeabb
Added requested type annotations for ssd1608.py.
sdomoszlai13 May 10, 2023
61d59ad
Added requested type annotations for il0398.py.
sdomoszlai13 May 10, 2023
207ba7e
Added requested type annotations to il91874.py.
sdomoszlai13 May 10, 2023
3b02f34
Added requested type annotations to il0373.py.
sdomoszlai13 May 10, 2023
2dccdd6
Merge branch 'adafruit:main' into fix-annotations-epd.py
sdomoszlai13 May 18, 2023
81fb192
Merge remote-tracking branch 'origin/fix-annotations-il0373.py' into …
sdomoszlai13 May 18, 2023
1904165
Merge remote-tracking branch 'origin/fix-annotations-il0398.py' into …
sdomoszlai13 May 18, 2023
af8ef7f
Merge remote-tracking branch 'origin/fix-annotations-il91874' into fi…
sdomoszlai13 May 18, 2023
b55613c
Merge remote-tracking branch 'origin/fix-annotations-mcp-sram.py' int…
sdomoszlai13 May 18, 2023
5119e0c
Merge remote-tracking branch 'origin/fix-annotations-ssd1608.py' into…
sdomoszlai13 May 18, 2023
d986bb3
Merge remote-tracking branch 'origin/fix-annotations-ssd1675.py' into…
sdomoszlai13 May 18, 2023
a37e7fe
Merge remote-tracking branch 'origin/fix-annotations-ssd1675b.py' int…
sdomoszlai13 May 18, 2023
254efdd
Merge remote-tracking branch 'origin/fix-annotations-ssd1681.py' into…
sdomoszlai13 May 18, 2023
2513226
Merge remote-tracking branch 'origin/fix-annotations-uc8151d.py' into…
sdomoszlai13 May 18, 2023
95758b3
Added changes requested by @FoamyGuy.
sdomoszlai13 May 18, 2023
3a6375d
Implemented changes requested by @FoamyGuy.
sdomoszlai13 May 20, 2023
148c744
Import Direction at runtime
FoamyGuy May 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 80 additions & 29 deletions adafruit_epd/epd.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,28 @@
CircuitPython driver for Adafruit ePaper display breakouts
* Author(s): Dean Miller
"""
# pylint: disable=ungrouped-imports

import time
from micropython import const
from digitalio import Direction
from adafruit_epd import mcp_sram

try:
"""Needed for type annotations"""
from typing import Any, Union, Callable, Optional
from busio import SPI
from digitalio import DigitalInOut
from circuitpython_typing.pil import Image

except ImportError:
pass

__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_EPD.git"


class Adafruit_EPD: # pylint: disable=too-many-instance-attributes, too-many-public-methods
class Adafruit_EPD: # pylint: disable=too-many-instance-attributes, too-many-public-methods, too-many-arguments
"""Base class for EPD displays"""

BLACK = const(0)
Expand All @@ -29,8 +40,16 @@ class Adafruit_EPD: # pylint: disable=too-many-instance-attributes, too-many-pu
LIGHT = const(5)

def __init__(
self, width, height, spi, cs_pin, dc_pin, sramcs_pin, rst_pin, busy_pin
): # pylint: disable=too-many-arguments
self,
width: int,
height: int,
spi: SPI,
cs_pin: DigitalInOut,
dc_pin: DigitalInOut,
sramcs_pin: DigitalInOut,
rst_pin: DigitalInOut,
busy_pin: DigitalInOut,
) -> None: # pylint: disable=too-many-arguments
self._width = width
self._height = height

Expand Down Expand Up @@ -76,7 +95,7 @@ def __init__(
self._black_inverted = self._color_inverted = True
self.hardware_reset()

def display(self): # pylint: disable=too-many-branches
def display(self) -> None: # pylint: disable=too-many-branches
"""show the contents of the display buffer"""
self.power_up()

Expand Down Expand Up @@ -149,15 +168,17 @@ def display(self): # pylint: disable=too-many-branches

self.update()

def hardware_reset(self):
def hardware_reset(self) -> None:
"""If we have a reset pin, do a hardware reset by toggling it"""
if self._rst:
self._rst.value = False
time.sleep(0.1)
self._rst.value = True
time.sleep(0.1)

def command(self, cmd, data=None, end=True):
def command(
self, cmd: int, data: Optional[bytearray] = None, end: bool = True
) -> int:
"""Send command byte to display."""
self._cs.value = True
self._dc.value = False
Expand All @@ -176,7 +197,7 @@ def command(self, cmd, data=None, end=True):

return ret

def _spi_transfer(self, data):
def _spi_transfer(self, data: Union[int, bytearray]) -> Optional[int]:
"""Transfer one byte or bytearray, toggling the cs pin if required by the EPD chipset"""
if isinstance(data, int): # single byte!
self._spibuf[0] = data
Expand All @@ -203,30 +224,30 @@ def _spi_transfer(self, data):
self._spi_transfer(x)
return None

def power_up(self):
def power_up(self) -> None:
"""Power up the display in preparation for writing RAM and updating.
must be implemented in subclass"""
raise NotImplementedError()

def power_down(self):
def power_down(self) -> None:
"""Power down the display, must be implemented in subclass"""
raise NotImplementedError()

def update(self):
def update(self) -> None:
"""Update the display from internal memory, must be implemented in subclass"""
raise NotImplementedError()

def write_ram(self, index):
def write_ram(self, index: int) -> None:
"""Send the one byte command for starting the RAM write process. Returns
the byte read at the same time over SPI. index is the RAM buffer, can be
0 or 1 for tri-color displays. must be implemented in subclass"""
raise NotImplementedError()

def set_ram_address(self, x, y):
def set_ram_address(self, x: int, y: int) -> None:
"""Set the RAM address location, must be implemented in subclass"""
raise NotImplementedError()

def set_black_buffer(self, index, inverted):
def set_black_buffer(self, index: Union[0, 1], inverted: bool) -> None:
"""Set the index for the black buffer data (0 or 1) and whether its inverted"""
if index == 0:
self._blackframebuf = self._framebuf1
Expand All @@ -236,7 +257,7 @@ def set_black_buffer(self, index, inverted):
raise RuntimeError("Buffer index must be 0 or 1")
self._black_inverted = inverted

def set_color_buffer(self, index, inverted):
def set_color_buffer(self, index: Union[0, 1], inverted: bool) -> None:
"""Set the index for the color buffer data (0 or 1) and whether its inverted"""
if index == 0:
self._colorframebuf = self._framebuf1
Expand All @@ -246,7 +267,12 @@ def set_color_buffer(self, index, inverted):
raise RuntimeError("Buffer index must be 0 or 1")
self._color_inverted = inverted

def _color_dup(self, func, args, color):
def _color_dup(
self,
func: Callable,
args: Any,
color: Union[0, 1, 2, 3, 4, 5],
) -> None:
black = getattr(self._blackframebuf, func)
red = getattr(self._colorframebuf, func)
if self._blackframebuf is self._colorframebuf: # monochrome
Expand All @@ -255,11 +281,11 @@ def _color_dup(self, func, args, color):
black(*args, color=(color == Adafruit_EPD.BLACK) != self._black_inverted)
red(*args, color=(color == Adafruit_EPD.RED) != self._color_inverted)

def pixel(self, x, y, color):
def pixel(self, x: int, y: int, color: int) -> None:
"""draw a single pixel in the display buffer"""
self._color_dup("pixel", (x, y), color)

def fill(self, color):
def fill(self, color: int) -> None:
"""fill the screen with the passed color"""
red_fill = ((color == Adafruit_EPD.RED) != self._color_inverted) * 0xFF
black_fill = ((color == Adafruit_EPD.BLACK) != self._black_inverted) * 0xFF
Expand All @@ -271,21 +297,34 @@ def fill(self, color):
self._blackframebuf.fill(black_fill)
self._colorframebuf.fill(red_fill)

def rect(self, x, y, width, height, color): # pylint: disable=too-many-arguments
def rect(
self, x: int, y: int, width: int, height: int, color: int
) -> None: # pylint: disable=too-many-arguments
"""draw a rectangle"""
self._color_dup("rect", (x, y, width, height), color)

def fill_rect(
self, x, y, width, height, color
): # pylint: disable=too-many-arguments
self, x: int, y: int, width: int, height: int, color: int
) -> None: # pylint: disable=too-many-arguments
"""fill a rectangle with the passed color"""
self._color_dup("fill_rect", (x, y, width, height), color)

def line(self, x_0, y_0, x_1, y_1, color): # pylint: disable=too-many-arguments
def line(
self, x_0: int, y_0: int, x_1: int, y_1: int, color: int
) -> None: # pylint: disable=too-many-arguments
"""Draw a line from (x_0, y_0) to (x_1, y_1) in passed color"""
self._color_dup("line", (x_0, y_0, x_1, y_1), color)

def text(self, string, x, y, color, *, font_name="font5x8.bin", size=1):
def text(
self,
string: str,
x: int,
y: int,
color: int,
*,
font_name: str = "font5x8.bin",
size: int = 1
) -> None:
"""Write text string at location (x, y) in given color, using font file"""
if self._blackframebuf is self._colorframebuf: # monochrome
self._blackframebuf.text(
Expand Down Expand Up @@ -315,39 +354,51 @@ def text(self, string, x, y, color, *, font_name="font5x8.bin", size=1):
)

@property
def width(self):
def width(self) -> int:
"""The width of the display, accounting for rotation"""
if self.rotation in (0, 2):
return self._width
return self._height

@property
def height(self):
def height(self) -> int:
"""The height of the display, accounting for rotation"""
if self.rotation in (0, 2):
return self._height
return self._width

@property
def rotation(self):
def rotation(self) -> Union[0, 1, 2, 3]:
"""The rotation of the display, can be one of (0, 1, 2, 3)"""
return self._framebuf1.rotation

@rotation.setter
def rotation(self, val):
def rotation(self, val: int) -> None:
self._framebuf1.rotation = val
if self._framebuf2:
self._framebuf2.rotation = val

def hline(self, x, y, width, color):
def hline(
self,
x: int,
y: int,
width: int,
color: int,
) -> None:
"""draw a horizontal line"""
self.fill_rect(x, y, width, 1, color)

def vline(self, x, y, height, color):
def vline(
self,
x: int,
y: int,
height: int,
color: int,
) -> None:
"""draw a vertical line"""
self.fill_rect(x, y, 1, height, color)

def image(self, image):
def image(self, image: Image) -> None:
"""Set buffer to value of Python Imaging Library image. The image should
be in RGB mode and a size equal to the display size.
"""
Expand Down
38 changes: 29 additions & 9 deletions adafruit_epd/il0373.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@
import adafruit_framebuf
from adafruit_epd.epd import Adafruit_EPD

try:
"""Needed for type annotations"""
from typing import Union
from busio import SPI
from digitalio import DigitalInOut

except ImportError:
pass

__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_EPD.git"

Expand Down Expand Up @@ -48,8 +57,17 @@ class Adafruit_IL0373(Adafruit_EPD):

# pylint: disable=too-many-arguments
def __init__(
self, width, height, spi, *, cs_pin, dc_pin, sramcs_pin, rst_pin, busy_pin
):
self,
width: int,
height: int,
spi: SPI,
*,
cs_pin: DigitalInOut,
dc_pin: DigitalInOut,
sramcs_pin: DigitalInOut,
rst_pin: DigitalInOut,
busy_pin: DigitalInOut
) -> None:
super().__init__(
width, height, spi, cs_pin, dc_pin, sramcs_pin, rst_pin, busy_pin
)
Expand All @@ -75,13 +93,13 @@ def __init__(
self.set_color_buffer(1, True)
# pylint: enable=too-many-arguments

def begin(self, reset=True):
def begin(self, reset: bool = True) -> None:
"""Begin communication with the display and set basic settings"""
if reset:
self.hardware_reset()
self.power_down()

def busy_wait(self):
def busy_wait(self) -> None:
"""Wait for display to be done with current task, either by polling the
busy pin, or pausing"""
if self._busy:
Expand All @@ -90,7 +108,7 @@ def busy_wait(self):
else:
time.sleep(0.5)

def power_up(self):
def power_up(self) -> None:
"""Power up the display in preparation for writing RAM and updating"""
self.hardware_reset()
self.busy_wait()
Expand All @@ -112,21 +130,21 @@ def power_up(self):
self.command(_IL0373_VCM_DC_SETTING, bytearray([0x0A]))
time.sleep(0.05)

def power_down(self):
def power_down(self) -> None:
"""Power down the display - required when not actively displaying!"""
self.command(_IL0373_CDI, bytearray([0x17]))
self.command(_IL0373_VCM_DC_SETTING, bytearray([0x00]))
self.command(_IL0373_POWER_OFF)

def update(self):
def update(self) -> None:
"""Update the display from internal memory"""
self.command(_IL0373_DISPLAY_REFRESH)
time.sleep(0.1)
self.busy_wait()
if not self._busy:
time.sleep(15) # wait 15 seconds

def write_ram(self, index):
def write_ram(self, index: Union[0, 1]) -> int:
"""Send the one byte command for starting the RAM write process. Returns
the byte read at the same time over SPI. index is the RAM buffer, can be
0 or 1 for tri-color displays."""
Expand All @@ -136,7 +154,9 @@ def write_ram(self, index):
return self.command(_IL0373_DTM2, end=False)
raise RuntimeError("RAM index must be 0 or 1")

def set_ram_address(self, x, y): # pylint: disable=unused-argument, no-self-use
def set_ram_address(
self, x: int, y: int
) -> None: # pylint: disable=unused-argument, no-self-use
"""Set the RAM address location, not used on this chipset but required by
the superclass"""
return # on this chip it does nothing
Loading