kopia lustrzana https://github.com/peterhinch/micropython-nano-gui
Address code review feedback
Three relatively small changes: 1) Undo changes to gui/core/writer.py 2) Modify setup_examples/ili9488_pico.py to specify pins by number rather than string. 3) As recommended, use a 2 byte per entry color lookup table rather than 3 bytes (needed to undo changes in writer.py). I ran the same tests for these changes as last time.pull/98/head
rodzic
10ca0458db
commit
82b263a422
|
@ -53,27 +53,29 @@ def _lcopy_gs(dest: ptr8, source: ptr8, length: int) :
|
||||||
|
|
||||||
# Portrait mode color
|
# Portrait mode color
|
||||||
@micropython.viper
|
@micropython.viper
|
||||||
def _lcopy(dest: ptr8, source: ptr8, lut: ptr8, length: int) :
|
def _lcopy(dest: ptr8, source: ptr8, lut: ptr16, length: int) :
|
||||||
# rgb666 - 18bit/pixel
|
# Convert lut rgb 565 to rgb666
|
||||||
n: int = 0
|
n: int = 0
|
||||||
x: int = 0
|
x: int = 0
|
||||||
while x < length:
|
while x < length:
|
||||||
c : uint = source[x]
|
c : uint = source[x]
|
||||||
p : uint = 3 * (c >> 4) # current pixel
|
p : uint = c >> 4 # current pixel
|
||||||
q : uint = 3 * (c & 0x0F) # next pixel
|
q = c & 0x0F # next pixel
|
||||||
|
|
||||||
dest[n] = lut[p]
|
v : uint16 = lut[p]
|
||||||
|
dest[n] = (v & 0xF800) >> 8 # R
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = lut[p+1]
|
dest[n] = (v & 0x07E0) >> 3 # G
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = lut[p+2]
|
dest[n] = (v & 0x001F) << 3 # B
|
||||||
n += 1
|
n += 1
|
||||||
|
|
||||||
dest[n] = lut[q]
|
v = lut[q]
|
||||||
|
dest[n] = (v & 0xF800) >> 8 # R
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = lut[q+1]
|
dest[n] = (v & 0x07E0) >> 3 # G
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = lut[q+2]
|
dest[n] = (v & 0x001F) << 3 # B
|
||||||
n += 1
|
n += 1
|
||||||
|
|
||||||
x += 1
|
x += 1
|
||||||
|
@ -104,46 +106,45 @@ def _lscopy_gs(dest: ptr8, source: ptr8, ch: int) :
|
||||||
|
|
||||||
# FB is in landscape mode color, hence issue a column at a time to portrait mode hardware.
|
# FB is in landscape mode color, hence issue a column at a time to portrait mode hardware.
|
||||||
@micropython.viper
|
@micropython.viper
|
||||||
def _lscopy(dest: ptr8, source: ptr8, lut: ptr8, ch: int) :
|
def _lscopy(dest: ptr8, source: ptr8, lut: ptr16, ch: int) :
|
||||||
|
# Convert lut rgb 565 to rgb666
|
||||||
col = ch & 0x1FF # Unpack (viper old 4 parameter limit)
|
col = ch & 0x1FF # Unpack (viper old 4 parameter limit)
|
||||||
height = (ch >> 9) & 0x1FF
|
height = (ch >> 9) & 0x1FF
|
||||||
wbytes = ch >> 19 # Width in bytes is width // 2
|
wbytes = ch >> 19 # Width in bytes is width // 2
|
||||||
# rgb666 - 18bit/pixel
|
|
||||||
n = 0
|
n = 0
|
||||||
clsb = col & 1
|
clsb = col & 1
|
||||||
idx = col >> 1 # 2 pixels per byte
|
idx = col >> 1 # 2 pixels per byte
|
||||||
while height:
|
while height:
|
||||||
if clsb:
|
if clsb:
|
||||||
c = 3 * (source[idx] & 0x0F)
|
c = source[idx] & 0x0F
|
||||||
else:
|
else:
|
||||||
c = 3 * (source[idx] >> 4)
|
c = source[idx] >> 4
|
||||||
dest[n] = lut[c]
|
v : uint16 = lut[c]
|
||||||
|
dest[n] = (v & 0xF800) >> 8 # R
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = lut[c+1]
|
dest[n] = (v & 0x07E0) >> 3 # G
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = lut[c+2]
|
dest[n] = (v & 0x001F) << 3 # B
|
||||||
n += 1
|
n += 1
|
||||||
|
|
||||||
idx += wbytes
|
idx += wbytes
|
||||||
height -= 1
|
height -= 1
|
||||||
|
|
||||||
|
|
||||||
class ILI9488(framebuf.FrameBuffer):
|
class ILI9488(framebuf.FrameBuffer):
|
||||||
|
|
||||||
# A lookup table with 3 bytes per entry formatted for direct send to ILI9488
|
lut = bytearray(32)
|
||||||
lut = bytearray(48)
|
|
||||||
|
|
||||||
COLOR_INVERT = 0
|
COLOR_INVERT = 0
|
||||||
|
|
||||||
# Convert r, g, b in range 0-255 to a 16 bit colour value
|
# Convert r, g, b in range 0-255 to a 16 bit colour value
|
||||||
# LS byte goes into LUT offset 0, MS byte into offset 1
|
# 5-6-5 format
|
||||||
# Same mapping in linebuf so LS byte is shifted out 1st
|
# byte order not swapped (compared to ili9486 driver).
|
||||||
# ILI9488 expects RGB order. 8 bit register writes require padding
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def rgb(cls, r, g, b):
|
def rgb(cls, r, g, b):
|
||||||
r_device = cls.COLOR_INVERT ^ (r & 0xfc)
|
return cls.COLOR_INVERT ^ (
|
||||||
g_device = cls.COLOR_INVERT ^ (g & 0xfc)
|
(r & 0xF8) << 8 | (g & 0xFC) << 3 | (b >> 3)
|
||||||
b_device = cls.COLOR_INVERT ^ (b & 0xfc)
|
)
|
||||||
return (r_device << 16) | (g_device << 8) | b_device
|
|
||||||
|
|
||||||
# Transpose width & height for landscape mode
|
# Transpose width & height for landscape mode
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -233,7 +234,7 @@ class ILI9488(framebuf.FrameBuffer):
|
||||||
self._wcmd(b"\x2c") # WRITE_RAM
|
self._wcmd(b"\x2c") # WRITE_RAM
|
||||||
self._dc(1)
|
self._dc(1)
|
||||||
self._cs(0)
|
self._cs(0)
|
||||||
if self.width < self.height: # Portrait 300 ms on ESP32 240MHz, 30MHz SPI clock
|
if self.width < self.height: # Portrait 350 ms on ESP32 160 MHz, 26.6 MHz SPI clock
|
||||||
wd = self.width // 2
|
wd = self.width // 2
|
||||||
ht = self.height
|
ht = self.height
|
||||||
if cm :
|
if cm :
|
||||||
|
@ -244,7 +245,7 @@ class ILI9488(framebuf.FrameBuffer):
|
||||||
for start in range(0, wd * ht, wd): # For each line
|
for start in range(0, wd * ht, wd): # For each line
|
||||||
_lcopy(lb, buf[start:], clut, wd) # Copy and map colors
|
_lcopy(lb, buf[start:], clut, wd) # Copy and map colors
|
||||||
self._spi.write(lb)
|
self._spi.write(lb)
|
||||||
else: # Landscape 330 ms on ESP32 240MHz, 30MHz SPI clock
|
else: # Landscape 370 ms on ESP32 160 MHz, 26.6 MHz SPI clock
|
||||||
width = self.width
|
width = self.width
|
||||||
wd = width - 1
|
wd = width - 1
|
||||||
cargs = (self.height << 9) + (width << 18) # Viper 4-arg limit
|
cargs = (self.height << 9) + (width << 18) # Viper 4-arg limit
|
||||||
|
|
|
@ -263,23 +263,10 @@ class CWriter(Writer):
|
||||||
return c
|
return c
|
||||||
if not 0 <= idx <= 15:
|
if not 0 <= idx <= 15:
|
||||||
raise ValueError('Color nos must be 0..15')
|
raise ValueError('Color nos must be 0..15')
|
||||||
|
|
||||||
if len(ssd.lut) == 32 :
|
|
||||||
# ssd supports 2 byte color
|
|
||||||
x = idx << 1
|
x = idx << 1
|
||||||
ssd.lut[x] = c & 0xff
|
ssd.lut[x] = c & 0xff
|
||||||
ssd.lut[x + 1] = c >> 8
|
ssd.lut[x + 1] = c >> 8
|
||||||
return idx
|
return idx
|
||||||
elif len(ssd.lut) == 48 :
|
|
||||||
# ssd supports 3 byte color
|
|
||||||
x = idx * 3
|
|
||||||
ssd.lut[x] = c >> 16
|
|
||||||
ssd.lut[x + 1] = (c >> 8) & 0xff
|
|
||||||
ssd.lut[x + 2] = c & 0xff
|
|
||||||
return idx
|
|
||||||
else :
|
|
||||||
raise TypeError("lut of %d bytes not supported" % (len(ssd.lut)))
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, device, font, fgcolor=None, bgcolor=None, verbose=True):
|
def __init__(self, device, font, fgcolor=None, bgcolor=None, verbose=True):
|
||||||
if not hasattr(device, 'palette'):
|
if not hasattr(device, 'palette'):
|
||||||
|
|
|
@ -8,16 +8,16 @@ from micropython import const
|
||||||
# Modify these Pin assignments to match your hardware.
|
# Modify these Pin assignments to match your hardware.
|
||||||
|
|
||||||
# Simple GPIO's
|
# Simple GPIO's
|
||||||
LCD_DC = 'GPIO21' # Pin 27
|
LCD_DC = const(21) # PICO Pin 27
|
||||||
LCD_RST = 'GPIO22' # Pin 29
|
LCD_RST = const(22) # PICO Pin 29
|
||||||
LCD_CS = 'GPIO27' # Pin 32
|
LCD_CS = const(27) # PICO Pin 32
|
||||||
LCD_BackLight = 'GPIO28' # Pin 34
|
LCD_BackLight = const(28) # PICO Pin 34
|
||||||
|
|
||||||
# SPI pins
|
# SPI pins
|
||||||
|
|
||||||
LCD_CLK = 'GPIO18' # Pin 24
|
LCD_CLK = const(18) # PICO Pin 24
|
||||||
LCD_MOSI = 'GPIO19' # Pin 25
|
LCD_MOSI = const(19) # PICO Pin 25
|
||||||
LCD_MISO = 'GPIO16' # Pin 21
|
LCD_MISO = const(16) # PICO Pin 21
|
||||||
|
|
||||||
from machine import Pin, SPI
|
from machine import Pin, SPI
|
||||||
from drivers.ili94xx.ili9488 import ILI9488 as SSD
|
from drivers.ili94xx.ili9488 import ILI9488 as SSD
|
||||||
|
|
Ładowanie…
Reference in New Issue