mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-15 00:52:02 +00:00
chore(core): remove legacy drawing code (c)
[no changelog]
This commit is contained in:
parent
2481f768f8
commit
d4286ff584
@ -38,7 +38,6 @@ ADDRESS_SANITIZER ?= 0
|
||||
CMAKELISTS ?= 0
|
||||
PYTEST_TIMEOUT ?= 500
|
||||
TEST_LANG ?= "en"
|
||||
NEW_RENDERING ?= 1
|
||||
THP ?= 0
|
||||
BENCHMARK ?= 0
|
||||
|
||||
@ -253,12 +252,12 @@ build_embed: build_boardloader build_bootloader build_firmware # build boardload
|
||||
|
||||
build_boardloader: ## build boardloader
|
||||
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" \
|
||||
CMAKELISTS="$(CMAKELISTS)" NEW_RENDERING="$(NEW_RENDERING)" $(BOARDLOADER_BUILD_DIR)/boardloader.bin
|
||||
CMAKELISTS="$(CMAKELISTS)" $(BOARDLOADER_BUILD_DIR)/boardloader.bin
|
||||
|
||||
build_bootloader: ## build bootloader
|
||||
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" \
|
||||
CMAKELISTS="$(CMAKELISTS)" BOOTLOADER_QA="$(BOOTLOADER_QA)" BOOTLOADER_DEVEL="$(BOOTLOADER_DEVEL)" \
|
||||
NEW_RENDERING="$(NEW_RENDERING)" $(BOOTLOADER_BUILD_DIR)/bootloader.bin
|
||||
$(BOOTLOADER_BUILD_DIR)/bootloader.bin
|
||||
|
||||
build_bootloader_ci: ## build CI device testing bootloader
|
||||
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" \
|
||||
@ -266,11 +265,11 @@ build_bootloader_ci: ## build CI device testing bootloader
|
||||
|
||||
build_bootloader_emu: ## build the unix bootloader emulator
|
||||
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" \
|
||||
CMAKELISTS="$(CMAKELISTS)" NEW_RENDERING="$(NEW_RENDERING)" $(BOOTLOADER_EMU_BUILD_DIR)/bootloader.elf
|
||||
CMAKELISTS="$(CMAKELISTS)" $(BOOTLOADER_EMU_BUILD_DIR)/bootloader.elf
|
||||
|
||||
build_bootloader_emu_debug: ## build the unix bootloader emulator
|
||||
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" \
|
||||
CMAKELISTS="$(CMAKELISTS)" NEW_RENDERING="$(NEW_RENDERING)" TREZOR_EMULATOR_DEBUGGABLE=1 \
|
||||
CMAKELISTS="$(CMAKELISTS)" TREZOR_EMULATOR_DEBUGGABLE=1 \
|
||||
$(BOOTLOADER_EMU_BUILD_DIR)/bootloader.elf
|
||||
|
||||
build_prodtest: ## build production test firmware
|
||||
@ -279,7 +278,7 @@ build_prodtest: ## build production test firmware
|
||||
|
||||
build_reflash: ## build reflash firmware + reflash image
|
||||
$(SCONS) CFLAGS="$(CFLAGS)" PRODUCTION="$(PRODUCTION)" TREZOR_MODEL="$(TREZOR_MODEL)" \
|
||||
CMAKELISTS="$(CMAKELISTS)" NEW_RENDERING="$(NEW_RENDERING)" $(REFLASH_BUILD_DIR)/reflash.bin
|
||||
CMAKELISTS="$(CMAKELISTS)" $(REFLASH_BUILD_DIR)/reflash.bin
|
||||
dd if=build/boardloader/boardloader.bin of=$(REFLASH_BUILD_DIR)/sdimage.bin bs=1 seek=0
|
||||
dd if=build/bootloader/bootloader.bin of=$(REFLASH_BUILD_DIR)/sdimage.bin bs=1 seek=49152
|
||||
|
||||
@ -294,27 +293,27 @@ build_firmware: templates build_cross build_kernel ## build firmware with frozen
|
||||
TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" \
|
||||
PYOPT="$(PYOPT)" BITCOIN_ONLY="$(BITCOIN_ONLY)" \
|
||||
BOOTLOADER_QA="$(BOOTLOADER_QA)" BOOTLOADER_DEVEL="$(BOOTLOADER_DEVEL)" \
|
||||
DISABLE_OPTIGA="$(DISABLE_OPTIGA)" THP="$(THP)" NEW_RENDERING="$(NEW_RENDERING)" \
|
||||
DISABLE_OPTIGA="$(DISABLE_OPTIGA)" THP="$(THP)" \
|
||||
BENCHMARK="$(BENCHMARK)" $(FIRMWARE_BUILD_DIR)/firmware.bin
|
||||
|
||||
build_unix: templates ## build unix port
|
||||
$(SCONS) CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) \
|
||||
TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" THP="$(THP)" \
|
||||
PYOPT="0" BITCOIN_ONLY="$(BITCOIN_ONLY)" TREZOR_EMULATOR_ASAN="$(ADDRESS_SANITIZER)" \
|
||||
NEW_RENDERING="$(NEW_RENDERING)" BENCHMARK="$(BENCHMARK)"
|
||||
BENCHMARK="$(BENCHMARK)"
|
||||
|
||||
build_unix_frozen: templates build_cross ## build unix port with frozen modules
|
||||
$(SCONS) CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) \
|
||||
TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" \
|
||||
PYOPT="$(PYOPT)" BITCOIN_ONLY="$(BITCOIN_ONLY)" TREZOR_EMULATOR_ASAN="$(ADDRESS_SANITIZER)" \
|
||||
TREZOR_MEMPERF="$(TREZOR_MEMPERF)" TREZOR_EMULATOR_FROZEN=1 NEW_RENDERING="$(NEW_RENDERING)" \
|
||||
TREZOR_MEMPERF="$(TREZOR_MEMPERF)" TREZOR_EMULATOR_FROZEN=1 \
|
||||
BENCHMARK="$(BENCHMARK)"
|
||||
|
||||
build_unix_debug: templates ## build unix port
|
||||
$(SCONS) --max-drift=1 CFLAGS="$(CFLAGS)" $(UNIX_BUILD_DIR)/trezor-emu-core $(UNIX_PORT_OPTS) \
|
||||
TREZOR_MODEL="$(TREZOR_MODEL)" CMAKELISTS="$(CMAKELISTS)" \
|
||||
BITCOIN_ONLY="$(BITCOIN_ONLY)" TREZOR_EMULATOR_ASAN=1 TREZOR_EMULATOR_DEBUGGABLE=1 \
|
||||
NEW_RENDERING="$(NEW_RENDERING)" BENCHMARK="$(BENCHMARK)"
|
||||
BENCHMARK="$(BENCHMARK)"
|
||||
|
||||
build_cross: ## build mpy-cross port
|
||||
$(MAKE) -C vendor/micropython/mpy-cross $(CROSS_PORT_OPTS)
|
||||
|
@ -6,14 +6,10 @@ import tools, models
|
||||
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
|
||||
CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
|
||||
HW_REVISION = ARGUMENTS.get('HW_REVISION', None)
|
||||
NEW_RENDERING = ARGUMENTS.get('NEW_RENDERING', '1') == '1'
|
||||
MODEL_IDENTIFIER = models.get_model_identifier(TREZOR_MODEL)
|
||||
|
||||
FEATURES_WANTED = ["sd_card"]
|
||||
|
||||
if NEW_RENDERING:
|
||||
FEATURES_WANTED.append("new_rendering")
|
||||
|
||||
CCFLAGS_MOD = ''
|
||||
CPPPATH_MOD = []
|
||||
CPPDEFINES_MOD = ["BOARDLOADER"]
|
||||
@ -56,7 +52,6 @@ CPPPATH_MOD += [
|
||||
'vendor/micropython/lib/uzlib',
|
||||
]
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/colors.c',
|
||||
'embed/lib/display_utils.c',
|
||||
'embed/lib/error_handling.c',
|
||||
'embed/lib/flash_utils.c',
|
||||
@ -70,18 +65,8 @@ SOURCE_MOD += [
|
||||
'embed/lib/mini_printf.c',
|
||||
'embed/lib/rsod.c',
|
||||
'embed/lib/terminal.c',
|
||||
'embed/lib/gfx_draw.c'
|
||||
]
|
||||
if NEW_RENDERING:
|
||||
CPPDEFINES_MOD += ['NEW_RENDERING']
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/gfx_draw.c',
|
||||
]
|
||||
else:
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/display_draw.c',
|
||||
]
|
||||
|
||||
|
||||
|
||||
env = Environment(ENV=os.environ,
|
||||
CFLAGS='%s -DPRODUCTION=%s' % (ARGUMENTS.get('CFLAGS', ''), ARGUMENTS.get('PRODUCTION', '0')),
|
||||
|
@ -8,14 +8,10 @@ CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
|
||||
BOOTLOADER_QA = ARGUMENTS.get('BOOTLOADER_QA', '0') == '1'
|
||||
PRODUCTION = 0 if BOOTLOADER_QA else ARGUMENTS.get('PRODUCTION', '0') == '1'
|
||||
HW_REVISION = ARGUMENTS.get('HW_REVISION', None)
|
||||
NEW_RENDERING = ARGUMENTS.get('NEW_RENDERING', '1') == '1' or TREZOR_MODEL in ('T3T1',)
|
||||
MODEL_IDENTIFIER = models.get_model_identifier(TREZOR_MODEL)
|
||||
|
||||
FEATURES_WANTED = ["input", "rgb_led", "consumption_mask", "usb", "optiga", "dma2d"]
|
||||
|
||||
if NEW_RENDERING:
|
||||
FEATURES_WANTED.append("new_rendering")
|
||||
|
||||
CCFLAGS_MOD = ''
|
||||
CPPPATH_MOD = []
|
||||
CPPDEFINES_MOD = []
|
||||
@ -66,8 +62,6 @@ CPPPATH_MOD += [
|
||||
|
||||
SOURCE_MOD += [
|
||||
'embed/extmod/modtrezorcrypto/rand.c',
|
||||
'embed/lib/buffers.c',
|
||||
'embed/lib/colors.c',
|
||||
'embed/lib/display_utils.c',
|
||||
'embed/lib/error_handling.c',
|
||||
'embed/lib/flash_utils.c',
|
||||
@ -81,22 +75,12 @@ SOURCE_MOD += [
|
||||
'embed/lib/mini_printf.c',
|
||||
'embed/lib/rsod.c',
|
||||
'embed/lib/terminal.c',
|
||||
'embed/lib/gfx_draw.c',
|
||||
'vendor/micropython/lib/uzlib/adler32.c',
|
||||
'vendor/micropython/lib/uzlib/crc32.c',
|
||||
'vendor/micropython/lib/uzlib/tinflate.c',
|
||||
]
|
||||
|
||||
if NEW_RENDERING:
|
||||
CPPDEFINES_MOD += ['NEW_RENDERING']
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/gfx_draw.c',
|
||||
]
|
||||
else:
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/display_draw.c',
|
||||
]
|
||||
|
||||
|
||||
SOURCE_NANOPB = [
|
||||
'vendor/nanopb/pb_common.c',
|
||||
'vendor/nanopb/pb_decode.c',
|
||||
@ -216,9 +200,6 @@ def cargo_build():
|
||||
features.append("bootloader")
|
||||
features.extend(FEATURES_AVAILABLE)
|
||||
|
||||
if NEW_RENDERING:
|
||||
features.append('new_rendering')
|
||||
|
||||
cargo_opts = [
|
||||
f'--target={env.get("ENV")["RUST_TARGET"]}',
|
||||
f'--target-dir=../../build/bootloader/rust',
|
||||
|
@ -6,14 +6,10 @@ import tools, models, ui
|
||||
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
|
||||
CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
|
||||
HW_REVISION = ARGUMENTS.get('HW_REVISION', None)
|
||||
NEW_RENDERING = ARGUMENTS.get('NEW_RENDERING', '1') == '1' or TREZOR_MODEL in ('T3T1',)
|
||||
MODEL_IDENTIFIER = models.get_model_identifier(TREZOR_MODEL)
|
||||
|
||||
FEATURES_WANTED = ["input", "rgb_led", "consumption_mask", "usb", "optiga"]
|
||||
|
||||
if NEW_RENDERING:
|
||||
FEATURES_WANTED.append("new_rendering")
|
||||
|
||||
CCFLAGS_MOD = ''
|
||||
CPPPATH_MOD = []
|
||||
CPPDEFINES_MOD = []
|
||||
@ -61,7 +57,6 @@ CPPPATH_MOD += [
|
||||
]
|
||||
SOURCE_MOD += [
|
||||
'embed/extmod/modtrezorcrypto/rand.c',
|
||||
'embed/lib/colors.c',
|
||||
'embed/lib/display_utils.c',
|
||||
'embed/lib/error_handling.c',
|
||||
'embed/lib/flash_utils.c',
|
||||
@ -75,23 +70,12 @@ SOURCE_MOD += [
|
||||
'embed/lib/mini_printf.c',
|
||||
'embed/lib/rsod.c',
|
||||
'embed/lib/terminal.c',
|
||||
'embed/lib/gfx_draw.c',
|
||||
'vendor/micropython/lib/uzlib/adler32.c',
|
||||
'vendor/micropython/lib/uzlib/crc32.c',
|
||||
'vendor/micropython/lib/uzlib/tinflate.c',
|
||||
]
|
||||
|
||||
|
||||
if NEW_RENDERING:
|
||||
CPPDEFINES_MOD += ['NEW_RENDERING']
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/gfx_draw.c',
|
||||
]
|
||||
else:
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/display_draw.c',
|
||||
]
|
||||
|
||||
|
||||
SOURCE_NANOPB = [
|
||||
'vendor/nanopb/pb_common.c',
|
||||
'vendor/nanopb/pb_decode.c',
|
||||
|
@ -6,7 +6,6 @@ import tools, models, ui
|
||||
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
|
||||
CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
|
||||
HW_REVISION = 'emulator'
|
||||
NEW_RENDERING = ARGUMENTS.get('NEW_RENDERING', '1') == '1' or TREZOR_MODEL in ('T3T1',)
|
||||
|
||||
if not models.has_emulator(TREZOR_MODEL):
|
||||
# skip bootloader build
|
||||
@ -22,9 +21,6 @@ if not models.has_emulator(TREZOR_MODEL):
|
||||
|
||||
FEATURES_WANTED = ["input", "rgb_led", "dma2d", "optiga"]
|
||||
|
||||
if NEW_RENDERING:
|
||||
FEATURES_WANTED.append("new_rendering")
|
||||
|
||||
CCFLAGS_MOD = ''
|
||||
CPPPATH_MOD = []
|
||||
CPPDEFINES_HAL = []
|
||||
@ -72,7 +68,6 @@ CPPPATH_MOD += [
|
||||
|
||||
SOURCE_MOD += [
|
||||
'embed/extmod/modtrezorcrypto/rand.c',
|
||||
'embed/lib/colors.c',
|
||||
'embed/lib/display_utils.c',
|
||||
'embed/lib/error_handling.c',
|
||||
'embed/lib/flash_utils.c',
|
||||
@ -86,22 +81,13 @@ SOURCE_MOD += [
|
||||
'embed/lib/mini_printf.c',
|
||||
'embed/lib/rsod.c',
|
||||
'embed/lib/terminal.c',
|
||||
'embed/lib/gfx_draw.c',
|
||||
'vendor/micropython/lib/uzlib/adler32.c',
|
||||
'vendor/micropython/lib/uzlib/crc32.c',
|
||||
'vendor/micropython/lib/uzlib/tinflate.c',
|
||||
'vendor/trezor-storage/flash_area.c',
|
||||
]
|
||||
|
||||
if NEW_RENDERING:
|
||||
CPPDEFINES_MOD += ['NEW_RENDERING']
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/gfx_draw.c',
|
||||
]
|
||||
else:
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/display_draw.c',
|
||||
]
|
||||
|
||||
SOURCE_NANOPB = [
|
||||
'vendor/nanopb/pb_common.c',
|
||||
'vendor/nanopb/pb_decode.c',
|
||||
@ -131,18 +117,9 @@ SOURCE_TREZORHAL = [
|
||||
'embed/trezorhal/unix/systimer.c',
|
||||
'embed/trezorhal/unix/unit_properties.c',
|
||||
'embed/trezorhal/unix/usb.c',
|
||||
'embed/trezorhal/unix/display_driver.c',
|
||||
]
|
||||
|
||||
if NEW_RENDERING:
|
||||
SOURCE_TREZORHAL += [
|
||||
'embed/trezorhal/unix/display_driver.c',
|
||||
'embed/trezorhal/xdisplay_legacy.c',
|
||||
]
|
||||
else:
|
||||
SOURCE_TREZORHAL += [
|
||||
'embed/trezorhal/unix/display-unix.c',
|
||||
]
|
||||
|
||||
SOURCE_UNIX = [
|
||||
'embed/unix/profile.c',
|
||||
]
|
||||
@ -238,9 +215,6 @@ RUST_LIBPATH = f'{RUST_LIBDIR}/lib{RUST_LIB}.a'
|
||||
def cargo_build():
|
||||
features = []
|
||||
|
||||
if NEW_RENDERING:
|
||||
features.append('new_rendering')
|
||||
|
||||
features.extend(RUST_UI_FEATURES)
|
||||
features.append("ui")
|
||||
features.append("bootloader")
|
||||
|
@ -15,7 +15,6 @@ PYOPT = ARGUMENTS.get('PYOPT', '1')
|
||||
DISABLE_OPTIGA = ARGUMENTS.get('DISABLE_OPTIGA', '0') == '1'
|
||||
HW_REVISION = ARGUMENTS.get('HW_REVISION', None)
|
||||
THP = ARGUMENTS.get('THP', '0') == '1' # Trezor-Host Protocol
|
||||
NEW_RENDERING = ARGUMENTS.get('NEW_RENDERING', '1') == '1'
|
||||
MODEL_IDENTIFIER = models.get_model_identifier(TREZOR_MODEL)
|
||||
BENCHMARK = ARGUMENTS.get('BENCHMARK', '0') == '1'
|
||||
|
||||
@ -32,8 +31,6 @@ FEATURE_FLAGS = {
|
||||
FEATURES_WANTED = ["input", "sbu", "sd_card", "rgb_led", "dma2d", "consumption_mask", "usb" ,"optiga", "haptic"]
|
||||
if DISABLE_OPTIGA and PYOPT == '0':
|
||||
FEATURES_WANTED.remove("optiga")
|
||||
if NEW_RENDERING:
|
||||
FEATURES_WANTED.append("new_rendering")
|
||||
|
||||
CCFLAGS_MOD = ''
|
||||
CPPPATH_MOD = []
|
||||
@ -197,8 +194,6 @@ CPPPATH_MOD += [
|
||||
]
|
||||
SOURCE_MOD += [
|
||||
'embed/extmod/modtrezorui/modtrezorui.c',
|
||||
'embed/lib/buffers.c',
|
||||
'embed/lib/colors.c',
|
||||
'embed/lib/display_utils.c',
|
||||
'embed/lib/error_handling.c',
|
||||
'embed/lib/fonts/font_bitmap.c',
|
||||
@ -212,22 +207,12 @@ SOURCE_MOD += [
|
||||
'embed/lib/rsod.c',
|
||||
'embed/lib/terminal.c',
|
||||
'embed/lib/translations.c',
|
||||
'embed/lib/gfx_draw.c',
|
||||
'vendor/micropython/lib/uzlib/adler32.c',
|
||||
'vendor/micropython/lib/uzlib/crc32.c',
|
||||
'vendor/micropython/lib/uzlib/tinflate.c',
|
||||
]
|
||||
|
||||
if NEW_RENDERING:
|
||||
CPPDEFINES_MOD += ['NEW_RENDERING']
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/gfx_draw.c',
|
||||
]
|
||||
else:
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/display_draw.c',
|
||||
]
|
||||
|
||||
|
||||
CPPDEFINES_MOD += [
|
||||
'TRANSLATIONS',
|
||||
'FANCY_FATAL_ERROR',
|
||||
@ -760,10 +745,6 @@ def cargo_build():
|
||||
features.append('ui')
|
||||
features.append('translations')
|
||||
|
||||
|
||||
if NEW_RENDERING:
|
||||
features.append('new_rendering')
|
||||
|
||||
if PYOPT == '0':
|
||||
features.append('debug')
|
||||
features.append('ui_debug')
|
||||
|
@ -15,8 +15,6 @@ PYOPT = ARGUMENTS.get('PYOPT', '1')
|
||||
DISABLE_OPTIGA = ARGUMENTS.get('DISABLE_OPTIGA', '0') == '1'
|
||||
HW_REVISION = ARGUMENTS.get('HW_REVISION', None)
|
||||
THP = ARGUMENTS.get('THP', '0') == '1' # Trezor-Host Protocol
|
||||
NEW_RENDERING = ARGUMENTS.get('NEW_RENDERING', '1') == '1' or TREZOR_MODEL in ('T3T1',)
|
||||
|
||||
|
||||
FEATURE_FLAGS = {
|
||||
"RDI": True,
|
||||
@ -28,8 +26,6 @@ FEATURE_FLAGS = {
|
||||
FEATURES_WANTED = ["input", "sbu", "sd_card", "rgb_led", "dma2d", "consumption_mask", "usb" ,"optiga", "haptic"]
|
||||
if DISABLE_OPTIGA and PYOPT == '0':
|
||||
FEATURES_WANTED.remove("optiga")
|
||||
if NEW_RENDERING:
|
||||
FEATURES_WANTED.append("new_rendering")
|
||||
|
||||
CCFLAGS_MOD = ''
|
||||
CPPPATH_MOD = []
|
||||
@ -184,8 +180,6 @@ if FEATURE_FLAGS["AES_GCM"]:
|
||||
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/bl_check.c',
|
||||
# 'embed/lib/buffers.c',
|
||||
# 'embed/lib/colors.c',
|
||||
# 'embed/lib/display_utils.c',
|
||||
'embed/lib/error_handling.c',
|
||||
'embed/lib/fonts/font_bitmap.c',
|
||||
@ -199,23 +193,13 @@ SOURCE_MOD += [
|
||||
'embed/lib/rsod.c',
|
||||
'embed/lib/terminal.c',
|
||||
'embed/lib/translations.c',
|
||||
'embed/lib/gfx_draw.c',
|
||||
'embed/extmod/modtrezorcrypto/rand.c',
|
||||
'vendor/micropython/lib/uzlib/adler32.c',
|
||||
'vendor/micropython/lib/uzlib/crc32.c',
|
||||
'vendor/micropython/lib/uzlib/tinflate.c',
|
||||
]
|
||||
|
||||
if NEW_RENDERING:
|
||||
CPPDEFINES_MOD += ['NEW_RENDERING']
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/gfx_draw.c',
|
||||
]
|
||||
else:
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/display_draw.c',
|
||||
]
|
||||
|
||||
|
||||
CPPDEFINES_MOD += [
|
||||
'TRANSLATIONS',
|
||||
'RSOD_IN_COREAPP',
|
||||
|
@ -8,13 +8,9 @@ CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
|
||||
PRODUCTION = ARGUMENTS.get('PRODUCTION', '0') == '1'
|
||||
BOOTLOADER_DEVEL = ARGUMENTS.get('BOOTLOADER_DEVEL', '0') == '1'
|
||||
HW_REVISION = ARGUMENTS.get('HW_REVISION', None)
|
||||
NEW_RENDERING = ARGUMENTS.get('NEW_RENDERING', '1') == '1'
|
||||
|
||||
FEATURES_WANTED = ["input", "sbu", "sd_card", "rdb_led", "usb", "consumption_mask", "optiga", "haptic"]
|
||||
|
||||
if NEW_RENDERING:
|
||||
FEATURES_WANTED.append("new_rendering")
|
||||
|
||||
CCFLAGS_MOD = ''
|
||||
CPPPATH_MOD = []
|
||||
CPPDEFINES_MOD = [
|
||||
@ -66,7 +62,6 @@ CPPPATH_MOD += [
|
||||
]
|
||||
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/colors.c',
|
||||
'embed/lib/display_utils.c',
|
||||
'embed/lib/error_handling.c',
|
||||
'embed/lib/fonts/font_bitmap.c',
|
||||
@ -80,22 +75,12 @@ SOURCE_MOD += [
|
||||
'embed/lib/rsod.c',
|
||||
'embed/lib/qr-code-generator/qrcodegen.c',
|
||||
'embed/lib/terminal.c',
|
||||
'embed/lib/gfx_draw.c',
|
||||
'vendor/micropython/lib/uzlib/adler32.c',
|
||||
'vendor/micropython/lib/uzlib/crc32.c',
|
||||
'vendor/micropython/lib/uzlib/tinflate.c',
|
||||
]
|
||||
|
||||
|
||||
if NEW_RENDERING:
|
||||
CPPDEFINES_MOD += ['NEW_RENDERING']
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/gfx_draw.c',
|
||||
]
|
||||
else:
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/display_draw.c',
|
||||
]
|
||||
|
||||
ui.init_ui(TREZOR_MODEL, "prodtest", CPPDEFINES_MOD, SOURCE_MOD, RUST_UI_FEATURES)
|
||||
|
||||
env = Environment(
|
||||
|
@ -6,7 +6,6 @@ import tools, models, ui
|
||||
TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
|
||||
CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
|
||||
HW_REVISION = ARGUMENTS.get('HW_REVISION', None)
|
||||
NEW_RENDERING = ARGUMENTS.get('NEW_RENDERING', '1') == '1'
|
||||
|
||||
if TREZOR_MODEL in ('DISC1', 'DISC2'):
|
||||
# skip reflash build
|
||||
@ -21,9 +20,6 @@ if TREZOR_MODEL in ('DISC1', 'DISC2'):
|
||||
|
||||
FEATURES_WANTED = ["input", "sd_card"]
|
||||
|
||||
if NEW_RENDERING:
|
||||
FEATURES_WANTED.append("new_rendering")
|
||||
|
||||
CCFLAGS_MOD = ''
|
||||
CPPPATH_MOD = []
|
||||
CPPDEFINES_MOD = []
|
||||
@ -52,7 +48,6 @@ CPPPATH_MOD += [
|
||||
'vendor/micropython/lib/uzlib',
|
||||
]
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/colors.c',
|
||||
'embed/lib/display_utils.c',
|
||||
'embed/lib/error_handling.c',
|
||||
'embed/lib/fonts/font_bitmap.c',
|
||||
@ -65,23 +60,13 @@ SOURCE_MOD += [
|
||||
'embed/lib/mini_printf.c',
|
||||
'embed/lib/rsod.c',
|
||||
'embed/lib/terminal.c',
|
||||
'embed/lib/gfx_draw.c',
|
||||
'vendor/micropython/lib/uzlib/adler32.c',
|
||||
'vendor/micropython/lib/uzlib/crc32.c',
|
||||
'vendor/micropython/lib/uzlib/tinflate.c',
|
||||
'vendor/trezor-storage/flash_area.c',
|
||||
]
|
||||
|
||||
if NEW_RENDERING:
|
||||
CPPDEFINES_MOD += ['NEW_RENDERING']
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/gfx_draw.c',
|
||||
]
|
||||
else:
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/display_draw.c',
|
||||
]
|
||||
|
||||
|
||||
ui.init_ui(TREZOR_MODEL, "prodtest", CPPDEFINES_MOD, SOURCE_MOD, RUST_UI_FEATURES)
|
||||
|
||||
env = Environment(
|
||||
|
@ -10,7 +10,6 @@ TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T')
|
||||
CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
|
||||
HW_REVISION ='emulator'
|
||||
THP = ARGUMENTS.get('THP', '0') == '1' # Trezor-Host Protocol
|
||||
NEW_RENDERING = ARGUMENTS.get('NEW_RENDERING', '1') == '1'
|
||||
BENCHMARK = ARGUMENTS.get('BENCHMARK', '0') == '1'
|
||||
PYOPT = ARGUMENTS.get('PYOPT', '1')
|
||||
FROZEN = ARGUMENTS.get('TREZOR_EMULATOR_FROZEN', 0)
|
||||
@ -22,8 +21,6 @@ if BENCHMARK and PYOPT != '0':
|
||||
exit(1)
|
||||
|
||||
FEATURES_WANTED = ["input", "sd_card", "dma2d", "optiga", "sbu"]
|
||||
if NEW_RENDERING:
|
||||
FEATURES_WANTED.append("new_rendering")
|
||||
|
||||
if not models.has_emulator(TREZOR_MODEL):
|
||||
# skip unix build
|
||||
@ -208,7 +205,6 @@ CPPPATH_MOD += [
|
||||
]
|
||||
SOURCE_MOD += [
|
||||
'embed/extmod/modtrezorui/modtrezorui.c',
|
||||
'embed/lib/colors.c',
|
||||
'embed/lib/display_utils.c',
|
||||
'embed/lib/error_handling.c',
|
||||
'embed/lib/fonts/font_bitmap.c',
|
||||
@ -222,20 +218,12 @@ SOURCE_MOD += [
|
||||
'embed/lib/rsod.c',
|
||||
'embed/lib/terminal.c',
|
||||
'embed/lib/translations.c',
|
||||
'embed/lib/gfx_draw.c',
|
||||
'vendor/micropython/lib/uzlib/adler32.c',
|
||||
'vendor/micropython/lib/uzlib/crc32.c',
|
||||
'vendor/micropython/lib/uzlib/tinflate.c',
|
||||
]
|
||||
|
||||
if NEW_RENDERING:
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/gfx_draw.c',
|
||||
]
|
||||
else:
|
||||
SOURCE_MOD += [
|
||||
'embed/lib/display_draw.c',
|
||||
]
|
||||
|
||||
CPPDEFINES_MOD += [
|
||||
'TRANSLATIONS',
|
||||
'FANCY_FATAL_ERROR',
|
||||
@ -246,9 +234,6 @@ if FROZEN:
|
||||
if RASPI:
|
||||
CPPDEFINES_MOD += ['TREZOR_EMULATOR_RASPI']
|
||||
|
||||
if NEW_RENDERING:
|
||||
CPPDEFINES_MOD += ['NEW_RENDERING']
|
||||
|
||||
# modtrezorutils
|
||||
SOURCE_MOD += [
|
||||
'embed/extmod/modtrezorutils/modtrezorutils.c',
|
||||
@ -405,6 +390,7 @@ SOURCE_UNIX = [
|
||||
'embed/trezorhal/unix/time_estimate.c',
|
||||
'embed/trezorhal/unix/unit_properties.c',
|
||||
'embed/trezorhal/unix/usb.c',
|
||||
'embed/trezorhal/unix/display_driver.c',
|
||||
'embed/unix/main_main.c',
|
||||
'embed/unix/main.c',
|
||||
'embed/unix/profile.c',
|
||||
@ -415,16 +401,6 @@ SOURCE_UNIX = [
|
||||
'vendor/micropython/shared/runtime/gchelper_generic.c',
|
||||
]
|
||||
|
||||
if NEW_RENDERING:
|
||||
SOURCE_MOD += [
|
||||
'embed/trezorhal/unix/display_driver.c',
|
||||
'embed/trezorhal/xdisplay_legacy.c',
|
||||
]
|
||||
else:
|
||||
SOURCE_MOD += [
|
||||
'embed/trezorhal/unix/display-unix.c',
|
||||
]
|
||||
|
||||
TRANSLATION_DATA = [
|
||||
"translations/en.json",
|
||||
"translations/order.json",
|
||||
@ -831,9 +807,6 @@ def cargo_build():
|
||||
|
||||
features.extend(FEATURES_AVAILABLE)
|
||||
|
||||
if NEW_RENDERING:
|
||||
features.append('new_rendering')
|
||||
|
||||
env.get('ENV')['TREZOR_MODEL'] = TREZOR_MODEL
|
||||
|
||||
bindgen_macros = tools.get_bindgen_defines(env.get("CPPDEFINES"), ALLPATHS)
|
||||
|
@ -22,12 +22,11 @@
|
||||
|
||||
#include "board_capabilities.h"
|
||||
#include "bootutils.h"
|
||||
#include "buffers.h"
|
||||
#include "compiler_traits.h"
|
||||
#include "display.h"
|
||||
#include "display_draw.h"
|
||||
#include "flash.h"
|
||||
#include "flash_utils.h"
|
||||
#include "gfx_draw.h"
|
||||
#include "image.h"
|
||||
#include "mpu.h"
|
||||
#include "pvd.h"
|
||||
@ -50,11 +49,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef USE_DMA2D
|
||||
#ifdef NEW_RENDERING
|
||||
#include "dma2d_bitblt.h"
|
||||
#else
|
||||
#include "dma2d.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "memzero.h"
|
||||
@ -104,7 +99,8 @@ struct BoardCapabilities capabilities
|
||||
.terminator_length = 0};
|
||||
|
||||
// we use SRAM as SD card read buffer (because DMA can't access the CCMRAM)
|
||||
BUFFER_SECTION uint32_t sdcard_buf[BOOTLOADER_MAXSIZE / sizeof(uint32_t)];
|
||||
__attribute__((section(".buf")))
|
||||
uint32_t sdcard_buf[BOOTLOADER_MAXSIZE / sizeof(uint32_t)];
|
||||
|
||||
#if defined USE_SD_CARD
|
||||
static uint32_t check_sdcard(void) {
|
||||
@ -182,7 +178,7 @@ static uint32_t check_sdcard(void) {
|
||||
static void progress_callback(int pos, int len) { term_printf("."); }
|
||||
|
||||
static secbool copy_sdcard(void) {
|
||||
display_backlight(255);
|
||||
display_set_backlight(255);
|
||||
|
||||
term_printf("Trezor Boardloader\n");
|
||||
term_printf("==================\n\n");
|
||||
@ -269,7 +265,7 @@ int main(void) {
|
||||
|
||||
display_init(DISPLAY_RESET_CONTENT);
|
||||
|
||||
display_clear();
|
||||
gfx_clear();
|
||||
display_refresh();
|
||||
|
||||
#if defined USE_SD_CARD
|
||||
|
@ -20,9 +20,7 @@
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "bootui.h"
|
||||
#include "colors.h"
|
||||
#include "display.h"
|
||||
#include "display_draw.h"
|
||||
#include "display_utils.h"
|
||||
#include "fonts/fonts.h"
|
||||
#include "mini_printf.h"
|
||||
@ -68,83 +66,10 @@ static void format_ver(const char *format, uint32_t version, char *buffer,
|
||||
|
||||
// boot UI
|
||||
|
||||
#ifndef NEW_RENDERING
|
||||
static uint16_t boot_background;
|
||||
#endif
|
||||
|
||||
static bool initial_setup = true;
|
||||
|
||||
void ui_set_initial_setup(bool initial) { initial_setup = initial; }
|
||||
|
||||
#ifndef NEW_RENDERING
|
||||
static void ui_screen_boot_old(const vendor_header *const vhdr,
|
||||
const image_header *const hdr) {
|
||||
const int show_string = ((vhdr->vtrust & VTRUST_NO_STRING) == 0);
|
||||
if ((vhdr->vtrust & VTRUST_NO_RED) != 0) {
|
||||
boot_background = COLOR_BLACK;
|
||||
} else {
|
||||
boot_background = COLOR_BL_FAIL;
|
||||
}
|
||||
|
||||
const uint8_t *vimg = vhdr->vimg;
|
||||
const uint32_t fw_version = hdr->version;
|
||||
|
||||
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, boot_background);
|
||||
|
||||
#if !defined TREZOR_MODEL_R && !defined TREZOR_MODEL_T3B1
|
||||
int image_top = show_string ? 30 : (DISPLAY_RESY - 120) / 2;
|
||||
// check whether vendor image is 120x120
|
||||
if (memcmp(vimg, "TOIF\x78\x00\x78\x00", 8) == 0) {
|
||||
uint32_t datalen = TOIF_LENGTH(vimg);
|
||||
display_image((DISPLAY_RESX - 120) / 2, image_top, vimg, datalen);
|
||||
}
|
||||
|
||||
if (show_string) {
|
||||
char ver_str[64];
|
||||
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 5 - 50, vhdr->vstr,
|
||||
vhdr->vstr_len, FONT_NORMAL, COLOR_BL_BG,
|
||||
boot_background);
|
||||
format_ver("%d.%d.%d", fw_version, ver_str, sizeof(ver_str));
|
||||
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 5 - 25, ver_str, -1,
|
||||
FONT_NORMAL, COLOR_BL_BG, boot_background);
|
||||
}
|
||||
#else
|
||||
// check whether vendor image is 24x24
|
||||
if (memcmp(vimg, "TOIG\x18\x00\x18\x00", 8) == 0) {
|
||||
uint32_t datalen = TOIF_LENGTH(vimg);
|
||||
display_icon((DISPLAY_RESX - 22) / 2, 0, vimg, datalen, COLOR_BL_BG,
|
||||
boot_background);
|
||||
}
|
||||
|
||||
if (show_string) {
|
||||
char ver_str[64];
|
||||
display_text_center(DISPLAY_RESX / 2, 36, vhdr->vstr, vhdr->vstr_len,
|
||||
FONT_NORMAL, COLOR_BL_BG, boot_background);
|
||||
format_ver("%d.%d.%d", fw_version, ver_str, sizeof(ver_str));
|
||||
display_text_center(DISPLAY_RESX / 2, 46, ver_str, -1, FONT_NORMAL,
|
||||
COLOR_BL_BG, boot_background);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
display_pixeldata_dirty();
|
||||
display_refresh();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NEW_RENDERING
|
||||
static void ui_screen_boot_wait(int wait_seconds) {
|
||||
char wait_str[32];
|
||||
mini_snprintf(wait_str, sizeof(wait_str), "starting in %d s", wait_seconds);
|
||||
display_bar(0, BOOT_WAIT_Y_TOP, DISPLAY_RESX, BOOT_WAIT_HEIGHT,
|
||||
boot_background);
|
||||
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 5, wait_str, -1,
|
||||
FONT_NORMAL, COLOR_BL_BG, boot_background);
|
||||
display_pixeldata_dirty();
|
||||
display_refresh();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined USE_TOUCH
|
||||
#include "touch.h"
|
||||
|
||||
@ -185,18 +110,6 @@ void ui_click(void) {
|
||||
#error "No input method defined"
|
||||
#endif
|
||||
|
||||
#ifndef NEW_RENDERING
|
||||
static void ui_screen_boot_click(void) {
|
||||
display_bar(0, BOOT_WAIT_Y_TOP, DISPLAY_RESX, BOOT_WAIT_HEIGHT,
|
||||
boot_background);
|
||||
bld_continue_label(boot_background);
|
||||
display_pixeldata_dirty();
|
||||
display_refresh();
|
||||
ui_click();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NEW_RENDERING
|
||||
void ui_screen_boot(const vendor_header *const vhdr,
|
||||
const image_header *const hdr, int wait) {
|
||||
bool show_string = ((vhdr->vtrust & VTRUST_NO_STRING) == 0);
|
||||
@ -208,19 +121,6 @@ void ui_screen_boot(const vendor_header *const vhdr,
|
||||
screen_boot(red_screen, vendor_str, vendor_str_len, hdr->version, vhdr->vimg,
|
||||
vimg_len, wait);
|
||||
}
|
||||
#else // NEW_RENDERING
|
||||
|
||||
void ui_screen_boot(const vendor_header *const vhdr,
|
||||
const image_header *const hdr, int wait) {
|
||||
if (wait == 0) {
|
||||
ui_screen_boot_old(vhdr, hdr);
|
||||
} else if (wait > 0) {
|
||||
ui_screen_boot_wait(wait);
|
||||
} else {
|
||||
ui_screen_boot_click();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// welcome UI
|
||||
|
||||
@ -302,7 +202,4 @@ void ui_screen_install_restricted(void) { screen_install_fail(); }
|
||||
|
||||
void ui_fadein(void) { display_fade(0, BACKLIGHT_NORMAL, 1000); }
|
||||
|
||||
void ui_fadeout(void) {
|
||||
display_fade(BACKLIGHT_NORMAL, 0, 500);
|
||||
display_clear();
|
||||
}
|
||||
void ui_fadeout(void) { display_fade(BACKLIGHT_NORMAL, 0, 500); }
|
||||
|
@ -42,11 +42,7 @@
|
||||
#include "systimer.h"
|
||||
|
||||
#ifdef USE_DMA2D
|
||||
#ifdef NEW_RENDERING
|
||||
#include "dma2d_bitblt.h"
|
||||
#else
|
||||
#include "dma2d.h"
|
||||
#endif
|
||||
#endif
|
||||
#ifdef USE_OPTIGA
|
||||
#include "optiga_hal.h"
|
||||
@ -342,7 +338,7 @@ void real_jump_to_firmware(void) {
|
||||
|
||||
#ifdef USE_RESET_TO_BOOT
|
||||
__attribute__((noreturn)) void jump_to_fw_through_reset(void) {
|
||||
display_fade(display_backlight(-1), 0, 200);
|
||||
display_fade(display_get_backlight(), 0, 200);
|
||||
|
||||
reboot_device();
|
||||
}
|
||||
|
@ -17,12 +17,14 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "bootui.h"
|
||||
#include "display.h"
|
||||
#include "display_draw.h"
|
||||
#include "display_utils.h"
|
||||
#include "fonts/fonts.h"
|
||||
#include "gfx_draw.h"
|
||||
#include "icon_done.h"
|
||||
#include "icon_fail.h"
|
||||
#include "icon_install.h"
|
||||
@ -50,19 +52,30 @@
|
||||
|
||||
// welcome UI
|
||||
|
||||
gfx_text_attr_t welcome_text_attr = {
|
||||
.font = FONT_NORMAL,
|
||||
.fg_color = COLOR_WELCOME_FG,
|
||||
.bg_color = COLOR_WELCOME_BG,
|
||||
};
|
||||
|
||||
gfx_text_attr_t normal_text_attr = {
|
||||
.font = FONT_NORMAL,
|
||||
.fg_color = COLOR_BL_FG,
|
||||
.bg_color = COLOR_BL_BG,
|
||||
};
|
||||
|
||||
void ui_screen_welcome_third(void) {
|
||||
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WELCOME_BG);
|
||||
display_text_center(120, 220, "Go to trezor.io/start", -1, FONT_NORMAL,
|
||||
COLOR_WELCOME_FG, COLOR_WELCOME_BG);
|
||||
gfx_draw_bar(gfx_rect_wh(0, 0, DISPLAY_RESX, DISPLAY_RESY), COLOR_WELCOME_BG);
|
||||
gfx_draw_text(gfx_offset(120, 220), "Go to trezor.io/start", -1,
|
||||
&welcome_text_attr, GFX_ALIGN_CENTER);
|
||||
}
|
||||
|
||||
// install UI
|
||||
|
||||
void ui_screen_install_start(void) {
|
||||
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_BL_BG);
|
||||
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24,
|
||||
"Installing firmware", -1, FONT_NORMAL, COLOR_BL_FG,
|
||||
COLOR_BL_BG);
|
||||
gfx_draw_bar(gfx_rect_wh(0, 0, DISPLAY_RESX, DISPLAY_RESY), COLOR_BL_BG);
|
||||
gfx_draw_text(gfx_offset(DISPLAY_RESX / 2, DISPLAY_RESY - 24),
|
||||
"Installing firmware", -1, &normal_text_attr, GFX_ALIGN_CENTER);
|
||||
}
|
||||
|
||||
void ui_screen_install_progress_erase(int pos, int len) {}
|
||||
@ -72,9 +85,9 @@ void ui_screen_install_progress_upload(int pos) {}
|
||||
// wipe UI
|
||||
|
||||
void ui_screen_wipe(void) {
|
||||
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_BL_BG);
|
||||
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, "Wiping device", -1,
|
||||
FONT_NORMAL, COLOR_BL_FG, COLOR_BL_BG);
|
||||
gfx_draw_bar(gfx_rect_wh(0, 0, DISPLAY_RESX, DISPLAY_RESY), COLOR_BL_BG);
|
||||
gfx_draw_text(gfx_offset(DISPLAY_RESX / 2, DISPLAY_RESY - 24),
|
||||
"Wiping device", -1, &normal_text_attr, GFX_ALIGN_CENTER);
|
||||
}
|
||||
|
||||
void ui_screen_wipe_progress(int pos, int len) {}
|
||||
@ -92,29 +105,27 @@ void ui_screen_done(int restart_seconds, secbool full_redraw) {
|
||||
str = "Done! Unplug the device.";
|
||||
}
|
||||
if (sectrue == full_redraw) {
|
||||
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_BL_BG);
|
||||
gfx_draw_bar(gfx_rect_wh(0, 0, DISPLAY_RESX, DISPLAY_RESY), COLOR_BL_BG);
|
||||
}
|
||||
if (secfalse == full_redraw) {
|
||||
display_bar(0, DISPLAY_RESY - 24 - 18, 240, 23, COLOR_BL_BG);
|
||||
gfx_draw_bar(gfx_rect_wh(0, DISPLAY_RESY - 24 - 18, 240, 23), COLOR_BL_BG);
|
||||
}
|
||||
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, str, -1, FONT_NORMAL,
|
||||
COLOR_BL_FG, COLOR_BL_BG);
|
||||
|
||||
gfx_draw_text(gfx_offset(DISPLAY_RESX / 2, DISPLAY_RESY - 24), str, -1,
|
||||
&normal_text_attr, GFX_ALIGN_CENTER);
|
||||
}
|
||||
|
||||
// error UI
|
||||
|
||||
void ui_screen_fail(void) {
|
||||
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_BL_BG);
|
||||
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24,
|
||||
"Failed! Please, reconnect.", -1, FONT_NORMAL,
|
||||
COLOR_BL_FG, COLOR_BL_BG);
|
||||
gfx_draw_bar(gfx_rect_wh(0, 0, DISPLAY_RESX, DISPLAY_RESY), COLOR_BL_BG);
|
||||
gfx_draw_text(gfx_offset(DISPLAY_RESX / 2, DISPLAY_RESY - 24),
|
||||
"Failed! Please, reconnect.", -1, &normal_text_attr,
|
||||
GFX_ALIGN_CENTER);
|
||||
}
|
||||
|
||||
// general functions
|
||||
|
||||
void ui_fadein(void) { display_fade(0, BACKLIGHT_NORMAL, 1000); }
|
||||
|
||||
void ui_fadeout(void) {
|
||||
display_fade(BACKLIGHT_NORMAL, 0, 500);
|
||||
display_clear();
|
||||
}
|
||||
void ui_fadeout(void) { display_fade(BACKLIGHT_NORMAL, 0, 500); }
|
||||
|
@ -23,9 +23,9 @@
|
||||
#include <sys/types.h>
|
||||
#include "bootutils.h"
|
||||
#include "display.h"
|
||||
#include "display_draw.h"
|
||||
#include "flash.h"
|
||||
#include "flash_otp.h"
|
||||
#include "gfx_draw.h"
|
||||
#include "image.h"
|
||||
#include "mini_printf.h"
|
||||
#include "mpu.h"
|
||||
@ -194,7 +194,7 @@ int main(void) {
|
||||
ensure_bootloader_min_version();
|
||||
#endif
|
||||
|
||||
display_clear();
|
||||
gfx_clear();
|
||||
|
||||
const image_header *hdr = NULL;
|
||||
vendor_header vhdr;
|
||||
|
@ -17,6 +17,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_types.h>
|
||||
|
||||
#include "button.h"
|
||||
@ -106,7 +107,7 @@ STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref,
|
||||
const uint32_t ey = evt & 0xFFFU; // y position
|
||||
uint32_t exr; // rotated x position
|
||||
uint32_t eyr; // rotated y position
|
||||
switch (display_orientation(-1)) {
|
||||
switch (display_get_orientation()) {
|
||||
case 90:
|
||||
exr = ey;
|
||||
eyr = DISPLAY_RESX - ex;
|
||||
@ -149,7 +150,7 @@ STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref,
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
|
||||
uint32_t etype = (evt >> 24) & 0x3U; // button down/up
|
||||
uint32_t en = evt & 0xFFFF; // button number
|
||||
if (display_orientation(-1) == 180) {
|
||||
if (display_get_orientation() == 180) {
|
||||
en = (en == BTN_LEFT) ? BTN_RIGHT : BTN_LEFT;
|
||||
}
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(etype);
|
||||
|
@ -17,9 +17,11 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_model.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "display_draw.h"
|
||||
#include "fonts/fonts.h"
|
||||
#include "gfx_draw.h"
|
||||
|
||||
/// class Display:
|
||||
/// """
|
||||
@ -70,7 +72,7 @@ STATIC mp_obj_t mod_trezorui_Display_bar(size_t n_args, const mp_obj_t *args) {
|
||||
mp_int_t w = mp_obj_get_int(args[3]);
|
||||
mp_int_t h = mp_obj_get_int(args[4]);
|
||||
uint16_t c = mp_obj_get_int(args[5]);
|
||||
display_bar(x, y, w, h, c);
|
||||
gfx_draw_bar(gfx_rect(x, y, w, h), gfx_color16_to_color(c));
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_trezorui_Display_bar_obj, 6, 6,
|
||||
@ -91,9 +93,9 @@ STATIC mp_obj_t mod_trezorui_Display_orientation(size_t n_args,
|
||||
if (deg != 0 && deg != 90 && deg != 180 && deg != 270) {
|
||||
mp_raise_ValueError("Value must be 0, 90, 180 or 270");
|
||||
}
|
||||
deg = display_orientation(deg);
|
||||
deg = display_set_orientation(deg);
|
||||
} else {
|
||||
deg = display_orientation(-1);
|
||||
deg = display_get_orientation();
|
||||
}
|
||||
return MP_OBJ_NEW_SMALL_INT(deg);
|
||||
}
|
||||
@ -114,9 +116,9 @@ STATIC mp_obj_t mod_trezorui_Display_backlight(size_t n_args,
|
||||
if (val < 0 || val > 255) {
|
||||
mp_raise_ValueError("Value must be between 0 and 255");
|
||||
}
|
||||
val = display_backlight(val);
|
||||
val = display_set_backlight(val);
|
||||
} else {
|
||||
val = display_backlight(-1);
|
||||
val = display_get_backlight();
|
||||
}
|
||||
return MP_OBJ_NEW_SMALL_INT(val);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "button.h"
|
||||
#include "consumption_mask.h"
|
||||
#include "display.h"
|
||||
#include "dma2d.h"
|
||||
#include "dma2d_bitblt.h"
|
||||
#include "entropy.h"
|
||||
#include "haptic.h"
|
||||
#include "image.h"
|
||||
|
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "buffers.h"
|
||||
#include "fonts/fonts.h"
|
||||
#include "memzero.h"
|
||||
|
||||
const int32_t text_buffer_height = FONT_MAX_HEIGHT;
|
||||
const int32_t buffer_width = DISPLAY_RESX;
|
||||
|
||||
#define CONCAT_(a, b) a##b
|
||||
#define CONCAT(a, b) CONCAT_(a, b)
|
||||
|
||||
#define CONCAT3_(a, b, c) a##b##c
|
||||
#define CONCAT3(a, b, c) CONCAT3_(a, b, c)
|
||||
|
||||
#define STRUCT(name) CONCAT3(buffers_, name, _t)
|
||||
#define TYPE(name) CONCAT3(buffer_, name, _t)
|
||||
#define FUNCTION(name) CONCAT(buffers_get_, name)
|
||||
#define FUNCTION_FREE(name) CONCAT(buffers_free_, name)
|
||||
#define VARNAME(name) CONCAT(buffers_, name)
|
||||
|
||||
#define BUFFER(section, name, count) \
|
||||
typedef struct { \
|
||||
TYPE(name) buffers[count]; \
|
||||
uint8_t allocated[count]; \
|
||||
} STRUCT(name); \
|
||||
section STRUCT(name) VARNAME(name); \
|
||||
\
|
||||
TYPE(name) * FUNCTION(name)(bool clear) { \
|
||||
int idx = -1; \
|
||||
for (int i = 0; i < (count); i++) { \
|
||||
if (VARNAME(name).allocated[i] == 0) { \
|
||||
idx = i; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
if (idx < 0) { \
|
||||
return NULL; \
|
||||
} \
|
||||
if (clear) { \
|
||||
memzero(&VARNAME(name).buffers[idx], \
|
||||
sizeof(VARNAME(name).buffers[idx])); \
|
||||
} \
|
||||
VARNAME(name).allocated[idx] = 1; \
|
||||
return &VARNAME(name).buffers[idx]; \
|
||||
} \
|
||||
void FUNCTION_FREE(name)(TYPE(name) * buffer) { \
|
||||
if (buffer == NULL) { \
|
||||
return; \
|
||||
} \
|
||||
for (uint16_t i = 0; i < (count); i++) { \
|
||||
if (buffer == &VARNAME(name).buffers[i]) { \
|
||||
VARNAME(name).allocated[i] = 0; \
|
||||
return; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
BUFFER(BUFFER_SECTION, line_16bpp, 3);
|
||||
BUFFER(BUFFER_SECTION, line_4bpp, 3);
|
||||
BUFFER(BUFFER_SECTION, text, 1);
|
||||
BUFFER(NODMA_BUFFER_SECTION, jpeg, 1);
|
||||
BUFFER(NODMA_BUFFER_SECTION, jpeg_work, 1);
|
||||
BUFFER(NODMA_BUFFER_SECTION, blurring, 1);
|
||||
BUFFER(NODMA_BUFFER_SECTION, blurring_totals, 1);
|
@ -1,110 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _BUFFERS_H
|
||||
#define _BUFFERS_H
|
||||
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_types.h>
|
||||
|
||||
#define BUFFER_PIXELS DISPLAY_RESX
|
||||
|
||||
#define TEXT_BUFFER_HEIGHT 36
|
||||
|
||||
#if TEXT_BUFFER_HEIGHT < FONT_MAX_HEIGHT
|
||||
#error Text buffer height is too small, please adjust to match used fonts
|
||||
#endif
|
||||
|
||||
#define LINE_BUFFER_16BPP_SIZE (BUFFER_PIXELS * 2)
|
||||
#define LINE_BUFFER_4BPP_SIZE (BUFFER_PIXELS / 2)
|
||||
#define TEXT_BUFFER_SIZE ((BUFFER_PIXELS * TEXT_BUFFER_HEIGHT) / 2)
|
||||
#define JPEG_BUFFER_SIZE (BUFFER_PIXELS * 16)
|
||||
|
||||
// 3100 is needed according to tjpgd docs,
|
||||
// 256 because we need non overlapping memory in rust
|
||||
// 6 << 10 is for huffman decoding table
|
||||
// 1000 bytes reserve, as we discovered that we are running out of memory
|
||||
// sometimes
|
||||
#define JPEG_WORK_SIZE (3100 + 256 + (6 << 10) + 1000)
|
||||
|
||||
#if defined BOOTLOADER || defined BOARDLOADER
|
||||
#define BUFFER_SECTION __attribute__((section(".buf")))
|
||||
#else
|
||||
#define BUFFER_SECTION
|
||||
#endif
|
||||
|
||||
#if defined BOOTLOADER || defined TREZOR_EMULATOR
|
||||
#define NODMA_BUFFER_SECTION
|
||||
#else
|
||||
#define NODMA_BUFFER_SECTION __attribute__((section(".no_dma_buffers")))
|
||||
#endif
|
||||
|
||||
typedef __attribute__((aligned(4))) struct {
|
||||
uint8_t buffer[LINE_BUFFER_16BPP_SIZE];
|
||||
} buffer_line_16bpp_t;
|
||||
|
||||
typedef __attribute__((aligned(4))) struct {
|
||||
uint8_t buffer[LINE_BUFFER_4BPP_SIZE];
|
||||
} buffer_line_4bpp_t;
|
||||
|
||||
typedef __attribute__((aligned(4))) struct {
|
||||
uint8_t buffer[TEXT_BUFFER_SIZE];
|
||||
} buffer_text_t;
|
||||
|
||||
typedef __attribute__((aligned(4))) struct {
|
||||
uint16_t buffer[JPEG_BUFFER_SIZE];
|
||||
} buffer_jpeg_t;
|
||||
|
||||
typedef __attribute__((aligned(4))) struct {
|
||||
uint8_t buffer[JPEG_WORK_SIZE];
|
||||
} buffer_jpeg_work_t;
|
||||
|
||||
typedef __attribute__((aligned(4))) struct {
|
||||
uint16_t buffer[10][3][BUFFER_PIXELS];
|
||||
} buffer_blurring_t;
|
||||
|
||||
typedef __attribute__((aligned(4))) struct {
|
||||
uint16_t buffer[3][BUFFER_PIXELS];
|
||||
} buffer_blurring_totals_t;
|
||||
|
||||
extern const int32_t text_buffer_height;
|
||||
extern const int32_t buffer_width;
|
||||
|
||||
buffer_line_16bpp_t* buffers_get_line_16bpp(bool clear);
|
||||
void buffers_free_line_16bpp(buffer_line_16bpp_t* buffer);
|
||||
|
||||
buffer_line_4bpp_t* buffers_get_line_4bpp(bool clear);
|
||||
void buffers_free_line_4bpp(buffer_line_4bpp_t* buffer);
|
||||
|
||||
buffer_text_t* buffers_get_text(bool clear);
|
||||
void buffers_free_text(buffer_text_t* buffer);
|
||||
|
||||
buffer_jpeg_t* buffers_get_jpeg(bool clear);
|
||||
void buffers_free_jpeg(buffer_jpeg_t* buffer);
|
||||
|
||||
buffer_jpeg_work_t* buffers_get_jpeg_work(bool clear);
|
||||
void buffers_free_jpeg_work(buffer_jpeg_work_t* buffer);
|
||||
|
||||
buffer_blurring_t* buffers_get_blurring(bool clear);
|
||||
void buffers_free_blurring(buffer_blurring_t* buffer);
|
||||
|
||||
buffer_blurring_totals_t* buffers_get_blurring_totals(bool clear);
|
||||
void buffers_free_blurring_totals(buffer_blurring_totals_t* buffer);
|
||||
|
||||
#endif // _BUFFERS_H
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "colors.h"
|
||||
|
||||
uint32_t rgb565_to_rgb888(uint16_t color) {
|
||||
uint32_t res = 0;
|
||||
res |= ((((((uint32_t)color & 0xF800) >> 11) * 527) + 23) >> 6) << 16;
|
||||
res |= ((((((uint32_t)color & 0x07E0) >> 5) * 259) + 33) >> 6) << 8;
|
||||
res |= ((((((uint32_t)color & 0x001F) >> 0) * 527) + 23) >> 6) << 0;
|
||||
res |= 0xFF000000;
|
||||
return res;
|
||||
}
|
||||
|
||||
uint32_t interpolate_rgb888_color(uint32_t color0, uint32_t color1,
|
||||
uint8_t step) {
|
||||
uint32_t cr, cg, cb;
|
||||
cr = (((color0 & 0xFF0000) >> 16) * step +
|
||||
((color1 & 0xFF0000) >> 16) * (15 - step)) /
|
||||
15;
|
||||
cg = (((color0 & 0xFF00) >> 8) * step +
|
||||
((color1 & 0xFF00) >> 8) * (15 - step)) /
|
||||
15;
|
||||
cb = ((color0 & 0x00FF) * step + (color1 & 0x00FF) * (15 - step)) / 15;
|
||||
return (cr << 16) | (cg << 8) | cb | 0xFF000000;
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _COLORS_H
|
||||
#define _COLORS_H
|
||||
|
||||
#include <trezor_types.h>
|
||||
|
||||
#ifdef USE_RGB_COLORS
|
||||
#define RGB16(R, G, B) ((R & 0xF8) << 8) | ((G & 0xFC) << 3) | ((B & 0xF8) >> 3)
|
||||
#endif
|
||||
|
||||
#define COLOR_WHITE 0xFFFF
|
||||
#define COLOR_BLACK 0x0000
|
||||
|
||||
static inline uint16_t interpolate_color(uint16_t color0, uint16_t color1,
|
||||
uint8_t step) {
|
||||
uint8_t cr = 0, cg = 0, cb = 0;
|
||||
cr = (((color0 & 0xF800) >> 11) * step +
|
||||
((color1 & 0xF800) >> 11) * (15 - step)) /
|
||||
15;
|
||||
cg = (((color0 & 0x07E0) >> 5) * step +
|
||||
((color1 & 0x07E0) >> 5) * (15 - step)) /
|
||||
15;
|
||||
cb = ((color0 & 0x001F) * step + (color1 & 0x001F) * (15 - step)) / 15;
|
||||
return (cr << 11) | (cg << 5) | cb;
|
||||
}
|
||||
|
||||
static inline void set_color_table(uint16_t colortable[16], uint16_t fgcolor,
|
||||
uint16_t bgcolor) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
colortable[i] = interpolate_color(fgcolor, bgcolor, i);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t rgb565_to_rgb888(uint16_t color);
|
||||
|
||||
uint32_t interpolate_rgb888_color(uint32_t color0, uint32_t color1,
|
||||
uint8_t step);
|
||||
|
||||
#endif //_COLORS_H
|
@ -1,357 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "buffers.h"
|
||||
#include "display.h"
|
||||
#include "display_draw.h"
|
||||
#include "fonts/fonts.h"
|
||||
#include "memzero.h"
|
||||
|
||||
#ifdef USE_DMA2D
|
||||
#include "dma2d.h"
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
int x, y;
|
||||
} DISPLAY_OFFSET;
|
||||
|
||||
// common display functions
|
||||
|
||||
#define CLAMP(x, min, max) (MIN(MAX((x), (min)), (max)))
|
||||
|
||||
static inline void clamp_coords(int x, int y, int w, int h, int *x0, int *y0,
|
||||
int *x1, int *y1) {
|
||||
*x0 = CLAMP(x, 0, DISPLAY_RESX);
|
||||
*y0 = CLAMP(y, 0, DISPLAY_RESY);
|
||||
*x1 = CLAMP(x + w - 1, -1, DISPLAY_RESX - 1);
|
||||
*y1 = CLAMP(y + h - 1, -1, DISPLAY_RESY - 1);
|
||||
}
|
||||
|
||||
void display_clear(void) {
|
||||
#ifdef DISPLAY_EFFICIENT_CLEAR
|
||||
display_efficient_clear();
|
||||
#else
|
||||
const int saved_orientation = display_get_orientation();
|
||||
|
||||
display_reset_state();
|
||||
|
||||
// set MADCTL first so that we can set the window correctly next
|
||||
display_orientation(0);
|
||||
// address the complete frame memory
|
||||
display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1);
|
||||
for (uint32_t i = 0; i < DISPLAY_RESX * DISPLAY_RESY; i++) {
|
||||
// 2 bytes per pixel because we're using RGB 5-6-5 format
|
||||
PIXELDATA(0x0000);
|
||||
}
|
||||
// go back to restricted window
|
||||
display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1);
|
||||
// if valid, go back to the saved orientation
|
||||
display_orientation(saved_orientation);
|
||||
// flag display for refresh
|
||||
#endif
|
||||
display_pixeldata_dirty();
|
||||
}
|
||||
|
||||
void display_bar(int x, int y, int w, int h, uint16_t c) {
|
||||
x += DISPLAY_OFFSET.x;
|
||||
y += DISPLAY_OFFSET.y;
|
||||
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
||||
clamp_coords(x, y, w, h, &x0, &y0, &x1, &y1);
|
||||
display_set_window(x0, y0, x1, y1);
|
||||
for (int i = 0; i < (x1 - x0 + 1) * (y1 - y0 + 1); i++) {
|
||||
PIXELDATA(c);
|
||||
}
|
||||
display_pixeldata_dirty();
|
||||
}
|
||||
|
||||
void display_text_render_buffer(const char *text, int textlen, int font,
|
||||
buffer_text_t *buffer, int text_offset) {
|
||||
// determine text length if not provided
|
||||
if (textlen < 0) {
|
||||
textlen = strlen(text);
|
||||
}
|
||||
|
||||
int x = 0;
|
||||
int max_height = font_max_height(font);
|
||||
int baseline = font_baseline(font);
|
||||
|
||||
// render glyphs
|
||||
font_glyph_iter_t iter = font_glyph_iter_init(font, (uint8_t *)text, textlen);
|
||||
const uint8_t *g = NULL;
|
||||
while (font_next_glyph(&iter, &g)) {
|
||||
const uint8_t w = g[0]; // width
|
||||
const uint8_t h = g[1]; // height
|
||||
const uint8_t adv = g[2]; // advance
|
||||
const uint8_t bearX = g[3]; // bearingX
|
||||
const uint8_t bearY = g[4]; // bearingY
|
||||
#if TREZOR_FONT_BPP == 4
|
||||
uint8_t wa = w + (w & 1);
|
||||
#else
|
||||
uint8_t wa = w;
|
||||
#endif
|
||||
if (wa && h) {
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < wa; i++) {
|
||||
const int a = i + j * wa;
|
||||
#if TREZOR_FONT_BPP == 1
|
||||
const uint8_t c = ((g[5 + a / 8] >> (7 - (a % 8) * 1)) & 0x01) * 15;
|
||||
#elif TREZOR_FONT_BPP == 2
|
||||
const uint8_t c = ((g[5 + a / 4] >> (6 - (a % 4) * 2)) & 0x03) * 5;
|
||||
#elif TREZOR_FONT_BPP == 4
|
||||
const uint8_t c = (g[5 + a / 2] >> ((a % 2) * 4)) & 0x0F;
|
||||
#elif TREZOR_FONT_BPP == 8
|
||||
#error Rendering into buffer not supported when using TREZOR_FONT_BPP = 8
|
||||
// const uint8_t c = g[5 + a / 1] >> 4;
|
||||
#else
|
||||
#error Unsupported TREZOR_FONT_BPP value
|
||||
#endif
|
||||
|
||||
int x_pos = text_offset + i + x + bearX;
|
||||
int y_pos = j + max_height - bearY - baseline;
|
||||
|
||||
if (y_pos < 0) continue;
|
||||
|
||||
if (x_pos >= BUFFER_PIXELS || x_pos < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int buffer_pos = x_pos + y_pos * BUFFER_PIXELS;
|
||||
|
||||
if (buffer_pos < (sizeof(buffer_text_t) * 2)) {
|
||||
int b = buffer_pos / 2;
|
||||
if (buffer_pos % 2) {
|
||||
buffer->buffer[b] |= c << 4;
|
||||
} else {
|
||||
buffer->buffer[b] |= (c);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
x += adv;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FRAMEBUFFER
|
||||
static void display_text_render(int x, int y, const char *text, int textlen,
|
||||
int font, uint16_t fgcolor, uint16_t bgcolor) {
|
||||
// determine text length if not provided
|
||||
if (textlen < 0) {
|
||||
textlen = strlen(text);
|
||||
}
|
||||
|
||||
int total_adv = 0;
|
||||
|
||||
uint32_t *fb = display_get_fb_addr();
|
||||
|
||||
uint16_t colortable[16] = {0};
|
||||
set_color_table(colortable, fgcolor, bgcolor);
|
||||
|
||||
// render glyphs
|
||||
font_glyph_iter_t iter = font_glyph_iter_init(font, (uint8_t *)text, textlen);
|
||||
const uint8_t *g = NULL;
|
||||
while (font_next_glyph(&iter, &g)) {
|
||||
const uint8_t w = g[0]; // width
|
||||
const uint8_t h = g[1]; // height
|
||||
const uint8_t adv = g[2]; // advance
|
||||
const uint8_t bearX = g[3]; // bearingX
|
||||
const uint8_t bearY = g[4]; // bearingY
|
||||
|
||||
#if TREZOR_FONT_BPP == 4
|
||||
uint8_t wa = w + (w & 1);
|
||||
#else
|
||||
uint8_t wa = w;
|
||||
#endif
|
||||
|
||||
if (w && h) {
|
||||
for (int j = 0; j < h; j++) {
|
||||
for (int i = 0; i < wa; i++) {
|
||||
const int a = i + j * wa;
|
||||
#if TREZOR_FONT_BPP == 1
|
||||
const uint8_t c = ((g[5 + a / 8] >> (7 - (a % 8) * 1)) & 0x01) * 15;
|
||||
#elif TREZOR_FONT_BPP == 2
|
||||
const uint8_t c = ((g[5 + a / 4] >> (6 - (a % 4) * 2)) & 0x03) * 5;
|
||||
#elif TREZOR_FONT_BPP == 4
|
||||
const uint8_t c = (g[5 + a / 2] >> ((a % 2) * 4)) & 0x0F;
|
||||
#elif TREZOR_FONT_BPP == 8
|
||||
#error Rendering into buffer not supported when using TREZOR_FONT_BPP = 8
|
||||
// const uint8_t c = g[5 + a / 1] >> 4;
|
||||
#else
|
||||
#error Unsupported TREZOR_FONT_BPP value
|
||||
#endif
|
||||
|
||||
int x_pos = x + i + total_adv + bearX;
|
||||
int y_pos = y + j - bearY;
|
||||
|
||||
if (y_pos < 0) continue;
|
||||
|
||||
if (x_pos >= DISPLAY_FRAMEBUFFER_WIDTH || x_pos < 0 ||
|
||||
y_pos >= DISPLAY_FRAMEBUFFER_HEIGHT || y_pos < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
display_pixel((uint8_t *)fb, x_pos, y_pos, colortable[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
total_adv += adv;
|
||||
}
|
||||
display_pixeldata_dirty();
|
||||
}
|
||||
|
||||
#else
|
||||
static void display_text_render(int x, int y, const char *text, int textlen,
|
||||
int font, uint16_t fgcolor, uint16_t bgcolor) {
|
||||
// determine text length if not provided
|
||||
if (textlen < 0) {
|
||||
textlen = strlen(text);
|
||||
}
|
||||
|
||||
uint16_t colortable[16] = {0};
|
||||
set_color_table(colortable, fgcolor, bgcolor);
|
||||
|
||||
// render glyphs
|
||||
font_glyph_iter_t iter = font_glyph_iter_init(font, (uint8_t *)text, textlen);
|
||||
const uint8_t *g = NULL;
|
||||
while (font_next_glyph(&iter, &g)) {
|
||||
const uint8_t w = g[0]; // width
|
||||
const uint8_t h = g[1]; // height
|
||||
const uint8_t adv = g[2]; // advance
|
||||
const uint8_t bearX = g[3]; // bearingX
|
||||
const uint8_t bearY = g[4]; // bearingY
|
||||
|
||||
#if TREZOR_FONT_BPP == 4
|
||||
uint8_t wa = w + (w & 1);
|
||||
#else
|
||||
uint8_t wa = w;
|
||||
#endif
|
||||
if (wa && h) {
|
||||
const int sx = x + bearX;
|
||||
const int sy = y - bearY;
|
||||
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
||||
clamp_coords(sx, sy, w, h, &x0, &y0, &x1, &y1);
|
||||
display_set_window(x0, y0, x1, y1);
|
||||
for (int j = y0; j <= y1; j++) {
|
||||
for (int i = x0; i <= x1; i++) {
|
||||
const int rx = i - sx;
|
||||
const int ry = j - sy;
|
||||
const int a = rx + ry * wa;
|
||||
#if TREZOR_FONT_BPP == 1
|
||||
const uint8_t c = ((g[5 + a / 8] >> (7 - (a % 8) * 1)) & 0x01) * 15;
|
||||
#elif TREZOR_FONT_BPP == 2
|
||||
const uint8_t c = ((g[5 + a / 4] >> (6 - (a % 4) * 2)) & 0x03) * 5;
|
||||
#elif TREZOR_FONT_BPP == 4
|
||||
const uint8_t c = (g[5 + a / 2] >> ((a % 2) * 4)) & 0x0F;
|
||||
#elif TREZOR_FONT_BPP == 8
|
||||
const uint8_t c = g[5 + a / 1] >> 4;
|
||||
#else
|
||||
#error Unsupported TREZOR_FONT_BPP value
|
||||
#endif
|
||||
PIXELDATA(colortable[c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
x += adv;
|
||||
}
|
||||
display_pixeldata_dirty();
|
||||
}
|
||||
#endif
|
||||
|
||||
void display_text(int x, int y, const char *text, int textlen, int font,
|
||||
uint16_t fgcolor, uint16_t bgcolor) {
|
||||
x += DISPLAY_OFFSET.x;
|
||||
y += DISPLAY_OFFSET.y;
|
||||
display_text_render(x, y, text, textlen, font, fgcolor, bgcolor);
|
||||
}
|
||||
|
||||
void display_text_center(int x, int y, const char *text, int textlen, int font,
|
||||
uint16_t fgcolor, uint16_t bgcolor) {
|
||||
x += DISPLAY_OFFSET.x;
|
||||
y += DISPLAY_OFFSET.y;
|
||||
int w = font_text_width(font, text, textlen);
|
||||
display_text_render(x - w / 2, y, text, textlen, font, fgcolor, bgcolor);
|
||||
}
|
||||
|
||||
void display_text_right(int x, int y, const char *text, int textlen, int font,
|
||||
uint16_t fgcolor, uint16_t bgcolor) {
|
||||
x += DISPLAY_OFFSET.x;
|
||||
y += DISPLAY_OFFSET.y;
|
||||
int w = font_text_width(font, text, textlen);
|
||||
display_text_render(x - w, y, text, textlen, font, fgcolor, bgcolor);
|
||||
}
|
||||
|
||||
#ifdef TREZOR_PRODTEST
|
||||
|
||||
#include "qr-code-generator/qrcodegen.h"
|
||||
#define QR_MAX_VERSION 9
|
||||
|
||||
void display_qrcode(int x, int y, const char *data, uint8_t scale) {
|
||||
if (scale < 1 || scale > 10) return;
|
||||
|
||||
uint8_t codedata[qrcodegen_BUFFER_LEN_FOR_VERSION(QR_MAX_VERSION)] = {0};
|
||||
uint8_t tempdata[qrcodegen_BUFFER_LEN_FOR_VERSION(QR_MAX_VERSION)] = {0};
|
||||
|
||||
int side = 0;
|
||||
if (qrcodegen_encodeText(data, tempdata, codedata, qrcodegen_Ecc_MEDIUM,
|
||||
qrcodegen_VERSION_MIN, QR_MAX_VERSION,
|
||||
qrcodegen_Mask_AUTO, true)) {
|
||||
side = qrcodegen_getSize(codedata);
|
||||
}
|
||||
|
||||
x += DISPLAY_OFFSET.x - (side + 2) * scale / 2;
|
||||
y += DISPLAY_OFFSET.y - (side + 2) * scale / 2;
|
||||
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
||||
clamp_coords(x, y, (side + 2) * scale, (side + 2) * scale, &x0, &y0, &x1,
|
||||
&y1);
|
||||
display_set_window(x0, y0, x1, y1);
|
||||
for (int j = y0; j <= y1; j++) {
|
||||
for (int i = x0; i <= x1; i++) {
|
||||
int rx = (i - x) / scale - 1;
|
||||
int ry = (j - y) / scale - 1;
|
||||
// 1px border
|
||||
if (rx < 0 || ry < 0 || rx >= side || ry >= side) {
|
||||
PIXELDATA(0xFFFF);
|
||||
continue;
|
||||
}
|
||||
if (qrcodegen_getModule(codedata, rx, ry)) {
|
||||
PIXELDATA(0x0000);
|
||||
} else {
|
||||
PIXELDATA(0xFFFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
display_pixeldata_dirty();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void display_offset(int set_xy[2], int *get_x, int *get_y) {
|
||||
if (set_xy) {
|
||||
DISPLAY_OFFSET.x = set_xy[0];
|
||||
DISPLAY_OFFSET.y = set_xy[1];
|
||||
}
|
||||
*get_x = DISPLAY_OFFSET.x;
|
||||
*get_y = DISPLAY_OFFSET.y;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __DISPLAY_DRAW_H__
|
||||
#define __DISPLAY_DRAW_H__
|
||||
|
||||
#include <trezor_types.h>
|
||||
|
||||
#include "buffers.h"
|
||||
#include "colors.h"
|
||||
#include "fonts/fonts.h"
|
||||
|
||||
// provided by common
|
||||
|
||||
void display_clear(void);
|
||||
|
||||
void display_bar(int x, int y, int w, int h, uint16_t c);
|
||||
|
||||
void display_text(int x, int y, const char *text, int textlen, int font,
|
||||
uint16_t fgcolor, uint16_t bgcolor);
|
||||
void display_text_center(int x, int y, const char *text, int textlen, int font,
|
||||
uint16_t fgcolor, uint16_t bgcolor);
|
||||
void display_text_right(int x, int y, const char *text, int textlen, int font,
|
||||
uint16_t fgcolor, uint16_t bgcolor);
|
||||
void display_text_render_buffer(const char *text, int textlen, int font,
|
||||
buffer_text_t *buffer, int text_offset);
|
||||
|
||||
void display_qrcode(int x, int y, const char *data, uint8_t scale);
|
||||
|
||||
void display_offset(int set_xy[2], int *get_x, int *get_y);
|
||||
|
||||
#endif
|
@ -25,9 +25,9 @@
|
||||
void display_fade(int start, int end, int delay) {
|
||||
#ifdef USE_BACKLIGHT
|
||||
for (int i = 0; i < 100; i++) {
|
||||
display_backlight(start + i * (end - start) / 100);
|
||||
display_set_backlight(start + i * (end - start) / 100);
|
||||
hal_delay(delay / 100);
|
||||
}
|
||||
display_backlight(end);
|
||||
display_set_backlight(end);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,144 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "colors.h"
|
||||
#include "display.h"
|
||||
|
||||
typedef enum {
|
||||
DMA2D_LAYER_FG = 1,
|
||||
DMA2D_LAYER_BG = 0,
|
||||
} dma2d_layer_t;
|
||||
|
||||
typedef enum {
|
||||
DMA2D_MODE_CONST = 0,
|
||||
DMA2D_MODE_4BPP,
|
||||
DMA2D_MODE_16BPP,
|
||||
DMA2D_MODE_4BPP_OVER_4BPP,
|
||||
DMA2D_MODE_4BPP_OVER_16BPP,
|
||||
} dma2d_mode_t;
|
||||
|
||||
static uint16_t clut_bg[16];
|
||||
static uint16_t clut_fg[16];
|
||||
static uint16_t dma2d_color;
|
||||
static dma2d_mode_t mode = 0;
|
||||
|
||||
void dma2d_init(void) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void dma2d_init_clut(uint16_t fg, uint16_t bg, dma2d_layer_t layer) {
|
||||
uint16_t* table;
|
||||
if (layer == DMA2D_LAYER_BG) {
|
||||
table = clut_bg;
|
||||
} else {
|
||||
table = clut_fg;
|
||||
}
|
||||
|
||||
set_color_table(table, fg, bg);
|
||||
}
|
||||
|
||||
void dma2d_setup_const(void) { mode = DMA2D_MODE_CONST; }
|
||||
|
||||
void dma2d_setup_4bpp(uint16_t fg_color, uint16_t bg_color) {
|
||||
dma2d_init_clut(fg_color, bg_color, DMA2D_LAYER_FG);
|
||||
mode = DMA2D_MODE_4BPP;
|
||||
}
|
||||
|
||||
void dma2d_setup_16bpp(void) { mode = DMA2D_MODE_16BPP; }
|
||||
|
||||
void dma2d_setup_4bpp_over_16bpp(uint16_t overlay_color) {
|
||||
mode = DMA2D_MODE_4BPP_OVER_16BPP;
|
||||
dma2d_color = overlay_color;
|
||||
}
|
||||
|
||||
void dma2d_setup_4bpp_over_4bpp(uint16_t fg_color, uint16_t bg_color,
|
||||
uint16_t overlay_color) {
|
||||
mode = DMA2D_MODE_4BPP_OVER_4BPP;
|
||||
|
||||
dma2d_color = overlay_color;
|
||||
dma2d_init_clut(fg_color, bg_color, DMA2D_LAYER_BG);
|
||||
}
|
||||
|
||||
void dma2d_start(uint8_t* in_addr, uint8_t* out_addr, int32_t pixels) {
|
||||
(void)out_addr;
|
||||
for (int i = 0; i < pixels; i++) {
|
||||
if (mode == DMA2D_MODE_4BPP) {
|
||||
uint8_t c = ((uint8_t*)in_addr)[i / 2];
|
||||
uint8_t even_pix = c >> 4;
|
||||
uint8_t odd_pix = c & 0xF;
|
||||
PIXELDATA(clut_fg[odd_pix]);
|
||||
PIXELDATA(clut_fg[even_pix]);
|
||||
i++; // wrote two pixels
|
||||
}
|
||||
if (mode == DMA2D_MODE_16BPP) {
|
||||
uint16_t c = ((uint16_t*)in_addr)[i];
|
||||
PIXELDATA(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dma2d_start_const(uint16_t color, uint8_t* out_addr, int32_t pixels) {
|
||||
(void)out_addr;
|
||||
for (int i = 0; i < pixels; i++) {
|
||||
PIXELDATA(color);
|
||||
}
|
||||
}
|
||||
|
||||
void dma2d_start_blend(uint8_t* overlay_addr, uint8_t* bg_addr,
|
||||
uint8_t* out_addr, int32_t pixels) {
|
||||
(void)out_addr;
|
||||
for (int i = 0; i < pixels; i++) {
|
||||
if (mode == DMA2D_MODE_4BPP_OVER_4BPP) {
|
||||
uint8_t c = overlay_addr[i / 2];
|
||||
uint8_t b = bg_addr[i / 2];
|
||||
|
||||
uint8_t odd_overlay_pix = c & 0xF;
|
||||
uint8_t odd_bg_pix = b & 0xF;
|
||||
uint16_t c_odd_bg = clut_bg[odd_bg_pix];
|
||||
uint16_t final_odd_color =
|
||||
interpolate_color(dma2d_color, c_odd_bg, odd_overlay_pix);
|
||||
PIXELDATA(final_odd_color);
|
||||
|
||||
uint8_t even_overlay_pix = c >> 4;
|
||||
uint8_t even_bg_pix = b >> 4;
|
||||
uint16_t c_even_bg = clut_bg[even_bg_pix];
|
||||
uint16_t final_even_color =
|
||||
interpolate_color(dma2d_color, c_even_bg, even_overlay_pix);
|
||||
PIXELDATA(final_even_color);
|
||||
|
||||
i++; // wrote two pixels
|
||||
}
|
||||
if (mode == DMA2D_MODE_4BPP_OVER_16BPP) {
|
||||
uint16_t c = ((uint16_t*)bg_addr)[i];
|
||||
uint8_t o = overlay_addr[i / 2];
|
||||
uint8_t o_pix;
|
||||
if (i % 2 == 0) {
|
||||
o_pix = o & 0xF;
|
||||
} else {
|
||||
o_pix = o >> 4;
|
||||
}
|
||||
uint16_t final_odd_color = interpolate_color(dma2d_color, c, o_pix);
|
||||
PIXELDATA(final_odd_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void dma2d_wait_for_transfer(void) {
|
||||
// done in place when emulating, so no need for wait here
|
||||
}
|
@ -18,7 +18,6 @@
|
||||
*/
|
||||
|
||||
#include "gfx_color.h"
|
||||
#include "colors.h"
|
||||
|
||||
const gfx_color16_t* gfx_color16_gradient_a4(gfx_color_t fg_color,
|
||||
gfx_color_t bg_color) {
|
||||
|
@ -54,6 +54,9 @@ typedef uint32_t gfx_color32_t;
|
||||
#define gfx_color_to_color32(c) (gfx_color16_to_color32(c))
|
||||
#define gfx_color32_to_color(c) (gfx_color32_to_color16(c))
|
||||
#define gfx_color_lum(c) (gfx_color16_lum(c))
|
||||
#define gfx_color_rgb(r, g, b) gfx_color16_rgb(r, g, b)
|
||||
#define COLOR_WHITE 0xFFFF
|
||||
#define COLOR_BLACK 0x0000
|
||||
#elif defined GFX_COLOR_32BIT
|
||||
#define gfx_color_t gfx_color32_t
|
||||
#define gfx_color_to_color16(c) (gfx_color32_to_color16(c))
|
||||
@ -61,6 +64,9 @@ typedef uint32_t gfx_color32_t;
|
||||
#define gfx_color_to_color32(c) (c)
|
||||
#define gfx_color32_to_color(c) (c)
|
||||
#define gfx_color_lum(c) (gfx_color32_lum(c))
|
||||
#define gfx_color_rgb(r, g, b) gfx_color32_rgb(r, g, b)
|
||||
#define COLOR_WHITE 0xFFFFFFFF
|
||||
#define COLOR_BLACK 0xFF000000
|
||||
#else
|
||||
#error "GFX_COLOR_16BIT/32BIT not specified"
|
||||
#endif
|
||||
|
@ -17,10 +17,10 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "display_draw.h"
|
||||
#include "fonts/fonts.h"
|
||||
#include "gfx_draw.h"
|
||||
|
||||
@ -200,11 +200,16 @@ void gfx_draw_bitmap(gfx_rect_t rect, const gfx_bitmap_t* bitmap) {
|
||||
#define GLYPH_DATA(g) ((void*)&(g)[5])
|
||||
|
||||
void gfx_draw_text(gfx_offset_t pos, const char* text, size_t maxlen,
|
||||
const gfx_text_attr_t* attr) {
|
||||
const gfx_text_attr_t* attr, gfx_text_align_t align) {
|
||||
if (text == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (align == GFX_ALIGN_CENTER) {
|
||||
int w = font_text_width(attr->font, text, maxlen);
|
||||
pos = gfx_offset(pos.x - w / 2, pos.y);
|
||||
}
|
||||
|
||||
gfx_bitmap_t bitmap = {
|
||||
.format = GLYPH_FORMAT,
|
||||
.fg_color = attr->fg_color,
|
||||
@ -247,9 +252,12 @@ void gfx_draw_text(gfx_offset_t pos, const char* text, size_t maxlen,
|
||||
#include "qr-code-generator/qrcodegen.h"
|
||||
#define QR_MAX_VERSION 9
|
||||
|
||||
void gfx_draw_qrcode(int x, int y, uint8_t scale, const char* data) {
|
||||
void gfx_draw_qrcode(gfx_offset_t offset, uint8_t scale, const char* data) {
|
||||
if (scale < 1 || scale > 10) return;
|
||||
|
||||
int x = offset.x;
|
||||
int y = offset.y;
|
||||
|
||||
uint8_t codedata[qrcodegen_BUFFER_LEN_FOR_VERSION(QR_MAX_VERSION)] = {0};
|
||||
uint8_t tempdata[qrcodegen_BUFFER_LEN_FOR_VERSION(QR_MAX_VERSION)] = {0};
|
||||
|
||||
@ -288,43 +296,3 @@ void gfx_draw_qrcode(int x, int y, uint8_t scale, const char* data) {
|
||||
}
|
||||
|
||||
#endif // TREZOR_PRODTEST
|
||||
|
||||
// ===============================================================
|
||||
// emulation of legacy functions
|
||||
|
||||
void display_clear(void) { gfx_clear(); }
|
||||
|
||||
void display_bar(int x, int y, int w, int h, uint16_t c) {
|
||||
gfx_draw_bar(gfx_rect_wh(x, y, w, h), gfx_color16_to_color(c));
|
||||
}
|
||||
|
||||
void display_text(int x, int y, const char* text, int textlen, int font,
|
||||
uint16_t fg_color, uint16_t bg_color) {
|
||||
gfx_text_attr_t attr = {
|
||||
.font = font,
|
||||
.fg_color = gfx_color16_to_color(fg_color),
|
||||
.bg_color = gfx_color16_to_color(bg_color),
|
||||
};
|
||||
|
||||
size_t maxlen = textlen < 0 ? UINT32_MAX : textlen;
|
||||
gfx_draw_text(gfx_offset(x, y), text, maxlen, &attr);
|
||||
}
|
||||
|
||||
void display_text_center(int x, int y, const char* text, int textlen, int font,
|
||||
uint16_t fg_color, uint16_t bg_color) {
|
||||
gfx_text_attr_t attr = {
|
||||
.font = font,
|
||||
.fg_color = gfx_color16_to_color(fg_color),
|
||||
.bg_color = gfx_color16_to_color(bg_color),
|
||||
};
|
||||
|
||||
size_t maxlen = textlen < 0 ? UINT32_MAX : textlen;
|
||||
int w = font_text_width(font, text, textlen);
|
||||
gfx_draw_text(gfx_offset(x - w / 2, y), text, maxlen, &attr);
|
||||
}
|
||||
|
||||
#ifdef TREZOR_PRODTEST
|
||||
void display_qrcode(int x, int y, const char* data, uint8_t scale) {
|
||||
gfx_draw_qrcode(x, y, scale, data);
|
||||
}
|
||||
#endif // TREZOR_PRODTEST
|
||||
|
@ -128,6 +128,9 @@ typedef struct {
|
||||
gfx_color_t bg_color;
|
||||
} gfx_text_attr_t;
|
||||
|
||||
// Clears the display with a black color.
|
||||
void gfx_clear(void);
|
||||
|
||||
// Fills a rectangle with a specified color.
|
||||
void gfx_draw_bar(gfx_rect_t rect, gfx_color_t color);
|
||||
|
||||
@ -141,14 +144,22 @@ void gfx_draw_bar(gfx_rect_t rect, gfx_color_t color);
|
||||
// Not all bitmap formats are supported now. Please see the implementation.
|
||||
void gfx_draw_bitmap(gfx_rect_t rect, const gfx_bitmap_t* bitmap);
|
||||
|
||||
// Horizontal alignment of a text
|
||||
typedef enum {
|
||||
GFX_ALIGN_LEFT,
|
||||
GFX_ALIGN_CENTER,
|
||||
} gfx_text_align_t;
|
||||
|
||||
// Draws a text to the specified position.
|
||||
//
|
||||
// `offset` - the most left point on the font baseline
|
||||
// `text` - utf-8 text
|
||||
// `maxlen` - maximum number of characters displayed (use SIZE_MAX when not
|
||||
// specified) `attr` - font & text color
|
||||
// specified)
|
||||
// `attr` - font & text color
|
||||
// `align` - horizontal alignment
|
||||
void gfx_draw_text(gfx_offset_t offset, const char* text, size_t maxlen,
|
||||
const gfx_text_attr_t* attr);
|
||||
const gfx_text_attr_t* attr, gfx_text_align_t align);
|
||||
|
||||
#ifdef TREZOR_PRODTEST
|
||||
// Draws a QR code to the specified position.
|
||||
@ -156,7 +167,7 @@ void gfx_draw_text(gfx_offset_t offset, const char* text, size_t maxlen,
|
||||
// `x`, `y` - center of the QR code
|
||||
// `scale` - size of a single QR code module
|
||||
// `data` - utf-8 text
|
||||
void gfx_draw_qrcode(int x, int y, uint8_t scale, const char* data);
|
||||
void gfx_draw_qrcode(gfx_offset_t offset, uint8_t scale, const char* data);
|
||||
#endif
|
||||
|
||||
#endif // GFX_DRAW_H
|
||||
|
@ -34,13 +34,13 @@
|
||||
#define RSOD_FG_COLOR COLOR_WHITE
|
||||
|
||||
#ifdef USE_RGB_COLORS
|
||||
#define RSOD_BG_COLOR RGB16(0x7F, 0x00, 0x00)
|
||||
#define RSOD_BG_COLOR gfx_color_rgb(0x7F, 0x00, 0x00)
|
||||
#else
|
||||
#define RSOD_BG_COLOR COLOR_BLACK
|
||||
#endif
|
||||
|
||||
void rsod_terminal(const systask_postmortem_t* pminfo) {
|
||||
display_orientation(0);
|
||||
display_set_orientation(0);
|
||||
term_set_color(RSOD_FG_COLOR, RSOD_BG_COLOR);
|
||||
|
||||
const char* title = RSOD_DEFAULT_TITLE;
|
||||
@ -93,7 +93,7 @@ void rsod_terminal(const systask_postmortem_t* pminfo) {
|
||||
term_printf("\n%s\n", footer);
|
||||
}
|
||||
|
||||
display_backlight(255);
|
||||
display_set_backlight(255);
|
||||
}
|
||||
|
||||
#endif // KERNEL_MODE
|
||||
|
@ -30,17 +30,15 @@
|
||||
#define TERMINAL_ROWS (DISPLAY_RESY / 8)
|
||||
|
||||
static char terminal_fb[TERMINAL_ROWS][TERMINAL_COLS];
|
||||
static uint16_t terminal_fgcolor = COLOR_WHITE;
|
||||
static uint16_t terminal_bgcolor = COLOR_BLACK;
|
||||
static gfx_color_t terminal_fgcolor = COLOR_WHITE;
|
||||
static gfx_color_t terminal_bgcolor = COLOR_BLACK;
|
||||
|
||||
// set colors for display_print function
|
||||
void term_set_color(uint16_t fgcolor, uint16_t bgcolor) {
|
||||
void term_set_color(gfx_color_t fgcolor, gfx_color_t bgcolor) {
|
||||
terminal_fgcolor = fgcolor;
|
||||
terminal_bgcolor = bgcolor;
|
||||
}
|
||||
|
||||
#ifdef NEW_RENDERING
|
||||
|
||||
// Font_Bitmap contains 96 (0x20 - 0x7F) 5x7 glyphs
|
||||
// Each glyph consists of 5 bytes (each byte represents one column)
|
||||
//
|
||||
@ -80,8 +78,8 @@ static void term_redraw_rows(int start_row, int row_count) {
|
||||
.src_x = 0,
|
||||
.src_y = 0,
|
||||
.src_stride = 8,
|
||||
.src_fg = gfx_color16_to_color(terminal_fgcolor),
|
||||
.src_bg = gfx_color16_to_color(terminal_bgcolor),
|
||||
.src_fg = terminal_fgcolor,
|
||||
.src_bg = terminal_bgcolor,
|
||||
};
|
||||
|
||||
for (int y = start_row; y < start_row + row_count; y++) {
|
||||
@ -93,7 +91,6 @@ static void term_redraw_rows(int start_row, int row_count) {
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // NEW_RENDERING
|
||||
|
||||
// display text using bitmap font
|
||||
void term_print(const char *text, int textlen) {
|
||||
@ -133,39 +130,8 @@ void term_print(const char *text, int textlen) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NEW_RENDERING
|
||||
term_redraw_rows(0, TERMINAL_ROWS);
|
||||
display_refresh();
|
||||
#else // NEW RENDERING
|
||||
// render buffer to display
|
||||
display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1);
|
||||
for (int i = 0; i < DISPLAY_RESX * DISPLAY_RESY; i++) {
|
||||
int x = (i % DISPLAY_RESX);
|
||||
int y = (i / DISPLAY_RESX);
|
||||
const int j = y % 8;
|
||||
y /= 8;
|
||||
const int k = x % 6;
|
||||
x /= 6;
|
||||
char c = 0;
|
||||
if (x < TERMINAL_COLS && y < TERMINAL_ROWS) {
|
||||
c = terminal_fb[y][x] & 0x7F;
|
||||
// char invert = terminal_fb[y][x] & 0x80;
|
||||
} else {
|
||||
c = ' ';
|
||||
}
|
||||
if (c < ' ') {
|
||||
c = ' ';
|
||||
}
|
||||
const uint8_t *g = Font_Bitmap + (5 * (c - ' '));
|
||||
if (k < 5 && (g[k] & (1 << j))) {
|
||||
PIXELDATA(gfx_color16_to_color(terminal_fgcolor));
|
||||
} else {
|
||||
PIXELDATA(gfx_color16_to_color(terminal_bgcolor));
|
||||
}
|
||||
}
|
||||
display_pixeldata_dirty();
|
||||
display_refresh();
|
||||
#endif
|
||||
}
|
||||
|
||||
// variadic term_print
|
||||
|
@ -20,9 +20,9 @@
|
||||
#ifndef LIB_TERMINAL_H
|
||||
#define LIB_TERMINAL_H
|
||||
|
||||
#include "colors.h"
|
||||
#include "gfx_color.h"
|
||||
|
||||
void term_set_color(uint16_t fgcolor, uint16_t bgcolor);
|
||||
void term_set_color(gfx_color_t fgcolor, gfx_color_t bgcolor);
|
||||
void term_print(const char *text, int textlen);
|
||||
void term_printf(const char *fmt, ...)
|
||||
__attribute__((__format__(__printf__, 1, 2)));
|
||||
|
@ -29,11 +29,12 @@
|
||||
#include "bootutils.h"
|
||||
#include "button.h"
|
||||
#include "display.h"
|
||||
#include "display_draw.h"
|
||||
#include "display_utils.h"
|
||||
#include "flash.h"
|
||||
#include "flash_otp.h"
|
||||
#include "fonts/fonts.h"
|
||||
#include "fwutils.h"
|
||||
#include "gfx_draw.h"
|
||||
#include "image.h"
|
||||
#include "mpu.h"
|
||||
#include "prodtest_common.h"
|
||||
@ -80,12 +81,18 @@
|
||||
#define MODEL_IDENTIFIER MODEL_INTERNAL_NAME "-"
|
||||
#endif
|
||||
|
||||
static gfx_text_attr_t bold = {
|
||||
.font = FONT_BOLD,
|
||||
.fg_color = COLOR_WHITE,
|
||||
.bg_color = COLOR_BLACK,
|
||||
};
|
||||
|
||||
static secbool startswith(const char *s, const char *prefix) {
|
||||
return sectrue * (0 == strncmp(s, prefix, strlen(prefix)));
|
||||
}
|
||||
|
||||
static void vcp_intr(void) {
|
||||
display_clear();
|
||||
gfx_clear();
|
||||
error_shutdown("vcp_intr");
|
||||
}
|
||||
|
||||
@ -193,15 +200,22 @@ void extract_params(const char *str, int *numbers, int *count, int max_count) {
|
||||
|
||||
static void draw_border(int width, int padding) {
|
||||
const int W = width, P = padding, RX = DISPLAY_RESX, RY = DISPLAY_RESY;
|
||||
display_clear();
|
||||
display_bar(P, P, RX - 2 * P, RY - 2 * P, 0xFFFF);
|
||||
display_bar(P + W, P + W, RX - 2 * (P + W), RY - 2 * (P + W), 0x0000);
|
||||
|
||||
gfx_clear();
|
||||
|
||||
gfx_rect_t r_out = gfx_rect_wh(P, P, RX - 2 * P, RY - 2 * P);
|
||||
gfx_rect_t r_in =
|
||||
gfx_rect_wh(P + W, P + W, RX - 2 * (P + W), RY - 2 * (P + W));
|
||||
|
||||
gfx_draw_bar(r_out, COLOR_WHITE);
|
||||
gfx_draw_bar(r_in, COLOR_BLACK);
|
||||
|
||||
display_refresh();
|
||||
}
|
||||
|
||||
static void draw_welcome_screen(void) {
|
||||
#if defined TREZOR_MODEL_R || defined TREZOR_MODEL_T3B1
|
||||
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, 0xFFFF);
|
||||
gfx_draw_bar(gfx_rect_wh(0, 0, DISPLAY_RESX, DISPLAY_RESY), COLOR_WHITE);
|
||||
display_refresh();
|
||||
#else
|
||||
draw_border(1, 3);
|
||||
@ -214,28 +228,30 @@ static void test_border(void) {
|
||||
}
|
||||
|
||||
static void test_display(const char *colors) {
|
||||
display_clear();
|
||||
gfx_clear();
|
||||
|
||||
size_t l = strlen(colors);
|
||||
size_t w = DISPLAY_RESX / l;
|
||||
|
||||
for (size_t i = 0; i < l; i++) {
|
||||
uint16_t c = 0x0000; // black
|
||||
uint16_t c = COLOR_BLACK; // black
|
||||
switch (colors[i]) {
|
||||
case 'R':
|
||||
c = 0xF800;
|
||||
c = gfx_color_rgb(255, 0, 0);
|
||||
break;
|
||||
case 'G':
|
||||
c = 0x07E0;
|
||||
c = gfx_color_rgb(0, 255, 0);
|
||||
break;
|
||||
case 'B':
|
||||
c = 0x001F;
|
||||
c = gfx_color_rgb(0, 0, 255);
|
||||
break;
|
||||
case 'W':
|
||||
c = 0xFFFF;
|
||||
c = COLOR_WHITE;
|
||||
break;
|
||||
}
|
||||
display_bar(i * w, 0, i * w + w, DISPLAY_RESY, c);
|
||||
|
||||
gfx_rect_t r = gfx_rect_wh(i * w, 0, i * w + w, DISPLAY_RESY);
|
||||
gfx_draw_bar(r, c);
|
||||
}
|
||||
display_refresh();
|
||||
vcp_println("OK");
|
||||
@ -365,19 +381,19 @@ static void test_touch(const char *args) {
|
||||
const int width = DISPLAY_RESX / 2;
|
||||
const int height = DISPLAY_RESY / 2;
|
||||
|
||||
display_clear();
|
||||
gfx_clear();
|
||||
switch (column) {
|
||||
case 1:
|
||||
display_bar(0, 0, width, height, 0xFFFF);
|
||||
gfx_draw_bar(gfx_rect_wh(0, 0, width, height), COLOR_WHITE);
|
||||
break;
|
||||
case 2:
|
||||
display_bar(width, 0, width, height, 0xFFFF);
|
||||
gfx_draw_bar(gfx_rect_wh(width, 0, width, height), COLOR_WHITE);
|
||||
break;
|
||||
case 3:
|
||||
display_bar(width, height, width, height, 0xFFFF);
|
||||
gfx_draw_bar(gfx_rect_wh(width, height, width, height), COLOR_WHITE);
|
||||
break;
|
||||
default:
|
||||
display_bar(0, height, width, height, 0xFFFF);
|
||||
gfx_draw_bar(gfx_rect_wh(0, height, width, height), COLOR_WHITE);
|
||||
break;
|
||||
}
|
||||
display_refresh();
|
||||
@ -392,7 +408,7 @@ static void test_touch(const char *args) {
|
||||
} else {
|
||||
vcp_println("ERROR TIMEOUT");
|
||||
}
|
||||
display_clear();
|
||||
gfx_clear();
|
||||
display_refresh();
|
||||
|
||||
touch_deinit();
|
||||
@ -421,8 +437,8 @@ static void test_touch_custom(const char *args) {
|
||||
|
||||
uint32_t ticks_start = hal_ticks_ms();
|
||||
|
||||
display_clear();
|
||||
display_bar(x, y, width, height, 0xFFFF);
|
||||
gfx_clear();
|
||||
gfx_draw_bar(gfx_rect_wh(x, y, width, height), COLOR_WHITE);
|
||||
display_refresh();
|
||||
|
||||
touch_init();
|
||||
@ -452,7 +468,7 @@ static void test_touch_custom(const char *args) {
|
||||
}
|
||||
}
|
||||
|
||||
display_clear();
|
||||
gfx_clear();
|
||||
display_refresh();
|
||||
|
||||
touch_deinit();
|
||||
@ -475,9 +491,9 @@ static void test_touch_idle(const char *args) {
|
||||
|
||||
uint32_t ticks_start = hal_ticks_ms();
|
||||
|
||||
display_clear();
|
||||
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY / 2, "DON'T TOUCH", -1,
|
||||
FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
|
||||
gfx_clear();
|
||||
gfx_offset_t pos = gfx_offset(DISPLAY_RESX / 2, DISPLAY_RESY / 2);
|
||||
gfx_draw_text(pos, "DON'T TOUCH", -1, &bold, GFX_ALIGN_CENTER);
|
||||
display_refresh();
|
||||
|
||||
touch_init();
|
||||
@ -494,7 +510,7 @@ static void test_touch_idle(const char *args) {
|
||||
}
|
||||
}
|
||||
|
||||
display_clear();
|
||||
gfx_clear();
|
||||
display_refresh();
|
||||
|
||||
touch_deinit();
|
||||
@ -515,9 +531,9 @@ static void test_touch_power(const char *args) {
|
||||
|
||||
int timeout = params[0];
|
||||
|
||||
display_clear();
|
||||
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY / 2, "MEASURING", -1,
|
||||
FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
|
||||
gfx_clear();
|
||||
gfx_offset_t pos = gfx_offset(DISPLAY_RESX / 2, DISPLAY_RESY / 2);
|
||||
gfx_draw_text(pos, "MEASURING", -1, &bold, GFX_ALIGN_CENTER);
|
||||
display_refresh();
|
||||
|
||||
touch_power_set(true);
|
||||
@ -528,7 +544,7 @@ static void test_touch_power(const char *args) {
|
||||
|
||||
touch_power_set(false);
|
||||
|
||||
display_clear();
|
||||
gfx_clear();
|
||||
display_refresh();
|
||||
}
|
||||
|
||||
@ -538,7 +554,7 @@ static void test_sensitivity(const char *args) {
|
||||
touch_init();
|
||||
touch_set_sensitivity(v & 0xFF);
|
||||
|
||||
display_clear();
|
||||
gfx_clear();
|
||||
display_refresh();
|
||||
|
||||
for (;;) {
|
||||
@ -546,11 +562,11 @@ static void test_sensitivity(const char *args) {
|
||||
if (evt & TOUCH_START || evt & TOUCH_MOVE) {
|
||||
int x = touch_unpack_x(evt);
|
||||
int y = touch_unpack_y(evt);
|
||||
display_clear();
|
||||
display_bar(x - 48, y - 48, 96, 96, 0xFFFF);
|
||||
gfx_clear();
|
||||
gfx_draw_bar(gfx_rect_wh(x - 48, y - 48, 96, 96), COLOR_WHITE);
|
||||
display_refresh();
|
||||
} else if (evt & TOUCH_END) {
|
||||
display_clear();
|
||||
gfx_clear();
|
||||
display_refresh();
|
||||
}
|
||||
}
|
||||
@ -569,7 +585,7 @@ static void touch_version(void) {
|
||||
static void test_pwm(const char *args) {
|
||||
int v = atoi(args);
|
||||
|
||||
display_backlight(v);
|
||||
display_set_backlight(v);
|
||||
display_refresh();
|
||||
vcp_println("OK");
|
||||
}
|
||||
@ -662,9 +678,9 @@ static void test_boardloader_version(const boardloader_version_t *version) {
|
||||
|
||||
static void test_wipe(void) {
|
||||
firmware_invalidate_header();
|
||||
display_clear();
|
||||
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY / 2 + 10, "WIPED", -1,
|
||||
FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
|
||||
gfx_clear();
|
||||
gfx_offset_t pos = gfx_offset(DISPLAY_RESX / 2, DISPLAY_RESY / 2 + 10);
|
||||
gfx_draw_text(pos, "WIPED", -1, &bold, GFX_ALIGN_CENTER);
|
||||
display_refresh();
|
||||
vcp_println("OK");
|
||||
}
|
||||
@ -858,16 +874,21 @@ int main(void) {
|
||||
pair_optiga();
|
||||
#endif
|
||||
|
||||
display_clear();
|
||||
gfx_clear();
|
||||
draw_welcome_screen();
|
||||
|
||||
char dom[32];
|
||||
// format: {MODEL_IDENTIFIER}-YYMMDD
|
||||
if (sectrue == flash_otp_read(FLASH_OTP_BLOCK_BATCH, 0, (uint8_t *)dom, 32) &&
|
||||
sectrue == startswith(dom, MODEL_IDENTIFIER) && dom[31] == 0) {
|
||||
display_qrcode(DISPLAY_RESX / 2, DISPLAY_RESY / 2, dom, 4);
|
||||
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 30, dom + 8, -1,
|
||||
FONT_BOLD, COLOR_WHITE, COLOR_BLACK);
|
||||
gfx_offset_t pos;
|
||||
|
||||
pos = gfx_offset(DISPLAY_RESX / 2, DISPLAY_RESY / 2);
|
||||
gfx_draw_qrcode(pos, 4, dom);
|
||||
|
||||
pos = gfx_offset(DISPLAY_RESX / 2, DISPLAY_RESY - 30);
|
||||
gfx_draw_text(pos, dom + 8, -1, &bold, GFX_ALIGN_CENTER);
|
||||
|
||||
display_refresh();
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,8 @@
|
||||
|
||||
#include "bootutils.h"
|
||||
#include "display.h"
|
||||
#include "display_draw.h"
|
||||
#include "flash.h"
|
||||
#include "gfx_draw.h"
|
||||
#include "image.h"
|
||||
#include "rng.h"
|
||||
#include "rsod.h"
|
||||
@ -76,7 +76,7 @@ int main(void) {
|
||||
#endif
|
||||
|
||||
display_orientation(0);
|
||||
display_clear();
|
||||
gfx_clear();
|
||||
display_backlight(255);
|
||||
|
||||
ensure(sdcard_is_present(), "sdcard_is_present");
|
||||
|
@ -19,8 +19,6 @@ xframebuffer = []
|
||||
display_mono = []
|
||||
display_rgb565 = ["ui_antialiasing"]
|
||||
display_rgba8888 = ["ui_antialiasing"]
|
||||
framebuffer = []
|
||||
framebuffer32bit = []
|
||||
ui_debug = []
|
||||
ui_antialiasing = []
|
||||
ui_blurring = []
|
||||
@ -29,14 +27,11 @@ ui_image_buffer = []
|
||||
ui_color_32bit = []
|
||||
ui_overlay = []
|
||||
ui_empty_lock = []
|
||||
new_rendering = []
|
||||
bootloader = []
|
||||
button = []
|
||||
touch = []
|
||||
clippy = []
|
||||
jpeg = []
|
||||
disp_i8080_8bit_dw = [] # write pixels directly to peripheral
|
||||
disp_i8080_16bit_dw = [] # write pixels directly to peripheral
|
||||
debug = ["ui_debug"]
|
||||
sbu = []
|
||||
haptic = []
|
||||
@ -55,7 +50,6 @@ test = [
|
||||
"debug",
|
||||
"glob",
|
||||
"micropython",
|
||||
"new_rendering",
|
||||
"optiga",
|
||||
"protobuf",
|
||||
"touch",
|
||||
|
@ -143,11 +143,6 @@ fn prepare_bindings() -> bindgen::Builder {
|
||||
bindings = bindings.clang_args(&["-DXFRAMEBUFFER"]);
|
||||
}
|
||||
|
||||
#[cfg(feature = "new_rendering")]
|
||||
{
|
||||
bindings = bindings.clang_args(["-DNEW_RENDERING"]);
|
||||
}
|
||||
|
||||
clang_args.push(&build_dir_include);
|
||||
|
||||
// Pass in correct include paths and defines.
|
||||
@ -398,40 +393,6 @@ fn generate_trezorhal_bindings() {
|
||||
.allowlist_function("systick_ms")
|
||||
// toif
|
||||
.allowlist_type("toif_format_t")
|
||||
// dma2d
|
||||
.allowlist_function("dma2d_setup_const")
|
||||
.allowlist_function("dma2d_setup_4bpp")
|
||||
.allowlist_function("dma2d_setup_16bpp")
|
||||
.allowlist_function("dma2d_setup_4bpp_over_4bpp")
|
||||
.allowlist_function("dma2d_setup_4bpp_over_16bpp")
|
||||
.allowlist_function("dma2d_start")
|
||||
.allowlist_function("dma2d_start_blend")
|
||||
.allowlist_function("dma2d_start_const")
|
||||
.allowlist_function("dma2d_start_const_multiline")
|
||||
.allowlist_function("dma2d_wait_for_transfer")
|
||||
//buffers
|
||||
.allowlist_function("buffers_get_line_16bpp")
|
||||
.allowlist_function("buffers_free_line_16bpp")
|
||||
.allowlist_function("buffers_get_line_4bpp")
|
||||
.allowlist_function("buffers_free_line_4bpp")
|
||||
.allowlist_function("buffers_get_text")
|
||||
.allowlist_function("buffers_free_text")
|
||||
.allowlist_function("buffers_get_jpeg")
|
||||
.allowlist_function("buffers_free_jpeg")
|
||||
.allowlist_function("buffers_get_jpeg_work")
|
||||
.allowlist_function("buffers_free_jpeg_work")
|
||||
.allowlist_function("buffers_get_blurring")
|
||||
.allowlist_function("buffers_free_blurring")
|
||||
.allowlist_function("buffers_get_blurring_totals")
|
||||
.allowlist_function("buffers_free_blurring_totals")
|
||||
.allowlist_var("TEXT_BUFFER_HEIGHT")
|
||||
.no_copy("buffer_line_16bpp_t")
|
||||
.no_copy("buffer_line_4bpp_t")
|
||||
.no_copy("buffer_text_t")
|
||||
.no_copy("buffer_jpeg_t")
|
||||
.no_copy("buffer_jpeg_work_t")
|
||||
.no_copy("buffer_blurring_t")
|
||||
.no_copy("buffer_blurring_totals_t")
|
||||
//usb
|
||||
.allowlist_function("usb_configured")
|
||||
// touch
|
||||
|
@ -17,88 +17,149 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZORHAL_DISPLAY_H
|
||||
#define TREZORHAL_DISPLAY_H
|
||||
#ifndef TREZORHAL_XDISPLAY_H
|
||||
#define TREZORHAL_XDISPLAY_H
|
||||
|
||||
#if NEW_RENDERING
|
||||
#include <xdisplay.h>
|
||||
#else
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_types.h>
|
||||
|
||||
#ifdef DISPLAY_LEGACY_HEADER
|
||||
#include DISPLAY_LEGACY_HEADER
|
||||
#endif
|
||||
#include "gfx_bitblt.h"
|
||||
|
||||
#ifndef DISPLAY_FRAMEBUFFER_OFFSET_Y
|
||||
#define DISPLAY_FRAMEBUFFER_OFFSET_Y 0
|
||||
#endif
|
||||
// This is a universal API for controlling different types of display
|
||||
// controllers.
|
||||
//
|
||||
// Currently, following displays displays are supported
|
||||
//
|
||||
// VG-2864KSWEG01 - OLED Mono / 128x64 pixels / SPI
|
||||
// - Model T2B1
|
||||
//
|
||||
// UG-2828SWIG01 - OLED Mono / 128x128 pixels / Parallel
|
||||
// - Early revisions of T2B1
|
||||
//
|
||||
// ST7789V - TFT RGB / 240x240 pixels / Parallel
|
||||
// - Model T2T1 / Model T3T1
|
||||
//
|
||||
// ILI9341 - TFT RGB / 320x240 pixels / Parallel / LTDC + SPI
|
||||
// - STM32F429I-DISC1 Discovery Board
|
||||
//
|
||||
// MIPI -
|
||||
// - STM32U5A9J-DK Discovery Board
|
||||
|
||||
#ifndef DISPLAY_FRAMEBUFFER_OFFSET_X
|
||||
#define DISPLAY_FRAMEBUFFER_OFFSET_X 0
|
||||
#endif
|
||||
|
||||
#ifndef DISPLAY_FRAMEBUFFER_WIDTH
|
||||
#define DISPLAY_FRAMEBUFFER_WIDTH 0
|
||||
#endif
|
||||
|
||||
#ifndef DISPLAY_FRAMEBUFFER_HEIGHT
|
||||
#define DISPLAY_FRAMEBUFFER_HEIGHT 0
|
||||
#endif
|
||||
|
||||
#ifndef PIXELDATA
|
||||
#define PIXELDATA(c) display_pixeldata(c)
|
||||
#endif
|
||||
|
||||
void display_pixeldata(uint16_t c);
|
||||
void display_pixeldata_dirty(void);
|
||||
|
||||
void display_reset_state();
|
||||
|
||||
void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
|
||||
int display_orientation(int degrees);
|
||||
int display_get_orientation(void);
|
||||
int display_backlight(int val);
|
||||
|
||||
void display_init_all(void);
|
||||
void display_reinit(void);
|
||||
void display_sync(void);
|
||||
void display_refresh(void);
|
||||
void display_finish_actions(void);
|
||||
const char *display_save(const char *prefix);
|
||||
void display_clear_save(void);
|
||||
|
||||
void display_efficient_clear(void);
|
||||
uint32_t *display_get_fb_addr(void);
|
||||
uint8_t *display_get_wr_addr(void);
|
||||
void display_shift_window(uint16_t pixels);
|
||||
uint16_t display_get_window_offset(void);
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
// Specifies how display content should be handled during
|
||||
// initialization or deinitialization.
|
||||
typedef enum {
|
||||
// Clear the display content
|
||||
DISPLAY_RESET_CONTENT,
|
||||
// Keeps the display without any changes
|
||||
// Retain the display content
|
||||
DISPLAY_RETAIN_CONTENT
|
||||
} display_content_mode_t;
|
||||
|
||||
static inline void display_init(display_content_mode_t mode) {
|
||||
if (mode == DISPLAY_RESET_CONTENT) {
|
||||
display_init_all();
|
||||
} else {
|
||||
display_reinit();
|
||||
}
|
||||
}
|
||||
// Initializes the display controller.
|
||||
//
|
||||
// If `mode` is `DISPLAY_RETAIN_CONTENT`, ensure the driver was previously
|
||||
// initialized and `display_deinit(DISPLAY_RETAIN_CONTENT)` was called.
|
||||
void display_init(display_content_mode_t mode);
|
||||
|
||||
static inline void display_deinit(display_content_mode_t mode) {
|
||||
// Deinitializes the display controller.
|
||||
//
|
||||
// If `mode` is `DISPLAY_RETAIN_CONTENT`, the function waits for
|
||||
// background operations to complete and disables interrupts, so the
|
||||
// application can safely proceed to the next boot stage and call
|
||||
// `display_init(DISPLAY_RETAIN_CONTENT)`.
|
||||
void display_deinit(display_content_mode_t mode);
|
||||
|
||||
#ifdef TREZOR_MODEL_T
|
||||
if (mode == DISPLAY_RESET_CONTENT) {
|
||||
display_orientation(0);
|
||||
}
|
||||
// Allows unprivileged access to the display framebuffer from
|
||||
// perspective of the GTZC (Global TrustZone Controller).
|
||||
void display_set_unpriv_access(bool unpriv);
|
||||
|
||||
#endif // KERNEL_MODE
|
||||
|
||||
// Sets display backlight level ranging from 0 (off)..255 (maximum).
|
||||
//
|
||||
// The default backligt level is 0. Without settings it
|
||||
// to some higher value the displayed pixels are not visible.
|
||||
// Beware that his also applies to the emulator.
|
||||
//
|
||||
// Returns the set level (usually the same value or the
|
||||
// closest value to the `level` argument)
|
||||
int display_set_backlight(int level);
|
||||
|
||||
// Gets current display level ranging from 0 (off)..255 (maximum).
|
||||
int display_get_backlight(void);
|
||||
|
||||
// Sets the display orientation.
|
||||
//
|
||||
// May accept one of following values: 0, 90, 180, 270
|
||||
// but accepted values are model-dependent.
|
||||
// Default display orientation is always 0.
|
||||
//
|
||||
// Returns the set orientation
|
||||
int display_set_orientation(int angle);
|
||||
|
||||
// Gets the display's current orientation
|
||||
//
|
||||
// Returned value is one of 0, 90, 180, 270.
|
||||
int display_get_orientation(void);
|
||||
|
||||
#ifdef XFRAMEBUFFER
|
||||
|
||||
typedef struct {
|
||||
// Pointer to the top-left pixel
|
||||
void *ptr;
|
||||
// Stride in bytes
|
||||
size_t stride;
|
||||
|
||||
} display_fb_info_t;
|
||||
|
||||
// Provides pointer to the inactive (writeable) framebuffer.
|
||||
//
|
||||
// If framebuffer is not available yet due to display refreshing etc.,
|
||||
// the function may block until the buffer is ready to write.
|
||||
//
|
||||
// Return `false` if the framebuffer is not available.
|
||||
bool display_get_frame_buffer(display_fb_info_t *fb);
|
||||
|
||||
#else // XFRAMEBUFFER
|
||||
|
||||
// Waits for the vertical synchronization pulse.
|
||||
//
|
||||
// Used for synchronization with the display refresh cycle
|
||||
// to achieve tearless UX if possible when not using a frame buffer.
|
||||
void display_wait_for_sync(void);
|
||||
#endif
|
||||
display_finish_actions();
|
||||
}
|
||||
|
||||
#endif // NEW_RENDERING
|
||||
#endif // TREZORHAL_DISPLAY_H
|
||||
// Swaps the frame buffers
|
||||
//
|
||||
// The function waits for vertical synchronization and
|
||||
// swaps the active (currently displayed) and the inactive frame buffers.
|
||||
void display_refresh(void);
|
||||
|
||||
// Following functions define display's bitblt interface.
|
||||
//
|
||||
// These functions draw directly to to display or to the
|
||||
// currently inactive framebuffer.
|
||||
//
|
||||
// bb->dst_row and bb->dst_stride must be 0
|
||||
|
||||
// Fills a rectangle with a solid color.
|
||||
// This function is supported by all types of displays.
|
||||
void display_fill(const gfx_bitblt_t *bb);
|
||||
// Copies an RGB565 bitmap.
|
||||
// This function is supported by RGB displays only.
|
||||
void display_copy_rgb565(const gfx_bitblt_t *bb);
|
||||
// Copies a MONO4 bitmap (supported only with RGB displays).
|
||||
// This function is supported by RGB displays only.
|
||||
void display_copy_mono4(const gfx_bitblt_t *bb);
|
||||
// Copies a MONO1P bitmap.
|
||||
// This function is supported by all types of displays.
|
||||
void display_copy_mono1p(const gfx_bitblt_t *bb);
|
||||
|
||||
#ifdef TREZOR_EMULATOR
|
||||
// Save the screen content to a file.
|
||||
// The function is available only on the emulator.
|
||||
const char *display_save(const char *prefix);
|
||||
void display_clear_save(void);
|
||||
#endif
|
||||
|
||||
#endif // TREZORHAL_XDISPLAY_H
|
||||
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZORHAL_DMA2D_H
|
||||
#define TREZORHAL_DMA2D_H
|
||||
|
||||
#include <trezor_types.h>
|
||||
|
||||
void dma2d_init(void);
|
||||
|
||||
void dma2d_setup_const(void);
|
||||
void dma2d_setup_4bpp(uint16_t fg_color, uint16_t bg_color);
|
||||
void dma2d_setup_16bpp(void);
|
||||
void dma2d_setup_4bpp_over_4bpp(uint16_t fg_color, uint16_t bg_color,
|
||||
uint16_t overlay_color);
|
||||
void dma2d_setup_4bpp_over_16bpp(uint16_t overlay_color);
|
||||
|
||||
void dma2d_start(uint8_t* in_addr, uint8_t* out_addr, int32_t pixels);
|
||||
void dma2d_start_const(uint16_t color, uint8_t* out_addr, int32_t pixels);
|
||||
void dma2d_start_const_multiline(uint16_t color, uint8_t* out_addr,
|
||||
int32_t width, int32_t height);
|
||||
void dma2d_start_blend(uint8_t* overlay_addr, uint8_t* bg_addr,
|
||||
uint8_t* out_addr, int32_t pixels);
|
||||
|
||||
void dma2d_wait_for_transfer(void);
|
||||
|
||||
#endif // TREZORHAL_DMA2D_H
|
@ -1,512 +0,0 @@
|
||||
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "ili9341_spi.h"
|
||||
|
||||
/**
|
||||
* @brief ILI9341 chip IDs
|
||||
*/
|
||||
#define ILI9341_ID 0x9341
|
||||
|
||||
/**
|
||||
* @brief ILI9341 Size
|
||||
*/
|
||||
#define ILI9341_LCD_PIXEL_WIDTH ((uint16_t)240)
|
||||
#define ILI9341_LCD_PIXEL_HEIGHT ((uint16_t)320)
|
||||
|
||||
/**
|
||||
* @brief ILI9341 Timing
|
||||
*/
|
||||
/* Timing configuration (Typical configuration from ILI9341 datasheet)
|
||||
HSYNC=10 (9+1)
|
||||
HBP=20 (29-10+1)
|
||||
ActiveW=240 (269-20-10+1)
|
||||
HFP=10 (279-240-20-10+1)
|
||||
|
||||
VSYNC=2 (1+1)
|
||||
VBP=2 (3-2+1)
|
||||
ActiveH=320 (323-2-2+1)
|
||||
VFP=4 (327-320-2-2+1)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief ILI9341 Registers
|
||||
*/
|
||||
|
||||
/* Level 1 Commands */
|
||||
#define LCD_SWRESET 0x01 /* Software Reset */
|
||||
#define LCD_READ_DISPLAY_ID 0x04 /* Read display identification information */
|
||||
#define LCD_RDDST 0x09 /* Read Display Status */
|
||||
#define LCD_RDDPM 0x0A /* Read Display Power Mode */
|
||||
#define LCD_RDDMADCTL 0x0B /* Read Display MADCTL */
|
||||
#define LCD_RDDCOLMOD 0x0C /* Read Display Pixel Format */
|
||||
#define LCD_RDDIM 0x0D /* Read Display Image Format */
|
||||
#define LCD_RDDSM 0x0E /* Read Display Signal Mode */
|
||||
#define LCD_RDDSDR 0x0F /* Read Display Self-Diagnostic Result */
|
||||
#define LCD_SPLIN 0x10 /* Enter Sleep Mode */
|
||||
#define LCD_SLEEP_OUT 0x11 /* Sleep out register */
|
||||
#define LCD_PTLON 0x12 /* Partial Mode ON */
|
||||
#define LCD_NORMAL_MODE_ON 0x13 /* Normal Display Mode ON */
|
||||
#define LCD_DINVOFF 0x20 /* Display Inversion OFF */
|
||||
#define LCD_DINVON 0x21 /* Display Inversion ON */
|
||||
#define LCD_GAMMA 0x26 /* Gamma register */
|
||||
#define LCD_DISPLAY_OFF 0x28 /* Display off register */
|
||||
#define LCD_DISPLAY_ON 0x29 /* Display on register */
|
||||
#define LCD_COLUMN_ADDR 0x2A /* Colomn address register */
|
||||
#define LCD_PAGE_ADDR 0x2B /* Page address register */
|
||||
#define LCD_GRAM 0x2C /* GRAM register */
|
||||
#define LCD_RGBSET 0x2D /* Color SET */
|
||||
#define LCD_RAMRD 0x2E /* Memory Read */
|
||||
#define LCD_PLTAR 0x30 /* Partial Area */
|
||||
#define LCD_VSCRDEF 0x33 /* Vertical Scrolling Definition */
|
||||
#define LCD_TEOFF 0x34 /* Tearing Effect Line OFF */
|
||||
#define LCD_TEON 0x35 /* Tearing Effect Line ON */
|
||||
#define LCD_MAC 0x36 /* Memory Access Control register*/
|
||||
#define LCD_VSCRSADD 0x37 /* Vertical Scrolling Start Address */
|
||||
#define LCD_IDMOFF 0x38 /* Idle Mode OFF */
|
||||
#define LCD_IDMON 0x39 /* Idle Mode ON */
|
||||
#define LCD_PIXEL_FORMAT 0x3A /* Pixel Format register */
|
||||
#define LCD_WRITE_MEM_CONTINUE 0x3C /* Write Memory Continue */
|
||||
#define LCD_READ_MEM_CONTINUE 0x3E /* Read Memory Continue */
|
||||
#define LCD_SET_TEAR_SCANLINE 0x44 /* Set Tear Scanline */
|
||||
#define LCD_GET_SCANLINE 0x45 /* Get Scanline */
|
||||
#define LCD_WDB 0x51 /* Write Brightness Display register */
|
||||
#define LCD_RDDISBV 0x52 /* Read Display Brightness */
|
||||
#define LCD_WCD 0x53 /* Write Control Display register*/
|
||||
#define LCD_RDCTRLD 0x54 /* Read CTRL Display */
|
||||
#define LCD_WRCABC 0x55 /* Write Content Adaptive Brightness Control */
|
||||
#define LCD_RDCABC 0x56 /* Read Content Adaptive Brightness Control */
|
||||
#define LCD_WRITE_CABC 0x5E /* Write CABC Minimum Brightness */
|
||||
#define LCD_READ_CABC 0x5F /* Read CABC Minimum Brightness */
|
||||
#define LCD_READ_ID1 0xDA /* Read ID1 */
|
||||
#define LCD_READ_ID2 0xDB /* Read ID2 */
|
||||
#define LCD_READ_ID3 0xDC /* Read ID3 */
|
||||
|
||||
/* Level 2 Commands */
|
||||
#define LCD_RGB_INTERFACE 0xB0 /* RGB Interface Signal Control */
|
||||
#define LCD_FRMCTR1 0xB1 /* Frame Rate Control (In Normal Mode) */
|
||||
#define LCD_FRMCTR2 0xB2 /* Frame Rate Control (In Idle Mode) */
|
||||
#define LCD_FRMCTR3 0xB3 /* Frame Rate Control (In Partial Mode) */
|
||||
#define LCD_INVTR 0xB4 /* Display Inversion Control */
|
||||
#define LCD_BPC 0xB5 /* Blanking Porch Control register */
|
||||
#define LCD_DFC 0xB6 /* Display Function Control register */
|
||||
#define LCD_ETMOD 0xB7 /* Entry Mode Set */
|
||||
#define LCD_BACKLIGHT1 0xB8 /* Backlight Control 1 */
|
||||
#define LCD_BACKLIGHT2 0xB9 /* Backlight Control 2 */
|
||||
#define LCD_BACKLIGHT3 0xBA /* Backlight Control 3 */
|
||||
#define LCD_BACKLIGHT4 0xBB /* Backlight Control 4 */
|
||||
#define LCD_BACKLIGHT5 0xBC /* Backlight Control 5 */
|
||||
#define LCD_BACKLIGHT7 0xBE /* Backlight Control 7 */
|
||||
#define LCD_BACKLIGHT8 0xBF /* Backlight Control 8 */
|
||||
#define LCD_POWER1 0xC0 /* Power Control 1 register */
|
||||
#define LCD_POWER2 0xC1 /* Power Control 2 register */
|
||||
#define LCD_VCOM1 0xC5 /* VCOM Control 1 register */
|
||||
#define LCD_VCOM2 0xC7 /* VCOM Control 2 register */
|
||||
#define LCD_NVMWR 0xD0 /* NV Memory Write */
|
||||
#define LCD_NVMPKEY 0xD1 /* NV Memory Protection Key */
|
||||
#define LCD_RDNVM 0xD2 /* NV Memory Status Read */
|
||||
#define LCD_READ_ID4 0xD3 /* Read ID4 */
|
||||
#define LCD_PGAMMA 0xE0 /* Positive Gamma Correction register */
|
||||
#define LCD_NGAMMA 0xE1 /* Negative Gamma Correction register */
|
||||
#define LCD_DGAMCTRL1 0xE2 /* Digital Gamma Control 1 */
|
||||
#define LCD_DGAMCTRL2 0xE3 /* Digital Gamma Control 2 */
|
||||
#define LCD_INTERFACE 0xF6 /* Interface control register */
|
||||
|
||||
/* Extend register commands */
|
||||
#define LCD_POWERA 0xCB /* Power control A register */
|
||||
#define LCD_POWERB 0xCF /* Power control B register */
|
||||
#define LCD_DTCA 0xE8 /* Driver timing control A */
|
||||
#define LCD_DTCB 0xEA /* Driver timing control B */
|
||||
#define LCD_POWER_SEQ 0xED /* Power on sequence register */
|
||||
#define LCD_3GAMMA_EN 0xF2 /* 3 Gamma enable register */
|
||||
#define LCD_PRC 0xF7 /* Pump ratio control register */
|
||||
|
||||
/* Size of read registers */
|
||||
#define LCD_READ_ID4_SIZE 3 /* Size of Read ID4 */
|
||||
|
||||
/*############################### SPIx #######################################*/
|
||||
#define DISCOVERY_SPIx SPI5
|
||||
#define DISCOVERY_SPIx_CLK_ENABLE() __HAL_RCC_SPI5_CLK_ENABLE()
|
||||
#define DISCOVERY_SPIx_GPIO_PORT GPIOF /* GPIOF */
|
||||
#define DISCOVERY_SPIx_AF GPIO_AF5_SPI5
|
||||
#define DISCOVERY_SPIx_GPIO_CLK_ENABLE() __HAL_RCC_GPIOF_CLK_ENABLE()
|
||||
#define DISCOVERY_SPIx_GPIO_CLK_DISABLE() __HAL_RCC_GPIOF_CLK_DISABLE()
|
||||
#define DISCOVERY_SPIx_SCK_PIN GPIO_PIN_7 /* PF.07 */
|
||||
#define DISCOVERY_SPIx_MISO_PIN GPIO_PIN_8 /* PF.08 */
|
||||
#define DISCOVERY_SPIx_MOSI_PIN GPIO_PIN_9 /* PF.09 */
|
||||
/* Maximum Timeout values for flags waiting loops. These timeouts are not based
|
||||
on accurate values, they just guarantee that the application will not remain
|
||||
stuck if the SPI communication is corrupted.
|
||||
You may modify these timeout values depending on CPU frequency and
|
||||
application conditions (interrupts routines ...). */
|
||||
#define SPIx_TIMEOUT_MAX ((uint32_t)0x1000)
|
||||
|
||||
/*################################ LCD #######################################*/
|
||||
/* Chip Select macro definition */
|
||||
#define LCD_CS_LOW() \
|
||||
HAL_GPIO_WritePin(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, GPIO_PIN_RESET)
|
||||
#define LCD_CS_HIGH() \
|
||||
HAL_GPIO_WritePin(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, GPIO_PIN_SET)
|
||||
|
||||
/* Set WRX High to send data */
|
||||
#define LCD_WRX_LOW() \
|
||||
HAL_GPIO_WritePin(LCD_WRX_GPIO_PORT, LCD_WRX_PIN, GPIO_PIN_RESET)
|
||||
#define LCD_WRX_HIGH() \
|
||||
HAL_GPIO_WritePin(LCD_WRX_GPIO_PORT, LCD_WRX_PIN, GPIO_PIN_SET)
|
||||
|
||||
/* Set WRX High to send data */
|
||||
#define LCD_RDX_LOW() \
|
||||
HAL_GPIO_WritePin(LCD_RDX_GPIO_PORT, LCD_RDX_PIN, GPIO_PIN_RESET)
|
||||
#define LCD_RDX_HIGH() \
|
||||
HAL_GPIO_WritePin(LCD_RDX_GPIO_PORT, LCD_RDX_PIN, GPIO_PIN_SET)
|
||||
|
||||
/**
|
||||
* @brief LCD Control pin
|
||||
*/
|
||||
#define LCD_NCS_PIN GPIO_PIN_2
|
||||
#define LCD_NCS_GPIO_PORT GPIOC
|
||||
#define LCD_NCS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
|
||||
#define LCD_NCS_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/**
|
||||
* @brief LCD Command/data pin
|
||||
*/
|
||||
#define LCD_WRX_PIN GPIO_PIN_13
|
||||
#define LCD_WRX_GPIO_PORT GPIOD
|
||||
#define LCD_WRX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
|
||||
#define LCD_WRX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOD_CLK_DISABLE()
|
||||
|
||||
#define LCD_RDX_PIN GPIO_PIN_12
|
||||
#define LCD_RDX_GPIO_PORT GPIOD
|
||||
#define LCD_RDX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
|
||||
#define LCD_RDX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOD_CLK_DISABLE()
|
||||
|
||||
static SPI_HandleTypeDef SpiHandle;
|
||||
uint32_t SpixTimeout =
|
||||
SPIx_TIMEOUT_MAX; /*<! Value of Timeout when SPI communication fails */
|
||||
|
||||
/* SPIx bus function */
|
||||
static void SPIx_Init(void);
|
||||
static void ili9341_Write(uint16_t Value);
|
||||
static uint32_t ili9341_Read(uint8_t ReadSize);
|
||||
static void ili9341_Error(void);
|
||||
|
||||
/**
|
||||
* @brief SPIx Bus initialization
|
||||
*/
|
||||
static void SPIx_Init(void) {
|
||||
if (HAL_SPI_GetState(&SpiHandle) == HAL_SPI_STATE_RESET) {
|
||||
/* SPI configuration -----------------------------------------------------*/
|
||||
SpiHandle.Instance = DISCOVERY_SPIx;
|
||||
/* SPI baudrate is set to 5.6 MHz (PCLK2/SPI_BaudRatePrescaler = 90/16
|
||||
= 5.625 MHz) to verify these constraints:
|
||||
- ILI9341 LCD SPI interface max baudrate is 10MHz for write and 6.66MHz
|
||||
for read
|
||||
- l3gd20 SPI interface max baudrate is 10MHz for write/read
|
||||
- PCLK2 frequency is set to 90 MHz
|
||||
*/
|
||||
SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
|
||||
|
||||
/* On STM32F429I-Discovery, LCD ID cannot be read then keep a common
|
||||
* configuration */
|
||||
/* for LCD and GYRO (SPI_DIRECTION_2LINES) */
|
||||
/* Note: To read a register a LCD, SPI_DIRECTION_1LINE should be set */
|
||||
SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
|
||||
SpiHandle.Init.CRCPolynomial = 7;
|
||||
SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
SpiHandle.Init.NSS = SPI_NSS_SOFT;
|
||||
SpiHandle.Init.TIMode = SPI_TIMODE_DISABLED;
|
||||
SpiHandle.Init.Mode = SPI_MODE_MASTER;
|
||||
|
||||
HAL_SPI_Init(&SpiHandle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPIx error treatment function.
|
||||
*/
|
||||
static void ili9341_Error(void) {
|
||||
/* De-initialize the SPI communication BUS */
|
||||
HAL_SPI_DeInit(&SpiHandle);
|
||||
|
||||
/* Re- Initialize the SPI communication BUS */
|
||||
SPIx_Init();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads 4 bytes from device.
|
||||
* @param ReadSize: Number of bytes to read (max 4 bytes)
|
||||
* @retval Value read on the SPI
|
||||
*/
|
||||
static uint32_t ili9341_Read(uint8_t ReadSize) {
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
uint32_t readvalue;
|
||||
|
||||
status =
|
||||
HAL_SPI_Receive(&SpiHandle, (uint8_t*)&readvalue, ReadSize, SpixTimeout);
|
||||
|
||||
/* Check the communication status */
|
||||
if (status != HAL_OK) {
|
||||
/* Re-Initialize the BUS */
|
||||
ili9341_Error();
|
||||
}
|
||||
|
||||
return readvalue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes a byte to device.
|
||||
* @param Value: value to be written
|
||||
*/
|
||||
static void ili9341_Write(uint16_t Value) {
|
||||
HAL_StatusTypeDef status = HAL_OK;
|
||||
|
||||
status = HAL_SPI_Transmit(&SpiHandle, (uint8_t*)&Value, 1, SpixTimeout);
|
||||
|
||||
/* Check the communication status */
|
||||
if (status != HAL_OK) {
|
||||
/* Re-Initialize the BUS */
|
||||
ili9341_Error();
|
||||
}
|
||||
}
|
||||
|
||||
void ili9341_spi_init(void) {
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
|
||||
/* Configure NCS in Output Push-Pull mode */
|
||||
LCD_WRX_GPIO_CLK_ENABLE();
|
||||
GPIO_InitStructure.Pin = LCD_WRX_PIN;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
|
||||
HAL_GPIO_Init(LCD_WRX_GPIO_PORT, &GPIO_InitStructure);
|
||||
|
||||
LCD_RDX_GPIO_CLK_ENABLE();
|
||||
GPIO_InitStructure.Pin = LCD_RDX_PIN;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
|
||||
HAL_GPIO_Init(LCD_RDX_GPIO_PORT, &GPIO_InitStructure);
|
||||
|
||||
/* Configure the LCD Control pins ----------------------------------------*/
|
||||
LCD_NCS_GPIO_CLK_ENABLE();
|
||||
|
||||
/* Configure NCS in Output Push-Pull mode */
|
||||
GPIO_InitStructure.Pin = LCD_NCS_PIN;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
|
||||
HAL_GPIO_Init(LCD_NCS_GPIO_PORT, &GPIO_InitStructure);
|
||||
|
||||
/* Set or Reset the control line */
|
||||
LCD_CS_LOW();
|
||||
LCD_CS_HIGH();
|
||||
|
||||
/* Enable SPIx clock */
|
||||
DISCOVERY_SPIx_CLK_ENABLE();
|
||||
|
||||
/* Enable DISCOVERY_SPI GPIO clock */
|
||||
DISCOVERY_SPIx_GPIO_CLK_ENABLE();
|
||||
|
||||
/* configure SPI SCK, MOSI and MISO */
|
||||
GPIO_InitStructure.Pin = (DISCOVERY_SPIx_SCK_PIN | DISCOVERY_SPIx_MOSI_PIN |
|
||||
DISCOVERY_SPIx_MISO_PIN);
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_PULLDOWN;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_MEDIUM;
|
||||
GPIO_InitStructure.Alternate = DISCOVERY_SPIx_AF;
|
||||
HAL_GPIO_Init(DISCOVERY_SPIx_GPIO_PORT, &GPIO_InitStructure);
|
||||
|
||||
SPIx_Init();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes register value.
|
||||
*/
|
||||
void ili9341_WriteData(uint16_t RegValue) {
|
||||
/* Set WRX to send data */
|
||||
LCD_WRX_HIGH();
|
||||
|
||||
/* Reset LCD control line(/CS) and Send data */
|
||||
LCD_CS_LOW();
|
||||
ili9341_Write(RegValue);
|
||||
|
||||
/* Deselect: Chip Select high */
|
||||
LCD_CS_HIGH();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes register address.
|
||||
*/
|
||||
void ili9341_WriteReg(uint8_t Reg) {
|
||||
/* Reset WRX to send command */
|
||||
LCD_WRX_LOW();
|
||||
|
||||
/* Reset LCD control line(/CS) and Send command */
|
||||
LCD_CS_LOW();
|
||||
ili9341_Write(Reg);
|
||||
|
||||
/* Deselect: Chip Select high */
|
||||
LCD_CS_HIGH();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reads register value.
|
||||
* @param RegValue Address of the register to read
|
||||
* @param ReadSize Number of bytes to read
|
||||
* @retval Content of the register value
|
||||
*/
|
||||
uint32_t ili9341_ReadData(uint16_t RegValue, uint8_t ReadSize) {
|
||||
uint32_t readvalue = 0;
|
||||
|
||||
/* Select: Chip Select low */
|
||||
LCD_CS_LOW();
|
||||
|
||||
/* Reset WRX to send command */
|
||||
LCD_WRX_LOW();
|
||||
|
||||
ili9341_Write(RegValue);
|
||||
|
||||
readvalue = ili9341_Read(ReadSize);
|
||||
|
||||
/* Set WRX to send data */
|
||||
LCD_WRX_HIGH();
|
||||
|
||||
/* Deselect: Chip Select high */
|
||||
LCD_CS_HIGH();
|
||||
|
||||
return readvalue;
|
||||
}
|
||||
|
||||
void ili9341_init(void) {
|
||||
/* Initialize ILI9341 low level bus layer ----------------------------------*/
|
||||
ili9341_spi_init();
|
||||
|
||||
ili9341_WriteReg(LCD_DISPLAY_OFF);
|
||||
|
||||
/* Configure LCD */
|
||||
ili9341_WriteReg(0xCA);
|
||||
ili9341_WriteData(0xC3);
|
||||
ili9341_WriteData(0x08);
|
||||
ili9341_WriteData(0x50);
|
||||
ili9341_WriteReg(LCD_POWERB);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteData(0xC1);
|
||||
ili9341_WriteData(0x30);
|
||||
ili9341_WriteReg(LCD_POWER_SEQ);
|
||||
ili9341_WriteData(0x64);
|
||||
ili9341_WriteData(0x03);
|
||||
ili9341_WriteData(0x12);
|
||||
ili9341_WriteData(0x81);
|
||||
ili9341_WriteReg(LCD_DTCA);
|
||||
ili9341_WriteData(0x85);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteData(0x78);
|
||||
ili9341_WriteReg(LCD_POWERA);
|
||||
ili9341_WriteData(0x39);
|
||||
ili9341_WriteData(0x2C);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteData(0x34);
|
||||
ili9341_WriteData(0x02);
|
||||
ili9341_WriteReg(LCD_PRC);
|
||||
ili9341_WriteData(0x20);
|
||||
ili9341_WriteReg(LCD_DTCB);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteReg(LCD_FRMCTR1);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteData(0x1B);
|
||||
ili9341_WriteReg(LCD_DFC);
|
||||
ili9341_WriteData(0x0A);
|
||||
ili9341_WriteData(0xA2);
|
||||
ili9341_WriteReg(LCD_POWER1);
|
||||
ili9341_WriteData(0x10);
|
||||
ili9341_WriteReg(LCD_POWER2);
|
||||
ili9341_WriteData(0x10);
|
||||
ili9341_WriteReg(LCD_VCOM1);
|
||||
ili9341_WriteData(0x45);
|
||||
ili9341_WriteData(0x15);
|
||||
ili9341_WriteReg(LCD_VCOM2);
|
||||
ili9341_WriteData(0x90);
|
||||
ili9341_WriteReg(LCD_MAC);
|
||||
ili9341_WriteData(0xC8);
|
||||
ili9341_WriteReg(LCD_3GAMMA_EN);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteReg(LCD_RGB_INTERFACE);
|
||||
ili9341_WriteData(0xC2);
|
||||
ili9341_WriteReg(LCD_DFC);
|
||||
ili9341_WriteData(0x0A);
|
||||
ili9341_WriteData(0xA7);
|
||||
ili9341_WriteData(0x27);
|
||||
ili9341_WriteData(0x04);
|
||||
|
||||
/* Colomn address set */
|
||||
ili9341_WriteReg(LCD_COLUMN_ADDR);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteData(0xEF);
|
||||
/* Page address set */
|
||||
ili9341_WriteReg(LCD_PAGE_ADDR);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteData(0x01);
|
||||
ili9341_WriteData(0x3F);
|
||||
ili9341_WriteReg(LCD_INTERFACE);
|
||||
ili9341_WriteData(0x01);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteData(0x06);
|
||||
|
||||
ili9341_WriteReg(LCD_GRAM);
|
||||
HAL_Delay(200);
|
||||
|
||||
ili9341_WriteReg(LCD_GAMMA);
|
||||
ili9341_WriteData(0x01);
|
||||
|
||||
ili9341_WriteReg(LCD_PGAMMA);
|
||||
ili9341_WriteData(0x0F);
|
||||
ili9341_WriteData(0x29);
|
||||
ili9341_WriteData(0x24);
|
||||
ili9341_WriteData(0x0C);
|
||||
ili9341_WriteData(0x0E);
|
||||
ili9341_WriteData(0x09);
|
||||
ili9341_WriteData(0x4E);
|
||||
ili9341_WriteData(0x78);
|
||||
ili9341_WriteData(0x3C);
|
||||
ili9341_WriteData(0x09);
|
||||
ili9341_WriteData(0x13);
|
||||
ili9341_WriteData(0x05);
|
||||
ili9341_WriteData(0x17);
|
||||
ili9341_WriteData(0x11);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteReg(LCD_NGAMMA);
|
||||
ili9341_WriteData(0x00);
|
||||
ili9341_WriteData(0x16);
|
||||
ili9341_WriteData(0x1B);
|
||||
ili9341_WriteData(0x04);
|
||||
ili9341_WriteData(0x11);
|
||||
ili9341_WriteData(0x07);
|
||||
ili9341_WriteData(0x31);
|
||||
ili9341_WriteData(0x33);
|
||||
ili9341_WriteData(0x42);
|
||||
ili9341_WriteData(0x05);
|
||||
ili9341_WriteData(0x0C);
|
||||
ili9341_WriteData(0x0A);
|
||||
ili9341_WriteData(0x28);
|
||||
ili9341_WriteData(0x2F);
|
||||
ili9341_WriteData(0x0F);
|
||||
|
||||
ili9341_WriteReg(LCD_SLEEP_OUT);
|
||||
HAL_Delay(200);
|
||||
ili9341_WriteReg(LCD_DISPLAY_ON);
|
||||
/* GRAM start writing */
|
||||
ili9341_WriteReg(LCD_GRAM);
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#ifndef _ILI9341_SPI_H
|
||||
#define _ILI9341_SPI_H
|
||||
|
||||
#define ILI9341_HSYNC ((uint32_t)9) /* Horizontal synchronization */
|
||||
#define ILI9341_HBP ((uint32_t)29) /* Horizontal back porch */
|
||||
#define ILI9341_HFP ((uint32_t)2) /* Horizontal front porch */
|
||||
#define ILI9341_VSYNC ((uint32_t)1) /* Vertical synchronization */
|
||||
#define ILI9341_VBP ((uint32_t)3) /* Vertical back porch */
|
||||
#define ILI9341_VFP ((uint32_t)2) /* Vertical front porch */
|
||||
|
||||
void ili9341_init(void);
|
||||
|
||||
#endif //_ILI9341_SPI_H
|
@ -1,418 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "ili9341_spi.h"
|
||||
#include "memzero.h"
|
||||
#include "sdram.h"
|
||||
|
||||
#define MAX_LAYER_NUMBER 2
|
||||
#define LCD_FRAME_BUFFER ((uint32_t)SDRAM_DEVICE_ADDR)
|
||||
|
||||
LTDC_HandleTypeDef LtdcHandler;
|
||||
static RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
|
||||
|
||||
/* Default LCD configuration with LCD Layer 1 */
|
||||
uint32_t ActiveLayer = 0;
|
||||
// static LCD_DrawPropTypeDef DrawProp[MAX_LAYER_NUMBER];
|
||||
// LCD_DrvTypeDef *LcdDrv;
|
||||
|
||||
static int DISPLAY_BACKLIGHT = -1;
|
||||
static int DISPLAY_ORIENTATION = -1;
|
||||
|
||||
// this is just for compatibility with DMA2D using algorithms
|
||||
uint8_t *const DISPLAY_DATA_ADDRESS = 0;
|
||||
|
||||
uint16_t cursor_x = 0;
|
||||
uint16_t cursor_y = 0;
|
||||
uint16_t window_x0 = 0;
|
||||
uint16_t window_y0 = DISPLAY_RESX - 1;
|
||||
uint16_t window_x1 = 0;
|
||||
uint16_t window_y1 = DISPLAY_RESY - 1;
|
||||
|
||||
void display_pixeldata(uint16_t c) {
|
||||
((uint16_t *)LCD_FRAME_BUFFER)[(cursor_y * DISPLAY_RESX) + cursor_x] = c;
|
||||
|
||||
cursor_x++;
|
||||
|
||||
if (cursor_x > window_x1) {
|
||||
cursor_x = window_x0;
|
||||
cursor_y++;
|
||||
|
||||
if (cursor_y > window_y1) {
|
||||
cursor_y = window_y0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void display_pixeldata_dirty(void) {}
|
||||
|
||||
void display_reset_state() {}
|
||||
|
||||
static void __attribute__((unused)) display_sleep(void) {}
|
||||
|
||||
static void display_unsleep(void) {}
|
||||
|
||||
/**
|
||||
* @brief Initializes the LCD layers.
|
||||
* @param LayerIndex: the layer foreground or background.
|
||||
* @param FB_Address: the layer frame buffer.
|
||||
*/
|
||||
void BSP_LCD_LayerDefaultInit(uint16_t LayerIndex, uint32_t FB_Address) {
|
||||
LTDC_LayerCfgTypeDef Layercfg = {0};
|
||||
|
||||
/* Layer Init */
|
||||
Layercfg.WindowX0 = 0;
|
||||
Layercfg.WindowX1 = DISPLAY_RESX;
|
||||
Layercfg.WindowY0 = 0;
|
||||
Layercfg.WindowY1 = DISPLAY_RESY;
|
||||
Layercfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
|
||||
Layercfg.FBStartAdress = FB_Address;
|
||||
Layercfg.Alpha = 255;
|
||||
Layercfg.Alpha0 = 0;
|
||||
Layercfg.Backcolor.Blue = 0;
|
||||
Layercfg.Backcolor.Green = 0;
|
||||
Layercfg.Backcolor.Red = 0;
|
||||
Layercfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
|
||||
Layercfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
|
||||
Layercfg.ImageWidth = DISPLAY_RESX;
|
||||
Layercfg.ImageHeight = DISPLAY_RESY;
|
||||
|
||||
HAL_LTDC_ConfigLayer(&LtdcHandler, &Layercfg, LayerIndex);
|
||||
|
||||
// DrawProp[LayerIndex].BackColor = LCD_COLOR_WHITE;
|
||||
// DrawProp[LayerIndex].pFont = &Font24;
|
||||
// DrawProp[LayerIndex].TextColor = LCD_COLOR_BLACK;
|
||||
|
||||
/* Dithering activation */
|
||||
HAL_LTDC_EnableDither(&LtdcHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Selects the LCD Layer.
|
||||
* @param LayerIndex: the Layer foreground or background.
|
||||
*/
|
||||
void BSP_LCD_SelectLayer(uint32_t LayerIndex) { ActiveLayer = LayerIndex; }
|
||||
|
||||
/**
|
||||
* @brief Sets a LCD Layer visible.
|
||||
* @param LayerIndex: the visible Layer.
|
||||
* @param state: new state of the specified layer.
|
||||
* This parameter can be: ENABLE or DISABLE.
|
||||
*/
|
||||
void BSP_LCD_SetLayerVisible(uint32_t LayerIndex, FunctionalState state) {
|
||||
if (state == ENABLE) {
|
||||
__HAL_LTDC_LAYER_ENABLE(&LtdcHandler, LayerIndex);
|
||||
} else {
|
||||
__HAL_LTDC_LAYER_DISABLE(&LtdcHandler, LayerIndex);
|
||||
}
|
||||
__HAL_LTDC_RELOAD_CONFIG(&LtdcHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets an LCD Layer visible without reloading.
|
||||
* @param LayerIndex: Visible Layer
|
||||
* @param State: New state of the specified layer
|
||||
* This parameter can be one of the following values:
|
||||
* @arg ENABLE
|
||||
* @arg DISABLE
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LCD_SetLayerVisible_NoReload(uint32_t LayerIndex,
|
||||
FunctionalState State) {
|
||||
if (State == ENABLE) {
|
||||
__HAL_LTDC_LAYER_ENABLE(&LtdcHandler, LayerIndex);
|
||||
} else {
|
||||
__HAL_LTDC_LAYER_DISABLE(&LtdcHandler, LayerIndex);
|
||||
}
|
||||
/* Do not Sets the Reload */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the Transparency.
|
||||
* @param LayerIndex: the Layer foreground or background.
|
||||
* @param Transparency: the Transparency,
|
||||
* This parameter must range from 0x00 to 0xFF.
|
||||
*/
|
||||
void BSP_LCD_SetTransparency(uint32_t LayerIndex, uint8_t Transparency) {
|
||||
HAL_LTDC_SetAlpha(&LtdcHandler, Transparency, LayerIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configures the transparency without reloading.
|
||||
* @param LayerIndex: Layer foreground or background.
|
||||
* @param Transparency: Transparency
|
||||
* This parameter must be a number between Min_Data = 0x00 and
|
||||
* Max_Data = 0xFF
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LCD_SetTransparency_NoReload(uint32_t LayerIndex,
|
||||
uint8_t Transparency) {
|
||||
HAL_LTDC_SetAlpha_NoReload(&LtdcHandler, Transparency, LayerIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets a LCD layer frame buffer address.
|
||||
* @param LayerIndex: specifies the Layer foreground or background
|
||||
* @param Address: new LCD frame buffer value
|
||||
*/
|
||||
void BSP_LCD_SetLayerAddress(uint32_t LayerIndex, uint32_t Address) {
|
||||
HAL_LTDC_SetAddress(&LtdcHandler, Address, LayerIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets an LCD layer frame buffer address without reloading.
|
||||
* @param LayerIndex: Layer foreground or background
|
||||
* @param Address: New LCD frame buffer value
|
||||
* @retval None
|
||||
*/
|
||||
void BSP_LCD_SetLayerAddress_NoReload(uint32_t LayerIndex, uint32_t Address) {
|
||||
HAL_LTDC_SetAddress_NoReload(&LtdcHandler, Address, LayerIndex);
|
||||
}
|
||||
|
||||
// static struct { uint16_t x, y; } BUFFER_OFFSET;
|
||||
|
||||
void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
window_x0 = x0;
|
||||
window_x1 = x1;
|
||||
window_y0 = y0;
|
||||
window_y1 = y1;
|
||||
cursor_x = x0;
|
||||
cursor_y = y0;
|
||||
|
||||
// /* Reconfigure the layer size */
|
||||
// HAL_LTDC_SetWindowSize_NoReload(&LtdcHandler, x1-x0 + 1, y1-y0 + 1, 0);
|
||||
//
|
||||
// /* Reconfigure the layer position */
|
||||
// HAL_LTDC_SetWindowPosition_NoReload(&LtdcHandler, x0, y0, 0);
|
||||
}
|
||||
|
||||
int display_orientation(int degrees) { return 0; }
|
||||
|
||||
int display_get_orientation(void) { return DISPLAY_ORIENTATION; }
|
||||
|
||||
int display_backlight(int val) {
|
||||
if (DISPLAY_BACKLIGHT != val && val >= 0 && val <= 255) {
|
||||
DISPLAY_BACKLIGHT = val;
|
||||
// TIM1->CCR1 = LED_PWM_TIM_PERIOD * val / 255;
|
||||
}
|
||||
return DISPLAY_BACKLIGHT;
|
||||
}
|
||||
|
||||
void display_init_seq(void) { display_unsleep(); }
|
||||
|
||||
void display_init_all(void) {
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
|
||||
/* Enable the LTDC and DMA2D Clock */
|
||||
__HAL_RCC_LTDC_CLK_ENABLE();
|
||||
__HAL_RCC_DMA2D_CLK_ENABLE();
|
||||
|
||||
/* Enable GPIOs clock */
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||
|
||||
/* GPIOs Configuration */
|
||||
/*
|
||||
+------------------------+-----------------------+----------------------------+
|
||||
+ LCD pins assignment +
|
||||
+------------------------+-----------------------+----------------------------+
|
||||
| LCD_TFT R2 <-> PC.10 | LCD_TFT G2 <-> PA.06 | LCD_TFT B2 <-> PD.06 | |
|
||||
LCD_TFT R3 <-> PB.00 | LCD_TFT G3 <-> PG.10 | LCD_TFT B3 <-> PG.11 |
|
||||
| LCD_TFT R4 <-> PA.11 | LCD_TFT G4 <-> PB.10 | LCD_TFT B4 <-> PG.12 | |
|
||||
LCD_TFT R5 <-> PA.12 | LCD_TFT G5 <-> PB.11 | LCD_TFT B5 <-> PA.03 |
|
||||
| LCD_TFT R6 <-> PB.01 | LCD_TFT G6 <-> PC.07 | LCD_TFT B6 <-> PB.08 | |
|
||||
LCD_TFT R7 <-> PG.06 | LCD_TFT G7 <-> PD.03 | LCD_TFT B7 <-> PB.09 |
|
||||
-------------------------------------------------------------------------------
|
||||
| LCD_TFT HSYNC <-> PC.06 | LCDTFT VSYNC <-> PA.04 |
|
||||
| LCD_TFT CLK <-> PG.07 | LCD_TFT DE <-> PF.10 |
|
||||
-----------------------------------------------------
|
||||
*/
|
||||
|
||||
/* GPIOA configuration */
|
||||
GPIO_InitStructure.Pin =
|
||||
GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_11 | GPIO_PIN_12;
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
|
||||
GPIO_InitStructure.Alternate = GPIO_AF14_LTDC;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
|
||||
/* GPIOB configuration */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
/* GPIOC configuration */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_10;
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
|
||||
/* GPIOD configuration */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_3 | GPIO_PIN_6;
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||||
|
||||
/* GPIOF configuration */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_10;
|
||||
HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);
|
||||
|
||||
/* GPIOG configuration */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_11;
|
||||
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
|
||||
|
||||
/* GPIOB configuration */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1;
|
||||
GPIO_InitStructure.Alternate = GPIO_AF9_LTDC;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
|
||||
/* GPIOG configuration */
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_10 | GPIO_PIN_12;
|
||||
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
|
||||
|
||||
/* On STM32F429I-DISCO, it is not possible to read ILI9341 ID because */
|
||||
/* PIN EXTC is not connected to VDD and then LCD_READ_ID4 is not accessible.
|
||||
*/
|
||||
/* In this case, ReadID function is bypassed.*/
|
||||
/*if(ili9341_drv.ReadID() == ILI9341_ID)*/
|
||||
|
||||
/* LTDC Configuration ----------------------------------------------------*/
|
||||
LtdcHandler.Instance = LTDC;
|
||||
|
||||
/* Timing configuration (Typical configuration from ILI9341 datasheet)
|
||||
HSYNC=10 (9+1)
|
||||
HBP=20 (29-10+1)
|
||||
ActiveW=240 (269-20-10+1)
|
||||
HFP=10 (279-240-20-10+1)
|
||||
|
||||
VSYNC=2 (1+1)
|
||||
VBP=2 (3-2+1)
|
||||
ActiveH=320 (323-2-2+1)
|
||||
VFP=4 (327-320-2-2+1)
|
||||
*/
|
||||
|
||||
/* Configure horizontal synchronization width */
|
||||
LtdcHandler.Init.HorizontalSync = ILI9341_HSYNC;
|
||||
/* Configure vertical synchronization height */
|
||||
LtdcHandler.Init.VerticalSync = ILI9341_VSYNC;
|
||||
/* Configure accumulated horizontal back porch */
|
||||
LtdcHandler.Init.AccumulatedHBP = ILI9341_HBP;
|
||||
/* Configure accumulated vertical back porch */
|
||||
LtdcHandler.Init.AccumulatedVBP = ILI9341_VBP;
|
||||
/* Configure accumulated active width */
|
||||
LtdcHandler.Init.AccumulatedActiveW = 269;
|
||||
/* Configure accumulated active height */
|
||||
LtdcHandler.Init.AccumulatedActiveH = 323;
|
||||
/* Configure total width */
|
||||
LtdcHandler.Init.TotalWidth = 279;
|
||||
/* Configure total height */
|
||||
LtdcHandler.Init.TotalHeigh = 327;
|
||||
|
||||
/* Configure R,G,B component values for LCD background color */
|
||||
LtdcHandler.Init.Backcolor.Red = 0;
|
||||
LtdcHandler.Init.Backcolor.Blue = 0;
|
||||
LtdcHandler.Init.Backcolor.Green = 0;
|
||||
|
||||
/* LCD clock configuration */
|
||||
/* PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz */
|
||||
/* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 192 Mhz */
|
||||
/* PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 192/4 = 48 Mhz */
|
||||
/* LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_8 = 48/4 = 6Mhz */
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
|
||||
PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
|
||||
PeriphClkInitStruct.PLLSAI.PLLSAIR = 4;
|
||||
PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_8;
|
||||
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
|
||||
|
||||
/* Polarity */
|
||||
LtdcHandler.Init.HSPolarity = LTDC_HSPOLARITY_AL;
|
||||
LtdcHandler.Init.VSPolarity = LTDC_VSPOLARITY_AL;
|
||||
LtdcHandler.Init.DEPolarity = LTDC_DEPOLARITY_AL;
|
||||
LtdcHandler.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
|
||||
|
||||
HAL_LTDC_Init(&LtdcHandler);
|
||||
|
||||
/* Initialize the LCD Layers */
|
||||
BSP_LCD_LayerDefaultInit(1, LCD_FRAME_BUFFER);
|
||||
|
||||
memzero((void *)LCD_FRAME_BUFFER, 153600);
|
||||
|
||||
ili9341_init();
|
||||
|
||||
display_init_seq();
|
||||
}
|
||||
|
||||
void display_reinit(void) {}
|
||||
|
||||
void display_refresh(void) {}
|
||||
|
||||
void display_sync(void) {}
|
||||
|
||||
const char *display_save(const char *prefix) { return NULL; }
|
||||
|
||||
void display_clear_save(void) {}
|
||||
|
||||
void display_efficient_clear(void) {
|
||||
memzero((void *)LCD_FRAME_BUFFER, 153600);
|
||||
}
|
||||
|
||||
uint8_t *display_get_wr_addr(void) {
|
||||
uint32_t address = LCD_FRAME_BUFFER;
|
||||
/* Get the rectangle start address */
|
||||
address = (address + (2 * ((cursor_y)*DISPLAY_RESX + (cursor_x))));
|
||||
|
||||
return (uint8_t *)address;
|
||||
}
|
||||
|
||||
uint32_t *display_get_fb_addr(void) { return (uint32_t *)LCD_FRAME_BUFFER; }
|
||||
|
||||
uint16_t display_get_window_width(void) { return window_x1 - window_x0 + 1; }
|
||||
|
||||
uint16_t display_get_window_height(void) { return window_y1 - window_y0 + 1; }
|
||||
|
||||
void display_shift_window(uint16_t pixels) {
|
||||
uint16_t w = display_get_window_width();
|
||||
uint16_t h = display_get_window_height();
|
||||
|
||||
uint16_t line_rem = w - (cursor_x - window_x0);
|
||||
|
||||
if (pixels < line_rem) {
|
||||
cursor_x += pixels;
|
||||
return;
|
||||
}
|
||||
|
||||
// start of next line
|
||||
pixels = pixels - line_rem;
|
||||
cursor_x = window_x0;
|
||||
cursor_y++;
|
||||
|
||||
// add the rest of pixels
|
||||
cursor_y = window_y0 + (((cursor_y - window_y0) + (pixels / w)) % h);
|
||||
cursor_x += pixels % w;
|
||||
}
|
||||
|
||||
uint16_t display_get_window_offset(void) {
|
||||
return DISPLAY_RESX - display_get_window_width();
|
||||
}
|
||||
|
||||
void display_finish_actions(void) {}
|
@ -1,22 +0,0 @@
|
||||
|
||||
#ifndef _LTDC_H
|
||||
#define _LTDC_H
|
||||
|
||||
#include <trezor_model.h>
|
||||
|
||||
#define DISPLAY_FRAMEBUFFER_WIDTH DISPLAY_RESX
|
||||
#define DISPLAY_FRAMEBUFFER_HEIGHT DISPLAY_RESY
|
||||
#define DISPLAY_FRAMEBUFFER_OFFSET_X 0
|
||||
#define DISPLAY_FRAMEBUFFER_OFFSET_Y 0
|
||||
#define DISPLAY_COLOR_MODE DMA2D_OUTPUT_RGB565
|
||||
#define DISPLAY_EFFICIENT_CLEAR 1
|
||||
|
||||
extern uint8_t* const DISPLAY_DATA_ADDRESS;
|
||||
|
||||
static inline void display_pixel(uint8_t* fb, int16_t x, int16_t y,
|
||||
uint16_t color) {
|
||||
uint32_t p = 2 * (y * DISPLAY_FRAMEBUFFER_WIDTH + x);
|
||||
*((uint16_t*)(fb + p)) = color;
|
||||
}
|
||||
|
||||
#endif //_LTDC_H
|
@ -1,115 +0,0 @@
|
||||
|
||||
|
||||
#include "displays/st7789v.h"
|
||||
|
||||
void _154a_init_seq(void) {
|
||||
// most recent manual: https://www.newhavendisplay.com/app_notes/ILI9341.pdf
|
||||
// TEON: Tearing Effect Line On; V-blanking only
|
||||
CMD(0x35);
|
||||
DATA(0x00);
|
||||
|
||||
// COLMOD: Interface Pixel format; 65K color: 16-bit/pixel (RGB 5-6-5 bits
|
||||
// input)
|
||||
CMD(0x3A);
|
||||
DATA(0x55);
|
||||
|
||||
// Display Function Control: gate scan direction 319 -> 0
|
||||
CMD(0xB6);
|
||||
DATA(0x0A);
|
||||
DATA(0xC2);
|
||||
DATA(0x27);
|
||||
DATA(0x00);
|
||||
|
||||
// Interface Control: XOR BGR as ST7789V does
|
||||
CMD(0xF6);
|
||||
DATA(0x09);
|
||||
DATA(0x30);
|
||||
DATA(0x00);
|
||||
|
||||
// the above config is the most important and definitely necessary
|
||||
|
||||
CMD(0xCF);
|
||||
DATA(0x00);
|
||||
DATA(0xC1);
|
||||
DATA(0x30);
|
||||
|
||||
CMD(0xED);
|
||||
DATA(0x64);
|
||||
DATA(0x03);
|
||||
DATA(0x12);
|
||||
DATA(0x81);
|
||||
|
||||
CMD(0xE8);
|
||||
DATA(0x85);
|
||||
DATA(0x10);
|
||||
DATA(0x7A);
|
||||
|
||||
CMD(0xF7);
|
||||
DATA(0x20);
|
||||
|
||||
CMD(0xEA);
|
||||
DATA(0x00);
|
||||
DATA(0x00);
|
||||
|
||||
// power control VRH[5:0]
|
||||
CMD(0xC0);
|
||||
DATA(0x23);
|
||||
|
||||
// power control SAP[2:0] BT[3:0]
|
||||
CMD(0xC1);
|
||||
DATA(0x12);
|
||||
|
||||
// vcm control 1
|
||||
CMD(0xC5);
|
||||
DATA(0x60);
|
||||
DATA(0x44);
|
||||
|
||||
// vcm control 2
|
||||
CMD(0xC7);
|
||||
DATA(0x8A);
|
||||
|
||||
// framerate
|
||||
CMD(0xB1);
|
||||
DATA(0x00);
|
||||
DATA(0x18);
|
||||
|
||||
// 3 gamma func disable
|
||||
CMD(0xF2);
|
||||
DATA(0x00);
|
||||
|
||||
// gamma curve 1
|
||||
CMD(0xE0);
|
||||
DATA(0x0F);
|
||||
DATA(0x2F);
|
||||
DATA(0x2C);
|
||||
DATA(0x0B);
|
||||
DATA(0x0F);
|
||||
DATA(0x09);
|
||||
DATA(0x56);
|
||||
DATA(0xD9);
|
||||
DATA(0x4A);
|
||||
DATA(0x0B);
|
||||
DATA(0x14);
|
||||
DATA(0x05);
|
||||
DATA(0x0C);
|
||||
DATA(0x06);
|
||||
DATA(0x00);
|
||||
|
||||
// gamma curve 2
|
||||
CMD(0xE1);
|
||||
DATA(0x00);
|
||||
DATA(0x10);
|
||||
DATA(0x13);
|
||||
DATA(0x04);
|
||||
DATA(0x10);
|
||||
DATA(0x06);
|
||||
DATA(0x25);
|
||||
DATA(0x26);
|
||||
DATA(0x3B);
|
||||
DATA(0x04);
|
||||
DATA(0x0B);
|
||||
DATA(0x0A);
|
||||
DATA(0x33);
|
||||
DATA(0x39);
|
||||
DATA(0x0F);
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
#ifndef _154A_H_
|
||||
#define _154A_H_
|
||||
|
||||
// ILI9341 IC controller
|
||||
|
||||
void _154a_init_seq(void);
|
||||
|
||||
#endif
|
@ -1,82 +0,0 @@
|
||||
|
||||
#include "displays/st7789v.h"
|
||||
|
||||
void lx154a2411_gamma(void) {
|
||||
// positive voltage correction
|
||||
CMD(0xE0);
|
||||
DATA(0xD0);
|
||||
DATA(0x03);
|
||||
DATA(0x08);
|
||||
DATA(0x0E);
|
||||
DATA(0x11);
|
||||
DATA(0x2B);
|
||||
DATA(0x3B);
|
||||
DATA(0x44);
|
||||
DATA(0x4C);
|
||||
DATA(0x2B);
|
||||
DATA(0x16);
|
||||
DATA(0x15);
|
||||
DATA(0x1E);
|
||||
DATA(0x21);
|
||||
|
||||
// negative voltage correction
|
||||
CMD(0xE1);
|
||||
DATA(0xD0);
|
||||
DATA(0x03);
|
||||
DATA(0x08);
|
||||
DATA(0x0E);
|
||||
DATA(0x11);
|
||||
DATA(0x2B);
|
||||
DATA(0x3B);
|
||||
DATA(0x54);
|
||||
DATA(0x4C);
|
||||
DATA(0x2B);
|
||||
DATA(0x16);
|
||||
DATA(0x15);
|
||||
DATA(0x1E);
|
||||
DATA(0x21);
|
||||
}
|
||||
|
||||
void lx154a2411_init_seq(void) {
|
||||
// most recent manual:
|
||||
// https://www.newhavendisplay.com/appnotes/datasheets/LCDs/ST7789V.pdf
|
||||
// TEON: Tearing Effect Line On; V-blanking only
|
||||
CMD(0x35);
|
||||
DATA(0x00);
|
||||
|
||||
// COLMOD: Interface Pixel format; 65K color: 16-bit/pixel (RGB 5-6-5 bits
|
||||
// input)
|
||||
CMD(0x3A);
|
||||
DATA(0x55);
|
||||
|
||||
// CMD2EN: Commands in command table 2 can be executed when EXTC level is Low
|
||||
CMD(0xDF);
|
||||
DATA(0x5A);
|
||||
DATA(0x69);
|
||||
DATA(0x02);
|
||||
DATA(0x01);
|
||||
|
||||
// LCMCTRL: LCM Control: XOR RGB setting
|
||||
CMD(0xC0);
|
||||
DATA(0x20);
|
||||
|
||||
// GATECTRL: Gate Control; NL = 240 gate lines, first scan line is gate 80.;
|
||||
// gate scan direction 319 -> 0
|
||||
CMD(0xE4);
|
||||
DATA(0x1D);
|
||||
DATA(0x0A);
|
||||
DATA(0x11);
|
||||
|
||||
// INVOFF (20h): Display Inversion Off
|
||||
// INVON (21h): Display Inversion On
|
||||
CMD(0x20);
|
||||
|
||||
// the above config is the most important and definitely necessary
|
||||
|
||||
// PWCTRL1: Power Control 1
|
||||
CMD(0xD0);
|
||||
DATA(0xA4);
|
||||
DATA(0xA1);
|
||||
|
||||
lx154a2411_gamma();
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
#ifndef LX154A2411_H_
|
||||
#define LX154A2411_H_
|
||||
|
||||
// ST7789_V IC controller
|
||||
void lx154a2411_gamma(void);
|
||||
void lx154a2411_init_seq(void);
|
||||
|
||||
#endif
|
@ -1,148 +0,0 @@
|
||||
|
||||
#include "display.h"
|
||||
#include "displays/st7789v.h"
|
||||
#include "touch.h"
|
||||
|
||||
void lx154a2422_gamma(void) {
|
||||
// positive voltage correction
|
||||
CMD(0xE0);
|
||||
DATA(0xD0);
|
||||
DATA(0x0A);
|
||||
DATA(0x10);
|
||||
DATA(0x0A);
|
||||
DATA(0x0A);
|
||||
DATA(0x26);
|
||||
DATA(0x36);
|
||||
DATA(0x34);
|
||||
DATA(0x4D);
|
||||
DATA(0x18);
|
||||
DATA(0x13);
|
||||
DATA(0x14);
|
||||
DATA(0x2F);
|
||||
DATA(0x34);
|
||||
|
||||
// negative voltage correction
|
||||
CMD(0xE1);
|
||||
DATA(0xD0);
|
||||
DATA(0x0A);
|
||||
DATA(0x10);
|
||||
DATA(0x0A);
|
||||
DATA(0x09);
|
||||
DATA(0x26);
|
||||
DATA(0x36);
|
||||
DATA(0x53);
|
||||
DATA(0x4C);
|
||||
DATA(0x18);
|
||||
DATA(0x14);
|
||||
DATA(0x14);
|
||||
DATA(0x2F);
|
||||
DATA(0x34);
|
||||
}
|
||||
|
||||
void lx154a2422_init_seq(void) {
|
||||
// most recent manual:
|
||||
// https://www.newhavendisplay.com/appnotes/datasheets/LCDs/ST7789V.pdf
|
||||
// TEON: Tearing Effect Line On; V-blanking only
|
||||
CMD(0x35);
|
||||
DATA(0x00);
|
||||
|
||||
// COLMOD: Interface Pixel format; 65K color: 16-bit/pixel (RGB 5-6-5 bits
|
||||
// input)
|
||||
CMD(0x3A);
|
||||
DATA(0x55);
|
||||
|
||||
// CMD2EN: Commands in command table 2 can be executed when EXTC level is Low
|
||||
CMD(0xDF);
|
||||
DATA(0x5A);
|
||||
DATA(0x69);
|
||||
DATA(0x02);
|
||||
DATA(0x01);
|
||||
|
||||
// LCMCTRL: LCM Control: XOR RGB setting
|
||||
CMD(0xC0);
|
||||
DATA(0x20);
|
||||
|
||||
// GATECTRL: Gate Control; NL = 240 gate lines, first scan line is gate 80.;
|
||||
// gate scan direction 319 -> 0
|
||||
CMD(0xE4);
|
||||
DATA(0x1D);
|
||||
DATA(0x0A);
|
||||
DATA(0x11);
|
||||
|
||||
// INVOFF (20h): Display Inversion Off
|
||||
// INVON (21h): Display Inversion On
|
||||
CMD(0x21);
|
||||
|
||||
// the above config is the most important and definitely necessary
|
||||
|
||||
// PWCTRL1: Power Control 1
|
||||
CMD(0xD0);
|
||||
DATA(0xA4);
|
||||
DATA(0xA1);
|
||||
|
||||
lx154a2422_gamma();
|
||||
}
|
||||
|
||||
void lx154a2422_rotate(int degrees, display_padding_t* padding) {
|
||||
uint16_t shift = 0;
|
||||
char BX = 0, BY = 0;
|
||||
|
||||
#define RGB (1 << 3)
|
||||
#define ML (1 << 4) // vertical refresh order
|
||||
#define MH (1 << 2) // horizontal refresh order
|
||||
#define MV (1 << 5)
|
||||
#define MX (1 << 6)
|
||||
#define MY (1 << 7)
|
||||
// MADCTL: Memory Data Access Control - reference:
|
||||
// section 8.12 in the ST7789V manual
|
||||
uint8_t display_command_parameter = 0;
|
||||
switch (degrees) {
|
||||
case 0:
|
||||
display_command_parameter = 0;
|
||||
BY = 0;
|
||||
break;
|
||||
case 90:
|
||||
display_command_parameter = MV | MX | MH | ML;
|
||||
BX = 1;
|
||||
shift = 1;
|
||||
break;
|
||||
case 180:
|
||||
display_command_parameter = MX | MY | MH | ML;
|
||||
BY = 0;
|
||||
shift = 1;
|
||||
break;
|
||||
case 270:
|
||||
display_command_parameter = MV | MY;
|
||||
BX = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
CMD(0x36);
|
||||
DATA(display_command_parameter);
|
||||
|
||||
if (shift) {
|
||||
// GATECTRL: Gate Control; NL = 240 gate lines, first scan line is
|
||||
// gate 80.; gate scan direction 319 -> 0
|
||||
CMD(0xE4);
|
||||
DATA(0x1D);
|
||||
DATA(0x00);
|
||||
DATA(0x11);
|
||||
} else {
|
||||
// GATECTRL: Gate Control; NL = 240 gate lines, first scan line is
|
||||
// gate 80.; gate scan direction 319 -> 0
|
||||
CMD(0xE4);
|
||||
DATA(0x1D);
|
||||
DATA(0x0A);
|
||||
DATA(0x11);
|
||||
}
|
||||
|
||||
// reset the column and page extents
|
||||
display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1);
|
||||
|
||||
padding->x = BX ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0;
|
||||
padding->y = BY ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0;
|
||||
}
|
||||
|
||||
uint32_t lx154a2422_transform_touch_coords(uint16_t x, uint16_t y) {
|
||||
return touch_pack_xy(x, y);
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
#ifndef LX154A2422_H_
|
||||
#define LX154A2422_H_
|
||||
|
||||
#include "displays/st7789v.h"
|
||||
|
||||
void lx154a2422_init_seq(void);
|
||||
void lx154a2422_gamma(void);
|
||||
void lx154a2422_rotate(int degrees, display_padding_t* padding);
|
||||
uint32_t lx154a2422_transform_touch_coords(uint16_t x, uint16_t y);
|
||||
|
||||
#endif
|
@ -1,158 +0,0 @@
|
||||
#include "display.h"
|
||||
#include "displays/st7789v.h"
|
||||
|
||||
void tf15411a_init_seq(void) {
|
||||
// Inter Register Enable1
|
||||
CMD(0xFE);
|
||||
|
||||
// Inter Register Enable2
|
||||
CMD(0xEF);
|
||||
|
||||
// TEON: Tearing Effect Line On; V-blanking only
|
||||
CMD(0x35);
|
||||
DATA(0x00);
|
||||
|
||||
// COLMOD: Interface Pixel format; 65K color: 16-bit/pixel (RGB 5-6-5 bits
|
||||
// input)
|
||||
CMD(0x3A);
|
||||
DATA(0x55);
|
||||
|
||||
// Frame Rate
|
||||
// CMD(0xE8); DATA(0x12); DATA(0x00);
|
||||
|
||||
// Power Control 2
|
||||
CMD(0xC3);
|
||||
DATA(0x27);
|
||||
|
||||
// Power Control 3
|
||||
CMD(0xC4);
|
||||
DATA(0x18);
|
||||
|
||||
// Power Control 4
|
||||
CMD(0xC9);
|
||||
DATA(0x1F);
|
||||
|
||||
CMD(0xC5);
|
||||
DATA(0x0F);
|
||||
|
||||
CMD(0xC6);
|
||||
DATA(0x00);
|
||||
|
||||
CMD(0xC7);
|
||||
DATA(0x10);
|
||||
|
||||
CMD(0xC8);
|
||||
DATA(0x01);
|
||||
|
||||
CMD(0xFF);
|
||||
DATA(0x62);
|
||||
|
||||
CMD(0x99);
|
||||
DATA(0x3E);
|
||||
|
||||
CMD(0x9D);
|
||||
DATA(0x4B);
|
||||
|
||||
CMD(0x8E);
|
||||
DATA(0x0F);
|
||||
|
||||
// SET_GAMMA1
|
||||
CMD(0xF0);
|
||||
DATA(0x8F);
|
||||
DATA(0x1B);
|
||||
DATA(0x05);
|
||||
DATA(0x06);
|
||||
DATA(0x07);
|
||||
DATA(0x42);
|
||||
|
||||
// SET_GAMMA3
|
||||
CMD(0xF2);
|
||||
DATA(0x5C);
|
||||
DATA(0x1F);
|
||||
DATA(0x12);
|
||||
DATA(0x10);
|
||||
DATA(0x07);
|
||||
DATA(0x43);
|
||||
|
||||
// SET_GAMMA2
|
||||
CMD(0xF1);
|
||||
DATA(0x59);
|
||||
DATA(0xCF);
|
||||
DATA(0xCF);
|
||||
DATA(0x35);
|
||||
DATA(0x37);
|
||||
DATA(0x8F);
|
||||
|
||||
// SET_GAMMA4
|
||||
CMD(0xF3);
|
||||
DATA(0x58);
|
||||
DATA(0xCF);
|
||||
DATA(0xCF);
|
||||
DATA(0x35);
|
||||
DATA(0x37);
|
||||
DATA(0x8F);
|
||||
}
|
||||
|
||||
void tf15411a_rotate(int degrees, display_padding_t* padding) {
|
||||
uint16_t shift = 0;
|
||||
char BX = 0, BY = 0;
|
||||
|
||||
#define RGB (1 << 3)
|
||||
#define ML (1 << 4) // vertical refresh order
|
||||
#define MH (1 << 2) // horizontal refresh order
|
||||
#define MV (1 << 5)
|
||||
#define MX (1 << 6)
|
||||
#define MY (1 << 7)
|
||||
// MADCTL: Memory Data Access Control - reference:
|
||||
// section 9.3 in the ILI9341 manual
|
||||
// section 6.2.18 in the GC9307 manual
|
||||
// section 8.12 in the ST7789V manual
|
||||
uint8_t display_command_parameter = 0;
|
||||
switch (degrees) {
|
||||
case 0:
|
||||
display_command_parameter = 0;
|
||||
BY = 1;
|
||||
break;
|
||||
case 90:
|
||||
display_command_parameter = MV | MX | MH | ML;
|
||||
BX = 0;
|
||||
shift = 1;
|
||||
break;
|
||||
case 180:
|
||||
display_command_parameter = MX | MY | MH | ML;
|
||||
BY = 1;
|
||||
shift = 1;
|
||||
break;
|
||||
case 270:
|
||||
display_command_parameter = MV | MY;
|
||||
BX = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
display_command_parameter ^= RGB | MY; // XOR RGB and MY settings
|
||||
|
||||
CMD(0x36);
|
||||
DATA(display_command_parameter);
|
||||
|
||||
if (shift) {
|
||||
// GATECTRL: Gate Control; NL = 240 gate lines, first scan line is
|
||||
// gate 80.; gate scan direction 319 -> 0
|
||||
CMD(0xE4);
|
||||
DATA(0x1D);
|
||||
DATA(0x00);
|
||||
DATA(0x11);
|
||||
} else {
|
||||
// GATECTRL: Gate Control; NL = 240 gate lines, first scan line is
|
||||
// gate 80.; gate scan direction 319 -> 0
|
||||
CMD(0xE4);
|
||||
DATA(0x1D);
|
||||
DATA(0x0A);
|
||||
DATA(0x11);
|
||||
}
|
||||
|
||||
// reset the column and page extents
|
||||
display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1);
|
||||
|
||||
padding->x = BX ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0;
|
||||
padding->y = BY ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0;
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
#ifndef TF15411A_H_
|
||||
#define TF15411A_H_
|
||||
|
||||
// GC9307 IC controller
|
||||
|
||||
void tf15411a_init_seq(void);
|
||||
void tf15411a_rotate(int degrees, display_padding_t* padding);
|
||||
|
||||
#endif
|
@ -1,769 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "backlight_pwm.h"
|
||||
#include "display.h"
|
||||
#include "irq.h"
|
||||
#include "memzero.h"
|
||||
#include "st7789v.h"
|
||||
|
||||
#ifdef TREZOR_MODEL_T
|
||||
#include "displays/panels/154a.h"
|
||||
#include "displays/panels/lx154a2411.h"
|
||||
#include "displays/panels/lx154a2422.h"
|
||||
#include "displays/panels/tf15411a.h"
|
||||
#else
|
||||
#include "displays/panels/lx154a2482.h"
|
||||
#endif
|
||||
|
||||
// using const volatile instead of #define results in binaries that change
|
||||
// only in 1-byte when the flag changes.
|
||||
// using #define leads compiler to over-optimize the code leading to bigger
|
||||
// differencies in the resulting binaries.
|
||||
const volatile uint8_t DISPLAY_ST7789V_INVERT_COLORS = 1;
|
||||
|
||||
#ifndef FMC_BANK1
|
||||
#define FMC_BANK1 0x60000000U
|
||||
#endif
|
||||
|
||||
#define DISPLAY_MEMORY_BASE FMC_BANK1
|
||||
#define DISPLAY_MEMORY_PIN 16
|
||||
#ifdef DISPLAY_I8080_16BIT_DW
|
||||
#define DISPLAY_ADDR_SHIFT 2
|
||||
#elif DISPLAY_I8080_8BIT_DW
|
||||
#define DISPLAY_ADDR_SHIFT 1
|
||||
#endif
|
||||
|
||||
__IO DISP_MEM_TYPE *const DISPLAY_CMD_ADDRESS =
|
||||
(__IO DISP_MEM_TYPE *const)((uint32_t)DISPLAY_MEMORY_BASE);
|
||||
__IO DISP_MEM_TYPE *const DISPLAY_DATA_ADDRESS =
|
||||
(__IO DISP_MEM_TYPE *const)((uint32_t)DISPLAY_MEMORY_BASE |
|
||||
(DISPLAY_ADDR_SHIFT << DISPLAY_MEMORY_PIN));
|
||||
|
||||
#ifdef FRAMEBUFFER
|
||||
#ifndef STM32U5
|
||||
#error Framebuffer only supported on STM32U5 for now
|
||||
#endif
|
||||
|
||||
#ifndef BOARDLOADER
|
||||
#include "bg_copy.h"
|
||||
#endif
|
||||
|
||||
#define DATA_TRANSFER(X) \
|
||||
DATA((X) & 0xFF); \
|
||||
DATA((X) >> 8)
|
||||
|
||||
__attribute__((section(".fb1")))
|
||||
ALIGN_32BYTES(static uint16_t PhysFrameBuffer0[DISPLAY_RESX * DISPLAY_RESY]);
|
||||
__attribute__((section(".fb2")))
|
||||
ALIGN_32BYTES(static uint16_t PhysFrameBuffer1[DISPLAY_RESX * DISPLAY_RESY]);
|
||||
|
||||
__attribute__((
|
||||
section(".framebuffer_select"))) static uint32_t act_frame_buffer = 0;
|
||||
|
||||
#ifndef BOARDLOADER
|
||||
static bool pending_fb_switch = false;
|
||||
#endif
|
||||
|
||||
static uint16_t window_x0 = 0;
|
||||
static uint16_t window_y0 = 0;
|
||||
static uint16_t window_x1 = 0;
|
||||
static uint16_t window_y1 = 0;
|
||||
static uint16_t cursor_x = 0;
|
||||
static uint16_t cursor_y = 0;
|
||||
|
||||
#else
|
||||
#define DATA_TRANSFER(X) PIXELDATA(X)
|
||||
#endif
|
||||
|
||||
// section "9.1.3 RDDID (04h): Read Display ID"
|
||||
// of ST7789V datasheet
|
||||
#define DISPLAY_ID_ST7789V 0x858552U
|
||||
|
||||
// section "6.2.1. Read display identification information (04h)"
|
||||
// of GC9307 datasheet
|
||||
#define DISPLAY_ID_GC9307 0x009307U
|
||||
|
||||
// section "8.3.23 Read ID4 (D3h)"
|
||||
// of ILI9341V datasheet
|
||||
#define DISPLAY_ID_ILI9341V 0x009341U
|
||||
|
||||
static int DISPLAY_ORIENTATION = -1;
|
||||
static display_padding_t DISPLAY_PADDING = {0};
|
||||
|
||||
void display_pixeldata_dirty(void) {}
|
||||
|
||||
#ifdef DISPLAY_IDENTIFY
|
||||
|
||||
static uint32_t read_display_id(uint8_t command) {
|
||||
volatile uint8_t c = 0;
|
||||
uint32_t id = 0;
|
||||
CMD(command);
|
||||
c = *DISPLAY_DATA_ADDRESS; // first returned value is a dummy value and
|
||||
// should be discarded
|
||||
c = *DISPLAY_DATA_ADDRESS;
|
||||
id |= (c << 16);
|
||||
c = *DISPLAY_DATA_ADDRESS;
|
||||
id |= (c << 8);
|
||||
c = *DISPLAY_DATA_ADDRESS;
|
||||
id |= c;
|
||||
return id;
|
||||
}
|
||||
|
||||
static uint32_t display_identify(void) {
|
||||
static uint32_t id = 0x000000U;
|
||||
static char id_set = 0;
|
||||
|
||||
if (id_set) return id; // return if id has been already set
|
||||
|
||||
id = read_display_id(0x04); // RDDID: Read Display ID
|
||||
// the default RDDID for ILI9341 should be 0x8000.
|
||||
// some display modules return 0x0.
|
||||
// the ILI9341 has an extra id, let's check it here.
|
||||
if ((id != DISPLAY_ID_ST7789V) &&
|
||||
(id != DISPLAY_ID_GC9307)) { // if not ST7789V and not GC9307
|
||||
uint32_t id4 = read_display_id(0xD3); // Read ID4
|
||||
if (id4 == DISPLAY_ID_ILI9341V) { // definitely found a ILI9341
|
||||
id = id4;
|
||||
}
|
||||
}
|
||||
id_set = 1;
|
||||
return id;
|
||||
}
|
||||
#else
|
||||
static uint32_t display_identify(void) { return DISPLAY_ID_ST7789V; }
|
||||
#endif
|
||||
|
||||
bool display_is_inverted() {
|
||||
bool inv_on = false;
|
||||
uint32_t id = display_identify();
|
||||
if (id == DISPLAY_ID_ST7789V) {
|
||||
volatile uint8_t c = 0;
|
||||
CMD(0x09); // read display status
|
||||
c = *DISPLAY_DATA_ADDRESS; // don't care
|
||||
c = *DISPLAY_DATA_ADDRESS; // don't care
|
||||
c = *DISPLAY_DATA_ADDRESS; // don't care
|
||||
c = *DISPLAY_DATA_ADDRESS;
|
||||
if (c & 0x20) {
|
||||
inv_on = true;
|
||||
}
|
||||
c = *DISPLAY_DATA_ADDRESS; // don't care
|
||||
}
|
||||
|
||||
return inv_on;
|
||||
}
|
||||
|
||||
void display_reset_state() {}
|
||||
|
||||
static void __attribute__((unused)) display_sleep(void) {
|
||||
uint32_t id = display_identify();
|
||||
if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) ||
|
||||
(id == DISPLAY_ID_ST7789V)) {
|
||||
CMD(0x28); // DISPOFF: Display Off
|
||||
CMD(0x10); // SLPIN: Sleep in
|
||||
HAL_Delay(5); // need to wait 5 milliseconds after "sleep in" before
|
||||
// sending any new commands
|
||||
}
|
||||
}
|
||||
|
||||
static void display_unsleep(void) {
|
||||
uint32_t id = display_identify();
|
||||
if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) ||
|
||||
(id == DISPLAY_ID_ST7789V)) {
|
||||
CMD(0x11); // SLPOUT: Sleep Out
|
||||
HAL_Delay(5); // need to wait 5 milliseconds after "sleep out" before
|
||||
// sending any new commands
|
||||
CMD(0x29); // DISPON: Display On
|
||||
}
|
||||
}
|
||||
|
||||
void panel_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
x0 += DISPLAY_PADDING.x;
|
||||
x1 += DISPLAY_PADDING.x;
|
||||
y0 += DISPLAY_PADDING.y;
|
||||
y1 += DISPLAY_PADDING.y;
|
||||
uint32_t id = display_identify();
|
||||
if ((id == DISPLAY_ID_ILI9341V) || (id == DISPLAY_ID_GC9307) ||
|
||||
(id == DISPLAY_ID_ST7789V)) {
|
||||
CMD(0x2A);
|
||||
DATA(x0 >> 8);
|
||||
DATA(x0 & 0xFF);
|
||||
DATA(x1 >> 8);
|
||||
DATA(x1 & 0xFF); // column addr set
|
||||
CMD(0x2B);
|
||||
DATA(y0 >> 8);
|
||||
DATA(y0 & 0xFF);
|
||||
DATA(y1 >> 8);
|
||||
DATA(y1 & 0xFF); // row addr set
|
||||
CMD(0x2C);
|
||||
}
|
||||
}
|
||||
|
||||
int display_orientation(int degrees) {
|
||||
if (degrees != DISPLAY_ORIENTATION) {
|
||||
if (degrees == 0 || degrees == 90 || degrees == 180 || degrees == 270) {
|
||||
DISPLAY_ORIENTATION = degrees;
|
||||
|
||||
panel_set_window(0, 0, MAX_DISPLAY_RESX - 1, MAX_DISPLAY_RESY - 1);
|
||||
#ifdef FRAMEBUFFER
|
||||
memzero(PhysFrameBuffer1, sizeof(PhysFrameBuffer1));
|
||||
memzero(PhysFrameBuffer0, sizeof(PhysFrameBuffer0));
|
||||
#endif
|
||||
for (uint32_t i = 0; i < MAX_DISPLAY_RESX * MAX_DISPLAY_RESY; i++) {
|
||||
// 2 bytes per pixel because we're using RGB 5-6-5 format
|
||||
DATA_TRANSFER(0x0000);
|
||||
}
|
||||
#ifdef TREZOR_MODEL_T
|
||||
uint32_t id = display_identify();
|
||||
if (id == DISPLAY_ID_GC9307) {
|
||||
tf15411a_rotate(degrees, &DISPLAY_PADDING);
|
||||
} else {
|
||||
lx154a2422_rotate(degrees, &DISPLAY_PADDING);
|
||||
}
|
||||
#else
|
||||
lx154a2482_rotate(degrees, &DISPLAY_PADDING);
|
||||
#endif
|
||||
panel_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1);
|
||||
}
|
||||
}
|
||||
return DISPLAY_ORIENTATION;
|
||||
}
|
||||
|
||||
int display_get_orientation(void) { return DISPLAY_ORIENTATION; }
|
||||
|
||||
static inline uint32_t is_mode_handler(void) {
|
||||
uint32_t r0;
|
||||
__asm__ volatile("mrs %0, ipsr" : "=r"(r0));
|
||||
return (r0 & 0x1FF) != 0;
|
||||
}
|
||||
|
||||
int display_backlight(int val) {
|
||||
#ifdef FRAMEBUFFER
|
||||
#ifndef BOARDLOADER
|
||||
// wait for DMA transfer to finish before changing backlight
|
||||
// so that we know that panel has current data
|
||||
if (backlight_pwm_get() != val && !is_mode_handler()) {
|
||||
bg_copy_wait();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return backlight_pwm_set(val);
|
||||
}
|
||||
|
||||
void display_init_seq(void) {
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET); // LCD_RST/PC14
|
||||
// wait 10 milliseconds. only needs to be low for 10 microseconds.
|
||||
// my dev display module ties display reset and touch panel reset together.
|
||||
// keeping this low for max(display_reset_time, ctpm_reset_time) aids
|
||||
// development and does not hurt.
|
||||
HAL_Delay(10);
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_SET); // LCD_RST/PC14
|
||||
// max wait time for hardware reset is 120 milliseconds
|
||||
// (experienced display flakiness using only 5ms wait before sending commands)
|
||||
HAL_Delay(120);
|
||||
|
||||
// identify the controller we will communicate with
|
||||
#ifdef TREZOR_MODEL_T
|
||||
uint32_t id = display_identify();
|
||||
if (id == DISPLAY_ID_GC9307) {
|
||||
tf15411a_init_seq();
|
||||
} else if (id == DISPLAY_ID_ST7789V) {
|
||||
if (DISPLAY_ST7789V_INVERT_COLORS) {
|
||||
lx154a2422_init_seq();
|
||||
} else {
|
||||
lx154a2411_init_seq();
|
||||
}
|
||||
} else if (id == DISPLAY_ID_ILI9341V) {
|
||||
_154a_init_seq();
|
||||
}
|
||||
#else
|
||||
lx154a2482_init_seq();
|
||||
#endif
|
||||
|
||||
display_unsleep();
|
||||
}
|
||||
|
||||
void display_setup_fmc(void) {
|
||||
// Reference UM1725 "Description of STM32F4 HAL and LL drivers",
|
||||
// section 64.2.1 "How to use this driver"
|
||||
SRAM_HandleTypeDef external_display_data_sram = {0};
|
||||
external_display_data_sram.Instance = FMC_NORSRAM_DEVICE;
|
||||
external_display_data_sram.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
|
||||
external_display_data_sram.Init.NSBank = FMC_NORSRAM_BANK1;
|
||||
external_display_data_sram.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
|
||||
external_display_data_sram.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
|
||||
#ifdef DISPLAY_I8080_16BIT_DW
|
||||
external_display_data_sram.Init.MemoryDataWidth =
|
||||
FMC_NORSRAM_MEM_BUS_WIDTH_16;
|
||||
#elif DISPLAY_I8080_8BIT_DW
|
||||
external_display_data_sram.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_8;
|
||||
#endif
|
||||
external_display_data_sram.Init.BurstAccessMode =
|
||||
FMC_BURST_ACCESS_MODE_DISABLE;
|
||||
external_display_data_sram.Init.WaitSignalPolarity =
|
||||
FMC_WAIT_SIGNAL_POLARITY_LOW;
|
||||
external_display_data_sram.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
|
||||
external_display_data_sram.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
|
||||
external_display_data_sram.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
|
||||
external_display_data_sram.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
|
||||
external_display_data_sram.Init.AsynchronousWait =
|
||||
FMC_ASYNCHRONOUS_WAIT_DISABLE;
|
||||
external_display_data_sram.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
|
||||
external_display_data_sram.Init.ContinuousClock =
|
||||
FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
|
||||
external_display_data_sram.Init.PageSize = FMC_PAGE_SIZE_NONE;
|
||||
|
||||
#ifdef STM32F4
|
||||
// reference RM0090 section 37.5 Table 259, 37.5.4, Mode 1 SRAM, and 37.5.6
|
||||
FMC_NORSRAM_TimingTypeDef normal_mode_timing = {0};
|
||||
normal_mode_timing.AddressSetupTime = 5;
|
||||
normal_mode_timing.AddressHoldTime = 1; // don't care
|
||||
normal_mode_timing.DataSetupTime = 6;
|
||||
normal_mode_timing.BusTurnAroundDuration = 0; // don't care
|
||||
normal_mode_timing.CLKDivision = 2; // don't care
|
||||
normal_mode_timing.DataLatency = 2; // don't care
|
||||
normal_mode_timing.AccessMode = FMC_ACCESS_MODE_A;
|
||||
|
||||
HAL_SRAM_Init(&external_display_data_sram, &normal_mode_timing, NULL);
|
||||
|
||||
#else
|
||||
external_display_data_sram.Init.ExtendedMode = FMC_EXTENDED_MODE_ENABLE;
|
||||
|
||||
FMC_NORSRAM_TimingTypeDef normal_mode_timing = {0};
|
||||
normal_mode_timing.AddressSetupTime = 15;
|
||||
normal_mode_timing.AddressHoldTime = 1; // don't care
|
||||
normal_mode_timing.DataSetupTime = 11;
|
||||
normal_mode_timing.BusTurnAroundDuration = 0; // don't care
|
||||
normal_mode_timing.CLKDivision = 2; // don't care
|
||||
normal_mode_timing.DataLatency = 2; // don't care
|
||||
normal_mode_timing.DataHoldTime = 0;
|
||||
normal_mode_timing.AccessMode = FMC_ACCESS_MODE_A;
|
||||
|
||||
FMC_NORSRAM_TimingTypeDef ext_mode_timing = {0};
|
||||
ext_mode_timing.AddressSetupTime = 4;
|
||||
ext_mode_timing.AddressHoldTime = 1; // don't care
|
||||
ext_mode_timing.DataSetupTime = 5;
|
||||
ext_mode_timing.BusTurnAroundDuration = 0; // don't care
|
||||
ext_mode_timing.CLKDivision = 2; // don't care
|
||||
ext_mode_timing.DataLatency = 2; // don't care
|
||||
ext_mode_timing.DataHoldTime = 3;
|
||||
ext_mode_timing.AccessMode = FMC_ACCESS_MODE_A;
|
||||
|
||||
HAL_SRAM_Init(&external_display_data_sram, &normal_mode_timing,
|
||||
&ext_mode_timing);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef FRAMEBUFFER
|
||||
void display_setup_te_interrupt(void) {
|
||||
#ifdef DISPLAY_TE_PIN
|
||||
EXTI_HandleTypeDef EXTI_Handle = {0};
|
||||
EXTI_ConfigTypeDef EXTI_Config = {0};
|
||||
EXTI_Config.GPIOSel = DISPLAY_TE_INTERRUPT_GPIOSEL;
|
||||
EXTI_Config.Line = DISPLAY_TE_INTERRUPT_EXTI_LINE;
|
||||
EXTI_Config.Mode = EXTI_MODE_INTERRUPT;
|
||||
EXTI_Config.Trigger = EXTI_TRIGGER_RISING;
|
||||
HAL_EXTI_SetConfigLine(&EXTI_Handle, &EXTI_Config);
|
||||
|
||||
// setup interrupt for tearing effect pin
|
||||
NVIC_SetPriority(DISPLAY_TE_INTERRUPT_NUM, IRQ_PRI_NORMAL);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void display_init_all(void) {
|
||||
// init peripherals
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
__HAL_RCC_FMC_CLK_ENABLE();
|
||||
|
||||
backlight_pwm_init(BACKLIGHT_RESET);
|
||||
|
||||
#ifdef STM32F4
|
||||
#define DISPLAY_GPIO_SPEED GPIO_SPEED_FREQ_VERY_HIGH
|
||||
#else
|
||||
#define DISPLAY_GPIO_SPEED GPIO_SPEED_FREQ_LOW
|
||||
#endif
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
|
||||
// LCD_RST/PC14
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = DISPLAY_GPIO_SPEED;
|
||||
GPIO_InitStructure.Alternate = 0;
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_14;
|
||||
// default to keeping display in reset
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET);
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
|
||||
#ifdef DISPLAY_TE_PIN
|
||||
// LCD_FMARK (tearing effect)
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = DISPLAY_GPIO_SPEED;
|
||||
GPIO_InitStructure.Alternate = 0;
|
||||
GPIO_InitStructure.Pin = DISPLAY_TE_PIN;
|
||||
HAL_GPIO_Init(DISPLAY_TE_PORT, &GPIO_InitStructure);
|
||||
#endif
|
||||
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = DISPLAY_GPIO_SPEED;
|
||||
GPIO_InitStructure.Alternate = GPIO_AF12_FMC;
|
||||
// LCD_CS/PD7 LCD_RS/PD11 LCD_RD/PD4 LCD_WR/PD5
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_7 | GPIO_PIN_11 | GPIO_PIN_4 | GPIO_PIN_5;
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||||
// LCD_D0/PD14 LCD_D1/PD15 LCD_D2/PD0 LCD_D3/PD1
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_14 | GPIO_PIN_15 | GPIO_PIN_0 | GPIO_PIN_1;
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||||
// LCD_D4/PE7 LCD_D5/PE8 LCD_D6/PE9 LCD_D7/PE10
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
|
||||
#ifdef DISPLAY_I8080_16BIT_DW
|
||||
// LCD_D8/PE11 LCD_D9/PE12 LCD_D10/PE13 LCD_D11/PE14
|
||||
GPIO_InitStructure.Pin =
|
||||
GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
|
||||
// LCD_D12/PE15
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_15;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
|
||||
// LCD_D13/PD8 LCD_D14/PD9 LCD_D15/PD10
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||||
#endif
|
||||
|
||||
display_setup_fmc();
|
||||
|
||||
display_init_seq();
|
||||
|
||||
display_set_little_endian();
|
||||
|
||||
panel_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1);
|
||||
|
||||
#ifdef FRAMEBUFFER
|
||||
display_setup_te_interrupt();
|
||||
#endif
|
||||
}
|
||||
|
||||
void display_reinit(void) {
|
||||
// reinitialize FMC to set correct timing, have to do this in reinit because
|
||||
// boardloader is fixed.
|
||||
display_setup_fmc();
|
||||
|
||||
// important for model T as this is not set in boardloader
|
||||
display_set_little_endian();
|
||||
|
||||
backlight_pwm_init(BACKLIGHT_RETAIN);
|
||||
|
||||
#ifdef TREZOR_MODEL_T
|
||||
uint32_t id = display_identify();
|
||||
if (id == DISPLAY_ID_ST7789V && display_is_inverted()) {
|
||||
// newest TT display - set proper gamma
|
||||
lx154a2422_gamma();
|
||||
} else if (id == DISPLAY_ID_ST7789V) {
|
||||
lx154a2411_gamma();
|
||||
}
|
||||
#else
|
||||
lx154a2482_init_seq();
|
||||
#endif
|
||||
|
||||
DISPLAY_ORIENTATION = 0;
|
||||
panel_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1);
|
||||
|
||||
#ifdef FRAMEBUFFER
|
||||
display_setup_te_interrupt();
|
||||
#endif
|
||||
}
|
||||
|
||||
void display_set_little_endian(void) {
|
||||
uint32_t id = display_identify();
|
||||
if (id == DISPLAY_ID_GC9307) {
|
||||
// CANNOT SET ENDIAN FOR GC9307
|
||||
} else if (id == DISPLAY_ID_ST7789V) {
|
||||
CMD(0xB0);
|
||||
DATA(0x00);
|
||||
DATA(0xF8);
|
||||
} else if (id == DISPLAY_ID_ILI9341V) {
|
||||
// Interface Control: XOR BGR as ST7789V does
|
||||
CMD(0xF6);
|
||||
DATA(0x09);
|
||||
DATA(0x30);
|
||||
DATA(0x20);
|
||||
}
|
||||
}
|
||||
|
||||
void display_set_big_endian(void) {
|
||||
uint32_t id = display_identify();
|
||||
if (id == DISPLAY_ID_GC9307) {
|
||||
// CANNOT SET ENDIAN FOR GC9307
|
||||
} else if (id == DISPLAY_ID_ST7789V) {
|
||||
CMD(0xB0);
|
||||
DATA(0x00);
|
||||
DATA(0xF0);
|
||||
} else if (id == DISPLAY_ID_ILI9341V) {
|
||||
// Interface Control: XOR BGR as ST7789V does
|
||||
CMD(0xF6);
|
||||
DATA(0x09);
|
||||
DATA(0x30);
|
||||
DATA(0x00);
|
||||
}
|
||||
}
|
||||
|
||||
const char *display_save(const char *prefix) { return NULL; }
|
||||
|
||||
void display_clear_save(void) {}
|
||||
|
||||
#ifdef FRAMEBUFFER
|
||||
|
||||
void display_pixeldata(uint16_t c) {
|
||||
uint16_t *address = 0;
|
||||
|
||||
if (act_frame_buffer == 0) {
|
||||
address = PhysFrameBuffer1;
|
||||
} else {
|
||||
address = PhysFrameBuffer0;
|
||||
}
|
||||
|
||||
/* Get the rectangle start address */
|
||||
address += cursor_y * DISPLAY_RESX + cursor_x;
|
||||
|
||||
*address = c;
|
||||
|
||||
cursor_x++;
|
||||
if (cursor_x > window_x1) {
|
||||
cursor_x = window_x0;
|
||||
cursor_y++;
|
||||
}
|
||||
if (cursor_y > window_y1) {
|
||||
cursor_y = window_y0;
|
||||
}
|
||||
}
|
||||
|
||||
void display_sync(void) {}
|
||||
|
||||
#ifndef BOARDLOADER
|
||||
void DISPLAY_TE_INTERRUPT_HANDLER(void) {
|
||||
NVIC_DisableIRQ(DISPLAY_TE_INTERRUPT_NUM);
|
||||
|
||||
if (act_frame_buffer == 1) {
|
||||
bg_copy_start_const_out_8((uint8_t *)PhysFrameBuffer1,
|
||||
(uint8_t *)DISPLAY_DATA_ADDRESS,
|
||||
DISPLAY_RESX * DISPLAY_RESY * 2, NULL);
|
||||
|
||||
} else {
|
||||
bg_copy_start_const_out_8((uint8_t *)PhysFrameBuffer0,
|
||||
(uint8_t *)DISPLAY_DATA_ADDRESS,
|
||||
DISPLAY_RESX * DISPLAY_RESY * 2, NULL);
|
||||
}
|
||||
|
||||
pending_fb_switch = false;
|
||||
__HAL_GPIO_EXTI_CLEAR_FLAG(DISPLAY_TE_PIN);
|
||||
}
|
||||
|
||||
static void wait_for_fb_switch(void) {
|
||||
while (pending_fb_switch) {
|
||||
__WFI();
|
||||
}
|
||||
bg_copy_wait();
|
||||
}
|
||||
#endif
|
||||
|
||||
static void copy_fb_to_display(uint16_t *fb) {
|
||||
for (int i = 0; i < DISPLAY_RESX * DISPLAY_RESY; i++) {
|
||||
// 2 bytes per pixel because we're using RGB 5-6-5 format
|
||||
DATA_TRANSFER(fb[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void switch_fb_manually(void) {
|
||||
// sync with the panel refresh
|
||||
while (GPIO_PIN_SET == HAL_GPIO_ReadPin(DISPLAY_TE_PORT, DISPLAY_TE_PIN)) {
|
||||
}
|
||||
while (GPIO_PIN_RESET == HAL_GPIO_ReadPin(DISPLAY_TE_PORT, DISPLAY_TE_PIN)) {
|
||||
}
|
||||
|
||||
if (act_frame_buffer == 0) {
|
||||
act_frame_buffer = 1;
|
||||
copy_fb_to_display(PhysFrameBuffer1);
|
||||
memcpy(PhysFrameBuffer0, PhysFrameBuffer1, sizeof(PhysFrameBuffer1));
|
||||
|
||||
} else {
|
||||
act_frame_buffer = 0;
|
||||
copy_fb_to_display(PhysFrameBuffer0);
|
||||
memcpy(PhysFrameBuffer1, PhysFrameBuffer0, sizeof(PhysFrameBuffer1));
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef BOARDLOADER
|
||||
static void switch_fb_in_backround(void) {
|
||||
if (act_frame_buffer == 0) {
|
||||
act_frame_buffer = 1;
|
||||
|
||||
memcpy(PhysFrameBuffer0, PhysFrameBuffer1, sizeof(PhysFrameBuffer1));
|
||||
|
||||
pending_fb_switch = true;
|
||||
__HAL_GPIO_EXTI_CLEAR_FLAG(DISPLAY_TE_PIN);
|
||||
NVIC_EnableIRQ(DISPLAY_TE_INTERRUPT_NUM);
|
||||
} else {
|
||||
act_frame_buffer = 0;
|
||||
memcpy(PhysFrameBuffer1, PhysFrameBuffer0, sizeof(PhysFrameBuffer1));
|
||||
|
||||
pending_fb_switch = true;
|
||||
__HAL_GPIO_EXTI_CLEAR_FLAG(DISPLAY_TE_PIN);
|
||||
NVIC_EnableIRQ(DISPLAY_TE_INTERRUPT_NUM);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void display_refresh(void) {
|
||||
#ifndef BOARDLOADER
|
||||
wait_for_fb_switch();
|
||||
|
||||
if (is_mode_handler()) {
|
||||
switch_fb_manually();
|
||||
} else {
|
||||
switch_fb_in_backround();
|
||||
}
|
||||
#else
|
||||
switch_fb_manually();
|
||||
#endif
|
||||
}
|
||||
|
||||
void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
window_x0 = x0;
|
||||
window_y0 = y0;
|
||||
window_x1 = x1;
|
||||
window_y1 = y1;
|
||||
cursor_x = x0;
|
||||
cursor_y = y0;
|
||||
}
|
||||
|
||||
uint8_t *display_get_wr_addr(void) {
|
||||
uint32_t address = 0;
|
||||
|
||||
if (act_frame_buffer == 0) {
|
||||
address = (uint32_t)PhysFrameBuffer1;
|
||||
} else {
|
||||
address = (uint32_t)PhysFrameBuffer0;
|
||||
}
|
||||
|
||||
/* Get the rectangle start address */
|
||||
address = (address + (2 * (cursor_y * DISPLAY_RESX + cursor_x)));
|
||||
|
||||
return (uint8_t *)address;
|
||||
}
|
||||
|
||||
uint32_t *display_get_fb_addr(void) {
|
||||
uint32_t address = 0;
|
||||
|
||||
if (act_frame_buffer == 0) {
|
||||
address = (uint32_t)PhysFrameBuffer1;
|
||||
} else {
|
||||
address = (uint32_t)PhysFrameBuffer0;
|
||||
}
|
||||
|
||||
return (uint32_t *)address;
|
||||
}
|
||||
uint16_t display_get_window_width(void) { return window_x1 - window_x0 + 1; }
|
||||
|
||||
uint16_t display_get_window_height(void) { return window_y1 - window_y0 + 1; }
|
||||
|
||||
void display_shift_window(uint16_t pixels) {
|
||||
uint16_t w = display_get_window_width();
|
||||
uint16_t h = display_get_window_height();
|
||||
|
||||
uint16_t line_rem = w - (cursor_x - window_x0);
|
||||
|
||||
if (pixels < line_rem) {
|
||||
cursor_x += pixels;
|
||||
return;
|
||||
}
|
||||
|
||||
// start of next line
|
||||
pixels = pixels - line_rem;
|
||||
cursor_x = window_x0;
|
||||
cursor_y++;
|
||||
|
||||
// add the rest of pixels
|
||||
cursor_y = window_y0 + (((cursor_y - window_y0) + (pixels / w)) % h);
|
||||
cursor_x += pixels % w;
|
||||
}
|
||||
|
||||
uint16_t display_get_window_offset(void) {
|
||||
return DISPLAY_RESX - display_get_window_width();
|
||||
}
|
||||
|
||||
void display_efficient_clear(void) {
|
||||
memzero(PhysFrameBuffer1, sizeof(PhysFrameBuffer1));
|
||||
memzero(PhysFrameBuffer0, sizeof(PhysFrameBuffer0));
|
||||
}
|
||||
|
||||
void display_finish_actions(void) {
|
||||
#ifndef BOARDLOADER
|
||||
bg_copy_wait();
|
||||
#endif
|
||||
backlight_pwm_deinit(BACKLIGHT_RETAIN);
|
||||
}
|
||||
#else
|
||||
// NOT FRAMEBUFFER
|
||||
|
||||
void display_pixeldata(uint16_t c) { PIXELDATA(c); }
|
||||
|
||||
void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
panel_set_window(x0, y0, x1, y1);
|
||||
}
|
||||
|
||||
void display_sync(void) {
|
||||
#ifdef DISPLAY_TE_PIN
|
||||
uint32_t id = display_identify();
|
||||
if (id && (id != DISPLAY_ID_GC9307)) {
|
||||
// synchronize with the panel synchronization signal
|
||||
// in order to avoid visual tearing effects
|
||||
while (GPIO_PIN_SET == HAL_GPIO_ReadPin(DISPLAY_TE_PORT, DISPLAY_TE_PIN))
|
||||
;
|
||||
while (GPIO_PIN_RESET == HAL_GPIO_ReadPin(DISPLAY_TE_PORT, DISPLAY_TE_PIN))
|
||||
;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void display_refresh(void) {}
|
||||
|
||||
uint8_t *display_get_wr_addr(void) { return (uint8_t *)DISPLAY_DATA_ADDRESS; }
|
||||
|
||||
uint16_t display_get_window_offset(void) { return 0; }
|
||||
|
||||
void display_shift_window(uint16_t pixels) {}
|
||||
|
||||
void display_finish_actions(void) {
|
||||
backlight_pwm_deinit(BACKLIGHT_RETAIN);
|
||||
#ifdef TREZOR_MODEL_T
|
||||
display_set_big_endian();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
@ -1,62 +0,0 @@
|
||||
#ifndef _ST7789V_H
|
||||
#define _ST7789V_H
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_types.h>
|
||||
|
||||
typedef struct {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} display_padding_t;
|
||||
|
||||
// ILI9341V, GC9307 and ST7789V drivers support 240px x 320px display resolution
|
||||
#define MAX_DISPLAY_RESX 240
|
||||
#define MAX_DISPLAY_RESY 320
|
||||
#define DISPLAY_COLOR_MODE DMA2D_OUTPUT_RGB565
|
||||
|
||||
#ifdef DISPLAY_I8080_16BIT_DW
|
||||
#define DISP_MEM_TYPE uint16_t
|
||||
#elif DISPLAY_I8080_8BIT_DW
|
||||
#define DISP_MEM_TYPE uint8_t
|
||||
#else
|
||||
#error "Unsupported display interface"
|
||||
#endif
|
||||
|
||||
#define DISP_MEM_TYPE uint8_t
|
||||
|
||||
extern __IO DISP_MEM_TYPE *const DISPLAY_CMD_ADDRESS;
|
||||
extern __IO DISP_MEM_TYPE *const DISPLAY_DATA_ADDRESS;
|
||||
|
||||
#define CMD(X) (*DISPLAY_CMD_ADDRESS = (X))
|
||||
#define DATA(X) (*DISPLAY_DATA_ADDRESS = (X))
|
||||
|
||||
void display_set_little_endian(void);
|
||||
void display_set_big_endian(void);
|
||||
void display_set_slow_pwm(void);
|
||||
|
||||
#ifdef FRAMEBUFFER
|
||||
#define DISPLAY_FRAMEBUFFER_WIDTH DISPLAY_RESX
|
||||
#define DISPLAY_FRAMEBUFFER_HEIGHT DISPLAY_RESY
|
||||
|
||||
#define DISPLAY_EFFICIENT_CLEAR 1
|
||||
|
||||
static inline void display_pixel(uint8_t *fb, int16_t x, int16_t y,
|
||||
uint16_t color) {
|
||||
uint32_t p = 2 * (y * DISPLAY_FRAMEBUFFER_WIDTH + x);
|
||||
*((uint16_t *)(fb + p)) = color;
|
||||
}
|
||||
void display_efficient_clear(void);
|
||||
|
||||
#else
|
||||
|
||||
#ifdef DISPLAY_I8080_16BIT_DW
|
||||
#define PIXELDATA(X) DATA(X)
|
||||
#elif DISPLAY_I8080_8BIT_DW
|
||||
#define PIXELDATA(X) \
|
||||
DATA((X) & 0xFF); \
|
||||
DATA((X) >> 8)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif //_ST7789V_H
|
@ -1,372 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "memzero.h"
|
||||
|
||||
// FSMC/FMC Bank 1 - NOR/PSRAM 1
|
||||
#define DISPLAY_MEMORY_BASE 0x60000000
|
||||
#define DISPLAY_MEMORY_PIN 16
|
||||
|
||||
#define CMD(X) (*((__IO uint8_t *)((uint32_t)(DISPLAY_MEMORY_BASE))) = (X))
|
||||
#define ADDR \
|
||||
(*((__IO uint8_t *)((uint32_t)(DISPLAY_MEMORY_BASE | \
|
||||
(1 << DISPLAY_MEMORY_PIN)))))
|
||||
#define DATA(X) (ADDR) = (X)
|
||||
|
||||
static int DISPLAY_BACKLIGHT = -1;
|
||||
static int DISPLAY_ORIENTATION = -1;
|
||||
struct {
|
||||
uint8_t RAM[DISPLAY_RESY / 8][DISPLAY_RESX];
|
||||
uint32_t row;
|
||||
uint32_t col;
|
||||
uint32_t window_x0;
|
||||
uint32_t window_x1;
|
||||
uint32_t window_y0;
|
||||
uint32_t window_y1;
|
||||
} DISPLAY_STATE;
|
||||
|
||||
static void display_set_page_and_col(uint8_t page, uint8_t col) {
|
||||
if (page < (DISPLAY_RESY / 8)) {
|
||||
CMD(0xB0 | (page & 0xF));
|
||||
|
||||
if (col < DISPLAY_RESX) {
|
||||
CMD(0x10 | ((col & 0x70) >> 4));
|
||||
CMD(0x00 | (col & 0x0F));
|
||||
} else {
|
||||
// Reset column to start
|
||||
CMD(0x10);
|
||||
CMD(0x00);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void display_pixeldata(uint16_t c) {
|
||||
uint8_t data = DISPLAY_STATE.RAM[DISPLAY_STATE.row / 8][DISPLAY_STATE.col];
|
||||
|
||||
uint8_t bit = 1 << (DISPLAY_STATE.row % 8);
|
||||
|
||||
// set to white if highest bits of all R, G, B values are set to 1
|
||||
// bin(10000 100000 10000) = hex(0x8410)
|
||||
// otherwise set to black
|
||||
if (c & 0x8410) {
|
||||
data |= bit;
|
||||
} else {
|
||||
data &= ~bit;
|
||||
}
|
||||
|
||||
DISPLAY_STATE.RAM[DISPLAY_STATE.row / 8][DISPLAY_STATE.col] = data;
|
||||
|
||||
DISPLAY_STATE.col++;
|
||||
|
||||
if (DISPLAY_STATE.col > DISPLAY_STATE.window_x1) {
|
||||
// next line
|
||||
DISPLAY_STATE.col = DISPLAY_STATE.window_x0;
|
||||
DISPLAY_STATE.row++;
|
||||
|
||||
if (DISPLAY_STATE.row > DISPLAY_STATE.window_y1) {
|
||||
// reached end of the window, go to start
|
||||
DISPLAY_STATE.row = DISPLAY_STATE.window_y1;
|
||||
}
|
||||
|
||||
// set display to start of next line, sets also page, even if it stays on
|
||||
// the same one
|
||||
display_set_page_and_col(DISPLAY_STATE.row / 8, DISPLAY_STATE.col);
|
||||
}
|
||||
}
|
||||
|
||||
void display_pixeldata_dirty(void) {}
|
||||
|
||||
void display_reset_state(void) {
|
||||
memzero(DISPLAY_STATE.RAM, sizeof(DISPLAY_STATE.RAM));
|
||||
DISPLAY_STATE.row = 0;
|
||||
DISPLAY_STATE.col = 0;
|
||||
DISPLAY_STATE.window_x0 = 0;
|
||||
DISPLAY_STATE.window_x1 = DISPLAY_RESX - 1;
|
||||
DISPLAY_STATE.window_y0 = 0;
|
||||
DISPLAY_STATE.window_y1 = DISPLAY_RESY - 1;
|
||||
}
|
||||
|
||||
static void __attribute__((unused)) display_sleep(void) {
|
||||
CMD(0xAE); // DISPOFF: Display Off
|
||||
HAL_Delay(5);
|
||||
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_8, GPIO_PIN_RESET); // Vpp disable
|
||||
}
|
||||
|
||||
static void display_unsleep(void) {
|
||||
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_8, GPIO_PIN_SET); // Vpp enable
|
||||
HAL_Delay(100); // 100 ms mandatory wait
|
||||
CMD(0xAF); // Display ON
|
||||
}
|
||||
|
||||
void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
if (x1 >= DISPLAY_RESX) {
|
||||
x1 = DISPLAY_RESX - 1;
|
||||
}
|
||||
if (y1 >= DISPLAY_RESY) {
|
||||
y1 = DISPLAY_RESY - 1;
|
||||
}
|
||||
|
||||
if (x0 < DISPLAY_RESX && x1 < DISPLAY_RESX && x0 <= x1 && y0 < DISPLAY_RESY &&
|
||||
y1 < DISPLAY_RESY && y0 <= y1) {
|
||||
DISPLAY_STATE.window_x0 = x0;
|
||||
DISPLAY_STATE.window_x1 = x1;
|
||||
DISPLAY_STATE.window_y0 = y0;
|
||||
DISPLAY_STATE.window_y1 = y1;
|
||||
DISPLAY_STATE.row = y0;
|
||||
DISPLAY_STATE.col = x0;
|
||||
|
||||
display_set_page_and_col(DISPLAY_STATE.row / 8, DISPLAY_STATE.col);
|
||||
}
|
||||
}
|
||||
|
||||
int display_orientation(int degrees) {
|
||||
if (degrees != DISPLAY_ORIENTATION) {
|
||||
if (degrees == 0 || degrees == 180) {
|
||||
DISPLAY_ORIENTATION = degrees;
|
||||
if (degrees == 0) {
|
||||
// Set Segment Re-map: (A0H - A1H)
|
||||
CMD(0xA1);
|
||||
// Set COM Output Scan Direction
|
||||
CMD(0xC8);
|
||||
}
|
||||
if (degrees == 180) {
|
||||
// Set Segment Re-map: (A0H - A1H)
|
||||
CMD(0xA0);
|
||||
// Set COM Output Scan Direction
|
||||
CMD(0xC0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return DISPLAY_ORIENTATION;
|
||||
}
|
||||
|
||||
int display_get_orientation(void) { return DISPLAY_ORIENTATION; }
|
||||
|
||||
int display_backlight(int val) {
|
||||
if (DISPLAY_BACKLIGHT != val && val >= 0 && val <= 255) {
|
||||
DISPLAY_BACKLIGHT = val;
|
||||
// Set Contrast Control Register: (Double Bytes Command)
|
||||
CMD(0x81);
|
||||
CMD(val & 0xFF);
|
||||
}
|
||||
return DISPLAY_BACKLIGHT;
|
||||
}
|
||||
|
||||
static void send_init_seq_SH1107(void) {
|
||||
// Display OFF
|
||||
CMD(0xAE);
|
||||
|
||||
// Set Display Clock Divide Ratio/Oscillator Frequency: (Double Bytes Command)
|
||||
CMD(0xD5);
|
||||
// Divide ratio 0, Oscillator Frequency +0%
|
||||
CMD(0x50);
|
||||
|
||||
// Set Memory Addressing Mode - page addressing mode
|
||||
CMD(0x20);
|
||||
|
||||
// Set Contrast Control Register: (Double Bytes Command)
|
||||
CMD(0x81);
|
||||
CMD(0x8F);
|
||||
|
||||
// Set DC-DC Setting: (Double Bytes Command)
|
||||
CMD(0xAD);
|
||||
CMD(0x8A);
|
||||
|
||||
// Set Segment Re-map: (A0H - A1H)
|
||||
// CMD(0xA0);
|
||||
CMD(0xA1);
|
||||
|
||||
// Set COM Output Scan Direction
|
||||
CMD(0xC8);
|
||||
// CMD(0xC0);
|
||||
|
||||
// Set Display Start Line:(Double Bytes Command)
|
||||
CMD(0xDC);
|
||||
CMD(0x00);
|
||||
|
||||
// Set Display Offset:(Double Bytes Command)
|
||||
CMD(0xD3);
|
||||
CMD(0x00);
|
||||
|
||||
// Set Discharge / Pre-Charge Period (Double Bytes Command)
|
||||
CMD(0xD9);
|
||||
CMD(0x22);
|
||||
|
||||
// Set VCOM Deselect Level
|
||||
CMD(0xDB);
|
||||
CMD(0x35);
|
||||
|
||||
// Set Multiplex Ratio
|
||||
CMD(0xA8);
|
||||
CMD(0x7F);
|
||||
|
||||
// Set Page
|
||||
CMD(0xB0);
|
||||
// Set Column
|
||||
CMD(0x00);
|
||||
CMD(0x10);
|
||||
|
||||
// Set Entire Display Off
|
||||
// to be clear, this command turns of the function
|
||||
// which turns entire display on, but it does not clear
|
||||
// the data in display RAM
|
||||
CMD(0xA4);
|
||||
|
||||
// Set Normal Display
|
||||
CMD(0xA6);
|
||||
|
||||
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_8, GPIO_PIN_SET); // Vpp enable
|
||||
|
||||
// Vpp stabilization period
|
||||
HAL_Delay(100);
|
||||
|
||||
display_set_window(0, 0, MAX_DISPLAY_RESX - 1, MAX_DISPLAY_RESY - 1);
|
||||
for (int i = 0; i < DISPLAY_RESY; i++) {
|
||||
for (int j = 0; j < DISPLAY_RESX; j++) {
|
||||
display_pixeldata(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Display ON
|
||||
CMD(0xAF);
|
||||
}
|
||||
|
||||
void display_init_seq(void) {
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET); // LCD_RST/PC14
|
||||
// wait 10 milliseconds. only needs to be low for 10 microseconds.
|
||||
// my dev display module ties display reset and touch panel reset together.
|
||||
// keeping this low for max(display_reset_time, ctpm_reset_time) aids
|
||||
// development and does not hurt.
|
||||
HAL_Delay(10);
|
||||
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_SET); // LCD_RST/PC14
|
||||
// max wait time for hardware reset is 120 milliseconds
|
||||
// (experienced display flakiness using only 5ms wait before sending commands)
|
||||
HAL_Delay(120);
|
||||
|
||||
send_init_seq_SH1107();
|
||||
|
||||
display_unsleep();
|
||||
}
|
||||
|
||||
void display_init_all(void) {
|
||||
// init peripherals
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
__HAL_RCC_FMC_CLK_ENABLE();
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
|
||||
// LCD_RST/PC14
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStructure.Alternate = 0;
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_14;
|
||||
// default to keeping display in reset
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_RESET);
|
||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
|
||||
|
||||
// VPP Enable
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_PULLDOWN;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStructure.Alternate = 0;
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_8;
|
||||
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_8, GPIO_PIN_RESET);
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||||
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStructure.Alternate = GPIO_AF12_FMC;
|
||||
// LCD_CS/PD7 LCD_RS/PD11 LCD_RD/PD4 LCD_WR/PD5
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_7 | GPIO_PIN_11 | GPIO_PIN_4 | GPIO_PIN_5;
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||||
// LCD_D0/PD14 LCD_D1/PD15 LCD_D2/PD0 LCD_D3/PD1
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_14 | GPIO_PIN_15 | GPIO_PIN_0 | GPIO_PIN_1;
|
||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
|
||||
// LCD_D4/PE7 LCD_D5/PE8 LCD_D6/PE9 LCD_D7/PE10
|
||||
GPIO_InitStructure.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
|
||||
|
||||
// Reference UM1725 "Description of STM32F4 HAL and LL drivers",
|
||||
// section 64.2.1 "How to use this driver"
|
||||
SRAM_HandleTypeDef external_display_data_sram = {0};
|
||||
external_display_data_sram.Instance = FMC_NORSRAM_DEVICE;
|
||||
external_display_data_sram.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
|
||||
external_display_data_sram.Init.NSBank = FMC_NORSRAM_BANK1;
|
||||
external_display_data_sram.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
|
||||
external_display_data_sram.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
|
||||
external_display_data_sram.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_8;
|
||||
external_display_data_sram.Init.BurstAccessMode =
|
||||
FMC_BURST_ACCESS_MODE_DISABLE;
|
||||
external_display_data_sram.Init.WaitSignalPolarity =
|
||||
FMC_WAIT_SIGNAL_POLARITY_LOW;
|
||||
external_display_data_sram.Init.WrapMode = FMC_WRAP_MODE_DISABLE;
|
||||
external_display_data_sram.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
|
||||
external_display_data_sram.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
|
||||
external_display_data_sram.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
|
||||
external_display_data_sram.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
|
||||
external_display_data_sram.Init.AsynchronousWait =
|
||||
FMC_ASYNCHRONOUS_WAIT_DISABLE;
|
||||
external_display_data_sram.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
|
||||
external_display_data_sram.Init.ContinuousClock =
|
||||
FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
|
||||
external_display_data_sram.Init.PageSize = FMC_PAGE_SIZE_NONE;
|
||||
|
||||
// reference RM0090 section 37.5 Table 259, 37.5.4, Mode 1 SRAM, and 37.5.6
|
||||
FMC_NORSRAM_TimingTypeDef normal_mode_timing = {0};
|
||||
normal_mode_timing.AddressSetupTime = 10;
|
||||
normal_mode_timing.AddressHoldTime = 10;
|
||||
normal_mode_timing.DataSetupTime = 10;
|
||||
normal_mode_timing.BusTurnAroundDuration = 0;
|
||||
normal_mode_timing.CLKDivision = 2;
|
||||
normal_mode_timing.DataLatency = 2;
|
||||
normal_mode_timing.AccessMode = FMC_ACCESS_MODE_A;
|
||||
|
||||
HAL_SRAM_Init(&external_display_data_sram, &normal_mode_timing, NULL);
|
||||
|
||||
display_init_seq();
|
||||
}
|
||||
|
||||
void display_sync(void) {}
|
||||
|
||||
void display_refresh(void) {
|
||||
for (int y = 0; y < (DISPLAY_RESY / 8); y++) {
|
||||
display_set_page_and_col(y, 0);
|
||||
for (int x = 0; x < DISPLAY_RESX; x++) {
|
||||
DATA(DISPLAY_STATE.RAM[y][x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void display_reinit(void) {}
|
||||
|
||||
const char *display_save(const char *prefix) { return NULL; }
|
||||
|
||||
void display_clear_save(void) {}
|
||||
|
||||
void display_finish_actions(void) {}
|
@ -1,9 +0,0 @@
|
||||
#ifndef _UG_2828TSWIG01_H
|
||||
#define _UG_2828TSWIG01_H
|
||||
|
||||
#define MAX_DISPLAY_RESX 128
|
||||
#define MAX_DISPLAY_RESY 128
|
||||
#define DISPLAY_RESX 128
|
||||
#define DISPLAY_RESY 128
|
||||
|
||||
#endif //_UG_2828TSWIG01_H
|
@ -1,300 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "display.h"
|
||||
|
||||
#ifdef USE_CONSUMPTION_MASK
|
||||
#include "consumption_mask.h"
|
||||
#endif
|
||||
|
||||
#define OLED_BUFSIZE (DISPLAY_RESX * DISPLAY_RESY / 8)
|
||||
#define OLED_OFFSET(x, y) (OLED_BUFSIZE - 1 - (x) - ((y) / 8) * DISPLAY_RESX)
|
||||
#define OLED_MASK(x, y) (1 << (7 - (y) % 8))
|
||||
|
||||
#define OLED_SETCONTRAST 0x81
|
||||
#define OLED_DISPLAYALLON_RESUME 0xA4
|
||||
#define OLED_DISPLAYALLON 0xA5
|
||||
#define OLED_NORMALDISPLAY 0xA6
|
||||
#define OLED_INVERTDISPLAY 0xA7
|
||||
#define OLED_DISPLAYOFF 0xAE
|
||||
#define OLED_DISPLAYON 0xAF
|
||||
#define OLED_SETDISPLAYOFFSET 0xD3
|
||||
#define OLED_SETCOMPINS 0xDA
|
||||
#define OLED_SETVCOMDETECT 0xDB
|
||||
#define OLED_SETDISPLAYCLOCKDIV 0xD5
|
||||
#define OLED_SETPRECHARGE 0xD9
|
||||
#define OLED_SETMULTIPLEX 0xA8
|
||||
#define OLED_SETLOWCOLUMN 0x00
|
||||
#define OLED_SETHIGHCOLUMN 0x10
|
||||
#define OLED_SETSTARTLINE 0x40
|
||||
#define OLED_MEMORYMODE 0x20
|
||||
#define OLED_COMSCANINC 0xC0
|
||||
#define OLED_COMSCANDEC 0xC8
|
||||
#define OLED_SEGREMAP 0xA0
|
||||
#define OLED_CHARGEPUMP 0x8D
|
||||
|
||||
static int DISPLAY_BACKLIGHT = -1;
|
||||
static int DISPLAY_ORIENTATION = -1;
|
||||
static uint8_t OLED_BUFFER[OLED_BUFSIZE];
|
||||
|
||||
static struct {
|
||||
struct {
|
||||
uint16_t x, y;
|
||||
} start;
|
||||
struct {
|
||||
uint16_t x, y;
|
||||
} end;
|
||||
struct {
|
||||
uint16_t x, y;
|
||||
} pos;
|
||||
} PIXELWINDOW;
|
||||
|
||||
static bool pixeldata_dirty_flag = true;
|
||||
|
||||
void display_pixeldata(uint16_t c) {
|
||||
if (PIXELWINDOW.pos.x <= PIXELWINDOW.end.x &&
|
||||
PIXELWINDOW.pos.y <= PIXELWINDOW.end.y) {
|
||||
// set to white if highest bits of all R, G, B values are set to 1
|
||||
// bin(10000 100000 10000) = hex(0x8410)
|
||||
// otherwise set to black
|
||||
if (c & 0x8410) {
|
||||
OLED_BUFFER[OLED_OFFSET(PIXELWINDOW.pos.x, PIXELWINDOW.pos.y)] |=
|
||||
OLED_MASK(PIXELWINDOW.pos.x, PIXELWINDOW.pos.y);
|
||||
} else {
|
||||
OLED_BUFFER[OLED_OFFSET(PIXELWINDOW.pos.x, PIXELWINDOW.pos.y)] &=
|
||||
~OLED_MASK(PIXELWINDOW.pos.x, PIXELWINDOW.pos.y);
|
||||
}
|
||||
}
|
||||
PIXELWINDOW.pos.x++;
|
||||
if (PIXELWINDOW.pos.x > PIXELWINDOW.end.x) {
|
||||
PIXELWINDOW.pos.x = PIXELWINDOW.start.x;
|
||||
PIXELWINDOW.pos.y++;
|
||||
}
|
||||
}
|
||||
|
||||
void display_reset_state() {}
|
||||
|
||||
void display_pixeldata_dirty(void) { pixeldata_dirty_flag = true; }
|
||||
|
||||
void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
PIXELWINDOW.start.x = x0;
|
||||
PIXELWINDOW.start.y = y0;
|
||||
PIXELWINDOW.end.x = x1;
|
||||
PIXELWINDOW.end.y = y1;
|
||||
PIXELWINDOW.pos.x = x0;
|
||||
PIXELWINDOW.pos.y = y0;
|
||||
}
|
||||
|
||||
int display_orientation(int degrees) {
|
||||
if (degrees != DISPLAY_ORIENTATION) {
|
||||
if (degrees == 0 || degrees == 180) {
|
||||
DISPLAY_ORIENTATION = degrees;
|
||||
display_refresh();
|
||||
}
|
||||
}
|
||||
return DISPLAY_ORIENTATION;
|
||||
}
|
||||
|
||||
int display_get_orientation(void) { return DISPLAY_ORIENTATION; }
|
||||
|
||||
int display_backlight(int val) {
|
||||
DISPLAY_BACKLIGHT = 255;
|
||||
return DISPLAY_BACKLIGHT;
|
||||
}
|
||||
|
||||
SPI_HandleTypeDef spi_handle;
|
||||
|
||||
static inline void spi_send(const uint8_t *data, int len) {
|
||||
volatile int32_t timeout = 1000;
|
||||
for (int i = 0; i < timeout; i++)
|
||||
;
|
||||
|
||||
if (HAL_OK != HAL_SPI_Transmit(&spi_handle, (uint8_t *)data, len, 1000)) {
|
||||
// TODO: error
|
||||
return;
|
||||
}
|
||||
while (HAL_SPI_STATE_READY != HAL_SPI_GetState(&spi_handle)) {
|
||||
}
|
||||
}
|
||||
|
||||
void display_handle_init(void) {
|
||||
spi_handle.Instance = OLED_SPI;
|
||||
spi_handle.State = HAL_SPI_STATE_RESET;
|
||||
spi_handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
|
||||
spi_handle.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
spi_handle.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
spi_handle.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
spi_handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
spi_handle.Init.CRCPolynomial = 7;
|
||||
spi_handle.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
spi_handle.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
spi_handle.Init.NSS = SPI_NSS_HARD_OUTPUT;
|
||||
spi_handle.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
spi_handle.Init.Mode = SPI_MODE_MASTER;
|
||||
}
|
||||
|
||||
void display_init_all(void) {
|
||||
OLED_DC_CLK_ENA();
|
||||
OLED_CS_CLK_ENA();
|
||||
OLED_RST_CLK_ENA();
|
||||
OLED_SPI_SCK_CLK_ENA();
|
||||
OLED_SPI_MOSI_CLK_ENA();
|
||||
OLED_SPI_CLK_ENA();
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
|
||||
// set GPIO for OLED display
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStructure.Alternate = 0;
|
||||
GPIO_InitStructure.Pin = OLED_CS_PIN;
|
||||
HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_RESET);
|
||||
HAL_GPIO_Init(OLED_CS_PORT, &GPIO_InitStructure);
|
||||
GPIO_InitStructure.Pin = OLED_DC_PIN;
|
||||
HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET);
|
||||
HAL_GPIO_Init(OLED_DC_PORT, &GPIO_InitStructure);
|
||||
GPIO_InitStructure.Pin = OLED_RST_PIN;
|
||||
HAL_GPIO_WritePin(OLED_RST_PORT, OLED_RST_PIN, GPIO_PIN_RESET);
|
||||
HAL_GPIO_Init(OLED_RST_PORT, &GPIO_InitStructure);
|
||||
|
||||
// enable SPI 1 for OLED display
|
||||
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStructure.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStructure.Alternate = OLED_SPI_AF;
|
||||
GPIO_InitStructure.Pin = OLED_SPI_SCK_PIN;
|
||||
HAL_GPIO_Init(OLED_SPI_SCK_PORT, &GPIO_InitStructure);
|
||||
GPIO_InitStructure.Pin = OLED_SPI_MOSI_PIN;
|
||||
HAL_GPIO_Init(OLED_SPI_MOSI_PORT, &GPIO_InitStructure);
|
||||
|
||||
display_handle_init();
|
||||
if (HAL_OK != HAL_SPI_Init(&spi_handle)) {
|
||||
// TODO: error
|
||||
return;
|
||||
}
|
||||
|
||||
// initialize display
|
||||
|
||||
static const uint8_t s[25] = {OLED_DISPLAYOFF,
|
||||
OLED_SETDISPLAYCLOCKDIV,
|
||||
0x80,
|
||||
OLED_SETMULTIPLEX,
|
||||
0x3F, // 128x64
|
||||
OLED_SETDISPLAYOFFSET,
|
||||
0x00,
|
||||
OLED_SETSTARTLINE | 0x00,
|
||||
OLED_CHARGEPUMP,
|
||||
0x14,
|
||||
OLED_MEMORYMODE,
|
||||
0x00,
|
||||
OLED_SEGREMAP | 0x01,
|
||||
OLED_COMSCANDEC,
|
||||
OLED_SETCOMPINS,
|
||||
0x12, // 128x64
|
||||
OLED_SETCONTRAST,
|
||||
0xCF,
|
||||
OLED_SETPRECHARGE,
|
||||
0xF1,
|
||||
OLED_SETVCOMDETECT,
|
||||
0x40,
|
||||
OLED_DISPLAYALLON_RESUME,
|
||||
OLED_NORMALDISPLAY,
|
||||
OLED_DISPLAYON};
|
||||
|
||||
HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); // set to CMD
|
||||
HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_SET); // SPI deselect
|
||||
|
||||
// Reset the LCD
|
||||
HAL_GPIO_WritePin(OLED_RST_PORT, OLED_RST_PIN, GPIO_PIN_SET);
|
||||
HAL_Delay(1);
|
||||
HAL_GPIO_WritePin(OLED_RST_PORT, OLED_RST_PIN, GPIO_PIN_RESET);
|
||||
HAL_Delay(1);
|
||||
HAL_GPIO_WritePin(OLED_RST_PORT, OLED_RST_PIN, GPIO_PIN_SET);
|
||||
|
||||
// init
|
||||
HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_RESET); // SPI select
|
||||
spi_send(s, 25);
|
||||
HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_SET); // SPI deselect
|
||||
|
||||
display_refresh();
|
||||
}
|
||||
|
||||
void display_reinit(void) {
|
||||
display_handle_init();
|
||||
HAL_SPI_Init(&spi_handle);
|
||||
}
|
||||
|
||||
static inline uint8_t reverse_byte(uint8_t b) {
|
||||
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
|
||||
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
|
||||
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
|
||||
return b;
|
||||
}
|
||||
|
||||
static void rotate_oled_buffer(void) {
|
||||
for (int i = 0; i < OLED_BUFSIZE / 2; i++) {
|
||||
uint8_t b = OLED_BUFFER[i];
|
||||
OLED_BUFFER[i] = reverse_byte(OLED_BUFFER[OLED_BUFSIZE - i - 1]);
|
||||
OLED_BUFFER[OLED_BUFSIZE - i - 1] = reverse_byte(b);
|
||||
}
|
||||
}
|
||||
|
||||
void display_sync(void) {}
|
||||
|
||||
void display_refresh(void) {
|
||||
static const uint8_t s[3] = {OLED_SETLOWCOLUMN | 0x00,
|
||||
OLED_SETHIGHCOLUMN | 0x00,
|
||||
OLED_SETSTARTLINE | 0x00};
|
||||
|
||||
if (!pixeldata_dirty_flag) {
|
||||
return;
|
||||
}
|
||||
pixeldata_dirty_flag = false;
|
||||
|
||||
HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_RESET); // SPI select
|
||||
spi_send(s, 3);
|
||||
|
||||
#if defined USE_CONSUMPTION_MASK && !defined BOARDLOADER
|
||||
consumption_mask_randomize();
|
||||
#endif
|
||||
|
||||
HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_SET); // SPI deselect
|
||||
|
||||
HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_SET); // set to DATA
|
||||
HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_RESET); // SPI select
|
||||
if (DISPLAY_ORIENTATION == 180) { // rotate buffer if needed
|
||||
rotate_oled_buffer();
|
||||
}
|
||||
spi_send(OLED_BUFFER, OLED_BUFSIZE);
|
||||
if (DISPLAY_ORIENTATION == 180) { // rotate buffer back to original position
|
||||
rotate_oled_buffer();
|
||||
}
|
||||
HAL_GPIO_WritePin(OLED_CS_PORT, OLED_CS_PIN, GPIO_PIN_SET); // SPI deselect
|
||||
HAL_GPIO_WritePin(OLED_DC_PORT, OLED_DC_PIN, GPIO_PIN_RESET); // set to CMD
|
||||
}
|
||||
|
||||
const char *display_save(const char *prefix) { return NULL; }
|
||||
|
||||
void display_clear_save(void) {}
|
||||
|
||||
void display_finish_actions(void) {}
|
@ -1,9 +0,0 @@
|
||||
#ifndef _VG_2864KSWEG01_H
|
||||
#define _VG_2864KSWEG01_H
|
||||
|
||||
#define MAX_DISPLAY_RESX 128
|
||||
#define MAX_DISPLAY_RESY 64
|
||||
#define DISPLAY_RESX 128
|
||||
#define DISPLAY_RESY 64
|
||||
|
||||
#endif //_VG_2864KSWEG01_H
|
@ -1,174 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
|
||||
#include "colors.h"
|
||||
#include "display.h"
|
||||
#include "dma2d.h"
|
||||
|
||||
typedef enum {
|
||||
DMA2D_LAYER_FG = 1,
|
||||
DMA2D_LAYER_BG = 0,
|
||||
} dma2d_layer_t;
|
||||
|
||||
static DMA2D_HandleTypeDef dma2d_handle = {0};
|
||||
static uint16_t current_width = 0;
|
||||
static uint16_t current_height = 0;
|
||||
|
||||
void dma2d_init(void) {
|
||||
__HAL_RCC_DMA2D_CLK_ENABLE();
|
||||
|
||||
dma2d_handle.Instance = (DMA2D_TypeDef*)DMA2D_BASE;
|
||||
dma2d_handle.Init.ColorMode = DISPLAY_COLOR_MODE;
|
||||
dma2d_handle.Init.OutputOffset = 0;
|
||||
}
|
||||
|
||||
static void dma2d_init_clut(uint16_t fg, uint16_t bg, dma2d_layer_t layer) {
|
||||
volatile uint32_t* table = NULL;
|
||||
if (layer == DMA2D_LAYER_BG) {
|
||||
table = dma2d_handle.Instance->BGCLUT;
|
||||
} else {
|
||||
table = dma2d_handle.Instance->FGCLUT;
|
||||
}
|
||||
|
||||
uint32_t fg32 = rgb565_to_rgb888(fg);
|
||||
uint32_t bg32 = rgb565_to_rgb888(bg);
|
||||
|
||||
for (uint8_t i = 0; i < 16; i++) {
|
||||
table[i] = interpolate_rgb888_color(fg32, bg32, i);
|
||||
}
|
||||
|
||||
DMA2D_CLUTCfgTypeDef clut = {0};
|
||||
clut.CLUTColorMode = DMA2D_CCM_ARGB8888;
|
||||
clut.Size = 0xf;
|
||||
clut.pCLUT = 0; // loading directly
|
||||
|
||||
HAL_DMA2D_ConfigCLUT(&dma2d_handle, clut, layer);
|
||||
}
|
||||
|
||||
void dma2d_setup_const(void) {
|
||||
dma2d_handle.Init.Mode = DMA2D_R2M;
|
||||
dma2d_handle.Init.OutputOffset = display_get_window_offset();
|
||||
HAL_DMA2D_Init(&dma2d_handle);
|
||||
}
|
||||
|
||||
void dma2d_setup_4bpp(uint16_t fg_color, uint16_t bg_color) {
|
||||
dma2d_handle.Init.Mode = DMA2D_M2M_PFC;
|
||||
dma2d_handle.Init.OutputOffset = display_get_window_offset();
|
||||
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_L4;
|
||||
dma2d_handle.LayerCfg[1].InputOffset = 0;
|
||||
dma2d_handle.LayerCfg[1].AlphaMode = 0;
|
||||
dma2d_handle.LayerCfg[1].InputAlpha = 0;
|
||||
|
||||
dma2d_init_clut(fg_color, bg_color, DMA2D_LAYER_FG);
|
||||
|
||||
HAL_DMA2D_Init(&dma2d_handle);
|
||||
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
|
||||
}
|
||||
|
||||
void dma2d_setup_16bpp(void) {
|
||||
dma2d_handle.Init.Mode = DMA2D_M2M_PFC;
|
||||
dma2d_handle.Init.OutputOffset = display_get_window_offset();
|
||||
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_RGB565;
|
||||
dma2d_handle.LayerCfg[1].InputOffset = 0;
|
||||
dma2d_handle.LayerCfg[1].AlphaMode = 0;
|
||||
dma2d_handle.LayerCfg[1].InputAlpha = 0;
|
||||
|
||||
HAL_DMA2D_Init(&dma2d_handle);
|
||||
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
|
||||
}
|
||||
|
||||
void dma2d_setup_4bpp_over_16bpp(uint16_t overlay_color) {
|
||||
dma2d_handle.Init.Mode = DMA2D_M2M_BLEND;
|
||||
dma2d_handle.Init.OutputOffset = display_get_window_offset();
|
||||
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_A4;
|
||||
dma2d_handle.LayerCfg[1].InputOffset = 0;
|
||||
dma2d_handle.LayerCfg[1].AlphaMode = 0;
|
||||
dma2d_handle.LayerCfg[1].InputAlpha =
|
||||
0xFF000000 | rgb565_to_rgb888(overlay_color);
|
||||
|
||||
dma2d_handle.LayerCfg[0].InputColorMode = DMA2D_INPUT_RGB565;
|
||||
dma2d_handle.LayerCfg[0].InputOffset = 0;
|
||||
dma2d_handle.LayerCfg[0].AlphaMode = 0;
|
||||
dma2d_handle.LayerCfg[0].InputAlpha = 0;
|
||||
|
||||
HAL_DMA2D_Init(&dma2d_handle);
|
||||
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
|
||||
HAL_DMA2D_ConfigLayer(&dma2d_handle, 0);
|
||||
}
|
||||
|
||||
void dma2d_setup_4bpp_over_4bpp(uint16_t fg_color, uint16_t bg_color,
|
||||
uint16_t overlay_color) {
|
||||
dma2d_handle.Init.Mode = DMA2D_M2M_BLEND;
|
||||
dma2d_handle.Init.OutputOffset = display_get_window_offset();
|
||||
dma2d_handle.LayerCfg[1].InputColorMode = DMA2D_INPUT_A4;
|
||||
dma2d_handle.LayerCfg[1].InputOffset = 0;
|
||||
dma2d_handle.LayerCfg[1].AlphaMode = 0;
|
||||
dma2d_handle.LayerCfg[1].InputAlpha = rgb565_to_rgb888(overlay_color);
|
||||
|
||||
dma2d_handle.LayerCfg[0].InputColorMode = DMA2D_INPUT_L4;
|
||||
dma2d_handle.LayerCfg[0].InputOffset = 0;
|
||||
dma2d_handle.LayerCfg[0].AlphaMode = DMA2D_REPLACE_ALPHA;
|
||||
dma2d_handle.LayerCfg[0].InputAlpha = 0xFF;
|
||||
|
||||
dma2d_init_clut(fg_color, bg_color, DMA2D_LAYER_BG);
|
||||
|
||||
HAL_DMA2D_Init(&dma2d_handle);
|
||||
HAL_DMA2D_ConfigLayer(&dma2d_handle, 1);
|
||||
HAL_DMA2D_ConfigLayer(&dma2d_handle, 0);
|
||||
}
|
||||
|
||||
void dma2d_start(uint8_t* in_addr, uint8_t* out_addr, int32_t pixels) {
|
||||
current_width = pixels;
|
||||
current_height = 1;
|
||||
HAL_DMA2D_Start(&dma2d_handle, (uint32_t)in_addr, (uint32_t)out_addr, pixels,
|
||||
1);
|
||||
}
|
||||
|
||||
void dma2d_start_const(uint16_t color, uint8_t* out_addr, int32_t pixels) {
|
||||
current_width = pixels;
|
||||
current_height = 1;
|
||||
HAL_DMA2D_Start(&dma2d_handle, rgb565_to_rgb888(color), (uint32_t)out_addr,
|
||||
pixels, 1);
|
||||
}
|
||||
|
||||
void dma2d_start_const_multiline(uint16_t color, uint8_t* out_addr,
|
||||
int32_t width, int32_t height) {
|
||||
current_width = width;
|
||||
current_height = height;
|
||||
HAL_DMA2D_Start(&dma2d_handle, rgb565_to_rgb888(color), (uint32_t)out_addr,
|
||||
width, height);
|
||||
}
|
||||
|
||||
void dma2d_start_blend(uint8_t* overlay_addr, uint8_t* bg_addr,
|
||||
uint8_t* out_addr, int32_t pixels) {
|
||||
current_width = pixels;
|
||||
current_height = 1;
|
||||
HAL_DMA2D_BlendingStart(&dma2d_handle, (uint32_t)overlay_addr,
|
||||
(uint32_t)bg_addr, (uint32_t)out_addr, pixels, 1);
|
||||
}
|
||||
|
||||
void dma2d_wait_for_transfer(void) {
|
||||
while (HAL_DMA2D_PollForTransfer(&dma2d_handle, 10) != HAL_OK)
|
||||
;
|
||||
display_shift_window(current_width * current_height);
|
||||
current_width = 0;
|
||||
current_height = 0;
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "display_draw.h"
|
||||
#include "flash.h"
|
||||
#include "mpu.h"
|
||||
#include "secret.h"
|
||||
|
@ -101,7 +101,7 @@ void reboot_device(void) {
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// xdisplay.h
|
||||
// display.h
|
||||
// =============================================================================
|
||||
|
||||
#include "display.h"
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <xdisplay.h>
|
||||
#include <display.h>
|
||||
|
||||
#include "backlight_pwm.h"
|
||||
#include "display_fb.h"
|
||||
|
@ -18,13 +18,14 @@
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "display_fb.h"
|
||||
#include "display_internal.h"
|
||||
#include "display_io.h"
|
||||
#include "display_panel.h"
|
||||
#include "xdisplay.h"
|
||||
|
||||
#include "gfx_bitblt.h"
|
||||
#include "irq.h"
|
||||
@ -189,18 +190,6 @@ bool display_get_frame_buffer(display_fb_info_t *fb) {
|
||||
state = drv->queue.entry[drv->queue.wix];
|
||||
} while (state == FB_STATE_READY || state == FB_STATE_COPYING);
|
||||
|
||||
if (state == FB_STATE_EMPTY) {
|
||||
// First use of this buffer, copy the previous buffer into it
|
||||
#if (FRAME_BUFFER_COUNT > 1)
|
||||
#ifndef NEW_RENDERING
|
||||
uint8_t *src = get_fb_ptr((FRAME_BUFFER_COUNT + drv->queue.wix - 1) %
|
||||
FRAME_BUFFER_COUNT);
|
||||
uint8_t *dst = get_fb_ptr(drv->queue.wix);
|
||||
memcpy(dst, src, PHYSICAL_FRAME_BUFFER_SIZE);
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
drv->queue.entry[drv->queue.wix] = FB_STATE_PREPARING;
|
||||
|
||||
fb->ptr = get_fb_ptr(drv->queue.wix);
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <xdisplay.h>
|
||||
#include <display.h>
|
||||
|
||||
#include "display_io.h"
|
||||
#include "display_panel.h"
|
||||
|
@ -18,14 +18,15 @@
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
#include "display.h"
|
||||
#include "display_internal.h"
|
||||
#include "ili9341_spi.h"
|
||||
#include "mpu.h"
|
||||
#include "xdisplay.h"
|
||||
|
||||
#if (DISPLAY_RESX != 240) || (DISPLAY_RESY != 320)
|
||||
#error "Incompatible display resolution"
|
||||
|
@ -18,11 +18,12 @@
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "display_internal.h"
|
||||
#include "ili9341_spi.h"
|
||||
#include "xdisplay.h"
|
||||
|
||||
#define MAX_LAYER_NUMBER 2
|
||||
|
||||
|
@ -20,8 +20,8 @@
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "mpu.h"
|
||||
#include "xdisplay.h"
|
||||
|
||||
#if (DISPLAY_RESX != 128) || (DISPLAY_RESY != 128)
|
||||
#error "Incompatible display resolution"
|
||||
|
@ -18,12 +18,13 @@
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "mpu.h"
|
||||
#include "sizedefs.h"
|
||||
#include "trustzone.h"
|
||||
#include "xdisplay.h"
|
||||
|
||||
#ifdef USE_CONSUMPTION_MASK
|
||||
#include "consumption_mask.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,26 +0,0 @@
|
||||
#ifndef DSI_H_
|
||||
#define DSI_H_
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_types.h>
|
||||
|
||||
#define DISPLAY_COLOR_MODE DMA2D_OUTPUT_ARGB8888
|
||||
#define DISPLAY_FRAMEBUFFER_WIDTH 768
|
||||
#define DISPLAY_FRAMEBUFFER_HEIGHT 480
|
||||
#define DISPLAY_FRAMEBUFFER_OFFSET_X 120
|
||||
#define DISPLAY_FRAMEBUFFER_OFFSET_Y 120
|
||||
|
||||
#define DISPLAY_EFFICIENT_CLEAR 1
|
||||
|
||||
extern uint8_t* const DISPLAY_DATA_ADDRESS;
|
||||
|
||||
uint32_t rgb565_to_rgb888(uint16_t color);
|
||||
|
||||
static inline void display_pixel(uint8_t* fb, int16_t x, int16_t y,
|
||||
uint16_t color) {
|
||||
uint32_t p = 4 * ((y + 120) * DISPLAY_FRAMEBUFFER_WIDTH + (x + 120));
|
||||
uint32_t c = rgb565_to_rgb888(color);
|
||||
*((uint32_t*)(fb + p)) = c;
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
../../../stm32f4/displays/panels/lx154a2422.c
|
@ -1 +0,0 @@
|
||||
../../../stm32f4/displays/panels/lx154a2422.h
|
@ -1,179 +0,0 @@
|
||||
|
||||
#include "display.h"
|
||||
#include "displays/st7789v.h"
|
||||
#include "touch.h"
|
||||
|
||||
void lx154a2482_gamma(void) {
|
||||
// positive voltage correction
|
||||
CMD(0xE0);
|
||||
DATA(0xD0);
|
||||
DATA(0x0A);
|
||||
DATA(0x10);
|
||||
DATA(0x0A);
|
||||
DATA(0x0A);
|
||||
DATA(0x26);
|
||||
DATA(0x36);
|
||||
DATA(0x34);
|
||||
DATA(0x4D);
|
||||
DATA(0x18);
|
||||
DATA(0x13);
|
||||
DATA(0x14);
|
||||
DATA(0x2F);
|
||||
DATA(0x34);
|
||||
|
||||
// negative voltage correction
|
||||
CMD(0xE1);
|
||||
DATA(0xD0);
|
||||
DATA(0x0A);
|
||||
DATA(0x10);
|
||||
DATA(0x0A);
|
||||
DATA(0x09);
|
||||
DATA(0x26);
|
||||
DATA(0x36);
|
||||
DATA(0x53);
|
||||
DATA(0x4C);
|
||||
DATA(0x18);
|
||||
DATA(0x14);
|
||||
DATA(0x14);
|
||||
DATA(0x2F);
|
||||
DATA(0x34);
|
||||
}
|
||||
|
||||
void lx154a2482_init_seq(void) {
|
||||
// TEON: Tearing Effect Line On; V-blanking only
|
||||
CMD(0x35);
|
||||
DATA(0x00);
|
||||
|
||||
// Memory Data Access Control (MADCTL)
|
||||
CMD(0x36);
|
||||
DATA(0x00);
|
||||
|
||||
// Interface Pixel Format
|
||||
CMD(0x3A);
|
||||
DATA(0x05);
|
||||
|
||||
// Column Address Set
|
||||
CMD(0x2A);
|
||||
DATA(0x00);
|
||||
DATA(0x00);
|
||||
DATA(0x00);
|
||||
DATA(0xEF);
|
||||
|
||||
// Row Address Set
|
||||
CMD(0x2B);
|
||||
DATA(0x00);
|
||||
DATA(0x00);
|
||||
DATA(0x00);
|
||||
DATA(0xEF);
|
||||
|
||||
// Porch Setting
|
||||
CMD(0xB2);
|
||||
DATA(0x0C);
|
||||
DATA(0x0C);
|
||||
DATA(0x00);
|
||||
DATA(0x33);
|
||||
DATA(0x33);
|
||||
|
||||
// VCOM Setting
|
||||
CMD(0xBB);
|
||||
DATA(0x1F);
|
||||
|
||||
// LCMCTRL: LCM Control: XOR RGB setting
|
||||
CMD(0xC0);
|
||||
DATA(0x20);
|
||||
|
||||
// VDV and VRH Command Enable
|
||||
CMD(0xC2);
|
||||
DATA(0x01);
|
||||
|
||||
// VRH Set
|
||||
CMD(0xC3);
|
||||
DATA(0x0F); // 4.3V
|
||||
|
||||
// VDV Setting
|
||||
CMD(0xC4);
|
||||
DATA(0x20);
|
||||
|
||||
// Frame Rate Control in Normal Mode
|
||||
CMD(0xC6);
|
||||
DATA(0xEF); // column inversion //0X0F Dot INV, 60Hz
|
||||
|
||||
// GATECTRL: Gate Control; NL = 240 gate lines, first scan line is gate 80.;
|
||||
// gate scan direction 319 -> 0
|
||||
CMD(0xE4);
|
||||
DATA(0x1D);
|
||||
DATA(0x0A);
|
||||
DATA(0x11);
|
||||
|
||||
// INVOFF (20h): Display Inversion Off
|
||||
// INVON (21h): Display Inversion On
|
||||
CMD(0x21);
|
||||
// the above config is the most important and definitely necessary
|
||||
|
||||
// PWCTRL1: Power Control 1
|
||||
CMD(0xD0);
|
||||
DATA(0xA4);
|
||||
DATA(0xA1);
|
||||
|
||||
lx154a2482_gamma();
|
||||
}
|
||||
|
||||
void lx154a2482_rotate(int degrees, display_padding_t* padding) {
|
||||
uint16_t shift = 0;
|
||||
char BX = 0, BY = 0;
|
||||
|
||||
#define RGB (1 << 3)
|
||||
#define ML (1 << 4) // vertical refresh order
|
||||
#define MH (1 << 2) // horizontal refresh order
|
||||
#define MV (1 << 5)
|
||||
#define MX (1 << 6)
|
||||
#define MY (1 << 7)
|
||||
// MADCTL: Memory Data Access Control - reference:
|
||||
// section 8.12 in the ST7789V manual
|
||||
uint8_t display_command_parameter = 0;
|
||||
switch (degrees) {
|
||||
case 0:
|
||||
display_command_parameter = 0;
|
||||
BY = 0;
|
||||
break;
|
||||
case 90:
|
||||
display_command_parameter = MV | MX | MH | ML;
|
||||
BX = 1;
|
||||
shift = 1;
|
||||
break;
|
||||
case 180:
|
||||
display_command_parameter = MX | MY | MH | ML;
|
||||
BY = 0;
|
||||
shift = 1;
|
||||
break;
|
||||
case 270:
|
||||
display_command_parameter = MV | MY;
|
||||
BX = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
CMD(0x36);
|
||||
DATA(display_command_parameter);
|
||||
|
||||
if (shift) {
|
||||
// GATECTRL: Gate Control; NL = 240 gate lines, first scan line is
|
||||
// gate 80.; gate scan direction 319 -> 0
|
||||
CMD(0xE4);
|
||||
DATA(0x1D);
|
||||
DATA(0x00);
|
||||
DATA(0x11);
|
||||
} else {
|
||||
// GATECTRL: Gate Control; NL = 240 gate lines, first scan line is
|
||||
// gate 80.; gate scan direction 319 -> 0
|
||||
CMD(0xE4);
|
||||
DATA(0x1D);
|
||||
DATA(0x0A);
|
||||
DATA(0x11);
|
||||
}
|
||||
|
||||
// reset the column and page extents
|
||||
display_set_window(0, 0, DISPLAY_RESX - 1, DISPLAY_RESY - 1);
|
||||
|
||||
padding->x = BX ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0;
|
||||
padding->y = BY ? (MAX_DISPLAY_RESY - DISPLAY_RESY) : 0;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
#ifndef LX154A2422_H_
|
||||
#define LX154A2422_H_
|
||||
|
||||
#include "displays/st7789v.h"
|
||||
|
||||
void lx154a2482_init_seq(void);
|
||||
void lx154a2482_gamma(void);
|
||||
void lx154a2482_rotate(int degrees, display_padding_t* padding);
|
||||
|
||||
#endif
|
@ -1 +0,0 @@
|
||||
../../stm32f4/displays/st7789v.c
|
@ -1 +0,0 @@
|
||||
../../stm32f4/displays/st7789v.h
|
@ -1 +0,0 @@
|
||||
../../stm32f4/displays/vg-2864ksweg01.c
|
@ -1 +0,0 @@
|
||||
../../stm32f4/displays/vg-2864ksweg01.h
|
@ -1 +0,0 @@
|
||||
../stm32f4/dma2d.c
|
@ -18,11 +18,12 @@
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "display_internal.h"
|
||||
#include "mpu.h"
|
||||
#include "xdisplay.h"
|
||||
|
||||
#if (DISPLAY_RESX != 240) || (DISPLAY_RESY != 240)
|
||||
#error "Incompatible display resolution"
|
||||
|
@ -18,9 +18,10 @@
|
||||
*/
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <xdisplay.h>
|
||||
#include "display.h"
|
||||
#include "display_internal.h"
|
||||
#include "mpu.h"
|
||||
#include "trustzone.h"
|
||||
|
@ -61,7 +61,6 @@
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include "colors.h"
|
||||
#include "display_internal.h"
|
||||
#include "irq.h"
|
||||
|
||||
|
@ -1,300 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_image.h>
|
||||
|
||||
#include "display.h"
|
||||
#include "profile.h"
|
||||
|
||||
#define EMULATOR_BORDER 16
|
||||
|
||||
static SDL_Window *WINDOW;
|
||||
static SDL_Renderer *RENDERER;
|
||||
static SDL_Surface *BUFFER;
|
||||
static SDL_Texture *TEXTURE, *BACKGROUND;
|
||||
|
||||
static SDL_Surface *PREV_SAVED;
|
||||
|
||||
static int DISPLAY_BACKLIGHT = -1;
|
||||
static int DISPLAY_ORIENTATION = -1;
|
||||
|
||||
int sdl_display_res_x = DISPLAY_RESX, sdl_display_res_y = DISPLAY_RESY;
|
||||
int sdl_touch_offset_x, sdl_touch_offset_y;
|
||||
|
||||
// Using RGB565 (16-bit) color format.
|
||||
typedef uint16_t pixel_color;
|
||||
|
||||
// this is just for compatibility with DMA2D using algorithms
|
||||
uint8_t *const DISPLAY_DATA_ADDRESS = 0;
|
||||
|
||||
static struct {
|
||||
struct {
|
||||
uint16_t x, y;
|
||||
} start;
|
||||
struct {
|
||||
uint16_t x, y;
|
||||
} end;
|
||||
struct {
|
||||
uint16_t x, y;
|
||||
} pos;
|
||||
} PIXELWINDOW;
|
||||
|
||||
void display_pixeldata(pixel_color c) {
|
||||
#if !defined USE_RGB_COLORS
|
||||
// set to white if highest bits of all R, G, B values are set to 1
|
||||
// bin(10000 100000 10000) = hex(0x8410)
|
||||
// otherwise set to black
|
||||
c = (c & 0x8410) ? 0xFFFF : 0x0000;
|
||||
#endif
|
||||
if (!RENDERER) {
|
||||
display_init_all();
|
||||
}
|
||||
if (PIXELWINDOW.pos.x <= PIXELWINDOW.end.x &&
|
||||
PIXELWINDOW.pos.y <= PIXELWINDOW.end.y) {
|
||||
((pixel_color *)
|
||||
BUFFER->pixels)[PIXELWINDOW.pos.x + PIXELWINDOW.pos.y * BUFFER->pitch /
|
||||
sizeof(pixel_color)] = c;
|
||||
}
|
||||
PIXELWINDOW.pos.x++;
|
||||
if (PIXELWINDOW.pos.x > PIXELWINDOW.end.x) {
|
||||
PIXELWINDOW.pos.x = PIXELWINDOW.start.x;
|
||||
PIXELWINDOW.pos.y++;
|
||||
}
|
||||
}
|
||||
|
||||
void display_pixeldata_dirty(void) {}
|
||||
|
||||
void display_reset_state() {}
|
||||
|
||||
void display_init_seq(void) {}
|
||||
|
||||
void display_exit_handler(void) {
|
||||
SDL_FreeSurface(PREV_SAVED);
|
||||
SDL_FreeSurface(BUFFER);
|
||||
if (BACKGROUND != NULL) {
|
||||
SDL_DestroyTexture(BACKGROUND);
|
||||
}
|
||||
if (TEXTURE != NULL) {
|
||||
SDL_DestroyTexture(TEXTURE);
|
||||
}
|
||||
if (RENDERER != NULL) {
|
||||
SDL_DestroyRenderer(RENDERER);
|
||||
}
|
||||
if (WINDOW != NULL) {
|
||||
SDL_DestroyWindow(WINDOW);
|
||||
}
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
void display_init_all(void) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
printf("%s\n", SDL_GetError());
|
||||
error_shutdown("SDL_Init error");
|
||||
}
|
||||
atexit(display_exit_handler);
|
||||
|
||||
char *window_title = NULL;
|
||||
char *window_title_alloc = NULL;
|
||||
if (asprintf(&window_title_alloc, "Trezor^emu: %s", profile_name()) > 0) {
|
||||
window_title = window_title_alloc;
|
||||
} else {
|
||||
window_title = "Trezor^emu";
|
||||
window_title_alloc = NULL;
|
||||
}
|
||||
|
||||
WINDOW =
|
||||
SDL_CreateWindow(window_title, SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED, WINDOW_WIDTH, WINDOW_HEIGHT,
|
||||
#ifdef TREZOR_EMULATOR_RASPI
|
||||
SDL_WINDOW_SHOWN | SDL_WINDOW_FULLSCREEN
|
||||
#else
|
||||
SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI
|
||||
#endif
|
||||
);
|
||||
free(window_title_alloc);
|
||||
if (!WINDOW) {
|
||||
printf("%s\n", SDL_GetError());
|
||||
error_shutdown("SDL_CreateWindow error");
|
||||
}
|
||||
RENDERER = SDL_CreateRenderer(WINDOW, -1, SDL_RENDERER_SOFTWARE);
|
||||
if (!RENDERER) {
|
||||
printf("%s\n", SDL_GetError());
|
||||
SDL_DestroyWindow(WINDOW);
|
||||
error_shutdown("SDL_CreateRenderer error");
|
||||
}
|
||||
SDL_SetRenderDrawColor(RENDERER, 0, 0, 0, 255);
|
||||
SDL_RenderClear(RENDERER);
|
||||
BUFFER = SDL_CreateRGBSurface(0, DISPLAY_RESX, DISPLAY_RESY, 16, 0xF800,
|
||||
0x07E0, 0x001F, 0x0000);
|
||||
TEXTURE = SDL_CreateTexture(RENDERER, SDL_PIXELFORMAT_RGB565,
|
||||
SDL_TEXTUREACCESS_STREAMING, DISPLAY_RESX,
|
||||
DISPLAY_RESY);
|
||||
SDL_SetTextureBlendMode(TEXTURE, SDL_BLENDMODE_BLEND);
|
||||
#ifdef __APPLE__
|
||||
// macOS Mojave SDL black screen workaround
|
||||
SDL_PumpEvents();
|
||||
SDL_SetWindowSize(WINDOW, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
#endif
|
||||
#include BACKGROUND_FILE
|
||||
#define CONCAT_LEN_HELPER(name) name##_len
|
||||
#define CONCAT_LEN(name) CONCAT_LEN_HELPER(name)
|
||||
BACKGROUND = IMG_LoadTexture_RW(
|
||||
RENDERER, SDL_RWFromMem(BACKGROUND_NAME, CONCAT_LEN(BACKGROUND_NAME)), 0);
|
||||
if (BACKGROUND) {
|
||||
SDL_SetTextureBlendMode(BACKGROUND, SDL_BLENDMODE_NONE);
|
||||
sdl_touch_offset_x = TOUCH_OFFSET_X;
|
||||
sdl_touch_offset_y = TOUCH_OFFSET_Y;
|
||||
} else {
|
||||
SDL_SetWindowSize(WINDOW, DISPLAY_RESX + 2 * EMULATOR_BORDER,
|
||||
DISPLAY_RESY + 2 * EMULATOR_BORDER);
|
||||
sdl_touch_offset_x = EMULATOR_BORDER;
|
||||
sdl_touch_offset_y = EMULATOR_BORDER;
|
||||
}
|
||||
#if !USE_BACKLIGHT
|
||||
// some models do not have backlight capabilities in hardware, so
|
||||
// setting its value here for emulator to avoid
|
||||
// calling any `set_backlight` functions
|
||||
DISPLAY_BACKLIGHT = 255;
|
||||
#else
|
||||
DISPLAY_BACKLIGHT = 0;
|
||||
#endif
|
||||
#ifdef TREZOR_EMULATOR_RASPI
|
||||
DISPLAY_ORIENTATION = 270;
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
#else
|
||||
DISPLAY_ORIENTATION = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
|
||||
if (!RENDERER) {
|
||||
display_init_all();
|
||||
}
|
||||
PIXELWINDOW.start.x = x0;
|
||||
PIXELWINDOW.start.y = y0;
|
||||
PIXELWINDOW.end.x = x1;
|
||||
PIXELWINDOW.end.y = y1;
|
||||
PIXELWINDOW.pos.x = x0;
|
||||
PIXELWINDOW.pos.y = y0;
|
||||
}
|
||||
|
||||
void display_sync(void) {}
|
||||
|
||||
void display_refresh(void) {
|
||||
if (!RENDERER) {
|
||||
display_init_all();
|
||||
}
|
||||
if (BACKGROUND) {
|
||||
const SDL_Rect r = {0, 0, WINDOW_WIDTH, WINDOW_HEIGHT};
|
||||
SDL_RenderCopy(RENDERER, BACKGROUND, NULL, &r);
|
||||
} else {
|
||||
SDL_RenderClear(RENDERER);
|
||||
}
|
||||
// Show the display buffer
|
||||
SDL_UpdateTexture(TEXTURE, NULL, BUFFER->pixels, BUFFER->pitch);
|
||||
#define BACKLIGHT_NORMAL 150
|
||||
SDL_SetTextureAlphaMod(TEXTURE,
|
||||
MIN(255, 255 * DISPLAY_BACKLIGHT / BACKLIGHT_NORMAL));
|
||||
if (BACKGROUND) {
|
||||
const SDL_Rect r = {TOUCH_OFFSET_X, TOUCH_OFFSET_Y, DISPLAY_RESX,
|
||||
DISPLAY_RESY};
|
||||
SDL_RenderCopyEx(RENDERER, TEXTURE, NULL, &r, DISPLAY_ORIENTATION, NULL, 0);
|
||||
} else {
|
||||
const SDL_Rect r = {EMULATOR_BORDER, EMULATOR_BORDER, DISPLAY_RESX,
|
||||
DISPLAY_RESY};
|
||||
SDL_RenderCopyEx(RENDERER, TEXTURE, NULL, &r, DISPLAY_ORIENTATION, NULL, 0);
|
||||
}
|
||||
SDL_RenderPresent(RENDERER);
|
||||
}
|
||||
|
||||
int display_orientation(int degrees) {
|
||||
if (degrees != DISPLAY_ORIENTATION) {
|
||||
#if defined ORIENTATION_NSEW
|
||||
if (degrees == 0 || degrees == 90 || degrees == 180 || degrees == 270) {
|
||||
#elif defined ORIENTATION_NS
|
||||
if (degrees == 0 || degrees == 180) {
|
||||
#else
|
||||
if (degrees == 0) {
|
||||
#endif
|
||||
DISPLAY_ORIENTATION = degrees;
|
||||
display_refresh();
|
||||
}
|
||||
}
|
||||
return DISPLAY_ORIENTATION;
|
||||
}
|
||||
|
||||
int display_get_orientation(void) { return DISPLAY_ORIENTATION; }
|
||||
|
||||
int display_backlight(int val) {
|
||||
#if !USE_BACKLIGHT
|
||||
val = 255;
|
||||
#endif
|
||||
if (DISPLAY_BACKLIGHT != val && val >= 0 && val <= 255) {
|
||||
DISPLAY_BACKLIGHT = val;
|
||||
display_refresh();
|
||||
}
|
||||
return DISPLAY_BACKLIGHT;
|
||||
}
|
||||
|
||||
const char *display_save(const char *prefix) {
|
||||
if (!RENDERER) {
|
||||
display_init_all();
|
||||
}
|
||||
static int count;
|
||||
static char filename[256];
|
||||
// take a cropped view of the screen contents
|
||||
const SDL_Rect rect = {0, 0, DISPLAY_RESX, DISPLAY_RESY};
|
||||
SDL_Surface *crop = SDL_CreateRGBSurface(
|
||||
BUFFER->flags, rect.w, rect.h, BUFFER->format->BitsPerPixel,
|
||||
BUFFER->format->Rmask, BUFFER->format->Gmask, BUFFER->format->Bmask,
|
||||
BUFFER->format->Amask);
|
||||
SDL_BlitSurface(BUFFER, &rect, crop, NULL);
|
||||
// compare with previous screen, skip if equal
|
||||
if (PREV_SAVED != NULL) {
|
||||
if (memcmp(PREV_SAVED->pixels, crop->pixels, crop->pitch * crop->h) == 0) {
|
||||
SDL_FreeSurface(crop);
|
||||
return filename;
|
||||
}
|
||||
SDL_FreeSurface(PREV_SAVED);
|
||||
}
|
||||
// save to png
|
||||
snprintf(filename, sizeof(filename), "%s%08d.png", prefix, count++);
|
||||
IMG_SavePNG(crop, filename);
|
||||
PREV_SAVED = crop;
|
||||
return filename;
|
||||
}
|
||||
|
||||
void display_clear_save(void) {
|
||||
SDL_FreeSurface(PREV_SAVED);
|
||||
PREV_SAVED = NULL;
|
||||
}
|
||||
|
||||
uint8_t *display_get_wr_addr(void) { return (uint8_t *)DISPLAY_DATA_ADDRESS; }
|
||||
|
||||
void display_finish_actions(void) {}
|
||||
|
||||
void display_reinit(void) {}
|
@ -20,9 +20,10 @@
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_model.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <xdisplay.h>
|
||||
#include "display.h"
|
||||
|
||||
#include <SDL.h>
|
||||
#include <SDL_image.h>
|
||||
|
@ -1,169 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZORHAL_XDISPLAY_H
|
||||
#define TREZORHAL_XDISPLAY_H
|
||||
|
||||
#include <trezor_types.h>
|
||||
|
||||
#include "gfx_bitblt.h"
|
||||
|
||||
// This is a universal API for controlling different types of display
|
||||
// controllers.
|
||||
//
|
||||
// Currently, following displays displays are supported
|
||||
//
|
||||
// VG-2864KSWEG01 - OLED Mono / 128x64 pixels / SPI
|
||||
// - Model T2B1
|
||||
//
|
||||
// UG-2828SWIG01 - OLED Mono / 128x128 pixels / Parallel
|
||||
// - Early revisions of T2B1
|
||||
//
|
||||
// ST7789V - TFT RGB / 240x240 pixels / Parallel
|
||||
// - Model T2T1 / Model T3T1
|
||||
//
|
||||
// ILI9341 - TFT RGB / 320x240 pixels / Parallel / LTDC + SPI
|
||||
// - STM32F429I-DISC1 Discovery Board
|
||||
//
|
||||
// MIPI -
|
||||
// - STM32U5A9J-DK Discovery Board
|
||||
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
// Specifies how display content should be handled during
|
||||
// initialization or deinitialization.
|
||||
typedef enum {
|
||||
// Clear the display content
|
||||
DISPLAY_RESET_CONTENT,
|
||||
// Retain the display content
|
||||
DISPLAY_RETAIN_CONTENT
|
||||
} display_content_mode_t;
|
||||
|
||||
// Initializes the display controller.
|
||||
//
|
||||
// If `mode` is `DISPLAY_RETAIN_CONTENT`, ensure the driver was previously
|
||||
// initialized and `display_deinit(DISPLAY_RETAIN_CONTENT)` was called.
|
||||
void display_init(display_content_mode_t mode);
|
||||
|
||||
// Deinitializes the display controller.
|
||||
//
|
||||
// If `mode` is `DISPLAY_RETAIN_CONTENT`, the function waits for
|
||||
// background operations to complete and disables interrupts, so the
|
||||
// application can safely proceed to the next boot stage and call
|
||||
// `display_init(DISPLAY_RETAIN_CONTENT)`.
|
||||
void display_deinit(display_content_mode_t mode);
|
||||
|
||||
// Allows unprivileged access to the display framebuffer from
|
||||
// perspective of the GTZC (Global TrustZone Controller).
|
||||
void display_set_unpriv_access(bool unpriv);
|
||||
|
||||
#endif // KERNEL_MODE
|
||||
|
||||
// Sets display backlight level ranging from 0 (off)..255 (maximum).
|
||||
//
|
||||
// The default backligt level is 0. Without settings it
|
||||
// to some higher value the displayed pixels are not visible.
|
||||
// Beware that his also applies to the emulator.
|
||||
//
|
||||
// Returns the set level (usually the same value or the
|
||||
// closest value to the `level` argument)
|
||||
int display_set_backlight(int level);
|
||||
|
||||
// Gets current display level ranging from 0 (off)..255 (maximum).
|
||||
int display_get_backlight(void);
|
||||
|
||||
// Sets the display orientation.
|
||||
//
|
||||
// May accept one of following values: 0, 90, 180, 270
|
||||
// but accepted values are model-dependent.
|
||||
// Default display orientation is always 0.
|
||||
//
|
||||
// Returns the set orientation
|
||||
int display_set_orientation(int angle);
|
||||
|
||||
// Gets the display's current orientation
|
||||
//
|
||||
// Returned value is one of 0, 90, 180, 270.
|
||||
int display_get_orientation(void);
|
||||
|
||||
#ifdef XFRAMEBUFFER
|
||||
|
||||
typedef struct {
|
||||
// Pointer to the top-left pixel
|
||||
void *ptr;
|
||||
// Stride in bytes
|
||||
size_t stride;
|
||||
|
||||
} display_fb_info_t;
|
||||
|
||||
// Provides pointer to the inactive (writeable) framebuffer.
|
||||
//
|
||||
// If framebuffer is not available yet due to display refreshing etc.,
|
||||
// the function may block until the buffer is ready to write.
|
||||
//
|
||||
// Return `false` if the framebuffer is not available.
|
||||
bool display_get_frame_buffer(display_fb_info_t *fb);
|
||||
|
||||
#else // XFRAMEBUFFER
|
||||
|
||||
// Waits for the vertical synchronization pulse.
|
||||
//
|
||||
// Used for synchronization with the display refresh cycle
|
||||
// to achieve tearless UX if possible when not using a frame buffer.
|
||||
void display_wait_for_sync(void);
|
||||
#endif
|
||||
|
||||
// Swaps the frame buffers
|
||||
//
|
||||
// The function waits for vertical synchronization and
|
||||
// swaps the active (currently displayed) and the inactive frame buffers.
|
||||
void display_refresh(void);
|
||||
|
||||
// Following functions define display's bitblt interface.
|
||||
//
|
||||
// These functions draw directly to to display or to the
|
||||
// currently inactive framebuffer.
|
||||
//
|
||||
// bb->dst_row and bb->dst_stride must be 0
|
||||
|
||||
// Fills a rectangle with a solid color.
|
||||
// This function is supported by all types of displays.
|
||||
void display_fill(const gfx_bitblt_t *bb);
|
||||
// Copies an RGB565 bitmap.
|
||||
// This function is supported by RGB displays only.
|
||||
void display_copy_rgb565(const gfx_bitblt_t *bb);
|
||||
// Copies a MONO4 bitmap (supported only with RGB displays).
|
||||
// This function is supported by RGB displays only.
|
||||
void display_copy_mono4(const gfx_bitblt_t *bb);
|
||||
// Copies a MONO1P bitmap.
|
||||
// This function is supported by all types of displays.
|
||||
void display_copy_mono1p(const gfx_bitblt_t *bb);
|
||||
|
||||
#ifdef TREZOR_EMULATOR
|
||||
// Save the screen content to a file.
|
||||
// The function is available only on the emulator.
|
||||
const char *display_save(const char *prefix);
|
||||
void display_clear_save(void);
|
||||
#endif
|
||||
|
||||
// Adds some declarations needed to compile with the legacy code
|
||||
// (will be removed with the display legacy code)
|
||||
#include "xdisplay_legacy.h"
|
||||
|
||||
#endif // TREZORHAL_XDISPLAY_H
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "xdisplay_legacy.h"
|
||||
#include "xdisplay.h"
|
||||
|
||||
// This code emulates the legacy display interface and will be
|
||||
// removed after final cleanup of display drivers when the legacy code
|
||||
// is removed.
|
||||
|
||||
int display_orientation(int angle) {
|
||||
if (angle >= 0) {
|
||||
return display_set_orientation(angle);
|
||||
} else {
|
||||
return display_get_orientation();
|
||||
}
|
||||
}
|
||||
|
||||
int display_backlight(int level) {
|
||||
if (level >= 0) {
|
||||
return display_set_backlight(level);
|
||||
} else {
|
||||
return display_get_backlight();
|
||||
}
|
||||
}
|
||||
|
||||
void display_sync(void) {
|
||||
#ifndef XFRAMEBUFFER
|
||||
display_wait_for_sync();
|
||||
#endif
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Trezor project, https://trezor.io/
|
||||
*
|
||||
* Copyright (c) SatoshiLabs
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZORHAL_DISPLAY_LEGACY_H
|
||||
#define TREZORHAL_DISPLAY_LEGACY_H
|
||||
|
||||
#include <trezor_types.h>
|
||||
|
||||
#include "buffers.h"
|
||||
|
||||
// These declarations will be removed after the final cleanup
|
||||
// of display drivers. They are here just to simplify integration
|
||||
// with the legacy code.
|
||||
//
|
||||
// Most of these functions are not called when NEW_RENDERING=1,
|
||||
// and they are only needed for successful code compilation.
|
||||
|
||||
#define DISPLAY_FRAMEBUFFER_WIDTH 768
|
||||
#define DISPLAY_FRAMEBUFFER_HEIGHT 480
|
||||
#define DISPLAY_FRAMEBUFFER_OFFSET_X 0
|
||||
#define DISPLAY_FRAMEBUFFER_OFFSET_Y 0
|
||||
|
||||
int display_orientation(int angle);
|
||||
int display_backlight(int level);
|
||||
void display_refresh(void);
|
||||
void display_shift_window(uint16_t pixels);
|
||||
uint16_t display_get_window_offset(void);
|
||||
void display_pixeldata_dirty(void);
|
||||
uint8_t* display_get_wr_addr(void);
|
||||
void display_sync(void);
|
||||
void display_set_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
|
||||
void display_pixeldata(uint16_t c);
|
||||
uint32_t* display_get_fb_addr(void);
|
||||
|
||||
void display_clear(void);
|
||||
void display_text_render_buffer(const char* text, int textlen, int font,
|
||||
buffer_text_t* buffer, int text_offset);
|
||||
|
||||
#define PIXELDATA(c) display_pixeldata(c)
|
||||
|
||||
#endif // TREZORHAL_DISPLAY_LEGACY_H
|
@ -13,7 +13,6 @@ def configure(
|
||||
) -> list[str]:
|
||||
features_available: list[str] = []
|
||||
board = "D001/boards/stm32f429i-disc1.h"
|
||||
display = "ltdc.c"
|
||||
hw_model = get_hw_model_as_number("D001")
|
||||
hw_revision = 0
|
||||
|
||||
@ -34,21 +33,13 @@ def configure(
|
||||
defines += [f"HW_MODEL={hw_model}"]
|
||||
defines += [f"HW_REVISION={hw_revision}"]
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
sources += [
|
||||
"embed/trezorhal/xdisplay_legacy.c",
|
||||
"embed/trezorhal/stm32f4/xdisplay/stm32f429i-disc1/display_driver.c",
|
||||
"embed/trezorhal/stm32f4/xdisplay/stm32f429i-disc1/display_ltdc.c",
|
||||
"embed/trezorhal/stm32f4/xdisplay/stm32f429i-disc1/ili9341_spi.c",
|
||||
]
|
||||
else:
|
||||
sources += [f"embed/trezorhal/stm32f4/displays/{display}"]
|
||||
sources += ["embed/trezorhal/stm32f4/displays/ili9341_spi.c"]
|
||||
sources += [
|
||||
"embed/trezorhal/stm32f4/xdisplay/stm32f429i-disc1/display_driver.c",
|
||||
"embed/trezorhal/stm32f4/xdisplay/stm32f429i-disc1/display_ltdc.c",
|
||||
"embed/trezorhal/stm32f4/xdisplay/stm32f429i-disc1/ili9341_spi.c",
|
||||
]
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
sources += ["embed/trezorhal/stm32u5/dma2d_bitblt.c"]
|
||||
else:
|
||||
sources += ["embed/trezorhal/stm32u5/dma2d.c"]
|
||||
sources += ["embed/trezorhal/stm32u5/dma2d_bitblt.c"]
|
||||
|
||||
sources += [
|
||||
"vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c"
|
||||
@ -58,15 +49,12 @@ def configure(
|
||||
]
|
||||
defines += ["USE_DMA2D"]
|
||||
defines += ["USE_RGB_COLORS=1"]
|
||||
defines += ["FRAMEBUFFER"]
|
||||
features_available.append("dma2d")
|
||||
features_available.append("framebuffer")
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
defines += ["XFRAMEBUFFER"]
|
||||
defines += ["DISPLAY_RGB565"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_rgb565")
|
||||
defines += ["XFRAMEBUFFER"]
|
||||
defines += ["DISPLAY_RGB565"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_rgb565")
|
||||
|
||||
sources += ["embed/trezorhal/stm32f4/sdram.c"]
|
||||
defines += ["USE_SDRAM=1"]
|
||||
|
@ -13,7 +13,6 @@ def configure(
|
||||
) -> list[str]:
|
||||
features_available: list[str] = []
|
||||
board = "D002/boards/stm32u5a9j-dk.h"
|
||||
display = "dsi.c"
|
||||
hw_model = get_hw_model_as_number("D002")
|
||||
hw_revision = 0
|
||||
|
||||
@ -41,17 +40,11 @@ def configure(
|
||||
f"HW_REVISION={hw_revision}",
|
||||
]
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
sources += [
|
||||
"embed/trezorhal/xdisplay_legacy.c",
|
||||
"embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_driver.c",
|
||||
"embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_fb.c",
|
||||
"embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_ltdc_dsi.c",
|
||||
]
|
||||
else:
|
||||
sources += [
|
||||
f"embed/trezorhal/stm32u5/displays/{display}",
|
||||
]
|
||||
sources += [
|
||||
"embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_driver.c",
|
||||
"embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_fb.c",
|
||||
"embed/trezorhal/stm32u5/xdisplay/stm32u5a9j-dk/display_ltdc_dsi.c",
|
||||
]
|
||||
|
||||
if "input" in features_wanted:
|
||||
sources += ["embed/trezorhal/stm32u5/i2c_bus.c"]
|
||||
@ -76,25 +69,19 @@ def configure(
|
||||
|
||||
defines += [
|
||||
"USE_DMA2D",
|
||||
"FRAMEBUFFER",
|
||||
"FRAMEBUFFER32BIT",
|
||||
"UI_COLOR_32BIT",
|
||||
"USE_RGB_COLORS",
|
||||
]
|
||||
if "new_rendering" in features_wanted:
|
||||
sources += ["embed/trezorhal/stm32u5/dma2d_bitblt.c"]
|
||||
else:
|
||||
sources += ["embed/trezorhal/stm32u5/dma2d.c"]
|
||||
|
||||
sources += ["embed/trezorhal/stm32u5/dma2d_bitblt.c"]
|
||||
|
||||
features_available.append("dma2d")
|
||||
features_available.append("framebuffer")
|
||||
features_available.append("framebuffer32bit")
|
||||
features_available.append("ui_color_32bit")
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
defines += ["XFRAMEBUFFER"]
|
||||
defines += ["DISPLAY_RGBA8888"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_rgba8888")
|
||||
defines += ["XFRAMEBUFFER"]
|
||||
defines += ["DISPLAY_RGBA8888"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_rgba8888")
|
||||
|
||||
defines += [
|
||||
"USE_HASH_PROCESSOR=1",
|
||||
|
@ -17,10 +17,9 @@ def configure(
|
||||
hw_revision = 0
|
||||
mcu = "STM32F427xx"
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
defines += ["XFRAMEBUFFER", "DISPLAY_MONO"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_mono")
|
||||
defines += ["XFRAMEBUFFER", "DISPLAY_MONO"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_mono")
|
||||
|
||||
defines += [mcu]
|
||||
defines += [f'TREZOR_BOARD=\\"{board}\\"']
|
||||
|
@ -15,12 +15,10 @@ def configure(
|
||||
hw_model = get_hw_model_as_number("T2B1")
|
||||
hw_revision = 10
|
||||
board = "T2B1/boards/trezor_r_v10.h"
|
||||
display = "vg-2864ksweg01.c"
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
defines += ["XFRAMEBUFFER"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_mono")
|
||||
defines += ["XFRAMEBUFFER"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_mono")
|
||||
|
||||
mcu = "STM32F427xx"
|
||||
|
||||
@ -39,11 +37,7 @@ def configure(
|
||||
defines += [f"HW_MODEL={hw_model}"]
|
||||
defines += [f"HW_REVISION={hw_revision}"]
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
sources += ["embed/trezorhal/xdisplay_legacy.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/vg-2864/display_driver.c"]
|
||||
else:
|
||||
sources += [f"embed/trezorhal/stm32f4/displays/{display}"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/vg-2864/display_driver.c"]
|
||||
|
||||
if "input" in features_wanted:
|
||||
sources += ["embed/trezorhal/stm32f4/button.c"]
|
||||
|
@ -17,9 +17,8 @@ def configure(
|
||||
hw_revision = 0
|
||||
mcu = "STM32F427xx"
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
defines += ["DISPLAY_RGB565"]
|
||||
features_available.append("display_rgb565")
|
||||
defines += ["DISPLAY_RGB565"]
|
||||
features_available.append("display_rgb565")
|
||||
defines += ["USE_RGB_COLORS"]
|
||||
|
||||
defines += [mcu]
|
||||
@ -32,12 +31,9 @@ def configure(
|
||||
|
||||
if "dma2d" in features_wanted:
|
||||
features_available.append("dma2d")
|
||||
if "new_rendering" in features_wanted:
|
||||
sources += [
|
||||
"embed/trezorhal/unix/dma2d_bitblt.c",
|
||||
]
|
||||
else:
|
||||
sources += ["embed/lib/dma2d_emul.c"]
|
||||
sources += [
|
||||
"embed/trezorhal/unix/dma2d_bitblt.c",
|
||||
]
|
||||
defines += ["USE_DMA2D"]
|
||||
|
||||
if "sd_card" in features_wanted:
|
||||
|
@ -13,14 +13,11 @@ def configure(
|
||||
) -> list[str]:
|
||||
features_available: list[str] = []
|
||||
board = "T2T1/boards/trezor_t.h"
|
||||
display = "st7789v.c"
|
||||
hw_model = get_hw_model_as_number("T2T1")
|
||||
hw_revision = 0
|
||||
features_available.append("disp_i8080_8bit_dw")
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
defines += ["DISPLAY_RGB565"]
|
||||
features_available.append("display_rgb565")
|
||||
defines += ["DISPLAY_RGB565"]
|
||||
features_available.append("display_rgb565")
|
||||
defines += ["USE_RGB_COLORS=1"]
|
||||
|
||||
mcu = "STM32F427xx"
|
||||
@ -40,39 +37,14 @@ def configure(
|
||||
defines += [f"HW_MODEL={hw_model}"]
|
||||
defines += [f"HW_REVISION={hw_revision}"]
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
sources += ["embed/trezorhal/xdisplay_legacy.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/display_nofb.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/display_driver.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/display_io.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/display_panel.c"]
|
||||
sources += [
|
||||
"embed/trezorhal/stm32f4/xdisplay/st-7789/panels/tf15411a.c",
|
||||
]
|
||||
sources += [
|
||||
"embed/trezorhal/stm32f4/xdisplay/st-7789/panels/154a.c",
|
||||
]
|
||||
sources += [
|
||||
"embed/trezorhal/stm32f4/xdisplay/st-7789/panels/lx154a2411.c",
|
||||
]
|
||||
sources += [
|
||||
"embed/trezorhal/stm32f4/xdisplay/st-7789/panels/lx154a2422.c",
|
||||
]
|
||||
|
||||
else:
|
||||
sources += [f"embed/trezorhal/stm32f4/displays/{display}"]
|
||||
sources += [
|
||||
"embed/trezorhal/stm32f4/displays/panels/tf15411a.c",
|
||||
]
|
||||
sources += [
|
||||
"embed/trezorhal/stm32f4/displays/panels/154a.c",
|
||||
]
|
||||
sources += [
|
||||
"embed/trezorhal/stm32f4/displays/panels/lx154a2411.c",
|
||||
]
|
||||
sources += [
|
||||
"embed/trezorhal/stm32f4/displays/panels/lx154a2422.c",
|
||||
]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/display_nofb.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/display_driver.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/display_io.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/display_panel.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/panels/tf15411a.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/panels/154a.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/panels/lx154a2411.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/panels/lx154a2422.c"]
|
||||
|
||||
sources += ["embed/trezorhal/stm32f4/backlight_pwm.c"]
|
||||
|
||||
@ -117,10 +89,7 @@ def configure(
|
||||
|
||||
if "dma2d" in features_wanted:
|
||||
defines += ["USE_DMA2D"]
|
||||
if "new_rendering" in features_wanted:
|
||||
sources += ["embed/trezorhal/stm32u5/dma2d_bitblt.c"]
|
||||
else:
|
||||
sources += ["embed/trezorhal/stm32u5/dma2d.c"]
|
||||
sources += ["embed/trezorhal/stm32u5/dma2d_bitblt.c"]
|
||||
sources += [
|
||||
"vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma2d.c"
|
||||
]
|
||||
|
@ -17,10 +17,9 @@ def configure(
|
||||
hw_revision = 0
|
||||
mcu = "STM32U585xx"
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
defines += ["XFRAMEBUFFER", "DISPLAY_MONO"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_mono")
|
||||
defines += ["XFRAMEBUFFER", "DISPLAY_MONO"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_mono")
|
||||
|
||||
defines += [mcu]
|
||||
defines += [f'TREZOR_BOARD=\\"{board}\\"']
|
||||
|
@ -13,14 +13,12 @@ def configure(
|
||||
) -> list[str]:
|
||||
features_available: list[str] = []
|
||||
board = "T3B1/boards/trezor_t3b1_revB.h"
|
||||
display = "vg-2864ksweg01.c"
|
||||
hw_model = get_hw_model_as_number("T3B1")
|
||||
hw_revision = "B"
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
defines += ["XFRAMEBUFFER"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_mono")
|
||||
defines += ["XFRAMEBUFFER"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_mono")
|
||||
|
||||
mcu = "STM32U585xx"
|
||||
linker_script = """embed/trezorhal/stm32u5/linker/u58/{target}.ld"""
|
||||
@ -40,11 +38,7 @@ def configure(
|
||||
defines += [f"HW_MODEL={hw_model}"]
|
||||
defines += [f"HW_REVISION={ord(hw_revision)}"]
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
sources += ["embed/trezorhal/xdisplay_legacy.c"]
|
||||
sources += ["embed/trezorhal/stm32u5/xdisplay/vg-2864/display_driver.c"]
|
||||
else:
|
||||
sources += [f"embed/trezorhal/stm32u5/displays/{display}"]
|
||||
sources += ["embed/trezorhal/stm32u5/xdisplay/vg-2864/display_driver.c"]
|
||||
|
||||
if "input" in features_wanted:
|
||||
sources += ["embed/trezorhal/stm32u5/button.c"]
|
||||
|
@ -17,10 +17,9 @@ def configure(
|
||||
hw_revision = 0
|
||||
mcu = "STM32U585xx"
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
defines += ["XFRAMEBUFFER", "DISPLAY_RGB565"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_rgb565")
|
||||
defines += ["XFRAMEBUFFER", "DISPLAY_RGB565"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_rgb565")
|
||||
defines += ["USE_RGB_COLORS=1"]
|
||||
|
||||
defines += [mcu]
|
||||
@ -34,12 +33,9 @@ def configure(
|
||||
|
||||
if "dma2d" in features_wanted:
|
||||
features_available.append("dma2d")
|
||||
if "new_rendering" in features_wanted:
|
||||
sources += [
|
||||
"embed/trezorhal/unix/dma2d_bitblt.c",
|
||||
]
|
||||
else:
|
||||
sources += ["embed/lib/dma2d_emul.c"]
|
||||
sources += [
|
||||
"embed/trezorhal/unix/dma2d_bitblt.c",
|
||||
]
|
||||
defines += ["USE_DMA2D"]
|
||||
|
||||
if "sd_card" in features_wanted:
|
||||
|
@ -13,18 +13,13 @@ def configure(
|
||||
) -> list[str]:
|
||||
features_available: list[str] = []
|
||||
board = "T3T1/boards/trezor_t3t1_revE.h"
|
||||
display = "st7789v.c"
|
||||
hw_model = get_hw_model_as_number("T3T1")
|
||||
hw_revision = 0
|
||||
features_available.append("disp_i8080_8bit_dw")
|
||||
features_available.append("framebuffer")
|
||||
defines += ["FRAMEBUFFER"]
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_rgb565")
|
||||
defines += ["DISPLAY_RGB565"]
|
||||
defines += ["XFRAMEBUFFER"]
|
||||
features_available.append("xframebuffer")
|
||||
features_available.append("display_rgb565")
|
||||
defines += ["DISPLAY_RGB565"]
|
||||
defines += ["XFRAMEBUFFER"]
|
||||
defines += ["USE_RGB_COLORS=1"]
|
||||
|
||||
mcu = "STM32U585xx"
|
||||
@ -45,20 +40,13 @@ def configure(
|
||||
defines += [f"HW_MODEL={hw_model}"]
|
||||
defines += [f"HW_REVISION={hw_revision}"]
|
||||
|
||||
if "new_rendering" in features_wanted:
|
||||
sources += ["embed/trezorhal/xdisplay_legacy.c"]
|
||||
sources += ["embed/trezorhal/stm32u5/xdisplay/st-7789/display_fb.c"]
|
||||
sources += ["embed/trezorhal/stm32u5/xdisplay/st-7789/display_driver.c"]
|
||||
sources += ["embed/trezorhal/stm32u5/xdisplay/st-7789/display_io.c"]
|
||||
sources += ["embed/trezorhal/stm32u5/xdisplay/st-7789/display_panel.c"]
|
||||
sources += [
|
||||
"embed/trezorhal/stm32u5/xdisplay/st-7789/panels/lx154a2482.c",
|
||||
]
|
||||
else:
|
||||
sources += [f"embed/trezorhal/stm32u5/displays/{display}"]
|
||||
sources += [
|
||||
"embed/trezorhal/stm32u5/displays/panels/lx154a2482.c",
|
||||
]
|
||||
sources += ["embed/trezorhal/stm32u5/xdisplay/st-7789/display_fb.c"]
|
||||
sources += ["embed/trezorhal/stm32u5/xdisplay/st-7789/display_driver.c"]
|
||||
sources += ["embed/trezorhal/stm32u5/xdisplay/st-7789/display_io.c"]
|
||||
sources += ["embed/trezorhal/stm32u5/xdisplay/st-7789/display_panel.c"]
|
||||
sources += [
|
||||
"embed/trezorhal/stm32u5/xdisplay/st-7789/panels/lx154a2482.c",
|
||||
]
|
||||
|
||||
sources += ["embed/trezorhal/stm32u5/backlight_pwm.c"]
|
||||
features_available.append("backlight")
|
||||
@ -117,10 +105,7 @@ def configure(
|
||||
|
||||
if "dma2d" in features_wanted:
|
||||
defines += ["USE_DMA2D"]
|
||||
if "new_rendering" in features_wanted:
|
||||
sources += ["embed/trezorhal/stm32u5/dma2d_bitblt.c"]
|
||||
else:
|
||||
sources += ["embed/trezorhal/stm32u5/dma2d.c"]
|
||||
sources += ["embed/trezorhal/stm32u5/dma2d_bitblt.c"]
|
||||
features_available.append("dma2d")
|
||||
|
||||
if "optiga" in features_wanted:
|
||||
|
@ -34,12 +34,9 @@ def configure(
|
||||
|
||||
if "dma2d" in features_wanted:
|
||||
features_available.append("dma2d")
|
||||
if "new_rendering" in features_wanted:
|
||||
sources += [
|
||||
"embed/trezorhal/unix/dma2d_bitblt.c",
|
||||
]
|
||||
else:
|
||||
sources += ["embed/lib/dma2d_emul.c"]
|
||||
sources += [
|
||||
"embed/trezorhal/unix/dma2d_bitblt.c",
|
||||
]
|
||||
defines += ["USE_DMA2D"]
|
||||
|
||||
if "sbu" in features_wanted:
|
||||
|
@ -15,7 +15,6 @@ def configure(
|
||||
board = "T3W1/boards/trezor_t3w1_d1.h"
|
||||
hw_model = get_hw_model_as_number("T3W1")
|
||||
hw_revision = 0
|
||||
features_available.append("disp_i8080_16bit_dw")
|
||||
|
||||
defines += ["DISPLAY_RGB565"]
|
||||
features_available.append("display_rgb565")
|
||||
@ -38,7 +37,6 @@ def configure(
|
||||
defines += [f"HW_MODEL={hw_model}"]
|
||||
defines += [f"HW_REVISION={hw_revision}"]
|
||||
|
||||
sources += ["embed/trezorhal/xdisplay_legacy.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/display_nofb.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/display_driver.c"]
|
||||
sources += ["embed/trezorhal/stm32f4/xdisplay/st-7789/display_io.c"]
|
||||
|
Loading…
Reference in New Issue
Block a user