From f89ba85f73b2b4af865b1fc9e4320d61965b69bf Mon Sep 17 00:00:00 2001 From: Jeroen Oudshoorn Date: Tue, 23 Jan 2024 10:59:25 +0100 Subject: [PATCH] Couple updated displays from Waveshare, not 213g. https://github.com/waveshareteam/e-Paper/commit/166c012cdeb3bee49f59780c7764daa076aea343 --- .../ui/hw/libs/waveshare/v1in02/epd1in02.py | 18 +- .../hw/libs/waveshare/v2in7_v2/epd2in7_V2.py | 79 +-- .../hw/libs/waveshare/v2in9_v2/epd2in9V2.py | 4 +- .../libs/waveshare/v2in9b_v4/epd2in9b_V4.py | 2 +- .../ui/hw/libs/waveshare/v4in26/epd4in26.py | 2 +- .../hw/libs/waveshare/v7in5_HD/epd7in5_HD.py | 487 +++++++++++++++--- .../hw/libs/waveshare/v7in5_v2/epd7in5_V2.py | 2 +- .../libs/waveshare/v7in5_v2/epd7in5_V2_old.py | 2 +- .../libs/waveshare/v7in5b_HD/epd7in5b_HD.py | 128 ++--- 9 files changed, 531 insertions(+), 193 deletions(-) diff --git a/pwnagotchi/ui/hw/libs/waveshare/v1in02/epd1in02.py b/pwnagotchi/ui/hw/libs/waveshare/v1in02/epd1in02.py index ae93437d..25fe7231 100644 --- a/pwnagotchi/ui/hw/libs/waveshare/v1in02/epd1in02.py +++ b/pwnagotchi/ui/hw/libs/waveshare/v1in02/epd1in02.py @@ -264,11 +264,11 @@ class EPD: def display(self, image): if (image == None): return - # Width = (self.width % 8 == 0)? (self.width / 8 ): (self.width / 8 + 1) + # Width = (self.width % 8 == 0)? (self.width // 8 ): (self.width // 8 + 1) if (self.width % 8 == 0): - Width = self.width / 8 + Width = self.width // 8 else: - Width = self.width / 8 + 1 + Width = self.width // 8 + 1 self.send_command(0x10) for j in range(0, self.height): @@ -282,11 +282,11 @@ class EPD: self.TurnOnDisplay() def Clear(self): - # Width = (self.width % 8 == 0)? (self.width / 8 ): (self.width / 8 + 1) + # Width = (self.width % 8 == 0)? (self.width // 8 ): (self.width // 8 + 1) if (self.width % 8 == 0): - Width = self.width / 8 + Width = self.width // 8 else: - Width = self.width / 8 + 1 + Width = self.width // 8 + 1 Height = self.height @@ -313,11 +313,11 @@ class EPD: self.send_data(127) # y-end self.send_data(0x00) - # Width = (self.width % 8 == 0)? (self.width / 8 ): (self.width / 8 + 1) + # Width = (self.width % 8 == 0)? (self.width // 8 ): (self.width // 8 + 1) if (self.width % 8 == 0): - Width = self.width / 8 + Width = self.width // 8 else: - Width = self.width / 8 + 1 + Width = self.width // 8 + 1 Height = self.height # send data diff --git a/pwnagotchi/ui/hw/libs/waveshare/v2in7_v2/epd2in7_V2.py b/pwnagotchi/ui/hw/libs/waveshare/v2in7_v2/epd2in7_V2.py index 4e786f0d..ae4e40a4 100644 --- a/pwnagotchi/ui/hw/libs/waveshare/v2in7_v2/epd2in7_V2.py +++ b/pwnagotchi/ui/hw/libs/waveshare/v2in7_v2/epd2in7_V2.py @@ -100,7 +100,7 @@ class EPD: def ReadBusy(self): logger.debug("e-Paper busy") - while epdconfig.digital_read(self.busy_pin) == 1: # 1: idle, 0: busy + while (epdconfig.digital_read(self.busy_pin) == 1): # 1: idle, 0: busy epdconfig.delay_ms(20) logger.debug("e-Paper busy release") @@ -134,7 +134,7 @@ class EPD: self.send_data(self.LUT_DATA_4Gray[i]) def init(self): - if epdconfig.module_init() != 0: + if (epdconfig.module_init() != 0): return -1 # EPD hardware init start @@ -159,7 +159,7 @@ class EPD: return 0 def init_Fast(self): - if epdconfig.module_init() != 0: + if (epdconfig.module_init() != 0): return -1 # EPD hardware init start @@ -204,12 +204,12 @@ class EPD: return 0 def Init_4Gray(self): - if epdconfig.module_init() != 0: + if (epdconfig.module_init() != 0): return -1 self.reset() self.send_command(0x12) # soft reset - self.ReadBusy() + self.ReadBusy(); self.send_command(0x74) # set analog block control self.send_data(0x54) @@ -268,14 +268,14 @@ class EPD: imwidth, imheight = image_monocolor.size pixels = image_monocolor.load() # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight) - if imwidth == self.width and imheight == self.height: + if (imwidth == self.width and imheight == self.height): logger.debug("Vertical") for y in range(imheight): for x in range(imwidth): # Set the bits for the column of pixels at the current position. if pixels[x, y] == 0: buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) - elif imwidth == self.height and imheight == self.width: + elif (imwidth == self.height and imheight == self.width): logger.debug("Horizontal") for y in range(imheight): for x in range(imwidth): @@ -293,40 +293,40 @@ class EPD: pixels = image_monocolor.load() i = 0 # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight) - if imwidth == self.width and imheight == self.height: + if (imwidth == self.width and imheight == self.height): logger.debug("Vertical") for y in range(imheight): for x in range(imwidth): # Set the bits for the column of pixels at the current position. - if pixels[x, y] == 0xC0: + if (pixels[x, y] == 0xC0): pixels[x, y] = 0x80 - elif pixels[x, y] == 0x80: + elif (pixels[x, y] == 0x80): pixels[x, y] = 0x40 i = i + 1 - if i % 4 == 0: + if (i % 4 == 0): buf[int((x + (y * self.width)) / 4)] = ( (pixels[x - 3, y] & 0xc0) | (pixels[x - 2, y] & 0xc0) >> 2 | ( pixels[x - 1, y] & 0xc0) >> 4 | (pixels[x, y] & 0xc0) >> 6) - elif imwidth == self.height and imheight == self.width: + elif (imwidth == self.height and imheight == self.width): logger.debug("Horizontal") for x in range(imwidth): for y in range(imheight): newx = y newy = self.height - x - 1 - if pixels[x, y] == 0xC0: + if (pixels[x, y] == 0xC0): pixels[x, y] = 0x80 - elif pixels[x, y] == 0x80: + elif (pixels[x, y] == 0x80): pixels[x, y] = 0x40 i = i + 1 - if i % 4 == 0: + if (i % 4 == 0): buf[int((newx + (newy * self.width)) / 4)] = ( (pixels[x, y - 3] & 0xc0) | (pixels[x, y - 2] & 0xc0) >> 2 | ( pixels[x, y - 1] & 0xc0) >> 4 | (pixels[x, y] & 0xc0) >> 6) return buf def Clear(self): - if self.width % 8 == 0: + if (self.width % 8 == 0): Width = self.width // 8 else: Width = self.width // 8 + 1 @@ -338,7 +338,7 @@ class EPD: self.TurnOnDisplay() def display(self, image): - if self.width % 8 == 0: + if (self.width % 8 == 0): Width = self.width // 8 else: Width = self.width // 8 + 1 @@ -350,7 +350,7 @@ class EPD: self.TurnOnDisplay() def display_Fast(self, image): - if self.width % 8 == 0: + if (self.width % 8 == 0): Width = self.width // 8 else: Width = self.width // 8 + 1 @@ -362,7 +362,7 @@ class EPD: self.TurnOnDisplay_Fast() def display_Base(self, image): - if self.width % 8 == 0: + if (self.width % 8 == 0): Width = self.width // 8 else: Width = self.width // 8 + 1 @@ -379,7 +379,7 @@ class EPD: self.TurnOnDisplay() def display_Base_color(self, color): - if self.width % 8 == 0: + if (self.width % 8 == 0): Width = self.width // 8 else: Width = self.width // 8 + 1 @@ -396,7 +396,8 @@ class EPD: # self.TurnOnDisplay() def display_Partial(self, Image, Xstart, Ystart, Xend, Yend): - if (Xstart % 8 + Xend % 8 == 8 & Xstart % 8 > Xend % 8) | Xstart % 8 + Xend % 8 == 0 | (Xend - Xstart) % 8 == 0: + if ((Xstart % 8 + Xend % 8 == 8 & Xstart % 8 > Xend % 8) | Xstart % 8 + Xend % 8 == 0 | ( + Xend - Xstart) % 8 == 0): Xstart = Xstart // 8 Xend = Xend // 8 else: @@ -439,23 +440,23 @@ class EPD: self.send_command(0x24) # Write Black and White image to RAM for j in range(Height): for i in range(Width): - if (j > Ystart - 1) & (j < (Yend + 1)) & (i > Xstart - 1) & (i < (Xend + 1)): + if ((j > Ystart - 1) & (j < (Yend + 1)) & (i > Xstart - 1) & (i < (Xend + 1))): self.send_data(Image[i + j * Width]) self.TurnOnDisplay_Partial() def display_4Gray(self, image): self.send_command(0x24) - for i in range(0, 5808): # 5808*4 46464 + for i in range(0, 48000): # 5808*4 46464 temp3 = 0 for j in range(0, 2): temp1 = image[i * 2 + j] for k in range(0, 2): temp2 = temp1 & 0xC0 - if temp2 == 0xC0: + if (temp2 == 0xC0): temp3 |= 0x00 - elif temp2 == 0x00: + elif (temp2 == 0x00): temp3 |= 0x01 - elif temp2 == 0x80: + elif (temp2 == 0x80): temp3 |= 0x01 else: # 0x40 temp3 |= 0x00 @@ -463,31 +464,31 @@ class EPD: temp1 <<= 2 temp2 = temp1 & 0xC0 - if temp2 == 0xC0: + if (temp2 == 0xC0): temp3 |= 0x00 - elif temp2 == 0x00: + elif (temp2 == 0x00): temp3 |= 0x01 - elif temp2 == 0x80: + elif (temp2 == 0x80): temp3 |= 0x01 else: # 0x40 temp3 |= 0x00 - if j != 1 or k != 1: + if (j != 1 or k != 1): temp3 <<= 1 temp1 <<= 2 self.send_data(temp3) self.send_command(0x26) - for i in range(0, 5808): # 5808*4 46464 + for i in range(0, 48000): # 5808*4 46464 temp3 = 0 for j in range(0, 2): temp1 = image[i * 2 + j] for k in range(0, 2): temp2 = temp1 & 0xC0 - if temp2 == 0xC0: + if (temp2 == 0xC0): temp3 |= 0x00 - elif temp2 == 0x00: + elif (temp2 == 0x00): temp3 |= 0x01 - elif temp2 == 0x80: + elif (temp2 == 0x80): temp3 |= 0x00 else: # 0x40 temp3 |= 0x01 @@ -495,15 +496,15 @@ class EPD: temp1 <<= 2 temp2 = temp1 & 0xC0 - if temp2 == 0xC0: + if (temp2 == 0xC0): temp3 |= 0x00 - elif temp2 == 0x00: + elif (temp2 == 0x00): temp3 |= 0x01 - elif temp2 == 0x80: + elif (temp2 == 0x80): temp3 |= 0x00 else: # 0x40 temp3 |= 0x01 - if j != 1 or k != 1: + if (j != 1 or k != 1): temp3 <<= 1 temp1 <<= 2 self.send_data(temp3) @@ -516,3 +517,5 @@ class EPD: epdconfig.delay_ms(2000) epdconfig.module_exit() + + ### END OF FILE ### \ No newline at end of file diff --git a/pwnagotchi/ui/hw/libs/waveshare/v2in9_v2/epd2in9V2.py b/pwnagotchi/ui/hw/libs/waveshare/v2in9_v2/epd2in9V2.py index 2f896373..b8a7a6a8 100644 --- a/pwnagotchi/ui/hw/libs/waveshare/v2in9_v2/epd2in9V2.py +++ b/pwnagotchi/ui/hw/libs/waveshare/v2in9_v2/epd2in9V2.py @@ -28,7 +28,7 @@ # import logging -from .. import epdconfig +from . import epdconfig # Display resolution EPD_WIDTH = 128 @@ -227,7 +227,7 @@ class EPD: self.send_data((y >> 8) & 0xFF) def init(self): - if epdconfig.module_init() != 0: + if (epdconfig.module_init() != 0): return -1 # EPD hardware init start self.reset() diff --git a/pwnagotchi/ui/hw/libs/waveshare/v2in9b_v4/epd2in9b_V4.py b/pwnagotchi/ui/hw/libs/waveshare/v2in9b_v4/epd2in9b_V4.py index d256cbe5..a5e904ee 100644 --- a/pwnagotchi/ui/hw/libs/waveshare/v2in9b_v4/epd2in9b_V4.py +++ b/pwnagotchi/ui/hw/libs/waveshare/v2in9b_v4/epd2in9b_V4.py @@ -184,7 +184,7 @@ class EPD: self.send_command(0x01) # Driver output control self.send_data((self.height - 1) % 256) - self.send_data((self.height - 1) / 256) + self.send_data((self.height - 1) // 256) self.send_data(0x00) self.send_command(0x11) # data entry mode diff --git a/pwnagotchi/ui/hw/libs/waveshare/v4in26/epd4in26.py b/pwnagotchi/ui/hw/libs/waveshare/v4in26/epd4in26.py index 8da379bd..4a698567 100644 --- a/pwnagotchi/ui/hw/libs/waveshare/v4in26/epd4in26.py +++ b/pwnagotchi/ui/hw/libs/waveshare/v4in26/epd4in26.py @@ -29,7 +29,7 @@ import logging -from .. import epdconfig +from . import epdconfig # Display resolution EPD_WIDTH = 800 diff --git a/pwnagotchi/ui/hw/libs/waveshare/v7in5_HD/epd7in5_HD.py b/pwnagotchi/ui/hw/libs/waveshare/v7in5_HD/epd7in5_HD.py index e42307ed..4a698567 100644 --- a/pwnagotchi/ui/hw/libs/waveshare/v7in5_HD/epd7in5_HD.py +++ b/pwnagotchi/ui/hw/libs/waveshare/v7in5_HD/epd7in5_HD.py @@ -1,11 +1,11 @@ # ***************************************************************************** -# * | File : epd7in5.py +# * | File : epd4in26.py # * | Author : Waveshare team # * | Function : Electronic paper driver # * | Info : # *---------------- -# * | This version: V4.0 -# * | Date : 2019-06-20 +# * | This version: V1.0 +# * | Date : 2023-12-20 # # | Info : python demo # ----------------------------------------------------------------------------- # Permission is hereby granted, free of charge, to any person obtaining a copy @@ -29,11 +29,16 @@ import logging -from .. import epdconfig +from . import epdconfig # Display resolution -EPD_WIDTH = 880 -EPD_HEIGHT = 528 +EPD_WIDTH = 800 +EPD_HEIGHT = 480 + +GRAY1 = 0xff # white +GRAY2 = 0xC0 +GRAY3 = 0x80 # gray +GRAY4 = 0x00 # Blackest logger = logging.getLogger(__name__) @@ -46,15 +51,39 @@ class EPD: self.cs_pin = epdconfig.CS_PIN self.width = EPD_WIDTH self.height = EPD_HEIGHT + self.GRAY1 = GRAY1 # white + self.GRAY2 = GRAY2 + self.GRAY3 = GRAY3 # gray + self.GRAY4 = GRAY4 # Blackest + + LUT_DATA_4Gray = [ # #112bytes + 0x80, 0x48, 0x4A, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0A, 0x48, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x88, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xA8, 0x48, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x07, 0x1E, 0x1C, 0x02, 0x00, + 0x05, 0x01, 0x05, 0x01, 0x02, + 0x08, 0x01, 0x01, 0x04, 0x04, + 0x00, 0x02, 0x00, 0x02, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, + 0x22, 0x22, 0x22, 0x22, 0x22, + 0x17, 0x41, 0xA8, 0x32, 0x30, + 0x00, 0x00] # Hardware reset def reset(self): epdconfig.digital_write(self.reset_pin, 1) - epdconfig.delay_ms(200) + epdconfig.delay_ms(20) epdconfig.digital_write(self.reset_pin, 0) epdconfig.delay_ms(2) epdconfig.digital_write(self.reset_pin, 1) - epdconfig.delay_ms(200) + epdconfig.delay_ms(20) def send_command(self, command): epdconfig.digital_write(self.dc_pin, 0) @@ -71,7 +100,7 @@ class EPD: def send_data2(self, data): epdconfig.digital_write(self.dc_pin, 1) epdconfig.digital_write(self.cs_pin, 0) - epdconfig.spi_writebyte2(data) + epdconfig.SPI.writebytes2(data) epdconfig.digital_write(self.cs_pin, 1) def ReadBusy(self): @@ -79,103 +108,409 @@ class EPD: busy = epdconfig.digital_read(self.busy_pin) while (busy == 1): busy = epdconfig.digital_read(self.busy_pin) - epdconfig.delay_ms(200) + epdconfig.delay_ms(20) + epdconfig.delay_ms(20) + logger.debug("e-Paper busy release") + + def TurnOnDisplay(self): + self.send_command(0x22) # Display Update Control + self.send_data(0xF7) + self.send_command(0x20) # Activate Display Update Sequence + self.ReadBusy() + + def TurnOnDisplay_Fast(self): + self.send_command(0x22) # Display Update Control + self.send_data(0xC7) + self.send_command(0x20) # Activate Display Update Sequence + self.ReadBusy() + + def TurnOnDisplay_Part(self): + self.send_command(0x22) # Display Update Control + self.send_data(0xFF) + self.send_command(0x20) # Activate Display Update Sequence + self.ReadBusy() + + def TurnOnDisplay_4GRAY(self): + self.send_command(0x22) # Display Update Control + self.send_data(0xC7) + self.send_command(0x20) # Activate Display Update Sequence + self.ReadBusy() + + ''' + function : Setting the display window + parameter: + xstart : X-axis starting position + ystart : Y-axis starting position + xend : End position of X-axis + yend : End position of Y-axis + ''' + + def SetWindow(self, x_start, y_start, x_end, y_end): + self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION + self.send_data(x_start & 0xFF) + self.send_data((x_start >> 8) & 0x03) + self.send_data(x_end & 0xFF) + self.send_data((x_end >> 8) & 0x03) + + self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION + self.send_data(y_start & 0xFF) + self.send_data((y_start >> 8) & 0xFF) + self.send_data(y_end & 0xFF) + self.send_data((y_end >> 8) & 0xFF) + + ''' + function : Set Cursor + parameter: + x : X-axis starting position + y : Y-axis starting position + ''' + + def SetCursor(self, x, y): + self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER + # x point must be the multiple of 8 or the last 3 bits will be ignored + self.send_data(x & 0xFF) + self.send_data((x >> 8) & 0x03) + + self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER + self.send_data(y & 0xFF) + self.send_data((y >> 8) & 0xFF) def init(self): if (epdconfig.module_init() != 0): return -1 # EPD hardware init start self.reset() + self.ReadBusy() - self.ReadBusy(); - self.send_command(0x12); # SWRESET - self.ReadBusy(); + self.send_command(0x12) # SWRESET + self.ReadBusy() - self.send_command(0x46); # Auto Write Red RAM - self.send_data(0xf7); - self.ReadBusy(); - self.send_command(0x47); # Auto Write B/W RAM - self.send_data(0xf7); - self.ReadBusy(); + self.send_command(0x18) # use the internal temperature sensor + self.send_data(0x80) - self.send_command(0x0C); # Soft start setting - self.send_data2([0xAE, 0xC7, 0xC3, 0xC0, 0x40]) + self.send_command(0x0C) # set soft start + self.send_data(0xAE) + self.send_data(0xC7) + self.send_data(0xC3) + self.send_data(0xC0) + self.send_data(0x80) - self.send_command(0x01); # Set MUX as 527 - self.send_data2([0xAF, 0x02, 0x01]) + self.send_command(0x01) # drive output control + self.send_data((self.height - 1) % 256) # Y + self.send_data((self.height - 1) // 256) # Y + self.send_data(0x02) - self.send_command(0x11); # Data entry mode - self.send_data(0x01); + self.send_command(0x3C) # Border Border setting + self.send_data(0x01) - self.send_command(0x44); - self.send_data2([0x00, 0x00, 0x6F, 0x03]) # RAM x address start at 0 - self.send_command(0x45); - self.send_data2([0xAF, 0x02, 0x00, 0x00]) + self.send_command(0x11) # data entry mode + self.send_data(0x01) # X-mode x+ y- - self.send_command(0x3C); # VBD - self.send_data(0x05); # LUT1, for white + self.SetWindow(0, self.height - 1, self.width - 1, 0) - self.send_command(0x18); - self.send_data(0X80); + self.SetCursor(0, 0) + self.ReadBusy() - self.send_command(0x22); - self.send_data(0XB1); # Load Temperature and waveform setting. - self.send_command(0x20); - self.ReadBusy(); + # EPD hardware init end + return 0 - self.send_command(0x4E); # set RAM x address count to 0; - self.send_data2([0x00, 0x00]) - self.send_command(0x4F); - self.send_data2([0x00, 0x00]) + def init_Fast(self): + if (epdconfig.module_init() != 0): + return -1 + # EPD hardware init start + self.reset() + self.ReadBusy() + + self.send_command(0x12) # SWRESET + self.ReadBusy() + + self.send_command(0x18) # use the internal temperature sensor + self.send_data(0x80) + + self.send_command(0x0C) # set soft start + self.send_data(0xAE) + self.send_data(0xC7) + self.send_data(0xC3) + self.send_data(0xC0) + self.send_data(0x80) + + self.send_command(0x01) # drive output control + self.send_data((self.height - 1) % 256) # Y + self.send_data((self.height - 1) // 256) # Y + self.send_data(0x02) + + self.send_command(0x3C) # Border Border setting + self.send_data(0x01) + + self.send_command(0x11) # data entry mode + self.send_data(0x01) # X-mode x+ y- + + self.SetWindow(0, self.height - 1, self.width - 1, 0) + + self.SetCursor(0, 0) + self.ReadBusy() + + # TEMP (1.5s) + self.send_command(0x1A) + self.send_data(0x5A) + + self.send_command(0x22) + self.send_data(0x91) + self.send_command(0x20) + + self.ReadBusy() + + # EPD hardware init end + return 0 + + def Lut(self): + self.send_command(0x32) + for count in range(0, 105): + self.send_data(self.LUT_DATA_4Gray[count]) + + self.send_command(0x03) # VGH + self.send_data(self.LUT_DATA_4Gray[105]) + + self.send_command(0x04) # + self.send_data(self.LUT_DATA_4Gray[106]) # VSH1 + self.send_data(self.LUT_DATA_4Gray[107]) # VSH2 + self.send_data(self.LUT_DATA_4Gray[108]) # VSL + + self.send_command(0x2C) # VCOM Voltage + self.send_data(self.LUT_DATA_4Gray[109]) # 0x1C + + def init_4GRAY(self): + if (epdconfig.module_init() != 0): + return -1 + # EPD hardware init start + self.reset() + self.ReadBusy() + + self.send_command(0x12) # SWRESET + self.ReadBusy() + + self.send_command(0x18) # use the internal temperature sensor + self.send_data(0x80) + + self.send_command(0x0C) # set soft start + self.send_data(0xAE) + self.send_data(0xC7) + self.send_data(0xC3) + self.send_data(0xC0) + self.send_data(0x80) + + self.send_command(0x01) # drive output control + self.send_data((self.height - 1) % 256) # Y + self.send_data((self.height - 1) // 256) # Y + self.send_data(0x02) + + self.send_command(0x3C) # Border Border setting + self.send_data(0x01) + + self.send_command(0x11) # data entry mode + self.send_data(0x01) # X-mode x+ y- + + self.SetWindow(0, self.height - 1, self.width - 1, 0) + + self.SetCursor(0, 0) + self.ReadBusy() + + self.Lut() # EPD hardware init end return 0 def getbuffer(self, image): - img = image - imwidth, imheight = img.size - if (imwidth == self.width and imheight == self.height): - img = img.convert('1') - elif (imwidth == self.height and imheight == self.width): - img = img.rotate(90, expand=True).convert('1') - else: - logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height)) - # return a blank buffer - return [0xff] * int(self.width * self.height / 8) + # logger.debug("bufsiz = ",int(self.width/8) * self.height) + buf = [0xFF] * (int(self.width / 8) * self.height) + image_monocolor = image.convert('1') + imwidth, imheight = image_monocolor.size + pixels = image_monocolor.load() + # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight) + if imwidth == self.width and imheight == self.height: + logger.debug("Horizontal") + for y in range(imheight): + for x in range(imwidth): + # Set the bits for the column of pixels at the current position. + if pixels[x, y] == 0: + buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) + elif imwidth == self.height and imheight == self.width: + logger.debug("Vertical") + for y in range(imheight): + for x in range(imwidth): + newx = y + newy = self.height - x - 1 + if pixels[x, y] == 0: + buf[int((newx + newy * self.width) / 8)] &= ~(0x80 >> (y % 8)) + return buf - buf = bytearray(img.tobytes('raw')) + def getbuffer_4Gray(self, image): + # logger.debug("bufsiz = ",int(self.width/8) * self.height) + buf = [0xFF] * (int(self.width / 4) * self.height) + image_monocolor = image.convert('L') + imwidth, imheight = image_monocolor.size + pixels = image_monocolor.load() + i = 0 + # logger.debug("imwidth = %d, imheight = %d",imwidth,imheight) + if (imwidth == self.width and imheight == self.height): + logger.debug("Vertical") + for y in range(imheight): + for x in range(imwidth): + # Set the bits for the column of pixels at the current position. + if (pixels[x, y] == 0xC0): + pixels[x, y] = 0x80 + elif (pixels[x, y] == 0x80): + pixels[x, y] = 0x40 + i = i + 1 + if (i % 4 == 0): + buf[int((x + (y * self.width)) / 4)] = ( + (pixels[x - 3, y] & 0xc0) | (pixels[x - 2, y] & 0xc0) >> 2 | ( + pixels[x - 1, y] & 0xc0) >> 4 | (pixels[x, y] & 0xc0) >> 6) + + elif (imwidth == self.height and imheight == self.width): + logger.debug("Horizontal") + for x in range(imwidth): + for y in range(imheight): + newx = y + newy = self.height - x - 1 + if (pixels[x, y] == 0xC0): + pixels[x, y] = 0x80 + elif (pixels[x, y] == 0x80): + pixels[x, y] = 0x40 + i = i + 1 + if (i % 4 == 0): + buf[int((newx + (newy * self.width)) / 4)] = ( + (pixels[x, y - 3] & 0xc0) | (pixels[x, y - 2] & 0xc0) >> 2 | ( + pixels[x, y - 1] & 0xc0) >> 4 | (pixels[x, y] & 0xc0) >> 6) return buf def display(self, image): - self.send_command(0x4F); - self.send_data2([0x00, 0x00]) - self.send_command(0x24); - self.send_data2(image) - self.send_command(0x22); - self.send_data(0xF7); # Load LUT from MCU(0x32) - self.send_command(0x20); - epdconfig.delay_ms(10); - self.ReadBusy(); - - def Clear(self): - buf = [0xff] * int(self.width * self.height / 8) - self.send_command(0x4F); - self.send_data2([0x00, 0x00]) self.send_command(0x24) - self.send_data2(buf) + self.send_data2(image) + + self.TurnOnDisplay() + + def display_Base(self, image): + self.send_command(0x24) + self.send_data2(image) self.send_command(0x26) - self.send_data2(buf) + self.send_data2(image) - self.send_command(0x22); - self.send_data(0xF7); # Load LUT from MCU(0x32) - self.send_command(0x20); - epdconfig.delay_ms(10); - self.ReadBusy(); + self.TurnOnDisplay() + + def display_Fast(self, image): + self.send_command(0x24) + self.send_data2(image) + + self.TurnOnDisplay_Fast() + + def display_Partial(self, Image): + + # Reset + self.reset() + + self.send_command(0x18) # BorderWavefrom + self.send_data(0x80) + + self.send_command(0x3C) # BorderWavefrom + self.send_data(0x80) + + self.send_command(0x01) # drive output control + self.send_data((self.height - 1) % 256) # Y + self.send_data((self.height - 1) // 256) # Y + + self.send_command(0x11) # data entry mode + self.send_data(0x01) # X-mode x+ y- + + self.SetWindow(0, self.height - 1, self.width - 1, 0) + + self.SetCursor(0, 0) + + self.send_command(0x24) # Write Black and White image to RAM + self.send_data2(Image) + + self.TurnOnDisplay_Part() + + def display_4Gray(self, image): + self.send_command(0x24) + for i in range(0, 48000): # 5808*4 46464 + temp3 = 0 + for j in range(0, 2): + temp1 = image[i * 2 + j] + for k in range(0, 2): + temp2 = temp1 & 0xC0 + if (temp2 == 0xC0): + temp3 |= 0x00 + elif (temp2 == 0x00): + temp3 |= 0x01 + elif (temp2 == 0x80): + temp3 |= 0x01 + else: # 0x40 + temp3 |= 0x00 + temp3 <<= 1 + + temp1 <<= 2 + temp2 = temp1 & 0xC0 + if (temp2 == 0xC0): + temp3 |= 0x00 + elif (temp2 == 0x00): + temp3 |= 0x01 + elif (temp2 == 0x80): + temp3 |= 0x01 + else: # 0x40 + temp3 |= 0x00 + if (j != 1 or k != 1): + temp3 <<= 1 + temp1 <<= 2 + self.send_data(temp3) + + self.send_command(0x26) + for i in range(0, 48000): # 5808*4 46464 + temp3 = 0 + for j in range(0, 2): + temp1 = image[i * 2 + j] + for k in range(0, 2): + temp2 = temp1 & 0xC0 + if (temp2 == 0xC0): + temp3 |= 0x00 + elif (temp2 == 0x00): + temp3 |= 0x01 + elif (temp2 == 0x80): + temp3 |= 0x00 + else: # 0x40 + temp3 |= 0x01 + temp3 <<= 1 + + temp1 <<= 2 + temp2 = temp1 & 0xC0 + if (temp2 == 0xC0): + temp3 |= 0x00 + elif (temp2 == 0x00): + temp3 |= 0x01 + elif (temp2 == 0x80): + temp3 |= 0x00 + else: # 0x40 + temp3 |= 0x01 + if (j != 1 or k != 1): + temp3 <<= 1 + temp1 <<= 2 + self.send_data(temp3) + + self.TurnOnDisplay_4GRAY() + + def Clear(self): + self.send_command(0x24) + self.send_data2([0xFF] * (int(self.width / 8) * self.height)) + + self.send_command(0x26) + self.send_data2([0xFF] * (int(self.width / 8) * self.height)) + + self.TurnOnDisplay() def sleep(self): - self.send_command(0x10); - self.send_data(0x01); + self.send_command(0x10) # DEEP_SLEEP + self.send_data(0x01) epdconfig.delay_ms(2000) epdconfig.module_exit() -### END OF FILE ### +### END OF FILE ### \ No newline at end of file diff --git a/pwnagotchi/ui/hw/libs/waveshare/v7in5_v2/epd7in5_V2.py b/pwnagotchi/ui/hw/libs/waveshare/v7in5_v2/epd7in5_V2.py index d122149d..60c38762 100644 --- a/pwnagotchi/ui/hw/libs/waveshare/v7in5_v2/epd7in5_V2.py +++ b/pwnagotchi/ui/hw/libs/waveshare/v7in5_v2/epd7in5_V2.py @@ -243,7 +243,7 @@ class EPD: else: Xend = Xend // 8 * 8 + 1 - Width = (Xend - Xstart) / 8 + Width = (Xend - Xstart) // 8 Height = Yend - Ystart self.send_command(0x50) diff --git a/pwnagotchi/ui/hw/libs/waveshare/v7in5_v2/epd7in5_V2_old.py b/pwnagotchi/ui/hw/libs/waveshare/v7in5_v2/epd7in5_V2_old.py index 54bef805..3d8c6c25 100644 --- a/pwnagotchi/ui/hw/libs/waveshare/v7in5_v2/epd7in5_V2_old.py +++ b/pwnagotchi/ui/hw/libs/waveshare/v7in5_v2/epd7in5_V2_old.py @@ -484,7 +484,7 @@ class EPD: else: Xend = Xend // 8 * 8 + 1 - Width = (Xend - Xstart) / 8 + Width = (Xend - Xstart) // 8 Height = Yend - Ystart self.send_command(0x50) diff --git a/pwnagotchi/ui/hw/libs/waveshare/v7in5b_HD/epd7in5b_HD.py b/pwnagotchi/ui/hw/libs/waveshare/v7in5b_HD/epd7in5b_HD.py index a1a24827..fc8a5b3c 100644 --- a/pwnagotchi/ui/hw/libs/waveshare/v7in5b_HD/epd7in5b_HD.py +++ b/pwnagotchi/ui/hw/libs/waveshare/v7in5b_HD/epd7in5b_HD.py @@ -81,59 +81,59 @@ class EPD: self.reset() - self.send_command(0x12); # SWRESET - self.ReadBusy(); # waiting for the electronic paper IC to release the idle signal + self.send_command(0x12) # SWRESET + self.ReadBusy() # waiting for the electronic paper IC to release the idle signal - self.send_command(0x46); # Auto Write RAM - self.send_data(0xF7); - self.ReadBusy(); # waiting for the electronic paper IC to release the idle signal + self.send_command(0x46) # Auto Write RAM + self.send_data(0xF7) + self.ReadBusy() # waiting for the electronic paper IC to release the idle signal - self.send_command(0x47); # Auto Write RAM - self.send_data(0xF7); - self.ReadBusy(); # waiting for the electronic paper IC to release the idle signal + self.send_command(0x47) # Auto Write RAM + self.send_data(0xF7) + self.ReadBusy() # waiting for the electronic paper IC to release the idle signal - self.send_command(0x0C); # Soft start setting - self.send_data(0xAE); - self.send_data(0xC7); - self.send_data(0xC3); - self.send_data(0xC0); - self.send_data(0x40); + self.send_command(0x0C) # Soft start setting + self.send_data(0xAE) + self.send_data(0xC7) + self.send_data(0xC3) + self.send_data(0xC0) + self.send_data(0x40) - self.send_command(0x01); # Set MUX as 527 - self.send_data(0xAF); - self.send_data(0x02); - self.send_data(0x01); + self.send_command(0x01) # Set MUX as 527 + self.send_data(0xAF) + self.send_data(0x02) + self.send_data(0x01) - self.send_command(0x11); # Data entry mode - self.send_data(0x01); + self.send_command(0x11) # Data entry mode + self.send_data(0x01) - self.send_command(0x44); - self.send_data(0x00); # RAM x address start at 0 - self.send_data(0x00); - self.send_data(0x6F); # RAM x address end at 36Fh -> 879 - self.send_data(0x03); - self.send_command(0x45); - self.send_data(0xAF); # RAM y address start at 20Fh; - self.send_data(0x02); - self.send_data(0x00); # RAM y address end at 00h; - self.send_data(0x00); + self.send_command(0x44) + self.send_data(0x00) # RAM x address start at 0 + self.send_data(0x00) + self.send_data(0x6F) # RAM x address end at 36Fh -> 879 + self.send_data(0x03) + self.send_command(0x45) + self.send_data(0xAF) # RAM y address start at 20Fh + self.send_data(0x02) + self.send_data(0x00) # RAM y address end at 00h + self.send_data(0x00) - self.send_command(0x3C); # VBD - self.send_data(0x01); # LUT1, for white + self.send_command(0x3C) # VBD + self.send_data(0x01) # LUT1, for white - self.send_command(0x18); - self.send_data(0X80); - self.send_command(0x22); - self.send_data(0XB1); # Load Temperature and waveform setting. - self.send_command(0x20); - self.ReadBusy(); # waiting for the electronic paper IC to release the idle signal + self.send_command(0x18) + self.send_data(0X80) + self.send_command(0x22) + self.send_data(0XB1) # Load Temperature and waveform setting. + self.send_command(0x20) + self.ReadBusy() # waiting for the electronic paper IC to release the idle signal - self.send_command(0x4E); - self.send_data(0x00); - self.send_data(0x00); - self.send_command(0x4F); - self.send_data(0xAF); - self.send_data(0x02); + self.send_command(0x4E) + self.send_data(0x00) + self.send_data(0x00) + self.send_command(0x4F) + self.send_data(0xAF) + self.send_data(0x02) return 0 @@ -162,44 +162,44 @@ class EPD: return buf def display(self, imageblack, imagered): - self.send_command(0x4F); - self.send_data(0xAf); + self.send_command(0x4F) + self.send_data(0xAf) self.send_command(0x24) for i in range(0, int(self.width * self.height / 8)): - self.send_data(imageblack[i]); + self.send_data(imageblack[i]) self.send_command(0x26) for i in range(0, int(self.width * self.height / 8)): - self.send_data(~imagered[i]); + self.send_data(~imagered[i]) - self.send_command(0x22); - self.send_data(0xC7); # Load LUT from MCU(0x32) - self.send_command(0x20); - epdconfig.delay_ms(200); # !!!The delay here is necessary, 200uS at least!!! - self.ReadBusy(); + self.send_command(0x22) + self.send_data(0xC7) # Load LUT from MCU(0x32) + self.send_command(0x20) + epdconfig.delay_ms(200) # !!!The delay here is necessary, 200uS at least!!! + self.ReadBusy() def Clear(self): - self.send_command(0x4F); - self.send_data(0xAf); + self.send_command(0x4F) + self.send_data(0xAf) self.send_command(0x24) for i in range(0, int(self.width * self.height / 8)): - self.send_data(0xff); + self.send_data(0xff) self.send_command(0x26) for i in range(0, int(self.width * self.height / 8)): - self.send_data(0x00); + self.send_data(0x00) - self.send_command(0x22); - self.send_data(0xC7); # Load LUT from MCU(0x32) - self.send_command(0x20); - epdconfig.delay_ms(200); # !!!The delay here is necessary, 200uS at least!!! - self.ReadBusy(); + self.send_command(0x22) + self.send_data(0xC7) # Load LUT from MCU(0x32) + self.send_command(0x20) + epdconfig.delay_ms(200) # !!!The delay here is necessary, 200uS at least!!! + self.ReadBusy() def sleep(self): - self.send_command(0x10); # deep sleep - self.send_data(0x01); + self.send_command(0x10) # deep sleep + self.send_data(0x01) epdconfig.delay_ms(2000) epdconfig.module_exit()