From 039f94aeecbfaa58163d921d52f0a70812613545 Mon Sep 17 00:00:00 2001 From: ladyada Date: Fri, 27 Sep 2019 23:39:42 -0400 Subject: [PATCH 01/18] fix simpletest 2.13" mono --- examples/epd_simpletest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/epd_simpletest.py b/examples/epd_simpletest.py index 858704a..2f6052d 100644 --- a/examples/epd_simpletest.py +++ b/examples/epd_simpletest.py @@ -19,7 +19,7 @@ # give them all to our driver print("Creating display") #display = Adafruit_SSD1608(200, 200, spi, # 1.54" HD mono display -#display = Adafruit_SSD1675(250, 122, spi, # 2.13" HD mono display +#display = Adafruit_SSD1675(122, 250, spi, # 2.13" HD mono display #display = Adafruit_IL91874(176, 264, spi, # 2.7" Tri-color display #display = Adafruit_IL0373(152, 152, spi, # 1.54" Tri-color display #display = Adafruit_IL0373(128, 296, spi, # 2.9" Tri-color display From 30434cc6c3e267e69e4c2338d5e332e79c07b48c Mon Sep 17 00:00:00 2001 From: ladyada Date: Fri, 27 Sep 2019 23:41:26 -0400 Subject: [PATCH 02/18] add missing displays --- examples/epd_bitmap.py | 13 ++++++++----- examples/epd_blinka.py | 12 +++++++++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/examples/epd_bitmap.py b/examples/epd_bitmap.py index c1b1536..9591469 100644 --- a/examples/epd_bitmap.py +++ b/examples/epd_bitmap.py @@ -6,6 +6,8 @@ from adafruit_epd.il91874 import Adafruit_IL91874 # pylint: disable=unused-import from adafruit_epd.il0398 import Adafruit_IL0398 # pylint: disable=unused-import from adafruit_epd.ssd1608 import Adafruit_SSD1608 # pylint: disable=unused-import +from adafruit_epd.ssd1675 import Adafruit_SSD1675 # pylint: disable=unused-import + # create the spi device and pins we will need spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) @@ -17,12 +19,13 @@ # give them all to our driver print("Creating display") -#display = Adafruit_SSD1608(200, 200, spi, # 1.54" HD mono display -#display = Adafruit_IL91874(176, 264, spi, # 2.7" Tri-color display +#display = Adafruit_SSD1608(200, 200, spi, # 1.54" HD mono display +#display = Adafruit_SSD1675(122, 250, spi, # 2.13" HD mono display +#display = Adafruit_IL91874(176, 264, spi, # 2.7" Tri-color display #display = Adafruit_IL0373(152, 152, spi, # 1.54" Tri-color display -#display = Adafruit_IL0373(128, 296, spi, # 2.9" Tri-color display -#display = Adafruit_IL0398(400, 300, spi, # 4.2" Tri-color display -display = Adafruit_IL0373(104, 212, spi, # 2.13" Tri-color display +#display = Adafruit_IL0373(128, 296, spi, # 2.9" Tri-color display +#display = Adafruit_IL0398(400, 300, spi, # 4.2" Tri-color display +display = Adafruit_IL0373(104, 212, spi, # 2.13" Tri-color display cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs, rst_pin=rst, busy_pin=busy) diff --git a/examples/epd_blinka.py b/examples/epd_blinka.py index 8b9b57a..a6b592c 100644 --- a/examples/epd_blinka.py +++ b/examples/epd_blinka.py @@ -7,6 +7,10 @@ from PIL import ImageFont from adafruit_epd.epd import Adafruit_EPD from adafruit_epd.il0373 import Adafruit_IL0373 +from adafruit_epd.il91874 import Adafruit_IL91874 # pylint: disable=unused-import +from adafruit_epd.il0398 import Adafruit_IL0398 # pylint: disable=unused-import +from adafruit_epd.ssd1608 import Adafruit_SSD1608 # pylint: disable=unused-import +from adafruit_epd.ssd1675 import Adafruit_SSD1675 # pylint: disable=unused-import # create the spi device and pins we will need spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) @@ -20,7 +24,13 @@ # give them all to our driver print("Creating display") -display = Adafruit_IL0373(104, 212, spi, +#display = Adafruit_SSD1608(200, 200, spi, # 1.54" HD mono display +#display = Adafruit_SSD1675(122, 250, spi, # 2.13" HD mono display +#display = Adafruit_IL91874(176, 264, spi, # 2.7" Tri-color display +#display = Adafruit_IL0373(152, 152, spi, # 1.54" Tri-color display +#display = Adafruit_IL0373(128, 296, spi, # 2.9" Tri-color display +#display = Adafruit_IL0398(400, 300, spi, # 4.2" Tri-color display +display = Adafruit_IL0373(104, 212, spi, # 2.13" Tri-color display cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs, rst_pin=rst, busy_pin=busy) From 432dacf019f9d4d06ff2c9db1c69e60813a4092b Mon Sep 17 00:00:00 2001 From: ladyada Date: Sat, 28 Sep 2019 00:12:52 -0400 Subject: [PATCH 03/18] fix image(), working now. blinka demo improvements --- adafruit_epd/epd.py | 31 +++++++++++++------------------ examples/epd_blinka.py | 25 +++++++++++++++---------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/adafruit_epd/epd.py b/adafruit_epd/epd.py index 39afa09..0f96511 100644 --- a/adafruit_epd/epd.py +++ b/adafruit_epd/epd.py @@ -340,24 +340,19 @@ def image(self, image): if imwidth != self.width or imheight != self.height: raise ValueError('Image must be same dimensions as display ({0}x{1}).' \ .format(self.width, self.height)) + if self.sram: + raise RuntimeError("PIL image is not for use with SRAM assist") # Grab all the pixels from the image, faster than getpixel. pix = image.load() - - for y in iter(range(image.size[1])): - for x in iter(range(image.size[0])): - if x == 0: - x = 1 + # clear out any display buffers + self.fill(Adafruit_EPD.WHITE) + + for y in range(image.size[1]): + for x in range(image.size[0]): pixel = pix[x, y] - - addr = int(((self._width - x) * self._height + y)/8) - - if pixel == (0xFF, 0, 0): - addr = addr + self._buffer1_size - current = self.sram.read8(addr) - - if pixel in ((0xFF, 0, 0), (0, 0, 0)): - current = current & ~(1 << (7 - y%8)) - else: - current = current | (1 << (7 - y%8)) - - self.sram.write8(addr, current) + if (pixel[0] >= 0x80) and (pixel[1] < 0x80) and (pixel[2] < 0x80): + # reddish + self.pixel(x, y, Adafruit_EPD.RED) + elif (pixel[0] < 0x80) and (pixel[1] < 0x80) and (pixel[2] < 0x80): + # dark + self.pixel(x, y, Adafruit_EPD.BLACK) diff --git a/examples/epd_blinka.py b/examples/epd_blinka.py index a6b592c..33dc719 100644 --- a/examples/epd_blinka.py +++ b/examples/epd_blinka.py @@ -15,11 +15,14 @@ # create the spi device and pins we will need spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) -ecs = digitalio.DigitalInOut(board.D22) -dc = digitalio.DigitalInOut(board.D13) -srcs = digitalio.DigitalInOut(board.D6) -rst = digitalio.DigitalInOut(board.D19) -busy = digitalio.DigitalInOut(board.D26) +# create the spi device and pins we will need +spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) +ecs = digitalio.DigitalInOut(board.D4) +dc = digitalio.DigitalInOut(board.D5) +srcs = None +rst = digitalio.DigitalInOut(board.D6) # can be None to not use this pin +busy = digitalio.DigitalInOut(board.D7) # can be None to not use this pin + # give them all to our driver @@ -34,7 +37,7 @@ cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs, rst_pin=rst, busy_pin=busy) - +display.rotation = 3 # Create blank image for drawing. # Make sure to create image with mode '1' for 1-bit color. width = display.width @@ -50,13 +53,15 @@ # Get drawing object to draw on image. draw = ImageDraw.Draw(image) +# empty it +draw.rectangle((0, 0, width, height), fill=WHITE) -# Draw a white filled box to clear the image. -draw.rectangle((0,0,width,height), outline=BLACK, fill=WHITE) +# Draw an outline box +draw.rectangle((1, 1, width-2, height-2), outline=BLACK, fill=WHITE) # Draw some shapes. # First define some constants to allow easy resizing of shapes. -padding = 2 +padding = 5 shape_width = 30 top = padding bottom = height-padding @@ -78,7 +83,7 @@ x += shape_width+padding # Load default font. -font = ImageFont.load_default() +font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 20) # Alternatively load a TTF font. Make sure the .ttf font # file is in the same directory as the python script! From 3090292ce706e8770f6fdccb9523968fa0f1c51e Mon Sep 17 00:00:00 2001 From: ladyada Date: Sat, 28 Sep 2019 03:14:28 -0400 Subject: [PATCH 04/18] start of ssd1681 driver --- adafruit_epd/ssd1681.py | 177 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 adafruit_epd/ssd1681.py diff --git a/adafruit_epd/ssd1681.py b/adafruit_epd/ssd1681.py new file mode 100644 index 0000000..f3bf35e --- /dev/null +++ b/adafruit_epd/ssd1681.py @@ -0,0 +1,177 @@ +# The MIT License (MIT) +# +# Copyright (c) 2018 Dean Miller for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_epd.ssd1681` - Adafruit SSD1681 - ePaper display driver +==================================================================================== +CircuitPython driver for Adafruit SSD1681 display breakouts +* Author(s): Dean Miller, Ladyada +""" + +import time +from micropython import const +import adafruit_framebuf +from adafruit_epd.epd import Adafruit_EPD + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_EPD.git" + +_SSD1681_DRIVER_CONTROL = const(0x01) +_SSD1681_GATE_VOLTAGE = const(0x03) +_SSD1681_SOURCE_VOLTAGE = const(0x04) +_SSD1681_INIT_SETTING = const(0x08) +_SSD1681_INIT_WRITE_REG = const(0x09) +_SSD1681_INIT_READ_REG = const(0x0A) +_SSD1681_BOOSTER_SOFT_START = const(0x0C) +_SSD1681_DEEP_SLEEP = const(0x10) +_SSD1681_DATA_MODE = const(0x11) +_SSD1681_SW_RESET = const(0x12) +_SSD1681_HV_DETECT = const(0x14) +_SSD1681_VCI_DETECT = const(0x15) +_SSD1681_TEMP_CONTROL = const(0x18) +_SSD1681_TEMP_WRITE = const(0x1A) +_SSD1681_TEMP_READ = const(0x1B) +_SSD1681_EXTTEMP_WRITE = const(0x1C) +_SSD1681_MASTER_ACTIVATE = const(0x20) +_SSD1681_DISP_CTRL1 = const(0x21) +_SSD1681_DISP_CTRL2 = const(0x22) +_SSD1681_WRITE_BWRAM = const(0x24) +_SSD1681_WRITE_REDRAM = const(0x26) +_SSD1681_READ_RAM = const(0x27) +_SSD1681_VCOM_SENSE = const(0x28) +_SSD1681_VCOM_DURATION = const(0x29) +_SSD1681_WRITE_VCOM_OTP = const(0x2A) +_SSD1681_WRITE_VCOM_CTRL = const(0x2B) +_SSD1681_WRITE_VCOM_REG = const(0x2C) +_SSD1681_READ_OTP = const(0x2D) +_SSD1681_READ_USERID = const(0x2E) +_SSD1681_READ_STATUS = const(0x2F) +_SSD1681_WRITE_WS_OTP = const(0x30) +_SSD1681_LOAD_WS_OTP = const(0x31) +_SSD1681_WRITE_LUT = const(0x32) +_SSD1681_CRC_CALC = const(0x34) +_SSD1681_CRC_READ = const(0x35) +_SSD1681_PROG_OTP = const(0x36) +_SSD1681_WRITE_DISPLAY_OPT = const(0x37) +_SSD1681_WRITE_USERID = const(0x38) +_SSD1681_OTP_PROGMODE = const(0x39) +_SSD1681_WRITE_BORDER = const(0x3C) +_SSD1681_END_OPTION = const(0x3F) +_SSD1681_READ_RAM = const(0x41) +_SSD1681_SET_RAMXPOS = const(0x44) +_SSD1681_SET_RAMYPOS = const(0x45) +_SSD1681_AUTOWRITE_RED = const(0x46) +_SSD1681_AUTOWRITE_BW = const(0x47) +_SSD1681_SET_RAMXCOUNT = const(0x4E) +_SSD1681_SET_RAMYCOUNT = const(0x4F) +_SSD1681_NOP = const(0xFF) + +_LUT_DATA = b'\x02\x02\x01\x11\x12\x12""fiiYX\x99\x99\x88\x00\x00\x00\x00\xf8\xb4\x13Q5QQ\x19\x01\x00' # pylint: disable=line-too-long + +class Adafruit_SSD1681(Adafruit_EPD): + """driver class for Adafruit SSD1681 ePaper display breakouts""" + # pylint: disable=too-many-arguments + def __init__(self, width, height, spi, *, cs_pin, dc_pin, sramcs_pin, rst_pin, busy_pin): + super(Adafruit_SSD1681, self).__init__(width, height, spi, cs_pin, dc_pin, + sramcs_pin, rst_pin, busy_pin) + + if height % 8 != 0: + height += (8 - height % 8) + self._height = height + + self._buffer1_size = int(width * height / 8) + + if sramcs_pin: + self._buffer1 = self.sram.get_view(0) + else: + self._buffer1 = bytearray((width * height) // 8) + self._framebuf1 = adafruit_framebuf.FrameBuffer(self._buffer1, width, height, + buf_format=adafruit_framebuf.MHMSB) + self.set_black_buffer(0, True) + self.set_color_buffer(0, True) + # pylint: enable=too-many-arguments + + def begin(self, reset=True): + """Begin communication with the display and set basic settings""" + if reset: + self.hardware_reset() + self.power_down() + + def busy_wait(self): + """Wait for display to be done with current task, either by polling the + busy pin, or pausing""" + if self._busy: + while self._busy.value: + time.sleep(0.01) + else: + time.sleep(0.5) + + def power_up(self): + """Power up the display in preparation for writing RAM and updating""" + self.hardware_reset() + self.busy_wait() + self.command(_SSD1681_SW_RESET) + self.busy_wait() + # driver output control + self.command(_SSD1681_DRIVER_CONTROL, + bytearray([self._width-1, (self._width-1) >> 8, 0x00])) + # data entry mode + self.command(_SSD1681_DATA_MODE, bytearray([0x01])) + # Set ram X start/end postion + self.command(_SSD1681_SET_RAMXPOS, bytearray([0x00, self._height//8 - 1])) + # Set ram Y start/end postion + self.command(_SSD1681_SET_RAMYPOS, + bytearray([0, 0, self._height - 1, (self._height - 1) >> 8])) + # Set border waveform + self.command(_SSD1681_WRITE_BORDER, bytearray([0x05])) + # Set temperature control + self.command(_SSD1681_TEMP_CONTROL, bytearray([0x80])) + + self.busy_wait() + + def power_down(self): + """Power down the display - required when not actively displaying!""" + self.command(_SSD1681_DEEP_SLEEP, bytearray([0x01])) + time.sleep(0.1) + + def update(self): + """Update the display from internal memory""" + self.command(_SSD1681_DISP_CTRL2, bytearray([0xF7])) + self.command(_SSD1681_MASTER_ACTIVATE) + self.busy_wait() + if not self._busy: + time.sleep(3) # wait 3 seconds + + def write_ram(self, index): + """Send the one byte command for starting the RAM write process. Returns + the byte read at the same time over SPI. index is the RAM buffer, can be + 0 or 1 for tri-color displays.""" + if index == 0: + return self.command(_SSD1681_WRITE_BWRAM, end=False) + raise RuntimeError("RAM index must be 0") + + def set_ram_address(self, x, y): # pylint: disable=unused-argument, no-self-use + """Set the RAM address location, not used on this chipset but required by + the superclass""" + # Set RAM X address counter + self.command(_SSD1681_SET_RAMXCOUNT, bytearray([x])) + # Set RAM Y address counter + self.command(_SSD1681_SET_RAMYCOUNT, bytearray([y>>8, y])) From 24a7c807562dedc83766861f134165ba94746a5e Mon Sep 17 00:00:00 2001 From: ladyada Date: Sat, 28 Sep 2019 03:42:17 -0400 Subject: [PATCH 05/18] fix display --- adafruit_epd/ssd1681.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adafruit_epd/ssd1681.py b/adafruit_epd/ssd1681.py index f3bf35e..8b35204 100644 --- a/adafruit_epd/ssd1681.py +++ b/adafruit_epd/ssd1681.py @@ -134,7 +134,7 @@ def power_up(self): self.command(_SSD1681_DRIVER_CONTROL, bytearray([self._width-1, (self._width-1) >> 8, 0x00])) # data entry mode - self.command(_SSD1681_DATA_MODE, bytearray([0x01])) + self.command(_SSD1681_DATA_MODE, bytearray([0x03])) # Set ram X start/end postion self.command(_SSD1681_SET_RAMXPOS, bytearray([0x00, self._height//8 - 1])) # Set ram Y start/end postion From da1a8ef8d9825b12fad9a86cbd0c5656f7539e8a Mon Sep 17 00:00:00 2001 From: ladyada Date: Sat, 28 Sep 2019 13:57:52 -0400 Subject: [PATCH 06/18] rough beginnings of an ssd1375b driver --- adafruit_epd/ssd1675b.py | 215 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 adafruit_epd/ssd1675b.py diff --git a/adafruit_epd/ssd1675b.py b/adafruit_epd/ssd1675b.py new file mode 100644 index 0000000..ced4c05 --- /dev/null +++ b/adafruit_epd/ssd1675b.py @@ -0,0 +1,215 @@ +# The MIT License (MIT) +# +# Copyright (c) 2018 Dean Miller for Adafruit Industries +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +""" +`adafruit_epd.ssd1675` - Adafruit SSD1675 - ePaper display driver +==================================================================================== +CircuitPython driver for Adafruit SSD1675 display breakouts +* Author(s): Dean Miller, Ladyada +""" + +import time +from micropython import const +import adafruit_framebuf +from adafruit_epd.epd import Adafruit_EPD + +__version__ = "0.0.0-auto.0" +__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_EPD.git" + +_SSD1675B_DRIVER_CONTROL = const(0x01) +_SSD1675B_GATE_VOLTAGE = const(0x03) +_SSD1675B_SOURCE_VOLTAGE = const(0x04) +_SSD1675B_INIT_SETTING = const(0x08) +_SSD1675B_INIT_WRITE_REG = const(0x09) +_SSD1675B_INIT_READ_REG = const(0x0A) +_SSD1675B_BOOSTER_SOFT_START = const(0x0C) +_SSD1675B_GATESCAN_START = const(0x0F) +_SSD1675B_DEEP_SLEEP = const(0x10) +_SSD1675B_DATA_MODE = const(0x11) +_SSD1675B_SW_RESET = const(0x12) +_SSD1675B_HV_READY = const(0x14) +_SSD1675B_VCI_READY = const(0x15) +_SSD1675B_TEMP_CONTROL = const(0x18) +_SSD1675B_TEMP_WRITE = const(0x1A) +_SSD1675B_TEMP_READ = const(0x1B) +_SSD1675B_EXTTEMP_WRITE = const(0x1C) +_SSD1675B_MASTER_ACTIVATE = const(0x20) +_SSD1675B_DISP_CTRL1 = const(0x21) +_SSD1675B_DISP_CTRL2 = const(0x22) +_SSD1675B_WRITE_RAM1 = const(0x24) +_SSD1675B_WRITE_RAM2 = const(0x26) +_SSD1675B_READ_RAM = const(0x27) +_SSD1675B_VCOM_SENSE = const(0x28) +_SSD1675B_VCOM_DURATION = const(0x29) +_SSD1675B_WRITE_VCOM_OTP = const(0x2A) +_SSD1675B_WRITE_VCOM_CTRL = const(0x2B) +_SSD1675B_WRITE_VCOM_REG = const(0x2C) +_SSD1675B_READ_OTP = const(0x2D) +_SSD1675B_READ_USERID = const(0x2E) +_SSD1675B_READ_STATUS = const(0x2F) +_SSD1675B_WRITE_WS_OTP = const(0x30) +_SSD1675B_LOAD_WS_OTP = const(0x31) +_SSD1675B_WRITE_LUT = const(0x32) +_SSD1675B_CRC_CALC = const(0x34) +_SSD1675B_CRC_READ = const(0x35) +_SSD1675B_PROG_OTP = const(0x36) +_SSD1675B_WRITE_DISPLAY_OPT = const(0x37) +_SSD1675B_WRITE_USERID = const(0x38) +_SSD1675B_OTP_PROGMODE = const(0x39) +_SSD1675B_WRITE_DUMMY = const(0x3A) +_SSD1675B_WRITE_GATELINE = const(0x3B) +_SSD1675B_WRITE_BORDER = const(0x3C) +_SSD1675B_READ_RAM = const(0x41) +_SSD1675B_SET_RAMXPOS = const(0x44) +_SSD1675B_SET_RAMYPOS = const(0x45) +_SSD1675B_AUTOWRITE_RED = const(0x46) +_SSD1675B_AUTOWRITE_BW = const(0x47) +_SSD1675B_SET_RAMXCOUNT = const(0x4E) +_SSD1675B_SET_RAMYCOUNT = const(0x4F) +_SSD1675B_SET_ANALOGBLOCK = const(0x74) +_SSD1675B_SET_DIGITALBLOCK = const(0x7E) +_SSD1675B_NOP = const(0xFF) +_LUT_DATA = b'\xa0\x90P\x00\x00\x00\x00\x00\x00\x00P\x90\xa0\x00\x00\x00\x00\x00\x00\x00\xa0\x90P\x00\x00\x00\x00\x00\x00\x00P\x90\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x0f\x0f\x00\x00\x03\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15A\xa82P,\x0b' # pylint: disable=line-too-long + + +class Adafruit_SSD1675B(Adafruit_EPD): + """driver class for Adafruit SSD1675B ePaper display breakouts""" + # pylint: disable=too-many-arguments + def __init__(self, width, height, spi, *, cs_pin, dc_pin, sramcs_pin, rst_pin, busy_pin): + super(Adafruit_SSD1675B, self).__init__(width, height, spi, cs_pin, dc_pin, + sramcs_pin, rst_pin, busy_pin) + if width % 8 != 0: + width += (8 - width % 8) + + self._buffer1_size = int(width * height / 8) + self._buffer2_size = self._buffer1_size + + if sramcs_pin: + self._buffer1 = self.sram.get_view(0) + self._buffer2 = self.sram.get_view(self._buffer1_size) + else: + self._buffer1 = bytearray(self._buffer1_size) + self._buffer2 = bytearray(self._buffer2_size) + # since we have *two* framebuffers - one for red and one for black + # we dont subclass but manage manually + self._framebuf1 = adafruit_framebuf.FrameBuffer(self._buffer1, width, height, + buf_format=adafruit_framebuf.MHMSB) + self._framebuf2 = adafruit_framebuf.FrameBuffer(self._buffer2, width, height, + buf_format=adafruit_framebuf.MHMSB) + self.set_black_buffer(0, True) + self.set_color_buffer(1, True) + # pylint: enable=too-many-arguments + + def begin(self, reset=True): + """Begin communication with the display and set basic settings""" + if reset: + self.hardware_reset() + self.power_down() + + def busy_wait(self): + """Wait for display to be done with current task, either by polling the + busy pin, or pausing""" + if self._busy: + while self._busy.value: + time.sleep(0.01) + else: + time.sleep(0.5) + + def power_up(self): + """Power up the display in preparation for writing RAM and updating""" + self.hardware_reset() + time.sleep(0.1) + self.busy_wait() + + self.command(_SSD1675B_SW_RESET) + self.busy_wait() + + # set analog block control + self.command(_SSD1675B_SET_ANALOGBLOCK, bytearray([0x54])) + # set digital block control + self.command(_SSD1675B_SET_DIGITALBLOCK, bytearray([0x3B])) + + # driver output control + self.command(_SSD1675B_DRIVER_CONTROL, + bytearray([0xF9, 0x00, 0x00])) + + # Data entry sequence + self.command(_SSD1675B_DATA_MODE, bytearray([0x01])) + + # Set ram X start/end postion + self.command(_SSD1675B_SET_RAMXPOS, bytearray([0x00, 0x0F])) + # Set ram Y start/end postion + self.command(_SSD1675B_SET_RAMYPOS, bytearray([0xF9, 0x0, 0x0, 0x0])) + + # Border color + self.command(_SSD1675B_WRITE_BORDER, bytearray([0x01])) + + # Vcom Voltage + self.command(_SSD1675B_WRITE_VCOM_REG, bytearray([0x50])) + # Set gate voltage + self.command(_SSD1675B_GATE_VOLTAGE, _LUT_DATA[100:101]) + # Set source voltage + self.command(_SSD1675B_SOURCE_VOLTAGE, _LUT_DATA[101:104]) + # Set dummy line period + self.command(_SSD1675B_WRITE_DUMMY, _LUT_DATA[105:106]) + # Set gate line width + self.command(_SSD1675B_WRITE_GATELINE, _LUT_DATA[106:107]) + # LUT + self.command(_SSD1675B_WRITE_LUT, _LUT_DATA[0:100]) + + # Set temperature control + #self.command(_SSD1675B_TEMP_CONTROL, bytearray([0x80])) + + # Set RAM X address counter + self.command(_SSD1675B_SET_RAMXCOUNT, bytearray([0])) + # Set RAM Y address counter + self.command(_SSD1675B_SET_RAMYCOUNT, bytearray([0xF9, 0])) + + self.busy_wait() + + def power_down(self): + """Power down the display - required when not actively displaying!""" + self.command(_SSD1675B_DEEP_SLEEP, bytearray([0x01])) + time.sleep(0.1) + + def update(self): + """Update the display from internal memory""" + self.command(_SSD1675B_DISP_CTRL2, bytearray([0xFF])) + self.command(_SSD1675B_MASTER_ACTIVATE) + self.busy_wait() + if not self._busy: + time.sleep(3) # wait 3 seconds + + def write_ram(self, index): + """Send the one byte command for starting the RAM write process. Returns + the byte read at the same time over SPI. index is the RAM buffer, can be + 0 or 1 for tri-color displays.""" + if index == 0: + return self.command(_SSD1675B_WRITE_RAM1, end=False) + if index == 1: + return self.command(_SSD1675B_WRITE_RAM2, end=False) + raise RuntimeError("RAM index must be 0 or 1") + + def set_ram_address(self, x, y): # pylint: disable=unused-argument, no-self-use + """Set the RAM address location, not used on this chipset but required by + the superclass""" + self.command(_SSD1675B_SET_RAMXCOUNT, bytearray([x])) + self.command(_SSD1675B_SET_RAMYCOUNT, bytearray([y, y>>8])) From be57b80782f6b76fccf25d5c399de3e67761f87a Mon Sep 17 00:00:00 2001 From: ladyada Date: Sat, 28 Sep 2019 14:09:53 -0400 Subject: [PATCH 07/18] fix orientation. needs lutwork --- adafruit_epd/ssd1675b.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/adafruit_epd/ssd1675b.py b/adafruit_epd/ssd1675b.py index ced4c05..2407095 100644 --- a/adafruit_epd/ssd1675b.py +++ b/adafruit_epd/ssd1675b.py @@ -147,17 +147,16 @@ def power_up(self): # set digital block control self.command(_SSD1675B_SET_DIGITALBLOCK, bytearray([0x3B])) - # driver output control self.command(_SSD1675B_DRIVER_CONTROL, - bytearray([0xF9, 0x00, 0x00])) + bytearray([self._height-1, (self._height-1) >> 8, 0x00])) # Data entry sequence - self.command(_SSD1675B_DATA_MODE, bytearray([0x01])) + self.command(_SSD1675B_DATA_MODE, bytearray([0x03])) # Set ram X start/end postion - self.command(_SSD1675B_SET_RAMXPOS, bytearray([0x00, 0x0F])) + self.command(_SSD1675B_SET_RAMXPOS, bytearray([0x00, self._width // 8])) # Set ram Y start/end postion - self.command(_SSD1675B_SET_RAMYPOS, bytearray([0xF9, 0x0, 0x0, 0x0])) + self.command(_SSD1675B_SET_RAMYPOS, bytearray([0x0, 0x0, self._height-1, (self._height-1) >> 8])) # Border color self.command(_SSD1675B_WRITE_BORDER, bytearray([0x01])) @@ -181,7 +180,7 @@ def power_up(self): # Set RAM X address counter self.command(_SSD1675B_SET_RAMXCOUNT, bytearray([0])) # Set RAM Y address counter - self.command(_SSD1675B_SET_RAMYCOUNT, bytearray([0xF9, 0])) + self.command(_SSD1675B_SET_RAMYCOUNT, bytearray([self._height-1, (self._height-1) >> 8])) self.busy_wait() From 058a11e7bf440c365cc8779c6418f21eec294512 Mon Sep 17 00:00:00 2001 From: ladyada Date: Sat, 28 Sep 2019 14:13:37 -0400 Subject: [PATCH 08/18] add new displays --- examples/epd_blinka.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/examples/epd_blinka.py b/examples/epd_blinka.py index 33dc719..5a92a2b 100644 --- a/examples/epd_blinka.py +++ b/examples/epd_blinka.py @@ -11,6 +11,8 @@ from adafruit_epd.il0398 import Adafruit_IL0398 # pylint: disable=unused-import from adafruit_epd.ssd1608 import Adafruit_SSD1608 # pylint: disable=unused-import from adafruit_epd.ssd1675 import Adafruit_SSD1675 # pylint: disable=unused-import +from adafruit_epd.ssd1675b import Adafruit_SSD1675B # pylint: disable=unused-import +from adafruit_epd.ssd1681 import Adafruit_SSD1681 # pylint: disable=unused-import # create the spi device and pins we will need spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) @@ -28,12 +30,14 @@ # give them all to our driver print("Creating display") #display = Adafruit_SSD1608(200, 200, spi, # 1.54" HD mono display +#display = Adafruit_SSD1681(200, 200, spi, # 1.54" HD mono display (alt) #display = Adafruit_SSD1675(122, 250, spi, # 2.13" HD mono display +display = Adafruit_SSD1675B(122, 250, spi, # 2.13" HD mono display (rev B) #display = Adafruit_IL91874(176, 264, spi, # 2.7" Tri-color display #display = Adafruit_IL0373(152, 152, spi, # 1.54" Tri-color display #display = Adafruit_IL0373(128, 296, spi, # 2.9" Tri-color display #display = Adafruit_IL0398(400, 300, spi, # 4.2" Tri-color display -display = Adafruit_IL0373(104, 212, spi, # 2.13" Tri-color display +#display = Adafruit_IL0373(104, 212, spi, # 2.13" Tri-color display cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs, rst_pin=rst, busy_pin=busy) From f557beff1ae4b5ae1795b2344eb1cae9b3e49d57 Mon Sep 17 00:00:00 2001 From: ladyada Date: Sun, 29 Sep 2019 01:32:52 -0400 Subject: [PATCH 09/18] run correct lut, checked with both 2.13"s --- adafruit_epd/ssd1675b.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/adafruit_epd/ssd1675b.py b/adafruit_epd/ssd1675b.py index 2407095..6c9c30b 100644 --- a/adafruit_epd/ssd1675b.py +++ b/adafruit_epd/ssd1675b.py @@ -89,7 +89,6 @@ _SSD1675B_NOP = const(0xFF) _LUT_DATA = b'\xa0\x90P\x00\x00\x00\x00\x00\x00\x00P\x90\xa0\x00\x00\x00\x00\x00\x00\x00\xa0\x90P\x00\x00\x00\x00\x00\x00\x00P\x90\xa0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0f\x0f\x00\x00\x00\x0f\x0f\x00\x00\x03\x0f\x0f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x15A\xa82P,\x0b' # pylint: disable=line-too-long - class Adafruit_SSD1675B(Adafruit_EPD): """driver class for Adafruit SSD1675B ePaper display breakouts""" # pylint: disable=too-many-arguments @@ -115,7 +114,7 @@ def __init__(self, width, height, spi, *, cs_pin, dc_pin, sramcs_pin, rst_pin, b self._framebuf2 = adafruit_framebuf.FrameBuffer(self._buffer2, width, height, buf_format=adafruit_framebuf.MHMSB) self.set_black_buffer(0, True) - self.set_color_buffer(1, True) + self.set_color_buffer(0, True) # pylint: enable=too-many-arguments def begin(self, reset=True): @@ -159,7 +158,7 @@ def power_up(self): self.command(_SSD1675B_SET_RAMYPOS, bytearray([0x0, 0x0, self._height-1, (self._height-1) >> 8])) # Border color - self.command(_SSD1675B_WRITE_BORDER, bytearray([0x01])) + self.command(_SSD1675B_WRITE_BORDER, bytearray([0x03])) # Vcom Voltage self.command(_SSD1675B_WRITE_VCOM_REG, bytearray([0x50])) @@ -191,7 +190,7 @@ def power_down(self): def update(self): """Update the display from internal memory""" - self.command(_SSD1675B_DISP_CTRL2, bytearray([0xFF])) + self.command(_SSD1675B_DISP_CTRL2, bytearray([0xC7])) self.command(_SSD1675B_MASTER_ACTIVATE) self.busy_wait() if not self._busy: From b202863f31fd9d63b5656a2d5dc63bb793dadb61 Mon Sep 17 00:00:00 2001 From: ladyada Date: Sun, 29 Sep 2019 01:38:04 -0400 Subject: [PATCH 10/18] lint --- adafruit_epd/epd.py | 2 +- adafruit_epd/ssd1675b.py | 5 +++-- examples/epd_blinka.py | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/adafruit_epd/epd.py b/adafruit_epd/epd.py index 0f96511..ac49c1b 100644 --- a/adafruit_epd/epd.py +++ b/adafruit_epd/epd.py @@ -346,7 +346,7 @@ def image(self, image): pix = image.load() # clear out any display buffers self.fill(Adafruit_EPD.WHITE) - + for y in range(image.size[1]): for x in range(image.size[0]): pixel = pix[x, y] diff --git a/adafruit_epd/ssd1675b.py b/adafruit_epd/ssd1675b.py index 6c9c30b..9949aff 100644 --- a/adafruit_epd/ssd1675b.py +++ b/adafruit_epd/ssd1675b.py @@ -94,7 +94,7 @@ class Adafruit_SSD1675B(Adafruit_EPD): # pylint: disable=too-many-arguments def __init__(self, width, height, spi, *, cs_pin, dc_pin, sramcs_pin, rst_pin, busy_pin): super(Adafruit_SSD1675B, self).__init__(width, height, spi, cs_pin, dc_pin, - sramcs_pin, rst_pin, busy_pin) + sramcs_pin, rst_pin, busy_pin) if width % 8 != 0: width += (8 - width % 8) @@ -155,7 +155,8 @@ def power_up(self): # Set ram X start/end postion self.command(_SSD1675B_SET_RAMXPOS, bytearray([0x00, self._width // 8])) # Set ram Y start/end postion - self.command(_SSD1675B_SET_RAMYPOS, bytearray([0x0, 0x0, self._height-1, (self._height-1) >> 8])) + self.command(_SSD1675B_SET_RAMYPOS, + bytearray([0x0, 0x0, self._height-1, (self._height-1) >> 8])) # Border color self.command(_SSD1675B_WRITE_BORDER, bytearray([0x03])) diff --git a/examples/epd_blinka.py b/examples/epd_blinka.py index 5a92a2b..bb2e4ef 100644 --- a/examples/epd_blinka.py +++ b/examples/epd_blinka.py @@ -38,8 +38,8 @@ #display = Adafruit_IL0373(128, 296, spi, # 2.9" Tri-color display #display = Adafruit_IL0398(400, 300, spi, # 4.2" Tri-color display #display = Adafruit_IL0373(104, 212, spi, # 2.13" Tri-color display - cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs, - rst_pin=rst, busy_pin=busy) + cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs, + rst_pin=rst, busy_pin=busy) display.rotation = 3 # Create blank image for drawing. From 14ed40f901f3a6740e6e7703e72bef30ea8e4ffc Mon Sep 17 00:00:00 2001 From: ladyada Date: Sun, 29 Sep 2019 01:41:06 -0400 Subject: [PATCH 11/18] lintlint --- examples/epd_blinka.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/epd_blinka.py b/examples/epd_blinka.py index bb2e4ef..412690e 100644 --- a/examples/epd_blinka.py +++ b/examples/epd_blinka.py @@ -29,15 +29,15 @@ # give them all to our driver print("Creating display") -#display = Adafruit_SSD1608(200, 200, spi, # 1.54" HD mono display -#display = Adafruit_SSD1681(200, 200, spi, # 1.54" HD mono display (alt) -#display = Adafruit_SSD1675(122, 250, spi, # 2.13" HD mono display +#display = Adafruit_SSD1608(200, 200, spi, # 1.54" HD mono display +#display = Adafruit_SSD1681(200, 200, spi, # 1.54" HD mono display (alt) +#display = Adafruit_SSD1675(122, 250, spi, # 2.13" HD mono display display = Adafruit_SSD1675B(122, 250, spi, # 2.13" HD mono display (rev B) #display = Adafruit_IL91874(176, 264, spi, # 2.7" Tri-color display -#display = Adafruit_IL0373(152, 152, spi, # 1.54" Tri-color display -#display = Adafruit_IL0373(128, 296, spi, # 2.9" Tri-color display -#display = Adafruit_IL0398(400, 300, spi, # 4.2" Tri-color display -#display = Adafruit_IL0373(104, 212, spi, # 2.13" Tri-color display +#display = Adafruit_IL0373(152, 152, spi, # 1.54" Tri-color display +#display = Adafruit_IL0373(128, 296, spi, # 2.9" Tri-color display +#display = Adafruit_IL0398(400, 300, spi, # 4.2" Tri-color display +#display = Adafruit_IL0373(104, 212, spi, # 2.13" Tri-color display cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs, rst_pin=rst, busy_pin=busy) From 5ce4a71d6aa0dc747f5add3fe2c5ba243c9e25fc Mon Sep 17 00:00:00 2001 From: ladyada Date: Sun, 29 Sep 2019 01:43:59 -0400 Subject: [PATCH 12/18] lint3 --- examples/epd_blinka.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/epd_blinka.py b/examples/epd_blinka.py index 412690e..163335b 100644 --- a/examples/epd_blinka.py +++ b/examples/epd_blinka.py @@ -6,13 +6,13 @@ from PIL import ImageDraw from PIL import ImageFont from adafruit_epd.epd import Adafruit_EPD -from adafruit_epd.il0373 import Adafruit_IL0373 -from adafruit_epd.il91874 import Adafruit_IL91874 # pylint: disable=unused-import -from adafruit_epd.il0398 import Adafruit_IL0398 # pylint: disable=unused-import -from adafruit_epd.ssd1608 import Adafruit_SSD1608 # pylint: disable=unused-import -from adafruit_epd.ssd1675 import Adafruit_SSD1675 # pylint: disable=unused-import +from adafruit_epd.il0373 import Adafruit_IL0373 # pylint: disable=unused-import +from adafruit_epd.il91874 import Adafruit_IL91874 # pylint: disable=unused-import +from adafruit_epd.il0398 import Adafruit_IL0398 # pylint: disable=unused-import +from adafruit_epd.ssd1608 import Adafruit_SSD1608 # pylint: disable=unused-import +from adafruit_epd.ssd1675 import Adafruit_SSD1675 # pylint: disable=unused-import from adafruit_epd.ssd1675b import Adafruit_SSD1675B # pylint: disable=unused-import -from adafruit_epd.ssd1681 import Adafruit_SSD1681 # pylint: disable=unused-import +from adafruit_epd.ssd1681 import Adafruit_SSD1681 # pylint: disable=unused-import # create the spi device and pins we will need spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) @@ -32,12 +32,12 @@ #display = Adafruit_SSD1608(200, 200, spi, # 1.54" HD mono display #display = Adafruit_SSD1681(200, 200, spi, # 1.54" HD mono display (alt) #display = Adafruit_SSD1675(122, 250, spi, # 2.13" HD mono display -display = Adafruit_SSD1675B(122, 250, spi, # 2.13" HD mono display (rev B) #display = Adafruit_IL91874(176, 264, spi, # 2.7" Tri-color display #display = Adafruit_IL0373(152, 152, spi, # 1.54" Tri-color display #display = Adafruit_IL0373(128, 296, spi, # 2.9" Tri-color display #display = Adafruit_IL0398(400, 300, spi, # 4.2" Tri-color display #display = Adafruit_IL0373(104, 212, spi, # 2.13" Tri-color display +display = Adafruit_SSD1675B(122, 250, spi, # 2.13" HD mono display (rev B) cs_pin=ecs, dc_pin=dc, sramcs_pin=srcs, rst_pin=rst, busy_pin=busy) From 2d2c84177320446d71c3b73fd9b64ee8545089cf Mon Sep 17 00:00:00 2001 From: ladyada Date: Sun, 29 Sep 2019 01:49:51 -0400 Subject: [PATCH 13/18] fix dup register and docname --- adafruit_epd/ssd1675b.py | 2 +- adafruit_epd/ssd1681.py | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/adafruit_epd/ssd1675b.py b/adafruit_epd/ssd1675b.py index 9949aff..c215ebf 100644 --- a/adafruit_epd/ssd1675b.py +++ b/adafruit_epd/ssd1675b.py @@ -20,7 +20,7 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. """ -`adafruit_epd.ssd1675` - Adafruit SSD1675 - ePaper display driver +`adafruit_epd.ssd1675b` - Adafruit SSD1675 - ePaper display driver ==================================================================================== CircuitPython driver for Adafruit SSD1675 display breakouts * Author(s): Dean Miller, Ladyada diff --git a/adafruit_epd/ssd1681.py b/adafruit_epd/ssd1681.py index 8b35204..6d9ba95 100644 --- a/adafruit_epd/ssd1681.py +++ b/adafruit_epd/ssd1681.py @@ -75,7 +75,6 @@ _SSD1681_OTP_PROGMODE = const(0x39) _SSD1681_WRITE_BORDER = const(0x3C) _SSD1681_END_OPTION = const(0x3F) -_SSD1681_READ_RAM = const(0x41) _SSD1681_SET_RAMXPOS = const(0x44) _SSD1681_SET_RAMYPOS = const(0x45) _SSD1681_AUTOWRITE_RED = const(0x46) From 3f9bc2665a85e869545a9f4f8d80c33a14d0a58d Mon Sep 17 00:00:00 2001 From: ladyada Date: Sun, 29 Sep 2019 01:51:44 -0400 Subject: [PATCH 14/18] remove another dup --- adafruit_epd/ssd1675b.py | 1 - 1 file changed, 1 deletion(-) diff --git a/adafruit_epd/ssd1675b.py b/adafruit_epd/ssd1675b.py index c215ebf..975ae88 100644 --- a/adafruit_epd/ssd1675b.py +++ b/adafruit_epd/ssd1675b.py @@ -77,7 +77,6 @@ _SSD1675B_WRITE_DUMMY = const(0x3A) _SSD1675B_WRITE_GATELINE = const(0x3B) _SSD1675B_WRITE_BORDER = const(0x3C) -_SSD1675B_READ_RAM = const(0x41) _SSD1675B_SET_RAMXPOS = const(0x44) _SSD1675B_SET_RAMYPOS = const(0x45) _SSD1675B_AUTOWRITE_RED = const(0x46) From 8022b3427ef6d622a5694fa424f79a4b1ba31d6e Mon Sep 17 00:00:00 2001 From: ladyada Date: Sun, 29 Sep 2019 12:29:29 -0400 Subject: [PATCH 15/18] fix stride for rotation of odd-pixel-counts --- adafruit_epd/ssd1675.py | 11 ++++++----- adafruit_epd/ssd1675b.py | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/adafruit_epd/ssd1675.py b/adafruit_epd/ssd1675.py index 96f15da..f2f1f7f 100644 --- a/adafruit_epd/ssd1675.py +++ b/adafruit_epd/ssd1675.py @@ -68,10 +68,11 @@ class Adafruit_SSD1675(Adafruit_EPD): def __init__(self, width, height, spi, *, cs_pin, dc_pin, sramcs_pin, rst_pin, busy_pin): super(Adafruit_SSD1675, self).__init__(width, height, spi, cs_pin, dc_pin, sramcs_pin, rst_pin, busy_pin) - if width % 8 != 0: - width += (8 - width % 8) + stride = width + if stride % 8 != 0: + stride += (8 - stride % 8) - self._buffer1_size = int(width * height / 8) + self._buffer1_size = int(stride * height / 8) self._buffer2_size = self._buffer1_size if sramcs_pin: @@ -82,9 +83,9 @@ def __init__(self, width, height, spi, *, cs_pin, dc_pin, sramcs_pin, rst_pin, b self._buffer2 = bytearray(self._buffer2_size) # since we have *two* framebuffers - one for red and one for black # we dont subclass but manage manually - self._framebuf1 = adafruit_framebuf.FrameBuffer(self._buffer1, width, height, + self._framebuf1 = adafruit_framebuf.FrameBuffer(self._buffer1, width, height, stride=stride, buf_format=adafruit_framebuf.MHMSB) - self._framebuf2 = adafruit_framebuf.FrameBuffer(self._buffer2, width, height, + self._framebuf2 = adafruit_framebuf.FrameBuffer(self._buffer2, width, height, stride=stride, buf_format=adafruit_framebuf.MHMSB) self.set_black_buffer(0, True) self.set_color_buffer(0, True) diff --git a/adafruit_epd/ssd1675b.py b/adafruit_epd/ssd1675b.py index 975ae88..f9e8fd9 100644 --- a/adafruit_epd/ssd1675b.py +++ b/adafruit_epd/ssd1675b.py @@ -94,10 +94,11 @@ class Adafruit_SSD1675B(Adafruit_EPD): def __init__(self, width, height, spi, *, cs_pin, dc_pin, sramcs_pin, rst_pin, busy_pin): super(Adafruit_SSD1675B, self).__init__(width, height, spi, cs_pin, dc_pin, sramcs_pin, rst_pin, busy_pin) - if width % 8 != 0: - width += (8 - width % 8) + stride = width + if stride % 8 != 0: + stride += (8 - stride % 8) - self._buffer1_size = int(width * height / 8) + self._buffer1_size = int(stride * height / 8) self._buffer2_size = self._buffer1_size if sramcs_pin: @@ -108,9 +109,9 @@ def __init__(self, width, height, spi, *, cs_pin, dc_pin, sramcs_pin, rst_pin, b self._buffer2 = bytearray(self._buffer2_size) # since we have *two* framebuffers - one for red and one for black # we dont subclass but manage manually - self._framebuf1 = adafruit_framebuf.FrameBuffer(self._buffer1, width, height, + self._framebuf1 = adafruit_framebuf.FrameBuffer(self._buffer1, width, height, stride=stride, buf_format=adafruit_framebuf.MHMSB) - self._framebuf2 = adafruit_framebuf.FrameBuffer(self._buffer2, width, height, + self._framebuf2 = adafruit_framebuf.FrameBuffer(self._buffer2, width, height, stride=stride, buf_format=adafruit_framebuf.MHMSB) self.set_black_buffer(0, True) self.set_color_buffer(0, True) From 7d08a07fa3ccc06d34fdf2d88f3b3e2a8838262d Mon Sep 17 00:00:00 2001 From: ladyada Date: Sun, 29 Sep 2019 14:27:02 -0400 Subject: [PATCH 16/18] bonnet demo --- examples/epd_bonnet.py | 80 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 examples/epd_bonnet.py diff --git a/examples/epd_bonnet.py b/examples/epd_bonnet.py new file mode 100644 index 0000000..e79aa5d --- /dev/null +++ b/examples/epd_bonnet.py @@ -0,0 +1,80 @@ +import digitalio +import busio +import board + +from PIL import Image +from PIL import ImageDraw +from PIL import ImageFont +from adafruit_epd.epd import Adafruit_EPD +from adafruit_epd.ssd1675b import Adafruit_SSD1675B # pylint: disable=unused-import + +# create the spi device and pins we will need +spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) +ecs = digitalio.DigitalInOut(board.D8) +dc = digitalio.DigitalInOut(board.D22) +rst = digitalio.DigitalInOut(board.D27) +busy = digitalio.DigitalInOut(board.D17) + +# give them all to our driver +display = Adafruit_SSD1675B(122, 250, spi, # 2.13" HD mono display (rev B) + cs_pin=ecs, dc_pin=dc, sramcs_pin=None, + rst_pin=rst, busy_pin=busy) +display.rotation = 1 + +# Create blank image for drawing. +# Make sure to create image with mode '1' for 1-bit color. +width = display.width +height = display.height +image = Image.new('RGB', (width, height)) + +WHITE = (0xFF, 0xFF, 0xFF) +BLACK = (0x00, 0x00, 0x00) + +# clear the buffer +display.fill(Adafruit_EPD.WHITE) + +# Get drawing object to draw on image. +draw = ImageDraw.Draw(image) +# empty it +draw.rectangle((0, 0, width, height), fill=WHITE) + +# Draw an outline box +draw.rectangle((1, 1, width-2, height-2), outline=BLACK, fill=WHITE) +# Draw some shapes. +# First define some constants to allow easy resizing of shapes. +padding = 5 +shape_width = 30 +top = padding +bottom = height-padding +# Move left to right keeping track of the current x position for drawing shapes. +x = padding +# Draw an ellipse. +draw.ellipse((x, top , x+shape_width, bottom), outline=BLACK, fill=WHITE) +x += shape_width+padding +# Draw a rectangle. +draw.rectangle((x, top, x+shape_width, bottom), outline=WHITE, fill=BLACK) +x += shape_width+padding +# Draw a triangle. +draw.polygon([(x, bottom), (x+shape_width/2, top), (x+shape_width, bottom)], + outline=BLACK, fill=WHITE) +x += shape_width+padding +# Draw an X. +draw.line((x, bottom, x+shape_width, top), fill=BLACK) +draw.line((x, top, x+shape_width, bottom), fill=BLACK) +x += shape_width+padding + +# Load default font. +font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', 20) + +# Alternatively load a TTF font. Make sure the .ttf font +# file is in the same directory as the python script! +# Some other nice fonts to try: http://www.dafont.com/bitmap.php +#font = ImageFont.truetype('Minecraftia.ttf', 8) + +# Write two lines of text. +draw.text((x, top), 'Hello', font=font, fill=BLACK) +draw.text((x, top+20), 'World!', font=font, fill=BLACK) +# Display image. +display.image(image) + +display.display() From 3761c4dad7850bfaad2155c8225a8779d446eea6 Mon Sep 17 00:00:00 2001 From: ladyada Date: Sun, 29 Sep 2019 14:31:13 -0400 Subject: [PATCH 17/18] test switches --- examples/epd_bonnet.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/examples/epd_bonnet.py b/examples/epd_bonnet.py index e79aa5d..4d36e7b 100644 --- a/examples/epd_bonnet.py +++ b/examples/epd_bonnet.py @@ -1,6 +1,8 @@ +import time import digitalio import busio import board +from digitalio import DigitalInOut, Direction, Pull from PIL import Image from PIL import ImageDraw @@ -8,6 +10,12 @@ from adafruit_epd.epd import Adafruit_EPD from adafruit_epd.ssd1675b import Adafruit_SSD1675B # pylint: disable=unused-import +# create two buttons +switch1 = DigitalInOut(board.D6) +switch2 = DigitalInOut(board.D5) +switch1.direction = Direction.INPUT +switch2.direction = Direction.INPUT + # create the spi device and pins we will need spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) ecs = digitalio.DigitalInOut(board.D8) @@ -32,6 +40,8 @@ # clear the buffer display.fill(Adafruit_EPD.WHITE) +# clear it out +display.display() # Get drawing object to draw on image. draw = ImageDraw.Draw(image) @@ -74,7 +84,18 @@ # Write two lines of text. draw.text((x, top), 'Hello', font=font, fill=BLACK) draw.text((x, top+20), 'World!', font=font, fill=BLACK) -# Display image. -display.image(image) -display.display() +while True: + if not switch1.value: + print("Switch 1") + display.image(image) + display.display() + while not switch1.value: + time.sleep(0.01) + if not switch2.value: + print("Switch 2") + display.fill(Adafruit_EPD.WHITE) + display.display() + while not switch2.value: + time.sleep(0.01) + time.sleep(0.01) From 037480b30df34b53b6e30844806f3d355fff5c1a Mon Sep 17 00:00:00 2001 From: dherrada Date: Tue, 8 Oct 2019 10:47:17 -0400 Subject: [PATCH 18/18] Fixed some syntax in order to get the examples pylint to pass --- examples/epd_bonnet.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/epd_bonnet.py b/examples/epd_bonnet.py index 4d36e7b..b64d179 100644 --- a/examples/epd_bonnet.py +++ b/examples/epd_bonnet.py @@ -1,8 +1,7 @@ import time -import digitalio import busio import board -from digitalio import DigitalInOut, Direction, Pull +from digitalio import DigitalInOut, Direction from PIL import Image from PIL import ImageDraw @@ -18,10 +17,10 @@ # create the spi device and pins we will need spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) -ecs = digitalio.DigitalInOut(board.D8) -dc = digitalio.DigitalInOut(board.D22) -rst = digitalio.DigitalInOut(board.D27) -busy = digitalio.DigitalInOut(board.D17) +ecs = DigitalInOut(board.D8) +dc = DigitalInOut(board.D22) +rst = DigitalInOut(board.D27) +busy = DigitalInOut(board.D17) # give them all to our driver display = Adafruit_SSD1675B(122, 250, spi, # 2.13" HD mono display (rev B)