mirror of
https://github.com/jayofelony/pwnagotchi.git
synced 2025-07-01 18:37:27 -04:00
I2C oled driver mods by NurseJackass
I2C oled config can be added in the config.toml Default is 128x64 display on i2c address 0x3C ui.display.type = "i2coled" ui.display.i2c_addr = 0x3C ui.display.width = 128 ui.display.height = 64
This commit is contained in:
@ -3,20 +3,33 @@
|
||||
# https://github.com/adafruit/Adafruit_Python_SSD1306
|
||||
# SMBus parts coming from BLavery's lib_oled96 repo:
|
||||
# https://github.com/BLavery/lib_oled96
|
||||
# I2C address, width and height import from config.toml made by NurseJackass
|
||||
|
||||
import logging
|
||||
|
||||
import pwnagotchi.ui.fonts as fonts
|
||||
from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
|
||||
#
|
||||
# Default is 128x64 display on i2c address 0x3C
|
||||
#
|
||||
# Configure i2c address and dimensions in config.toml:
|
||||
#
|
||||
# ui.display.type = "i2coled"
|
||||
# ui.display.i2c_addr = 0x3C
|
||||
# ui.display.width = 128
|
||||
# ui.display.height = 64
|
||||
#
|
||||
|
||||
class I2COled(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
self._config = config['ui']['display']
|
||||
super(I2COled, self).__init__(config, 'i2coled')
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(8, 8, 8, 10, 10, 8)
|
||||
self._layout['width'] = 128
|
||||
self._layout['height'] = 64
|
||||
self._layout['width'] = self._config['width'] if 'width' in self._config else 128
|
||||
self._layout['height'] = self._config['height'] if 'height' in self._config else 64
|
||||
self._layout['face'] = (0, 30)
|
||||
self._layout['name'] = (0, 10)
|
||||
self._layout['channel'] = (72, 10)
|
||||
@ -36,10 +49,14 @@ class I2COled(DisplayImpl):
|
||||
return self._layout
|
||||
|
||||
def initialize(self):
|
||||
logging.info("initializing 128x64 I2C Oled Display on address 0x3C")
|
||||
logging.info("To change resolution or address check pwnagotchi/ui/hw/libs/i2coled/epd.py")
|
||||
i2caddr = self._config['i2c_addr'] if 'i2c_addr' in self._config else 0x3C
|
||||
width = self._config['width'] if 'width' in self._config else 128
|
||||
height = self._config['height'] if 'height' in self._config else 64
|
||||
|
||||
logging.info("initializing %dx%d I2C Oled Display on address 0x%X" % (width, height, i2caddr))
|
||||
|
||||
from pwnagotchi.ui.hw.libs.i2coled.epd import EPD
|
||||
self._display = EPD()
|
||||
self._display = EPD(address=i2caddr, width=width, height=height)
|
||||
self._display.Init()
|
||||
self._display.Clear()
|
||||
|
||||
|
@ -100,13 +100,19 @@ class SSD1306Base(object):
|
||||
"""Send command byte to display."""
|
||||
# I2C write.
|
||||
assert(len(cmd) <= 31)
|
||||
self.bus.write_i2c_block_data(self.addr, self.cmd_mode, list(cmd))
|
||||
try:
|
||||
self.bus.write_i2c_block_data(self.addr, self.cmd_mode, list(cmd))
|
||||
except Exception as e:
|
||||
logging.exception(e)
|
||||
|
||||
def data(self, data):
|
||||
"""Send byte of data to display."""
|
||||
# I2C write.
|
||||
for i in range(0, len(data), 31):
|
||||
self.bus.write_i2c_block_data(self.addr, self.data_mode, list(data[i:i+31]))
|
||||
try:
|
||||
for i in range(0, len(data), 31):
|
||||
self.bus.write_i2c_block_data(self.addr, self.data_mode, list(data[i:i+31]))
|
||||
except Exception as e:
|
||||
logging.exception(e)
|
||||
|
||||
def begin(self, vccstate=SSD1306_SWITCHCAPVCC):
|
||||
"""Initialize display."""
|
||||
@ -128,9 +134,11 @@ class SSD1306Base(object):
|
||||
self.command(SSD1306_PAGEADDR)
|
||||
self.command(0) # Page start address. (0 = reset)
|
||||
self.command(self._pages-1) # Page end address.
|
||||
|
||||
for i in range(0, len(self._buffer), 16):
|
||||
self.bus.write_i2c_block_data(self.addr, self.data_mode, self._buffer[i:i+16])
|
||||
try:
|
||||
for i in range(0, len(self._buffer), 16):
|
||||
self.bus.write_i2c_block_data(self.addr, self.data_mode, self._buffer[i:i+16])
|
||||
except Exception as e:
|
||||
logging.exception(e)
|
||||
|
||||
def getbuffer(self, image):
|
||||
"""Set buffer to value of Python Imaging Library image. The image should
|
||||
@ -229,7 +237,7 @@ class SSD1306_128_64(SSD1306Base):
|
||||
class SSD1306_128_32(SSD1306Base):
|
||||
def __init__(self, width, height, address=None, bus=None):
|
||||
# Call base class constructor.
|
||||
super(SSD1306_128_64, self).__init__(128, 64, address, bus)
|
||||
super(SSD1306_128_32, self).__init__(128, 32, address, bus)
|
||||
|
||||
def _initialize(self):
|
||||
# 128x32 pixel specific initialization.
|
||||
|
@ -8,20 +8,27 @@ EPD_HEIGHT = 64
|
||||
# disp = SSD1306.SSD1306_128_32(128, 32, address=0x3C)
|
||||
# disp = SSD1306.SSD1306_96_16(96, 16, address=0x3C)
|
||||
# If you change for different resolution, you have to modify the layout in pwnagotchi/ui/hw/i2coled.py
|
||||
disp = SSD1306.SSD1306_128_64(128, 64, address=0x3C)
|
||||
|
||||
class EPD(object):
|
||||
|
||||
def __init__(self):
|
||||
self.width = EPD_WIDTH
|
||||
self.height = EPD_HEIGHT
|
||||
def __init__(self, address=0x3D, width=EPD_WIDTH, height=EPD_HEIGHT):
|
||||
self.width = width
|
||||
self.height = height
|
||||
|
||||
# choose subclass based on dimensions
|
||||
if height == 32:
|
||||
self.disp = SSD1306.SSD1306_128_32(width, height, address)
|
||||
elif height == 16:
|
||||
self.disp = SSD1306.SSD1306_96_16(width, height, address)
|
||||
else:
|
||||
self.disp = SSD1306.SSD1306_128_64(width, height, address)
|
||||
|
||||
def Init(self):
|
||||
disp.begin()
|
||||
self.disp.begin()
|
||||
|
||||
def Clear(self):
|
||||
disp.clear()
|
||||
self.disp.clear()
|
||||
|
||||
def display(self, image):
|
||||
disp.getbuffer(image)
|
||||
disp.ShowImage()
|
||||
self.disp.getbuffer(image)
|
||||
self.disp.ShowImage()
|
@ -95,11 +95,8 @@ class ST7789(object):
|
||||
offset_left=0,
|
||||
offset_top=0):
|
||||
"""Create an instance of the display using SPI communication.
|
||||
|
||||
Must provide the GPIO pin number for the D/C pin and the SPI driver.
|
||||
|
||||
Can optionally provide the GPIO pin number for the reset pin as the rst parameter.
|
||||
|
||||
:param port: SPI port number
|
||||
:param cs: SPI chip-select number (0 or 1 for BCM
|
||||
:param backlight: Pin for controlling backlight
|
||||
@ -109,7 +106,6 @@ class ST7789(object):
|
||||
:param rotation: Rotation of display connected to ST7789
|
||||
:param invert: Invert display
|
||||
:param spi_speed_hz: SPI speed (in Hz)
|
||||
|
||||
"""
|
||||
if rotation not in [0, 90, 180, 270]:
|
||||
raise ValueError("Invalid rotation {}".format(rotation))
|
||||
@ -287,9 +283,7 @@ class ST7789(object):
|
||||
|
||||
def begin(self):
|
||||
"""Set up the display
|
||||
|
||||
Deprecated. Included in __init__.
|
||||
|
||||
"""
|
||||
pass
|
||||
|
||||
@ -326,9 +320,7 @@ class ST7789(object):
|
||||
|
||||
def display(self, image):
|
||||
"""Write the provided image to the hardware.
|
||||
|
||||
:param image: Should be RGB format and the same dimensions as the display hardware.
|
||||
|
||||
"""
|
||||
# Set address bounds to entire display.
|
||||
self.set_window()
|
||||
|
Reference in New Issue
Block a user