import logging import epdconfig from PIL import Image import time # Display resolution width = 800 height = 480 BLACK = 0x000000 # 00 BGR WHITE = 0xffffff # 01 YELLOW = 0x00ffff # 10 RED = 0x0000ff # 11 logger = logging.getLogger(__name__) # Hardware reset def reset(): epdconfig.GPIO_RST_PIN.on() time.sleep(200/1000) epdconfig.GPIO_RST_PIN.off() # module reset time.sleep(2/1000) epdconfig.GPIO_RST_PIN.on() time.sleep(200/1000) def send_command(*command): if command: epdconfig.GPIO_DC_PIN.off() epdconfig.spi_writebyte2(command[:1]) if data := command[1:]: epdconfig.GPIO_DC_PIN.on() epdconfig.spi_writebyte2(data) def wait_for_busy_hi(): logger.debug("e-Paper busy H") while not epdconfig.GPIO_BUSY_PIN.value: # 0: idle, 1: busy time.sleep(5/1000) logger.debug("e-Paper busy H release") def wait_for_busy_lo(): logger.debug("e-Paper busy L") while epdconfig.GPIO_BUSY_PIN.value: # 0: busy, 1: idle time.sleep(5/1000) logger.debug("e-Paper busy L release") def display_on(): send_command(0x12, 0x01) # DISPLAY_REFRESH wait_for_busy_hi() send_command(0x02, 0x00) # POWER_OFF wait_for_busy_hi() def init(): epdconfig.module_init() # EPD hardware init start reset() wait_for_busy_hi() time.sleep(30/1000) send_command(0xAA, 0x49, 0x55, 0x20, 0x08, 0x09, 0x18) send_command(0x01, 0x3F) send_command(0x00, 0x4F, 0x69) send_command(0x05, 0x40, 0x1F, 0x1F, 0x2C) send_command(0x08, 0x6F, 0x1F, 0x1F, 0x22) # =================== # 20211212 # First setting send_command(0x06, 0x6F, 0x1F, 0x14, 0x14) # =================== send_command(0x03, 0x00, 0x54, 0x00, 0x44) send_command(0x60, 0x02, 0x00) # Please notice that PLL must be set for version 2 IC send_command(0x30, 0x08) send_command(0x50, 0x3F) send_command(0x61, 0x03, 0x20, 0x01, 0xE0) send_command(0xE3, 0x2F) send_command(0x84, 0x01) def get_buffer(image): # Create a pallette with the 4 colors supported by the panel pal_image = Image.new("P", (1,1)) pal_image.putpalette((0x00,0x00,0x00, 0xff,0xff,0xff, 0xff,0xff,0x00, 0xff,0x00,0x00) + (0x00,0x00,0x00)*252) # Check if we need to rotate the image if image.size == (width, height): image_temp = image elif image.size == (height, width): image_temp = image.rotate(90, expand=True) else: raise RuntimeError("Invalid image dimensions: %d x %d, expected %d x %d" % (image.size[0], image.height[1], width, height)) # Convert the source image to the 4 colors, dithering if needed image_4color = image_temp.convert("RGB").quantize(palette=pal_image) buf_4color = bytearray(image_4color.tobytes('raw')) # into a single byte to transfer to the panel buf = [0x00] * int(width * height / 4) for idx in range(len(buf_4color) // 4): buf[idx] = (buf_4color[idx*4] << 6) + (buf_4color[idx*4+1] << 4) + (buf_4color[idx*4+2] << 2) + buf_4color[idx*4+3] return buf def display(image): assert len(image) == width * height / 4 send_command(0x04) wait_for_busy_hi() send_command(*([0x10] + image)) display_on() def clear(color=0x55): assert not width % 4 iwidth = width // 4 send_command(0x04) wait_for_busy_hi() send_command(*([0x10] + [color]*(height * iwidth))) display_on() def sleep(): send_command(0x02, 0x00) # POWER_OFF send_command(0x07, 0xa5) # DEEP_SLEEP time.sleep(2) epdconfig.module_exit()