]> git.walde.dev - epaper_display/commitdiff
Move src into named module main
authorDustin Walde <redacted>
Mon, 6 Jan 2025 04:14:59 +0000 (20:14 -0800)
committerDustin Walde <redacted>
Mon, 6 Jan 2025 04:14:59 +0000 (20:14 -0800)
22 files changed:
src/__init__.py [deleted file]
src/display.py [deleted file]
src/drivers/__init__.py [deleted file]
src/drivers/epd12in48.py [deleted file]
src/drivers/epd12in48b.py [deleted file]
src/drivers/epd12in48b_V2.py [deleted file]
src/drivers/epd_12_in_48_lib_32bit.so [deleted file]
src/drivers/epd_12_in_48_lib_64bit.so [deleted file]
src/drivers/epdconfig.py [deleted file]
src/epaper_display/__init__.py [new file with mode: 0644]
src/epaper_display/display.py [new file with mode: 0644]
src/epaper_display/drivers/__init__.py [new file with mode: 0644]
src/epaper_display/drivers/epd12in48.py [new file with mode: 0644]
src/epaper_display/drivers/epd12in48b.py [new file with mode: 0644]
src/epaper_display/drivers/epd12in48b_V2.py [new file with mode: 0644]
src/epaper_display/drivers/epd_12_in_48_lib_32bit.so [new file with mode: 0644]
src/epaper_display/drivers/epd_12_in_48_lib_64bit.so [new file with mode: 0644]
src/epaper_display/drivers/epdconfig.py [new file with mode: 0644]
src/epaper_display/main.py [new file with mode: 0644]
src/epaper_display/renderer.py [new file with mode: 0644]
src/main.py [deleted file]
src/renderer.py [deleted file]

diff --git a/src/__init__.py b/src/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/display.py b/src/display.py
deleted file mode 100644 (file)
index 1899d42..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-"""
-"""
-
-from logging import Logger
-
-import PIL
-from PIL import Image
-
-from drivers.epd12in48b import EPD, EPD_HEIGHT, EPD_WIDTH
-
-logger = Logger(__name__)
-
-
-class Display:
-
-    def __init__(self) -> None:
-        self.width = EPD_WIDTH
-        self.height = EPD_HEIGHT
-        self.epaper = EPD()
-
-    def render(self, black: Image, red: Image):
-        logger.info("Init display")
-        self.epaper.init()
-        logger.info("Update display")
-        self.epaper.display(black, red)
-        logger.info("Sleep display")
-        self.epaper.sleep()
-
-    def calibrate(self, iterations=1):
-        logger.info("Init display for calibration")
-        self.epaper.init()
-
-        white = Image.new('1', (self.width, self.height), 'white')
-        black = Image.new('1', (self.width, self.height), 'black')
-
-        logger.info('Calibrating e-paper display')
-        for i in range(iterations):
-            logger.info('black')
-            self.epaper.display(black, white)
-            logger.info('red')
-            self.epaper.display(white, black)
-            logger.info('white')
-            self.epaper.display(white, white)
-            logger.info(f'#{i + 1} of {iterations} complete')
-
-        self.epaper.sleep()
-
diff --git a/src/drivers/__init__.py b/src/drivers/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/src/drivers/epd12in48.py b/src/drivers/epd12in48.py
deleted file mode 100644 (file)
index 16b33f5..0000000
+++ /dev/null
@@ -1,398 +0,0 @@
-# /*****************************************************************************\r
-# * | File        :      epd12in48.py\r
-# * | Author      :   Waveshare electrices\r
-# * | Function    :   Hardware underlying interface\r
-# * | Info        :\r
-# *----------------\r
-# * |  This version:   V1.0\r
-# * | Date        :   2019-11-01\r
-# * | Info        :   \r
-# ******************************************************************************/\r
-# Permission is hereby granted, free of charge, to any person obtaining a copy\r
-# of this software and associated documnetation files (the "Software"), to deal\r
-# in the Software without restriction, including without limitation the rights\r
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-# copies of the Software, and to permit persons to  whom the Software is\r
-# furished to do so, subject to the following conditions:\r
-#\r
-# The above copyright notice and this permission notice shall be included in\r
-# all copies or substantial portions of the Software.\r
-#\r
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
-# THE SOFTWARE.\r
-#\r
-import time\r
-import epdconfig\r
-\r
-EPD_WIDTH       = 1304\r
-EPD_HEIGHT      = 984\r
-\r
-class EPD(object):\r
-    def __init__(self):\r
-        self.width = EPD_WIDTH\r
-        self.height = EPD_HEIGHT\r
-        \r
-        self.EPD_M1_CS_PIN  = epdconfig.EPD_M1_CS_PIN\r
-        self.EPD_S1_CS_PIN  = epdconfig.EPD_S1_CS_PIN\r
-        self.EPD_M2_CS_PIN  = epdconfig.EPD_M2_CS_PIN\r
-        self.EPD_S2_CS_PIN  = epdconfig.EPD_S2_CS_PIN\r
-\r
-        self.EPD_M1S1_DC_PIN  = epdconfig.EPD_M1S1_DC_PIN\r
-        self.EPD_M2S2_DC_PIN  = epdconfig.EPD_M2S2_DC_PIN\r
-\r
-        self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN\r
-        self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN\r
-\r
-        self.EPD_M1_BUSY_PIN  = epdconfig.EPD_M1_BUSY_PIN\r
-        self.EPD_S1_BUSY_PIN  = epdconfig.EPD_S1_BUSY_PIN\r
-        self.EPD_M2_BUSY_PIN  = epdconfig.EPD_M2_BUSY_PIN\r
-        self.EPD_S2_BUSY_PIN  = epdconfig.EPD_S2_BUSY_PIN\r
-\r
-    def Init(self):\r
-        print("EPD init...")\r
-        epdconfig.module_init()\r
-        \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
-        self.Reset() \r
-\r
-        #panel setting\r
-        self.M1_SendCommand(0x00) \r
-        self.M1_SendData(0x1f)         #KW-3f   KWR-2F BWROTP 0f       BWOTP 1f\r
-        self.S1_SendCommand(0x00) \r
-        self.S1_SendData(0x1f) \r
-        self.M2_SendCommand(0x00) \r
-        self.M2_SendData(0x13) \r
-        self.S2_SendCommand(0x00) \r
-        self.S2_SendData(0x13) \r
-\r
-        # booster soft start\r
-        self.M1_SendCommand(0x06) \r
-        self.M1_SendData(0x17)         #A\r
-        self.M1_SendData(0x17)         #B\r
-        self.M1_SendData(0x39)         #C\r
-        self.M1_SendData(0x17) \r
-        self.M2_SendCommand(0x06) \r
-        self.M2_SendData(0x17) \r
-        self.M2_SendData(0x17) \r
-        self.M2_SendData(0x39) \r
-        self.M2_SendData(0x17) \r
-\r
-        #resolution setting\r
-        self.M1_SendCommand(0x61) \r
-        self.M1_SendData(0x02) \r
-        self.M1_SendData(0x88)         #source 648\r
-        self.M1_SendData(0x01)         #gate 492\r
-        self.M1_SendData(0xEC) \r
-        self.S1_SendCommand(0x61) \r
-        self.S1_SendData(0x02) \r
-        self.S1_SendData(0x90)         #source 656\r
-        self.S1_SendData(0x01)         #gate 492\r
-        self.S1_SendData(0xEC) \r
-        self.M2_SendCommand(0x61) \r
-        self.M2_SendData(0x02) \r
-        self.M2_SendData(0x90)         #source 656\r
-        self.M2_SendData(0x01)         #gate 492\r
-        self.M2_SendData(0xEC) \r
-        self.S2_SendCommand(0x61) \r
-        self.S2_SendData(0x02) \r
-        self.S2_SendData(0x88)         #source 648\r
-        self.S2_SendData(0x01)         #gate 492\r
-        self.S2_SendData(0xEC) \r
-\r
-        self.M1S1M2S2_SendCommand(0x15)        #DUSPI\r
-        self.M1S1M2S2_SendData(0x20) \r
-\r
-        self.M1S1M2S2_SendCommand(0x50)        #Vcom and data interval setting\r
-        self.M1S1M2S2_SendData(0x21)  #Border KW\r
-        self.M1S1M2S2_SendData(0x07) \r
-\r
-        self.M1S1M2S2_SendCommand(0x60) #TCON\r
-        self.M1S1M2S2_SendData(0x22) \r
-\r
-        self.M1S1M2S2_SendCommand(0xE3) \r
-        self.M1S1M2S2_SendData(0x00) \r
-\r
-        #temperature\r
-        temp =  self.M1_ReadTemperature() \r
-\r
-        self.M1S1M2S2_SendCommand(0xe0) #Cascade setting\r
-        self.M1S1M2S2_SendData(0x03) \r
-        self.M1S1M2S2_SendCommand(0xe5) #Force temperature\r
-        self.M1S1M2S2_SendData(temp)\r
-        \r
-    def display(self, Image):\r
-        start = time.clock()\r
-        buf = [0x00] * int(self.width * self.height / 8)\r
-        image_monocolor = Image.convert('1')\r
-        imwidth, imheight = image_monocolor.size \r
-        pixels = image_monocolor.load()\r
-        temp=0;\r
-        for y in range(0, imheight):\r
-                for x in range(0, imwidth):\r
-                    # Set the bits for the column of pixels at the current position.\r
-                    if pixels[x, y] < 127:           # black\r
-                        buf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
-                    else:                           # white\r
-                        buf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
-                    temp=temp+1\r
-                    if(temp==8):\r
-                        temp=0\r
-\r
-        #M1 part 648*492    \r
-        self.M1_SendCommand(0x13)\r
-        for y in  range(492, 984):\r
-            for x in  range(0, 81):\r
-                    self.M1_SendData(buf[y*163 + x])\r
-\r
-        #S1 part 656*492\r
-        self.S1_SendCommand(0x13)\r
-        for y in  range(492, 984):\r
-            for x in  range(81, 163):\r
-                self.S1_SendData(buf[y*163 + x])\r
-\r
-        #M2 part 656*492\r
-        self.M2_SendCommand(0x13)\r
-        for y in  range(0, 492):\r
-            for x in  range(81, 163):\r
-                self.M2_SendData(buf[y*163 + x])\r
-\r
-        #S2 part 648*492\r
-        self.S2_SendCommand(0x13)\r
-        for y in  range(0, 492):\r
-            for x in  range(0, 81):\r
-                self.S2_SendData(buf[y*163 + x])\r
-                \r
-        end = time.clock()\r
-        print("use time:%f"%(end - start))\r
-        self.TurnOnDisplay()\r
-\r
-    def clear(self):\r
-        """Clear contents of image buffer"""\r
-        start = time.clock()\r
-        self.M1_SendCommand(0x13)\r
-        for y in  range(492, 984):\r
-            for x in  range(0, 81):\r
-                self.M1_SendData(0xff)\r
-\r
-        self.S1_SendCommand(0x13)\r
-        for y in  range(492, 984):\r
-            for x in  range(81, 163):\r
-                self.S1_SendData(0xff)\r
-    \r
-        self.M2_SendCommand(0x13)\r
-        for y in  range(0, 492):\r
-            for x in  range(81, 163):\r
-                self.M2_SendData(0xff)\r
-\r
-        self.S2_SendCommand(0x13)\r
-        for y in  range(0, 492):\r
-            for x in  range(0, 81):\r
-                self.S2_SendData(0xff)\r
-        end = time.clock()\r
-        print("use time:%f"%(end - start))\r
-        self.TurnOnDisplay()\r
-        \r
-    """   M1S1M2S2 Write register address and data     """\r
-    def M1S1M2S2_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
-        \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd) \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-    \r
-    def M1S1M2S2_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val) \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-\r
-    """   M1M2 Write register address and data     """\r
-    def M1M2_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd) \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-        \r
-    def M1S1M2S2_Senddata(self, val): \r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val) \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)   \r
-          \r
-    """   S2 Write register address and data     """\r
-    def S2_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-\r
-\r
-    def S2_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-        \r
-    """   M2 Write register address and data     """\r
-    def M2_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd) \r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-\r
-    def M2_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val) \r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-\r
-    """   S1 Write register address and data     """\r
-    def S1_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-\r
-    def S1_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-        \r
-    """   M1 Write register address and data     """\r
-    def M1_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-\r
-    def M1_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-\r
-    def Reset(self):\r
-        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
-        time.sleep(0.2) \r
-        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) \r
-        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) \r
-        time.sleep(0.01) \r
-        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
-        time.sleep(0.2) \r
-    \r
-    def EPD_Sleep(self):\r
-        self.M1S1M2S2_SendCommand(0X02)        \r
-        time.sleep(0.3) \r
-\r
-        self.M1S1M2S2_SendCommand(0X07)        \r
-        self.M1S1M2S2_SendData(0xA5) \r
-        time.sleep(0.3) \r
-        print("module_exit")\r
-        epdconfig.module_exit()\r
-        \r
-        \r
-    def TurnOnDisplay(self):\r
-        self.M1M2_SendCommand(0x04)  \r
-        time.sleep(0.3) \r
-        self.M1S1M2S2_SendCommand(0x12) \r
-        self.M1_ReadBusy()\r
-        self.S1_ReadBusy()\r
-        self.M2_ReadBusy()\r
-        self.S2_ReadBusy()\r
-    \r
-    #Busy\r
-    def M1_ReadBusy(self):\r
-        self.M1_SendCommand(0x71) \r
-        busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
-        busy = not(busy & 0x01) \r
-        print("M1_ReadBusy")\r
-        while(busy):\r
-            self.M1_SendCommand(0x71) \r
-            busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
-            busy = not(busy & 0x01) \r
-        time.sleep(0.2)\r
-        \r
-    def M2_ReadBusy(self):\r
-        self.M2_SendCommand(0x71) \r
-        busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
-        busy = not(busy & 0x01) \r
-        print("M2_ReadBusy")\r
-        while(busy):\r
-            self.M2_SendCommand(0x71) \r
-            busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
-            busy =not(busy & 0x01) \r
-        time.sleep(0.2)   \r
-        \r
-    def S1_ReadBusy(self):\r
-        self.S1_SendCommand(0x71) \r
-        busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
-        busy = not(busy & 0x01) \r
-        print("s1_ReadBusy")\r
-        while(busy):\r
-            self.S1_SendCommand(0x71) \r
-            busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
-            busy = not(busy & 0x01) \r
-        time.sleep(0.2)   \r
-        \r
-    def S2_ReadBusy(self):\r
-        self.S2_SendCommand(0x71) \r
-        busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
-        busy = not(busy & 0x01) \r
-        print("S2_ReadBusy")\r
-        while(busy):\r
-            self.S2_SendCommand(0x71) \r
-            busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
-            busy = not(busy & 0x01) \r
-        time.sleep(0.2)            \r
-        \r
-    def M1_ReadTemperature(self):\r
-        self.M1_SendCommand(0x40) \r
-        self.M1_ReadBusy() \r
-        time.sleep(0.3) \r
-\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) \r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
-        \r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) \r
-        time.sleep(0.01) \r
-        \r
-        # temp = epdconfig.spi_readbyte(0x00)\r
-        temp = 25\r
-        print("Read Temperature Reg:%d"%temp)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
-        # temp =0x29\r
-        return temp \r
diff --git a/src/drivers/epd12in48b.py b/src/drivers/epd12in48b.py
deleted file mode 100644 (file)
index e4035a4..0000000
+++ /dev/null
@@ -1,520 +0,0 @@
-# /*****************************************************************************\r
-# * | File        :      epd12in48.py\r
-# * | Author      :   Waveshare electrices\r
-# * | Function    :   Hardware underlying interface\r
-# * | Info        :\r
-# *----------------\r
-# * |  This version:   V1.0\r
-# * | Date        :   2019-11-01\r
-# * | Info        :   \r
-# ******************************************************************************/\r
-# Permission is hereby granted, free of charge, to any person obtaining a copy\r
-# of this software and associated documnetation files (the "Software"), to deal\r
-# in the Software without restriction, including without limitation the rights\r
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-# copies of the Software, and to permit persons to  whom the Software is\r
-# furished to do so, subject to the following conditions:\r
-#\r
-# The above copyright notice and this permission notice shall be included in\r
-# all copies or substantial portions of the Software.\r
-#\r
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
-# THE SOFTWARE.\r
-#\r
-import time\r
-from . import epdconfig\r
-\r
-EPD_WIDTH       = 1304\r
-EPD_HEIGHT      = 984\r
-\r
-class EPD(object):\r
-    def __init__(self):\r
-        self.width = EPD_WIDTH\r
-        self.height = EPD_HEIGHT\r
-        \r
-        self.EPD_M1_CS_PIN  = epdconfig.EPD_M1_CS_PIN\r
-        self.EPD_S1_CS_PIN  = epdconfig.EPD_S1_CS_PIN\r
-        self.EPD_M2_CS_PIN  = epdconfig.EPD_M2_CS_PIN\r
-        self.EPD_S2_CS_PIN  = epdconfig.EPD_S2_CS_PIN\r
-\r
-        self.EPD_M1S1_DC_PIN  = epdconfig.EPD_M1S1_DC_PIN\r
-        self.EPD_M2S2_DC_PIN  = epdconfig.EPD_M2S2_DC_PIN\r
-\r
-        self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN\r
-        self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN\r
-\r
-        self.EPD_M1_BUSY_PIN  = epdconfig.EPD_M1_BUSY_PIN\r
-        self.EPD_S1_BUSY_PIN  = epdconfig.EPD_S1_BUSY_PIN\r
-        self.EPD_M2_BUSY_PIN  = epdconfig.EPD_M2_BUSY_PIN\r
-        self.EPD_S2_BUSY_PIN  = epdconfig.EPD_S2_BUSY_PIN\r
-\r
-    def init(self):\r
-        self.Init()\r
-\r
-    def Init(self):\r
-        print("EPD init...")\r
-        epdconfig.module_init()\r
-        \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
-        self.Reset() \r
-\r
-        #panel setting\r
-        self.M1_SendCommand(0x00) \r
-        self.M1_SendData(0x2f)         #KW-3f   KWR-2F BWROTP 0f       BWOTP 1f\r
-        self.S1_SendCommand(0x00) \r
-        self.S1_SendData(0x2f) \r
-        self.M2_SendCommand(0x00) \r
-        self.M2_SendData(0x23) \r
-        self.S2_SendCommand(0x00) \r
-        self.S2_SendData(0x23) \r
-\r
-        # POWER SETTING\r
-        self.M1_SendCommand(0x01)\r
-        self.M1_SendData(0x07)\r
-        self.M1_SendData(0x17) # VGH=20V,VGL=-20V\r
-        self.M1_SendData(0x3F)   # VDH=15V\r
-        self.M1_SendData(0x3F)   # VDL=-15V\r
-        self.M1_SendData(0x0d)\r
-        self.M2_SendCommand(0x01)\r
-        self.M2_SendData(0x07)\r
-        self.M2_SendData(0x17) # VGH=20V,VGL=-20V\r
-        self.M2_SendData(0x3F) # VDH=15V\r
-        self.M2_SendData(0x3F)  # VDL=-15V\r
-        self.M2_SendData(0x0d)\r
-        \r
-        # booster soft start\r
-        self.M1_SendCommand(0x06)\r
-        self.M1_SendData(0x17) #A\r
-        self.M1_SendData(0x17) #B\r
-        self.M1_SendData(0x39) #C\r
-        self.M1_SendData(0x17)\r
-        self.M2_SendCommand(0x06)\r
-        self.M2_SendData(0x17)\r
-        self.M2_SendData(0x17)\r
-        self.M2_SendData(0x39)\r
-        self.M2_SendData(0x17)\r
-\r
-        #resolution setting\r
-        self.M1_SendCommand(0x61)\r
-        self.M1_SendData(0x02)\r
-        self.M1_SendData(0x88) #source 648\r
-        self.M1_SendData(0x01) #gate 492\r
-        self.M1_SendData(0xEC)\r
-        self.S1_SendCommand(0x61)\r
-        self.S1_SendData(0x02)\r
-        self.S1_SendData(0x90) #source 656\r
-        self.S1_SendData(0x01) #gate 492\r
-        self.S1_SendData(0xEC)\r
-        self.M2_SendCommand(0x61)\r
-        self.M2_SendData(0x02)\r
-        self.M2_SendData(0x90) #source 656\r
-        self.M2_SendData(0x01) #gate 492\r
-        self.M2_SendData(0xEC)\r
-        self.S2_SendCommand(0x61)\r
-        self.S2_SendData(0x02)\r
-        self.S2_SendData(0x88) #source 648\r
-        self.S2_SendData(0x01) #gate 492\r
-        self.S2_SendData(0xEC)\r
-\r
-        self.M1S1M2S2_SendCommand(0x15)        #DUSPI\r
-        self.M1S1M2S2_SendData(0x20)\r
-\r
-        self.M1S1M2S2_SendCommand(0x30)        # PLL\r
-        self.M1S1M2S2_SendData(0x08)\r
-\r
-        self.M1S1M2S2_SendCommand(0x50)        #Vcom and data interval setting\r
-        self.M1S1M2S2_SendData(0x31)\r
-        self.M1S1M2S2_SendData(0x07)\r
-\r
-        self.M1S1M2S2_SendCommand(0x60)#TCON\r
-        self.M1S1M2S2_SendData(0x22)\r
-\r
-        self.M1_SendCommand(0xE0)                      #POWER SETTING\r
-        self.M1_SendData(0x01)\r
-        self.M2_SendCommand(0xE0)                      #POWER SETTING\r
-        self.M2_SendData(0x01)\r
-\r
-        self.M1S1M2S2_SendCommand(0xE3)\r
-        self.M1S1M2S2_SendData(0x00)\r
-\r
-        self.M1_SendCommand(0x82)\r
-        self.M1_SendData(0x1c)\r
-        self.M2_SendCommand(0x82)\r
-        self.M2_SendData(0x1c)\r
-\r
-        self.SetLut()\r
-        \r
-    def display(self, BlackImage, RedImage):\r
-        Blackbuf = [0x00] * int(self.width * self.height / 8)\r
-        blackconvert = BlackImage.convert('1')       \r
-        bimwidth, bimheight = blackconvert.size \r
-        Blackpixles = blackconvert.load()\r
-        temp=0;\r
-        for y in range(0, bimheight):\r
-            for x in range(0, bimwidth):\r
-                if Blackpixles[x, y] < 127:           # black\r
-                    Blackbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
-                else:                           # white\r
-                    Blackbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
-                temp=temp+1\r
-                if(temp==8):\r
-                    temp=0\r
-                    \r
-        Redbuf = [0x00] * int(self.width * self.height / 8)\r
-        redconvert = RedImage.convert('1')\r
-        rimwidth, rimheight = redconvert.size \r
-        Redpixles = redconvert.load()\r
-        temp=0;\r
-        for y in range(0, rimheight):\r
-            for x in range(0, rimwidth):\r
-                if Redpixles[x, y] < 127:           # black\r
-                    Redbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
-                else:                           # white\r
-                    Redbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
-                temp=temp+1\r
-                if(temp==8):\r
-                    temp=0\r
-                    \r
-        #S2 part 648*492\r
-        self.S2_SendCommand(0x10)\r
-        for y in  range(0, 492):\r
-            for x in  range(0, 81):\r
-                self.S2_SendData(Blackbuf[y*163 + x])\r
-        self.S2_SendCommand(0x13)\r
-        for y in  range(0, 492):\r
-            for x in  range(0, 81):\r
-                self.S2_SendData(~Redbuf[y*163 + x])\r
-                \r
-        #M2 part 656*492\r
-        self.M2_SendCommand(0x10)\r
-        for y in  range(0, 492):\r
-            for x in  range(81, 163):\r
-                self.M2_SendData(Blackbuf[y*163 + x])\r
-        self.M2_SendCommand(0x13)\r
-        for y in  range(0, 492):\r
-            for x in  range(81, 163):\r
-                self.M2_SendData(~Redbuf[y*163 + x])\r
-\r
-        #M1 part 648*492    \r
-        self.M1_SendCommand(0x10)\r
-        for y in  range(492, 984):\r
-            for x in  range(0, 81):\r
-                self.M1_SendData(Blackbuf[y*163 + x])\r
-        self.M1_SendCommand(0x13)\r
-        for y in  range(492, 984):\r
-            for x in  range(0, 81):\r
-                self.M1_SendData(~Redbuf[y*163 + x])\r
-        \r
-        #S1 part 656*492\r
-        self.S1_SendCommand(0x10)\r
-        for y in  range(492, 984):\r
-            for x in  range(81, 163):\r
-                self.S1_SendData(Blackbuf[y*163 + x])\r
-        self.S1_SendCommand(0x13)\r
-        for y in  range(492, 984):\r
-            for x in  range(81, 163):\r
-                self.S1_SendData(~Redbuf[y*163 + x])\r
-                \r
-        self.TurnOnDisplay()\r
-\r
-    def clear(self):\r
-        """Clear contents of image buffer"""\r
-        self.S2_SendCommand(0x10)\r
-        for y in  range(0, 492):\r
-            for x in  range(0, 81):\r
-                self.S2_SendData(0xff)        \r
-        self.S2_SendCommand(0x13)\r
-        for y in  range(0, 492):\r
-            for x in  range(0, 81):\r
-                self.S2_SendData(0x00)\r
-                \r
-        self.M2_SendCommand(0x10)\r
-        for y in  range(0, 492):\r
-            for x in  range(81, 163):\r
-                self.M2_SendData(0xff)\r
-        self.M2_SendCommand(0x13)\r
-        for y in  range(0, 492):\r
-            for x in  range(81, 163):\r
-                self.M2_SendData(0x00)       \r
-                    \r
-        self.M1_SendCommand(0x10)\r
-        for y in  range(492, 984):\r
-            for x in  range(0, 81):\r
-                self.M1_SendData(0xff)\r
-        self.M1_SendCommand(0x13)\r
-        for y in  range(492, 984):\r
-            for x in  range(0, 81):\r
-                self.M1_SendData(0x00)\r
-                \r
-        self.S1_SendCommand(0x10)\r
-        for y in  range(492, 984):\r
-            for x in  range(81, 163):\r
-                self.S1_SendData(0xff)\r
-        self.S1_SendCommand(0x13)\r
-        for y in  range(492, 984):\r
-            for x in  range(81, 163):\r
-                self.S1_SendData(0x00)\r
-                \r
-        self.TurnOnDisplay()\r
-        \r
-    def Reset(self):\r
-        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
-        time.sleep(0.2) \r
-        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) \r
-        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) \r
-        time.sleep(0.01) \r
-        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
-        time.sleep(0.2) \r
-\r
-    def sleep(self):\r
-        self.EPD_Sleep()\r
-    \r
-    def EPD_Sleep(self):\r
-        self.M1S1M2S2_SendCommand(0X02)        \r
-        time.sleep(0.3) \r
-\r
-        self.M1S1M2S2_SendCommand(0X07)        \r
-        self.M1S1M2S2_SendData(0xA5) \r
-        time.sleep(0.3) \r
-        print("module_exit")\r
-        epdconfig.module_exit()\r
-\r
-    def TurnOnDisplay(self):\r
-        self.M1M2_SendCommand(0x04)  \r
-        time.sleep(0.3) \r
-        self.M1S1M2S2_SendCommand(0x12) \r
-        self.M1_ReadBusy()\r
-        self.S1_ReadBusy()\r
-        self.M2_ReadBusy()\r
-        self.S2_ReadBusy()   \r
-        \r
-    """   M1S1M2S2 Write register address and data     """\r
-    def M1S1M2S2_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
-        \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd) \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-    \r
-    def M1S1M2S2_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val) \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-\r
-    """   M1M2 Write register address and data     """\r
-    def M1M2_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd) \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-        \r
-    def M1M2_Sendata(self, val): \r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val) \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)   \r
-          \r
-    """   S2 Write register address and data     """\r
-    def S2_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-    def S2_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-        \r
-    """   M2 Write register address and data     """\r
-    def M2_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd) \r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-    def M2_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val) \r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-\r
-    """   S1 Write register address and data     """\r
-    def S1_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-    def S1_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-        \r
-    """   M1 Write register address and data     """\r
-    def M1_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-    def M1_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-\r
-    #Busy\r
-    def M1_ReadBusy(self):\r
-        self.M1_SendCommand(0x71) \r
-        busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
-        busy = not(busy & 0x01) \r
-        while(busy):\r
-            self.M1_SendCommand(0x71) \r
-            busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
-            busy = not(busy & 0x01) \r
-        time.sleep(0.2)\r
-    def M2_ReadBusy(self):\r
-        self.M2_SendCommand(0x71) \r
-        busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
-        busy = not(busy & 0x01) \r
-        self.M2_SendCommand(0x71) \r
-        while(busy):\r
-            self.M2_SendCommand(0x71) \r
-            busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
-            busy =not(busy & 0x01) \r
-        time.sleep(0.2)\r
-    def S1_ReadBusy(self):\r
-        self.S1_SendCommand(0x71) \r
-        busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
-        busy = not(busy & 0x01) \r
-        while(busy):\r
-            self.S1_SendCommand(0x71) \r
-            busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
-            busy = not(busy & 0x01) \r
-        time.sleep(0.2)        \r
-    def S2_ReadBusy(self):\r
-        self.S2_SendCommand(0x71) \r
-        busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
-        busy = not(busy & 0x01) \r
-        while(busy):\r
-            self.S2_SendCommand(0x71) \r
-            busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
-            busy = not(busy & 0x01) \r
-        time.sleep(0.2)            \r
-\r
-    lut_vcom1 = [\r
-        0x00,  0x10,   0x10,   0x01,   0x08,   0x01,\r
-        0x00,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x00,  0x08,   0x01,   0x08,   0x01,   0x06,\r
-        0x00,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
-        0x00,  0x04,   0x05,   0x08,   0x08,   0x01,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-    ]\r
-    lut_ww1 = [\r
-        0x91,  0x10,   0x10,   0x01,   0x08,   0x01,\r
-        0x04,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
-        0x80,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
-        0x08,  0x04,   0x05,   0x08,   0x08,   0x01,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-    ]\r
-    lut_bw1 = [\r
-        0xA8,  0x10,   0x10,   0x01,   0x08,   0x01,\r
-        0x84,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
-        0x86,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x8C,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
-        0x8C,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
-        0xF0,  0x04,   0x05,   0x08,   0x08,   0x01,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-    ]\r
-    lut_wb1 = [\r
-        0x91,  0x10,   0x10,   0x01,   0x08,   0x01,\r
-        0x04,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
-        0x80,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
-        0x08,  0x04,   0x05,   0x08,   0x08,   0x01,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-    ]\r
-    lut_bb1 = [\r
-        0x92,  0x10,   0x10,   0x01,   0x08,   0x01,\r
-        0x80,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
-        0x04,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
-        0x01,  0x04,   0x05,   0x08,   0x08,   0x01,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-    ]\r
-    \r
-    def SetLut(self):\r
-        self.M1S1M2S2_SendCommand(0x20) #vcom\r
-        for count in range(0, 60):\r
-            self.M1S1M2S2_SendData(self.lut_vcom1[count])\r
-\r
-        self.M1S1M2S2_SendCommand(0x21) #red not use\r
-        for count in range(0, 60):\r
-            self.M1S1M2S2_SendData(self.lut_ww1[count])\r
-\r
-        self.M1S1M2S2_SendCommand(0x22) #bw r\r
-        for count in range(0, 60):\r
-            self.M1S1M2S2_SendData(self.lut_bw1[count])   # bw=r\r
-\r
-        self.M1S1M2S2_SendCommand(0x23) #wb w\r
-        for count in range(0, 60):\r
-            self.M1S1M2S2_SendData(self.lut_wb1[count])   # wb=w\r
-\r
-        self.M1S1M2S2_SendCommand(0x24) #bb b\r
-        for count in range(0, 60):\r
-            self.M1S1M2S2_SendData(self.lut_bb1[count])   # bb=b\r
-            \r
-        self.M1S1M2S2_SendCommand(0x25) #bb b\r
-        for count in range(0, 60):\r
-            self.M1S1M2S2_SendData(self.lut_ww1[count])   # bb=b\r
diff --git a/src/drivers/epd12in48b_V2.py b/src/drivers/epd12in48b_V2.py
deleted file mode 100644 (file)
index b6e90a2..0000000
+++ /dev/null
@@ -1,529 +0,0 @@
-# /*****************************************************************************\r
-# * | File        :      epd12in48b_V2.py\r
-# * | Author      :   Waveshare electrices\r
-# * | Function    :   Hardware underlying interface\r
-# * | Info        :\r
-# *----------------\r
-# * | This version:   V1.0\r
-# * | Date        :   2022-09-14\r
-# * | Info        :   \r
-# ******************************************************************************/\r
-# Permission is hereby granted, free of charge, to any person obtaining a copy\r
-# of this software and associated documnetation files (the "Software"), to deal\r
-# in the Software without restriction, including without limitation the rights\r
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-# copies of the Software, and to permit persons to  whom the Software is\r
-# furished to do so, subject to the following conditions:\r
-#\r
-# The above copyright notice and this permission notice shall be included in\r
-# all copies or substantial portions of the Software.\r
-#\r
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
-# THE SOFTWARE.\r
-#\r
-import time\r
-import epdconfig\r
-\r
-EPD_WIDTH       = 1304\r
-EPD_HEIGHT      = 984\r
-\r
-class EPD(object):\r
-    def __init__(self):\r
-        self.width = EPD_WIDTH\r
-        self.height = EPD_HEIGHT\r
-        \r
-        self.EPD_M1_CS_PIN  = epdconfig.EPD_M1_CS_PIN\r
-        self.EPD_S1_CS_PIN  = epdconfig.EPD_S1_CS_PIN\r
-        self.EPD_M2_CS_PIN  = epdconfig.EPD_M2_CS_PIN\r
-        self.EPD_S2_CS_PIN  = epdconfig.EPD_S2_CS_PIN\r
-\r
-        self.EPD_M1S1_DC_PIN  = epdconfig.EPD_M1S1_DC_PIN\r
-        self.EPD_M2S2_DC_PIN  = epdconfig.EPD_M2S2_DC_PIN\r
-\r
-        self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN\r
-        self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN\r
-\r
-        self.EPD_M1_BUSY_PIN  = epdconfig.EPD_M1_BUSY_PIN\r
-        self.EPD_S1_BUSY_PIN  = epdconfig.EPD_S1_BUSY_PIN\r
-        self.EPD_M2_BUSY_PIN  = epdconfig.EPD_M2_BUSY_PIN\r
-        self.EPD_S2_BUSY_PIN  = epdconfig.EPD_S2_BUSY_PIN\r
-\r
-    def Init(self):\r
-        print("EPD init...")\r
-        epdconfig.module_init()\r
-        \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
-        self.Reset() \r
-\r
-        # panel setting for Clear\r
-        # self.M1_SendCommand(0x00)\r
-        # self.M1_SendData(0x07)       #KW-3f   KWR-2F BWROTP 0f       BWOTP 1f\r
-        # self.S1_SendCommand(0x00)\r
-        # self.S1_SendData(0x07)\r
-        # self.M2_SendCommand(0x00)\r
-        # self.M2_SendData(0x07)\r
-        # self.S2_SendCommand(0x00)\r
-        # self.S2_SendData(0x07)\r
-\r
-        # panel setting for Display\r
-        self.M1_SendCommand(0x00)\r
-        self.M1_SendData(0x0f) #KW-3f   KWR-2F BWROTP 0f       BWOTP 1f\r
-        self.S1_SendCommand(0x00)\r
-        self.S1_SendData(0x0f)\r
-        self.M2_SendCommand(0x00)\r
-        self.M2_SendData(0x03)\r
-        self.S2_SendCommand(0x00)\r
-        self.S2_SendData(0x03)\r
-\r
-        # booster soft start\r
-        self.M1_SendCommand(0x06)\r
-        self.M1_SendData(0x17) #A\r
-        self.M1_SendData(0x17) #B\r
-        self.M1_SendData(0x39) #C\r
-        self.M1_SendData(0x17)\r
-        self.M2_SendCommand(0x06)\r
-        self.M2_SendData(0x17)\r
-        self.M2_SendData(0x17)\r
-        self.M2_SendData(0x39)\r
-        self.M2_SendData(0x17)\r
-\r
-        #resolution setting\r
-        self.M1_SendCommand(0x61)\r
-        self.M1_SendData(0x02)\r
-        self.M1_SendData(0x88) #source 648\r
-        self.M1_SendData(0x01) #gate 492\r
-        self.M1_SendData(0xEC)\r
-        self.S1_SendCommand(0x61)\r
-        self.S1_SendData(0x02)\r
-        self.S1_SendData(0x90) #source 656\r
-        self.S1_SendData(0x01) #gate 492\r
-        self.S1_SendData(0xEC)\r
-        self.M2_SendCommand(0x61)\r
-        self.M2_SendData(0x02)\r
-        self.M2_SendData(0x90) #source 656\r
-        self.M2_SendData(0x01) #gate 492\r
-        self.M2_SendData(0xEC)\r
-        self.S2_SendCommand(0x61)\r
-        self.S2_SendData(0x02)\r
-        self.S2_SendData(0x88) #source 648\r
-        self.S2_SendData(0x01) #gate 492\r
-        self.S2_SendData(0xEC)\r
-\r
-        self.M1S1M2S2_SendCommand(0x15)        #DUSPI\r
-        self.M1S1M2S2_SendData(0x20)\r
-\r
-        self.M1S1M2S2_SendCommand(0x50)        #Vcom and data interval setting\r
-        self.M1S1M2S2_SendData(0x11)\r
-        self.M1S1M2S2_SendData(0x07)\r
-\r
-        self.M1S1M2S2_SendCommand(0x60)#TCON\r
-        self.M1S1M2S2_SendData(0x22)\r
-\r
-        self.M1S1M2S2_SendCommand(0xE3)\r
-        self.M1S1M2S2_SendData(0x00)\r
-\r
-        self.M1_ReadTemperature()\r
-        \r
-    def display(self, BlackImage, RedImage):\r
-        start = time.perf_counter()\r
-        \r
-        Blackbuf = [0x00] * int(self.width * self.height / 8)\r
-        blackconvert = BlackImage.convert('1')       \r
-        bimwidth, bimheight = blackconvert.size \r
-        Blackpixles = blackconvert.load()\r
-        temp=0\r
-        for y in range(0, bimheight):\r
-            for x in range(0, bimwidth):\r
-                if Blackpixles[x, y] < 127:           # black\r
-                    Blackbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
-                else:                           # white\r
-                    Blackbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
-                temp=temp+1\r
-                if(temp==8):\r
-                    temp=0\r
-                    \r
-        Redbuf = [0x00] * int(self.width * self.height / 8)\r
-        redconvert = RedImage.convert('1')\r
-        rimwidth, rimheight = redconvert.size \r
-        Redpixles = redconvert.load()\r
-        temp=0\r
-        for y in range(0, rimheight):\r
-            for x in range(0, rimwidth):\r
-                if Redpixles[x, y] < 127:           # black\r
-                    Redbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
-                else:                           # white\r
-                    Redbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
-                temp=temp+1\r
-                if(temp==8):\r
-                    temp=0\r
-                    \r
-        #S2 part 648*492\r
-        self.S2_SendCommand(0x10)\r
-        for y in  range(0, 492):\r
-            for x in  range(0, 81):\r
-                self.S2_SendData(Blackbuf[y*163 + x])\r
-        self.S2_SendCommand(0x13)\r
-        for y in  range(0, 492):\r
-            for x in  range(0, 81):\r
-                self.S2_SendData(~Redbuf[y*163 + x])\r
-                \r
-        #M2 part 656*492\r
-        self.M2_SendCommand(0x10)\r
-        for y in  range(0, 492):\r
-            for x in  range(81, 163):\r
-                self.M2_SendData(Blackbuf[y*163 + x])\r
-        self.M2_SendCommand(0x13)\r
-        for y in  range(0, 492):\r
-            for x in  range(81, 163):\r
-                self.M2_SendData(~Redbuf[y*163 + x])\r
-\r
-        #M1 part 648*492    \r
-        self.M1_SendCommand(0x10)\r
-        for y in  range(492, 984):\r
-            for x in  range(0, 81):\r
-                self.M1_SendData(Blackbuf[y*163 + x])\r
-        self.M1_SendCommand(0x13)\r
-        for y in  range(492, 984):\r
-            for x in  range(0, 81):\r
-                self.M1_SendData(~Redbuf[y*163 + x])\r
-        \r
-        #S1 part 656*492\r
-        self.S1_SendCommand(0x10)\r
-        for y in  range(492, 984):\r
-            for x in  range(81, 163):\r
-                self.S1_SendData(Blackbuf[y*163 + x])\r
-        self.S1_SendCommand(0x13)\r
-        for y in  range(492, 984):\r
-            for x in  range(81, 163):\r
-                self.S1_SendData(~Redbuf[y*163 + x])\r
-                \r
-        end = time.perf_counter()\r
-        print("use time: %f"%(end - start))\r
-        self.TurnOnDisplay()\r
-\r
-    def clear(self):\r
-        """Clear contents of image buffer"""\r
-        start = time.perf_counter()\r
-        \r
-        self.S2_SendCommand(0x10)\r
-        for y in  range(0, 492):\r
-            for x in  range(0, 81):\r
-                self.S2_SendData(0xff)        \r
-        self.S2_SendCommand(0x13)\r
-        for y in  range(0, 492):\r
-            for x in  range(0, 81):\r
-                self.S2_SendData(0x00)\r
-                \r
-        self.M2_SendCommand(0x10)\r
-        for y in  range(0, 492):\r
-            for x in  range(81, 163):\r
-                self.M2_SendData(0xff)\r
-        self.M2_SendCommand(0x13)\r
-        for y in  range(0, 492):\r
-            for x in  range(81, 163):\r
-                self.M2_SendData(0x00)       \r
-                    \r
-        self.M1_SendCommand(0x10)\r
-        for y in  range(492, 984):\r
-            for x in  range(0, 81):\r
-                self.M1_SendData(0xff)\r
-        self.M1_SendCommand(0x13)\r
-        for y in  range(492, 984):\r
-            for x in  range(0, 81):\r
-                self.M1_SendData(0x00)\r
-                \r
-        self.S1_SendCommand(0x10)\r
-        for y in  range(492, 984):\r
-            for x in  range(81, 163):\r
-                self.S1_SendData(0xff)\r
-        self.S1_SendCommand(0x13)\r
-        for y in  range(492, 984):\r
-            for x in  range(81, 163):\r
-                self.S1_SendData(0x00)\r
-                \r
-        end = time.perf_counter()\r
-        print (end)\r
-        print (start)\r
-        print("use time: %f" %(end - start))\r
-        \r
-        self.TurnOnDisplay()\r
-        \r
-    def Reset(self):\r
-        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
-        time.sleep(0.2) \r
-        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) \r
-        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) \r
-        time.sleep(0.01) \r
-        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
-        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
-        time.sleep(0.2) \r
-    \r
-    def EPD_Sleep(self):\r
-        self.M1S1M2S2_SendCommand(0X02)        \r
-        time.sleep(0.3) \r
-\r
-        self.M1S1M2S2_SendCommand(0X07)        \r
-        self.M1S1M2S2_SendData(0xA5) \r
-        time.sleep(0.3) \r
-        print("module_exit")\r
-        epdconfig.module_exit()\r
-\r
-    def TurnOnDisplay(self):\r
-        self.M1M2_SendCommand(0x04)  \r
-        time.sleep(0.3) \r
-        self.M1S1M2S2_SendCommand(0x12) \r
-        self.M1_ReadBusy()\r
-        self.S1_ReadBusy()\r
-        self.M2_ReadBusy()\r
-        self.S2_ReadBusy()   \r
-        \r
-    """   M1S1M2S2 Write register address and data     """\r
-    def M1S1M2S2_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
-        \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd) \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-    \r
-    def M1S1M2S2_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val) \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-\r
-    """   M1M2 Write register address and data     """\r
-    def M1M2_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd) \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-        \r
-    def M1M2_Sendata(self, val): \r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val) \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)   \r
-          \r
-    """   S2 Write register address and data     """\r
-    def S2_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-    def S2_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-        \r
-    """   M2 Write register address and data     """\r
-    def M2_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd) \r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-    def M2_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val) \r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-\r
-    """   S1 Write register address and data     """\r
-    def S1_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-    def S1_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-        \r
-    """   M1 Write register address and data     """\r
-    def M1_SendCommand(self, cmd):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(cmd)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-    def M1_SendData(self, val):\r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.spi_writebyte(val)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-\r
-    #Busy\r
-    def M1_ReadBusy(self):\r
-        self.M1_SendCommand(0x71) \r
-        busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
-        busy = not(busy & 0x01) \r
-        while(busy):\r
-            self.M1_SendCommand(0x71) \r
-            busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
-            busy = not(busy & 0x01) \r
-        time.sleep(0.2)\r
-    def M2_ReadBusy(self):\r
-        self.M2_SendCommand(0x71) \r
-        busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
-        busy = not(busy & 0x01) \r
-        self.M2_SendCommand(0x71) \r
-        while(busy):\r
-            self.M2_SendCommand(0x71) \r
-            busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
-            busy =not(busy & 0x01) \r
-        time.sleep(0.2)\r
-    def S1_ReadBusy(self):\r
-        self.S1_SendCommand(0x71) \r
-        busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
-        busy = not(busy & 0x01) \r
-        while(busy):\r
-            self.S1_SendCommand(0x71) \r
-            busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
-            busy = not(busy & 0x01) \r
-        time.sleep(0.2)        \r
-    def S2_ReadBusy(self):\r
-        self.S2_SendCommand(0x71) \r
-        busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
-        busy = not(busy & 0x01) \r
-        while(busy):\r
-            self.S2_SendCommand(0x71) \r
-            busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
-            busy = not(busy & 0x01) \r
-        time.sleep(0.2)            \r
-\r
-    lut_vcom1 = [\r
-        0x00,  0x10,   0x10,   0x01,   0x08,   0x01,\r
-        0x00,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x00,  0x08,   0x01,   0x08,   0x01,   0x06,\r
-        0x00,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
-        0x00,  0x04,   0x05,   0x08,   0x08,   0x01,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-    ]\r
-    lut_ww1 = [\r
-        0x91,  0x10,   0x10,   0x01,   0x08,   0x01,\r
-        0x04,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
-        0x80,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
-        0x08,  0x04,   0x05,   0x08,   0x08,   0x01,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-    ]\r
-    lut_bw1 = [\r
-        0xA8,  0x10,   0x10,   0x01,   0x08,   0x01,\r
-        0x84,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
-        0x86,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x8C,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
-        0x8C,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
-        0xF0,  0x04,   0x05,   0x08,   0x08,   0x01,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-    ]\r
-    lut_wb1 = [\r
-        0x91,  0x10,   0x10,   0x01,   0x08,   0x01,\r
-        0x04,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
-        0x80,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
-        0x08,  0x04,   0x05,   0x08,   0x08,   0x01,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-    ]\r
-    lut_bb1 = [\r
-        0x92,  0x10,   0x10,   0x01,   0x08,   0x01,\r
-        0x80,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
-        0x04,  0x06,   0x01,   0x06,   0x01,   0x05,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
-        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
-        0x01,  0x04,   0x05,   0x08,   0x08,   0x01,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
-    ]\r
-    \r
-    def SetLut(self):\r
-        self.M1S1M2S2_SendCommand(0x20) #vcom\r
-        for count in range(0, 60):\r
-            self.M1S1M2S2_SendData(self.lut_vcom1[count])\r
-\r
-        self.M1S1M2S2_SendCommand(0x21) #red not use\r
-        for count in range(0, 60):\r
-            self.M1S1M2S2_SendData(self.lut_ww1[count])\r
-\r
-        self.M1S1M2S2_SendCommand(0x22) #bw r\r
-        for count in range(0, 60):\r
-            self.M1S1M2S2_SendData(self.lut_bw1[count])   # bw=r\r
-\r
-        self.M1S1M2S2_SendCommand(0x23) #wb w\r
-        for count in range(0, 60):\r
-            self.M1S1M2S2_SendData(self.lut_wb1[count])   # wb=w\r
-\r
-        self.M1S1M2S2_SendCommand(0x24) #bb b\r
-        for count in range(0, 60):\r
-            self.M1S1M2S2_SendData(self.lut_bb1[count])   # bb=b\r
-            \r
-        self.M1S1M2S2_SendCommand(0x25) #bb b\r
-        for count in range(0, 60):\r
-            self.M1S1M2S2_SendData(self.lut_ww1[count])   # bb=b\r
-\r
-    def M1_ReadTemperature(self):\r
-        self.M1_SendCommand(0x40)\r
-        self.M1_ReadBusy()\r
-        time.sleep(0.3)\r
-        \r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
-        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
-        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
-        \r
-        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
-        time.sleep(0.05)\r
-        \r
-        temp = epdconfig.spi_readbyte(0x00)\r
-        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
-        \r
-        self.M1S1M2S2_SendCommand(0xE0)\r
-        self.M1S1M2S2_SendData(0x03)\r
-        self.M1S1M2S2_SendCommand(0xE5)\r
-        self.M1S1M2S2_SendData(temp)\r
diff --git a/src/drivers/epd_12_in_48_lib_32bit.so b/src/drivers/epd_12_in_48_lib_32bit.so
deleted file mode 100644 (file)
index acdbb26..0000000
Binary files a/src/drivers/epd_12_in_48_lib_32bit.so and /dev/null differ
diff --git a/src/drivers/epd_12_in_48_lib_64bit.so b/src/drivers/epd_12_in_48_lib_64bit.so
deleted file mode 100644 (file)
index ed8ae87..0000000
Binary files a/src/drivers/epd_12_in_48_lib_64bit.so and /dev/null differ
diff --git a/src/drivers/epdconfig.py b/src/drivers/epdconfig.py
deleted file mode 100644 (file)
index c70a1f1..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-# /*****************************************************************************\r
-# * | File        :      epdconfig.py\r
-# * | Author      :   Waveshare electrices\r
-# * | Function    :   Hardware underlying interface\r
-# * | Info        :\r
-# *----------------\r
-# * |  This version:   V1.0\r
-# * | Date        :   2019-11-01\r
-# * | Info        :   \r
-# ******************************************************************************/\r
-# Permission is hereby granted, free of charge, to any person obtaining a copy\r
-# of this software and associated documnetation files (the "Software"), to deal\r
-# in the Software without restriction, including without limitation the rights\r
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
-# copies of the Software, and to permit persons to  whom the Software is\r
-# furished to do so, subject to the following conditions:\r
-#\r
-# The above copyright notice and this permission notice shall be included in\r
-# all copies or substantial portions of the Software.\r
-#\r
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
-# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
-# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
-# THE SOFTWARE.\r
-#\r
-import time\r
-import os\r
-import logging\r
-import sys\r
-\r
-from ctypes import *\r
-\r
-EPD_SCK_PIN   =11\r
-EPD_MOSI_PIN  =10\r
-\r
-EPD_M1_CS_PIN  =8\r
-EPD_S1_CS_PIN  =7\r
-EPD_M2_CS_PIN  =17\r
-EPD_S2_CS_PIN  =18\r
-\r
-EPD_M1S1_DC_PIN  =13\r
-EPD_M2S2_DC_PIN  =22\r
-\r
-EPD_M1S1_RST_PIN =6\r
-EPD_M2S2_RST_PIN =23\r
-\r
-EPD_M1_BUSY_PIN  =5\r
-EPD_S1_BUSY_PIN  =19\r
-EPD_M2_BUSY_PIN  =27\r
-EPD_S2_BUSY_PIN  =24\r
-\r
-find_dirs = [\r
-    os.path.dirname(os.path.realpath(__file__)),\r
-    '/usr/local/lib',\r
-    '/usr/lib',\r
-]\r
-spi = None\r
-for find_dir in find_dirs:\r
-    val = int(os.popen('getconf LONG_BIT').read())\r
-    logging.debug("System is %d bit"%val)\r
-    if val == 64:\r
-        so_filename = os.path.join(find_dir, 'epd_12_in_48_lib_64bit.so')\r
-    else:\r
-        so_filename = os.path.join(find_dir, 'epd_12_in_48_lib_32bit.so')\r
-    if os.path.exists(so_filename):\r
-        spi = CDLL(so_filename)\r
-        break\r
-if spi is None:\r
-    RuntimeError('Cannot find DEV_Config.so')\r
-\r
-def digital_write(pin, value):\r
-    spi.DEV_Digital_Write(pin, value)\r
-\r
-def digital_read(pin):\r
-    return spi.DEV_Digital_Read(pin)\r
-\r
-def spi_writebyte(value): \r
-    spi.DEV_SPI_WriteByte(value)\r
\r
-def delay_ms(delaytime):\r
-    time.sleep(delaytime / 1000.0)\r
-        \r
-def module_init():\r
-    spi.DEV_ModuleInit()\r
-\r
-def module_exit():\r
-    spi.DEV_ModuleExit()\r
-\r
-\r
-def spi_readbyte(Reg):\r
-    return spi.DEV_SPI_ReadByte(Reg)\r
-    \r
-def delay_ms(delaytime):\r
-    time.sleep(delaytime / 1000.0)\r
-\r
-  \r
diff --git a/src/epaper_display/__init__.py b/src/epaper_display/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/epaper_display/display.py b/src/epaper_display/display.py
new file mode 100644 (file)
index 0000000..1899d42
--- /dev/null
@@ -0,0 +1,47 @@
+"""
+"""
+
+from logging import Logger
+
+import PIL
+from PIL import Image
+
+from drivers.epd12in48b import EPD, EPD_HEIGHT, EPD_WIDTH
+
+logger = Logger(__name__)
+
+
+class Display:
+
+    def __init__(self) -> None:
+        self.width = EPD_WIDTH
+        self.height = EPD_HEIGHT
+        self.epaper = EPD()
+
+    def render(self, black: Image, red: Image):
+        logger.info("Init display")
+        self.epaper.init()
+        logger.info("Update display")
+        self.epaper.display(black, red)
+        logger.info("Sleep display")
+        self.epaper.sleep()
+
+    def calibrate(self, iterations=1):
+        logger.info("Init display for calibration")
+        self.epaper.init()
+
+        white = Image.new('1', (self.width, self.height), 'white')
+        black = Image.new('1', (self.width, self.height), 'black')
+
+        logger.info('Calibrating e-paper display')
+        for i in range(iterations):
+            logger.info('black')
+            self.epaper.display(black, white)
+            logger.info('red')
+            self.epaper.display(white, black)
+            logger.info('white')
+            self.epaper.display(white, white)
+            logger.info(f'#{i + 1} of {iterations} complete')
+
+        self.epaper.sleep()
+
diff --git a/src/epaper_display/drivers/__init__.py b/src/epaper_display/drivers/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/src/epaper_display/drivers/epd12in48.py b/src/epaper_display/drivers/epd12in48.py
new file mode 100644 (file)
index 0000000..16b33f5
--- /dev/null
@@ -0,0 +1,398 @@
+# /*****************************************************************************\r
+# * | File        :      epd12in48.py\r
+# * | Author      :   Waveshare electrices\r
+# * | Function    :   Hardware underlying interface\r
+# * | Info        :\r
+# *----------------\r
+# * |  This version:   V1.0\r
+# * | Date        :   2019-11-01\r
+# * | Info        :   \r
+# ******************************************************************************/\r
+# Permission is hereby granted, free of charge, to any person obtaining a copy\r
+# of this software and associated documnetation files (the "Software"), to deal\r
+# in the Software without restriction, including without limitation the rights\r
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+# copies of the Software, and to permit persons to  whom the Software is\r
+# furished to do so, subject to the following conditions:\r
+#\r
+# The above copyright notice and this permission notice shall be included in\r
+# all copies or substantial portions of the Software.\r
+#\r
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+# THE SOFTWARE.\r
+#\r
+import time\r
+import epdconfig\r
+\r
+EPD_WIDTH       = 1304\r
+EPD_HEIGHT      = 984\r
+\r
+class EPD(object):\r
+    def __init__(self):\r
+        self.width = EPD_WIDTH\r
+        self.height = EPD_HEIGHT\r
+        \r
+        self.EPD_M1_CS_PIN  = epdconfig.EPD_M1_CS_PIN\r
+        self.EPD_S1_CS_PIN  = epdconfig.EPD_S1_CS_PIN\r
+        self.EPD_M2_CS_PIN  = epdconfig.EPD_M2_CS_PIN\r
+        self.EPD_S2_CS_PIN  = epdconfig.EPD_S2_CS_PIN\r
+\r
+        self.EPD_M1S1_DC_PIN  = epdconfig.EPD_M1S1_DC_PIN\r
+        self.EPD_M2S2_DC_PIN  = epdconfig.EPD_M2S2_DC_PIN\r
+\r
+        self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN\r
+        self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN\r
+\r
+        self.EPD_M1_BUSY_PIN  = epdconfig.EPD_M1_BUSY_PIN\r
+        self.EPD_S1_BUSY_PIN  = epdconfig.EPD_S1_BUSY_PIN\r
+        self.EPD_M2_BUSY_PIN  = epdconfig.EPD_M2_BUSY_PIN\r
+        self.EPD_S2_BUSY_PIN  = epdconfig.EPD_S2_BUSY_PIN\r
+\r
+    def Init(self):\r
+        print("EPD init...")\r
+        epdconfig.module_init()\r
+        \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
+        self.Reset() \r
+\r
+        #panel setting\r
+        self.M1_SendCommand(0x00) \r
+        self.M1_SendData(0x1f)         #KW-3f   KWR-2F BWROTP 0f       BWOTP 1f\r
+        self.S1_SendCommand(0x00) \r
+        self.S1_SendData(0x1f) \r
+        self.M2_SendCommand(0x00) \r
+        self.M2_SendData(0x13) \r
+        self.S2_SendCommand(0x00) \r
+        self.S2_SendData(0x13) \r
+\r
+        # booster soft start\r
+        self.M1_SendCommand(0x06) \r
+        self.M1_SendData(0x17)         #A\r
+        self.M1_SendData(0x17)         #B\r
+        self.M1_SendData(0x39)         #C\r
+        self.M1_SendData(0x17) \r
+        self.M2_SendCommand(0x06) \r
+        self.M2_SendData(0x17) \r
+        self.M2_SendData(0x17) \r
+        self.M2_SendData(0x39) \r
+        self.M2_SendData(0x17) \r
+\r
+        #resolution setting\r
+        self.M1_SendCommand(0x61) \r
+        self.M1_SendData(0x02) \r
+        self.M1_SendData(0x88)         #source 648\r
+        self.M1_SendData(0x01)         #gate 492\r
+        self.M1_SendData(0xEC) \r
+        self.S1_SendCommand(0x61) \r
+        self.S1_SendData(0x02) \r
+        self.S1_SendData(0x90)         #source 656\r
+        self.S1_SendData(0x01)         #gate 492\r
+        self.S1_SendData(0xEC) \r
+        self.M2_SendCommand(0x61) \r
+        self.M2_SendData(0x02) \r
+        self.M2_SendData(0x90)         #source 656\r
+        self.M2_SendData(0x01)         #gate 492\r
+        self.M2_SendData(0xEC) \r
+        self.S2_SendCommand(0x61) \r
+        self.S2_SendData(0x02) \r
+        self.S2_SendData(0x88)         #source 648\r
+        self.S2_SendData(0x01)         #gate 492\r
+        self.S2_SendData(0xEC) \r
+\r
+        self.M1S1M2S2_SendCommand(0x15)        #DUSPI\r
+        self.M1S1M2S2_SendData(0x20) \r
+\r
+        self.M1S1M2S2_SendCommand(0x50)        #Vcom and data interval setting\r
+        self.M1S1M2S2_SendData(0x21)  #Border KW\r
+        self.M1S1M2S2_SendData(0x07) \r
+\r
+        self.M1S1M2S2_SendCommand(0x60) #TCON\r
+        self.M1S1M2S2_SendData(0x22) \r
+\r
+        self.M1S1M2S2_SendCommand(0xE3) \r
+        self.M1S1M2S2_SendData(0x00) \r
+\r
+        #temperature\r
+        temp =  self.M1_ReadTemperature() \r
+\r
+        self.M1S1M2S2_SendCommand(0xe0) #Cascade setting\r
+        self.M1S1M2S2_SendData(0x03) \r
+        self.M1S1M2S2_SendCommand(0xe5) #Force temperature\r
+        self.M1S1M2S2_SendData(temp)\r
+        \r
+    def display(self, Image):\r
+        start = time.clock()\r
+        buf = [0x00] * int(self.width * self.height / 8)\r
+        image_monocolor = Image.convert('1')\r
+        imwidth, imheight = image_monocolor.size \r
+        pixels = image_monocolor.load()\r
+        temp=0;\r
+        for y in range(0, imheight):\r
+                for x in range(0, imwidth):\r
+                    # Set the bits for the column of pixels at the current position.\r
+                    if pixels[x, y] < 127:           # black\r
+                        buf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
+                    else:                           # white\r
+                        buf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
+                    temp=temp+1\r
+                    if(temp==8):\r
+                        temp=0\r
+\r
+        #M1 part 648*492    \r
+        self.M1_SendCommand(0x13)\r
+        for y in  range(492, 984):\r
+            for x in  range(0, 81):\r
+                    self.M1_SendData(buf[y*163 + x])\r
+\r
+        #S1 part 656*492\r
+        self.S1_SendCommand(0x13)\r
+        for y in  range(492, 984):\r
+            for x in  range(81, 163):\r
+                self.S1_SendData(buf[y*163 + x])\r
+\r
+        #M2 part 656*492\r
+        self.M2_SendCommand(0x13)\r
+        for y in  range(0, 492):\r
+            for x in  range(81, 163):\r
+                self.M2_SendData(buf[y*163 + x])\r
+\r
+        #S2 part 648*492\r
+        self.S2_SendCommand(0x13)\r
+        for y in  range(0, 492):\r
+            for x in  range(0, 81):\r
+                self.S2_SendData(buf[y*163 + x])\r
+                \r
+        end = time.clock()\r
+        print("use time:%f"%(end - start))\r
+        self.TurnOnDisplay()\r
+\r
+    def clear(self):\r
+        """Clear contents of image buffer"""\r
+        start = time.clock()\r
+        self.M1_SendCommand(0x13)\r
+        for y in  range(492, 984):\r
+            for x in  range(0, 81):\r
+                self.M1_SendData(0xff)\r
+\r
+        self.S1_SendCommand(0x13)\r
+        for y in  range(492, 984):\r
+            for x in  range(81, 163):\r
+                self.S1_SendData(0xff)\r
+    \r
+        self.M2_SendCommand(0x13)\r
+        for y in  range(0, 492):\r
+            for x in  range(81, 163):\r
+                self.M2_SendData(0xff)\r
+\r
+        self.S2_SendCommand(0x13)\r
+        for y in  range(0, 492):\r
+            for x in  range(0, 81):\r
+                self.S2_SendData(0xff)\r
+        end = time.clock()\r
+        print("use time:%f"%(end - start))\r
+        self.TurnOnDisplay()\r
+        \r
+    """   M1S1M2S2 Write register address and data     """\r
+    def M1S1M2S2_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+        \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd) \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+    \r
+    def M1S1M2S2_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val) \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+\r
+    """   M1M2 Write register address and data     """\r
+    def M1M2_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd) \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+        \r
+    def M1S1M2S2_Senddata(self, val): \r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val) \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)   \r
+          \r
+    """   S2 Write register address and data     """\r
+    def S2_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+\r
+\r
+    def S2_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+        \r
+    """   M2 Write register address and data     """\r
+    def M2_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd) \r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+\r
+    def M2_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val) \r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+\r
+    """   S1 Write register address and data     """\r
+    def S1_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+\r
+    def S1_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+        \r
+    """   M1 Write register address and data     """\r
+    def M1_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+\r
+    def M1_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+\r
+    def Reset(self):\r
+        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
+        time.sleep(0.2) \r
+        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) \r
+        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) \r
+        time.sleep(0.01) \r
+        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
+        time.sleep(0.2) \r
+    \r
+    def EPD_Sleep(self):\r
+        self.M1S1M2S2_SendCommand(0X02)        \r
+        time.sleep(0.3) \r
+\r
+        self.M1S1M2S2_SendCommand(0X07)        \r
+        self.M1S1M2S2_SendData(0xA5) \r
+        time.sleep(0.3) \r
+        print("module_exit")\r
+        epdconfig.module_exit()\r
+        \r
+        \r
+    def TurnOnDisplay(self):\r
+        self.M1M2_SendCommand(0x04)  \r
+        time.sleep(0.3) \r
+        self.M1S1M2S2_SendCommand(0x12) \r
+        self.M1_ReadBusy()\r
+        self.S1_ReadBusy()\r
+        self.M2_ReadBusy()\r
+        self.S2_ReadBusy()\r
+    \r
+    #Busy\r
+    def M1_ReadBusy(self):\r
+        self.M1_SendCommand(0x71) \r
+        busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
+        busy = not(busy & 0x01) \r
+        print("M1_ReadBusy")\r
+        while(busy):\r
+            self.M1_SendCommand(0x71) \r
+            busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
+            busy = not(busy & 0x01) \r
+        time.sleep(0.2)\r
+        \r
+    def M2_ReadBusy(self):\r
+        self.M2_SendCommand(0x71) \r
+        busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
+        busy = not(busy & 0x01) \r
+        print("M2_ReadBusy")\r
+        while(busy):\r
+            self.M2_SendCommand(0x71) \r
+            busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
+            busy =not(busy & 0x01) \r
+        time.sleep(0.2)   \r
+        \r
+    def S1_ReadBusy(self):\r
+        self.S1_SendCommand(0x71) \r
+        busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
+        busy = not(busy & 0x01) \r
+        print("s1_ReadBusy")\r
+        while(busy):\r
+            self.S1_SendCommand(0x71) \r
+            busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
+            busy = not(busy & 0x01) \r
+        time.sleep(0.2)   \r
+        \r
+    def S2_ReadBusy(self):\r
+        self.S2_SendCommand(0x71) \r
+        busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
+        busy = not(busy & 0x01) \r
+        print("S2_ReadBusy")\r
+        while(busy):\r
+            self.S2_SendCommand(0x71) \r
+            busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
+            busy = not(busy & 0x01) \r
+        time.sleep(0.2)            \r
+        \r
+    def M1_ReadTemperature(self):\r
+        self.M1_SendCommand(0x40) \r
+        self.M1_ReadBusy() \r
+        time.sleep(0.3) \r
+\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0) \r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
+        \r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1) \r
+        time.sleep(0.01) \r
+        \r
+        # temp = epdconfig.spi_readbyte(0x00)\r
+        temp = 25\r
+        print("Read Temperature Reg:%d"%temp)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
+        # temp =0x29\r
+        return temp \r
diff --git a/src/epaper_display/drivers/epd12in48b.py b/src/epaper_display/drivers/epd12in48b.py
new file mode 100644 (file)
index 0000000..e4035a4
--- /dev/null
@@ -0,0 +1,520 @@
+# /*****************************************************************************\r
+# * | File        :      epd12in48.py\r
+# * | Author      :   Waveshare electrices\r
+# * | Function    :   Hardware underlying interface\r
+# * | Info        :\r
+# *----------------\r
+# * |  This version:   V1.0\r
+# * | Date        :   2019-11-01\r
+# * | Info        :   \r
+# ******************************************************************************/\r
+# Permission is hereby granted, free of charge, to any person obtaining a copy\r
+# of this software and associated documnetation files (the "Software"), to deal\r
+# in the Software without restriction, including without limitation the rights\r
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+# copies of the Software, and to permit persons to  whom the Software is\r
+# furished to do so, subject to the following conditions:\r
+#\r
+# The above copyright notice and this permission notice shall be included in\r
+# all copies or substantial portions of the Software.\r
+#\r
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+# THE SOFTWARE.\r
+#\r
+import time\r
+from . import epdconfig\r
+\r
+EPD_WIDTH       = 1304\r
+EPD_HEIGHT      = 984\r
+\r
+class EPD(object):\r
+    def __init__(self):\r
+        self.width = EPD_WIDTH\r
+        self.height = EPD_HEIGHT\r
+        \r
+        self.EPD_M1_CS_PIN  = epdconfig.EPD_M1_CS_PIN\r
+        self.EPD_S1_CS_PIN  = epdconfig.EPD_S1_CS_PIN\r
+        self.EPD_M2_CS_PIN  = epdconfig.EPD_M2_CS_PIN\r
+        self.EPD_S2_CS_PIN  = epdconfig.EPD_S2_CS_PIN\r
+\r
+        self.EPD_M1S1_DC_PIN  = epdconfig.EPD_M1S1_DC_PIN\r
+        self.EPD_M2S2_DC_PIN  = epdconfig.EPD_M2S2_DC_PIN\r
+\r
+        self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN\r
+        self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN\r
+\r
+        self.EPD_M1_BUSY_PIN  = epdconfig.EPD_M1_BUSY_PIN\r
+        self.EPD_S1_BUSY_PIN  = epdconfig.EPD_S1_BUSY_PIN\r
+        self.EPD_M2_BUSY_PIN  = epdconfig.EPD_M2_BUSY_PIN\r
+        self.EPD_S2_BUSY_PIN  = epdconfig.EPD_S2_BUSY_PIN\r
+\r
+    def init(self):\r
+        self.Init()\r
+\r
+    def Init(self):\r
+        print("EPD init...")\r
+        epdconfig.module_init()\r
+        \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
+        self.Reset() \r
+\r
+        #panel setting\r
+        self.M1_SendCommand(0x00) \r
+        self.M1_SendData(0x2f)         #KW-3f   KWR-2F BWROTP 0f       BWOTP 1f\r
+        self.S1_SendCommand(0x00) \r
+        self.S1_SendData(0x2f) \r
+        self.M2_SendCommand(0x00) \r
+        self.M2_SendData(0x23) \r
+        self.S2_SendCommand(0x00) \r
+        self.S2_SendData(0x23) \r
+\r
+        # POWER SETTING\r
+        self.M1_SendCommand(0x01)\r
+        self.M1_SendData(0x07)\r
+        self.M1_SendData(0x17) # VGH=20V,VGL=-20V\r
+        self.M1_SendData(0x3F)   # VDH=15V\r
+        self.M1_SendData(0x3F)   # VDL=-15V\r
+        self.M1_SendData(0x0d)\r
+        self.M2_SendCommand(0x01)\r
+        self.M2_SendData(0x07)\r
+        self.M2_SendData(0x17) # VGH=20V,VGL=-20V\r
+        self.M2_SendData(0x3F) # VDH=15V\r
+        self.M2_SendData(0x3F)  # VDL=-15V\r
+        self.M2_SendData(0x0d)\r
+        \r
+        # booster soft start\r
+        self.M1_SendCommand(0x06)\r
+        self.M1_SendData(0x17) #A\r
+        self.M1_SendData(0x17) #B\r
+        self.M1_SendData(0x39) #C\r
+        self.M1_SendData(0x17)\r
+        self.M2_SendCommand(0x06)\r
+        self.M2_SendData(0x17)\r
+        self.M2_SendData(0x17)\r
+        self.M2_SendData(0x39)\r
+        self.M2_SendData(0x17)\r
+\r
+        #resolution setting\r
+        self.M1_SendCommand(0x61)\r
+        self.M1_SendData(0x02)\r
+        self.M1_SendData(0x88) #source 648\r
+        self.M1_SendData(0x01) #gate 492\r
+        self.M1_SendData(0xEC)\r
+        self.S1_SendCommand(0x61)\r
+        self.S1_SendData(0x02)\r
+        self.S1_SendData(0x90) #source 656\r
+        self.S1_SendData(0x01) #gate 492\r
+        self.S1_SendData(0xEC)\r
+        self.M2_SendCommand(0x61)\r
+        self.M2_SendData(0x02)\r
+        self.M2_SendData(0x90) #source 656\r
+        self.M2_SendData(0x01) #gate 492\r
+        self.M2_SendData(0xEC)\r
+        self.S2_SendCommand(0x61)\r
+        self.S2_SendData(0x02)\r
+        self.S2_SendData(0x88) #source 648\r
+        self.S2_SendData(0x01) #gate 492\r
+        self.S2_SendData(0xEC)\r
+\r
+        self.M1S1M2S2_SendCommand(0x15)        #DUSPI\r
+        self.M1S1M2S2_SendData(0x20)\r
+\r
+        self.M1S1M2S2_SendCommand(0x30)        # PLL\r
+        self.M1S1M2S2_SendData(0x08)\r
+\r
+        self.M1S1M2S2_SendCommand(0x50)        #Vcom and data interval setting\r
+        self.M1S1M2S2_SendData(0x31)\r
+        self.M1S1M2S2_SendData(0x07)\r
+\r
+        self.M1S1M2S2_SendCommand(0x60)#TCON\r
+        self.M1S1M2S2_SendData(0x22)\r
+\r
+        self.M1_SendCommand(0xE0)                      #POWER SETTING\r
+        self.M1_SendData(0x01)\r
+        self.M2_SendCommand(0xE0)                      #POWER SETTING\r
+        self.M2_SendData(0x01)\r
+\r
+        self.M1S1M2S2_SendCommand(0xE3)\r
+        self.M1S1M2S2_SendData(0x00)\r
+\r
+        self.M1_SendCommand(0x82)\r
+        self.M1_SendData(0x1c)\r
+        self.M2_SendCommand(0x82)\r
+        self.M2_SendData(0x1c)\r
+\r
+        self.SetLut()\r
+        \r
+    def display(self, BlackImage, RedImage):\r
+        Blackbuf = [0x00] * int(self.width * self.height / 8)\r
+        blackconvert = BlackImage.convert('1')       \r
+        bimwidth, bimheight = blackconvert.size \r
+        Blackpixles = blackconvert.load()\r
+        temp=0;\r
+        for y in range(0, bimheight):\r
+            for x in range(0, bimwidth):\r
+                if Blackpixles[x, y] < 127:           # black\r
+                    Blackbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
+                else:                           # white\r
+                    Blackbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
+                temp=temp+1\r
+                if(temp==8):\r
+                    temp=0\r
+                    \r
+        Redbuf = [0x00] * int(self.width * self.height / 8)\r
+        redconvert = RedImage.convert('1')\r
+        rimwidth, rimheight = redconvert.size \r
+        Redpixles = redconvert.load()\r
+        temp=0;\r
+        for y in range(0, rimheight):\r
+            for x in range(0, rimwidth):\r
+                if Redpixles[x, y] < 127:           # black\r
+                    Redbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
+                else:                           # white\r
+                    Redbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
+                temp=temp+1\r
+                if(temp==8):\r
+                    temp=0\r
+                    \r
+        #S2 part 648*492\r
+        self.S2_SendCommand(0x10)\r
+        for y in  range(0, 492):\r
+            for x in  range(0, 81):\r
+                self.S2_SendData(Blackbuf[y*163 + x])\r
+        self.S2_SendCommand(0x13)\r
+        for y in  range(0, 492):\r
+            for x in  range(0, 81):\r
+                self.S2_SendData(~Redbuf[y*163 + x])\r
+                \r
+        #M2 part 656*492\r
+        self.M2_SendCommand(0x10)\r
+        for y in  range(0, 492):\r
+            for x in  range(81, 163):\r
+                self.M2_SendData(Blackbuf[y*163 + x])\r
+        self.M2_SendCommand(0x13)\r
+        for y in  range(0, 492):\r
+            for x in  range(81, 163):\r
+                self.M2_SendData(~Redbuf[y*163 + x])\r
+\r
+        #M1 part 648*492    \r
+        self.M1_SendCommand(0x10)\r
+        for y in  range(492, 984):\r
+            for x in  range(0, 81):\r
+                self.M1_SendData(Blackbuf[y*163 + x])\r
+        self.M1_SendCommand(0x13)\r
+        for y in  range(492, 984):\r
+            for x in  range(0, 81):\r
+                self.M1_SendData(~Redbuf[y*163 + x])\r
+        \r
+        #S1 part 656*492\r
+        self.S1_SendCommand(0x10)\r
+        for y in  range(492, 984):\r
+            for x in  range(81, 163):\r
+                self.S1_SendData(Blackbuf[y*163 + x])\r
+        self.S1_SendCommand(0x13)\r
+        for y in  range(492, 984):\r
+            for x in  range(81, 163):\r
+                self.S1_SendData(~Redbuf[y*163 + x])\r
+                \r
+        self.TurnOnDisplay()\r
+\r
+    def clear(self):\r
+        """Clear contents of image buffer"""\r
+        self.S2_SendCommand(0x10)\r
+        for y in  range(0, 492):\r
+            for x in  range(0, 81):\r
+                self.S2_SendData(0xff)        \r
+        self.S2_SendCommand(0x13)\r
+        for y in  range(0, 492):\r
+            for x in  range(0, 81):\r
+                self.S2_SendData(0x00)\r
+                \r
+        self.M2_SendCommand(0x10)\r
+        for y in  range(0, 492):\r
+            for x in  range(81, 163):\r
+                self.M2_SendData(0xff)\r
+        self.M2_SendCommand(0x13)\r
+        for y in  range(0, 492):\r
+            for x in  range(81, 163):\r
+                self.M2_SendData(0x00)       \r
+                    \r
+        self.M1_SendCommand(0x10)\r
+        for y in  range(492, 984):\r
+            for x in  range(0, 81):\r
+                self.M1_SendData(0xff)\r
+        self.M1_SendCommand(0x13)\r
+        for y in  range(492, 984):\r
+            for x in  range(0, 81):\r
+                self.M1_SendData(0x00)\r
+                \r
+        self.S1_SendCommand(0x10)\r
+        for y in  range(492, 984):\r
+            for x in  range(81, 163):\r
+                self.S1_SendData(0xff)\r
+        self.S1_SendCommand(0x13)\r
+        for y in  range(492, 984):\r
+            for x in  range(81, 163):\r
+                self.S1_SendData(0x00)\r
+                \r
+        self.TurnOnDisplay()\r
+        \r
+    def Reset(self):\r
+        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
+        time.sleep(0.2) \r
+        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) \r
+        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) \r
+        time.sleep(0.01) \r
+        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
+        time.sleep(0.2) \r
+\r
+    def sleep(self):\r
+        self.EPD_Sleep()\r
+    \r
+    def EPD_Sleep(self):\r
+        self.M1S1M2S2_SendCommand(0X02)        \r
+        time.sleep(0.3) \r
+\r
+        self.M1S1M2S2_SendCommand(0X07)        \r
+        self.M1S1M2S2_SendData(0xA5) \r
+        time.sleep(0.3) \r
+        print("module_exit")\r
+        epdconfig.module_exit()\r
+\r
+    def TurnOnDisplay(self):\r
+        self.M1M2_SendCommand(0x04)  \r
+        time.sleep(0.3) \r
+        self.M1S1M2S2_SendCommand(0x12) \r
+        self.M1_ReadBusy()\r
+        self.S1_ReadBusy()\r
+        self.M2_ReadBusy()\r
+        self.S2_ReadBusy()   \r
+        \r
+    """   M1S1M2S2 Write register address and data     """\r
+    def M1S1M2S2_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+        \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd) \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+    \r
+    def M1S1M2S2_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val) \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+\r
+    """   M1M2 Write register address and data     """\r
+    def M1M2_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd) \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+        \r
+    def M1M2_Sendata(self, val): \r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val) \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)   \r
+          \r
+    """   S2 Write register address and data     """\r
+    def S2_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+    def S2_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+        \r
+    """   M2 Write register address and data     """\r
+    def M2_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd) \r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+    def M2_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val) \r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+\r
+    """   S1 Write register address and data     """\r
+    def S1_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+    def S1_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+        \r
+    """   M1 Write register address and data     """\r
+    def M1_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+    def M1_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+\r
+    #Busy\r
+    def M1_ReadBusy(self):\r
+        self.M1_SendCommand(0x71) \r
+        busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
+        busy = not(busy & 0x01) \r
+        while(busy):\r
+            self.M1_SendCommand(0x71) \r
+            busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
+            busy = not(busy & 0x01) \r
+        time.sleep(0.2)\r
+    def M2_ReadBusy(self):\r
+        self.M2_SendCommand(0x71) \r
+        busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
+        busy = not(busy & 0x01) \r
+        self.M2_SendCommand(0x71) \r
+        while(busy):\r
+            self.M2_SendCommand(0x71) \r
+            busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
+            busy =not(busy & 0x01) \r
+        time.sleep(0.2)\r
+    def S1_ReadBusy(self):\r
+        self.S1_SendCommand(0x71) \r
+        busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
+        busy = not(busy & 0x01) \r
+        while(busy):\r
+            self.S1_SendCommand(0x71) \r
+            busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
+            busy = not(busy & 0x01) \r
+        time.sleep(0.2)        \r
+    def S2_ReadBusy(self):\r
+        self.S2_SendCommand(0x71) \r
+        busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
+        busy = not(busy & 0x01) \r
+        while(busy):\r
+            self.S2_SendCommand(0x71) \r
+            busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
+            busy = not(busy & 0x01) \r
+        time.sleep(0.2)            \r
+\r
+    lut_vcom1 = [\r
+        0x00,  0x10,   0x10,   0x01,   0x08,   0x01,\r
+        0x00,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x00,  0x08,   0x01,   0x08,   0x01,   0x06,\r
+        0x00,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
+        0x00,  0x04,   0x05,   0x08,   0x08,   0x01,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+    ]\r
+    lut_ww1 = [\r
+        0x91,  0x10,   0x10,   0x01,   0x08,   0x01,\r
+        0x04,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
+        0x80,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
+        0x08,  0x04,   0x05,   0x08,   0x08,   0x01,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+    ]\r
+    lut_bw1 = [\r
+        0xA8,  0x10,   0x10,   0x01,   0x08,   0x01,\r
+        0x84,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
+        0x86,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x8C,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
+        0x8C,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
+        0xF0,  0x04,   0x05,   0x08,   0x08,   0x01,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+    ]\r
+    lut_wb1 = [\r
+        0x91,  0x10,   0x10,   0x01,   0x08,   0x01,\r
+        0x04,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
+        0x80,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
+        0x08,  0x04,   0x05,   0x08,   0x08,   0x01,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+    ]\r
+    lut_bb1 = [\r
+        0x92,  0x10,   0x10,   0x01,   0x08,   0x01,\r
+        0x80,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
+        0x04,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
+        0x01,  0x04,   0x05,   0x08,   0x08,   0x01,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+    ]\r
+    \r
+    def SetLut(self):\r
+        self.M1S1M2S2_SendCommand(0x20) #vcom\r
+        for count in range(0, 60):\r
+            self.M1S1M2S2_SendData(self.lut_vcom1[count])\r
+\r
+        self.M1S1M2S2_SendCommand(0x21) #red not use\r
+        for count in range(0, 60):\r
+            self.M1S1M2S2_SendData(self.lut_ww1[count])\r
+\r
+        self.M1S1M2S2_SendCommand(0x22) #bw r\r
+        for count in range(0, 60):\r
+            self.M1S1M2S2_SendData(self.lut_bw1[count])   # bw=r\r
+\r
+        self.M1S1M2S2_SendCommand(0x23) #wb w\r
+        for count in range(0, 60):\r
+            self.M1S1M2S2_SendData(self.lut_wb1[count])   # wb=w\r
+\r
+        self.M1S1M2S2_SendCommand(0x24) #bb b\r
+        for count in range(0, 60):\r
+            self.M1S1M2S2_SendData(self.lut_bb1[count])   # bb=b\r
+            \r
+        self.M1S1M2S2_SendCommand(0x25) #bb b\r
+        for count in range(0, 60):\r
+            self.M1S1M2S2_SendData(self.lut_ww1[count])   # bb=b\r
diff --git a/src/epaper_display/drivers/epd12in48b_V2.py b/src/epaper_display/drivers/epd12in48b_V2.py
new file mode 100644 (file)
index 0000000..b6e90a2
--- /dev/null
@@ -0,0 +1,529 @@
+# /*****************************************************************************\r
+# * | File        :      epd12in48b_V2.py\r
+# * | Author      :   Waveshare electrices\r
+# * | Function    :   Hardware underlying interface\r
+# * | Info        :\r
+# *----------------\r
+# * | This version:   V1.0\r
+# * | Date        :   2022-09-14\r
+# * | Info        :   \r
+# ******************************************************************************/\r
+# Permission is hereby granted, free of charge, to any person obtaining a copy\r
+# of this software and associated documnetation files (the "Software"), to deal\r
+# in the Software without restriction, including without limitation the rights\r
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+# copies of the Software, and to permit persons to  whom the Software is\r
+# furished to do so, subject to the following conditions:\r
+#\r
+# The above copyright notice and this permission notice shall be included in\r
+# all copies or substantial portions of the Software.\r
+#\r
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+# THE SOFTWARE.\r
+#\r
+import time\r
+import epdconfig\r
+\r
+EPD_WIDTH       = 1304\r
+EPD_HEIGHT      = 984\r
+\r
+class EPD(object):\r
+    def __init__(self):\r
+        self.width = EPD_WIDTH\r
+        self.height = EPD_HEIGHT\r
+        \r
+        self.EPD_M1_CS_PIN  = epdconfig.EPD_M1_CS_PIN\r
+        self.EPD_S1_CS_PIN  = epdconfig.EPD_S1_CS_PIN\r
+        self.EPD_M2_CS_PIN  = epdconfig.EPD_M2_CS_PIN\r
+        self.EPD_S2_CS_PIN  = epdconfig.EPD_S2_CS_PIN\r
+\r
+        self.EPD_M1S1_DC_PIN  = epdconfig.EPD_M1S1_DC_PIN\r
+        self.EPD_M2S2_DC_PIN  = epdconfig.EPD_M2S2_DC_PIN\r
+\r
+        self.EPD_M1S1_RST_PIN = epdconfig.EPD_M1S1_RST_PIN\r
+        self.EPD_M2S2_RST_PIN = epdconfig.EPD_M2S2_RST_PIN\r
+\r
+        self.EPD_M1_BUSY_PIN  = epdconfig.EPD_M1_BUSY_PIN\r
+        self.EPD_S1_BUSY_PIN  = epdconfig.EPD_S1_BUSY_PIN\r
+        self.EPD_M2_BUSY_PIN  = epdconfig.EPD_M2_BUSY_PIN\r
+        self.EPD_S2_BUSY_PIN  = epdconfig.EPD_S2_BUSY_PIN\r
+\r
+    def Init(self):\r
+        print("EPD init...")\r
+        epdconfig.module_init()\r
+        \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1) \r
+        self.Reset() \r
+\r
+        # panel setting for Clear\r
+        # self.M1_SendCommand(0x00)\r
+        # self.M1_SendData(0x07)       #KW-3f   KWR-2F BWROTP 0f       BWOTP 1f\r
+        # self.S1_SendCommand(0x00)\r
+        # self.S1_SendData(0x07)\r
+        # self.M2_SendCommand(0x00)\r
+        # self.M2_SendData(0x07)\r
+        # self.S2_SendCommand(0x00)\r
+        # self.S2_SendData(0x07)\r
+\r
+        # panel setting for Display\r
+        self.M1_SendCommand(0x00)\r
+        self.M1_SendData(0x0f) #KW-3f   KWR-2F BWROTP 0f       BWOTP 1f\r
+        self.S1_SendCommand(0x00)\r
+        self.S1_SendData(0x0f)\r
+        self.M2_SendCommand(0x00)\r
+        self.M2_SendData(0x03)\r
+        self.S2_SendCommand(0x00)\r
+        self.S2_SendData(0x03)\r
+\r
+        # booster soft start\r
+        self.M1_SendCommand(0x06)\r
+        self.M1_SendData(0x17) #A\r
+        self.M1_SendData(0x17) #B\r
+        self.M1_SendData(0x39) #C\r
+        self.M1_SendData(0x17)\r
+        self.M2_SendCommand(0x06)\r
+        self.M2_SendData(0x17)\r
+        self.M2_SendData(0x17)\r
+        self.M2_SendData(0x39)\r
+        self.M2_SendData(0x17)\r
+\r
+        #resolution setting\r
+        self.M1_SendCommand(0x61)\r
+        self.M1_SendData(0x02)\r
+        self.M1_SendData(0x88) #source 648\r
+        self.M1_SendData(0x01) #gate 492\r
+        self.M1_SendData(0xEC)\r
+        self.S1_SendCommand(0x61)\r
+        self.S1_SendData(0x02)\r
+        self.S1_SendData(0x90) #source 656\r
+        self.S1_SendData(0x01) #gate 492\r
+        self.S1_SendData(0xEC)\r
+        self.M2_SendCommand(0x61)\r
+        self.M2_SendData(0x02)\r
+        self.M2_SendData(0x90) #source 656\r
+        self.M2_SendData(0x01) #gate 492\r
+        self.M2_SendData(0xEC)\r
+        self.S2_SendCommand(0x61)\r
+        self.S2_SendData(0x02)\r
+        self.S2_SendData(0x88) #source 648\r
+        self.S2_SendData(0x01) #gate 492\r
+        self.S2_SendData(0xEC)\r
+\r
+        self.M1S1M2S2_SendCommand(0x15)        #DUSPI\r
+        self.M1S1M2S2_SendData(0x20)\r
+\r
+        self.M1S1M2S2_SendCommand(0x50)        #Vcom and data interval setting\r
+        self.M1S1M2S2_SendData(0x11)\r
+        self.M1S1M2S2_SendData(0x07)\r
+\r
+        self.M1S1M2S2_SendCommand(0x60)#TCON\r
+        self.M1S1M2S2_SendData(0x22)\r
+\r
+        self.M1S1M2S2_SendCommand(0xE3)\r
+        self.M1S1M2S2_SendData(0x00)\r
+\r
+        self.M1_ReadTemperature()\r
+        \r
+    def display(self, BlackImage, RedImage):\r
+        start = time.perf_counter()\r
+        \r
+        Blackbuf = [0x00] * int(self.width * self.height / 8)\r
+        blackconvert = BlackImage.convert('1')       \r
+        bimwidth, bimheight = blackconvert.size \r
+        Blackpixles = blackconvert.load()\r
+        temp=0\r
+        for y in range(0, bimheight):\r
+            for x in range(0, bimwidth):\r
+                if Blackpixles[x, y] < 127:           # black\r
+                    Blackbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
+                else:                           # white\r
+                    Blackbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
+                temp=temp+1\r
+                if(temp==8):\r
+                    temp=0\r
+                    \r
+        Redbuf = [0x00] * int(self.width * self.height / 8)\r
+        redconvert = RedImage.convert('1')\r
+        rimwidth, rimheight = redconvert.size \r
+        Redpixles = redconvert.load()\r
+        temp=0\r
+        for y in range(0, rimheight):\r
+            for x in range(0, rimwidth):\r
+                if Redpixles[x, y] < 127:           # black\r
+                    Redbuf[int((x + y*self.width)/8)] &= ~(0x80>>temp)\r
+                else:                           # white\r
+                    Redbuf[int((x + y*self.width)/8)] |= (0x80>>temp)\r
+                temp=temp+1\r
+                if(temp==8):\r
+                    temp=0\r
+                    \r
+        #S2 part 648*492\r
+        self.S2_SendCommand(0x10)\r
+        for y in  range(0, 492):\r
+            for x in  range(0, 81):\r
+                self.S2_SendData(Blackbuf[y*163 + x])\r
+        self.S2_SendCommand(0x13)\r
+        for y in  range(0, 492):\r
+            for x in  range(0, 81):\r
+                self.S2_SendData(~Redbuf[y*163 + x])\r
+                \r
+        #M2 part 656*492\r
+        self.M2_SendCommand(0x10)\r
+        for y in  range(0, 492):\r
+            for x in  range(81, 163):\r
+                self.M2_SendData(Blackbuf[y*163 + x])\r
+        self.M2_SendCommand(0x13)\r
+        for y in  range(0, 492):\r
+            for x in  range(81, 163):\r
+                self.M2_SendData(~Redbuf[y*163 + x])\r
+\r
+        #M1 part 648*492    \r
+        self.M1_SendCommand(0x10)\r
+        for y in  range(492, 984):\r
+            for x in  range(0, 81):\r
+                self.M1_SendData(Blackbuf[y*163 + x])\r
+        self.M1_SendCommand(0x13)\r
+        for y in  range(492, 984):\r
+            for x in  range(0, 81):\r
+                self.M1_SendData(~Redbuf[y*163 + x])\r
+        \r
+        #S1 part 656*492\r
+        self.S1_SendCommand(0x10)\r
+        for y in  range(492, 984):\r
+            for x in  range(81, 163):\r
+                self.S1_SendData(Blackbuf[y*163 + x])\r
+        self.S1_SendCommand(0x13)\r
+        for y in  range(492, 984):\r
+            for x in  range(81, 163):\r
+                self.S1_SendData(~Redbuf[y*163 + x])\r
+                \r
+        end = time.perf_counter()\r
+        print("use time: %f"%(end - start))\r
+        self.TurnOnDisplay()\r
+\r
+    def clear(self):\r
+        """Clear contents of image buffer"""\r
+        start = time.perf_counter()\r
+        \r
+        self.S2_SendCommand(0x10)\r
+        for y in  range(0, 492):\r
+            for x in  range(0, 81):\r
+                self.S2_SendData(0xff)        \r
+        self.S2_SendCommand(0x13)\r
+        for y in  range(0, 492):\r
+            for x in  range(0, 81):\r
+                self.S2_SendData(0x00)\r
+                \r
+        self.M2_SendCommand(0x10)\r
+        for y in  range(0, 492):\r
+            for x in  range(81, 163):\r
+                self.M2_SendData(0xff)\r
+        self.M2_SendCommand(0x13)\r
+        for y in  range(0, 492):\r
+            for x in  range(81, 163):\r
+                self.M2_SendData(0x00)       \r
+                    \r
+        self.M1_SendCommand(0x10)\r
+        for y in  range(492, 984):\r
+            for x in  range(0, 81):\r
+                self.M1_SendData(0xff)\r
+        self.M1_SendCommand(0x13)\r
+        for y in  range(492, 984):\r
+            for x in  range(0, 81):\r
+                self.M1_SendData(0x00)\r
+                \r
+        self.S1_SendCommand(0x10)\r
+        for y in  range(492, 984):\r
+            for x in  range(81, 163):\r
+                self.S1_SendData(0xff)\r
+        self.S1_SendCommand(0x13)\r
+        for y in  range(492, 984):\r
+            for x in  range(81, 163):\r
+                self.S1_SendData(0x00)\r
+                \r
+        end = time.perf_counter()\r
+        print (end)\r
+        print (start)\r
+        print("use time: %f" %(end - start))\r
+        \r
+        self.TurnOnDisplay()\r
+        \r
+    def Reset(self):\r
+        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
+        time.sleep(0.2) \r
+        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 0) \r
+        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 0) \r
+        time.sleep(0.01) \r
+        epdconfig.digital_write(self.EPD_M1S1_RST_PIN, 1) \r
+        epdconfig.digital_write(self.EPD_M2S2_RST_PIN, 1) \r
+        time.sleep(0.2) \r
+    \r
+    def EPD_Sleep(self):\r
+        self.M1S1M2S2_SendCommand(0X02)        \r
+        time.sleep(0.3) \r
+\r
+        self.M1S1M2S2_SendCommand(0X07)        \r
+        self.M1S1M2S2_SendData(0xA5) \r
+        time.sleep(0.3) \r
+        print("module_exit")\r
+        epdconfig.module_exit()\r
+\r
+    def TurnOnDisplay(self):\r
+        self.M1M2_SendCommand(0x04)  \r
+        time.sleep(0.3) \r
+        self.M1S1M2S2_SendCommand(0x12) \r
+        self.M1_ReadBusy()\r
+        self.S1_ReadBusy()\r
+        self.M2_ReadBusy()\r
+        self.S2_ReadBusy()   \r
+        \r
+    """   M1S1M2S2 Write register address and data     """\r
+    def M1S1M2S2_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+        \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd) \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+    \r
+    def M1S1M2S2_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val) \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+\r
+    """   M1M2 Write register address and data     """\r
+    def M1M2_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd) \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+        \r
+    def M1M2_Sendata(self, val): \r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val) \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)   \r
+          \r
+    """   S2 Write register address and data     """\r
+    def S2_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+    def S2_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+        \r
+    """   M2 Write register address and data     """\r
+    def M2_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd) \r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+    def M2_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M2S2_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val) \r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+\r
+    """   S1 Write register address and data     """\r
+    def S1_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+    def S1_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+        \r
+    """   M1 Write register address and data     """\r
+    def M1_SendCommand(self, cmd):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(cmd)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+    def M1_SendData(self, val):\r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.spi_writebyte(val)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+\r
+    #Busy\r
+    def M1_ReadBusy(self):\r
+        self.M1_SendCommand(0x71) \r
+        busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
+        busy = not(busy & 0x01) \r
+        while(busy):\r
+            self.M1_SendCommand(0x71) \r
+            busy = epdconfig.digital_read(self.EPD_M1_BUSY_PIN) \r
+            busy = not(busy & 0x01) \r
+        time.sleep(0.2)\r
+    def M2_ReadBusy(self):\r
+        self.M2_SendCommand(0x71) \r
+        busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
+        busy = not(busy & 0x01) \r
+        self.M2_SendCommand(0x71) \r
+        while(busy):\r
+            self.M2_SendCommand(0x71) \r
+            busy = epdconfig.digital_read(self.EPD_M2_BUSY_PIN) \r
+            busy =not(busy & 0x01) \r
+        time.sleep(0.2)\r
+    def S1_ReadBusy(self):\r
+        self.S1_SendCommand(0x71) \r
+        busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
+        busy = not(busy & 0x01) \r
+        while(busy):\r
+            self.S1_SendCommand(0x71) \r
+            busy = epdconfig.digital_read(self.EPD_S1_BUSY_PIN) \r
+            busy = not(busy & 0x01) \r
+        time.sleep(0.2)        \r
+    def S2_ReadBusy(self):\r
+        self.S2_SendCommand(0x71) \r
+        busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
+        busy = not(busy & 0x01) \r
+        while(busy):\r
+            self.S2_SendCommand(0x71) \r
+            busy = epdconfig.digital_read(self.EPD_S2_BUSY_PIN) \r
+            busy = not(busy & 0x01) \r
+        time.sleep(0.2)            \r
+\r
+    lut_vcom1 = [\r
+        0x00,  0x10,   0x10,   0x01,   0x08,   0x01,\r
+        0x00,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x00,  0x08,   0x01,   0x08,   0x01,   0x06,\r
+        0x00,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
+        0x00,  0x04,   0x05,   0x08,   0x08,   0x01,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+    ]\r
+    lut_ww1 = [\r
+        0x91,  0x10,   0x10,   0x01,   0x08,   0x01,\r
+        0x04,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
+        0x80,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
+        0x08,  0x04,   0x05,   0x08,   0x08,   0x01,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+    ]\r
+    lut_bw1 = [\r
+        0xA8,  0x10,   0x10,   0x01,   0x08,   0x01,\r
+        0x84,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
+        0x86,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x8C,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
+        0x8C,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
+        0xF0,  0x04,   0x05,   0x08,   0x08,   0x01,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+    ]\r
+    lut_wb1 = [\r
+        0x91,  0x10,   0x10,   0x01,   0x08,   0x01,\r
+        0x04,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
+        0x80,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
+        0x08,  0x04,   0x05,   0x08,   0x08,   0x01,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+    ]\r
+    lut_bb1 = [\r
+        0x92,  0x10,   0x10,   0x01,   0x08,   0x01,\r
+        0x80,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x84,  0x08,   0x01,   0x08,   0x01,   0x06,\r
+        0x04,  0x06,   0x01,   0x06,   0x01,   0x05,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x06,\r
+        0x00,  0x05,   0x01,   0x1E,   0x0F,   0x01,\r
+        0x01,  0x04,   0x05,   0x08,   0x08,   0x01,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+        0x00,  0x00,   0x00,   0x00,   0x00,   0x00,\r
+    ]\r
+    \r
+    def SetLut(self):\r
+        self.M1S1M2S2_SendCommand(0x20) #vcom\r
+        for count in range(0, 60):\r
+            self.M1S1M2S2_SendData(self.lut_vcom1[count])\r
+\r
+        self.M1S1M2S2_SendCommand(0x21) #red not use\r
+        for count in range(0, 60):\r
+            self.M1S1M2S2_SendData(self.lut_ww1[count])\r
+\r
+        self.M1S1M2S2_SendCommand(0x22) #bw r\r
+        for count in range(0, 60):\r
+            self.M1S1M2S2_SendData(self.lut_bw1[count])   # bw=r\r
+\r
+        self.M1S1M2S2_SendCommand(0x23) #wb w\r
+        for count in range(0, 60):\r
+            self.M1S1M2S2_SendData(self.lut_wb1[count])   # wb=w\r
+\r
+        self.M1S1M2S2_SendCommand(0x24) #bb b\r
+        for count in range(0, 60):\r
+            self.M1S1M2S2_SendData(self.lut_bb1[count])   # bb=b\r
+            \r
+        self.M1S1M2S2_SendCommand(0x25) #bb b\r
+        for count in range(0, 60):\r
+            self.M1S1M2S2_SendData(self.lut_ww1[count])   # bb=b\r
+\r
+    def M1_ReadTemperature(self):\r
+        self.M1_SendCommand(0x40)\r
+        self.M1_ReadBusy()\r
+        time.sleep(0.3)\r
+        \r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 0)\r
+        epdconfig.digital_write(self.EPD_S1_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_M2_CS_PIN, 1)\r
+        epdconfig.digital_write(self.EPD_S2_CS_PIN, 1)\r
+        \r
+        epdconfig.digital_write(self.EPD_M1S1_DC_PIN, 1)\r
+        time.sleep(0.05)\r
+        \r
+        temp = epdconfig.spi_readbyte(0x00)\r
+        epdconfig.digital_write(self.EPD_M1_CS_PIN, 1)\r
+        \r
+        self.M1S1M2S2_SendCommand(0xE0)\r
+        self.M1S1M2S2_SendData(0x03)\r
+        self.M1S1M2S2_SendCommand(0xE5)\r
+        self.M1S1M2S2_SendData(temp)\r
diff --git a/src/epaper_display/drivers/epd_12_in_48_lib_32bit.so b/src/epaper_display/drivers/epd_12_in_48_lib_32bit.so
new file mode 100644 (file)
index 0000000..acdbb26
Binary files /dev/null and b/src/epaper_display/drivers/epd_12_in_48_lib_32bit.so differ
diff --git a/src/epaper_display/drivers/epd_12_in_48_lib_64bit.so b/src/epaper_display/drivers/epd_12_in_48_lib_64bit.so
new file mode 100644 (file)
index 0000000..ed8ae87
Binary files /dev/null and b/src/epaper_display/drivers/epd_12_in_48_lib_64bit.so differ
diff --git a/src/epaper_display/drivers/epdconfig.py b/src/epaper_display/drivers/epdconfig.py
new file mode 100644 (file)
index 0000000..c70a1f1
--- /dev/null
@@ -0,0 +1,99 @@
+# /*****************************************************************************\r
+# * | File        :      epdconfig.py\r
+# * | Author      :   Waveshare electrices\r
+# * | Function    :   Hardware underlying interface\r
+# * | Info        :\r
+# *----------------\r
+# * |  This version:   V1.0\r
+# * | Date        :   2019-11-01\r
+# * | Info        :   \r
+# ******************************************************************************/\r
+# Permission is hereby granted, free of charge, to any person obtaining a copy\r
+# of this software and associated documnetation files (the "Software"), to deal\r
+# in the Software without restriction, including without limitation the rights\r
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+# copies of the Software, and to permit persons to  whom the Software is\r
+# furished to do so, subject to the following conditions:\r
+#\r
+# The above copyright notice and this permission notice shall be included in\r
+# all copies or substantial portions of the Software.\r
+#\r
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+# THE SOFTWARE.\r
+#\r
+import time\r
+import os\r
+import logging\r
+import sys\r
+\r
+from ctypes import *\r
+\r
+EPD_SCK_PIN   =11\r
+EPD_MOSI_PIN  =10\r
+\r
+EPD_M1_CS_PIN  =8\r
+EPD_S1_CS_PIN  =7\r
+EPD_M2_CS_PIN  =17\r
+EPD_S2_CS_PIN  =18\r
+\r
+EPD_M1S1_DC_PIN  =13\r
+EPD_M2S2_DC_PIN  =22\r
+\r
+EPD_M1S1_RST_PIN =6\r
+EPD_M2S2_RST_PIN =23\r
+\r
+EPD_M1_BUSY_PIN  =5\r
+EPD_S1_BUSY_PIN  =19\r
+EPD_M2_BUSY_PIN  =27\r
+EPD_S2_BUSY_PIN  =24\r
+\r
+find_dirs = [\r
+    os.path.dirname(os.path.realpath(__file__)),\r
+    '/usr/local/lib',\r
+    '/usr/lib',\r
+]\r
+spi = None\r
+for find_dir in find_dirs:\r
+    val = int(os.popen('getconf LONG_BIT').read())\r
+    logging.debug("System is %d bit"%val)\r
+    if val == 64:\r
+        so_filename = os.path.join(find_dir, 'epd_12_in_48_lib_64bit.so')\r
+    else:\r
+        so_filename = os.path.join(find_dir, 'epd_12_in_48_lib_32bit.so')\r
+    if os.path.exists(so_filename):\r
+        spi = CDLL(so_filename)\r
+        break\r
+if spi is None:\r
+    RuntimeError('Cannot find DEV_Config.so')\r
+\r
+def digital_write(pin, value):\r
+    spi.DEV_Digital_Write(pin, value)\r
+\r
+def digital_read(pin):\r
+    return spi.DEV_Digital_Read(pin)\r
+\r
+def spi_writebyte(value): \r
+    spi.DEV_SPI_WriteByte(value)\r
\r
+def delay_ms(delaytime):\r
+    time.sleep(delaytime / 1000.0)\r
+        \r
+def module_init():\r
+    spi.DEV_ModuleInit()\r
+\r
+def module_exit():\r
+    spi.DEV_ModuleExit()\r
+\r
+\r
+def spi_readbyte(Reg):\r
+    return spi.DEV_SPI_ReadByte(Reg)\r
+    \r
+def delay_ms(delaytime):\r
+    time.sleep(delaytime / 1000.0)\r
+\r
+  \r
diff --git a/src/epaper_display/main.py b/src/epaper_display/main.py
new file mode 100644 (file)
index 0000000..ff77b38
--- /dev/null
@@ -0,0 +1,18 @@
+import logging
+import sys
+
+from PIL import Image
+
+import renderer
+
+logger = logging.getLogger()
+logger.setLevel(logging.INFO)
+logger = logging.getLogger(__name__)
+
+image = Image.open("testtree_IXCCGR.png")
+logger.info("image open")
+
+rend = renderer.Renderer()
+
+rend.render(image)
+
diff --git a/src/epaper_display/renderer.py b/src/epaper_display/renderer.py
new file mode 100644 (file)
index 0000000..b4274da
--- /dev/null
@@ -0,0 +1,51 @@
+from PIL import Image
+
+import display
+
+from typing import List, Tuple, Callable
+
+class Renderer:
+    def __init__(self) -> None:
+        self.width = display.EPD_HEIGHT
+        self.height = display.EPD_WIDTH
+        self.display = display.Display()
+        self.rules: List[Tuple[Callable[[],bool],Callable[[int,int],Image]]] = [];
+        self._calibrate_before_next_render = False
+
+    def render(self):
+        # check for calibration first
+        if self._calibrate_before_next_render:
+            self._calibrate_before_next_render = False
+            self.display.calibrate()
+
+        for rule in self.rules:
+            if rule[0]():
+                self.render_image(rule[1](self.width, self.height))
+                return
+
+    def render_image(self, image: Image):
+        hsv_image = image.convert("HSV")
+        hsv_pixels = hsv_image.load()
+
+        black_image = image.copy()
+        black_pixels = black_image.load()
+        red_image = Image.new('L', (self.width, self.height), 'white')
+        red_pixels = red_image.load()
+
+        for x in range(self.width):
+            for y in range(self.height):
+                h, s, v = hsv_pixels[x,y]
+                red_hue_val = max(0, 255 - h*6, (h-212)*6)
+                red_val = int(red_hue_val * s * v / 256 / 256)
+                black_val = int(255 * max(0, v - red_val) / max(1, 255 - red_val))
+                if red_val > 0:
+                    red_pixels[x, y] = 255 - red_val
+                    black_pixels[x, y] = 3*(black_val,)
+
+        black_image = black_image.transpose(Image.Transpose.ROTATE_270)
+        red_image = red_image.transpose(Image.Transpose.ROTATE_270)
+        self.display.render(black_image, red_image)
+
+    def set_calibrate_next_render(self, calibrate: bool = True) -> None:
+        self._calibrate_before_next_render = calibrate
+
diff --git a/src/main.py b/src/main.py
deleted file mode 100644 (file)
index ff77b38..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-import logging
-import sys
-
-from PIL import Image
-
-import renderer
-
-logger = logging.getLogger()
-logger.setLevel(logging.INFO)
-logger = logging.getLogger(__name__)
-
-image = Image.open("testtree_IXCCGR.png")
-logger.info("image open")
-
-rend = renderer.Renderer()
-
-rend.render(image)
-
diff --git a/src/renderer.py b/src/renderer.py
deleted file mode 100644 (file)
index b4274da..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-from PIL import Image
-
-import display
-
-from typing import List, Tuple, Callable
-
-class Renderer:
-    def __init__(self) -> None:
-        self.width = display.EPD_HEIGHT
-        self.height = display.EPD_WIDTH
-        self.display = display.Display()
-        self.rules: List[Tuple[Callable[[],bool],Callable[[int,int],Image]]] = [];
-        self._calibrate_before_next_render = False
-
-    def render(self):
-        # check for calibration first
-        if self._calibrate_before_next_render:
-            self._calibrate_before_next_render = False
-            self.display.calibrate()
-
-        for rule in self.rules:
-            if rule[0]():
-                self.render_image(rule[1](self.width, self.height))
-                return
-
-    def render_image(self, image: Image):
-        hsv_image = image.convert("HSV")
-        hsv_pixels = hsv_image.load()
-
-        black_image = image.copy()
-        black_pixels = black_image.load()
-        red_image = Image.new('L', (self.width, self.height), 'white')
-        red_pixels = red_image.load()
-
-        for x in range(self.width):
-            for y in range(self.height):
-                h, s, v = hsv_pixels[x,y]
-                red_hue_val = max(0, 255 - h*6, (h-212)*6)
-                red_val = int(red_hue_val * s * v / 256 / 256)
-                black_val = int(255 * max(0, v - red_val) / max(1, 255 - red_val))
-                if red_val > 0:
-                    red_pixels[x, y] = 255 - red_val
-                    black_pixels[x, y] = 3*(black_val,)
-
-        black_image = black_image.transpose(Image.Transpose.ROTATE_270)
-        red_image = red_image.transpose(Image.Transpose.ROTATE_270)
-        self.display.render(black_image, red_image)
-
-    def set_calibrate_next_render(self, calibrate: bool = True) -> None:
-        self._calibrate_before_next_render = calibrate
-