diff --git a/bootloader/Makefile.bootloader b/bootloader/Makefile.bootloader new file mode 100644 index 0000000000..ed1c976f5c --- /dev/null +++ b/bootloader/Makefile.bootloader @@ -0,0 +1,253 @@ +# Select the board to build for: if not given on the command line, +# then default to TREZORV2. +BOARD ?= TREZORV2 +ifeq ($(wildcard boards/$(BOARD)/.),) +$(error Invalid BOARD specified) +endif + +# If the build directory is not given, make it reflect the board name. +BUILD ?= build-$(BOARD) + +include ../py/mkenv.mk +-include mpconfigport.mk +include boards/$(BOARD)/mpconfigboard.mk + +# qstr definitions (must come before including py.mk) +QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h $(BUILD)/modstm_qstr.h + +# include py core make definitions +include ../py/py.mk + +CMSIS_DIR=cmsis +HAL_DIR=hal/$(MCU_SERIES) +USBDEV_DIR=usbdev +#USBHOST_DIR=usbhost +FATFS_DIR=lib/fatfs +DFU=../tools/dfu.py +# may need to prefix dfu-util with sudo +USE_PYDFU ?= 1 +PYDFU ?= ../tools/pydfu.py +DFU_UTIL ?= dfu-util +DEVICE=0483:df11 +STFLASH ?= st-flash +OPENOCD ?= openocd +OPENOCD_CONFIG ?= boards/openocd_stm32f4.cfg + +CROSS_COMPILE = arm-none-eabi- + +INC += -I. +INC += -I.. +INC += -I$(BUILD) +INC += -I$(CMSIS_DIR)/inc +INC += -I$(CMSIS_DIR)/devinc +INC += -I$(HAL_DIR)/inc +INC += -I$(USBDEV_DIR)/core/inc -I$(USBDEV_DIR)/class/inc +#INC += -I$(USBHOST_DIR) +INC += -I../extmod/modtrezorui + +CFLAGS_CORTEX_M = -mthumb -mabi=aapcs-linux -mfpu=fpv4-sp-d16 -mfloat-abi=hard -fsingle-precision-constant -Wdouble-promotion +CFLAGS_MCU_f4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4 -DMCU_SERIES_F4 +CFLAGS_MCU_f7 = $(CFLAGS_CORTEX_M) -mtune=cortex-m7 -mcpu=cortex-m7 -DMCU_SERIES_F7 +CFLAGS_MCU_l4 = $(CFLAGS_CORTEX_M) -mtune=cortex-m4 -mcpu=cortex-m4 -DMCU_SERIES_L4 + +CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -ansi -std=gnu99 -nostdlib $(CFLAGS_MOD) +CFLAGS += -D$(CMSIS_MCU) +CFLAGS += $(CFLAGS_MCU_$(MCU_SERIES)) +CFLAGS += $(COPT) +CFLAGS += -Iboards/$(BOARD) +CFLAGS += -DSTM32_HAL_H='' + +LDFLAGS = -nostdlib -T $(LD_FILE) -Map=$(@:.elf=.map) --cref +LIBS = + +# Remove uncalled code from the final image. +CFLAGS += -fdata-sections -ffunction-sections +LDFLAGS += --gc-sections + +# Debugging/Optimization +ifeq ($(DEBUG), 1) +CFLAGS += -g -DPENDSV_DEBUG +COPT = -O0 +else +COPT += -Os -DNDEBUG +endif + +# uncomment this if you want libgcc +LIBS += $(shell $(CC) -print-libgcc-file-name) + +SRC_C = \ + bootloader.c \ + system_stm32.c \ + $(wildcard boards/$(BOARD)/*.c) + +SRC_O = \ + startup_stm32.o \ + +SRC_HAL = $(addprefix $(HAL_DIR)/src/stm32$(MCU_SERIES)xx_,\ + hal.c \ + hal_adc.c \ + hal_adc_ex.c \ + hal_can.c \ + hal_cortex.c \ + hal_dac.c \ + hal_dac_ex.c \ + hal_dma.c \ + hal_flash.c \ + hal_flash_ex.c \ + hal_gpio.c \ + hal_i2c.c \ + hal_pcd.c \ + hal_pcd_ex.c \ + hal_pwr.c \ + hal_pwr_ex.c \ + hal_rcc.c \ + hal_rcc_ex.c \ + hal_rng.c \ + hal_rtc.c \ + hal_rtc_ex.c \ + hal_sd.c \ + hal_spi.c \ + hal_sram.c \ + hal_tim.c \ + hal_tim_ex.c \ + hal_uart.c \ + ll_fsmc.c \ + ll_sdmmc.c \ + ll_usb.c \ + ) + +SRC_USBDEV = $(addprefix $(USBDEV_DIR)/,\ + core/src/usbd_core.c \ + core/src/usbd_ctlreq.c \ + core/src/usbd_ioreq.c \ + class/src/usbd_cdc_msc_hid.c \ + class/src/usbd_msc_bot.c \ + class/src/usbd_msc_scsi.c \ + class/src/usbd_msc_data.c \ + ) + +SRC_MODUI = $(addprefix extmod/modtrezorui/,\ + display.c \ + font_robotomono_regular.c \ + ) + +OBJ = +OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_O)) +OBJ += $(addprefix $(BUILD)/, $(SRC_HAL:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_USBDEV:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_MODUI:.c=.o)) +OBJ += $(BUILD)/pins_$(BOARD).o + +# We put ff.o and stm32f4xx_hal_sd.o into the first 16K section with the ISRs. +# If we compile these using -O0 then it won't fit. So if you really want these +# to be compiled with -O0, then edit stm32f405.ld (in the .isr_vector section) +# and comment out the following 2 lines. +$(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os +$(BUILD)/$(HAL_DIR)/src/stm32$(MCU_SERIES)xx_hal_sd.o: COPT += -Os + +all: $(BUILD)/bootloader.dfu $(BUILD)/bootloader.hex + +.PHONY: deploy + +deploy: $(BUILD)/bootloader.dfu + $(ECHO) "Writing $< to the board" +ifeq ($(USE_PYDFU),1) + $(Q)$(PYTHON) $(PYDFU) -u $< +else + $(Q)$(DFU_UTIL) -a 0 -d $(DEVICE) -D $< +endif + +deploy-stlink: $(BUILD)/bootloader.dfu + $(ECHO) "Writing $(BUILD)/bootloader0.bin to the board via ST-LINK" + $(Q)$(STFLASH) write $(BUILD)/bootloader0.bin 0x08000000 + $(ECHO) "Writing $(BUILD)/bootloader1.bin to the board via ST-LINK" + $(Q)$(STFLASH) --reset write $(BUILD)/bootloader1.bin 0x08020000 + +deploy-openocd: $(BUILD)/bootloader.dfu + $(ECHO) "Writing $(BUILD)/bootloader{0,1}.bin to the board via ST-LINK using OpenOCD" + $(Q)$(OPENOCD) -f $(OPENOCD_CONFIG) -c "stm_flash $(BUILD)/bootloader0.bin $(BUILD)/bootloader1.bin" + +$(BUILD)/bootloader.dfu: $(BUILD)/bootloader.elf + $(ECHO) "Create $@" + $(Q)$(OBJCOPY) -O binary -j .isr_vector $^ $(BUILD)/bootloader0.bin + $(Q)$(OBJCOPY) -O binary -j .text -j .data $^ $(BUILD)/bootloader1.bin + $(Q)$(PYTHON) $(DFU) -b 0x08000000:$(BUILD)/bootloader0.bin -b 0x08020000:$(BUILD)/bootloader1.bin $@ + +$(BUILD)/bootloader.hex: $(BUILD)/bootloader.elf + $(ECHO) "Create $@" + $(Q)$(OBJCOPY) -O ihex $< $@ + +$(BUILD)/bootloader.elf: $(OBJ) + $(ECHO) "LINK $@" + $(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS) + $(Q)$(SIZE) $@ + +MAKE_PINS = boards/make-pins.py +BOARD_PINS = boards/$(BOARD)/pins.csv +PREFIX_FILE = boards/stm32f4xx_prefix.c +GEN_PINS_SRC = $(BUILD)/pins_$(BOARD).c +GEN_PINS_HDR = $(HEADER_BUILD)/pins.h +GEN_PINS_QSTR = $(BUILD)/pins_qstr.h +GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins_af_const.h +GEN_PINS_AF_PY = $(BUILD)/pins_af.py + +INSERT_USB_IDS = ../tools/insert-usb-ids.py +FILE2H = ../tools/file2h.py + +USB_IDS_FILE = usb.h +CDCINF_TEMPLATE = pybcdc.inf_template +GEN_CDCINF_FILE = $(HEADER_BUILD)/pybcdc.inf +GEN_CDCINF_HEADER = $(HEADER_BUILD)/pybcdc_inf.h + +# List of sources for qstr extraction +SRC_QSTR += $(SRC_C) +# Append any auto-generated sources that are needed by sources listed in +# SRC_QSTR +SRC_QSTR_AUTO_DEPS += $(GEN_CDCINF_HEADER) + +# Making OBJ use an order-only depenedency on the generated pins.h file +# has the side effect of making the pins.h file before we actually compile +# any of the objects. The normal dependency generation will deal with the +# case when pins.h is modified. But when it doesn't exist, we don't know +# which source files might need it. +$(OBJ): | $(HEADER_BUILD)/pins.h + +# With conditional pins, we may need to regenerate qstrdefs.h when config +# options change. +$(HEADER_BUILD)/qstrdefs.generated.h: boards/$(BOARD)/mpconfigboard.h + +# main.c can't be even preprocessed without $(GEN_CDCINF_HEADER) +main.c: $(GEN_CDCINF_HEADER) + +# Use a pattern rule here so that make will only call make-pins.py once to make +# both pins_$(BOARD).c and pins.h +$(BUILD)/%_$(BOARD).c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%_af_const.h $(BUILD)/%_qstr.h: boards/$(BOARD)/%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD) + $(ECHO) "Create $@" + $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) --qstr $(GEN_PINS_QSTR) --af-const $(GEN_PINS_AF_CONST) --af-py $(GEN_PINS_AF_PY) > $(GEN_PINS_SRC) + +$(BUILD)/pins_$(BOARD).o: $(BUILD)/pins_$(BOARD).c + $(call compile_c) + +GEN_STMCONST_HDR = $(HEADER_BUILD)/modstm_const.h +GEN_STMCONST_QSTR = $(BUILD)/modstm_qstr.h +GEN_STMCONST_MPZ = $(HEADER_BUILD)/modstm_mpz.h +CMSIS_MCU_LOWER = $(shell echo $(CMSIS_MCU) | tr '[:upper:]' '[:lower:]') +CMSIS_MCU_HDR = cmsis/devinc/$(CMSIS_MCU_LOWER).h + +$(BUILD)/modstm.o: $(GEN_STMCONST_HDR) +# Use a pattern rule here so that make will only call make-stmconst.py once to +# make both modstm_const.h and modstm_qstr.h +$(HEADER_BUILD)/%_const.h $(BUILD)/%_qstr.h: $(CMSIS_MCU_HDR) make-stmconst.py | $(HEADER_BUILD) + $(ECHO) "Create stmconst $@" + $(Q)$(PYTHON) make-stmconst.py --qstr $(GEN_STMCONST_QSTR) --mpz $(GEN_STMCONST_MPZ) $(CMSIS_MCU_HDR) > $(GEN_STMCONST_HDR) + +$(GEN_CDCINF_HEADER): $(GEN_CDCINF_FILE) $(FILE2H) | $(HEADER_BUILD) + $(ECHO) "Create $@" + $(Q)$(PYTHON) $(FILE2H) $< > $@ + +$(GEN_CDCINF_FILE): $(CDCINF_TEMPLATE) $(INSERT_USB_IDS) $(USB_IDS_FILE) | $(HEADER_BUILD) + $(ECHO) "Create $@" + $(Q)$(PYTHON) $(INSERT_USB_IDS) $(USB_IDS_FILE) $< > $@ + +include ../py/mkrules.mk diff --git a/bootloader/bootloader.c b/bootloader/bootloader.c new file mode 100644 index 0000000000..03a01e2263 --- /dev/null +++ b/bootloader/bootloader.c @@ -0,0 +1,75 @@ +#include STM32_HAL_H + +#include "display.h" + +// ### from main.c + +void flash_error(int n) { + for (int i = 0; i < n; i++) { + // blink(on) + HAL_Delay(250); + // blink(off) + HAL_Delay(250); + } +} + +void __attribute__((noreturn)) __fatal_error(const char *msg) { + for (volatile uint32_t delay = 0; delay < 10000000; delay++) { + } + // TODO: printf("FATAL ERROR: %s\n", msg); + for (;;) { + __WFI(); + } +} + +void nlr_jump_fail(void *val) { + __fatal_error("FATAL: uncaught exception"); +} + +void SystemClock_Config(void); + +// ### + +// ### from timer.c + +uint32_t timer_get_source_freq(uint32_t tim_id) { + uint32_t source; + if (tim_id == 1 || (8 <= tim_id && tim_id <= 11)) { + // TIM{1,8,9,10,11} are on APB2 + source = HAL_RCC_GetPCLK2Freq(); + if ((uint32_t)((RCC->CFGR & RCC_CFGR_PPRE2) >> 3) != RCC_HCLK_DIV1) { + source *= 2; + } + } else { + // TIM{2,3,4,5,6,7,12,13,14} are on APB1 + source = HAL_RCC_GetPCLK1Freq(); + if ((uint32_t)(RCC->CFGR & RCC_CFGR_PPRE1) != RCC_HCLK_DIV1) { + source *= 2; + } + } + return source; +} + +// ### + +int main(void) { + + HAL_Init(); + + SystemClock_Config(); + + __GPIOA_CLK_ENABLE(); + __GPIOB_CLK_ENABLE(); + __GPIOC_CLK_ENABLE(); + __GPIOD_CLK_ENABLE(); + + + display_init(); + display_bar(0, 0, RESX, RESY, 0x0000); + display_text(0, 0, "TREZOR", 6, 0, 0xFFFF, 0x0000); + display_backlight(255); + + __fatal_error("end"); + + return 0; +} diff --git a/extmod/modtrezorui/display.c b/extmod/modtrezorui/display.c index 09026a5e0b..9562f95204 100644 --- a/extmod/modtrezorui/display.c +++ b/extmod/modtrezorui/display.c @@ -182,7 +182,7 @@ static const uint8_t *get_glyph(uint8_t font, uint8_t c) // first two bytes are width and height of the glyph // third, fourth and fifth bytes are advance, bearingX and bearingY of the horizontal metrics of the glyph // rest is packed 4-bit glyph data -void display_text(uint8_t x, uint8_t y, const uint8_t *text, int textlen, uint8_t font, uint16_t fgcolor, uint16_t bgcolor) +void display_text(uint8_t x, uint8_t y, const char *text, int textlen, uint8_t font, uint16_t fgcolor, uint16_t bgcolor) { uint32_t px = x; uint16_t colortable[16]; @@ -190,7 +190,7 @@ void display_text(uint8_t x, uint8_t y, const uint8_t *text, int textlen, uint8_ // render glyphs for (int i = 0; i < textlen; i++) { - const uint8_t *g = get_glyph(font, text[i]); + const uint8_t *g = get_glyph(font, (uint8_t)text[i]); if (!g) continue; // g[0], g[1] = width, height // g[2] = advance diff --git a/extmod/modtrezorui/display.h b/extmod/modtrezorui/display.h index f47e528945..591b1c9075 100644 --- a/extmod/modtrezorui/display.h +++ b/extmod/modtrezorui/display.h @@ -23,7 +23,7 @@ void display_bar_radius(uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint16_t c, void display_blit(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const void *data, int datalen); void display_image(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const void *data, int datalen); void display_icon(uint8_t x, uint8_t y, uint8_t w, uint8_t h, const void *data, int datalen, uint16_t fgcolor, uint16_t bgcolor); -void display_text(uint8_t x, uint8_t y, const uint8_t *text, int textlen, uint8_t font, uint16_t fgcolor, uint16_t bgcolor); +void display_text(uint8_t x, uint8_t y, const char *text, int textlen, uint8_t font, uint16_t fgcolor, uint16_t bgcolor); uint32_t display_text_width(const uint8_t *text, int textlen, uint8_t font); void display_qrcode(uint8_t x, uint8_t y, const char *data, int datalen, int scale); void display_loader(uint16_t progress, uint16_t fgcolor, uint16_t bgcolor, const uint8_t *icon, uint32_t iconlen, uint16_t iconfgcolor); diff --git a/vendor/micropython b/vendor/micropython index 861b0136cd..d18807370a 160000 --- a/vendor/micropython +++ b/vendor/micropython @@ -1 +1 @@ -Subproject commit 861b0136cd68b3fe4431010588cabee96b016d41 +Subproject commit d18807370a82d78410b7f80c2f1f7880f410dd68