wasp: simulator: Add ST7789 simulation
This commit is contained in:
parent
c7e11d6020
commit
e21f2a79ca
3 changed files with 102 additions and 7 deletions
73
wasp/boards/simulator/display.py
Normal file
73
wasp/boards/simulator/display.py
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
""" Simulated ST7789 display. """
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import sdl2
|
||||||
|
import sdl2.ext
|
||||||
|
|
||||||
|
CASET = 0x2a
|
||||||
|
RASET = 0x2b
|
||||||
|
RAMWR = 0x2c
|
||||||
|
|
||||||
|
class ST7789Sim(object):
|
||||||
|
def __init__(self, width=240, height=240):
|
||||||
|
sdl2.ext.init()
|
||||||
|
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
|
||||||
|
self.x = 0
|
||||||
|
self.y = 0
|
||||||
|
self.colclip = [0, width-1]
|
||||||
|
self.rowclip = [0, height-1]
|
||||||
|
self.cmd = 0
|
||||||
|
|
||||||
|
self.window = sdl2.ext.Window("ST7789", size=(width, height))
|
||||||
|
self.window.show()
|
||||||
|
self.windowsurface = self.window.get_surface()
|
||||||
|
sdl2.ext.fill(self.windowsurface, (0, 0, 0))
|
||||||
|
|
||||||
|
def write(self, data):
|
||||||
|
if len(data) == 1:
|
||||||
|
# Assume if we get a byte at a time then it is command.
|
||||||
|
# This is a simplification do we don't have to track
|
||||||
|
# the D/C pin from within the simulator.
|
||||||
|
self.cmd = data[0]
|
||||||
|
|
||||||
|
elif self.cmd == CASET:
|
||||||
|
self.colclip[0] = (data[0] << 8) + data[1]
|
||||||
|
self.colclip[1] = (data[2] << 8) + data[3]
|
||||||
|
self.x = self.colclip[0]
|
||||||
|
|
||||||
|
elif self.cmd == RASET:
|
||||||
|
self.rowclip[0] = (data[0] << 8) + data[1]
|
||||||
|
self.rowclip[1] = (data[2] << 8) + data[3]
|
||||||
|
self.y = self.rowclip[0]
|
||||||
|
|
||||||
|
elif self.cmd == RAMWR:
|
||||||
|
pixelview = sdl2.ext.PixelView(self.windowsurface)
|
||||||
|
|
||||||
|
half = False
|
||||||
|
for d in data:
|
||||||
|
if not half:
|
||||||
|
rgb = d << 8
|
||||||
|
half = True
|
||||||
|
continue
|
||||||
|
rgb |= d
|
||||||
|
half = False
|
||||||
|
|
||||||
|
pixel = ((rgb & 0xf800) >> 8,
|
||||||
|
(rgb & 0x07e0) >> 3,
|
||||||
|
(rgb & 0x001f) << 3)
|
||||||
|
|
||||||
|
pixelview[self.y][self.x] = pixel
|
||||||
|
|
||||||
|
self.x += 1
|
||||||
|
if self.x > self.rowclip[1]:
|
||||||
|
self.x = self.rowclip[0]
|
||||||
|
self.y += 1
|
||||||
|
if self.y > self.colclip[1]:
|
||||||
|
self.y = self.colclip[0]
|
||||||
|
|
||||||
|
# Forcibly release the surface to ensure it is unlocked
|
||||||
|
del pixelview
|
||||||
|
self.window.refresh()
|
|
@ -1,3 +1,5 @@
|
||||||
|
import display
|
||||||
|
|
||||||
class Tracer(object):
|
class Tracer(object):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
print(f'{self.__class__.__name__}.__init__{args} {kwargs}')
|
print(f'{self.__class__.__name__}.__init__{args} {kwargs}')
|
||||||
|
@ -14,9 +16,10 @@ class Pin(object):
|
||||||
IN = 'IN'
|
IN = 'IN'
|
||||||
OUT = 'OUT'
|
OUT = 'OUT'
|
||||||
|
|
||||||
def __init__(self, id, direction, value=1):
|
def __init__(self, id, direction, value=1, quiet=False):
|
||||||
self._id = id
|
self._id = id
|
||||||
self._value = 0
|
self._value = 0
|
||||||
|
self._quiet = quiet
|
||||||
|
|
||||||
def init(self, d, value):
|
def init(self, d, value):
|
||||||
self.value(value)
|
self.value(value)
|
||||||
|
@ -29,12 +32,16 @@ class Pin(object):
|
||||||
|
|
||||||
def value(self, v=None):
|
def value(self, v=None):
|
||||||
if v is None:
|
if v is None:
|
||||||
|
if not self._quiet:
|
||||||
|
print(f'{self._id}: read {self._value}')
|
||||||
return self._value
|
return self._value
|
||||||
if v:
|
if v:
|
||||||
print(self._id + ": on")
|
if not self._quiet:
|
||||||
|
print(self._id + ": set on")
|
||||||
self._value = False
|
self._value = False
|
||||||
else:
|
else:
|
||||||
print(self._id + ": off")
|
if not self._quiet:
|
||||||
|
print(self._id + ": set off")
|
||||||
self._value = True
|
self._value = True
|
||||||
|
|
||||||
def __call__(self, v=None):
|
def __call__(self, v=None):
|
||||||
|
@ -46,9 +53,16 @@ class PWM(Tracer):
|
||||||
class SPI(object):
|
class SPI(object):
|
||||||
def __init__(self, id):
|
def __init__(self, id):
|
||||||
self._id = id
|
self._id = id
|
||||||
|
if id == 0:
|
||||||
|
self.sim = display.ST7789Sim()
|
||||||
|
else:
|
||||||
|
self.sim = None
|
||||||
|
|
||||||
def init(self, baudrate=1000000, polarity=0, phase=0, bits=8, sck=None, mosi=None, miso=None):
|
def init(self, baudrate=1000000, polarity=0, phase=0, bits=8, sck=None, mosi=None, miso=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def write(self, buf):
|
def write(self, buf):
|
||||||
|
if self.sim:
|
||||||
|
self.sim.write(buf)
|
||||||
|
else:
|
||||||
print("Sending data: " + str(buf))
|
print("Sending data: " + str(buf))
|
||||||
|
|
|
@ -9,6 +9,13 @@ from machine import SPI
|
||||||
from drivers.st7789 import ST7789_SPI
|
from drivers.st7789 import ST7789_SPI
|
||||||
from drivers.vibrator import Vibrator
|
from drivers.vibrator import Vibrator
|
||||||
|
|
||||||
|
class Backlight(object):
|
||||||
|
def __init__(self, level=1):
|
||||||
|
self.set(level)
|
||||||
|
|
||||||
|
def set(self, level):
|
||||||
|
print(f'BACKLIGHT: {level}')
|
||||||
|
|
||||||
class Display(ST7789_SPI):
|
class Display(ST7789_SPI):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
spi = SPI(0)
|
spi = SPI(0)
|
||||||
|
@ -16,11 +23,12 @@ class Display(ST7789_SPI):
|
||||||
spi.init(polarity=1, phase=1, baudrate=8000000)
|
spi.init(polarity=1, phase=1, baudrate=8000000)
|
||||||
|
|
||||||
# Configure the display
|
# Configure the display
|
||||||
cs = Pin("DISP_CS", Pin.OUT)
|
cs = Pin("DISP_CS", Pin.OUT, quiet=True)
|
||||||
dc = Pin("DISP_DC", Pin.OUT)
|
dc = Pin("DISP_DC", Pin.OUT, quiet=True)
|
||||||
rst = Pin("DISP_RST", Pin.OUT)
|
rst = Pin("DISP_RST", Pin.OUT, quiet=True)
|
||||||
|
|
||||||
super().__init__(240, 240, spi, cs=cs, dc=dc, res=rst)
|
super().__init__(240, 240, spi, cs=cs, dc=dc, res=rst)
|
||||||
|
|
||||||
display = Display()
|
display = Display()
|
||||||
|
backlight = Backlight()
|
||||||
vibrator = Vibrator(Pin('MOTOR', Pin.OUT, value=0), active_low=True)
|
vibrator = Vibrator(Pin('MOTOR', Pin.OUT, value=0), active_low=True)
|
||||||
|
|
Loading…
Reference in a new issue