begin framebuffification
This commit is contained in:
parent
346a9d47ff
commit
f7c350111d
2 changed files with 55 additions and 75 deletions
|
|
@ -28,6 +28,7 @@ CircuitPython driver for Adafruit ePaper display breakouts
|
|||
|
||||
import time
|
||||
import digitalio
|
||||
import adafruit_framebuf
|
||||
from adafruit_epd import mcp_sram
|
||||
|
||||
class Adafruit_EPD:
|
||||
|
|
@ -46,41 +47,47 @@ class Adafruit_EPD:
|
|||
self.width = width
|
||||
self.height = height
|
||||
|
||||
# Setup reset pin.
|
||||
# Setup reset pin, if we have one
|
||||
self._rst = rst_pin
|
||||
if rst_pin:
|
||||
self._rst.direction = digitalio.Direction.OUTPUT
|
||||
|
||||
# Setup busy pin.
|
||||
# Setup busy pin, if we have one
|
||||
self._busy = busy_pin
|
||||
if busy_pin:
|
||||
self._busy.direction = digitalio.Direction.INPUT
|
||||
|
||||
# Setup dc pin.
|
||||
# Setup dc pin (required)
|
||||
self._dc = dc_pin
|
||||
self._dc.direction = digitalio.Direction.OUTPUT
|
||||
self._dc.value = False
|
||||
|
||||
# Setup cs pin.
|
||||
# Setup cs pin (required)
|
||||
self._cs = cs_pin
|
||||
self._cs.direction = digitalio.Direction.OUTPUT
|
||||
self._cs.value = True
|
||||
|
||||
# SPI interface (required)
|
||||
self.spi_device = spi
|
||||
|
||||
if sramcs_pin:
|
||||
self.sram = mcp_sram.Adafruit_MCP_SRAM(sramcs_pin, spi)
|
||||
else:
|
||||
self.sram = None
|
||||
self.bw_buffer = bytearray((width // 8) * height)
|
||||
self.red_buffer = bytearray((width // 8) * height)
|
||||
self._bw_buffer = bytearray((width // 8) * height)
|
||||
self._red_buffer = bytearray((width // 8) * height)
|
||||
# since we have *two* framebuffers - one for red and one for black, we dont subclass but manage manually
|
||||
self._red_framebuf = adafruit_framebuf.FrameBuffer(self._red_buffer, width, height, buf_format=adafruit_framebuf.MHMSB)
|
||||
self._bw_framebuf = adafruit_framebuf.FrameBuffer(self._bw_buffer, width, height, buf_format=adafruit_framebuf.MHMSB)
|
||||
|
||||
# if we hav ea reset pin, do a hardware reset
|
||||
if self._rst:
|
||||
self._rst.value = False
|
||||
time.sleep(.1)
|
||||
self._rst.value = True
|
||||
time.sleep(.1)
|
||||
|
||||
|
||||
def command(self, cmd, data=None, end=True):
|
||||
"""Send command byte to display."""
|
||||
self._cs.value = True
|
||||
|
|
@ -109,42 +116,34 @@ class Adafruit_EPD:
|
|||
self._cs.value = True
|
||||
self.spi_device.unlock()
|
||||
|
||||
def draw_pixel(self, x, y, color):
|
||||
"""This should be overridden in the subclass"""
|
||||
pass
|
||||
|
||||
#framebuf methods
|
||||
def fill(self, color):
|
||||
"""fill the screen with the passed color"""
|
||||
self.fill_rect(0, 0, self.width, self.height, color)
|
||||
#This should be overridden in the subclass
|
||||
self._bw_framebuf.fill((color == Adafruit_EPD.BLACK) != self.black_invert)
|
||||
self._red_framebuf.fill((color == Adafruit_EPD.RED) != self.red_invert)
|
||||
|
||||
def pixel(self, x, y, color=None):
|
||||
"""This should be overridden in the subclass"""
|
||||
self._bw_framebuf.pixel(x, y, (color == Adafruit_EPD.BLACK) != self.black_invert)
|
||||
self._red_framebuf.pixel(x, y, (color == Adafruit_EPD.RED) != self.red_invert)
|
||||
|
||||
def rect(self, x, y, width, height, color):
|
||||
"""draw a rectangle"""
|
||||
self._bw_framebuf.rect(x, y, width, height, (color == Adafruit_EPD.BLACK) != self.black_invert)
|
||||
self._red_framebuf.rect(x, y, width, height, (color == Adafruit_EPD.RED) != self.red_invert)
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
def fill_rect(self, x, y, width, height, color):
|
||||
"""fill a rectangle with the passed color"""
|
||||
if width < 1 or height < 1 or (x+width) <= 0:
|
||||
return
|
||||
if (y+height) <= 0 or y >= self.height or x >= self.width:
|
||||
return
|
||||
xend = min(self.width, x+width)
|
||||
yend = min(self.height, y+height)
|
||||
x = max(x, 0)
|
||||
y = max(y, 0)
|
||||
for _x in range(xend - x):
|
||||
for _y in range(yend - y):
|
||||
self.draw_pixel(x + _x, y + _y, color)
|
||||
return
|
||||
self._bw_framebuf.fill_rect(x, y, width, height, (color == Adafruit_EPD.BLACK) != self.black_invert)
|
||||
self._red_framebuf.fill_rect(x, y, width, height, (color == Adafruit_EPD.RED) != self.red_invert)
|
||||
|
||||
def pixel(self, x, y, color=None):
|
||||
"""draw a pixel"""
|
||||
if x < 0 or x >= self.width or y < 0 or y >= self.height:
|
||||
return None
|
||||
#TODO: figure this out when we know what framebuffer we
|
||||
# will actually use
|
||||
#if color is None:
|
||||
# return self.get_pixel(self, x, y)
|
||||
def line(self, x_0, y_0, x_1, y_1, color):
|
||||
self._bw_framebuf.line(x_0, y_0, x_1, y_1, (color == Adafruit_EPD.BLACK) != self.black_invert)
|
||||
self._red_framebuf.line(x_0, y_0, x_1, y_1, (color == Adafruit_EPD.RED) != self.red_invert)
|
||||
|
||||
self.draw_pixel(x, y, color)
|
||||
return None
|
||||
def text(self, string, x, y, color, *, font_name="font5x8.bin"):
|
||||
self._bw_framebuf.text(string, x, y, (color == Adafruit_EPD.BLACK) != self.black_invert, font_name)
|
||||
self._red_framebuf.text(string, x, y, (color == Adafruit_EPD.RED) != self.red_invert, font_name)
|
||||
|
||||
def hline(self, x, y, width, color):
|
||||
"""draw a horizontal line"""
|
||||
|
|
@ -153,10 +152,3 @@ class Adafruit_EPD:
|
|||
def vline(self, x, y, height, color):
|
||||
"""draw a vertical line"""
|
||||
self.fill_rect(x, y, 1, height, color)
|
||||
|
||||
def rect(self, x, y, width, height, color):
|
||||
"""draw a rectangle"""
|
||||
self.fill_rect(x, y, width, 1, color)
|
||||
self.fill_rect(x, y+height, width, 1, color)
|
||||
self.fill_rect(x, y, 1, height, color)
|
||||
self.fill_rect(x+width, y, 1, height, color)
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ CircuitPython driver for Adafruit il0373 display breakouts
|
|||
|
||||
import time
|
||||
from micropython import const
|
||||
import adafruit_framebuf
|
||||
from adafruit_epd.epd import Adafruit_EPD
|
||||
from adafruit_epd.mcp_sram import Adafruit_MCP_SRAM
|
||||
|
||||
|
|
@ -65,6 +66,8 @@ class Adafruit_IL0373(Adafruit_EPD):
|
|||
|
||||
self.bw_bufsize = int(width * height / 8)
|
||||
self.red_bufsize = int(width * height / 8)
|
||||
self.black_invert = True
|
||||
self.red_invert = True
|
||||
# pylint: enable=too-many-arguments
|
||||
|
||||
def begin(self, reset=True):
|
||||
|
|
@ -172,7 +175,7 @@ class Adafruit_IL0373(Adafruit_EPD):
|
|||
while not self.spi_device.try_lock():
|
||||
pass
|
||||
self._dc.value = True
|
||||
self.spi_device.write(self.bw_buffer)
|
||||
self.spi_device.write(self._bw_buffer)
|
||||
self._cs.value = True
|
||||
self.spi_device.unlock()
|
||||
|
||||
|
|
@ -182,7 +185,7 @@ class Adafruit_IL0373(Adafruit_EPD):
|
|||
while not self.spi_device.try_lock():
|
||||
pass
|
||||
self._dc.value = True
|
||||
self.spi_device.write(self.red_buffer)
|
||||
self.spi_device.write(self._red_buffer)
|
||||
self._cs.value = True
|
||||
self.spi_device.unlock()
|
||||
|
||||
|
|
@ -220,45 +223,32 @@ class Adafruit_IL0373(Adafruit_EPD):
|
|||
|
||||
self.sram.write8(addr, current)
|
||||
|
||||
def draw_pixel(self, x, y, color):
|
||||
def pixel(self, x, y, color):
|
||||
"""draw a single pixel in the display buffer"""
|
||||
if (x < 0) or (x >= self.width) or (y < 0) or (y >= self.height):
|
||||
return
|
||||
|
||||
if x == 0:
|
||||
x = 1
|
||||
|
||||
addr = ((self.width - x) * self.height + y) // 8
|
||||
|
||||
if self.sram:
|
||||
if (x < 0) or (x >= self.width) or (y < 0) or (y >= self.height):
|
||||
return
|
||||
if x == 0:
|
||||
x = 1
|
||||
addr = ((self.width - x) * self.height + y) // 8
|
||||
if color == Adafruit_EPD.RED:
|
||||
current = self.sram.read8(addr + self.bw_bufsize)
|
||||
else:
|
||||
current = self.sram.read8(addr)
|
||||
else:
|
||||
if color == Adafruit_EPD.RED:
|
||||
current = self.red_buffer[addr]
|
||||
else:
|
||||
current = self.bw_buffer[addr]
|
||||
|
||||
if color == Adafruit_EPD.WHITE:
|
||||
current = current | (1 << (7 - y%8))
|
||||
elif color in (Adafruit_EPD.RED, Adafruit_EPD.BLACK):
|
||||
current = current & ~(1 << (7 - y%8))
|
||||
elif color == Adafruit_EPD.INVERSE:
|
||||
current = current ^ (1 << (7 - y%8))
|
||||
if color == Adafruit_EPD.WHITE:
|
||||
current = current | (1 << (7 - y%8))
|
||||
elif color in (Adafruit_EPD.RED, Adafruit_EPD.BLACK):
|
||||
current = current & ~(1 << (7 - y%8))
|
||||
elif color == Adafruit_EPD.INVERSE:
|
||||
current = current ^ (1 << (7 - y%8))
|
||||
|
||||
if self.sram:
|
||||
if color == Adafruit_EPD.RED:
|
||||
current = self.sram.write8(addr + self.bw_bufsize, current)
|
||||
self.sram.write8(addr + self.bw_bufsize, current)
|
||||
else:
|
||||
current = self.sram.write8(addr, current)
|
||||
self.sram.write8(addr, current)
|
||||
else:
|
||||
if color == Adafruit_EPD.RED:
|
||||
self.red_buffer[addr] = current
|
||||
else:
|
||||
self.bw_buffer[addr] = current
|
||||
return
|
||||
super().pixel(x, y, color)
|
||||
|
||||
def fill(self, color):
|
||||
"""fill the screen with the passed color"""
|
||||
|
|
@ -272,6 +262,4 @@ class Adafruit_IL0373(Adafruit_EPD):
|
|||
self.sram.erase(0x00, self.bw_bufsize, black_fill)
|
||||
self.sram.erase(self.bw_bufsize, self.red_bufsize, red_fill)
|
||||
else:
|
||||
for i in range(len(self.bw_buffer)):
|
||||
self.bw_buffer[i] = black_fill
|
||||
self.red_buffer[i] = red_fill
|
||||
super().fill(color)
|
||||
|
|
|
|||
Loading…
Reference in a new issue