diff --git a/pwnagotchi/ui/display.py b/pwnagotchi/ui/display.py index 181ed769..186030fa 100644 --- a/pwnagotchi/ui/display.py +++ b/pwnagotchi/ui/display.py @@ -49,8 +49,11 @@ class Display(View): def is_lcdhat(self): return self._implementation.name == 'lcdhat' - def is_dfrobot(self): - return self._implementation.name == 'dfrobot' + def is_dfrobot_v1(self): + return self._implementation.name == 'dfrobot_v1' + + def is_dfrobot_v2(self): + return self._implementation.name == 'dfrobot_v2' def is_waveshare144lcd(self): return self._implementation.name == 'waveshare144lcd' diff --git a/pwnagotchi/ui/hw/__init__.py b/pwnagotchi/ui/hw/__init__.py index 432cb54c..eb927dcb 100644 --- a/pwnagotchi/ui/hw/__init__.py +++ b/pwnagotchi/ui/hw/__init__.py @@ -2,7 +2,8 @@ from pwnagotchi.ui.hw.inky import Inky from pwnagotchi.ui.hw.papirus import Papirus from pwnagotchi.ui.hw.oledhat import OledHat from pwnagotchi.ui.hw.lcdhat import LcdHat -from pwnagotchi.ui.hw.dfrobot import DFRobot +from pwnagotchi.ui.hw.dfrobot1 import DFRobotV1 +from pwnagotchi.ui.hw.dfrobot2 import DFRobotV2 from pwnagotchi.ui.hw.waveshare1 import WaveshareV1 from pwnagotchi.ui.hw.waveshare2 import WaveshareV2 from pwnagotchi.ui.hw.waveshare27inch import Waveshare27inch @@ -27,8 +28,11 @@ def display_for(config): if config['ui']['display']['type'] == 'lcdhat': return LcdHat(config) - if config['ui']['display']['type'] == 'dfrobot': - return DFRobot(config) + if config['ui']['display']['type'] == 'dfrobot_1': + return DFRobotV1(config) + + if config['ui']['display']['type'] == 'dfrobot_2': + return DFRobotV2(config) elif config['ui']['display']['type'] == 'waveshare_1': return WaveshareV1(config) diff --git a/pwnagotchi/ui/hw/dfrobot.py b/pwnagotchi/ui/hw/dfrobot1.py similarity index 84% rename from pwnagotchi/ui/hw/dfrobot.py rename to pwnagotchi/ui/hw/dfrobot1.py index 1d9c8ee3..732faf8e 100644 --- a/pwnagotchi/ui/hw/dfrobot.py +++ b/pwnagotchi/ui/hw/dfrobot1.py @@ -3,9 +3,9 @@ import logging import pwnagotchi.ui.fonts as fonts from pwnagotchi.ui.hw.base import DisplayImpl -class DFRobot(DisplayImpl): +class DFRobotV1(DisplayImpl): def __init__(self, config): - super(DFRobot, self).__init__(config, 'dfrobot') + super(DFRobotV1, self).__init__(config, 'dfrobot_1') self._display = None def layout(self): @@ -31,8 +31,8 @@ class DFRobot(DisplayImpl): return self._layout def initialize(self): - logging.info("initializing dfrobot display") - from pwnagotchi.ui.hw.libs.dfrobot.dfrobot import DFRobot + logging.info("initializing dfrobot1 display") + from pwnagotchi.ui.hw.libs.dfrobot.v1.dfrobot import DFRobot self._display = DFRobot() def render(self, canvas): diff --git a/pwnagotchi/ui/hw/dfrobot2.py b/pwnagotchi/ui/hw/dfrobot2.py new file mode 100644 index 00000000..995afd38 --- /dev/null +++ b/pwnagotchi/ui/hw/dfrobot2.py @@ -0,0 +1,43 @@ +import logging + +import pwnagotchi.ui.fonts as fonts +from pwnagotchi.ui.hw.base import DisplayImpl + +class DFRobotV2(DisplayImpl): + def __init__(self, config): + super(DFRobotV2, self).__init__(config, 'dfrobot_2') + self._display = None + + def layout(self): + fonts.setup(10, 9, 10, 35, 25, 9) + self._layout['width'] = 250 + self._layout['height'] = 122 + self._layout['face'] = (0, 40) + self._layout['name'] = (5, 20) + self._layout['channel'] = (0, 0) + self._layout['aps'] = (28, 0) + self._layout['uptime'] = (185, 0) + self._layout['line1'] = [0, 14, 250, 14] + self._layout['line2'] = [0, 108, 250, 108] + self._layout['friend_face'] = (0, 92) + self._layout['friend_name'] = (40, 94) + self._layout['shakes'] = (0, 109) + self._layout['mode'] = (225, 109) + self._layout['status'] = { + 'pos': (125, 20), + 'font': fonts.status_font(fonts.Medium), + 'max': 20 + } + return self._layout + + def initialize(self): + logging.info("initializing dfrobot2 display") + from pwnagotchi.ui.hw.libs.dfrobot.v2.dfrobot import DFRobot + self._display = DFRobot() + + def render(self, canvas): + buf = self._display.getbuffer(canvas) + self._display.display(buf) + + def clear(self): + self._display.Clear(0xFF) diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v1/__init__.py b/pwnagotchi/ui/hw/libs/dfrobot/v1/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pwnagotchi/ui/hw/libs/dfrobot/dfrobot.py b/pwnagotchi/ui/hw/libs/dfrobot/v1/dfrobot.py similarity index 100% rename from pwnagotchi/ui/hw/libs/dfrobot/dfrobot.py rename to pwnagotchi/ui/hw/libs/dfrobot/v1/dfrobot.py diff --git a/pwnagotchi/ui/hw/libs/dfrobot/dfrobot_epaper.py b/pwnagotchi/ui/hw/libs/dfrobot/v1/dfrobot_epaper.py similarity index 100% rename from pwnagotchi/ui/hw/libs/dfrobot/dfrobot_epaper.py rename to pwnagotchi/ui/hw/libs/dfrobot/v1/dfrobot_epaper.py diff --git a/pwnagotchi/ui/hw/libs/dfrobot/gpio.py b/pwnagotchi/ui/hw/libs/dfrobot/v1/gpio.py similarity index 100% rename from pwnagotchi/ui/hw/libs/dfrobot/gpio.py rename to pwnagotchi/ui/hw/libs/dfrobot/v1/gpio.py diff --git a/pwnagotchi/ui/hw/libs/dfrobot/spi.py b/pwnagotchi/ui/hw/libs/dfrobot/v1/spi.py similarity index 100% rename from pwnagotchi/ui/hw/libs/dfrobot/spi.py rename to pwnagotchi/ui/hw/libs/dfrobot/v1/spi.py diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/__init__.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot.py new file mode 100644 index 00000000..02ebb8d6 --- /dev/null +++ b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot.py @@ -0,0 +1,66 @@ +# DFRobot display support + +import logging +from . import dfrobot_epaper + +#Resolution of display +WIDTH = 250 +HEIGHT = 122 + +RASPBERRY_SPI_BUS = 0 +RASPBERRY_SPI_DEV = 0 +RASPBERRY_PIN_CS = 27 +RASPBERRY_PIN_CD = 17 +RASPBERRY_PIN_BUSY = 4 + +class DFRobot: + def __init__(self): + self._display = dfrobot_epaper.DFRobot_Epaper_SPI(RASPBERRY_SPI_BUS, RASPBERRY_SPI_DEV, RASPBERRY_PIN_CS, RASPBERRY_PIN_CD, RASPBERRY_PIN_BUSY) + self._display.begin() + self.clear(0xFF) + self.FULL = self._display.FULL + self.PART = self._display.PART + + def getbuffer(self, image): + if HEIGHT % 8 == 0: + linewidth = HEIGHT // 8 + else: + linewidth = HEIGHT // 8 + 1 + + buf = [0xFF] * (linewidth * WIDTH) + image_monocolor = image.convert('1') + imwidth, imheight = image_monocolor.size + pixels = image_monocolor.load() + + if (imwidth == HEIGHT and imheight == WIDTH): + 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 == WIDTH and imheight == HEIGHT): + for y in range(imheight): + for x in range(imwidth): + newx = y + newy = WIDTH - x - 1 + if pixels[x,y] == 0: + newy = imwidth - newy - 1 + buf[newx // 8 + newy * linewidth] &= ~(0x80 >> (y % 8)) + return buf + + def flush(self, type): + self._display.flush(type) + + def display(self, buf): + self._display.setBuffer(buf) + self.flush(self._display.PART) + + def clear(self, color): + if HEIGHT % 8 == 0: + linewidth = HEIGHT // 8 + else: + linewidth = HEIGHT // 8 + 1 + + buf = [color] * (linewidth * WIDTH) + self._display.setBuffer(buf) + self.flush(self._display.FULL) diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/__init__.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/__init__.pyc b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/__init__.pyc new file mode 100644 index 00000000..d739fd19 Binary files /dev/null and b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/__init__.pyc differ diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_display.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_display.py new file mode 100644 index 00000000..7a055f71 --- /dev/null +++ b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_display.py @@ -0,0 +1,673 @@ +# -*- coding:utf-8 -*- + +import sys + +from .dfrobot_printString import PrintString +from .dfrobot_fonts import Fonts + +def color24to16(color): + return (((color >> 8) & 0xf800) | ((color >> 5) & 0x7e0) | ((color >> 3) & 0x1f)) + +def color16to24(color): + return (((color & 0xf800) << 8) | ((color & 0x7e0) << 5) | ((color & 0x1f) << 3)) + +def swap(o1, o2): + return (o2, o1) + +class DFRobot_Display(PrintString): + + WHITE24 = 0xffffff + SILVER24 = 0xc0c0c0 + GRAY24 = 0x808080 + BLACK24 = 0x000000 + RED24 = 0xff0000 + MAROON24 = 0x800000 + YELLOW24 = 0xffff00 + OLIVE24 = 0x808000 + GREEN24 = 0x00ff00 + DARKGREEN24 = 0x008000 + CYAN24 = 0x00ffff + BLUE24 = 0x0000ff + NAVY24 = 0x000080 + FUCHSIA24 = 0xff00ff + PURPLE24 = 0x800080 + TEAL24 = 0x008080 + + WHITE16 = color24to16(WHITE24) + SILVER16 = color24to16(SILVER24) + GRAY16 = color24to16(GRAY24) + BLACK16 = color24to16(BLACK24) + RED16 = color24to16(RED24) + MAROON16 = color24to16(MAROON24) + YELLOW16 = color24to16(YELLOW24) + OLIVE16 = color24to16(OLIVE24) + GREEN16 = color24to16(GREEN24) + DARKGREEN16 = color24to16(DARKGREEN24) + CYAN16 = color24to16(CYAN24) + BLUE16 = color24to16(BLUE24) + NAVY16 = color24to16(NAVY24) + FUCHSIA16 = color24to16(FUCHSIA24) + PURPLE16 = color24to16(PURPLE24) + TEAL16 = color24to16(TEAL24) + + WHITE = WHITE16 + SILVER = SILVER16 + GRAY = GRAY16 + BLACK = BLACK16 + RED = RED16 + MAROON = MAROON16 + YELLOW = YELLOW16 + OLIVE = OLIVE16 + GREEN = GREEN16 + DARKGREEN = DARKGREEN16 + CYAN = CYAN16 + BLUE = BLUE16 + NAVY = NAVY16 + FUCHSIA = FUCHSIA16 + PURPLE = PURPLE16 + TEAL = TEAL16 + + POSITIVE = 1 + REVERSE = -1 + + BITMAP_TBMLLR = "TBMLLR" + BITMAP_TBMRLL = "TBMRLL" + BITMAP_BTMLLR = "BTMLLR" + BITMAP_BTMRLL = "BTMRLL" + BITMAP_LRMTLB = "LRMTLB" + BITMAP_LRMBLT = "LRMBLT" + BITMAP_RLMTLB = "RLMTLB" + BIMTAP_RLMBLT = "RLMBLT" + BITMAP_UNKNOW = "UNKNOW" + + def __init__(self, w, h): + PrintString.__init__(self) + print("DFRobot_Display init " + str(w) + " " + str(h)) + self._width = w + self._height = h + + self._lineWidth = 1 + self._bitmapSize = 1 + self._bitmapFmt = "" + self._bmpFmt = self.BITMAP_TBMLLR + + self._fonts = Fonts() + self._textSize = 1 + self._textColor = self.BLACK + self._textBackground = self.WHITE + self._textCursorX = 0 + self._textCursorY = 0 + self._textIntervalRow = 0 + self._textIntervalCol = 0 + + def _ternaryExpression(self, condition, o1, o2): + if condition: + return o1 + return o2 + + def _getDirection(self, value): + if value >= 0: + return 1 + return -1 + + def color16to24(self, color): + return color16to24(color) + + def color24to16(self, color): + return color24to16(color) + + def setColorTo16(self): + self.WHITE = self.WHITE16 + self.SILVER = self.SILVER16 + self.GRAY = self.GRAY16 + self.BLACK = self.BLACK16 + self.RED = self.RED16 + self.MAROON = self.MAROON16 + self.YELLOW = self.YELLOW16 + self.OLIVE = self.OLIVE16 + self.GREEN = self.GREEN16 + self.DARKGREEN = self.DARKGREEN16 + self.CYAN = self.CYAN16 + self.BLUE = self.BLUE16 + self.NAVY = self.NAVY16 + self.FUCHSIA = self.FUCHSIA16 + self.PURPLE = self.PURPLE16 + self.TEAL = self.TEAL16 + + def setColorTo24(self): + self.WHITE = self.WHITE24 + self.SILVER = self.SILVER24 + self.GRAY = self.GRAY24 + self.BLACK = self.BLACK24 + self.RED = self.RED24 + self.MAROON = self.MAROON24 + self.YELLOW = self.YELLOW24 + self.OLIVE = self.OLIVE24 + self.GREEN = self.GREEN24 + self.DARKGREEN = self.DARKGREEN24 + self.CYAN = self.CYAN24 + self.BLUE = self.BLUE24 + self.NAVY = self.NAVY24 + self.FUCHSIA = self.FUCHSIA24 + self.PURPLE = self.PURPLE24 + self.TEAL = self.TEAL24 + + def setLineWidth(self, w): + if w < 0: + return + self._lineWidth = w + + def setTextFormat(self, size, color, background, intervalRow = 2, intervalCol = 0): + self._textColor = color + self._textIntervalRow = intervalRow + self._textIntervalCol = intervalCol + self._textBackground = background + if size < 0: + return + self._textSize = size + + def setTextCursor(self, x, y): + self._textCursorX = int(x) + self._textCursorY = int(y) + + def setBitmapSize(self, size): + if size < 0: + return + self._bitmapSize = size + + def setBitmapFmt(self, fmt): + self._bmpFmt = fmt + + def setExFonts(self, obj): + self._fonts.setExFonts(obj) + + def setExFontsFmt(self, width, height): + self._fonts.setExFontsFmt(width, height) + + def setEnableDefaultFonts(self, opt): + self._fonts.setEnableDefaultFonts(opt) + + def pixel(self, x, y, color): + pass + + def clear(self, color): + self.fillRect(0, 0, self._width, self._height, color) + self._textCursorX = 0 + self._textCursorY = 0 + + def VLine(self, x, y, h, color): + x = int(x) + y = int(y) + h = int(h) + direction = self._getDirection(h) + x -= self._lineWidth // 2 + h = self._ternaryExpression(h > 0, h, -h) + for i in range(self._ternaryExpression(h > 0, h, - h)): + xx = x + for j in range(self._lineWidth): + self.pixel(xx, y, color) + xx += 1 + y += direction + + def HLine(self, x, y, w, color): + x = int(x) + y = int(y) + w = int(w) + direction = self._getDirection(w) + y -= self._lineWidth // 2 + for i in range(self._ternaryExpression(w > 0, w, - w)): + yy = y + for j in range(self._lineWidth): + self.pixel(x, yy, color) + yy += 1 + x += direction + + def line(self, x, y, x1, y1, color): + x = int(x) + y = int(y) + x1 = int(x1) + y1 = int(y1) + if x == x1: + self.VLine(x, y, y1 - y, color) + return + if y == y1: + self.HLine(x, y, x1 - x, color) + return + dx = abs(x1 - x) + dy = abs(y1 - y) + dirX = self._ternaryExpression(x < x1, 1, -1) + dirY = self._ternaryExpression(y < y1, 1, -1) + if dx > dy: + err = dx / 2 + for i in range(dx): + self.HLine(x, y, 1, color) + x += dirX + err -= dy + if err < 0: + err += dx + y += dirY + self.HLine(x1, y1, 1, color) + else: + err = dy / 2 + for i in range(dy): + self.VLine(x, y, 1, color) + y += dirY + err -= dx + if err < 0: + err += dy + x += dirX + self.VLine(x1, y1, 1, color) + + def triangle(self, x, y, x1, y1, x2, y2, color): + self.line(x, y, x1, y1, color) + self.line(x1, y1, x2, y2, color) + self.line(x2, y2, x, y, color) + + def fillTriangle(self, x, y, x1, y1, x2, y2, color): + self.line(x, y, x1, y1, color) + self.line(x1, y1, x2, y2, color) + self.line(x2, y2, x, y, color) + x = int(x) + y = int(y) + x1 = int(x1) + y1 = int(y1) + x2 = int(x2) + y2 = int(y2) + temp = self._lineWidth + self._lineWidth = 1 + if x == x1 and x == x2: + ymax = max([y, y1, y2]) + ymin = min([y, y1, y2]) + self.HLine(x, ymin, ymax - ymin, color) + self._lineWidth = temp + return + if y == y1 and y == y2: + xmax = max([x, x1, x2]) + xmin = max([x, x1, x2]) + self.VLine(xmin, y, xmax - xmin, color) + self._lineWidth = temp + return + + direction = self.POSITIVE + if y == y1 or y1 == y2 or y == y2: + if y == y1: + (x, x2) = swap(x, x2) + (y, y2) = swap(y, y2) + elif y == y2: + (x, x1) = swap(x, x1) + (y, y1) = swap(y, y1) + if y > y1: + direction = self.REVERSE + if x1 > x2: + (x1, x2) = swap(x1, x2) + (y1, y2) = swap(y1, y2) + else: + if y > y1: + (x, x1) = swap(x, x1) + (y, y1) = swap(y, y1) + if y > y2: + (x, x2) = swap(x, x2) + (y, y2) = swap(y, y2) + if y1 > y2: + (x1, x2) = swap(x1, x2) + (y1, y2) = swap(y1, y2) + + dx1 = x1 - x + dx2 = x2 - x + dx3 = x2 - x1 + dy1 = y1 - y + dy2 = y2 - y + dy3 = y2 - y1 + if direction == self.POSITIVE: + for i in range(dy1): + self.HLine(x + dx1 * i / dy1, y + i, (x + dx2 * i / dy2) - (x + dx1 * i / dy1) + 1, color) + for i in range(dy3): + self.HLine(x1 + dx3 * i / dy3, y1 + i, (x + dx2 * (i + dy1) / dy2) - (x1 + dx3 * i / dy3) + 1, color) + else: + y = y1 + dy1 + dy1 = - dy1 + for i in range(dy1): + self.HLine(x + dx1 * i / dy1, y1 + dy1 - i, (x + dx2 * i / dy1) - (x + dx1 * i / dy1) + 1, color) + self._lineWidth = temp + + def rect(self, x, y, w, h, color): + if w < 0: + x += w + w = -w + if h < 0: + y += h + h = -h + self.HLine(x - self._lineWidth // 2, y, w + self._lineWidth, color) + self.HLine(x - self._lineWidth // 2, y + h, w + self._lineWidth, color) + self.VLine(x, y - self._lineWidth // 2, h + self._lineWidth, color) + self.VLine(x + w, y - self._lineWidth // 2, h + self._lineWidth, color) + + def fillRect(self, x, y, w, h, color): + temp = self._lineWidth + self._lineWidth = 1 + if w < 0: + x += w + w = abs(w) + for i in range(w): + self.VLine(x + i, y, h, color) + self._lineWidth = temp + + QUADRANT_1 = 1 + QUADRANT_2 = 2 + QUADRANT_3 = 4 + QUADRANT_4 = 8 + QUADRANT_ALL = 15 + + def circleHelper(self, x, y, r, quadrant, color): + x = int(x) + y = int(y) + r = abs(int(r)) + vx = 0 + vy = r + dx = 1 + dy = -2 * r + p = 1 - r + if quadrant & self.QUADRANT_1: + self.VLine(x + r, y, 1, color) + if quadrant & self.QUADRANT_2: + self.VLine(x, y - r, 1, color) + if quadrant & self.QUADRANT_3: + self.VLine(x - r, y, 1, color) + if quadrant & self.QUADRANT_4: + self.VLine(x, y + r, 1, color) + + halfLineWidth = self._lineWidth // 2 + while vx < vy: + if p >= 0: + vy -= 1 + dy += 2 + p += dy + vx += 1 + dx += 2 + p += dx + if quadrant & self.QUADRANT_1: + self.fillRect(x + vx - halfLineWidth, y - vy - halfLineWidth, self._lineWidth, self._lineWidth, color) # quadrant 1 + self.fillRect(x + vy - halfLineWidth, y - vx - halfLineWidth, self._lineWidth, self._lineWidth, color) # quadrant 1 + if quadrant & self.QUADRANT_2: + self.fillRect(x - vx - halfLineWidth, y - vy - halfLineWidth, self._lineWidth, self._lineWidth, color) # quadrant 2 + self.fillRect(x - vy - halfLineWidth, y - vx - halfLineWidth, self._lineWidth, self._lineWidth, color) # quadrant 2 + if quadrant & self.QUADRANT_3: + self.fillRect(x - vx - halfLineWidth, y + vy - halfLineWidth, self._lineWidth, self._lineWidth, color) # quadrant 3 + self.fillRect(x - vy - halfLineWidth, y + vx - halfLineWidth, self._lineWidth, self._lineWidth, color) # quadrant 3 + if quadrant & self.QUADRANT_4: + self.fillRect(x + vx - halfLineWidth, y + vy - halfLineWidth, self._lineWidth, self._lineWidth, color) # quadrant 4 + self.fillRect(x + vy - halfLineWidth, y + vx - halfLineWidth, self._lineWidth, self._lineWidth, color) # quadrant 4 + + def circle(self, x, y, r, color): + self.circleHelper(x, y, r, self.QUADRANT_ALL, color) + + def fillCircleHelper(self, x, y, r, quadrant, color): + x = int(x) + y = int(y) + r = abs(int(r)) + temp = self._lineWidth + self._lineWidth = 1 + vx = 0 + vy = r + dx = 1 + dy = -2 * r + p = 1 - r + if quadrant & self.QUADRANT_1: + self.HLine(x, y, r + 1, color) + if quadrant & self.QUADRANT_2: + self.VLine(x, y, - r - 1, color) + if quadrant & self.QUADRANT_3: + self.HLine(x, y, - r - 1, color) + if quadrant & self.QUADRANT_4: + self.VLine(x, y, r + 1, color) + + while vx < vy: + if p >= 0: + vy -= 1 + dy += 2 + p += dy + vx += 1 + dx += 2 + p += dx + if quadrant & self.QUADRANT_1: + self.VLine(x + vx, y - vy, vy, color) # quadrant 1 + self.VLine(x + vy, y - vx, vx, color) # quadrant 1 + if quadrant & self.QUADRANT_2: + self.VLine(x - vx, y - vy, vy, color) # quadrant 2 + self.VLine(x - vy, y - vx, vx, color) # quadrant 2 + if quadrant & self.QUADRANT_3: + self.VLine(x - vx, y + vy, - vy, color) # quadrant 3 + self.VLine(x - vy, y + vx, - vx, color) # quadrant 3 + if quadrant & self.QUADRANT_4: + self.VLine(x + vx, y + vy, - vy, color) # quadrant 4 + self.VLine(x + vy, y + vx, - vx, color) # quadrant 4 + self._lineWidth = temp + + def fillCircle(self, x, y, r, color): + self.fillCircleHelper(x, y, r, self.QUADRANT_ALL, color) + + def roundRect(self, x, y, w, h, r, color): + x = int(x) + y = int(y) + w = int(w) + h = int(h) + r = abs(int(r)) + if w < 0: + x += w + w = abs(w) + if h < 0: + y += h + h = abs(h) + self.HLine(x + r, y, w - 2 * r + 1, color) + self.HLine(x + r, y + h, w - 2 * r + 1, color) + self.VLine(x, y + r, h - 2 * r + 1, color) + self.VLine(x + w, y + r, h - 2 * r + 1, color) + self.circleHelper(x + r, y + r, r, self.QUADRANT_2, color) + self.circleHelper(x + w - r, y + r, r, self.QUADRANT_1, color) + self.circleHelper(x + r, y + h - r, r, self.QUADRANT_3, color) + self.circleHelper(x + w - r, y + h - r, r, self.QUADRANT_4, color) + + def fillRoundRect(self, x, y, w, h, r, color): + x = int(x) + y = int(y) + w = int(w) + h = int(h) + r = abs(int(r)) + if w < 0: + x += w + w = abs(w) + if h < 0: + y += h + h = abs(h) + self.fillRect(x + r, y, w - 2 * r, h, color) + self.fillRect(x, y + r, r, h - 2 * r, color) + self.fillRect(x + w - r, y + r, r, h - 2 * r, color) + self.fillCircleHelper(x + r, y + r, r, self.QUADRANT_2, color) + self.fillCircleHelper(x + w - r - 1, y + r, r, self.QUADRANT_1, color) + self.fillCircleHelper(x + r, y + h - r - 1, r, self.QUADRANT_3, color) + self.fillCircleHelper(x + w - r - 1, y + h - r - 1, r, self.QUADRANT_4, color) + + def _bitmapHelper(self, increaseAxis, staticAxis, data, dataBit, exchange, color, background): + for i in data: + for j in range(8): + if i & dataBit: + if exchange: + self.fillRect(staticAxis, increaseAxis, self._bitmapSize, self._bitmapSize, color) + else: + self.fillRect(increaseAxis, staticAxis, self._bitmapSize, self._bitmapSize, color) + else: + if exchange: + self.fillRect(staticAxis, increaseAxis, self._bitmapSize, self._bitmapSize, background) + else: + self.fillRect(increaseAxis, staticAxis, self._bitmapSize, self._bitmapSize, background) + increaseAxis += self._bitmapSize + if dataBit & 0x80: + i <<= 1 + else: + i >>= 1 + + def bitmap(self, x, y, bitmap, w, h, color, background): + if w < 0 or h < 0: + return + x = abs(int(x)) + y = abs(int(y)) + + if self._bmpFmt == self.BITMAP_TBMLLR: + oneLineDataLen = (w - 1) // 8 + 1 + for i in range(h): + yMask = y + i * self._bitmapSize + self._bitmapHelper(x, yMask, bitmap[i * oneLineDataLen : oneLineDataLen * (i + 1)], 0x80, False, color, background) + elif self._bmpFmt == self.BITMAP_TBMRLL: + oneLineDataLen = (w - 1) // 8 + 1 + for i in range(h): + yMask = y + i * self._bitmapSize + self._bitmapHelper(x, yMask, bitmap[i * oneLineDataLen : oneLineDataLen * (i + 1)], 0x01, False, color, background) + elif self._bmpFmt == self.BITMAP_BTMLLR: + oneLineDataLen = (w - 1) // 8 + 1 + for i in range(h): + yMask = y + h * self._bitmapSize - i * self._bitmapSize + self._bitmapHelper(x, yMask, bitmap[i * oneLineDataLen : oneLineDataLen * (i + 1)], 0x80, False, color, background) + elif self._bmpFmt == self.BITMAP_BTMRLL: + oneLineDataLen = (w - 1) // 8 + 1 + for i in range(h): + yMask = y + h * self._bitmapSize - i * self._bitmapSize + self._bitmapHelper(x, yMask, bitmap[i * oneLineDataLen : oneLineDataLen * (i + 1)], 0x01, False, color, background) + elif self._bmpFmt == self.BITMAP_LRMTLB: + oneLineDataLen = (h - 1) // 8 + 1 + for i in range(w): + xMask = x + i * self._bitmapSize + self._bitmapHelper(y, xMask, bitmap[i * oneLineDataLen : oneLineDataLen * (i + 1)], 0x80, True, color, background) + elif self._bmpFmt == self.BITMAP_LRMBLT: + oneLineDataLen = (h - 1) // 8 + 1 + for i in range(w): + xMask = x + i * self._bitmapSize + self._bitmapHelper(y, xMask, bitmap[i * oneLineDataLen : oneLineDataLen * (i + 1)], 0x01, True, color, background) + elif self._bmpFmt == self.BITMAP_RLMTLB: + oneLineDataLen = (h - 1) // 8 + 1 + for i in range(w): + xMask = x + w * self._bitmapSize - i * self._bitmapSize + self._bitmapHelper(y, xMask, bitmap[i * oneLineDataLen : oneLineDataLen * (i + 1)], 0x80, True, color, background) + elif self._bmpFmt == self.BIMTAP_RLMBLT: + oneLineDataLen = (h - 1) // 8 + 1 + for i in range(w): + xMask = x + w * self._bitmapSize - i * self._bitmapSize + self._bitmapHelper(y, xMask, bitmap[i * oneLineDataLen : oneLineDataLen * (i + 1)], 0x01, True, color, background) + + def _bytesToNumber(self, data): + r = 0 + i = len(data) + while i > 0: + i -= 1 + r = r << 8 | data[i] + return r + + def _getQuads(self, data, count): + r = [] + for i in range(count): + r.append(data[i * 4 + 54 : i * 4 + 58]) + return r + + BITMAP_COMPRESSION_NO = 0 + BITMAP_COMPRESSION_RLE8 = 1 + BITMAP_COMPRESSION_RLE4 = 2 + BITMAP_COMPRESSION_FIELDS = 3 + + def startDrawBitmapFile(self, x, y): + pass + + def bitmapFileHelper(self, buf): + pass + + def endDrawBitmapFile(self): + pass + + def bitmapFile(self, x, y, path): + try: + f = open(path, "rb") + except: + print("open file error") + return + c = bytearray(f.read()) + f.close() + if c[0] != 0x42 and c[1] != 0x4d: + print("file error") + print(c[0]) + print(c[1]) + return + DIBOffset = self._bytesToNumber(c[10:14]) + width = self._bytesToNumber(c[18:22]) + height = self._bytesToNumber(c[22:26]) + colorBits = self._bytesToNumber(c[28:30]) + compression = self._bytesToNumber(c[30:32]) + # print("w: %d, h: %d, colorBits: %d" %(width, height, colorBits)) + + if colorBits == 24: + width3 = width * 3 + for i in range(height): + self.startDrawBitmapFile(x, y + height - i) + buf = [] + left = DIBOffset + i * width3 + i = 0 + while i < width3: + buf.append(c[left + i + 2]) + buf.append(c[left + i + 1]) + buf.append(c[left + i + 0]) + i += 3 + self.bitmapFileHelper(buf) + self.endDrawBitmapFile() + + elif colorBits == 1: + quads = self._getQuads(c, 2) + addr = DIBOffset + if compression == self.BITMAP_COMPRESSION_NO: + addrCountComplement = (width // 8 + 1) % 4 + if addrCountComplement != 0: + addrCountComplement = 4 - addrCountComplement + for i in range(height): + w = width + addrCount = 0 + self.startDrawBitmapFile(x, y + height - i - 1) + buf = [] + while w > 0: + d = c[addr + addrCount] + addrCount = addrCount + 1 + j = 8 + while w > 0 and j > 0: + j -= 1 + quad = d & (0x01 << j) + if quad > 0: + quad = 1 + buf.append(quads[quad][2]) + buf.append(quads[quad][1]) + buf.append(quads[quad][0]) + w -= 1 + self.bitmapFileHelper(buf) + addrCount += addrCountComplement + addr += addrCount + self.endDrawBitmapFile() + else: + print("dont support this bitmap file format yet") + + def writeOneChar(self, c): + if len(c) > 1: + c = c[0] + (l, width, height, fmt) = self._fonts.getOneCharacter(c) + temp = self._bmpFmt + self._bmpFmt = fmt + ts = self._textSize + if ord(c) == ord("\n"): + self._textCursorX = 0 + self._textCursorY += height * ts + self._textIntervalCol + elif len(l): + temp1 = self._bitmapSize + self._bitmapSize = ts + self._textCursorX += self._textIntervalRow + if self._textCursorX + ts * width > self._width: + self.fillRect(self._textCursorX, self._textCursorY, self._width - self._textCursorX, self._fonts._extensionFontsHeight * ts + self._textIntervalCol, self._textBackground) + self._textCursorX = self._textIntervalRow + self._textCursorY += ts * self._fonts._extensionFontsHeight + self._textIntervalCol + self.fillRect(self._textCursorX, self._textCursorY, self._fonts._extensionFontsWidth * ts + self._textIntervalRow, self._fonts._extensionFontsHeight * ts + self._textIntervalCol, self._textBackground) + self.bitmap(self._textCursorX, self._textCursorY, l, width, height, self._textColor, self._textBackground) + self._textCursorX += ts * width + self._bitmapSize = temp1 + self._bmpFmt = temp diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_display.pyc b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_display.pyc new file mode 100644 index 00000000..d9bcc266 Binary files /dev/null and b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_display.pyc differ diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_fonts.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_fonts.py new file mode 100644 index 00000000..c85b9ae0 --- /dev/null +++ b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_fonts.py @@ -0,0 +1,69 @@ +# -*- coding:utf-8 -*- + +import json + +class Fonts: + + def __init__(self): + self._haveFontsABC = False + self._fontsABC = {} + self._fontsABCWidth = 0 + self._fontsABCHeight = 0 + self._fontsABCFmt = "" + + self._haveExtensionFonts = False + self._extensionFontsWidth = 0 + self._extensionFontsHeight = 0 + + self._enableDefaultFonts = True + + def setFontsABC(self, fonts): + self._haveFontsABC = True + self._fontsABC = fonts.fonts + self._fontsABCWidth = fonts.width + self._fontsABCHeight = fonts.height + self._fontsABCFmt = fonts.fmt + + self._extensionFontsWidth = fonts.width * 2 + self._extensionFontsHeight = fonts.height * 2 + + def setExFonts(self, obj): + self._haveExtensionFonts = True + self._extensionFonts = obj + self._enableDefaultFonts = False + + def setEnableDefaultFonts(self, opt): + if opt: + self._enableDefaultFonts = True + else: + self._enableDefaultFonts = False + + def setExFontsFmt(self, width, height): + if self._haveExtensionFonts: + self._extensionFonts.setFmt(width, height) + self._extensionFontsWidth = width + self._extensionFontsHeight = height + + def getOneCharacter(self, c): + w = 0 + h = 0 + fmt = "UNKNOW" + rslt = [] + done = False + if self._haveFontsABC and self._enableDefaultFonts: + try: + rslt = self._fontsABC[c] + w = self._fontsABCWidth + h = self._fontsABCHeight + fmt = self._fontsABCFmt + done = True + except: + # print("try get fonts ABC faild") + pass + if self._haveExtensionFonts and done == False: + try: + (rslt, w, h, fmt) = self._extensionFonts.getOne(c) + done = True + except: + print("try get unicode fonts faild: %s" %(c)) + return (rslt, w, h, fmt) diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_fonts.pyc b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_fonts.pyc new file mode 100644 index 00000000..274bbf43 Binary files /dev/null and b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_fonts.pyc differ diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_printString.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_printString.py new file mode 100644 index 00000000..b32acf6e --- /dev/null +++ b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_printString.py @@ -0,0 +1,25 @@ +# -*- coding:utf-8 -*- + +import sys + +class PrintString: + + def __init__(self): + pass + + def writeOneChar(self, ch): + pass + + def printStr(self, c): + try: + c = str(c) + except: + return + if sys.version_info.major == 2: + c = c.decode("utf-8") + for i in c: + self.writeOneChar(i) + + def printStrLn(self, c): + self.printStr(c) + self.writeOneChar("\n") diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_printString.pyc b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_printString.pyc new file mode 100644 index 00000000..51dc169e Binary files /dev/null and b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_display/dfrobot_printString.pyc differ diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_epaper.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_epaper.py new file mode 100644 index 00000000..3f2b001c --- /dev/null +++ b/pwnagotchi/ui/hw/libs/dfrobot/v2/dfrobot_epaper.py @@ -0,0 +1,250 @@ +# -*- coding:utf-8 -*- + +import time + +import sys +sys.path.append("..") +import RPi.GPIO as RPIGPIO +from .dfrobot_display.dfrobot_display import DFRobot_Display +from .display_extension import fonts_8_16 as fonts_ABC + +try: + from .spi import SPI + from .gpio import GPIO +except: + print("unknow platform") + exit() + +CONFIG_IL0376F = { + +} + +CONFIG_IL3895 = { + +} + +class DFRobot_Epaper(DFRobot_Display): + + XDOT = 128 + YDOT = 250 + + FULL = True + PART = False + + def __init__(self, width = 250, height = 122): + DFRobot_Display.__init__(self, width, height) + # length = width * height // 8 + length = 4000 + self._displayBuffer = bytearray(length) + i = 0 + while i < length: + self._displayBuffer[i] = 0xff + i = i + 1 + + self._isBusy = False + self._busyExitEdge = GPIO.RISING + + self._fonts.setFontsABC(fonts_ABC) + self.setExFontsFmt(16, 16) + + def _busyCB(self, channel): + self._isBusy = False + + def setBusyExitEdge(self, edge): + if edge != GPIO.HIGH and edge != GPIO.LOW: + return + self._busyEdge = edge + + def begin(self): + pass + #self._init() + #self._powerOn() + #self.setBusyCB(self._busyCB) + #self._powerOn() + + def setBuffer(self, buffer): + self._displayBuffer = buffer + + def pixel(self, x, y, color): + if x < 0 or x >= self._width: + return + if y < 0 or y >= self._height: + return + x = int(x) + y = int(y) + m = int(x * 16 + (y + 1) / 8) + sy = int((y + 1) % 8) + if color == self.WHITE: + if sy != 0: + self._displayBuffer[m] = self._displayBuffer[m] | int(pow(2, 8 - sy)) + else: + self._displayBuffer[m - 1] = self._displayBuffer[m - 1] | 1 + elif color == self.BLACK: + if sy != 0: + self._displayBuffer[m] = self._displayBuffer[m] & (0xff - int(pow(2, 8 - sy))) + else: + self._displayBuffer[m - 1] = self._displayBuffer[m - 1] & 0xfe + + def _initLut(self, mode): + if mode == self.FULL: + self.writeCmdAndData(0x32, [ 0xA0, 0x90, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x90, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xA0, 0x90, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x90, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x0F, 0x0F, 0x00, 0x00, 0x00, + 0x0F, 0x0F, 0x00, 0x00, 0x03, + 0x0F, 0x0F, 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, 0x00, 0x00, + ]) + elif mode == self.PART: + self.writeCmdAndData(0x32, [0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, + 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + + 0x0f, 0x00, 0x00, 0x00, 0x00, + 0x0, 0x00, 0x00, 0x00, 0x00, + 0x0, 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, 0x00, 0x00, 0x00, + ]) + + def _setRamData(self, xStart, xEnd, yStart, yStart1, yEnd, yEnd1): + self.writeCmdAndData(0x44, [xStart, xEnd]) + self.writeCmdAndData(0x45, [yStart, yStart1, yEnd, yEnd1]) + + def _setRamPointer(self, x, y, y1): + self.writeCmdAndData(0x4e, [x]) + self.writeCmdAndData(0x4f, [y, y1]) + + def _init(self,mode): + self.writeCmdAndData(0x12, []) + self.writeCmdAndData(0x01, [0xf9, 0x00, 0x00]) + self.writeCmdAndData(0x74, [0x54]) + self.writeCmdAndData(0x7e, [0x3b]) + self.writeCmdAndData(0x11, [0x01]) + self._setRamData(0x00, 0x0f, 0xf9,0x00, 0x00, 0x00) + self.writeCmdAndData(0x3c, [0x03]) + self._setRamPointer(0x00, 0xf9, 0x00) + self.writeCmdAndData(0x21, [0x08]) + self.writeCmdAndData(0x2c, [0x50]) + self.writeCmdAndData(0x03, [0x15]) + self.writeCmdAndData(0x04, [0x41,0xa8,0x32]) + self.writeCmdAndData(0x3a, [0x2c]) + self.writeCmdAndData(0x3b, [0x0b]) + self.writeCmdAndData(0x0c, [0x8b,0x9c,0x96,0x0f]) + + + + + + + def _writeDisRam(self, sizeX, sizeY): + if sizeX % 8 != 0: + sizeX = sizeX + (8 - sizeX % 8) + sizeX = sizeX // 8 + + self.writeCmdAndData(0x24, self._displayBuffer[0: sizeX * sizeY]) + + + + def _updateDis(self, mode): + if mode == self.FULL: + self.writeCmdAndData(0x22, [0xc7]) + elif mode == self.PART: + self.writeCmdAndData(0x22, [0xc7]) + else: + return + self.writeCmdAndData(0x20, []) + + + def _waitBusyExit(self): + temp = 0 + while self.readBusy() != False: + time.sleep(0.01) + temp = temp + 1 + if (temp % 200) == 0: + print("waitBusyExit") + + def _powerOn(self): + self.writeCmdAndData(0x22, [0xC0]) + self.writeCmdAndData(0x20, []) + + def _powerOff(self): + self.writeCmdAndData(0x10, [0x01]) + time.sleep(0.1) + + def _disPart(self, xStart, xEnd, yStart, yEnd): + self._setRamData(xStart // 8, xEnd // 8, yEnd % 256, yEnd // 256, yStart % 256, yStart // 256) + self._setRamPointer(xStart // 8, yEnd % 256, yEnd // 256) + self._writeDisRam(xEnd - xStart, yEnd - yStart + 1) + self._updateDis(self.PART) + + def flush(self, mode): + if mode != self.FULL and mode != self.PART: + return + self._init(mode) + self._initLut(mode) + self._powerOn() + if mode == self.PART: + self._disPart(0, self.XDOT - 1, 0, self.YDOT - 1) + else: + self._setRamPointer(0x00, (self.YDOT - 1) % 256, (self.YDOT - 1) // 256) + self._writeDisRam(self.XDOT, self.YDOT) + self._updateDis(self.FULL) + + def startDrawBitmapFile(self, x, y): + self._bitmapFileStartX = x + self._bitmapFileStartY = y + + def bitmapFileHelper(self, buf): + for i in range(len(buf) // 3): + addr = i * 3 + if buf[addr] == 0x00 and buf[addr + 1] == 0x00 and buf[addr + 2] == 0x00: + self.pixel(self._bitmapFileStartX, self._bitmapFileStartY, self.BLACK) + else: + self.pixel(self._bitmapFileStartX, self._bitmapFileStartY, self.WHITE) + self._bitmapFileStartX += 1 + + def endDrawBitmapFile(self): + self.flush(self.PART) + +class DFRobot_Epaper_SPI(DFRobot_Epaper): + + def __init__(self, bus, dev, cs, cd, busy): + DFRobot_Epaper.__init__(self) + self._spi = SPI(bus, dev) + self._cs = GPIO(cs, GPIO.OUT) + self._cd = GPIO(cd, GPIO.OUT) + self._busy = GPIO(busy, GPIO.IN) + + def writeCmdAndData(self, cmd, data = []): + self._waitBusyExit() + self._cs.setOut(GPIO.LOW) + self._cd.setOut(GPIO.LOW) + self._spi.transfer([cmd]) + self._cd.setOut(GPIO.HIGH) + self._spi.transfer(data) + self._cs.setOut(GPIO.HIGH) + + def readBusy(self): + return self._busy.read() + + def setBusyCB(self, cb): + self._busy.setInterrupt(self._busyExitEdge, cb) + def __del__(self): + RPIGPIO.cleanup() diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/__init__.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/__init__.pyc b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/__init__.pyc new file mode 100644 index 00000000..38130c00 Binary files /dev/null and b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/__init__.pyc differ diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/fonts_6_8.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/fonts_6_8.py new file mode 100644 index 00000000..b1edc5e4 --- /dev/null +++ b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/fonts_6_8.py @@ -0,0 +1,101 @@ +fonts = { # left to right, msb to bottom, lsb to top + " ": [0x00,0x00,0x00,0x00,0x00,0x00], + "!": [0x00,0x00,0x5F,0x00,0x00,0x00], + "\"": [0x00,0x07,0x00,0x07,0x00,0x00], + "#": [0x14,0x7F,0x14,0x7F,0x14,0x00], + "$": [0x24,0x2A,0x7F,0x2A,0x12,0x00], + "%": [0x23,0x13,0x08,0x64,0x62,0x00], + "&": [0x36,0x49,0x56,0x20,0x50,0x00], + "'": [0x00,0x08,0x07,0x03,0x00,0x00], + "(": [0x00,0x1C,0x22,0x41,0x00,0x00], + ")": [0x00,0x41,0x22,0x1C,0x00,0x00], + "*": [0x24,0x18,0x7E,0x18,0x24,0x00], + "+": [0x08,0x08,0x3E,0x08,0x08,0x00], + ",": [0x00,0x80,0x70,0x30,0x00,0x00], + "-": [0x08,0x08,0x08,0x08,0x08,0x00], + ".": [0x00,0x00,0x60,0x60,0x00,0x00], + "/": [0x20,0x10,0x08,0x04,0x02,0x00], + "0": [0x3E,0x41,0x49,0x41,0x3E,0x00], + "1": [0x00,0x42,0x7F,0x40,0x00,0x00], + "2": [0x72,0x49,0x49,0x49,0x46,0x00], + "3": [0x21,0x41,0x49,0x4D,0x32,0x00], + "4": [0x18,0x14,0x12,0x7F,0x10,0x00], + "5": [0x27,0x45,0x45,0x45,0x38,0x00], + "6": [0x3C,0x4A,0x49,0x49,0x31,0x00], + "7": [0x41,0x21,0x11,0x09,0x07,0x00], + "8": [0x36,0x49,0x49,0x49,0x36,0x00], + "9": [0x46,0x49,0x49,0x29,0x16,0x00], + ":": [0x00,0x00,0x14,0x00,0x00,0x00], + ";": [0x00,0x40,0x34,0x00,0x00,0x00], + "<": [0x00,0x08,0x14,0x22,0x41,0x00], + "=": [0x14,0x14,0x14,0x14,0x14,0x00], + ">": [0x00,0x41,0x22,0x14,0x08,0x00], + "?": [0x02,0x01,0x59,0x09,0x06,0x00], + "@": [0x3E,0x41,0x5D,0x59,0x4E,0x00], + "A": [0x7C,0x12,0x11,0x12,0x7C,0x00], + "B": [0x7F,0x49,0x49,0x49,0x36,0x00], + "C": [0x3E,0x41,0x41,0x41,0x22,0x00], + "D": [0x7F,0x41,0x41,0x41,0x3E,0x00], + "E": [0x7F,0x49,0x49,0x49,0x41,0x00], + "F": [0x7F,0x09,0x09,0x09,0x01,0x00], + "G": [0x3E,0x41,0x41,0x51,0x73,0x00], + "H": [0x7F,0x08,0x08,0x08,0x7F,0x00], + "I": [0x00,0x41,0x7F,0x41,0x00,0x00], + "J": [0x20,0x40,0x41,0x3F,0x01,0x00], + "K": [0x7F,0x08,0x14,0x22,0x41,0x00], + "L": [0x7F,0x40,0x40,0x40,0x40,0x00], + "M": [0x7F,0x02,0x1C,0x02,0x7F,0x00], + "N": [0x7F,0x04,0x08,0x10,0x7F,0x00], + "O": [0x3E,0x41,0x41,0x41,0x3E,0x00], + "P": [0x7F,0x09,0x09,0x09,0x06,0x00], + "Q": [0x3E,0x41,0x51,0x21,0x5E,0x00], + "R": [0x7F,0x09,0x19,0x29,0x46,0x00], + "S": [0x26,0x49,0x49,0x49,0x32,0x00], + "T": [0x03,0x01,0x7F,0x01,0x03,0x00], + "U": [0x3F,0x40,0x40,0x40,0x3F,0x00], + "V": [0x1F,0x20,0x40,0x20,0x1F,0x00], + "W": [0x3F,0x40,0x38,0x40,0x3F,0x00], + "X": [0x63,0x14,0x08,0x14,0x63,0x00], + "Y": [0x03,0x04,0x78,0x04,0x03,0x00], + "Z": [0x61,0x59,0x49,0x4D,0x43,0x00], + "[": [0x00,0x7F,0x41,0x41,0x41,0x00], + "\\": [0x02,0x04,0x08,0x10,0x20,0x00], + "]": [0x00,0x41,0x41,0x41,0x7f,0x00], + "^": [0x04,0x02,0x01,0x02,0x04,0x00], + "_": [0x40,0x40,0x40,0x40,0x46,0x00], + "'": [0x00,0x03,0x07,0x08,0x00,0x00], + "a": [0x20,0x54,0x54,0x78,0x40,0x00], + "b": [0x7F,0x28,0x44,0x44,0x38,0x00], + "c": [0x38,0x44,0x44,0x44,0x28,0x00], + "d": [0x38,0x44,0x44,0x28,0x7F,0x00], + "e": [0x38,0x54,0x54,0x54,0x18,0x00], + "f": [0x00,0x08,0x7E,0x09,0x02,0x00], + "g": [0x38,0xA4,0xA4,0x9C,0x78,0x00], + "h": [0x7F,0x08,0x04,0x04,0x78,0x00], + "i": [0x00,0x44,0x7D,0x40,0x00,0x00], + "j": [0x20,0x40,0x40,0x3D,0x00,0x00], + "k": [0x7F,0x10,0x28,0x44,0x00,0x00], + "l": [0x00,0x41,0x7F,0x40,0x00,0x00], + "m": [0x7C,0x04,0x78,0x04,0x78,0x00], + "n": [0x7C,0x08,0x04,0x04,0x78,0x00], + "o": [0x38,0x44,0x44,0x44,0x38,0x00], + "p": [0xFC,0x18,0x24,0x24,0x18,0x00], + "q": [0x18,0x24,0x24,0x18,0xFC,0x00], + "r": [0x7C,0x08,0x04,0x04,0x08,0x00], + "s": [0x48,0x54,0x54,0x54,0x24,0x00], + "t": [0x04,0x04,0x3F,0x44,0x24,0x00], + "u": [0x3C,0x40,0x40,0x20,0x7C,0x00], + "v": [0x1C,0x20,0x40,0x20,0x1C,0x00], + "w": [0x3C,0x40,0x20,0x40,0x3C,0x00], + "x": [0x44,0x28,0x10,0x28,0x44,0x00], + "y": [0x4C,0x90,0x90,0x90,0x7C,0x00], + "z": [0x44,0x64,0x54,0x4C,0x44,0x00], + "{": [0x00,0x08,0x36,0x41,0x00,0x00], + "|": [0x00,0x00,0x77,0x00,0x00,0x00], + "}": [0x00,0x41,0x36,0x08,0x00,0x00], + "~": [0x02,0x01,0x02,0x04,0x02,0x00] +} + +width = 6 +height = 8 +fmt = "LRMBLT" diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/fonts_8_16.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/fonts_8_16.py new file mode 100644 index 00000000..35331ce2 --- /dev/null +++ b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/fonts_8_16.py @@ -0,0 +1,101 @@ +fonts = { # top to bottom, msb left, lsb right + " ": [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], + "!": [0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00], + "\"": [0x00,0x63,0x63,0x63,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], + "#": [0x00,0x00,0x00,0x36,0x36,0x7F,0x36,0x36,0x36,0x7F,0x36,0x36,0x00,0x00,0x00,0x00], + "$": [0x0C,0x0C,0x3E,0x63,0x61,0x60,0x3E,0x03,0x03,0x43,0x63,0x3E,0x0C,0x0C,0x00,0x00], + "%": [0x00,0x00,0x00,0x00,0x00,0x61,0x63,0x06,0x0C,0x18,0x33,0x63,0x00,0x00,0x00,0x00], + "&": [0x00,0x00,0x00,0x1C,0x36,0x36,0x1C,0x3B,0x6E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00], + "'": [0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], + "(": [0x00,0x00,0x0C,0x18,0x18,0x30,0x30,0x30,0x30,0x18,0x18,0x0C,0x00,0x00,0x00,0x00], + ")": [0x00,0x00,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x00,0x00,0x00,0x00], + "*": [0x00,0x00,0x00,0x00,0x42,0x66,0x3C,0xFF,0x3C,0x66,0x42,0x00,0x00,0x00,0x00,0x00], + "+": [0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00], + ",": [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00], + "-": [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], + ".": [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00], + "/": [0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x70,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00], + "0": [0x00,0x00,0x3E,0x63,0x63,0x63,0x6B,0x6B,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00], + "1": [0x00,0x00,0x0C,0x1C,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3F,0x00,0x00,0x00,0x00], + "2": [0x00,0x00,0x3E,0x63,0x03,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00], + "3": [0x00,0x00,0x3E,0x63,0x03,0x03,0x1E,0x03,0x03,0x03,0x63,0x3E,0x00,0x00,0x00,0x00], + "4": [0x00,0x00,0x06,0x0E,0x1E,0x36,0x66,0x66,0x7F,0x06,0x06,0x0F,0x00,0x00,0x00,0x00], + "5": [0x00,0x00,0x7F,0x60,0x60,0x60,0x7E,0x03,0x03,0x63,0x73,0x3E,0x00,0x00,0x00,0x00], + "6": [0x00,0x00,0x1C,0x30,0x60,0x60,0x7E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00], + "7": [0x00,0x00,0x7F,0x63,0x03,0x06,0x06,0x0C,0x0C,0x18,0x18,0x18,0x00,0x00,0x00,0x00], + "8": [0x00,0x00,0x3E,0x63,0x63,0x63,0x3E,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00], + "9": [0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x3F,0x03,0x03,0x06,0x3C,0x00,0x00,0x00,0x00], + ":": [0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00], + ";": [0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00], + "<": [0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00], + "=": [0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00], + ">": [0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00], + "?": [0x00,0x00,0x3E,0x63,0x63,0x06,0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x00,0x00,0x00,0x00], + "@": [0x00,0x00,0x3E,0x63,0x63,0x6F,0x6B,0x6B,0x6E,0x60,0x60,0x3E,0x00,0x00,0x00,0x00], + "A": [0x00,0x00,0x08,0x1C,0x36,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x00,0x00,0x00,0x00], + "B": [0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x33,0x33,0x33,0x33,0x7E,0x00,0x00,0x00,0x00], + "C": [0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x60,0x60,0x61,0x33,0x1E,0x00,0x00,0x00,0x00], + "D": [0x00,0x00,0x7C,0x36,0x33,0x33,0x33,0x33,0x33,0x33,0x36,0x7C,0x00,0x00,0x00,0x00], + "E": [0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00], + "F": [0x00,0x00,0x7F,0x33,0x31,0x34,0x3C,0x34,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00], + "G": [0x00,0x00,0x1E,0x33,0x61,0x60,0x60,0x6F,0x63,0x63,0x37,0x1D,0x00,0x00,0x00,0x00], + "H": [0x00,0x00,0x63,0x63,0x63,0x63,0x7F,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00], + "I": [0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00], + "J": [0x00,0x00,0x0F,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00,0x00,0x00], + "K": [0x00,0x00,0x73,0x33,0x36,0x36,0x3C,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00], + "L": [0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x33,0x7F,0x00,0x00,0x00,0x00], + "M": [0x00,0x00,0x63,0x77,0x7F,0x6B,0x63,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00], + "N": [0x00,0x00,0x63,0x63,0x73,0x7B,0x7F,0x6F,0x67,0x63,0x63,0x63,0x00,0x00,0x00,0x00], + "O": [0x00,0x00,0x1C,0x36,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x00,0x00,0x00,0x00], + "P": [0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00], + "Q": [0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x63,0x6B,0x6F,0x3E,0x06,0x07,0x00,0x00], + "R": [0x00,0x00,0x7E,0x33,0x33,0x33,0x3E,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00], + "S": [0x00,0x00,0x3E,0x63,0x63,0x30,0x1C,0x06,0x03,0x63,0x63,0x3E,0x00,0x00,0x00,0x00], + "T": [0x00,0x00,0xFF,0xDB,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00], + "U": [0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00], + "V": [0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1C,0x08,0x00,0x00,0x00,0x00], + "W": [0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x36,0x00,0x00,0x00,0x00], + "X": [0x00,0x00,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x3C,0x66,0xC3,0xC3,0x00,0x00,0x00,0x00], + "Y": [0x00,0x00,0xC3,0xC3,0xC3,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00], + "Z": [0x00,0x00,0x7F,0x63,0x43,0x06,0x0C,0x18,0x30,0x61,0x63,0x7F,0x00,0x00,0x00,0x00], + "[": [0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00], + "\\": [0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00], + "]": [0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00], + "^": [0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], + "_": [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00], + "'": [0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], + "a": [0x00,0x00,0x00,0x00,0x00,0x3C,0x46,0x06,0x3E,0x66,0x66,0x3B,0x00,0x00,0x00,0x00], + "b": [0x00,0x00,0x70,0x30,0x30,0x3C,0x36,0x33,0x33,0x33,0x33,0x6E,0x00,0x00,0x00,0x00], + "c": [0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x60,0x60,0x60,0x63,0x3E,0x00,0x00,0x00,0x00], + "d": [0x00,0x00,0x0E,0x06,0x06,0x1E,0x36,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00], + "e": [0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x7E,0x60,0x63,0x3E,0x00,0x00,0x00,0x00], + "f": [0x00,0x00,0x1C,0x36,0x32,0x30,0x7C,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00], + "g": [0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00,0x00], + "h": [0x00,0x00,0x70,0x30,0x30,0x36,0x3B,0x33,0x33,0x33,0x33,0x73,0x00,0x00,0x00,0x00], + "i": [0x00,0x00,0x0C,0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00], + "j": [0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,0x00], + "k": [0x00,0x00,0x70,0x30,0x30,0x33,0x33,0x36,0x3C,0x36,0x33,0x73,0x00,0x00,0x00,0x00], + "l": [0x00,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00], + "m": [0x00,0x00,0x00,0x00,0x00,0x6E,0x7F,0x6B,0x6B,0x6B,0x6B,0x6B,0x00,0x00,0x00,0x00], + "n": [0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x00], + "o": [0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00,0x00,0x00,0x00], + "p": [0x00,0x00,0x00,0x00,0x00,0x6E,0x33,0x33,0x33,0x33,0x3E,0x30,0x30,0x78,0x00,0x00], + "q": [0x00,0x00,0x00,0x00,0x00,0x3B,0x66,0x66,0x66,0x66,0x3E,0x06,0x06,0x0F,0x00,0x00], + "r": [0x00,0x00,0x00,0x00,0x00,0x6E,0x3B,0x33,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00], + "s": [0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x38,0x0E,0x03,0x63,0x3E,0x00,0x00,0x00,0x00], + "t": [0x00,0x00,0x08,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x1B,0x0E,0x00,0x00,0x00,0x00], + "u": [0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3B,0x00,0x00,0x00,0x00], + "v": [0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x36,0x1C,0x1C,0x08,0x00,0x00,0x00,0x00], + "w": [0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x6B,0x6B,0x7F,0x36,0x00,0x00,0x00,0x00], + "x": [0x00,0x00,0x00,0x00,0x00,0x63,0x36,0x1C,0x1C,0x1C,0x36,0x63,0x00,0x00,0x00,0x00], + "y": [0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x3F,0x03,0x06,0x3C,0x00,0x00], + "z": [0x00,0x00,0x00,0x00,0x00,0x7F,0x66,0x0C,0x18,0x30,0x63,0x7F,0x00,0x00,0x00,0x00], + "{": [0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00], + "|": [0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00], + "}": [0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00], + "~": [0x00,0x00,0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00] +} + +width = 8 +height = 16 +fmt = "TBMLLR" diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/fonts_8_16.pyc b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/fonts_8_16.pyc new file mode 100644 index 00000000..96d1b66e Binary files /dev/null and b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/fonts_8_16.pyc differ diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/freetype_helper.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/freetype_helper.py new file mode 100644 index 00000000..ee7be906 --- /dev/null +++ b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/freetype_helper.py @@ -0,0 +1,80 @@ +# -*- coding:utf-8 -*- + +''' +depends: freetype-py +''' + +import freetype +import math +#import sys + +#reload(sys) +#sys.setdefaultencoding("utf-8") +import importlib,sys + +#importlib.reload(sys) +class Freetype_Helper: + + def __init__(self, filePath): + self._face = freetype.Face(filePath) + self._width = 0 + self._height = 0 + self._fade = 96 + + def setFmt(self, width, height): + self._width = int(width) + self._height = int(height) + self._face.set_pixel_sizes(width, height) + + def setDisLowerLimite(self, limite): + self._fade = limite + + def getOne(self, ch): + self._face.load_char(ch) + bitmap = self._face.glyph.bitmap + originY = self._face.glyph.bitmap_top + width = bitmap.width + height = bitmap.rows + buffer = bitmap.buffer + rslt = [] + + # width = 4 + # height = 4 + # buffer = [0xff] * width * height + + if height > self._height: + buffer = buffer[0: width * self._height] + height = self._height + if width > self._width: + for i in range(height): + rslt += buffer[i * width: i * width + self._width] + width = self._width + buffer = rslt + rslt = [] + if (ord(ch) >= ord(" ") and ord(ch) <= ord("~")) or width <= (self._width // 2): + rslt = [0] * (((self._width - 1) // 16 + 1) * self._height + 1) + left = (self._width // 2 - width) // 2 + lineDataLen = (self._width - 1) // 16 + 1 + else: + rslt = [0] * (((self._width - 1) // 8 + 1) * self._height + 1) + left = (self._width - width) // 2 + lineDataLen = (self._width - 1) // 8 + 1 + if left < 0: + left = 0 + # top = (self._height - height) * lineDataLen // 2 + top = ((self._height * 8 + 5) // 10 - originY) * lineDataLen + if top < 0: + top = 0 + for i in range(height): + for j in range(width): + if buffer[i * width + j] > self._fade: + try: + rslt[i * lineDataLen + (j + left) // 8 + top] |= 0x80 >> ((j + left) % 8) + except: + print("freetype_helper getOne err: width: %d, height: %d, top: %d, left: %d, rslt_len: %d, originY: %d" %(width, height, top, left, len(rslt), originY)) + raise("err") + # rslt[i * lineDataLen + (j + left) // 8 + top] |= 0x80 >> ((j + left) % 8) + if (ord(ch) >= ord(" ") and ord(ch) <= ord("~")) or width < (self._width // 2): + return (rslt, self._width // 2, self._height, "TBMLLR") + else: + return (rslt, self._width, self._height, "TBMLLR") diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/freetype_helper.pyc b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/freetype_helper.pyc new file mode 100644 index 00000000..b45f122f Binary files /dev/null and b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/freetype_helper.pyc differ diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/logo_colorbits1.bmp b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/logo_colorbits1.bmp new file mode 100644 index 00000000..0eace4ed Binary files /dev/null and b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/logo_colorbits1.bmp differ diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/logo_colorbits24.bmp b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/logo_colorbits24.bmp new file mode 100644 index 00000000..44bf6571 Binary files /dev/null and b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/logo_colorbits24.bmp differ diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/readme.md b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/readme.md new file mode 100644 index 00000000..15ffa708 --- /dev/null +++ b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/readme.md @@ -0,0 +1,2 @@ +wqydkzh.ttf = 文泉驿等宽正黑.ttf GPL2 license
+zkklt.ttf = 站酷快乐体.ttf Chinese open source fonts file, use with freetype_helper.py \ No newline at end of file diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/wqydkzh.ttf b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/wqydkzh.ttf new file mode 100644 index 00000000..3b7649ad Binary files /dev/null and b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/wqydkzh.ttf differ diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/zkklt.ttf b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/zkklt.ttf new file mode 100644 index 00000000..ba2ad8a7 Binary files /dev/null and b/pwnagotchi/ui/hw/libs/dfrobot/v2/display_extension/zkklt.ttf differ diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/gpio.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/gpio.py new file mode 100644 index 00000000..3a6a597f --- /dev/null +++ b/pwnagotchi/ui/hw/libs/dfrobot/v2/gpio.py @@ -0,0 +1,64 @@ +# -*- coding:utf-8 -*- + +import time +import RPi.GPIO as RPIGPIO + +RPIGPIO.setmode(RPIGPIO.BCM) +RPIGPIO.setwarnings(False) + +class GPIO: + + HIGH = RPIGPIO.HIGH + LOW = RPIGPIO.LOW + + OUT = RPIGPIO.OUT + IN = RPIGPIO.IN + + RISING = RPIGPIO.RISING + FALLING = RPIGPIO.FALLING + BOTH = RPIGPIO.BOTH + + def __init__(self, pin, mode, defaultOut = HIGH): + self._pin = pin + self._fInt = None + self._intDone = True + self._intMode = None + if mode == self.OUT: + RPIGPIO.setup(pin, mode) + if defaultOut == self.HIGH: + RPIGPIO.output(pin, defaultOut) + else: + RPIGPIO.output(pin, self.LOW) + else: + RPIGPIO.setup(pin, self.IN, pull_up_down = RPIGPIO.PUD_UP) + + def setOut(self, level): + if level: + RPIGPIO.output(self._pin, self.HIGH) + else: + RPIGPIO.output(self._pin, self.LOW) + + def _intCB(self, status): + if self._intDone: + self._intDone = False + time.sleep(0.02) + if self._intMode == self.BOTH: + self._fInt() + elif self._intMode == self.RISING and self.read() == self.HIGH: + self._fInt() + elif self._intMode == self.FALLING and self.read() == self.LOW: + self._fInt() + self._intDone = True + + def setInterrupt(self, mode, cb): + if mode != self.RISING and mode != self.FALLING and mode != self.BOTH: + return + self._intMode = mode + RPIGPIO.add_event_detect(self._pin, mode, self._intCB) + self._fInt = cb + + def read(self): + return RPIGPIO.input(self._pin) + + def cleanup(self): + RPIGPIO.cleanup() diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/i2c.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/i2c.py new file mode 100644 index 00000000..7b1048f5 --- /dev/null +++ b/pwnagotchi/ui/hw/libs/dfrobot/v2/i2c.py @@ -0,0 +1,21 @@ +# -*- coding:utf-8 -*- + +''' +change i2c frequency on raspberry: + 1. edit /etc/modprobe.d + 2. add line: + options i2c_bcm2708 baudrate=400000 +''' + +import smbus + +class I2C: + + def __init__(self, port): + self._bus = smbus.SMBus(port) + + def writeBytes(self, addr, reg, buf): + self._bus.write_block_data(addr, reg, buf) + + def readBytes(self, addr, reg, length): + return self._bus.read_block_data(addr, reg, length) diff --git a/pwnagotchi/ui/hw/libs/dfrobot/v2/spi.py b/pwnagotchi/ui/hw/libs/dfrobot/v2/spi.py new file mode 100644 index 00000000..f1f39f01 --- /dev/null +++ b/pwnagotchi/ui/hw/libs/dfrobot/v2/spi.py @@ -0,0 +1,21 @@ +# -*- coding:utf-8 -*- + +import spidev + +class SPI: + + MODE_1 = 1 + MODE_2 = 2 + MODE_3 = 3 + MODE_4 = 4 + + def __init__(self, bus, dev, speed = 3900000, mode = MODE_4): + self._bus = spidev.SpiDev() + self._bus.open(0, 0) + self._bus.no_cs = True + self._bus.max_speed_hz = speed + + def transfer(self, buf): + if len(buf): + return self._bus.xfer(buf) + return [] diff --git a/pwnagotchi/utils.py b/pwnagotchi/utils.py index dee51dfd..a142e44c 100644 --- a/pwnagotchi/utils.py +++ b/pwnagotchi/utils.py @@ -257,8 +257,11 @@ def load_config(args): elif config['ui']['display']['type'] in ('lcdhat',): config['ui']['display']['type'] = 'lcdhat' - elif config['ui']['display']['type'] in ('dfrobot', 'df'): - config['ui']['display']['type'] = 'dfrobot' + elif config['ui']['display']['type'] in ('dfrobot_1', 'df1'): + config['ui']['display']['type'] = 'dfrobot_1' + + elif config['ui']['display']['type'] in ('dfrobot_2', 'df2'): + config['ui']['display']['type'] = 'dfrobot_2' elif config['ui']['display']['type'] in ('ws_154inch', 'ws154inch', 'waveshare_154inch', 'waveshare154inch'): config['ui']['display']['type'] = 'waveshare154inch'