Skip to content

Commit

Permalink
Merge branch 'single-line-refresh'
Browse files Browse the repository at this point in the history
  • Loading branch information
mcarr823 committed Dec 20, 2023
2 parents 789cad4 + 429fd6d commit c5e6743
Show file tree
Hide file tree
Showing 4 changed files with 683 additions and 37 deletions.
120 changes: 88 additions & 32 deletions papertty/drivers/driver_it8951.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ def __init__(self):
self.enable_1bpp = True
self.align_1bpp_width = 32
self.align_1bpp_height = 16
self.supports_multi_draw = True

def delay_ms(self, delaytime):
time.sleep(float(delaytime) / 1000.0)
Expand Down Expand Up @@ -313,11 +314,49 @@ def display_area(self, x, y, w, h, display_mode):
self.write_data_half_word(h)
self.write_data_half_word(display_mode)

def draw(self, x, y, image, update_mode_override=None):
def draw_multi(self, imageArray):

"""This function performs multiple draws in a single panel refresh"""

#First, calculate the bounds of the panel area which is being refreshed.
#ie. a rectangle within which all of the images in imageArray would fit.
smallest_x = -1
biggest_x = -1
smallest_y = -1
biggest_y = -1
for arrayItem in imageArray:
left = arrayItem["x"]
top = arrayItem["y"]
image = arrayItem["image"]
right = left + image.width
bottom = top + image.height
if left < smallest_x or smallest_x == -1:
smallest_x = left
if right > biggest_x or biggest_x == -1:
biggest_x = right
if top < smallest_y or smallest_y == -1:
smallest_y = top
if bottom > biggest_y or biggest_y == -1:
biggest_y = bottom
bbox = (smallest_x, smallest_y, biggest_x, biggest_y)

#Next, draw each image.
for i, arrayItem in enumerate(imageArray):
x = arrayItem["x"]
y = arrayItem["y"]
image = arrayItem["image"]
update_mode_override = None
isFirst = i == 0
isLast = i == len(imageArray) - 1
self.draw(x, y, image, update_mode_override, isFirst, isLast, bbox)

def draw(self, x, y, image, update_mode_override=None, isFirst=True, isLast=True, bbox=None):
width = image.size[0]
height = image.size[1]

self.wait_for_display_ready()
#If this is the first (or only) image to draw, prepare the display.
if isFirst:
self.wait_for_display_ready()

#Set to 4bpp by default
bpp = 4
Expand All @@ -343,15 +382,18 @@ def draw(self, x, y, image, update_mode_override=None):
#Confusingly, 1bpp actually requires the use of the 8bpp flag
bpp_mode = self.BPP_8

#If the panel isn't already in 1bpp mode, write these specific commands to the
#register to put it into 1bpp mode.
#This is the important bit which actually puts it in 1bpp in spite of the 8bpp flag
if not self.in_bpp1_mode:
self.write_register(self.REG_UP1SR+2, self.read_register(self.REG_UP1SR+2) | (1<<2) )
self.in_bpp1_mode = True

#Also write the black and white color table for 1bpp mode
self.write_register(self.REG_BGVR, (self.Front_Gray_Val<<8) | self.Back_Gray_Val)
#If this is the first (or only) image to draw, write the registers.
if isFirst:

#If the panel isn't already in 1bpp mode, write these specific commands to the
#register to put it into 1bpp mode.
#This is the important bit which actually puts it in 1bpp in spite of the 8bpp flag
if not self.in_bpp1_mode:
self.write_register(self.REG_UP1SR+2, self.read_register(self.REG_UP1SR+2) | (1<<2) )
self.in_bpp1_mode = True

#Also write the black and white color table for 1bpp mode
self.write_register(self.REG_BGVR, (self.Front_Gray_Val<<8) | self.Back_Gray_Val)

else:
#If we're not in 1bpp mode, default to 4bpp.
Expand All @@ -364,15 +406,18 @@ def draw(self, x, y, image, update_mode_override=None):
bpp = 4
bpp_mode = self.BPP_4

#If the last write was in 1bpp mode, unset that register to take it out of 1bpp mode.
if self.in_bpp1_mode:
self.write_register(self.REG_UP1SR+2, self.read_register(self.REG_UP1SR+2) & ~(1<<2) )
self.in_bpp1_mode = False
#If this is the first (or only) image to draw, write the registers.
if isFirst:

#If the last write was in 1bpp mode, unset that register to take it out of 1bpp mode.
if self.in_bpp1_mode:
self.write_register(self.REG_UP1SR+2, self.read_register(self.REG_UP1SR+2) & ~(1<<2) )
self.in_bpp1_mode = False

#Then write the expected registers for 4bpp mode.
self.write_register(
self.REG_MEMORY_CONV_LISAR + 2, (self.img_addr >> 16) & 0xFFFF)
self.write_register(self.REG_MEMORY_CONV_LISAR, self.img_addr & 0xFFFF)
#Then write the expected registers for 4bpp mode.
self.write_register(
self.REG_MEMORY_CONV_LISAR + 2, (self.img_addr >> 16) & 0xFFFF)
self.write_register(self.REG_MEMORY_CONV_LISAR, self.img_addr & 0xFFFF)

# Define the region being loaded.
self.write_command(self.CMD_LOAD_IMAGE_AREA)
Expand All @@ -391,20 +436,31 @@ def draw(self, x, y, image, update_mode_override=None):
self.write_data_bytes(packed_image)
self.write_command(self.CMD_LOAD_IMAGE_END);

if update_mode_override is not None:
update_mode = update_mode_override
elif image.mode == "1":
# Use a faster, non-flashy update mode for pure black and white
# images.
if bpp == 1 and self.supports_a2 and self.enable_a2:
update_mode = self.DISPLAY_UPDATE_MODE_A2
#If this is the last (or only) image to draw, refresh the panel.
if isLast:

if update_mode_override is not None:
update_mode = update_mode_override
elif image.mode == "1":
# Use a faster, non-flashy update mode for pure black and white
# images.
if bpp == 1 and self.supports_a2 and self.enable_a2:
update_mode = self.DISPLAY_UPDATE_MODE_A2
else:
update_mode = self.DISPLAY_UPDATE_MODE_DU
else:
update_mode = self.DISPLAY_UPDATE_MODE_DU
else:
# Use a slower, flashy update mode for gray scale images.
update_mode = self.DISPLAY_UPDATE_MODE_GC16
# Blit the image to the display
self.display_area(x, y, width, height, update_mode)
# Use a slower, flashy update mode for gray scale images.
update_mode = self.DISPLAY_UPDATE_MODE_GC16

# Blit the image to the display.
# If bbox has been passed in (eg. if performing multiple draws at once)
# then we should update that area.
# Otherwise, refresh the panel based on the image's bounds.
if bbox:
(left, top, right, bottom) = bbox
self.display_area(left, top, right-left, bottom-top, update_mode)
else:
self.display_area(x, y, width, height, update_mode)

def clear(self):
image = Image.new('1', (self.width, self.height), self.white)
Expand Down
1 change: 1 addition & 0 deletions papertty/drivers/drivers_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ def __init__(self):
self.enable_1bpp = None
self.align_1bpp_width = None
self.align_1bpp_height = None
self.supports_multi_draw = None

@abstractmethod
def init(self, **kwargs):
Expand Down
1 change: 1 addition & 0 deletions papertty/drivers/drivers_full.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def __init__(self, **kwargs):
self.enable_1bpp = False
self.align_1bpp_width = False
self.align_1bpp_height = False
self.supports_multi_draw = False

def wait_until_idle(self):
while self.digital_read(self.BUSY_PIN) == 0: # 0: busy, 1: idle
Expand Down
Loading

0 comments on commit c5e6743

Please sign in to comment.