diff --git a/pwnagotchi/bettercap.py b/pwnagotchi/bettercap.py index 5d24c21e..def18802 100644 --- a/pwnagotchi/bettercap.py +++ b/pwnagotchi/bettercap.py @@ -100,7 +100,6 @@ class Client(object): await asyncio.sleep(sleep_time) continue except OSError: - sleep_time = min_sleep + max_sleep * random.random() logging.warning('connection to the bettercap endpoint failed...') pwnagotchi.restart("AUTO") diff --git a/pwnagotchi/ui/hw/libs/waveshare/v1/__init__.py b/pwnagotchi/google/__init__.py similarity index 100% rename from pwnagotchi/ui/hw/libs/waveshare/v1/__init__.py rename to pwnagotchi/google/__init__.py diff --git a/pwnagotchi/ui/hw/libs/waveshare/v2/__init__.py b/pwnagotchi/locale/__init__.py similarity index 100% rename from pwnagotchi/ui/hw/libs/waveshare/v2/__init__.py rename to pwnagotchi/locale/__init__.py diff --git a/pwnagotchi/plugins/default/fix_services.py b/pwnagotchi/plugins/default/fix_services.py index 51f2398e..0ca1dbca 100644 --- a/pwnagotchi/plugins/default/fix_services.py +++ b/pwnagotchi/plugins/default/fix_services.py @@ -4,6 +4,8 @@ import subprocess import time import random from io import TextIOWrapper +import os +import platform import pwnagotchi from pwnagotchi import plugins @@ -32,6 +34,8 @@ class FixServices(plugins.Plugin): self.pattern2 = re.compile(r'wifi error while hopping to channel') self.pattern3 = re.compile(r'Firmware has halted or crashed') self.pattern4 = re.compile(r'error 400: could not find interface wlan0mon') + self.pattern5 = re.compile(r'fatal error: concurrent map iteration and map write') + self.pattern6 = re.compile(r'panic: runtime error') self.isReloadingMon = False self.connection = None self.LASTTRY = 0 @@ -113,41 +117,43 @@ class FixServices(plugins.Plugin): logging.debug("[Fix_Services]**** checking") # Look for pattern 1 - if len(self.pattern.findall(last_lines)) >= 3: - logging.debug("[Fix_Services]**** Should trigger a reload of the wlan0mon device:\n%s" % last_lines) - if hasattr(agent, 'view'): - display = agent.view() - display.set('status', 'Blind-Bug detected. Restarting.') - display.update(force=True) - logging.debug('[Fix_Services] Blind-Bug detected. Restarting.') - try: - self._tryTurningItOffAndOnAgain(agent) - except Exception as err: - logging.warning("[Fix_Services] TTOAOA: %s" % repr(err)) + if platform.machine().startswith('arm'): + if len(self.pattern.findall(last_lines)) >= 3: + logging.debug("[Fix_Services]**** Should trigger a reload of the wlan0mon device:\n%s" % last_lines) + if hasattr(agent, 'view'): + display = agent.view() + display.set('status', 'Blind-Bug detected. Restarting.') + display.update(force=True) + logging.debug('[Fix_Services] Blind-Bug detected. Restarting.') + try: + self._tryTurningItOffAndOnAgain(agent) + except Exception as err: + logging.warning("[Fix_Services] TTOAOA: %s" % repr(err)) # Look for pattern 2 elif len(self.pattern2.findall(other_last_lines)) >= 5: - logging.debug("[Fix_Services]**** Should trigger a reload of the wlan0mon device:\n%s" % last_lines) - if hasattr(agent, 'view'): - display = agent.view() - display.set('status', 'Wifi channel stuck. Restarting recon.') - display.update(force=True) - logging.debug('[Fix_Services] Wifi channel stuck. Restarting recon.') + if platform.machine().startswith('arm'): + logging.debug("[Fix_Services]**** Should trigger a reload of the wlan0mon device:\n%s" % last_lines) + if hasattr(agent, 'view'): + display = agent.view() + display.set('status', 'Wifi channel stuck. Restarting recon.') + display.update(force=True) + logging.debug('[Fix_Services] Wifi channel stuck. Restarting recon.') - try: - result = agent.run("wifi.recon off; wifi.recon on") - if result["success"]: - logging.debug("[Fix_Services] wifi.recon flip: success!") - if display: - display.update(force=True, new_data={"status": "Wifi recon flipped!", - "face": faces.COOL}) + try: + result = agent.run("wifi.recon off; wifi.recon on") + if result["success"]: + logging.debug("[Fix_Services] wifi.recon flip: success!") + if display: + display.update(force=True, new_data={"status": "Wifi recon flipped!", + "face": faces.COOL}) + else: + print("Wifi recon flipped\nthat was easy!") else: - print("Wifi recon flipped\nthat was easy!") - else: - logging.warning("[Fix_Services] wifi.recon flip: FAILED: %s" % repr(result)) + logging.warning("[Fix_Services] wifi.recon flip: FAILED: %s" % repr(result)) - except Exception as err: - logging.error("[Fix_Services wifi.recon flip] %s" % repr(err)) + except Exception as err: + logging.error("[Fix_Services wifi.recon flip] %s" % repr(err)) # Look for pattern 3 elif len(self.pattern3.findall(other_last_lines)) >= 1: @@ -177,6 +183,25 @@ class FixServices(plugins.Plugin): except Exception as err: logging.error("[Fix_Services monstart]: %s" % repr(err)) + # Look for pattern 5 + elif len(self.pattern5.findall(other_other_last_lines)) >= 1: + logging.debug("[Fix_Services] Bettercap has crashed!") + if hasattr(agent, 'view'): + display = agent.view() + display.set('status', 'Restarting pwnagotchi!') + display.update(force=True) + os.system("systemctl restart bettercap") + pwnagotchi.restart("AUTO") + + # Look for pattern 6 + elif len(self.pattern6.findall(other_other_last_lines)) >= 1: + logging.debug("[Fix_Services] Bettercap has crashed!") + if hasattr(agent, 'view'): + display = agent.view() + display.set('status', 'Restarting pwnagotchi!') + display.update(force=True) + os.system("systemctl restart bettercap") + pwnagotchi.restart("AUTO") else: print("logs look good") diff --git a/pwnagotchi/ui/__init__.py b/pwnagotchi/ui/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pwnagotchi/ui/hw/displayhatmini.py b/pwnagotchi/ui/hw/displayhatmini.py index 2c9f1c99..b5a8db80 100644 --- a/pwnagotchi/ui/hw/displayhatmini.py +++ b/pwnagotchi/ui/hw/displayhatmini.py @@ -34,10 +34,10 @@ class DisplayHatMini(DisplayImpl): def initialize(self): logging.info("initializing Display Hat Mini") from pwnagotchi.ui.hw.libs.pimoroni.displayhatmini.ST7789 import ST7789 - self._display = ST7789(0,1,9,13) + self._display = ST7789(0, 1, 9, 13) def render(self, canvas): self._display.display(canvas) def clear(self): - self._display.clear() \ No newline at end of file + self._display.clear() diff --git a/pwnagotchi/ui/hw/libs/pimoroni/displayhatmini/ST7789.py b/pwnagotchi/ui/hw/libs/pimoroni/displayhatmini/ST7789.py index 50048092..cc554cdc 100644 --- a/pwnagotchi/ui/hw/libs/pimoroni/displayhatmini/ST7789.py +++ b/pwnagotchi/ui/hw/libs/pimoroni/displayhatmini/ST7789.py @@ -90,8 +90,8 @@ ST7789_PWCTR6 = 0xFC class ST7789(object): """Representation of an ST7789 TFT LCD.""" - def __init__(self, port, cs, dc, backlight, rst=None, width=320, - height=240, rotation=0, invert=True, spi_speed_hz=60 * 1000 * 1000, + def __init__(self, port, cs, dc, backlight=None, rst=None, width=240, + height=240, rotation=90, invert=True, spi_speed_hz=4000000, offset_left=0, offset_top=0): """Create an instance of the display using SPI communication. diff --git a/pwnagotchi/ui/hw/libs/waveshare/v1/epd2in13.py b/pwnagotchi/ui/hw/libs/waveshare/v1/epd2in13.py deleted file mode 100644 index 7913c0ef..00000000 --- a/pwnagotchi/ui/hw/libs/waveshare/v1/epd2in13.py +++ /dev/null @@ -1,224 +0,0 @@ -# ***************************************************************************** -# * | File : epd2in13.py -# * | Author : Waveshare team -# * | Function : Electronic paper driver -# * | Info : -# *---------------- -# * | This version: V4.0 -# * | Date : 2019-06-20 -# # | Info : python demo -# ----------------------------------------------------------------------------- -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - - -import logging -from . import epdconfig - -# Display resolution -EPD_WIDTH = 122 -EPD_HEIGHT = 250 - -class EPD: - def __init__(self): - self.reset_pin = epdconfig.RST_PIN - self.dc_pin = epdconfig.DC_PIN - self.busy_pin = epdconfig.BUSY_PIN - self.cs_pin = epdconfig.CS_PIN - self.width = EPD_WIDTH - self.height = EPD_HEIGHT - - lut_full_update = [ - 0x22, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x11, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 - ] - - lut_partial_update = [ - 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - ] - - # Hardware reset - def reset(self): - epdconfig.digital_write(self.cs_pin, 0) - epdconfig.digital_write(self.reset_pin, 1) - epdconfig.delay_ms(200) - epdconfig.digital_write(self.reset_pin, 0) - epdconfig.delay_ms(10) - epdconfig.digital_write(self.reset_pin, 1) - epdconfig.delay_ms(200) - epdconfig.digital_write(self.cs_pin, 1) - - def send_command(self, command): - epdconfig.digital_write(self.cs_pin, 0) - epdconfig.digital_write(self.dc_pin, 0) - epdconfig.spi_writebyte([command]) - epdconfig.digital_write(self.cs_pin, 1) - - def send_data(self, data): - epdconfig.digital_write(self.cs_pin, 0) - epdconfig.digital_write(self.dc_pin, 1) - epdconfig.spi_writebyte([data]) - epdconfig.digital_write(self.cs_pin, 1) - - def ReadBusy(self): - while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy - epdconfig.delay_ms(100) - - def TurnOnDisplay(self): - self.send_command(0x22) # DISPLAY_UPDATE_CONTROL_2 - self.send_data(0xC4) - self.send_command(0x20) # MASTER_ACTIVATION - self.send_command(0xFF) # TERMINATE_FRAME_READ_WRITE - - logging.debug("e-Paper busy") - self.ReadBusy() - logging.debug("e-Paper busy release") - - def init(self, lut): - if (epdconfig.module_init() != 0): - return -1 - # EPD hardware init start - self.reset() - self.send_command(0x01) # DRIVER_OUTPUT_CONTROL - self.send_data((EPD_HEIGHT - 1) & 0xFF) - self.send_data(((EPD_HEIGHT - 1) >> 8) & 0xFF) - self.send_data(0x00) # GD = 0 SM = 0 TB = 0 - - self.send_command(0x0C) # BOOSTER_SOFT_START_CONTROL - self.send_data(0xD7) - self.send_data(0xD6) - self.send_data(0x9D) - - self.send_command(0x2C) # WRITE_VCOM_REGISTER - self.send_data(0xA8) # VCOM 7C - - self.send_command(0x3A) # SET_DUMMY_LINE_PERIOD - self.send_data(0x1A) # 4 dummy lines per gate - - self.send_command(0x3B) # SET_GATE_TIME - self.send_data(0x08) # 2us per line - - self.send_command(0X3C) # BORDER_WAVEFORM_CONTROL - self.send_data(0x03) - - self.send_command(0X11) # DATA_ENTRY_MODE_SETTING - self.send_data(0x03) # X increment; Y increment - - # WRITE_LUT_REGISTER - self.send_command(0x32) - for count in range(30): - self.send_data(lut[count]) - - return 0 - -## - # @brief: specify the memory area for data R/W - ## - def SetWindows(self, x_start, y_start, x_end, y_end): - self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION - self.send_data((x_start >> 3) & 0xFF) - self.send_data((x_end >> 3) & 0xFF) - self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION - self.send_data(y_start & 0xFF) - self.send_data((y_start >> 8) & 0xFF) - self.send_data(y_end & 0xFF) - self.send_data((y_end >> 8) & 0xFF) - -## - # @brief: specify the start point for data R/W - ## - def SetCursor(self, x, y): - self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER - # x point must be the multiple of 8 or the last 3 bits will be ignored - self.send_data((x >> 3) & 0xFF) - self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER - self.send_data(y & 0xFF) - self.send_data((y >> 8) & 0xFF) - self.ReadBusy() - - def getbuffer(self, image): - if self.width%8 == 0: - linewidth = int(self.width/8) - else: - linewidth = int(self.width/8) + 1 - - buf = [0xFF] * (linewidth * self.height) - image_monocolor = image.convert('1') - imwidth, imheight = image_monocolor.size - pixels = image_monocolor.load() - - if(imwidth == self.width and imheight == self.height): - for y in range(imheight): - for x in range(imwidth): - if pixels[x, y] == 0: - # x = imwidth - x - buf[int(x / 8) + y * linewidth] &= ~(0x80 >> (x % 8)) - elif(imwidth == self.height and imheight == self.width): - for y in range(imheight): - for x in range(imwidth): - newx = y - newy = self.height - x - 1 - if pixels[x, y] == 0: - # newy = imwidth - newy - 1 - buf[int(newx / 8) + newy*linewidth] &= ~(0x80 >> (y % 8)) - return buf - - - def display(self, image): - if self.width%8 == 0: - linewidth = int(self.width/8) - else: - linewidth = int(self.width/8) + 1 - - self.SetWindows(0, 0, self.width, self.height); - for j in range(0, self.height): - self.SetCursor(0, j); - self.send_command(0x24); - for i in range(0, linewidth): - self.send_data(image[i + j * linewidth]) - self.TurnOnDisplay() - - def Clear(self, color): - if self.width%8 == 0: - linewidth = int(self.width/8) - else: - linewidth = int(self.width/8) + 1 - - self.SetWindows(0, 0, self.width, self.height); - for j in range(0, self.height): - self.SetCursor(0, j); - self.send_command(0x24); - for i in range(0, linewidth): - self.send_data(color) - self.TurnOnDisplay() - - def sleep(self): - self.send_command(0x10) #enter deep sleep - self.send_data(0x01) - epdconfig.delay_ms(100) - - epdconfig.module_exit() - -### END OF FILE ### - diff --git a/pwnagotchi/ui/hw/libs/waveshare/v1/epd2in13bc.py b/pwnagotchi/ui/hw/libs/waveshare/v1/epd2in13bc.py deleted file mode 100644 index 7974617d..00000000 --- a/pwnagotchi/ui/hw/libs/waveshare/v1/epd2in13bc.py +++ /dev/null @@ -1,164 +0,0 @@ -# ***************************************************************************** -# * | File : epd2in13bc.py -# * | Author : Waveshare team -# * | Function : Electronic paper driver -# * | Info : -# *---------------- -# * | This version: V4.0 -# * | Date : 2019-06-20 -# # | Info : python demo -# ----------------------------------------------------------------------------- -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -from . import epdconfig -import RPi.GPIO as GPIO -# import numpy as np - -# Display resolution -EPD_WIDTH = 104 -EPD_HEIGHT = 212 - -class EPD: - def __init__(self): - self.reset_pin = epdconfig.RST_PIN - self.dc_pin = epdconfig.DC_PIN - self.busy_pin = epdconfig.BUSY_PIN - self.cs_pin = epdconfig.CS_PIN - self.width = EPD_WIDTH - self.height = EPD_HEIGHT - - # Hardware reset - def reset(self): - epdconfig.digital_write(self.reset_pin, GPIO.HIGH) - epdconfig.delay_ms(200) - epdconfig.digital_write(self.reset_pin, GPIO.LOW) # module reset - epdconfig.delay_ms(200) - epdconfig.digital_write(self.reset_pin, GPIO.HIGH) - epdconfig.delay_ms(200) - - def send_command(self, command): - epdconfig.digital_write(self.dc_pin, GPIO.LOW) - epdconfig.digital_write(self.cs_pin, GPIO.LOW) - epdconfig.spi_writebyte([command]) - epdconfig.digital_write(self.cs_pin, GPIO.HIGH) - - def send_data(self, data): - epdconfig.digital_write(self.dc_pin, GPIO.HIGH) - epdconfig.digital_write(self.cs_pin, GPIO.LOW) - epdconfig.spi_writebyte([data]) - epdconfig.digital_write(self.cs_pin, GPIO.HIGH) - - def ReadBusy(self): - epdconfig.delay_ms(20) - while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy - epdconfig.delay_ms(100) - - def init(self): - if (epdconfig.module_init() != 0): - return -1 - # EPD hardware init start - self.reset() - - self.send_command(0x06) # BOOSTER_SOFT_START - self.send_data(0x17) - self.send_data(0x17) - self.send_data(0x17) - - self.send_command(0x04) # POWER_ON - self.ReadBusy() - - self.send_command(0x00) # PANEL_SETTING - self.send_data(0x8F) - - self.send_command(0x50) # VCOM_AND_DATA_INTERVAL_SETTING - self.send_data(0xF0) - - self.send_command(0x61) # RESOLUTION_SETTING - self.send_data(self.width & 0xff) - self.send_data(self.height >> 8) - self.send_data(self.height & 0xff) - return 0 - - def getbuffer(self, image): - buf = [0xFF] * (int(self.width/8) * self.height) - image_monocolor = image.convert('1') - imwidth, imheight = image_monocolor.size - pixels = image_monocolor.load() - if(imwidth == self.width and imheight == self.height): - for y in range(imheight): - for x in range(imwidth): - # Set the bits for the column of pixels at the current position. - if pixels[x, y] == 0: - buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) - elif(imwidth == self.height and imheight == self.width): - for y in range(imheight): - for x in range(imwidth): - newx = y - newy = self.height - x - 1 - if pixels[x, y] == 0: - buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) - return buf - - def displayBlack(self, imageblack): - self.send_command(0x10) - for i in range(0, int(self.width * self.height / 8)): - self.send_data(imageblack[i]) - self.send_command(0x92) - - self.send_command(0x12) # REFRESH - self.ReadBusy() - - def display(self, imageblack, imagecolor): - self.send_command(0x10) - for i in range(0, int(self.width * self.height / 8)): - self.send_data(imageblack[i]) - self.send_command(0x92) - - self.send_command(0x13) - for i in range(0, int(self.width * self.height / 8)): - self.send_data(imagecolor[i]) - self.send_command(0x92) - - self.send_command(0x12) # REFRESH - self.ReadBusy() - - def Clear(self): - self.send_command(0x10) - for i in range(0, int(self.width * self.height / 8)): - self.send_data(0xFF) - self.send_command(0x92) - - self.send_command(0x13) - for i in range(0, int(self.width * self.height / 8)): - self.send_data(0xFF) - self.send_command(0x92) - - self.send_command(0x12) # REFRESH - self.ReadBusy() - - def sleep(self): - self.send_command(0x02) # POWER_OFF - self.ReadBusy() - self.send_command(0x07) # DEEP_SLEEP - self.send_data(0xA5) # check code - -# epdconfig.module_exit() -### END OF FILE ### - diff --git a/pwnagotchi/ui/hw/libs/waveshare/v1/epd2in13bcFAST.py b/pwnagotchi/ui/hw/libs/waveshare/v1/epd2in13bcFAST.py deleted file mode 100644 index b7704543..00000000 --- a/pwnagotchi/ui/hw/libs/waveshare/v1/epd2in13bcFAST.py +++ /dev/null @@ -1,359 +0,0 @@ -# ***************************************************************************** -# * | File : epd2in13d.py -# * | Author : Waveshare team -# * | Function : Electronic paper driver -# * | Info : -# *---------------- -# * | This version: V4.0 -# * | Date : 2019-06-20 -# # | Info : python demo -# ----------------------------------------------------------------------------- -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documnetation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - - -# ============================================================================= -# THIS FILE HAS BEEN MODIFIED FROM ORIGINAL, IT HAS BEEN MODIFIED TO RUN THE -# THREE COLOR WAVESHARE 2.13IN DISPLAY AT A MUCH, MUCH FASTER RATE THAN NORMAL -# AND IT COULD DAMAGE YOUR DISPLAY. THERE IS NO WARRANTY INCLUDED AND YOU USE -# THIS CODE AT YOUR OWN RISK. WE ARE NOT RESPONSIBLE FOR ANYTHING THAT HAPPENS -# INCLUDING BUT NOT LIMITED TO: DESTRUCTION OF YOUR DISPLAY, PI, HOUSE, CAR, -# SPACE-TIME-CONTINUUM, OR IF THE CODE KILLS YOUR CAT. IF YOU AREN'T WILLING TO -# TAKE THESE RISKS, PLEASE DO NOT USE THIS CODE. -# ============================================================================= - - -import logging -from . import epdconfig -from PIL import Image -import RPi.GPIO as GPIO - -# Display resolution -EPD_WIDTH = 104 -EPD_HEIGHT = 212 - -class EPD: - def __init__(self): - self.reset_pin = epdconfig.RST_PIN - self.dc_pin = epdconfig.DC_PIN - self.busy_pin = epdconfig.BUSY_PIN - self.cs_pin = epdconfig.CS_PIN - self.width = EPD_WIDTH - self.height = EPD_HEIGHT - - lut_vcomDC = [ - 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, - 0x60, 0x28, 0x28, 0x00, 0x00, 0x01, - 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, - 0x00, 0x12, 0x12, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - ] - - lut_ww = [ - 0x40, 0x08, 0x00, 0x00, 0x00, 0x02, - 0x90, 0x28, 0x28, 0x00, 0x00, 0x01, - 0x40, 0x14, 0x00, 0x00, 0x00, 0x01, - 0xA0, 0x12, 0x12, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ] - - lut_bw = [ - 0x40, 0x17, 0x00, 0x00, 0x00, 0x02, - 0x90, 0x0F, 0x0F, 0x00, 0x00, 0x03, - 0x40, 0x0A, 0x01, 0x00, 0x00, 0x01, - 0xA0, 0x0E, 0x0E, 0x00, 0x00, 0x02, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ] - - lut_wb = [ - 0x80, 0x08, 0x00, 0x00, 0x00, 0x02, - 0x90, 0x28, 0x28, 0x00, 0x00, 0x01, - 0x80, 0x14, 0x00, 0x00, 0x00, 0x01, - 0x50, 0x12, 0x12, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ] - - lut_bb = [ - 0x80, 0x08, 0x00, 0x00, 0x00, 0x02, - 0x90, 0x28, 0x28, 0x00, 0x00, 0x00, - 0x80, 0x14, 0x00, 0x00, 0x00, 0x01, - 0x50, 0x12, 0x12, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ] - - lut_vcom1 = [ - 0xA0, 0x10, 0x10, 0x00, 0x00, 0x02, - 0x00, 0x10, 0x10, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, - ] - - lut_ww1 = [ - 0x50, 0x01, 0x01, 0x00, 0x00, 0x01, - 0xA0, 0x42, 0x42, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ] - - lut_bw1 = [ - 0x50, 0x01, 0x01, 0x00, 0x00, 0x01, - 0xA0, 0x42, 0x42, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ] - - lut_wb1 = [ - 0xA0, 0x01, 0x01, 0x00, 0x00, 0x01, - 0x50, 0x42, 0x42, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ] - - lut_bb1 = [ - 0xA0, 0x01, 0x01, 0x00, 0x00, 0x01, - 0x50, 0x42, 0x42, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ] - - - # Hardware reset - def reset(self): - epdconfig.digital_write(self.reset_pin, 1) - epdconfig.delay_ms(200) - epdconfig.digital_write(self.reset_pin, 0) - epdconfig.delay_ms(10) - epdconfig.digital_write(self.reset_pin, 1) - epdconfig.delay_ms(200) - - def send_command(self, command): - epdconfig.digital_write(self.dc_pin, 0) - epdconfig.digital_write(self.cs_pin, 0) - epdconfig.spi_writebyte([command]) - epdconfig.digital_write(self.cs_pin, 1) - - def send_data(self, data): - epdconfig.digital_write(self.dc_pin, 1) - epdconfig.digital_write(self.cs_pin, 0) - epdconfig.spi_writebyte([data]) - epdconfig.digital_write(self.cs_pin, 1) - - def ReadBusy(self): - logging.debug("e-Paper busy") - while(epdconfig.digital_read(self.busy_pin) == 0): # 0: idle, 1: busy - self.send_command(0x71) - epdconfig.delay_ms(100) - logging.debug("e-Paper busy release") - - def TurnOnDisplay(self): - self.send_command(0x12) - epdconfig.delay_ms(10) - self.ReadBusy() - - def init(self): - if (epdconfig.module_init() != 0): - return -1 - # EPD hardware init start - self.reset() - - self.send_command(0x01) # POWER SETTING - self.send_data(0x03) - self.send_data(0x00) - self.send_data(0x2b) - self.send_data(0x2b) - self.send_data(0x03) - - self.send_command(0x06) # boost soft start - self.send_data(0x17) # A - self.send_data(0x17) # B - self.send_data(0x17) # C - - self.send_command(0x04) - self.ReadBusy() - - self.send_command(0x00) # panel setting - self.send_data(0xbf) # LUT from OTP,128x296 - self.send_data(0x0d) # VCOM to 0V fast - - self.send_command(0x30) # PLL setting - self.send_data(0x21) # 3a 100HZ 29 150Hz 39 200HZ 31 171HZ - - self.send_command(0x61) # resolution setting - self.send_data(self.width) - self.send_data((self.height >> 8) & 0xff) - self.send_data(self.height& 0xff) - - self.send_command(0x82) # vcom_DC setting - self.send_data(0x28) - return 0 - - def SetFullReg(self): - self.send_command(0x82) - self.send_data(0x00) - self.send_command(0X50) - self.send_data(0x97) -# self.send_command(0x00) # panel setting -# self.send_data(0x9f) # LUT from OTP,128x296 - - def SetPartReg(self): -# self.send_command(0x00) # panel setting -# self.send_data(0xbf) # LUT from OTP,128x296 - self.send_command(0x82) - self.send_data(0x03) - self.send_command(0X50) - self.send_data(0x47) - - self.send_command(0x20) # vcom - for count in range(0, 44): - self.send_data(self.lut_vcom1[count]) - self.send_command(0x21) # ww -- - for count in range(0, 42): - self.send_data(self.lut_ww1[count]) - self.send_command(0x22) # bw r - for count in range(0, 42): - self.send_data(self.lut_bw1[count]) - self.send_command(0x23) # wb w - for count in range(0, 42): - self.send_data(self.lut_wb1[count]) - self.send_command(0x24) # bb b - for count in range(0, 42): - self.send_data(self.lut_bb1[count]) - - def getbuffer(self, image): - # logging.debug("bufsiz = ",int(self.width/8) * self.height) - buf = [0xFF] * (int(self.width/8) * self.height) - image_monocolor = image.convert('1') - imwidth, imheight = image_monocolor.size - pixels = image_monocolor.load() - # logging.debug("imwidth = %d, imheight = %d",imwidth,imheight) - if(imwidth == self.width and imheight == self.height): - logging.debug("Vertical") - for y in range(imheight): - for x in range(imwidth): - # Set the bits for the column of pixels at the current position. - if pixels[x, y] == 0: - buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8)) - elif(imwidth == self.height and imheight == self.width): - logging.debug("Horizontal") - for y in range(imheight): - for x in range(imwidth): - newx = y - newy = self.height - x - 1 - if pixels[x, y] == 0: - buf[int((newx + newy*self.width) / 8)] &= ~(0x80 >> (y % 8)) - return buf - - def display(self, image): - if (Image == None): - return - - self.send_command(0x10) - for i in range(0, int(self.width * self.height / 8)): - self.send_data(0x00) - epdconfig.delay_ms(10) - - self.send_command(0x13) - for i in range(0, int(self.width * self.height / 8)): - self.send_data(image[i]) - epdconfig.delay_ms(10) - - self.SetFullReg() - self.TurnOnDisplay() - - def DisplayPartial(self, image): - if (Image == None): - return - - self.SetPartReg() - self.send_command(0x91) - self.send_command(0x90) - self.send_data(0) - self.send_data(self.width - 1) - - self.send_data(0) - self.send_data(0) - self.send_data(int(self.height / 256)) - self.send_data(self.height % 256 - 1) - self.send_data(0x28) - - self.send_command(0x10) - for i in range(0, int(self.width * self.height / 8)): - self.send_data(image[i]) - epdconfig.delay_ms(10) - - self.send_command(0x13) - for i in range(0, int(self.width * self.height / 8)): - self.send_data(~image[i]) - epdconfig.delay_ms(10) - - self.TurnOnDisplay() - - def Clear(self): - self.send_command(0x10) - for i in range(0, int(self.width * self.height / 8)): - self.send_data(0x00) - epdconfig.delay_ms(10) - - self.send_command(0x13) - for i in range(0, int(self.width * self.height / 8)): - self.send_data(0x00) - epdconfig.delay_ms(10) - - self.SetFullReg() - self.TurnOnDisplay() - - def sleep(self): - self.send_command(0X50) - self.send_data(0xf7) - self.send_command(0X02) # power off - self.send_command(0X07) # deep sleep - self.send_data(0xA5) - - epdconfig.module_exit() - -### END OF FILE ### diff --git a/pwnagotchi/ui/hw/libs/waveshare/v1/epdconfig.py b/pwnagotchi/ui/hw/libs/waveshare/v1/epdconfig.py deleted file mode 100644 index 728f5cf8..00000000 --- a/pwnagotchi/ui/hw/libs/waveshare/v1/epdconfig.py +++ /dev/null @@ -1,154 +0,0 @@ -# /***************************************************************************** -# * | File : epdconfig.py -# * | Author : Waveshare team -# * | Function : Hardware underlying interface -# * | Info : -# *---------------- -# * | This version: V1.0 -# * | Date : 2019-06-21 -# * | Info : -# ****************************************************************************** -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -import os -import logging -import sys -import time - - -class RaspberryPi: - # Pin definition - RST_PIN = 17 - DC_PIN = 25 - CS_PIN = 8 - BUSY_PIN = 24 - - def __init__(self): - import spidev - import RPi.GPIO - - self.GPIO = RPi.GPIO - - # SPI device, bus = 0, device = 0 - self.SPI = spidev.SpiDev(0, 0) - - def digital_write(self, pin, value): - self.GPIO.output(pin, value) - - def digital_read(self, pin): - return self.GPIO.input(self.BUSY_PIN) - - def delay_ms(self, delaytime): - time.sleep(delaytime / 1000.0) - - def spi_writebyte(self, data): - self.SPI.writebytes(data) - - def module_init(self): - self.GPIO.setmode(self.GPIO.BCM) - self.GPIO.setwarnings(False) - self.GPIO.setup(self.RST_PIN, self.GPIO.OUT) - self.GPIO.setup(self.DC_PIN, self.GPIO.OUT) - self.GPIO.setup(self.CS_PIN, self.GPIO.OUT) - self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN) - self.SPI.max_speed_hz = 4000000 - self.SPI.mode = 0b00 - return 0 - - def module_exit(self): - logging.debug("spi end") - self.SPI.close() - - logging.debug("close 5V, Module enters 0 power consumption ...") - self.GPIO.output(self.RST_PIN, 0) - self.GPIO.output(self.DC_PIN, 0) - - self.GPIO.cleanup() - - -class JetsonNano: - # Pin definition - RST_PIN = 17 - DC_PIN = 25 - CS_PIN = 8 - BUSY_PIN = 24 - - def __init__(self): - import ctypes - find_dirs = [ - os.path.dirname(os.path.realpath(__file__)), - '/usr/local/lib', - '/usr/lib', - ] - self.SPI = None - for find_dir in find_dirs: - so_filename = os.path.join(find_dir, 'sysfs_software_spi.so') - if os.path.exists(so_filename): - self.SPI = ctypes.cdll.LoadLibrary(so_filename) - break - if self.SPI is None: - raise RuntimeError('Cannot find sysfs_software_spi.so') - - import Jetson.GPIO - self.GPIO = Jetson.GPIO - - def digital_write(self, pin, value): - self.GPIO.output(pin, value) - - def digital_read(self, pin): - return self.GPIO.input(self.BUSY_PIN) - - def delay_ms(self, delaytime): - time.sleep(delaytime / 1000.0) - - def spi_writebyte(self, data): - self.SPI.SYSFS_software_spi_transfer(data[0]) - - def module_init(self): - self.GPIO.setmode(self.GPIO.BCM) - self.GPIO.setwarnings(False) - self.GPIO.setup(self.RST_PIN, self.GPIO.OUT) - self.GPIO.setup(self.DC_PIN, self.GPIO.OUT) - self.GPIO.setup(self.CS_PIN, self.GPIO.OUT) - self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN) - self.SPI.SYSFS_software_spi_begin() - return 0 - - def module_exit(self): - logging.debug("spi end") - self.SPI.SYSFS_software_spi_end() - - logging.debug("close 5V, Module enters 0 power consumption ...") - self.GPIO.output(self.RST_PIN, 0) - self.GPIO.output(self.DC_PIN, 0) - - self.GPIO.cleanup() - - -if os.path.exists('/sys/bus/platform/drivers/gpiomem-bcm2835'): - implementation = RaspberryPi() -else: - implementation = JetsonNano() - -for func in [x for x in dir(implementation) if not x.startswith('_')]: - setattr(sys.modules[__name__], func, getattr(implementation, func)) - - -### END OF FILE ### diff --git a/pwnagotchi/ui/hw/libs/waveshare/v2/waveshare.py b/pwnagotchi/ui/hw/libs/waveshare/v2/waveshare.py deleted file mode 100644 index a9faac84..00000000 --- a/pwnagotchi/ui/hw/libs/waveshare/v2/waveshare.py +++ /dev/null @@ -1,338 +0,0 @@ -# //***************************************************************************** -# * | File : epd2in13.py -# * | Author : Waveshare team -# * | Function : Electronic paper driver -# * | Info : -# *---------------- -# * | This version: V3.0 -# * | Date : 2018-11-01 -# * | Info : python2 demo -# * 1.Remove: -# digital_write(self, pin, value) -# digital_read(self, pin) -# delay_ms(self, delaytime) -# set_lut(self, lut) -# self.lut = self.lut_full_update -# * 2.Change: -# display_frame -> TurnOnDisplay -# set_memory_area -> SetWindow -# set_memory_pointer -> SetCursor -# * 3.How to use -# epd = epd2in13.EPD() -# epd.init(epd.lut_full_update) -# image = Image.new('1', (epd2in13.EPD_WIDTH, epd2in13.EPD_HEIGHT), 255) -# ... -# drawing ...... -# ... -# epd.display(getbuffer(image)) -# ******************************************************************************// -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and//or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -import time -import spidev -import RPi.GPIO as GPIO -from PIL import Image - -# Pin definition -RST_PIN = 17 -DC_PIN = 25 -CS_PIN = 8 -BUSY_PIN = 24 - -# SPI device, bus = 0, device = 0 -SPI = spidev.SpiDev(0, 0) - - -def digital_write(pin, value): - GPIO.output(pin, value) - - -def digital_read(pin): - return GPIO.input(BUSY_PIN) - - -def delay_ms(delaytime): - time.sleep(delaytime / 1000.0) - - -def spi_writebyte(data): - SPI.writebytes(data) - - -def module_init(): - GPIO.setmode(GPIO.BCM) - GPIO.setwarnings(False) - GPIO.setup(RST_PIN, GPIO.OUT) - GPIO.setup(DC_PIN, GPIO.OUT) - GPIO.setup(CS_PIN, GPIO.OUT) - GPIO.setup(BUSY_PIN, GPIO.IN) - SPI.max_speed_hz = 2000000 - SPI.mode = 0b00 - return 0; - - -# Display resolution -EPD_WIDTH = 122 -EPD_HEIGHT = 250 - - -class EPD: - def __init__(self): - self.reset_pin = RST_PIN - self.dc_pin = DC_PIN - self.busy_pin = BUSY_PIN - self.width = EPD_WIDTH - self.height = EPD_HEIGHT - - FULL_UPDATE = 0 - PART_UPDATE = 1 - lut_full_update = [ - 0x80, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, # LUT0: BB: VS 0 ~7 - 0x10, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, # LUT1: BW: VS 0 ~7 - 0x80, 0x60, 0x40, 0x00, 0x00, 0x00, 0x00, # LUT2: WB: VS 0 ~7 - 0x10, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, # LUT3: WW: VS 0 ~7 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # LUT4: VCOM: VS 0 ~7 - - 0x03, 0x03, 0x00, 0x00, 0x02, # TP0 A~D RP0 - 0x09, 0x09, 0x00, 0x00, 0x02, # TP1 A~D RP1 - 0x03, 0x03, 0x00, 0x00, 0x02, # TP2 A~D RP2 - 0x00, 0x00, 0x00, 0x00, 0x00, # TP3 A~D RP3 - 0x00, 0x00, 0x00, 0x00, 0x00, # TP4 A~D RP4 - 0x00, 0x00, 0x00, 0x00, 0x00, # TP5 A~D RP5 - 0x00, 0x00, 0x00, 0x00, 0x00, # TP6 A~D RP6 - - 0x15, 0x41, 0xA8, 0x32, 0x30, 0x0A, - ] - - lut_partial_update = [ # 20 bytes - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # LUT0: BB: VS 0 ~7 - 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # LUT1: BW: VS 0 ~7 - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # LUT2: WB: VS 0 ~7 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # LUT3: WW: VS 0 ~7 - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # LUT4: VCOM: VS 0 ~7 - - 0x0A, 0x00, 0x00, 0x00, 0x00, # TP0 A~D RP0 - 0x00, 0x00, 0x00, 0x00, 0x00, # TP1 A~D RP1 - 0x00, 0x00, 0x00, 0x00, 0x00, # TP2 A~D RP2 - 0x00, 0x00, 0x00, 0x00, 0x00, # TP3 A~D RP3 - 0x00, 0x00, 0x00, 0x00, 0x00, # TP4 A~D RP4 - 0x00, 0x00, 0x00, 0x00, 0x00, # TP5 A~D RP5 - 0x00, 0x00, 0x00, 0x00, 0x00, # TP6 A~D RP6 - - 0x15, 0x41, 0xA8, 0x32, 0x30, 0x0A, - ] - - # Hardware reset - def reset(self): - digital_write(self.reset_pin, GPIO.HIGH) - delay_ms(200) - digital_write(self.reset_pin, GPIO.LOW) # module reset - delay_ms(200) - digital_write(self.reset_pin, GPIO.HIGH) - delay_ms(200) - - def send_command(self, command): - digital_write(self.dc_pin, GPIO.LOW) - spi_writebyte([command]) - - def send_data(self, data): - digital_write(self.dc_pin, GPIO.HIGH) - spi_writebyte([data]) - - def wait_until_idle(self): - while (digital_read(self.busy_pin) == 1): # 0: idle, 1: busy - delay_ms(100) - - def TurnOnDisplay(self): - self.send_command(0x22) - self.send_data(0xC7) - self.send_command(0x20) - self.wait_until_idle() - - def init(self, update): - if (module_init() != 0): - return -1 - # EPD hardware init start - self.reset() - if (update == self.FULL_UPDATE): - self.wait_until_idle() - self.send_command(0x12) # soft reset - self.wait_until_idle() - - self.send_command(0x74) # set analog block control - self.send_data(0x54) - self.send_command(0x7E) # set digital block control - self.send_data(0x3B) - - self.send_command(0x01) # Driver output control - self.send_data(0xF9) - self.send_data(0x00) - self.send_data(0x00) - - self.send_command(0x11) # data entry mode - self.send_data(0x01) - - self.send_command(0x44) # set Ram-X address start//end position - self.send_data(0x00) - self.send_data(0x0F) # 0x0C-->(15+1)*8=128 - - self.send_command(0x45) # set Ram-Y address start//end position - self.send_data(0xF9) # 0xF9-->(249+1)=250 - self.send_data(0x00) - self.send_data(0x00) - self.send_data(0x00) - - self.send_command(0x3C) # BorderWavefrom - self.send_data(0x03) - - self.send_command(0x2C) # VCOM Voltage - self.send_data(0x55) # - - self.send_command(0x03) - self.send_data(self.lut_full_update[70]) - - self.send_command(0x04) # - self.send_data(self.lut_full_update[71]) - self.send_data(self.lut_full_update[72]) - self.send_data(self.lut_full_update[73]) - - self.send_command(0x3A) # Dummy Line - self.send_data(self.lut_full_update[74]) - self.send_command(0x3B) # Gate time - self.send_data(self.lut_full_update[75]) - - self.send_command(0x32) - for count in range(70): - self.send_data(self.lut_full_update[count]) - - self.send_command(0x4E) # set RAM x address count to 0 - self.send_data(0x00) - self.send_command(0x4F) # set RAM y address count to 0X127 - self.send_data(0xF9) - self.send_data(0x00) - self.wait_until_idle() - else: - self.send_command(0x2C) # VCOM Voltage - self.send_data(0x26) - - self.wait_until_idle() - - self.send_command(0x32) - for count in range(70): - self.send_data(self.lut_partial_update[count]) - - self.send_command(0x37) - self.send_data(0x00) - self.send_data(0x00) - self.send_data(0x00) - self.send_data(0x00) - self.send_data(0x40) - self.send_data(0x00) - self.send_data(0x00) - - self.send_command(0x22) - self.send_data(0xC0) - self.send_command(0x20) - self.wait_until_idle() - - self.send_command(0x3C) # BorderWavefrom - self.send_data(0x01) - return 0 - - def getbuffer(self, image): - if self.width % 8 == 0: - linewidth = self.width // 8 - else: - linewidth = self.width // 8 + 1 - - buf = [0xFF] * (linewidth * self.height) - image_monocolor = image.convert('1') - imwidth, imheight = image_monocolor.size - pixels = image_monocolor.load() - - if (imwidth == self.width and imheight == self.height): - # print("Vertical") - for y in range(imheight): - for x in range(imwidth): - if pixels[x, y] == 0: - x = imwidth - x - buf[x // 8 + y * linewidth] &= ~(0x80 >> (x % 8)) - elif (imwidth == self.height and imheight == self.width): - # print("Horizontal") - for y in range(imheight): - for x in range(imwidth): - newx = y - newy = self.height - x - 1 - if pixels[x, y] == 0: - newy = imwidth - newy - 1 - buf[newx // 8 + newy * linewidth] &= ~(0x80 >> (y % 8)) - return buf - - def display(self, image): - if self.width % 8 == 0: - linewidth = self.width // 8 - else: - linewidth = self.width // 8 + 1 - - self.send_command(0x24) - for j in range(0, self.height): - for i in range(0, linewidth): - self.send_data(image[i + j * linewidth]) - self.TurnOnDisplay() - - def displayPartial(self, image): - if self.width % 8 == 0: - linewidth = self.width // 8 - else: - linewidth = self.width // 8 + 1 - - self.send_command(0x24) - for j in range(0, self.height): - for i in range(0, linewidth): - self.send_data(image[i + j * linewidth]) - self.send_command(0x26) - for j in range(0, self.height): - for i in range(0, linewidth): - self.send_data(~image[i + j * linewidth]) - self.TurnOnDisplay() - - def Clear(self, color): - if self.width % 8 == 0: - linewidth = self.width // 8 - else: - linewidth = self.width // 8 + 1 - # print(linewidth) - - self.send_command(0x24) - for j in range(0, self.height): - for i in range(0, linewidth): - self.send_data(color) - self.TurnOnDisplay() - - def sleep(self): - self.send_command(0x22) # POWER OFF - self.send_data(0xC3) - self.send_command(0x20) - - self.send_command(0x10) # enter deep sleep - self.send_data(0x01) - delay_ms(100) - - ### END OF FILE ### \ No newline at end of file diff --git a/pwnagotchi/ui/hw/libs/waveshare/v3/epd2in13_V3.py b/pwnagotchi/ui/hw/libs/waveshare/v3/epd2in13_V3.py deleted file mode 100644 index 38121901..00000000 --- a/pwnagotchi/ui/hw/libs/waveshare/v3/epd2in13_V3.py +++ /dev/null @@ -1,397 +0,0 @@ -# ***************************************************************************** -# * | File : epd2in13_V3.py -# * | Author : Waveshare team -# * | Function : Electronic paper driver -# * | Info : -# *---------------- -# * | This version: V1.1 -# * | Date : 2021-10-30 -# # | Info : python demo -# ----------------------------------------------------------------------------- -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documnetation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - - -import logging -from . import epdconfig -import numpy as np - -# Display resolution -EPD_WIDTH = 122 -EPD_HEIGHT = 250 - -logger = logging.getLogger(__name__) - -class EPD: - def __init__(self): - self.reset_pin = epdconfig.RST_PIN - self.dc_pin = epdconfig.DC_PIN - self.busy_pin = epdconfig.BUSY_PIN - self.cs_pin = epdconfig.CS_PIN - self.width = EPD_WIDTH - self.height = EPD_HEIGHT - - lut_partial_update= [ - 0x0,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x80,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x40,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x14,0x0,0x0,0x0,0x0,0x0,0x0, - 0x1,0x0,0x0,0x0,0x0,0x0,0x0, - 0x1,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0, - 0x22,0x17,0x41,0x00,0x32,0x36, - ] - - lut_full_update = [ - 0x80,0x4A,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x40,0x4A,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x80,0x4A,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x40,0x4A,0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0xF,0x0,0x0,0x0,0x0,0x0,0x0, - 0xF,0x0,0x0,0xF,0x0,0x0,0x2, - 0xF,0x0,0x0,0x0,0x0,0x0,0x0, - 0x1,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x0,0x0,0x0,0x0,0x0,0x0,0x0, - 0x22,0x22,0x22,0x22,0x22,0x22,0x0,0x0,0x0, - 0x22,0x17,0x41,0x0,0x32,0x36, - ] - - ''' - function :Hardware reset - parameter: - ''' - def reset(self): - epdconfig.digital_write(self.reset_pin, 1) - epdconfig.delay_ms(20) - epdconfig.digital_write(self.reset_pin, 0) - epdconfig.delay_ms(2) - epdconfig.digital_write(self.reset_pin, 1) - epdconfig.delay_ms(20) - - ''' - function :send command - parameter: - command : Command register - ''' - def send_command(self, command): - epdconfig.digital_write(self.dc_pin, 0) - epdconfig.digital_write(self.cs_pin, 0) - epdconfig.spi_writebyte([command]) - epdconfig.digital_write(self.cs_pin, 1) - - ''' - function :send data - parameter: - data : Write data - ''' - def send_data(self, data): - epdconfig.digital_write(self.dc_pin, 1) - epdconfig.digital_write(self.cs_pin, 0) - epdconfig.spi_writebyte([data]) - epdconfig.digital_write(self.cs_pin, 1) - - ''' - function :Wait until the busy_pin goes LOW - parameter: - ''' - def ReadBusy(self): - logger.debug("e-Paper busy") - while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy - epdconfig.delay_ms(10) - logger.debug("e-Paper busy release") - - ''' - function : Turn On Display - parameter: - ''' - def TurnOnDisplay(self): - self.send_command(0x22) # Display Update Control - self.send_data(0xC7) - self.send_command(0x20) # Activate Display Update Sequence - self.ReadBusy() - - ''' - function : Turn On Display Part - parameter: - ''' - def TurnOnDisplayPart(self): - self.send_command(0x22) # Display Update Control - self.send_data(0x0f) # fast:0x0c, quality:0x0f, 0xcf - self.send_command(0x20) # Activate Display Update Sequence - self.ReadBusy() - - ''' - function : Set lut - parameter: - lut : lut data - ''' - def Lut(self, lut): - self.send_command(0x32) - for i in range(0, 153): - self.send_data(lut[i]) - self.ReadBusy() - - ''' - function : Send lut data and configuration - parameter: - lut : lut data - ''' - def SetLut(self, lut): - self.Lut(lut) - self.send_command(0x3f) - self.send_data(lut[153]) - self.send_command(0x03) # gate voltage - self.send_data(lut[154]) - self.send_command(0x04) # source voltage - self.send_data(lut[155]) # VSH - self.send_data(lut[156]) # VSH2 - self.send_data(lut[157]) # VSL - self.send_command(0x2c) # VCOM - self.send_data(lut[158]) - - ''' - function : Setting the display window - parameter: - xstart : X-axis starting position - ystart : Y-axis starting position - xend : End position of X-axis - yend : End position of Y-axis - ''' - def SetWindow(self, x_start, y_start, x_end, y_end): - self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION - # x point must be the multiple of 8 or the last 3 bits will be ignored - self.send_data((x_start>>3) & 0xFF) - self.send_data((x_end>>3) & 0xFF) - - self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION - self.send_data(y_start & 0xFF) - self.send_data((y_start >> 8) & 0xFF) - self.send_data(y_end & 0xFF) - self.send_data((y_end >> 8) & 0xFF) - - ''' - function : Set Cursor - parameter: - x : X-axis starting position - y : Y-axis starting position - ''' - def SetCursor(self, x, y): - self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER - # x point must be the multiple of 8 or the last 3 bits will be ignored - self.send_data(x & 0xFF) - - self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER - self.send_data(y & 0xFF) - self.send_data((y >> 8) & 0xFF) - - ''' - function : Initialize the e-Paper register - parameter: - ''' - def init(self): - if (epdconfig.module_init() != 0): - return -1 - # EPD hardware init start - self.reset() - - self.ReadBusy() - self.send_command(0x12) #SWRESET - self.ReadBusy() - - self.send_command(0x01) #Driver output control - self.send_data(0xf9) - self.send_data(0x00) - self.send_data(0x00) - - self.send_command(0x11) #data entry mode - self.send_data(0x03) - - self.SetWindow(0, 0, self.width-1, self.height-1) - self.SetCursor(0, 0) - - self.send_command(0x3c) - self.send_data(0x05) - - self.send_command(0x21) # Display update control - self.send_data(0x00) - self.send_data(0x80) - - self.send_command(0x18) - self.send_data(0x80) - - self.ReadBusy() - - self.SetLut(self.lut_full_update) - return 0 - - ''' - function : Display images - parameter: - image : Image data - ''' - def getbuffer(self, image): - img = image - imwidth, imheight = img.size - if(imwidth == self.width and imheight == self.height): - img = img.convert('1') - elif(imwidth == self.height and imheight == self.width): - # image has correct dimensions, but needs to be rotated - img = img.rotate(90, expand=True).convert('1') - else: - logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height)) - # return a blank buffer - return [0x00] * (int(self.width/8) * self.height) - - buf = bytearray(img.tobytes('raw')) - return buf - - ''' - function : Sends the image buffer in RAM to e-Paper and displays - parameter: - image : Image data - ''' - def display(self, image): - if self.width%8 == 0: - linewidth = int(self.width/8) - else: - linewidth = int(self.width/8) + 1 - - self.send_command(0x24) - for j in range(0, self.height): - for i in range(0, linewidth): - self.send_data(image[i + j * linewidth]) - self.TurnOnDisplay() - - ''' - function : Sends the image buffer in RAM to e-Paper and partial refresh - parameter: - image : Image data - ''' - def displayPartial(self, image): - if self.width%8 == 0: - linewidth = int(self.width/8) - else: - linewidth = int(self.width/8) + 1 - - epdconfig.digital_write(self.reset_pin, 0) - epdconfig.delay_ms(1) - epdconfig.digital_write(self.reset_pin, 1) - - self.SetLut(self.lut_partial_update) - self.send_command(0x37) - self.send_data(0x00) - self.send_data(0x00) - self.send_data(0x00) - self.send_data(0x00) - self.send_data(0x00) - self.send_data(0x40) - self.send_data(0x00) - self.send_data(0x00) - self.send_data(0x00) - self.send_data(0x00) - - self.send_command(0x3C) #BorderWavefrom - self.send_data(0x80) - - self.send_command(0x22) - self.send_data(0xC0) - self.send_command(0x20) - self.ReadBusy() - - self.SetWindow(0, 0, self.width - 1, self.height - 1) - self.SetCursor(0, 0) - - self.send_command(0x24) # WRITE_RAM - for j in range(0, self.height): - for i in range(0, linewidth): - self.send_data(image[i + j * linewidth]) - self.TurnOnDisplayPart() - - ''' - function : Refresh a base image - parameter: - image : Image data - ''' - def displayPartBaseImage(self, image): - if self.width%8 == 0: - linewidth = int(self.width/8) - else: - linewidth = int(self.width/8) + 1 - - self.send_command(0x24) - for j in range(0, self.height): - for i in range(0, linewidth): - self.send_data(image[i + j * linewidth]) - - self.send_command(0x26) - for j in range(0, self.height): - for i in range(0, linewidth): - self.send_data(image[i + j * linewidth]) - self.TurnOnDisplay() - - ''' - function : Clear screen - parameter: - ''' - def Clear(self, color): - if self.width%8 == 0: - linewidth = int(self.width/8) - else: - linewidth = int(self.width/8) + 1 - # logger.debug(linewidth) - - self.send_command(0x24) - for j in range(0, self.height): - for i in range(0, linewidth): - self.send_data(color) - - self.TurnOnDisplay() - - ''' - function : Enter sleep mode - parameter: - ''' - def sleep(self): - self.send_command(0x10) #enter deep sleep - self.send_data(0x01) - - epdconfig.delay_ms(2000) - epdconfig.module_exit() - -### END OF FILE ### - diff --git a/pwnagotchi/ui/hw/libs/waveshare/v3/epdconfig.py b/pwnagotchi/ui/hw/libs/waveshare/v3/epdconfig.py deleted file mode 100644 index 861f43da..00000000 --- a/pwnagotchi/ui/hw/libs/waveshare/v3/epdconfig.py +++ /dev/null @@ -1,154 +0,0 @@ -# /***************************************************************************** -# * | File : epdconfig.py -# * | Author : Waveshare team -# * | Function : Hardware underlying interface -# * | Info : -# *---------------- -# * | This version: V1.0 -# * | Date : 2019-06-21 -# * | Info : -# ****************************************************************************** -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documnetation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -import os -import logging -import sys -import time - - -class RaspberryPi: - # Pin definition - RST_PIN = 17 - DC_PIN = 25 - CS_PIN = 8 - BUSY_PIN = 24 - - def __init__(self): - import spidev - import RPi.GPIO - - self.GPIO = RPi.GPIO - - # SPI device, bus = 0, device = 0 - self.SPI = spidev.SpiDev(0, 0) - - def digital_write(self, pin, value): - self.GPIO.output(pin, value) - - def digital_read(self, pin): - return self.GPIO.input(pin) - - def delay_ms(self, delaytime): - time.sleep(delaytime / 1000.0) - - def spi_writebyte(self, data): - self.SPI.writebytes(data) - - def module_init(self): - self.GPIO.setmode(self.GPIO.BCM) - self.GPIO.setwarnings(False) - self.GPIO.setup(self.RST_PIN, self.GPIO.OUT) - self.GPIO.setup(self.DC_PIN, self.GPIO.OUT) - self.GPIO.setup(self.CS_PIN, self.GPIO.OUT) - self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN) - self.SPI.max_speed_hz = 4000000 - self.SPI.mode = 0b00 - return 0 - - def module_exit(self): - logging.debug("spi end") - self.SPI.close() - - logging.debug("close 5V, Module enters 0 power consumption ...") - self.GPIO.output(self.RST_PIN, 0) - self.GPIO.output(self.DC_PIN, 0) - - self.GPIO.cleanup() - - -class JetsonNano: - # Pin definition - RST_PIN = 17 - DC_PIN = 25 - CS_PIN = 8 - BUSY_PIN = 24 - - def __init__(self): - import ctypes - find_dirs = [ - os.path.dirname(os.path.realpath(__file__)), - '/usr/local/lib', - '/usr/lib', - ] - self.SPI = None - for find_dir in find_dirs: - so_filename = os.path.join(find_dir, 'sysfs_software_spi.so') - if os.path.exists(so_filename): - self.SPI = ctypes.cdll.LoadLibrary(so_filename) - break - if self.SPI is None: - raise RuntimeError('Cannot find sysfs_software_spi.so') - - import Jetson.GPIO - self.GPIO = Jetson.GPIO - - def digital_write(self, pin, value): - self.GPIO.output(pin, value) - - def digital_read(self, pin): - return self.GPIO.input(self.BUSY_PIN) - - def delay_ms(self, delaytime): - time.sleep(delaytime / 1000.0) - - def spi_writebyte(self, data): - self.SPI.SYSFS_software_spi_transfer(data[0]) - - def module_init(self): - self.GPIO.setmode(self.GPIO.BCM) - self.GPIO.setwarnings(False) - self.GPIO.setup(self.RST_PIN, self.GPIO.OUT) - self.GPIO.setup(self.DC_PIN, self.GPIO.OUT) - self.GPIO.setup(self.CS_PIN, self.GPIO.OUT) - self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN) - self.SPI.SYSFS_software_spi_begin() - return 0 - - def module_exit(self): - logging.debug("spi end") - self.SPI.SYSFS_software_spi_end() - - logging.debug("close 5V, Module enters 0 power consumption ...") - self.GPIO.output(self.RST_PIN, 0) - self.GPIO.output(self.DC_PIN, 0) - - self.GPIO.cleanup() - - -if os.path.exists('/sys/bus/platform/drivers/gpiomem-bcm2835'): - implementation = RaspberryPi() -else: - implementation = JetsonNano() - -for func in [x for x in dir(implementation) if not x.startswith('_')]: - setattr(sys.modules[__name__], func, getattr(implementation, func)) - - -### END OF FILE ### diff --git a/pwnagotchi/ui/hw/libs/waveshare/v4/epd2in13_V4.py b/pwnagotchi/ui/hw/libs/waveshare/v4/epd2in13_V4.py deleted file mode 100644 index 50c5394d..00000000 --- a/pwnagotchi/ui/hw/libs/waveshare/v4/epd2in13_V4.py +++ /dev/null @@ -1,350 +0,0 @@ -# ***************************************************************************** -# * | File : epd2in13_V4.py -# * | Author : Waveshare team -# * | Function : Electronic paper driver -# * | Info : -# *---------------- -# * | This version: V1.0 -# * | Date : 2023-06-25 -# # | Info : python demo -# ----------------------------------------------------------------------------- -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documnetation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - - -import logging -from . import epdconfig - -# Display resolution -EPD_WIDTH = 122 -EPD_HEIGHT = 250 - -logger = logging.getLogger(__name__) - - -class EPD: - def __init__(self): - self.reset_pin = epdconfig.RST_PIN - self.dc_pin = epdconfig.DC_PIN - self.busy_pin = epdconfig.BUSY_PIN - self.cs_pin = epdconfig.CS_PIN - self.width = EPD_WIDTH - self.height = EPD_HEIGHT - - ''' - function :Hardware reset - parameter: - ''' - def reset(self): - epdconfig.digital_write(self.reset_pin, 1) - epdconfig.delay_ms(20) - epdconfig.digital_write(self.reset_pin, 0) - epdconfig.delay_ms(2) - epdconfig.digital_write(self.reset_pin, 1) - epdconfig.delay_ms(20) - - ''' - function :send command - parameter: - command : Command register - ''' - def send_command(self, command): - epdconfig.digital_write(self.dc_pin, 0) - epdconfig.digital_write(self.cs_pin, 0) - epdconfig.spi_writebyte([command]) - epdconfig.digital_write(self.cs_pin, 1) - - ''' - function :send data - parameter: - data : Write data - ''' - def send_data(self, data): - epdconfig.digital_write(self.dc_pin, 1) - epdconfig.digital_write(self.cs_pin, 0) - epdconfig.spi_writebyte([data]) - epdconfig.digital_write(self.cs_pin, 1) - - # send a lot of data - def send_data2(self, data): - epdconfig.digital_write(self.dc_pin, 1) - epdconfig.digital_write(self.cs_pin, 0) - epdconfig.spi_writebyte2(data) - epdconfig.digital_write(self.cs_pin, 1) - - ''' - function :Wait until the busy_pin goes LOW - parameter: - ''' - def ReadBusy(self): - logger.debug("e-Paper busy") - while(epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy - epdconfig.delay_ms(10) - logger.debug("e-Paper busy release") - - ''' - function : Turn On Display - parameter: - ''' - def TurnOnDisplay(self): - self.send_command(0x22) # Display Update Control - self.send_data(0xf7) - self.send_command(0x20) # Activate Display Update Sequence - self.ReadBusy() - - ''' - function : Turn On Display Fast - parameter: - ''' - def TurnOnDisplay_Fast(self): - self.send_command(0x22) # Display Update Control - self.send_data(0xC7) # fast:0x0c, quality:0x0f, 0xcf - self.send_command(0x20) # Activate Display Update Sequence - self.ReadBusy() - - ''' - function : Turn On Display Part - parameter: - ''' - def TurnOnDisplayPart(self): - self.send_command(0x22) # Display Update Control - self.send_data(0xff) # fast:0x0c, quality:0x0f, 0xcf - self.send_command(0x20) # Activate Display Update Sequence - self.ReadBusy() - - - ''' - function : Setting the display window - parameter: - xstart : X-axis starting position - ystart : Y-axis starting position - xend : End position of X-axis - yend : End position of Y-axis - ''' - def SetWindow(self, x_start, y_start, x_end, y_end): - self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION - # x point must be the multiple of 8 or the last 3 bits will be ignored - self.send_data((x_start>>3) & 0xFF) - self.send_data((x_end>>3) & 0xFF) - - self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION - self.send_data(y_start & 0xFF) - self.send_data((y_start >> 8) & 0xFF) - self.send_data(y_end & 0xFF) - self.send_data((y_end >> 8) & 0xFF) - - ''' - function : Set Cursor - parameter: - x : X-axis starting position - y : Y-axis starting position - ''' - def SetCursor(self, x, y): - self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER - # x point must be the multiple of 8 or the last 3 bits will be ignored - self.send_data(x & 0xFF) - - self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER - self.send_data(y & 0xFF) - self.send_data((y >> 8) & 0xFF) - - ''' - function : Initialize the e-Paper register - parameter: - ''' - def init(self): - if (epdconfig.module_init() != 0): - return -1 - # EPD hardware init start - self.reset() - - self.ReadBusy() - self.send_command(0x12) #SWRESET - self.ReadBusy() - - self.send_command(0x01) #Driver output control - self.send_data(0xf9) - self.send_data(0x00) - self.send_data(0x00) - - self.send_command(0x11) #data entry mode - self.send_data(0x03) - - self.SetWindow(0, 0, self.width-1, self.height-1) - self.SetCursor(0, 0) - - self.send_command(0x3c) - self.send_data(0x05) - - self.send_command(0x21) # Display update control - self.send_data(0x00) - self.send_data(0x80) - - self.send_command(0x18) - self.send_data(0x80) - - self.ReadBusy() - - return 0 - - ''' - function : Initialize the e-Paper fast register - parameter: - ''' - def init_fast(self): - if (epdconfig.module_init() != 0): - return -1 - # EPD hardware init start - self.reset() - - self.send_command(0x12) #SWRESET - self.ReadBusy() - - self.send_command(0x18) # Read built-in temperature sensor - self.send_command(0x80) - - self.send_command(0x11) # data entry mode - self.send_data(0x03) - - self.SetWindow(0, 0, self.width-1, self.height-1) - self.SetCursor(0, 0) - - self.send_command(0x22) # Load temperature value - self.send_data(0xB1) - self.send_command(0x20) - self.ReadBusy() - - self.send_command(0x1A) # Write to temperature register - self.send_data(0x64) - self.send_data(0x00) - - self.send_command(0x22) # Load temperature value - self.send_data(0x91) - self.send_command(0x20) - self.ReadBusy() - - return 0 - ''' - function : Display images - parameter: - image : Image data - ''' - def getbuffer(self, image): - img = image - imwidth, imheight = img.size - if(imwidth == self.width and imheight == self.height): - img = img.convert('1') - elif(imwidth == self.height and imheight == self.width): - # image has correct dimensions, but needs to be rotated - img = img.rotate(90, expand=True).convert('1') - else: - logger.warning("Wrong image dimensions: must be " + str(self.width) + "x" + str(self.height)) - # return a blank buffer - return [0x00] * (int(self.width/8) * self.height) - - buf = bytearray(img.tobytes('raw')) - return buf - - ''' - function : Sends the image buffer in RAM to e-Paper and displays - parameter: - image : Image data - ''' - def display(self, image): - self.send_command(0x24) - self.send_data2(image) - self.TurnOnDisplay() - - ''' - function : Sends the image buffer in RAM to e-Paper and fast displays - parameter: - image : Image data - ''' - def display_fast(self, image): - self.send_command(0x24) - self.send_data2(image) - self.TurnOnDisplay_Fast() - ''' - function : Sends the image buffer in RAM to e-Paper and partial refresh - parameter: - image : Image data - ''' - def displayPartial(self, image): - epdconfig.digital_write(self.reset_pin, 0) - epdconfig.delay_ms(1) - epdconfig.digital_write(self.reset_pin, 1) - - self.send_command(0x3C) # BorderWavefrom - self.send_data(0x80) - - self.send_command(0x01) # Driver output control - self.send_data(0xF9) - self.send_data(0x00) - self.send_data(0x00) - - self.send_command(0x11) # data entry mode - self.send_data(0x03) - - self.SetWindow(0, 0, self.width - 1, self.height - 1) - self.SetCursor(0, 0) - - self.send_command(0x24) # WRITE_RAM - self.send_data2(image) - self.TurnOnDisplayPart() - - ''' - function : Refresh a base image - parameter: - image : Image data - ''' - def displayPartBaseImage(self, image): - self.send_command(0x24) - self.send_data2(image) - - self.send_command(0x26) - self.send_data2(image) - self.TurnOnDisplay() - - ''' - function : Clear screen - parameter: - ''' - def Clear(self, color=0xFF): - if self.width%8 == 0: - linewidth = int(self.width/8) - else: - linewidth = int(self.width/8) + 1 - # logger.debug(linewidth) - - self.send_command(0x24) - self.send_data2([color] * int(self.height * linewidth)) - self.TurnOnDisplay() - - ''' - function : Enter sleep mode - parameter: - ''' - def sleep(self): - self.send_command(0x10) #enter deep sleep - self.send_data(0x01) - - epdconfig.delay_ms(2000) - epdconfig.module_exit() - -### END OF FILE ### \ No newline at end of file diff --git a/pwnagotchi/ui/hw/libs/waveshare/v4/epdconfig.py b/pwnagotchi/ui/hw/libs/waveshare/v4/epdconfig.py deleted file mode 100644 index 0c134192..00000000 --- a/pwnagotchi/ui/hw/libs/waveshare/v4/epdconfig.py +++ /dev/null @@ -1,243 +0,0 @@ -# /***************************************************************************** -# * | File : epdconfig.py -# * | Author : Waveshare team -# * | Function : Hardware underlying interface -# * | Info : -# *---------------- -# * | This version: V1.2 -# * | Date : 2022-10-29 -# * | Info : -# ****************************************************************************** -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documnetation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS OR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. -# - -import os -import logging -import sys -import time - -logger = logging.getLogger(__name__) - - -class RaspberryPi: - # Pin definition - RST_PIN = 17 - DC_PIN = 25 - CS_PIN = 8 - BUSY_PIN = 24 - PWR_PIN = 18 - - def __init__(self): - import spidev - import RPi.GPIO - - self.GPIO = RPi.GPIO - self.SPI = spidev.SpiDev() - - def digital_write(self, pin, value): - self.GPIO.output(pin, value) - - def digital_read(self, pin): - return self.GPIO.input(pin) - - def delay_ms(self, delaytime): - time.sleep(delaytime / 1000.0) - - def spi_writebyte(self, data): - self.SPI.writebytes(data) - - def spi_writebyte2(self, data): - self.SPI.writebytes2(data) - - def module_init(self): - self.GPIO.setmode(self.GPIO.BCM) - self.GPIO.setwarnings(False) - self.GPIO.setup(self.RST_PIN, self.GPIO.OUT) - self.GPIO.setup(self.DC_PIN, self.GPIO.OUT) - self.GPIO.setup(self.CS_PIN, self.GPIO.OUT) - self.GPIO.setup(self.PWR_PIN, self.GPIO.OUT) - self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN) - - self.GPIO.output(self.PWR_PIN, 1) - - # SPI device, bus = 0, device = 0 - self.SPI.open(0, 0) - self.SPI.max_speed_hz = 4000000 - self.SPI.mode = 0b00 - return 0 - - def module_exit(self): - logger.debug("spi end") - self.SPI.close() - - logger.debug("close 5V, Module enters 0 power consumption ...") - self.GPIO.output(self.RST_PIN, 0) - self.GPIO.output(self.DC_PIN, 0) - self.GPIO.output(self.PWR_PIN, 0) - - self.GPIO.cleanup([self.RST_PIN, self.DC_PIN, self.CS_PIN, self.BUSY_PIN, self.PWR_PIN]) - - -class JetsonNano: - # Pin definition - RST_PIN = 17 - DC_PIN = 25 - CS_PIN = 8 - BUSY_PIN = 24 - PWR_PIN = 18 - - def __init__(self): - import ctypes - find_dirs = [ - os.path.dirname(os.path.realpath(__file__)), - '/usr/local/lib', - '/usr/lib', - ] - self.SPI = None - for find_dir in find_dirs: - so_filename = os.path.join(find_dir, 'sysfs_software_spi.so') - if os.path.exists(so_filename): - self.SPI = ctypes.cdll.LoadLibrary(so_filename) - break - if self.SPI is None: - raise RuntimeError('Cannot find sysfs_software_spi.so') - - import Jetson.GPIO - self.GPIO = Jetson.GPIO - - def digital_write(self, pin, value): - self.GPIO.output(pin, value) - - def digital_read(self, pin): - return self.GPIO.input(self.BUSY_PIN) - - def delay_ms(self, delaytime): - time.sleep(delaytime / 1000.0) - - def spi_writebyte(self, data): - self.SPI.SYSFS_software_spi_transfer(data[0]) - - def spi_writebyte2(self, data): - for i in range(len(data)): - self.SPI.SYSFS_software_spi_transfer(data[i]) - - def module_init(self): - self.GPIO.setmode(self.GPIO.BCM) - self.GPIO.setwarnings(False) - self.GPIO.setup(self.RST_PIN, self.GPIO.OUT) - self.GPIO.setup(self.DC_PIN, self.GPIO.OUT) - self.GPIO.setup(self.CS_PIN, self.GPIO.OUT) - self.GPIO.setup(self.PWR_PIN, self.GPIO.OUT) - self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN) - - self.GPIO.output(self.PWR_PIN, 1) - - self.SPI.SYSFS_software_spi_begin() - return 0 - - def module_exit(self): - logger.debug("spi end") - self.SPI.SYSFS_software_spi_end() - - logger.debug("close 5V, Module enters 0 power consumption ...") - self.GPIO.output(self.RST_PIN, 0) - self.GPIO.output(self.DC_PIN, 0) - self.GPIO.output(self.PWR_PIN, 0) - - self.GPIO.cleanup([self.RST_PIN, self.DC_PIN, self.CS_PIN, self.BUSY_PIN, self.PWR_PIN]) - - -class SunriseX3: - # Pin definition - RST_PIN = 17 - DC_PIN = 25 - CS_PIN = 8 - BUSY_PIN = 24 - PWR_PIN = 18 - Flag = 0 - - def __init__(self): - import spidev - import Hobot.GPIO - - self.GPIO = Hobot.GPIO - self.SPI = spidev.SpiDev() - - def digital_write(self, pin, value): - self.GPIO.output(pin, value) - - def digital_read(self, pin): - return self.GPIO.input(pin) - - def delay_ms(self, delaytime): - time.sleep(delaytime / 1000.0) - - def spi_writebyte(self, data): - self.SPI.writebytes(data) - - def spi_writebyte2(self, data): - # for i in range(len(data)): - # self.SPI.writebytes([data[i]]) - self.SPI.xfer3(data) - - def module_init(self): - if self.Flag == 0: - self.Flag = 1 - self.GPIO.setmode(self.GPIO.BCM) - self.GPIO.setwarnings(False) - self.GPIO.setup(self.RST_PIN, self.GPIO.OUT) - self.GPIO.setup(self.DC_PIN, self.GPIO.OUT) - self.GPIO.setup(self.CS_PIN, self.GPIO.OUT) - self.GPIO.setup(self.PWR_PIN, self.GPIO.OUT) - self.GPIO.setup(self.BUSY_PIN, self.GPIO.IN) - - self.GPIO.output(self.PWR_PIN, 1) - - # SPI device, bus = 0, device = 0 - self.SPI.open(2, 0) - self.SPI.max_speed_hz = 4000000 - self.SPI.mode = 0b00 - return 0 - else: - return 0 - - def module_exit(self): - logger.debug("spi end") - self.SPI.close() - - logger.debug("close 5V, Module enters 0 power consumption ...") - self.Flag = 0 - self.GPIO.output(self.RST_PIN, 0) - self.GPIO.output(self.DC_PIN, 0) - self.GPIO.output(self.PWR_PIN, 0) - - self.GPIO.cleanup([self.RST_PIN, self.DC_PIN, self.CS_PIN, self.BUSY_PIN], self.PWR_PIN) - - -if os.path.exists('/sys/bus/platform/drivers/gpiomem-bcm2835'): - implementation = RaspberryPi() -elif os.path.exists('/sys/bus/platform/drivers/gpio-x3'): - implementation = SunriseX3() -else: - implementation = JetsonNano() - -for func in [x for x in dir(implementation) if not x.startswith('_')]: - setattr(sys.modules[__name__], func, getattr(implementation, func)) - -### END OF FILE ### \ No newline at end of file diff --git a/pwnagotchi/ui/hw/waveshare3in52.py b/pwnagotchi/ui/hw/waveshare3in52.py index a980e40e..0b502279 100644 --- a/pwnagotchi/ui/hw/waveshare3in52.py +++ b/pwnagotchi/ui/hw/waveshare3in52.py @@ -42,6 +42,5 @@ class Waveshare3in52(DisplayImpl): self._display.display(buf) self._display.refresh() - def clear(self): self._display.Clear() diff --git a/pwnagotchi/utils.py b/pwnagotchi/utils.py index 227364cd..674e8b84 100644 --- a/pwnagotchi/utils.py +++ b/pwnagotchi/utils.py @@ -304,16 +304,16 @@ def load_config(args): elif config['ui']['display']['type'] in ('waveshare1in64g', 'ws1in64g', 'ws164g', 'waveshare_164g', 'waveshare_1in64g'): config['ui']['display']['type'] = 'waveshare1in64g' - elif config['ui']['display']['type'] in ('ws_1', 'ws1', 'waveshare_1', 'waveshare1'): + elif config['ui']['display']['type'] in ('ws_1', 'ws1', 'waveshare_1', 'waveshare1', 'waveshare2in13'): config['ui']['display']['type'] = 'waveshare_1' - elif config['ui']['display']['type'] in ('ws_2', 'ws2', 'waveshare_2', 'waveshare2'): + elif config['ui']['display']['type'] in ('ws_2', 'ws2', 'waveshare_2', 'waveshare2', 'waveshare2in13v2'): config['ui']['display']['type'] = 'waveshare_2' - elif config['ui']['display']['type'] in ('ws_3', 'ws3', 'waveshare_3', 'waveshare3'): + elif config['ui']['display']['type'] in ('ws_3', 'ws3', 'waveshare_3', 'waveshare3', 'waveshare2in13v3'): config['ui']['display']['type'] = 'waveshare_3' - elif config['ui']['display']['type'] in ('ws_4', 'ws4', 'waveshare_4', 'waveshare4'): + elif config['ui']['display']['type'] in ('ws_4', 'ws4', 'waveshare_4', 'waveshare4', 'waveshare2in13v4'): config['ui']['display']['type'] = 'waveshare_4' elif config['ui']['display']['type'] in ('waveshare2in13b_v3', 'waveshare2in13b_v3', 'ws213bv3', 'waveshare_213bv3', 'waveshare213inb_v3'): diff --git a/pyproject.toml b/pyproject.toml index ff8eaa25..834dcb47 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,11 +9,13 @@ dependencies = [ "Pillow", "PyYAML", "RPi.GPIO", + "dbus-python", "file-read-backwards", "flask", "flask-cors", "flask-wtf", "gast", + "gpiozero", "gym", "inky", "pycryptodome", @@ -30,7 +32,7 @@ dependencies = [ "torch", "torchvision", "tweepy", - "websockets" + "websockets", ] requires-python = ">=3.9" authors = [ diff --git a/setup.py b/setup.py index 6202183a..cf05b52f 100644 --- a/setup.py +++ b/setup.py @@ -9,6 +9,7 @@ import re import shutil import warnings import platform +import apt log = logging.getLogger(__name__) @@ -31,6 +32,18 @@ def install_file(source_filename, dest_filename): def install_system_files(): + f = open("apt_packages.txt", "r") + cache = apt.cache.Cache() + cache.update() + cache.open() + + for x in f: + pkg = cache[x] + if pkg.is_installed: + continue + else: + pkg.mark_install() + f.close() setup_path = os.path.dirname(__file__) if platform.machine().startswith('arm'): data_path = os.path.join(setup_path, "builder/data/32bit")