From 7f79a9bd7fac4f984f1f4286256ac5b1576eaecc Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Thu, 9 Feb 2023 23:56:03 +0100 Subject: [PATCH] feat(core): support STM32F429 discovery board --- core/SConscript.boardloader | 7 + core/SConscript.bootloader | 17 +- core/SConscript.bootloader_ci | 6 +- core/SConscript.bootloader_emu | 4 +- core/SConscript.firmware | 45 +- core/SConscript.prodtest | 11 + core/SConscript.reflash | 11 + core/SConscript.unix | 11 + core/embed/boardloader/main.c | 7 + .../extmod/modtrezorconfig/norcow_config.h | 6 +- .../extmod/modtrezorutils/modtrezorutils.c | 3 + core/embed/firmware/bl_check.c | 2 + core/embed/firmware/memory_DISC1.ld | 1 + core/embed/firmware/startup.S | 8 +- core/embed/lib/colors.h | 3 +- core/embed/lib/fonts/fonts.h | 9 +- .../embed/trezorhal/boards/stm32f429i-disc1.h | 24 + core/embed/trezorhal/boards/trezor_t.h | 14 + core/embed/trezorhal/displays/ili9341_spi.c | 512 +++++++++++++ core/embed/trezorhal/displays/ili9341_spi.h | 13 + core/embed/trezorhal/displays/ltdc.c | 373 ++++++++++ core/embed/trezorhal/displays/ltdc.h | 15 + core/embed/trezorhal/flash.c | 6 +- core/embed/trezorhal/flash.h | 10 +- core/embed/trezorhal/i2c.c | 76 +- core/embed/trezorhal/i2c.h | 6 + core/embed/trezorhal/mpu.c | 21 + core/embed/trezorhal/sdram.c | 445 +++++++++++ core/embed/trezorhal/sdram.h | 177 +++++ core/embed/trezorhal/stm32f4xx_hal_conf.h | 3 +- core/embed/trezorhal/touch/stmpe811.c | 700 ++++++++++++++++++ core/embed/trezorhal/touch/stmpe811.h | 6 + core/embed/unix/board-unix.h | 1 + core/site_scons/boards/discovery.py | 31 + core/site_scons/tools.py | 7 +- 35 files changed, 2515 insertions(+), 76 deletions(-) create mode 120000 core/embed/firmware/memory_DISC1.ld create mode 100644 core/embed/trezorhal/boards/stm32f429i-disc1.h create mode 100644 core/embed/trezorhal/displays/ili9341_spi.c create mode 100644 core/embed/trezorhal/displays/ili9341_spi.h create mode 100644 core/embed/trezorhal/displays/ltdc.c create mode 100644 core/embed/trezorhal/displays/ltdc.h create mode 100644 core/embed/trezorhal/sdram.c create mode 100644 core/embed/trezorhal/sdram.h create mode 100644 core/embed/trezorhal/touch/stmpe811.c create mode 100644 core/embed/trezorhal/touch/stmpe811.h create mode 100644 core/site_scons/boards/discovery.py diff --git a/core/SConscript.boardloader b/core/SConscript.boardloader index 2c379a835..09d991bdb 100644 --- a/core/SConscript.boardloader +++ b/core/SConscript.boardloader @@ -67,13 +67,16 @@ SOURCE_STMHAL = [ 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c', @@ -124,6 +127,10 @@ if TREZOR_MODEL in ('T', 'R'): CPU_ASFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16' CPU_CCFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 ' CPU_MODEL = 'STM32F427xx' +elif TREZOR_MODEL in ('DISC1'): + CPU_ASFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16' + CPU_CCFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 ' + CPU_MODEL = 'STM32F429xx' else: raise ValueError('Unknown Trezor model') diff --git a/core/SConscript.bootloader b/core/SConscript.bootloader index d448bf025..5ce2f34fc 100644 --- a/core/SConscript.bootloader +++ b/core/SConscript.bootloader @@ -32,7 +32,7 @@ if TREZOR_MODEL in ('1', 'R'): FONT_DEMIBOLD=None FONT_BOLD=None FONT_MONO='Font_PixelOperatorMono_Regular_8' -if TREZOR_MODEL in ('T', ): +if TREZOR_MODEL in ('T', 'DISC1', ): FONT_NORMAL='Font_TTHoves_Regular_21' FONT_DEMIBOLD=None FONT_BOLD='Font_TTHoves_Bold_17' @@ -92,13 +92,16 @@ SOURCE_STMHAL = [ 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c', @@ -165,16 +168,16 @@ env.Replace( env.Replace( TREZOR_MODEL=TREZOR_MODEL, ) -if TREZOR_MODEL in ('T', 'R'): +if TREZOR_MODEL in ('T', 'R', ): CPU_ASFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16' CPU_CCFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 ' CPU_MODEL = 'STM32F427xx' RUST_TARGET = 'thumbv7em-none-eabihf' -elif TREZOR_MODEL in ('1',): - CPU_ASFLAGS = '-mthumb -mcpu=cortex-m3 -mfloat-abi=soft' - CPU_CCFLAGS = '-mthumb -mtune=cortex-m3 -mcpu=cortex-m3 -mfloat-abi=soft ' - CPU_MODEL = 'STM32F405xx' - RUST_TARGET = 'thumbv7m-none-eabi' +elif TREZOR_MODEL in ('DISC1', ): + CPU_ASFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16' + CPU_CCFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 ' + CPU_MODEL = 'STM32F429xx' + RUST_TARGET = 'thumbv7em-none-eabihf' else: raise ValueError('Unknown Trezor model') diff --git a/core/SConscript.bootloader_ci b/core/SConscript.bootloader_ci index 2ef33355e..8ef216812 100644 --- a/core/SConscript.bootloader_ci +++ b/core/SConscript.bootloader_ci @@ -6,13 +6,13 @@ import tools TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T') CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0)) -if TREZOR_MODEL in ('1', ): +if TREZOR_MODEL in ('1', 'DISC1', ): # skip bootloader_ci build env = Environment() def build_bootloader_ci(target,source,env): print(f'Bootloader_ci: nothing to build for Model {TREZOR_MODEL}') program_bin = env.Command( - target='bootloader_ci.bin', + target='bootloader.bin', source=None, action=build_bootloader_ci ) @@ -25,7 +25,7 @@ CPPPATH_MOD = [] CPPDEFINES_MOD = [] SOURCE_MOD = [] -if TREZOR_MODEL in ('1', 'R'): +if TREZOR_MODEL in ('1', 'R', ): FONT_NORMAL='Font_PixelOperator_Regular_8' FONT_DEMIBOLD=None FONT_BOLD=None diff --git a/core/SConscript.bootloader_emu b/core/SConscript.bootloader_emu index 1684f43ce..52b4b3e78 100644 --- a/core/SConscript.bootloader_emu +++ b/core/SConscript.bootloader_emu @@ -8,13 +8,13 @@ TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T') CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0)) DMA2D = False -if TREZOR_MODEL in ('1', ): +if TREZOR_MODEL in ('1', 'DISC1', ): # skip bootloader build env = Environment() def build_bootloader(target,source,env): print(f'Bootloader: nothing to build for Model {TREZOR_MODEL}') program_bin = env.Command( - target='bootloader.bin', + target='bootloader.elf', source=None, action=build_bootloader ) diff --git a/core/SConscript.firmware b/core/SConscript.firmware index 76658c404..dbb15c17e 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -33,7 +33,7 @@ if TREZOR_MODEL in ('1', 'R'): FONT_DEMIBOLD=None FONT_BOLD='Font_PixelOperator_Bold_8' FONT_MONO='Font_PixelOperatorMono_Regular_8' -if TREZOR_MODEL in ('T', ): +if TREZOR_MODEL in ('T', 'DISC1', ): FONT_NORMAL='Font_TTHoves_Regular_21' FONT_DEMIBOLD='Font_TTHoves_DemiBold_21' FONT_BOLD='Font_TTHoves_Bold_17' @@ -332,13 +332,16 @@ SOURCE_STMHAL = [ 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_ltdc.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pcd_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sd.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_spi.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sram.c', + 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_sdram.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c', 'vendor/micropython/lib/stm32lib/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_fmc.c', @@ -429,12 +432,18 @@ env.Replace( env.Replace( TREZOR_MODEL=TREZOR_MODEL,) -if TREZOR_MODEL in ('T', 'R'): +if TREZOR_MODEL in ('T', 'R', ): CPU_ASFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16' CPU_CCFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 ' CPU_MODEL = 'STM32F427xx' LD_VARIANT = '' RUST_TARGET = 'thumbv7em-none-eabihf' +elif TREZOR_MODEL in ('DISC1', ): + CPU_ASFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16' + CPU_CCFLAGS = '-mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mtune=cortex-m4 ' + CPU_MODEL = 'STM32F429xx' + LD_VARIANT = '' + RUST_TARGET = 'thumbv7em-none-eabihf' elif TREZOR_MODEL in ('1',): CPU_ASFLAGS = '-mthumb -mcpu=cortex-m3 -mfloat-abi=soft' CPU_CCFLAGS = '-mthumb -mtune=cortex-m3 -mcpu=cortex-m3 -mfloat-abi=soft ' @@ -570,7 +579,7 @@ if FROZEN: SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/recovery.py')) if EVERYTHING: SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/fido.py')) - if TREZOR_MODEL in ('T',): + if TREZOR_MODEL in ('T', 'DISC1', ): SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt_v2/__init__.py')) SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt_v2/homescreen.py')) SOURCE_PY.extend(Glob(SOURCE_PY_DIR + 'trezor/ui/layouts/tt_v2/reset.py')) @@ -704,7 +713,11 @@ def cargo_build(): profile = '' # T1 does not have its own Rust feature, it shares it with TR - model_feature = 'model_tr' if TREZOR_MODEL == '1' else f'model_t{TREZOR_MODEL.lower()}' + if TREZOR_MODEL in ('1', 'R', ): + model_feature = 'model_tr' + else: + model_feature = 'model_tt' + features = ['micropython', 'protobuf', model_feature] if BITCOIN_ONLY == '1': features.append('bitcoin_only') @@ -765,7 +778,6 @@ cmake_gen = env.Command( action='$MAKECMAKELISTS --sources $ALLSOURCES --dirs $CPPPATH --defs $ALLDEFS', ) - MODEL_IDENTIFIER = tools.get_model_identifier(TREZOR_MODEL) if BOOTLOADER_QA: VENDORHEADER = 'embed/vendorheader/vendorheader_qa_DO_NOT_SIGN_signed_dev.bin' @@ -785,16 +797,17 @@ obj_program.extend( ' --rename-section .data=.vendorheader,alloc,load,readonly,contents' ' $SOURCE $TARGET', )) -obj_program.extend( - env.Command( - target='embed/firmware/bootloaders/bootloader.o', - source=f'embed/firmware/bootloaders/bootloader_{BOOTLOADER_SUFFIX}.bin', - action='$OBJCOPY -I binary -O elf32-littlearm -B arm' - ' --rename-section .data=.bootloader' - f' --redefine-sym _binary_embed_firmware_bootloaders_bootloader_{BOOTLOADER_SUFFIX}_bin_start=_binary_embed_firmware_bootloader_bin_start' - f' --redefine-sym _binary_embed_firmware_bootloaders_bootloader_{BOOTLOADER_SUFFIX}_bin_end=_binary_embed_firmware_bootloader_bin_end' - f' --redefine-sym _binary_embed_firmware_bootloaders_bootloader_{BOOTLOADER_SUFFIX}_bin_size=_binary_embed_firmware_bootloader_bin_size' - ' $SOURCE $TARGET', )) +if TREZOR_MODEL not in ('DISC1', ): + obj_program.extend( + env.Command( + target='embed/firmware/bootloaders/bootloader.o', + source=f'embed/firmware/bootloaders/bootloader_{BOOTLOADER_SUFFIX}.bin', + action='$OBJCOPY -I binary -O elf32-littlearm -B arm' + ' --rename-section .data=.bootloader' + f' --redefine-sym _binary_embed_firmware_bootloaders_bootloader_{BOOTLOADER_SUFFIX}_bin_start=_binary_embed_firmware_bootloader_bin_start' + f' --redefine-sym _binary_embed_firmware_bootloaders_bootloader_{BOOTLOADER_SUFFIX}_bin_end=_binary_embed_firmware_bootloader_bin_end' + f' --redefine-sym _binary_embed_firmware_bootloaders_bootloader_{BOOTLOADER_SUFFIX}_bin_size=_binary_embed_firmware_bootloader_bin_size' + ' $SOURCE $TARGET', )) env.Depends(obj_program, qstr_generated) @@ -818,7 +831,7 @@ BINARY_NAME += "-dirty" if tools.get_git_modified() else "" BINARY_NAME += ".bin" -if TREZOR_MODEL in ('T', 'R'): +if TREZOR_MODEL in ('T', 'R', 'DISC1', ): action_bin=[ '$OBJCOPY -O binary -j .vendorheader -j .header -j .flash -j .data --pad-to 0x08100000 $SOURCE ${TARGET}.p1', '$OBJCOPY -O binary -j .flash2 $SOURCE ${TARGET}.p2', diff --git a/core/SConscript.prodtest b/core/SConscript.prodtest index efb2a4aea..dd6b0bdd4 100644 --- a/core/SConscript.prodtest +++ b/core/SConscript.prodtest @@ -6,6 +6,17 @@ import tools TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T') CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0)) +if TREZOR_MODEL in ('DISC1', ): + # skip prodtest build + env = Environment() + def build_prodtest(target,source,env): + print(f'Prodtest: nothing to build for Model {TREZOR_MODEL}') + program_bin = env.Command( + target='prodtest.bin', + source=None, + action=build_prodtest) + Return() + FEATURES_WANTED = ["input", "sbu", "sd_card", "rdb_led"] CCFLAGS_MOD = '' diff --git a/core/SConscript.reflash b/core/SConscript.reflash index e3114886d..a8d119eb3 100644 --- a/core/SConscript.reflash +++ b/core/SConscript.reflash @@ -6,6 +6,17 @@ import tools TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T') CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0)) +if TREZOR_MODEL in ('DISC1', ): + # skip reflash build + env = Environment() + def build_reflash(target,source,env): + print(f'Reflash: nothing to build for Model {TREZOR_MODEL}') + program_bin = env.Command( + target='reflash.bin', + source=None, + action=build_reflash) + Return() + FEATURES_WANTED = ["input", "sd_card"] CCFLAGS_MOD = '' diff --git a/core/SConscript.unix b/core/SConscript.unix index a6497570e..ad2bc03a9 100644 --- a/core/SConscript.unix +++ b/core/SConscript.unix @@ -10,6 +10,17 @@ TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T') DMA2D = TREZOR_MODEL in ('T', ) CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0)) +if TREZOR_MODEL in ('DISC1', ): + # skip unix build + env = Environment() + def build_unix(target,source,env): + print(f'Emulator: nothing to build for Model {TREZOR_MODEL}') + program_bin = env.Command( + target='trezor-emu-core', + source=None, + action=build_unix) + Return() + FEATURE_FLAGS = { "SECP256K1_ZKP": True, # required for trezor.crypto.curve.bip340 (BIP340/Taproot) } diff --git a/core/embed/boardloader/main.c b/core/embed/boardloader/main.c index 351a9b0bc..ad9c2e0ff 100644 --- a/core/embed/boardloader/main.c +++ b/core/embed/boardloader/main.c @@ -29,6 +29,9 @@ #ifdef USE_SD_CARD #include "sdcard.h" #endif +#ifdef USE_SDRAM +#include "sdram.h" +#endif #include "lowlevel.h" #include "version.h" @@ -215,6 +218,10 @@ int main(void) { clear_otg_hs_memory(); +#ifdef USE_SDRAM + sdram_init(); +#endif + display_init(); display_clear(); diff --git a/core/embed/extmod/modtrezorconfig/norcow_config.h b/core/embed/extmod/modtrezorconfig/norcow_config.h index 588b4fc41..af79081ca 100644 --- a/core/embed/extmod/modtrezorconfig/norcow_config.h +++ b/core/embed/extmod/modtrezorconfig/norcow_config.h @@ -25,12 +25,12 @@ #define NORCOW_HEADER_LEN 0 #define NORCOW_SECTOR_COUNT 2 -#if defined TREZOR_MODEL_T || defined TREZOR_MODEL_R +#if defined STM32F427xx || defined STM32F429xx #define NORCOW_SECTOR_SIZE (64 * 1024) -#elif defined TREZOR_MODEL_1 +#elif defined STM32F405xx #define NORCOW_SECTOR_SIZE (16 * 1024) #else -#error Unknown Trezor model +#error Unknown MCU #endif #define NORCOW_SECTORS \ diff --git a/core/embed/extmod/modtrezorutils/modtrezorutils.c b/core/embed/extmod/modtrezorutils/modtrezorutils.c index 1905cf062..113c88662 100644 --- a/core/embed/extmod/modtrezorutils/modtrezorutils.c +++ b/core/embed/extmod/modtrezorutils/modtrezorutils.c @@ -263,6 +263,9 @@ STATIC const mp_rom_map_elem_t mp_module_trezorutils_globals_table[] = { {MP_ROM_QSTR(MP_QSTR_MODEL), MP_ROM_QSTR(MP_QSTR_T)}, #elif defined TREZOR_MODEL_R {MP_ROM_QSTR(MP_QSTR_MODEL), MP_ROM_QSTR(MP_QSTR_R)}, +#elif defined TREZOR_MODEL_DISC1 + // for python, this will report as "T" for now to get same features + {MP_ROM_QSTR(MP_QSTR_MODEL), MP_ROM_QSTR(MP_QSTR_T)}, #else #error Unknown Trezor model #endif diff --git a/core/embed/firmware/bl_check.c b/core/embed/firmware/bl_check.c index aacdaf2d7..493d0fbcf 100644 --- a/core/embed/firmware/bl_check.c +++ b/core/embed/firmware/bl_check.c @@ -99,8 +99,10 @@ static secbool known_bootloader(const uint8_t *hash, int len) { #define BOOTLOADER_FF BOOTLOADER_T2B1_FF #endif #else +#if PRODUCTION || BOOTLOADER_QA #error "Cannot select bootloader hashes for unknown model." #endif +#endif // clang-format on #if PRODUCTION || BOOTLOADER_QA diff --git a/core/embed/firmware/memory_DISC1.ld b/core/embed/firmware/memory_DISC1.ld new file mode 120000 index 000000000..3f68ec99f --- /dev/null +++ b/core/embed/firmware/memory_DISC1.ld @@ -0,0 +1 @@ +memory_T.ld \ No newline at end of file diff --git a/core/embed/firmware/startup.S b/core/embed/firmware/startup.S index a82ffa5e4..7b44f5f19 100644 --- a/core/embed/firmware/startup.S +++ b/core/embed/firmware/startup.S @@ -48,10 +48,12 @@ reset_handler: // according to "ARM Cortex-M Programming Guide to Memory Barrier Instructions" Application Note 321, section 4.7: // "If it is not necessary to ensure that a pended interrupt is recognized immediately before // subsequent operations, it is not necessary to insert a memory barrier instruction." -#if defined TREZOR_MODEL_T || defined TREZOR_MODEL_R - cpsie f -#elif defined TREZOR_MODEL_1 +#if defined STM32F405xx cpsie if +#elif defined STM32F427xx || defined STM32F429xx + cpsie f +#else + #error "Unknown MCU" #endif // enter the application code diff --git a/core/embed/lib/colors.h b/core/embed/lib/colors.h index b1b639782..1451959c7 100644 --- a/core/embed/lib/colors.h +++ b/core/embed/lib/colors.h @@ -21,8 +21,9 @@ #define _COLORS_H #include "common.h" +#include TREZOR_BOARD -#ifdef TREZOR_MODEL_T +#ifdef USE_RGB_COLORS #define RGB16(R, G, B) ((R & 0xF8) << 8) | ((G & 0xFC) << 3) | ((B & 0xF8) >> 3) #endif diff --git a/core/embed/lib/fonts/fonts.h b/core/embed/lib/fonts/fonts.h index 3d73fe113..52fc21c1b 100644 --- a/core/embed/lib/fonts/fonts.h +++ b/core/embed/lib/fonts/fonts.h @@ -21,15 +21,12 @@ #define _FONTS_H #include "fonts/font_bitmap.h" +#include TREZOR_BOARD -#if defined TREZOR_MODEL_T +#ifdef USE_RGB_COLORS #define TREZOR_FONT_BPP 4 -#elif defined TREZOR_MODEL_1 -#define TREZOR_FONT_BPP 1 -#elif defined TREZOR_MODEL_R -#define TREZOR_FONT_BPP 1 #else -#error Unknown Trezor model +#define TREZOR_FONT_BPP 1 #endif #define COMPOSE(font_name, suffix) font_name##suffix diff --git a/core/embed/trezorhal/boards/stm32f429i-disc1.h b/core/embed/trezorhal/boards/stm32f429i-disc1.h new file mode 100644 index 000000000..8cdaa552b --- /dev/null +++ b/core/embed/trezorhal/boards/stm32f429i-disc1.h @@ -0,0 +1,24 @@ +#ifndef _STM32F429I_DISC1_H +#define _STM32F429I_DISC1_H + +#define USE_I2C 1 +#define USE_TOUCH 1 +#define USE_SDRAM 1 +#define USE_RGB_COLORS 1 + +#include "displays/ltdc.h" + +#define I2C_INSTANCE I2C3 +#define I2C_INSTANCE_CLK_EN __HAL_RCC_I2C3_CLK_ENABLE +#define I2C_INSTANCE_CLK_DIS __HAL_RCC_I2C3_CLK_DISABLE +#define I2C_INSTANCE_PIN_AF GPIO_AF4_I2C3 +#define I2C_INSTANCE_SDA_PORT GPIOC +#define I2C_INSTANCE_SDA_PIN GPIO_PIN_9 +#define I2C_INSTANCE_SDA_CLK_EN __HAL_RCC_GPIOC_CLK_ENABLE +#define I2C_INSTANCE_SCL_PORT GPIOA +#define I2C_INSTANCE_SCL_PIN GPIO_PIN_8 +#define I2C_INSTANCE_SCL_CLK_EN __HAL_RCC_GPIOA_CLK_ENABLE +#define I2C_INSTANCE_FORCE_RESET __HAL_RCC_I2C3_FORCE_RESET +#define I2C_INSTANCE_RELEASE_RESET __HAL_RCC_I2C3_RELEASE_RESET + +#endif //_STM32F429I_DISC1_H diff --git a/core/embed/trezorhal/boards/trezor_t.h b/core/embed/trezorhal/boards/trezor_t.h index 5853cb988..a2111853d 100644 --- a/core/embed/trezorhal/boards/trezor_t.h +++ b/core/embed/trezorhal/boards/trezor_t.h @@ -5,8 +5,22 @@ #define USE_I2C 1 #define USE_TOUCH 1 #define USE_SBU 1 +#define USE_RGB_COLORS 1 #define USE_DISP_I8080_8BIT_DW 1 +#define I2C_INSTANCE I2C1 +#define I2C_INSTANCE_CLK_EN __HAL_RCC_I2C1_CLK_ENABLE +#define I2C_INSTANCE_CLK_DIS __HAL_RCC_I2C1_CLK_DISABLE +#define I2C_INSTANCE_PIN_AF GPIO_AF4_I2C1 +#define I2C_INSTANCE_SDA_PORT GPIOB +#define I2C_INSTANCE_SDA_PIN GPIO_PIN_7 +#define I2C_INSTANCE_SDA_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE +#define I2C_INSTANCE_SCL_PORT GPIOB +#define I2C_INSTANCE_SCL_PIN GPIO_PIN_6 +#define I2C_INSTANCE_SCL_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE +#define I2C_INSTANCE_FORCE_RESET __HAL_RCC_I2C1_FORCE_RESET +#define I2C_INSTANCE_RELEASE_RESET __HAL_RCC_I2C1_RELEASE_RESET + #include "displays/st7789v.h" #endif //_TREZOR_T_H diff --git a/core/embed/trezorhal/displays/ili9341_spi.c b/core/embed/trezorhal/displays/ili9341_spi.c new file mode 100644 index 000000000..309fb3f0d --- /dev/null +++ b/core/embed/trezorhal/displays/ili9341_spi.c @@ -0,0 +1,512 @@ + + +#include +#include TREZOR_BOARD +#include "ili9341_spi.h" +#include STM32_HAL_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; /*. + */ + +#include +#include TREZOR_BOARD +#include "display_interface.h" +#include "memzero.h" +#include STM32_HAL_H + +#include "ili9341_spi.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 display_index_x = 0; +uint16_t display_index_y = 0; +uint16_t display_window_x0 = 0; +uint16_t display_window_y0 = MAX_DISPLAY_RESX - 1; +uint16_t display_window_x1 = 0; +uint16_t display_window_y1 = MAX_DISPLAY_RESY - 1; + +void display_pixeldata(uint16_t c) { + ((uint16_t *)LCD_FRAME_BUFFER)[(display_index_y * MAX_DISPLAY_RESX) + + display_index_x] = c; + + display_index_x++; + + if (display_index_x > display_window_x1) { + display_index_x = display_window_x0; + display_index_y++; + + if (display_index_y > display_window_y1) { + display_index_y = display_window_y0; + } + } +} + +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; + + /* Layer Init */ + Layercfg.WindowX0 = 0; + Layercfg.WindowX1 = MAX_DISPLAY_RESX; + Layercfg.WindowY0 = 0; + Layercfg.WindowY1 = MAX_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 = MAX_DISPLAY_RESX; + Layercfg.ImageHeight = MAX_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) { + display_window_x0 = x0; + display_window_x1 = x1; + display_window_y0 = y0; + display_window_y1 = y1; + display_index_x = x0; + display_index_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(void) { + GPIO_InitTypeDef GPIO_InitStructure; + + /* 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) {} diff --git a/core/embed/trezorhal/displays/ltdc.h b/core/embed/trezorhal/displays/ltdc.h new file mode 100644 index 000000000..63848cf1a --- /dev/null +++ b/core/embed/trezorhal/displays/ltdc.h @@ -0,0 +1,15 @@ + +#ifndef _LTDC_H +#define _LTDC_H + +#include STM32_HAL_H + +#define MAX_DISPLAY_RESX 240 +#define MAX_DISPLAY_RESY 320 +#define DISPLAY_RESX 240 +#define DISPLAY_RESY 240 +#define TREZOR_FONT_BPP 4 + +extern uint8_t *const DISPLAY_DATA_ADDRESS; + +#endif //_LTDC_H diff --git a/core/embed/trezorhal/flash.c b/core/embed/trezorhal/flash.c index 886e185d8..c85b58669 100644 --- a/core/embed/trezorhal/flash.c +++ b/core/embed/trezorhal/flash.c @@ -39,7 +39,7 @@ static const uint32_t FLASH_SECTOR_TABLE[FLASH_SECTOR_COUNT + 1] = { [9] = 0x080A0000, // - 0x080BFFFF | 128 KiB [10] = 0x080C0000, // - 0x080DFFFF | 128 KiB [11] = 0x080E0000, // - 0x080FFFFF | 128 KiB -#if defined TREZOR_MODEL_T || defined TREZOR_MODEL_R +#if defined STM32F427xx || defined STM32F429xx [12] = 0x08100000, // - 0x08103FFF | 16 KiB [13] = 0x08104000, // - 0x08107FFF | 16 KiB [14] = 0x08108000, // - 0x0810BFFF | 16 KiB @@ -53,10 +53,10 @@ static const uint32_t FLASH_SECTOR_TABLE[FLASH_SECTOR_COUNT + 1] = { [22] = 0x081C0000, // - 0x081DFFFF | 128 KiB [23] = 0x081E0000, // - 0x081FFFFF | 128 KiB [24] = 0x08200000, // last element - not a valid sector -#elif defined TREZOR_MODEL_1 +#elif defined STM32F405xx [12] = 0x08100000, // last element - not a valid sector #else -#error Unknown Trezor model +#error Unknown MCU #endif }; diff --git a/core/embed/trezorhal/flash.h b/core/embed/trezorhal/flash.h index 039409f8f..b95c568ca 100644 --- a/core/embed/trezorhal/flash.h +++ b/core/embed/trezorhal/flash.h @@ -26,9 +26,9 @@ // see docs/memory.md for more information -#if defined TREZOR_MODEL_T || defined TREZOR_MODEL_R +#if defined STM32F427xx || defined STM32F429xx #define FLASH_SECTOR_COUNT 24 -#elif defined TREZOR_MODEL_1 +#elif defined STM32F405xx #define FLASH_SECTOR_COUNT 12 #else #error Unknown Trezor model @@ -40,14 +40,14 @@ // 3 -#if defined TREZOR_MODEL_T || defined TREZOR_MODEL_R +#if defined STM32F427xx || defined STM32F429xx #define FLASH_SECTOR_STORAGE_1 4 #define FLASH_SECTOR_STORAGE_2 16 -#elif defined TREZOR_MODEL_1 +#elif defined STM32F405xx #define FLASH_SECTOR_STORAGE_1 2 #define FLASH_SECTOR_STORAGE_2 3 #else -#error Unknown Trezor model +#error Unknown MCU #endif #define FLASH_SECTOR_BOOTLOADER 5 diff --git a/core/embed/trezorhal/i2c.c b/core/embed/trezorhal/i2c.c index 68ee03dc9..daaa507cf 100644 --- a/core/embed/trezorhal/i2c.c +++ b/core/embed/trezorhal/i2c.c @@ -1,6 +1,7 @@ #include STM32_HAL_H +#include TREZOR_BOARD #include "i2c.h" #include "common.h" @@ -8,12 +9,14 @@ static I2C_HandleTypeDef i2c_handle; void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c) { // enable I2C clock - __HAL_RCC_I2C1_CLK_ENABLE(); - // GPIO have already been initialised by touch_init + I2C_INSTANCE_CLK_EN(); + I2C_INSTANCE_SCL_CLK_EN(); + I2C_INSTANCE_SDA_CLK_EN(); } void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c) { - __HAL_RCC_I2C1_CLK_DISABLE(); + // disable I2C clock + I2C_INSTANCE_CLK_DIS(); } void i2c_init(void) { @@ -21,19 +24,26 @@ void i2c_init(void) { return; } + HAL_I2C_MspInit(&i2c_handle); + GPIO_InitTypeDef GPIO_InitStructure; - // configure CTP I2C SCL and SDA GPIO lines (PB6 & PB7) + // configure CTP I2C SCL and SDA GPIO lines GPIO_InitStructure.Mode = GPIO_MODE_AF_OD; GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; // I2C is a KHz bus and low speed is still good into // the low MHz - GPIO_InitStructure.Alternate = GPIO_AF4_I2C1; - GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7; - HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); - i2c_handle.Instance = I2C1; + GPIO_InitStructure.Alternate = I2C_INSTANCE_PIN_AF; + GPIO_InitStructure.Pin = I2C_INSTANCE_SCL_PIN; + HAL_GPIO_Init(I2C_INSTANCE_SCL_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.Alternate = I2C_INSTANCE_PIN_AF; + GPIO_InitStructure.Pin = I2C_INSTANCE_SDA_PIN; + HAL_GPIO_Init(I2C_INSTANCE_SDA_PORT, &GPIO_InitStructure); + + i2c_handle.Instance = I2C_INSTANCE; i2c_handle.Init.ClockSpeed = 200000; i2c_handle.Init.DutyCycle = I2C_DUTYCYCLE_16_9; i2c_handle.Init.OwnAddress1 = 0xFE; // master @@ -56,9 +66,10 @@ void _i2c_deinit(void) { } } -void _i2c_ensure_pin(uint16_t GPIO_Pin, GPIO_PinState PinState) { - HAL_GPIO_WritePin(GPIOB, GPIO_Pin, PinState); - while (HAL_GPIO_ReadPin(GPIOB, GPIO_Pin) != PinState) +void _i2c_ensure_pin(GPIO_TypeDef *port, uint16_t GPIO_Pin, + GPIO_PinState PinState) { + HAL_GPIO_WritePin(port, GPIO_Pin, PinState); + while (HAL_GPIO_ReadPin(port, GPIO_Pin) != PinState) ; } @@ -77,37 +88,41 @@ void i2c_cycle(void) { GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7; - HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); + GPIO_InitStructure.Pin = I2C_INSTANCE_SDA_PIN; + HAL_GPIO_Init(I2C_INSTANCE_SDA_PORT, &GPIO_InitStructure); + GPIO_InitStructure.Pin = I2C_INSTANCE_SCL_PIN; + HAL_GPIO_Init(I2C_INSTANCE_SCL_PORT, &GPIO_InitStructure); HAL_Delay(50); // 3. Check SCL and SDA High level - _i2c_ensure_pin(GPIO_PIN_6, GPIO_PIN_SET); - _i2c_ensure_pin(GPIO_PIN_7, GPIO_PIN_SET); + _i2c_ensure_pin(I2C_INSTANCE_SCL_PORT, I2C_INSTANCE_SCL_PIN, GPIO_PIN_SET); + _i2c_ensure_pin(I2C_INSTANCE_SDA_PORT, I2C_INSTANCE_SDA_PIN, GPIO_PIN_SET); // 4+5. Check SDA Low level - _i2c_ensure_pin(GPIO_PIN_7, GPIO_PIN_RESET); + _i2c_ensure_pin(I2C_INSTANCE_SDA_PORT, I2C_INSTANCE_SDA_PIN, GPIO_PIN_RESET); // 6+7. Check SCL Low level - _i2c_ensure_pin(GPIO_PIN_6, GPIO_PIN_RESET); + _i2c_ensure_pin(I2C_INSTANCE_SCL_PORT, I2C_INSTANCE_SCL_PIN, GPIO_PIN_RESET); // 8+9. Check SCL High level - _i2c_ensure_pin(GPIO_PIN_6, GPIO_PIN_SET); + _i2c_ensure_pin(I2C_INSTANCE_SCL_PORT, I2C_INSTANCE_SCL_PIN, GPIO_PIN_SET); // 10+11. Check SDA High level - _i2c_ensure_pin(GPIO_PIN_7, GPIO_PIN_SET); + _i2c_ensure_pin(I2C_INSTANCE_SDA_PORT, I2C_INSTANCE_SDA_PIN, GPIO_PIN_SET); // 12. Configure SCL/SDA as Alternate function Open-Drain GPIO_InitStructure.Mode = GPIO_MODE_AF_OD; GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStructure.Alternate = GPIO_AF4_I2C1; - GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7; - HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); + GPIO_InitStructure.Alternate = I2C_INSTANCE_PIN_AF; + GPIO_InitStructure.Pin = I2C_INSTANCE_SCL_PIN; + HAL_GPIO_Init(I2C_INSTANCE_SCL_PORT, &GPIO_InitStructure); + GPIO_InitStructure.Pin = I2C_INSTANCE_SDA_PIN; + HAL_GPIO_Init(I2C_INSTANCE_SDA_PORT, &GPIO_InitStructure); HAL_Delay(50); // 13. Set SWRST bit in I2Cx_CR1 register - __HAL_RCC_I2C1_FORCE_RESET(); + I2C_INSTANCE_FORCE_RESET(); HAL_Delay(50); // 14. Clear SWRST bit in I2Cx_CR1 register - __HAL_RCC_I2C1_RELEASE_RESET(); + I2C_INSTANCE_RELEASE_RESET(); // 15. Enable the I2C peripheral i2c_init(); @@ -122,3 +137,16 @@ HAL_StatusTypeDef i2c_receive(uint8_t addr, uint8_t *data, uint16_t len, uint32_t timeout) { return HAL_I2C_Master_Receive(&i2c_handle, addr, data, len, timeout); } + +HAL_StatusTypeDef i2c_mem_write(uint8_t addr, uint16_t mem_addr, + uint16_t mem_addr_size, uint8_t *data, + uint16_t len, uint32_t timeout) { + return HAL_I2C_Mem_Write(&i2c_handle, addr, mem_addr, mem_addr_size, data, + len, timeout); +} +HAL_StatusTypeDef i2c_mem_read(uint8_t addr, uint16_t mem_addr, + uint16_t mem_addr_size, uint8_t *data, + uint16_t len, uint32_t timeout) { + return HAL_I2C_Mem_Read(&i2c_handle, addr, mem_addr, mem_addr_size, data, len, + timeout); +} diff --git a/core/embed/trezorhal/i2c.h b/core/embed/trezorhal/i2c.h index cbf6c3d84..8b4f964f2 100644 --- a/core/embed/trezorhal/i2c.h +++ b/core/embed/trezorhal/i2c.h @@ -7,3 +7,9 @@ HAL_StatusTypeDef i2c_transmit(uint8_t addr, uint8_t *data, uint16_t len, uint32_t timeout); HAL_StatusTypeDef i2c_receive(uint8_t addr, uint8_t *data, uint16_t len, uint32_t timeout); +HAL_StatusTypeDef i2c_mem_write(uint8_t addr, uint16_t mem_addr, + uint16_t mem_addr_size, uint8_t *data, + uint16_t len, uint32_t timeout); +HAL_StatusTypeDef i2c_mem_read(uint8_t addr, uint16_t mem_addr, + uint16_t mem_addr_size, uint8_t *data, + uint16_t len, uint32_t timeout); diff --git a/core/embed/trezorhal/mpu.c b/core/embed/trezorhal/mpu.c index 90376b542..61ca977c2 100644 --- a/core/embed/trezorhal/mpu.c +++ b/core/embed/trezorhal/mpu.c @@ -18,6 +18,7 @@ */ #include STM32_HAL_H +#include TREZOR_BOARD #include "stm32f4xx_ll_cortex.h" // http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/BABDJJGF.html @@ -64,6 +65,15 @@ void mpu_config_bootloader(void) { LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0); +#ifdef USE_SDRAM + // Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never) + // SDRAM (0xC0000000 - 0xDFFFFFFF, read-write, execute never) + MPU->RNR = MPU_REGION_NUMBER4; + MPU->RBAR = 0; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | + LL_MPU_REGION_SIZE_4GB | LL_MPU_REGION_FULL_ACCESS | + MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xBB); +#else // Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never) // External RAM (0x60000000 - 0x7FFFFFFF, read-write, execute never) MPU->RNR = MPU_REGION_NUMBER4; @@ -71,6 +81,7 @@ void mpu_config_bootloader(void) { MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; +#endif #if defined STM32F427xx || defined STM32F429xx // CCMRAM (0x10000000 - 0x1000FFFF, read-write, execute never) @@ -145,6 +156,15 @@ void mpu_config_firmware(void) { LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0); +#ifdef USE_SDRAM + // Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never) + // SDRAM (0xC0000000 - 0xDFFFFFFF, read-write, execute never) + MPU->RNR = MPU_REGION_NUMBER6; + MPU->RBAR = 0; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | + LL_MPU_REGION_SIZE_4GB | LL_MPU_REGION_FULL_ACCESS | + MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xBB); +#else // Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never) // External RAM (0x60000000 - 0x7FFFFFFF, read-write, execute never) MPU->RNR = MPU_REGION_NUMBER6; @@ -152,6 +172,7 @@ void mpu_config_firmware(void) { MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; +#endif #if defined STM32F427xx || defined STM32F429xx // CCMRAM (0x10000000 - 0x1000FFFF, read-write, execute never) diff --git a/core/embed/trezorhal/sdram.c b/core/embed/trezorhal/sdram.c new file mode 100644 index 000000000..3a5b0272e --- /dev/null +++ b/core/embed/trezorhal/sdram.c @@ -0,0 +1,445 @@ +/** + ****************************************************************************** + * @file stm32f429i_discovery_sdram.c + * @author MCD Application Team + * @brief This file provides a set of functions needed to drive the + * IS42S16400J SDRAM memory mounted on STM32F429I-Discovery Kit. + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "sdram.h" + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32F429I_DISCOVERY + * @{ + */ + +/** @defgroup STM32F429I_DISCOVERY_SDRAM STM32F429I DISCOVERY SDRAM + * @{ + */ + +/** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Types_Definitions STM32F429I + * DISCOVERY SDRAM Private Types Definitions + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Defines STM32F429I DISCOVERY + * SDRAM Private Defines + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Macros STM32F429I DISCOVERY + * SDRAM Private Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Variables STM32F429I DISCOVERY + * SDRAM Private Variables + * @{ + */ +static SDRAM_HandleTypeDef SdramHandle; +static FMC_SDRAM_TimingTypeDef Timing; +static FMC_SDRAM_CommandTypeDef Command; + +void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params); + +/** + * @} + */ + +/** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Function_Prototypes STM32F429I + * DISCOVERY SDRAM Private Function Prototypes + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32F429I_DISCOVERY_SDRAM_Private_Functions STM32F429I DISCOVERY + * SDRAM Private Functions + * @{ + */ + +/** + * @brief Initializes the SDRAM device. + */ +void sdram_init(void) { + static uint8_t sdramstatus = SDRAM_ERROR; + + /* SDRAM device configuration */ + SdramHandle.Instance = FMC_SDRAM_DEVICE; + + /* FMC Configuration -------------------------------------------------------*/ + /* FMC SDRAM Bank configuration */ + /* Timing configuration for 90 Mhz of SD clock frequency (180Mhz/2) */ + /* TMRD: 2 Clock cycles */ + Timing.LoadToActiveDelay = 2; + /* TXSR: min=70ns (7x11.11ns) */ + Timing.ExitSelfRefreshDelay = 7; + /* TRAS: min=42ns (4x11.11ns) max=120k (ns) */ + Timing.SelfRefreshTime = 4; + /* TRC: min=70 (7x11.11ns) */ + Timing.RowCycleDelay = 7; + /* TWR: min=1+ 7ns (1+1x11.11ns) */ + Timing.WriteRecoveryTime = 2; + /* TRP: 20ns => 2x11.11ns*/ + Timing.RPDelay = 2; + /* TRCD: 20ns => 2x11.11ns */ + Timing.RCDDelay = 2; + + /* FMC SDRAM control configuration */ + SdramHandle.Init.SDBank = FMC_SDRAM_BANK2; + /* Row addressing: [7:0] */ + SdramHandle.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8; + /* Column addressing: [11:0] */ + SdramHandle.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12; + SdramHandle.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH; + SdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4; + SdramHandle.Init.CASLatency = SDRAM_CAS_LATENCY; + SdramHandle.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE; + SdramHandle.Init.SDClockPeriod = SDCLOCK_PERIOD; + SdramHandle.Init.ReadBurst = SDRAM_READBURST; + SdramHandle.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_1; + + /* SDRAM controller initialization */ + /* __weak function can be surcharged by the application code */ + BSP_SDRAM_MspInit(&SdramHandle, (void *)NULL); + if (HAL_SDRAM_Init(&SdramHandle, &Timing) != HAL_OK) { + sdramstatus = SDRAM_ERROR; + } else { + sdramstatus = SDRAM_OK; + } + + /* SDRAM initialization sequence */ + BSP_SDRAM_Initialization_sequence(REFRESH_COUNT); + + (void)sdramstatus; +} + +/** + * @brief Programs the SDRAM device. + * @param RefreshCount: SDRAM refresh counter value + */ +void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount) { + __IO uint32_t tmpmrd = 0; + + /* Step 1: Configure a clock configuration enable command */ + Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; + Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; + Command.AutoRefreshNumber = 1; + Command.ModeRegisterDefinition = 0; + + /* Send the command */ + HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT); + + /* Step 2: Insert 100 us minimum delay */ + /* Inserted delay is equal to 1 ms due to systick time base unit (ms) */ + HAL_Delay(1); + + /* Step 3: Configure a PALL (precharge all) command */ + Command.CommandMode = FMC_SDRAM_CMD_PALL; + Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; + Command.AutoRefreshNumber = 1; + Command.ModeRegisterDefinition = 0; + + /* Send the command */ + HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT); + + /* Step 4: Configure an Auto Refresh command */ + Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; + Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; + Command.AutoRefreshNumber = 4; + Command.ModeRegisterDefinition = 0; + + /* Send the command */ + HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT); + + /* Step 5: Program the external memory mode register */ + tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 | + SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | SDRAM_MODEREG_CAS_LATENCY_3 | + SDRAM_MODEREG_OPERATING_MODE_STANDARD | + SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; + + Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE; + Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; + Command.AutoRefreshNumber = 1; + Command.ModeRegisterDefinition = tmpmrd; + + /* Send the command */ + HAL_SDRAM_SendCommand(&SdramHandle, &Command, SDRAM_TIMEOUT); + + /* Step 6: Set the refresh rate counter */ + /* Set the device refresh rate */ + HAL_SDRAM_ProgramRefreshRate(&SdramHandle, RefreshCount); +} + +/** + * @brief Reads an mount of data from the SDRAM memory in polling mode. + * @param uwStartAddress : Read start address + * @param pData : Pointer to data to be read + * @param uwDataSize: Size of read data from the memory + */ +uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t *pData, + uint32_t uwDataSize) { + if (HAL_SDRAM_Read_32b(&SdramHandle, (uint32_t *)uwStartAddress, pData, + uwDataSize) != HAL_OK) { + return SDRAM_ERROR; + } else { + return SDRAM_OK; + } +} + +/** + * @brief Reads an mount of data from the SDRAM memory in DMA mode. + * @param uwStartAddress : Read start address + * @param pData : Pointer to data to be read + * @param uwDataSize: Size of read data from the memory + */ +uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t *pData, + uint32_t uwDataSize) { + if (HAL_SDRAM_Read_DMA(&SdramHandle, (uint32_t *)uwStartAddress, pData, + uwDataSize) != HAL_OK) { + return SDRAM_ERROR; + } else { + return SDRAM_OK; + } +} + +/** + * @brief Writes an mount of data to the SDRAM memory in polling mode. + * @param uwStartAddress : Write start address + * @param pData : Pointer to data to be written + * @param uwDataSize: Size of written data from the memory + */ +uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t *pData, + uint32_t uwDataSize) { + /* Disable write protection */ + HAL_SDRAM_WriteProtection_Disable(&SdramHandle); + + /*Write 32-bit data buffer to SDRAM memory*/ + if (HAL_SDRAM_Write_32b(&SdramHandle, (uint32_t *)uwStartAddress, pData, + uwDataSize) != HAL_OK) { + return SDRAM_ERROR; + } else { + return SDRAM_OK; + } +} + +/** + * @brief Writes an mount of data to the SDRAM memory in DMA mode. + * @param uwStartAddress : Write start address + * @param pData : Pointer to data to be written + * @param uwDataSize: Size of written data from the memory + */ +uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t *pData, + uint32_t uwDataSize) { + if (HAL_SDRAM_Write_DMA(&SdramHandle, (uint32_t *)uwStartAddress, pData, + uwDataSize) != HAL_OK) { + return SDRAM_ERROR; + } else { + return SDRAM_OK; + } +} + +/** + * @brief Sends command to the SDRAM bank. + * @param SdramCmd: Pointer to SDRAM command structure + * @retval HAL status + */ +uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd) { + if (HAL_SDRAM_SendCommand(&SdramHandle, SdramCmd, SDRAM_TIMEOUT) != HAL_OK) { + return SDRAM_ERROR; + } else { + return SDRAM_OK; + } +} + +/** + * @brief Handles SDRAM DMA transfer interrupt request. + */ +void BSP_SDRAM_DMA_IRQHandler(void) { HAL_DMA_IRQHandler(SdramHandle.hdma); } + +/** + * @brief Initializes SDRAM MSP. + * @note This function can be surcharged by application code. + * @param hsdram: pointer on SDRAM handle + * @param Params: pointer on additional configuration parameters, can be NULL. + */ +void BSP_SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params) { + static DMA_HandleTypeDef dmaHandle; + GPIO_InitTypeDef GPIO_InitStructure; + + if (hsdram != (SDRAM_HandleTypeDef *)NULL) { + /* Enable FMC clock */ + __HAL_RCC_FMC_CLK_ENABLE(); + + /* Enable chosen DMAx clock */ + __DMAx_CLK_ENABLE(); + + /* Enable GPIOs clock */ + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + + /*-- GPIOs Configuration + * -----------------------------------------------------*/ + /* + +-------------------+--------------------+--------------------+--------------------+ + + SDRAM pins assignment + + +-------------------+--------------------+--------------------+--------------------+ + | PD0 <-> FMC_D2 | PE0 <-> FMC_NBL0 | PF0 <-> FMC_A0 | PG0 <-> + FMC_A10 | | PD1 <-> FMC_D3 | PE1 <-> FMC_NBL1 | PF1 <-> FMC_A1 | + PG1 <-> FMC_A11 | | PD8 <-> FMC_D13 | PE7 <-> FMC_D4 | PF2 <-> + FMC_A2 | PG8 <-> FMC_SDCLK | | PD9 <-> FMC_D14 | PE8 <-> FMC_D5 | + PF3 <-> FMC_A3 | PG15 <-> FMC_NCAS | | PD10 <-> FMC_D15 | PE9 <-> + FMC_D6 | PF4 <-> FMC_A4 |--------------------+ | PD14 <-> FMC_D0 | + PE10 <-> FMC_D7 | PF5 <-> FMC_A5 | | PD15 <-> FMC_D1 | PE11 <-> + FMC_D8 | PF11 <-> FMC_NRAS | + +-------------------| PE12 <-> FMC_D9 | PF12 <-> FMC_A6 | + | PE13 <-> FMC_D10 | PF13 <-> FMC_A7 | + | PE14 <-> FMC_D11 | PF14 <-> FMC_A8 | + | PE15 <-> FMC_D12 | PF15 <-> FMC_A9 | + +-------------------+--------------------+--------------------+ + | PB5 <-> FMC_SDCKE1| + | PB6 <-> FMC_SDNE1 | + | PC0 <-> FMC_SDNWE | + +-------------------+ + + */ + + /* Common GPIO configuration */ + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Speed = GPIO_SPEED_FAST; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Alternate = GPIO_AF12_FMC; + + /* GPIOB configuration */ + GPIO_InitStructure.Pin = GPIO_PIN_5 | GPIO_PIN_6; + HAL_GPIO_Init(GPIOB, &GPIO_InitStructure); + + /* GPIOC configuration */ + GPIO_InitStructure.Pin = GPIO_PIN_0; + HAL_GPIO_Init(GPIOC, &GPIO_InitStructure); + + /* GPIOD configuration */ + GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_8 | GPIO_PIN_9 | + GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15; + HAL_GPIO_Init(GPIOD, &GPIO_InitStructure); + + /* GPIOE configuration */ + GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_7 | GPIO_PIN_8 | + GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | + GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | + GPIO_PIN_15; + HAL_GPIO_Init(GPIOE, &GPIO_InitStructure); + + /* GPIOF configuration */ + GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | + GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_11 | + GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | + GPIO_PIN_15; + HAL_GPIO_Init(GPIOF, &GPIO_InitStructure); + + /* GPIOG configuration */ + GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | + GPIO_PIN_8 | GPIO_PIN_15; + HAL_GPIO_Init(GPIOG, &GPIO_InitStructure); + + /* Configure common DMA parameters */ + dmaHandle.Init.Channel = SDRAM_DMAx_CHANNEL; + dmaHandle.Init.Direction = DMA_MEMORY_TO_MEMORY; + dmaHandle.Init.PeriphInc = DMA_PINC_ENABLE; + dmaHandle.Init.MemInc = DMA_MINC_ENABLE; + dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; + dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; + dmaHandle.Init.Mode = DMA_NORMAL; + dmaHandle.Init.Priority = DMA_PRIORITY_HIGH; + dmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + dmaHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + dmaHandle.Init.MemBurst = DMA_MBURST_SINGLE; + dmaHandle.Init.PeriphBurst = DMA_PBURST_SINGLE; + + dmaHandle.Instance = SDRAM_DMAx_STREAM; + + /* Associate the DMA handle */ + __HAL_LINKDMA(hsdram, hdma, dmaHandle); + + /* Deinitialize the stream for new transfer */ + HAL_DMA_DeInit(&dmaHandle); + + /* Configure the DMA stream */ + HAL_DMA_Init(&dmaHandle); + + /* NVIC configuration for DMA transfer complete interrupt */ + HAL_NVIC_SetPriority(SDRAM_DMAx_IRQn, 0x0F, 0); + HAL_NVIC_EnableIRQ(SDRAM_DMAx_IRQn); + } /* of if(hsdram != (SDRAM_HandleTypeDef *)NULL) */ +} + +/** + * @brief DeInitializes SDRAM MSP. + * @note This function can be surcharged by application code. + * @param hsdram: pointer on SDRAM handle + * @param Params: pointer on additional configuration parameters, can be NULL. + */ +void BSP_SDRAM_MspDeInit(SDRAM_HandleTypeDef *hsdram, void *Params) { + static DMA_HandleTypeDef dma_handle; + + if (hsdram != (SDRAM_HandleTypeDef *)NULL) { + /* Disable NVIC configuration for DMA interrupt */ + HAL_NVIC_DisableIRQ(SDRAM_DMAx_IRQn); + + /* Deinitialize the stream for new transfer */ + dma_handle.Instance = SDRAM_DMAx_STREAM; + HAL_DMA_DeInit(&dma_handle); + + /* DeInit GPIO pins can be done in the application + (by surcharging this __weak function) */ + + /* GPIO pins clock, FMC clock and DMA clock can be shut down in the + application by surcharging this __weak function */ + + } /* of if(hsdram != (SDRAM_HandleTypeDef *)NULL) */ +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/core/embed/trezorhal/sdram.h b/core/embed/trezorhal/sdram.h new file mode 100644 index 000000000..78b4b6c0e --- /dev/null +++ b/core/embed/trezorhal/sdram.h @@ -0,0 +1,177 @@ +/** + ****************************************************************************** + * @file stm32f429i_discovery_sdram.h + * @author MCD Application Team + * @brief This file contains all the functions prototypes for the + * stm32f429i_discovery_sdram.c driver. + ****************************************************************************** + * @attention + * + * Copyright (c) 2017 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F429I_DISCOVERY_SDRAM_H +#define __STM32F429I_DISCOVERY_SDRAM_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include STM32_HAL_H + +/** @addtogroup BSP + * @{ + */ + +/** @addtogroup STM32F429I_DISCOVERY + * @{ + */ + +/** @addtogroup STM32F429I_DISCOVERY_SDRAM + * @{ + */ + +/** @defgroup STM32F429I_DISCOVERY_SDRAM_Exported_Types STM32F429I DISCOVERY + * SDRAM Exported Types + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32F429I_DISCOVERY_SDRAM_Exported_Constants STM32F429I DISCOVERY + * SDRAM Exported Constants + * @{ + */ + +/** + * @brief SDRAM status structure definition + */ +#define SDRAM_OK ((uint8_t)0x00) +#define SDRAM_ERROR ((uint8_t)0x01) + +/** + * @brief FMC SDRAM Bank address + */ +#define SDRAM_DEVICE_ADDR ((uint32_t)0xD0000000) +#define SDRAM_DEVICE_SIZE \ + ((uint32_t)0x800000) /* SDRAM device size in Bytes \ + */ + +/** + * @brief FMC SDRAM Memory Width + */ +/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_8 */ +#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16 + +/** + * @brief FMC SDRAM CAS Latency + */ +/* #define SDRAM_CAS_LATENCY FMC_SDRAM_CAS_LATENCY_2 */ +#define SDRAM_CAS_LATENCY FMC_SDRAM_CAS_LATENCY_3 + +/** + * @brief FMC SDRAM Memory clock period + */ +#define SDCLOCK_PERIOD \ + FMC_SDRAM_CLOCK_PERIOD_2 /* Default configuration used with LCD */ +/* #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_3 */ + +/** + * @brief FMC SDRAM Memory Read Burst feature + */ +#define SDRAM_READBURST \ + FMC_SDRAM_RBURST_DISABLE /* Default configuration used with LCD */ +/* #define SDRAM_READBURST FMC_SDRAM_RBURST_ENABLE */ + +/** + * @brief FMC SDRAM Bank Remap + */ +/* #define SDRAM_BANK_REMAP */ + +/* Set the refresh rate counter */ +/* (15.62 us x Freq) - 20 */ +#define REFRESH_COUNT ((uint32_t)1386) /* SDRAM refresh counter */ +#define SDRAM_TIMEOUT ((uint32_t)0xFFFF) + +/* DMA definitions for SDRAM DMA transfer */ +#define __DMAx_CLK_ENABLE __HAL_RCC_DMA2_CLK_ENABLE +#define SDRAM_DMAx_CHANNEL DMA_CHANNEL_0 +#define SDRAM_DMAx_STREAM DMA2_Stream0 +#define SDRAM_DMAx_IRQn DMA2_Stream0_IRQn +#define SDRAM_DMAx_IRQHandler DMA2_Stream0_IRQHandler + +/** + * @brief FMC SDRAM Mode definition register defines + */ +#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001) +#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002) +#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004) +#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) +#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020) +#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030) +#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000) +#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) +#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) +/** + * @} + */ + +/** @defgroup STM32F429I_DISCOVERY_SDRAM_Exported_Macro STM32F429I DISCOVERY + * SDRAM Exported Macro + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32F429I_DISCOVERY_SDRAM_Exported_Functions STM32F429I DISCOVERY + * SDRAM Exported Functions + * @{ + */ +uint8_t BSP_SDRAM_Init(void); +void BSP_SDRAM_Initialization_sequence(uint32_t RefreshCount); +uint8_t BSP_SDRAM_ReadData(uint32_t uwStartAddress, uint32_t* pData, + uint32_t uwDataSize); +uint8_t BSP_SDRAM_ReadData_DMA(uint32_t uwStartAddress, uint32_t* pData, + uint32_t uwDataSize); +uint8_t BSP_SDRAM_WriteData(uint32_t uwStartAddress, uint32_t* pData, + uint32_t uwDataSize); +uint8_t BSP_SDRAM_WriteData_DMA(uint32_t uwStartAddress, uint32_t* pData, + uint32_t uwDataSize); +uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef* SdramCmd); +void BSP_SDRAM_DMA_IRQHandler(void); + +void sdram_init(void); + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F429I_DISCOVERY_SDRAM_H */ diff --git a/core/embed/trezorhal/stm32f4xx_hal_conf.h b/core/embed/trezorhal/stm32f4xx_hal_conf.h index 7ac476503..467d575be 100644 --- a/core/embed/trezorhal/stm32f4xx_hal_conf.h +++ b/core/embed/trezorhal/stm32f4xx_hal_conf.h @@ -80,13 +80,12 @@ /* #define HAL_NOR_MODULE_ENABLED */ /* #define HAL_PCCARD_MODULE_ENABLED */ #define HAL_SRAM_MODULE_ENABLED -/* #define HAL_SDRAM_MODULE_ENABLED */ +#define HAL_SDRAM_MODULE_ENABLED /* #define HAL_HASH_MODULE_ENABLED */ #define HAL_GPIO_MODULE_ENABLED #define HAL_I2C_MODULE_ENABLED /* #define HAL_I2S_MODULE_ENABLED */ /* #define HAL_IWDG_MODULE_ENABLED */ -/* #define HAL_LTDC_MODULE_ENABLED */ #define HAL_PWR_MODULE_ENABLED #define HAL_RCC_MODULE_ENABLED #define HAL_RNG_MODULE_ENABLED diff --git a/core/embed/trezorhal/touch/stmpe811.c b/core/embed/trezorhal/touch/stmpe811.c new file mode 100644 index 000000000..836cf0699 --- /dev/null +++ b/core/embed/trezorhal/touch/stmpe811.c @@ -0,0 +1,700 @@ +/* + * 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 . + */ + +#include STM32_HAL_H + +#include + +#include "common.h" +#include "secbool.h" + +#include "i2c.h" +#include "stmpe811.h" +#include "touch.h" + +/* Chip IDs */ +#define STMPE811_ID 0x0811 + +/* Identification registers & System Control */ +#define STMPE811_REG_CHP_ID_LSB 0x00 +#define STMPE811_REG_CHP_ID_MSB 0x01 +#define STMPE811_REG_ID_VER 0x02 + +/* Global interrupt Enable bit */ +#define STMPE811_GIT_EN 0x01 + +/* IO expander functionalities */ +#define STMPE811_ADC_FCT 0x01 +#define STMPE811_TS_FCT 0x02 +#define STMPE811_IO_FCT 0x04 +#define STMPE811_TEMPSENS_FCT 0x08 + +/* Global Interrupts definitions */ +#define STMPE811_GIT_IO 0x80 /* IO interrupt */ +#define STMPE811_GIT_ADC 0x40 /* ADC interrupt */ +#define STMPE811_GIT_TEMP 0x20 /* Not implemented */ +#define STMPE811_GIT_FE 0x10 /* FIFO empty interrupt */ +#define STMPE811_GIT_FF 0x08 /* FIFO full interrupt */ +#define STMPE811_GIT_FOV 0x04 /* FIFO overflowed interrupt */ +#define STMPE811_GIT_FTH 0x02 /* FIFO above threshold interrupt */ +#define STMPE811_GIT_TOUCH 0x01 /* Touch is detected interrupt */ +#define STMPE811_ALL_GIT 0x1F /* All global interrupts */ +#define STMPE811_TS_IT \ + (STMPE811_GIT_TOUCH | STMPE811_GIT_FTH | STMPE811_GIT_FOV | \ + STMPE811_GIT_FF | STMPE811_GIT_FE) /* Touch screen interrupts */ + +/* General Control Registers */ +#define STMPE811_REG_SYS_CTRL1 0x03 +#define STMPE811_REG_SYS_CTRL2 0x04 +#define STMPE811_REG_SPI_CFG 0x08 + +/* Interrupt system Registers */ +#define STMPE811_REG_INT_CTRL 0x09 +#define STMPE811_REG_INT_EN 0x0A +#define STMPE811_REG_INT_STA 0x0B +#define STMPE811_REG_IO_INT_EN 0x0C +#define STMPE811_REG_IO_INT_STA 0x0D + +/* IO Registers */ +#define STMPE811_REG_IO_SET_PIN 0x10 +#define STMPE811_REG_IO_CLR_PIN 0x11 +#define STMPE811_REG_IO_MP_STA 0x12 +#define STMPE811_REG_IO_DIR 0x13 +#define STMPE811_REG_IO_ED 0x14 +#define STMPE811_REG_IO_RE 0x15 +#define STMPE811_REG_IO_FE 0x16 +#define STMPE811_REG_IO_AF 0x17 + +/* ADC Registers */ +#define STMPE811_REG_ADC_INT_EN 0x0E +#define STMPE811_REG_ADC_INT_STA 0x0F +#define STMPE811_REG_ADC_CTRL1 0x20 +#define STMPE811_REG_ADC_CTRL2 0x21 +#define STMPE811_REG_ADC_CAPT 0x22 +#define STMPE811_REG_ADC_DATA_CH0 0x30 +#define STMPE811_REG_ADC_DATA_CH1 0x32 +#define STMPE811_REG_ADC_DATA_CH2 0x34 +#define STMPE811_REG_ADC_DATA_CH3 0x36 +#define STMPE811_REG_ADC_DATA_CH4 0x38 +#define STMPE811_REG_ADC_DATA_CH5 0x3A +#define STMPE811_REG_ADC_DATA_CH6 0x3B +#define STMPE811_REG_ADC_DATA_CH7 0x3C + +/* Touch Screen Registers */ +#define STMPE811_REG_TSC_CTRL 0x40 +#define STMPE811_REG_TSC_CFG 0x41 +#define STMPE811_REG_WDM_TR_X 0x42 +#define STMPE811_REG_WDM_TR_Y 0x44 +#define STMPE811_REG_WDM_BL_X 0x46 +#define STMPE811_REG_WDM_BL_Y 0x48 +#define STMPE811_REG_FIFO_TH 0x4A +#define STMPE811_REG_FIFO_STA 0x4B +#define STMPE811_REG_FIFO_SIZE 0x4C +#define STMPE811_REG_TSC_DATA_X 0x4D +#define STMPE811_REG_TSC_DATA_Y 0x4F +#define STMPE811_REG_TSC_DATA_Z 0x51 +#define STMPE811_REG_TSC_DATA_XYZ 0x52 +#define STMPE811_REG_TSC_FRACT_XYZ 0x56 +#define STMPE811_REG_TSC_DATA_INC 0x57 +#define STMPE811_REG_TSC_DATA_NON_INC 0xD7 +#define STMPE811_REG_TSC_I_DRIVE 0x58 +#define STMPE811_REG_TSC_SHIELD 0x59 + +/* Touch Screen Pins definition */ +#define STMPE811_TOUCH_YD STMPE811_PIN_7 +#define STMPE811_TOUCH_XD STMPE811_PIN_6 +#define STMPE811_TOUCH_YU STMPE811_PIN_5 +#define STMPE811_TOUCH_XU STMPE811_PIN_4 +#define STMPE811_TOUCH_IO_ALL \ + (uint32_t)(STMPE811_TOUCH_YD | STMPE811_TOUCH_XD | STMPE811_TOUCH_YU | \ + STMPE811_TOUCH_XU) + +/* IO Pins definition */ +#define STMPE811_PIN_0 0x01 +#define STMPE811_PIN_1 0x02 +#define STMPE811_PIN_2 0x04 +#define STMPE811_PIN_3 0x08 +#define STMPE811_PIN_4 0x10 +#define STMPE811_PIN_5 0x20 +#define STMPE811_PIN_6 0x40 +#define STMPE811_PIN_7 0x80 +#define STMPE811_PIN_ALL 0xFF + +/* IO Pins directions */ +#define STMPE811_DIRECTION_IN 0x00 +#define STMPE811_DIRECTION_OUT 0x01 + +/* IO IT types */ +#define STMPE811_TYPE_LEVEL 0x00 +#define STMPE811_TYPE_EDGE 0x02 + +/* IO IT polarity */ +#define STMPE811_POLARITY_LOW 0x00 +#define STMPE811_POLARITY_HIGH 0x04 + +/* IO Pin IT edge modes */ +#define STMPE811_EDGE_FALLING 0x01 +#define STMPE811_EDGE_RISING 0x02 + +/* TS registers masks */ +#define STMPE811_TS_CTRL_ENABLE 0x01 +#define STMPE811_TS_CTRL_STATUS 0x80 + +#define TOUCH_ADDRESS \ + (0x38U << 1) // the HAL requires the 7-bit address to be shifted by one bit +#define TOUCH_PACKET_SIZE 7U +#define EVENT_PRESS_DOWN 0x00U +#define EVENT_CONTACT 0x80U +#define EVENT_LIFT_UP 0x40U +#define EVENT_NO_EVENT 0xC0U +#define GESTURE_NO_GESTURE 0x00U +#define X_POS_MSB (touch_data[3] & 0x0FU) +#define X_POS_LSB (touch_data[4]) +#define Y_POS_MSB (touch_data[5] & 0x0FU) +#define Y_POS_LSB (touch_data[6]) + +#define EVENT_OLD_TIMEOUT_MS 50 +#define EVENT_MISSING_TIMEOUT_MS 50 + +#define TS_I2C_ADDRESS 0x82 + +#define I2Cx_TIMEOUT_MAX \ + 0x3000 /* all registers are reinitialized + */ + IOE_Write(TS_I2C_ADDRESS, STMPE811_REG_SYS_CTRL1, 0); + + /* Wait for a delay to ensure registers erasing */ + IOE_Delay(2); +} + +void touch_init(void) { + GPIO_InitTypeDef GPIO_InitStructure; + + __HAL_RCC_GPIOA_CLK_ENABLE(); + + // PC4 capacitive touch panel module (CTPM) interrupt (INT) input + GPIO_InitStructure.Mode = GPIO_MODE_IT_RISING; + GPIO_InitStructure.Pull = GPIO_PULLUP; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStructure.Pin = GPIO_PIN_15; + HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); + __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_15); + + stmpe811_Reset(); + touch_set_mode(); + touch_sensitivity(0x06); +} + +void touch_sensitivity(uint8_t value) { + // set panel threshold (TH_GROUP) - default value is 0x12 + // uint8_t touch_panel_threshold[] = {0x80, value}; + // ensure(sectrue * + // (HAL_OK == HAL_I2C_Master_Transmit( + // &I2c_handle, TOUCH_ADDRESS, touch_panel_threshold, + // sizeof(touch_panel_threshold), 10)), + // NULL); +} + +uint32_t touch_is_detected(void) { + uint8_t state = ((IOE_Read(TS_I2C_ADDRESS, STMPE811_REG_TSC_CTRL) & + (uint8_t)STMPE811_TS_CTRL_STATUS) == (uint8_t)0x80); + return state > 0; +} + +uint32_t touch_active(void) { + // check the interrupt line coming in from the CTPM. + // the line make a short pulse, which sets an interrupt flag when new data is + // available. + // Reference section 1.2 of "Application Note for FT6x06 CTPM". we + // configure the touch controller to use "interrupt trigger mode". + + // uint32_t event = __HAL_GPIO_EXTI_GET_FLAG(GPIO_PIN_15); + // if (event != 0) { + // __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_15); + // } + + uint8_t state; + uint8_t ret = 0; + + state = ((IOE_Read(TS_I2C_ADDRESS, STMPE811_REG_TSC_CTRL) & + (uint8_t)STMPE811_TS_CTRL_STATUS) == (uint8_t)0x80); + + if (state > 0) { + if (IOE_Read(TS_I2C_ADDRESS, STMPE811_REG_FIFO_SIZE) > 0) { + ret = 1; + } + } else { + /* Reset FIFO */ + IOE_Write(TS_I2C_ADDRESS, STMPE811_REG_FIFO_STA, 0x01); + /* Enable the FIFO again */ + IOE_Write(TS_I2C_ADDRESS, STMPE811_REG_FIFO_STA, 0x00); + } + + return ret; +} + +uint32_t check_timeout(uint32_t prev, uint32_t timeout) { + uint32_t current = hal_ticks_ms(); + uint32_t diff = current - prev; + + if (diff >= timeout) { + return 1; + } + + return 0; +} + +/** + * @brief Get the touch screen X and Y positions values + * @param DeviceAddr: Device address on communication Bus. + * @param X: Pointer to X position value + * @param Y: Pointer to Y position value + * @retval None. + */ +void stmpe811_TS_GetXY(uint16_t *X, uint16_t *Y) { + uint8_t dataXYZ[4]; + uint32_t uldataXYZ; + + IOE_ReadMultiple(TS_I2C_ADDRESS, STMPE811_REG_TSC_DATA_NON_INC, dataXYZ, + sizeof(dataXYZ)); + + /* Calculate positions values */ + uldataXYZ = (dataXYZ[0] << 24) | (dataXYZ[1] << 16) | (dataXYZ[2] << 8) | + (dataXYZ[3] << 0); + *X = (uldataXYZ >> 20) & 0x00000FFF; + *Y = (uldataXYZ >> 8) & 0x00000FFF; + + /* Reset FIFO */ + IOE_Write(TS_I2C_ADDRESS, STMPE811_REG_FIFO_STA, 0x01); + /* Enable the FIFO again */ + IOE_Write(TS_I2C_ADDRESS, STMPE811_REG_FIFO_STA, 0x00); +} + +typedef struct { + uint16_t TouchDetected; + uint16_t X; + uint16_t Y; + uint16_t Z; +} TS_StateTypeDef; + +/** + * @brief Returns status and positions of the touch screen. + * @param TsState: Pointer to touch screen current state structure + */ +void BSP_TS_GetState(TS_StateTypeDef *TsState) { + static uint32_t _x = 0, _y = 0; + uint16_t xDiff, yDiff, x, y, xr, yr; + + TsState->TouchDetected = touch_active(); + + if (TsState->TouchDetected) { + stmpe811_TS_GetXY(&x, &y); + + /* Y value first correction */ + y -= 360; + + /* Y value second correction */ + yr = y / 11; + + /* Return y position value */ + if (yr <= 0) { + yr = 0; + } else if (yr > 320) { + yr = 320 - 1; + } else { + yr = 320 - yr; + } + y = yr; + + /* X value first correction */ + if (x <= 3000) { + x = 3870 - x; + } else { + x = 3800 - x; + } + + /* X value second correction */ + xr = x / 15; + + /* Return X position value */ + if (xr <= 0) { + xr = 0; + } else if (xr > 240) { + xr = 240 - 1; + } else { + } + + x = xr; + xDiff = x > _x ? (x - _x) : (_x - x); + yDiff = y > _y ? (y - _y) : (_y - y); + + if (xDiff + yDiff > 5) { + _x = x; + _y = y; + } + + /* Update the X position */ + TsState->X = _x; + + /* Update the Y position */ + TsState->Y = _y; + } +} + +uint32_t touch_read(void) { + TS_StateTypeDef state = {0}; + static uint32_t xy = 0; + static TS_StateTypeDef state_last = {0}; + // static uint16_t first = 1; + static uint16_t touching = 0; + + if (!touch_is_detected()) { + if (touching) { + // touch end + memcpy(&state_last, &state, sizeof(state)); + touching = 0; + return TOUCH_END | xy; + } + return 0; + } + + BSP_TS_GetState(&state); + + if (state.TouchDetected == 0) { + return 0; + } + + // if (first != 0) { + // memcpy(&state_last, &state, sizeof(state)); + // first = 0; + // return 0; + // } + + if ((state.TouchDetected == 0 && state_last.TouchDetected == 0) || + memcmp(&state, &state_last, sizeof(state)) == 0) { + // no change detected + return 0; + } + + xy = touch_pack_xy(state.X, state.Y); + + if (state.TouchDetected && !state_last.TouchDetected) { + // touch start + memcpy(&state_last, &state, sizeof(state)); + touching = 1; + return TOUCH_START | xy; + } else if (!state.TouchDetected && state_last.TouchDetected) { + // touch end + memcpy(&state_last, &state, sizeof(state)); + touching = 0; + return TOUCH_END | xy; + } else { + // touch move + memcpy(&state_last, &state, sizeof(state)); + return TOUCH_MOVE | xy; + } + + return 0; +} diff --git a/core/embed/trezorhal/touch/stmpe811.h b/core/embed/trezorhal/touch/stmpe811.h new file mode 100644 index 000000000..bc3539045 --- /dev/null +++ b/core/embed/trezorhal/touch/stmpe811.h @@ -0,0 +1,6 @@ + + +#ifndef _STMPE811_H +#define _STMPE811_H + +#endif //_STMPE811_H diff --git a/core/embed/unix/board-unix.h b/core/embed/unix/board-unix.h index 32fd61a7e..8251a5ea0 100644 --- a/core/embed/unix/board-unix.h +++ b/core/embed/unix/board-unix.h @@ -5,6 +5,7 @@ #define USE_TOUCH 1 #define USE_SD_CARD 1 #define USE_SBU 1 +#define USE_RGB_COLORS 1 #endif #ifdef TREZOR_MODEL_1 diff --git a/core/site_scons/boards/discovery.py b/core/site_scons/boards/discovery.py new file mode 100644 index 000000000..80f5728b1 --- /dev/null +++ b/core/site_scons/boards/discovery.py @@ -0,0 +1,31 @@ +from . import get_hw_model_as_number + + +def configure(env, features_wanted, defines, sources): + features_available = [] + board = 'stm32f429i-disc1.h' + display = 'ltdc.c' + hw_model = get_hw_model_as_number('TDT1') + hw_revision = 0 + + defines += [f'TREZOR_BOARD=\\"boards/{board}\\"', ] + defines += [f'HW_MODEL={hw_model}', ] + defines += [f'HW_REVISION={hw_revision}', ] + sources += [f'embed/trezorhal/displays/{display}', ] + sources += ['embed/trezorhal/displays/ili9341_spi.c'] + sources += ['embed/trezorhal/sdram.c'] + + if "input" in features_wanted: + sources += ['embed/trezorhal/i2c.c', ] + sources += ['embed/trezorhal/touch/touch.c', ] + sources += ['embed/trezorhal/touch/stmpe811.c', ] + features_available.append("touch") + + if "dma2d" in features_wanted: + defines += ["USE_DMA2D", ] + sources += ['embed/lib/dma2d_emul.c', ] + features_available.append("dma2d") + + env.get('ENV')['TREZOR_BOARD'] = board + + return features_available diff --git a/core/site_scons/tools.py b/core/site_scons/tools.py index 09d8d2d96..d59973093 100644 --- a/core/site_scons/tools.py +++ b/core/site_scons/tools.py @@ -1,7 +1,7 @@ from pathlib import Path import subprocess -from boards import trezor_1, trezor_r_v3, trezor_r_v4, trezor_t +from boards import trezor_1, trezor_r_v3, trezor_r_v4, trezor_t, discovery HERE = Path(__file__).parent.resolve() @@ -32,10 +32,13 @@ def configure_board(model, features_wanted, env, defines, sources): return trezor_r_v3.configure(env, features_wanted, defines, sources) else: return trezor_r_v4.configure(env, features_wanted, defines, sources) + elif model in ('DISC1',): + return discovery.configure(env, features_wanted, defines, sources) else: raise Exception("Unknown model") + def get_model_identifier(model): if model == '1': return "T1B1" @@ -43,6 +46,8 @@ def get_model_identifier(model): return "T2T1" elif model == 'R': return "T2B1" + elif model == 'DISC1': + return "D001" else: raise Exception("Unknown model")