firmware/unix/variant/ssd1306.py
2026-03-04 17:32:21 -05:00

96 lines
2.6 KiB
Python

# compatibility layer: emulate an SPI-connected OLED display
from micropython import const
import framebuf
# register definitions
SET_CONTRAST = const(0x81)
SET_ENTIRE_ON = const(0xa4)
SET_NORM_INV = const(0xa6)
SET_DISP = const(0xae)
SET_MEM_ADDR = const(0x20)
SET_COL_ADDR = const(0x21)
SET_PAGE_ADDR = const(0x22)
SET_DISP_START_LINE = const(0x40)
SET_SEG_REMAP = const(0xa0)
SET_MUX_RATIO = const(0xa8)
SET_COM_OUT_DIR = const(0xc0)
SET_DISP_OFFSET = const(0xd3)
SET_COM_PIN_CFG = const(0xda)
SET_DISP_CLK_DIV = const(0xd5)
SET_PRECHARGE = const(0xd9)
SET_VCOM_DESEL = const(0xdb)
SET_CHARGE_PUMP = const(0x8d)
# Subclassing FrameBuffer provides support for graphics primitives
# http://docs.micropython.org/en/latest/pyboard/library/framebuf.html
class SSD1306(framebuf.FrameBuffer):
def __init__(self, width, height, is_mk5):
self.width = width
self.height = height
self.is_mk5 = is_mk5
self.pages = self.height // 8
self.buffer = bytearray(self.pages * self.width)
super().__init__(self.buffer, self.width, self.height, framebuf.MONO_VLSB)
self.init_display()
def init_display(self):
self.fill(0)
self.show()
def poweroff(self):
#self.write_cmd(SET_DISP | 0x00)
pass
def poweron(self):
#self.write_cmd(SET_DISP | 0x01)
pass
def contrast(self, contrast):
#self.write_cmd(SET_CONTRAST)
#self.write_cmd(contrast)
pass
def invert(self, invert):
#self.write_cmd(SET_NORM_INV | (invert & 1))
# TODO
pass
def show(self):
x0 = 0
x1 = self.width - 1
if self.width == 64:
# displays with width of 64 pixels are shifted by 32
x0 += 32
x1 += 32
self.write_cmd(SET_COL_ADDR)
self.write_cmd(x0)
self.write_cmd(x1)
self.write_cmd(SET_PAGE_ADDR)
self.write_cmd(0)
self.write_cmd(self.pages - 1)
self.write_data(self.buffer)
def busy_bar(self, enable, pattern):
# Render a continuous activity (not progress) bar in lower 8 lines of display
if enable:
# just show as static pattern
t = self.buffer[:-128] + pattern
self.write_data(t)
class SSD1306_SPI(SSD1306):
def __init__(self, width, height, spi, dc, res, cs, is_mk5=False):
import sys
self.pipe = open(int(sys.argv[1]), 'wb')
super().__init__(width, height, is_mk5)
def write_cmd(self, cmd):
pass
def write_data(self, buf):
self.pipe.write(buf)