begin framebuffification

This commit is contained in:
ladyada 2019-01-05 21:43:42 -05:00
parent 346a9d47ff
commit f7c350111d
2 changed files with 55 additions and 75 deletions

View file

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

View file

@ -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,26 +223,18 @@ 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 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 self.sram:
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))
@ -248,17 +243,12 @@ class Adafruit_IL0373(Adafruit_EPD):
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)