kopia lustrzana https://github.com/peterhinch/micropython-micro-gui
ili9488.py: Add acknowledgement of Carl Pottle.
rodzic
501f91cf7b
commit
99b72f86f4
|
@ -6,14 +6,15 @@
|
||||||
# Copyright (c) Peter Hinch 2022-2025
|
# Copyright (c) Peter Hinch 2022-2025
|
||||||
# Released under the MIT license see LICENSE
|
# Released under the MIT license see LICENSE
|
||||||
|
|
||||||
#
|
# This driver, adapted from ILI9486, was contributed by Carl Pottle (cpottle9).
|
||||||
|
|
||||||
# Note: If your hardware uses the ILI9488 parallel interface
|
# Note: If your hardware uses the ILI9488 parallel interface
|
||||||
# you will likely be better off using the ili9486 driver.
|
# you will likely be better off using the ili9486 driver.
|
||||||
# It will send 2 bytes per pixel which will run faster.
|
# It will send 2 bytes per pixel which will run faster.
|
||||||
#
|
#
|
||||||
# You must use this driver only when using the ILI9488 SPI
|
# You must use this driver only when using the ILI9488 SPI
|
||||||
# interface. It will send 3 bytes per pixel.
|
# interface. It will send 3 bytes per pixel.
|
||||||
#
|
|
||||||
|
|
||||||
from time import sleep_ms
|
from time import sleep_ms
|
||||||
import gc
|
import gc
|
||||||
|
@ -24,15 +25,15 @@ from drivers.boolpalette import BoolPalette
|
||||||
|
|
||||||
# Portrait mode greyscale
|
# Portrait mode greyscale
|
||||||
@micropython.viper
|
@micropython.viper
|
||||||
def _lcopy_gs(dest: ptr8, source: ptr8, length: int) :
|
def _lcopy_gs(dest: ptr8, source: ptr8, length: int):
|
||||||
# rgb666 - 18bit/pixel
|
# rgb666 - 18bit/pixel
|
||||||
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]
|
||||||
# Store the index in the 4 high order bits
|
# Store the index in the 4 high order bits
|
||||||
p : uint = c & 0xF0 # current pixel
|
p: uint = c & 0xF0 # current pixel
|
||||||
q : uint = c << 4 # next pixel
|
q: uint = c << 4 # next pixel
|
||||||
|
|
||||||
dest[n] = p
|
dest[n] = p
|
||||||
n += 1
|
n += 1
|
||||||
|
@ -40,36 +41,36 @@ def _lcopy_gs(dest: ptr8, source: ptr8, length: int) :
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = p
|
dest[n] = p
|
||||||
n += 1
|
n += 1
|
||||||
|
|
||||||
dest[n] = q
|
dest[n] = q
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = q
|
dest[n] = q
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = q
|
dest[n] = q
|
||||||
n += 1
|
n += 1
|
||||||
|
|
||||||
x += 1
|
x += 1
|
||||||
|
|
||||||
|
|
||||||
# Portrait mode color
|
# Portrait mode color
|
||||||
@micropython.viper
|
@micropython.viper
|
||||||
def _lcopy(dest: ptr8, source: ptr8, lut: ptr16, length: int) :
|
def _lcopy(dest: ptr8, source: ptr8, lut: ptr16, length: int):
|
||||||
# Convert lut rgb 565 to rgb666
|
# 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 = c >> 4 # current pixel
|
p: uint = c >> 4 # current pixel
|
||||||
q = c & 0x0F # next pixel
|
q = c & 0x0F # next pixel
|
||||||
|
|
||||||
v : uint16 = lut[p]
|
v: uint16 = lut[p]
|
||||||
dest[n] = (v & 0xF800) >> 8 # R
|
dest[n] = (v & 0xF800) >> 8 # R
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = (v & 0x07E0) >> 3 # G
|
dest[n] = (v & 0x07E0) >> 3 # G
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = (v & 0x001F) << 3 # B
|
dest[n] = (v & 0x001F) << 3 # B
|
||||||
n += 1
|
n += 1
|
||||||
|
|
||||||
v = lut[q]
|
v = lut[q]
|
||||||
dest[n] = (v & 0xF800) >> 8 # R
|
dest[n] = (v & 0xF800) >> 8 # R
|
||||||
n += 1
|
n += 1
|
||||||
|
@ -77,12 +78,13 @@ def _lcopy(dest: ptr8, source: ptr8, lut: ptr16, length: int) :
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = (v & 0x001F) << 3 # B
|
dest[n] = (v & 0x001F) << 3 # B
|
||||||
n += 1
|
n += 1
|
||||||
|
|
||||||
x += 1
|
x += 1
|
||||||
|
|
||||||
|
|
||||||
# FB is in landscape mode greyscale
|
# FB is in landscape mode greyscale
|
||||||
@micropython.viper
|
@micropython.viper
|
||||||
def _lscopy_gs(dest: ptr8, source: ptr8, ch: int) :
|
def _lscopy_gs(dest: ptr8, source: ptr8, ch: int):
|
||||||
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
|
||||||
|
@ -91,22 +93,23 @@ def _lscopy_gs(dest: ptr8, source: ptr8, ch: int) :
|
||||||
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 = source[idx] << 4
|
c = source[idx] << 4
|
||||||
else :
|
else:
|
||||||
c = source[idx] & 0xf0
|
c = source[idx] & 0xF0
|
||||||
dest[n] = c
|
dest[n] = c
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = c
|
dest[n] = c
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = c
|
dest[n] = c
|
||||||
n += 1
|
n += 1
|
||||||
idx += wbytes
|
idx += wbytes
|
||||||
height -= 1
|
height -= 1
|
||||||
|
|
||||||
|
|
||||||
# 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: ptr16, ch: int) :
|
def _lscopy(dest: ptr8, source: ptr8, lut: ptr16, ch: int):
|
||||||
# Convert lut rgb 565 to rgb666
|
# 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
|
||||||
|
@ -119,7 +122,7 @@ def _lscopy(dest: ptr8, source: ptr8, lut: ptr16, ch: int) :
|
||||||
c = source[idx] & 0x0F
|
c = source[idx] & 0x0F
|
||||||
else:
|
else:
|
||||||
c = source[idx] >> 4
|
c = source[idx] >> 4
|
||||||
v : uint16 = lut[c]
|
v: uint16 = lut[c]
|
||||||
dest[n] = (v & 0xF800) >> 8 # R
|
dest[n] = (v & 0xF800) >> 8 # R
|
||||||
n += 1
|
n += 1
|
||||||
dest[n] = (v & 0x07E0) >> 3 # G
|
dest[n] = (v & 0x07E0) >> 3 # G
|
||||||
|
@ -142,9 +145,7 @@ class ILI9488(framebuf.FrameBuffer):
|
||||||
# byte order not swapped (compared to ili9486 driver).
|
# byte order not swapped (compared to ili9486 driver).
|
||||||
@classmethod
|
@classmethod
|
||||||
def rgb(cls, r, g, b):
|
def rgb(cls, r, g, b):
|
||||||
return cls.COLOR_INVERT ^ (
|
return cls.COLOR_INVERT ^ ((r & 0xF8) << 8 | (g & 0xFC) << 3 | (b >> 3))
|
||||||
(r & 0xF8) << 8 | (g & 0xFC) << 3 | (b >> 3)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Transpose width & height for landscape mode
|
# Transpose width & height for landscape mode
|
||||||
def __init__(
|
def __init__(
|
||||||
|
@ -237,11 +238,11 @@ class ILI9488(framebuf.FrameBuffer):
|
||||||
if self.width < self.height: # Portrait 350 ms on ESP32 160 MHz, 26.6 MHz 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:
|
||||||
for start in range(0, wd * ht, wd): # For each line
|
for start in range(0, wd * ht, wd): # For each line
|
||||||
_lcopy_gs(lb, buf[start:], wd) # Copy greyscale
|
_lcopy_gs(lb, buf[start:], wd) # Copy greyscale
|
||||||
self._spi.write(lb)
|
self._spi.write(lb)
|
||||||
else :
|
else:
|
||||||
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)
|
||||||
|
@ -249,15 +250,15 @@ class ILI9488(framebuf.FrameBuffer):
|
||||||
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
|
||||||
if cm :
|
if cm:
|
||||||
for col in range(width): # For each column of landscape display
|
for col in range(width): # For each column of landscape display
|
||||||
_lscopy_gs(lb, buf, wd - col + cargs) # Copy greyscale
|
_lscopy_gs(lb, buf, wd - col + cargs) # Copy greyscale
|
||||||
self._spi.write(lb)
|
self._spi.write(lb)
|
||||||
else :
|
else:
|
||||||
for col in range(width): # For each column of landscape display
|
for col in range(width): # For each column of landscape display
|
||||||
_lscopy(lb, buf, clut, wd - col + cargs) # Copy and map colors
|
_lscopy(lb, buf, clut, wd - col + cargs) # Copy and map colors
|
||||||
self._spi.write(lb)
|
self._spi.write(lb)
|
||||||
|
|
||||||
self._cs(1)
|
self._cs(1)
|
||||||
|
|
||||||
def short_lock(self, v=None):
|
def short_lock(self, v=None):
|
||||||
|
@ -289,11 +290,15 @@ class ILI9488(framebuf.FrameBuffer):
|
||||||
self._spi_init(self._spi) # Bus may be shared
|
self._spi_init(self._spi) # Bus may be shared
|
||||||
self._cs(0)
|
self._cs(0)
|
||||||
if cm:
|
if cm:
|
||||||
for start in range(wd * line, wd * (line + lines), wd): # For each line
|
for start in range(
|
||||||
|
wd * line, wd * (line + lines), wd
|
||||||
|
): # For each line
|
||||||
_lcopy_gs(lb, buf[start:], wd) # Copy and greyscale
|
_lcopy_gs(lb, buf[start:], wd) # Copy and greyscale
|
||||||
self._spi.write(lb)
|
self._spi.write(lb)
|
||||||
else :
|
else:
|
||||||
for start in range(wd * line, wd * (line + lines), wd): # For each line
|
for start in range(
|
||||||
|
wd * line, wd * (line + lines), 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)
|
||||||
|
|
||||||
|
@ -309,11 +314,11 @@ class ILI9488(framebuf.FrameBuffer):
|
||||||
if self._spi_init: # A callback was passed
|
if self._spi_init: # A callback was passed
|
||||||
self._spi_init(self._spi) # Bus may be shared
|
self._spi_init(self._spi) # Bus may be shared
|
||||||
self._cs(0)
|
self._cs(0)
|
||||||
if cm :
|
if cm:
|
||||||
for col in range(sc, ec, -1): # For each column of landscape display
|
for col in range(sc, ec, -1): # For each column of landscape display
|
||||||
_lscopy_gs(lb, buf, col + cargs) # Copy and map colors
|
_lscopy_gs(lb, buf, col + cargs) # Copy and map colors
|
||||||
self._spi.write(lb)
|
self._spi.write(lb)
|
||||||
else :
|
else:
|
||||||
for col in range(sc, ec, -1): # For each column of landscape display
|
for col in range(sc, ec, -1): # For each column of landscape display
|
||||||
_lscopy(lb, buf, clut, col + cargs) # Copy and map colors
|
_lscopy(lb, buf, clut, col + cargs) # Copy and map colors
|
||||||
self._spi.write(lb)
|
self._spi.write(lb)
|
||||||
|
|
Ładowanie…
Reference in New Issue