diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..045faef --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "firmware/libopencm3"] + path = firmware/libopencm3 + url = https://github.com/libopencm3/libopencm3 +[submodule "libopencm3"] + path = libopencm3 + url = https://github.com/libopencm3/libopencm3/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7371f46 --- /dev/null +++ b/Makefile @@ -0,0 +1,57 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +BINARY = monerujo + + +############################################################################### +# Source files (modify here after adding new .c files into src folder) + +OBJS += src/bitmaps.o +OBJS += src/button.o +OBJS += src/crypto.o +OBJS += src/display.o +OBJS += src/fonts.o +OBJS += src/logo.o +OBJS += src/main.o +OBJS += src/setup.o +OBJS += src/timer.o +OBJS += src/usb.o +OBJS += src/util.o +OBJS += src/crypto/curve25519-donna-32bit.o +OBJS += src/crypto/curve25519-donna-helpers.o +OBJS += src/crypto/curve25519-donna-scalarmult-base.o +OBJS += src/crypto/ed25519.o +OBJS += src/crypto/ed25519-donna-32bit-tables.o +OBJS += src/crypto/ed25519-donna-basepoint-table.o +OBJS += src/crypto/ed25519-donna-impl-base.o +OBJS += src/crypto/ed25519-keccak.o +OBJS += src/crypto/ed25519-sha3.o +OBJS += src/crypto/modm-donna-32bit.o +OBJS += src/crypto/sha2.o +OBJS += src/crypto/sha3.o +OBJS += src/mnemonics/mnemonics.o +OBJS += src/qrcode/qrcode.o +OBJS += src/qrcode/qrcodegen.o +#OBJS += src/newCfileHere. + +OPENCM3_DIR=libopencm3 +LDSCRIPT = monerujo.ld + +include libopencm3.target.mk diff --git a/README.md b/README.md index 651c74e..2ac706a 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Monerujo Firmware for [The Sekura Monero Hardware Wallet](https://github.com/mon ## udev Rules ``` SUBSYSTEM=="usb", ATTR{idVendor}=="0483", ATTR{idProduct}=="df11", MODE="660", GROUP="plugdev" -SUBSYSTEM=="usb", ATTR{idVendor}=="f055", ATTR{idProduct}=="c0da", MODE="660", GROUP="plugdev", ENV{ID_MM_DEVICE_IGNORE}="1" +SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="c0da", MODE="660", GROUP="plugdev", ENV{ID_MM_DEVICE_IGNORE}="1" ``` ## Programming diff --git a/include/display.h b/include/display.h index 5a0cea8..acbcdbb 100644 --- a/include/display.h +++ b/include/display.h @@ -32,6 +32,8 @@ #define OLED_BUFSIZE (OLED_WIDTH * OLED_HEIGHT / 8) #define OLED_CONTRAST_DEFAULT (0x7f) +#define OLED_CONTRAST_GOOD (0xcf) +#define OLED_CONTRAST_MAX (0xff) #define OLED_CHAR_SPACE 1 diff --git a/libopencm3 b/libopencm3 new file mode 160000 index 0000000..f6517f7 --- /dev/null +++ b/libopencm3 @@ -0,0 +1 @@ +Subproject commit f6517f7816206f9d4509a21242f330aa59360119 diff --git a/libopencm3.rules.mk b/libopencm3.rules.mk new file mode 100644 index 0000000..f349da6 --- /dev/null +++ b/libopencm3.rules.mk @@ -0,0 +1,276 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2010 Piotr Esden-Tempski +## Copyright (C) 2013 Frantisek Burian +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +# Be silent per default, but 'make V=1' will show all compiler calls. +ifneq ($(V),1) +Q := @ +NULL := 2>/dev/null +endif + +############################################################################### +# Executables + +PREFIX ?= arm-none-eabi + +CC := $(PREFIX)-gcc +CXX := $(PREFIX)-g++ +LD := $(PREFIX)-gcc +AR := $(PREFIX)-ar +AS := $(PREFIX)-as +OBJCOPY := $(PREFIX)-objcopy +OBJDUMP := $(PREFIX)-objdump +GDB := $(PREFIX)-gdb +STFLASH = $(shell which st-flash) +DFUUTIL = $(shell which dfu-util) +STYLECHECK := /checkpatch.pl +STYLECHECKFLAGS := --no-tree -f --terse --mailback +STYLECHECKFILES := $(shell find . -name '*.[ch]') +OPT := -Os +CSTD ?= -std=c99 + +############################################################################### + +ifeq ($(strip $(OPENCM3_DIR)),) +# user has not specified the library path, so we try to detect it + +# where we search for the library +LIBPATHS := ./libopencm3 + +OPENCM3_DIR := $(wildcard $(LIBPATHS:=/locm3.sublime-project)) +OPENCM3_DIR := $(firstword $(dir $(OPENCM3_DIR))) + +ifeq ($(strip $(OPENCM3_DIR)),) +$(warning Cannot find libopencm3 library in the standard search paths.) +$(error Please specify it through OPENCM3_DIR variable!) +endif +endif + +ifeq ($(V),1) +$(info Using $(OPENCM3_DIR) path to library) +endif + +define ERR_DEVICE_LDSCRIPT_CONFLICT +You can either specify DEVICE=blah, and have the LDSCRIPT generated, +or you can provide LDSCRIPT, and ensure CPPFLAGS, LDFLAGS and LDLIBS +all contain the correct values for the target you wish to use. +You cannot provide both! +endef + +ifeq ($(strip $(DEVICE)),) +# Old style, assume LDSCRIPT exists +DEFS += -I$(OPENCM3_DIR)/include +LDFLAGS += -L$(OPENCM3_DIR)/lib +LDLIBS += -l$(LIBNAME) +LDSCRIPT ?= $(BINARY).ld +else +# New style, assume device is provided, and we're generating the rest. +ifneq ($(strip $(LDSCRIPT)),) +$(error $(ERR_DEVICE_LDSCRIPT_CONFLICT)) +endif +include $(OPENCM3_DIR)/mk/genlink-config.mk +endif + +OPENCM3_SCRIPT_DIR = $(OPENCM3_DIR)/scripts +EXAMPLES_SCRIPT_DIR = $(OPENCM3_DIR)/../scripts + +############################################################################### +# C flags + +TGT_CFLAGS += $(OPT) $(CSTD) -g +TGT_CFLAGS += $(ARCH_FLAGS) +TGT_CFLAGS += -Wextra -Wshadow -Wimplicit-function-declaration +TGT_CFLAGS += -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes +TGT_CFLAGS += -fno-common -ffunction-sections -fdata-sections + +############################################################################### +# C++ flags + +TGT_CXXFLAGS += $(OPT) $(CXXSTD) -g +TGT_CXXFLAGS += $(ARCH_FLAGS) +TGT_CXXFLAGS += -Wextra -Wshadow -Wredundant-decls -Weffc++ +TGT_CXXFLAGS += -fno-common -ffunction-sections -fdata-sections + +############################################################################### +# C & C++ preprocessor common flags + +TGT_CPPFLAGS += -MD +TGT_CPPFLAGS += -Wall -Wundef +TGT_CPPFLAGS += $(DEFS) +TGT_CPPFLAGS += -I./include/ + + + +############################################################################### +# Linker flags + +TGT_LDFLAGS += --static -nostartfiles +TGT_LDFLAGS += -T$(LDSCRIPT) +TGT_LDFLAGS += $(ARCH_FLAGS) +TGT_LDFLAGS += -Wl,-Map=$(*).map +TGT_LDFLAGS += -Wl,--gc-sections +ifeq ($(V),99) +TGT_LDFLAGS += -Wl,--print-gc-sections +endif + +############################################################################### +# Used libraries + +LDLIBS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group + + +############################################################################### +############################################################################### +############################################################################### + +.SUFFIXES: .elf .bin .hex .srec .list .map .images +.SECONDEXPANSION: +.SECONDARY: + +all: elf bin hex + +elf: $(BINARY).elf +bin: $(BINARY).bin +hex: $(BINARY).hex +srec: $(BINARY).srec +list: $(BINARY).list + +images: $(BINARY).images +flash: $(BINARY).flash +########################### +# programming by dfu-util # +########################### +program: $(BINARY).program + + +# Either verify the user provided LDSCRIPT exists, or generate it. +ifeq ($(strip $(DEVICE)),) +$(LDSCRIPT): + ifeq (,$(wildcard $(LDSCRIPT))) + $(error Unable to find specified linker script: $(LDSCRIPT)) + endif +else +include $(OPENCM3_DIR)/mk/genlink-rules.mk +endif + +# Define a helper macro for debugging make errors online +# you can type "make print-OPENCM3_DIR" and it will show you +# how that ended up being resolved by all of the included +# makefiles. +print-%: + @echo $*=$($*) + +%.images: %.bin %.hex %.srec %.list %.map + @#printf "*** $* images generated ***\n" + +%.bin: %.elf + @#printf " OBJCOPY $(*).bin\n" + $(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin + +%.hex: %.elf + @#printf " OBJCOPY $(*).hex\n" + $(Q)$(OBJCOPY) -Oihex $(*).elf $(*).hex + +%.srec: %.elf + @#printf " OBJCOPY $(*).srec\n" + $(Q)$(OBJCOPY) -Osrec $(*).elf $(*).srec + +%.list: %.elf + @#printf " OBJDUMP $(*).list\n" + $(Q)$(OBJDUMP) -S $(*).elf > $(*).list + +%.elf %.map: $(OBJS) $(LDSCRIPT) + @#printf " LD $(*).elf\n" + $(Q)$(LD) $(TGT_LDFLAGS) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $(*).elf + +%.o: %.c + @#printf " CC $(*).c\n" + $(Q)$(CC) $(TGT_CFLAGS) $(CFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $(*).o -c $(*).c + +%.o: %.cxx + @#printf " CXX $(*).cxx\n" + $(Q)$(CXX) $(TGT_CXXFLAGS) $(CXXFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $(*).o -c $(*).cxx + +%.o: %.cpp + @#printf " CXX $(*).cpp\n" + $(Q)$(CXX) $(TGT_CXXFLAGS) $(CXXFLAGS) $(TGT_CPPFLAGS) $(CPPFLAGS) -o $(*).o -c $(*).cpp + +clean: + @#printf " CLEAN\n" + $(Q)$(RM) ./src/*.o *.o *.d ./src/*.d *.elf *.bin *.hex *.srec *.list *.map generated.* ${OBJS} ${OBJS:%.o:%.d} + +stylecheck: $(STYLECHECKFILES:=.stylecheck) +styleclean: $(STYLECHECKFILES:=.styleclean) + +# the cat is due to multithreaded nature - we like to have consistent chunks of text on the output +%.stylecheck: % + $(Q)$(OPENCM3_SCRIPT_DIR)$(STYLECHECK) $(STYLECHECKFLAGS) $* > $*.stylecheck; \ + if [ -s $*.stylecheck ]; then \ + cat $*.stylecheck; \ + else \ + rm -f $*.stylecheck; \ + fi; + +%.styleclean: + $(Q)rm -f $*.stylecheck; + + +%.stlink-flash: %.bin + @printf " FLASH $<\n" + $(STFLASH) write $(*).bin 0x8000000 + + +########################### +# programming by dfu-util # +########################### +%.program: %.bin + @printf " FLASHING BY dfu-util $<\n" + $(DFUUTIL) -a 0 -s 0x08000000:leave -D $(*).bin + +ifeq ($(BMP_PORT),) +ifeq ($(OOCD_FILE),) + +%.flash: %.elf + @printf " FLASH $<\n" + (echo "halt; program $(realpath $(*).elf) verify reset" | nc -4 localhost 4444 2>/dev/null) || \ + $(OOCD) -f interface/$(OOCD_INTERFACE).cfg \ + -f target/$(OOCD_TARGET).cfg \ + -c "program $(*).elf verify reset exit" \ + $(NULL) +else +%.flash: %.elf + @printf " FLASH $<\n" + (echo "halt; program $(realpath $(*).elf) verify reset" | nc -4 localhost 4444 2>/dev/null) || \ + $(OOCD) -f $(OOCD_FILE) \ + -c "program $(*).elf verify reset exit" \ + $(NULL) +endif +else +%.flash: %.elf + @printf " GDB $(*).elf (flash)\n" + $(GDB) --batch \ + -ex 'target extended-remote $(BMP_PORT)' \ + -x $(EXAMPLES_SCRIPT_DIR)/black_magic_probe_flash.scr \ + $(*).elf +endif + +.PHONY: images clean stylecheck styleclean elf bin hex srec list program + +-include $(OBJS:.o=.d) diff --git a/libopencm3.target.mk b/libopencm3.target.mk new file mode 100644 index 0000000..f5981da --- /dev/null +++ b/libopencm3.target.mk @@ -0,0 +1,46 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## Copyright (C) 2010 Piotr Esden-Tempski +## Copyright (C) 2011 Fergus Noble +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see . +## + +LIBNAME = opencm3_stm32f2 +DEFS += -DSTM32F2 + +FP_FLAGS ?= -msoft-float +ARCH_FLAGS = -mthumb -mcpu=cortex-m3 $(FP_FLAGS) -mfix-cortex-m3-ldrd + + +################################################################################ +# OpenOCD specific variables + +OOCD ?= openocd +OOCD_INTERFACE ?= stlink-v2-1 +OOCD_TARGET ?= stm32f2x + +################################################################################ +# Black Magic Probe specific variables +# Set the BMP_PORT to a serial port and then BMP is used for flashing +BMP_PORT ?= + +################################################################################ +# texane/stlink specific variables +#STLINK_PORT ?= :4242 + + +include libopencm3.rules.mk diff --git a/monerujo.ld b/monerujo.ld new file mode 100644 index 0000000..5c562c5 --- /dev/null +++ b/monerujo.ld @@ -0,0 +1,126 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ +MEMORY +{ + +/* +For flashing by external programmer: rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K +For flashing by USB DFU bootloader prpgrammer: rom (rx) : ORIGIN = 0x08002000, LENGTH = 512K +*/ + + rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} + + + + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + + .confidential (NOLOAD) : { + *(confidential) + ASSERT ((SIZEOF(.confidential) <= 32K), "Error: Confidential section too big!"); + } >ram + + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/src/display.c b/src/display.c index 165e6ca..682e372 100644 --- a/src/display.c +++ b/src/display.c @@ -33,17 +33,22 @@ #define OLED_INVERTDISPLAY 0xA7 #define OLED_DISPLAYOFF 0xAE #define OLED_DISPLAYON 0xAF -#define OLED_SETDISPLAYOFFSET 0xD3 +#define OLED_SETDISPLAYCLOCKDIV 0xD5 +#define OLED_SETDISPLAYOFFSET 0xD3 #define OLED_SETCOMPINS 0xDA -#define OLED_SETVCOMDESELECT 0xDB +#define OLED_SETVCOMDESELECT 0xDB #define OLED_SETDFOSC 0xD5 #define OLED_SETPRECHARGE 0xD9 #define OLED_SETMULTIPLEX 0xA8 #define OLED_SETSTARTLINE 0x40 #define OLED_MEMORYMODE 0x20 #define OLED_CHARGEPUMP 0x8D -#define OLED_SETCOMREMAP 0xC8 -#define OLED_SETSEGREMAP 0xA1 + +// NORM and FLIP/SWAP rotates the display orientation +#define OLED_SETCOMNORM 0xC0 +#define OLED_SETCOMFLIP 0xC8 +#define OLED_SETSEGNORM 0xA0 +#define OLED_SETSEGSWAP 0xA1 #define OLED_SPI_BASE SPI1 #define OLED_DC_PORT GPIOB @@ -129,10 +134,22 @@ void oledSetContrast(uint8_t level) { void oled_setup() { static uint8_t initCommands[] = { - OLED_MEMORYMODE, 0x00, // Horizontal Addressing Mode - OLED_CHARGEPUMP, 0x14, // enable charge pump - OLED_SETCONTRAST, OLED_CONTRAST_DEFAULT, - OLED_DISPLAYON }; + OLED_DISPLAYOFF, + OLED_SETDISPLAYCLOCKDIV, 0x80, + OLED_SETMULTIPLEX, 0x7F, + OLED_SETDISPLAYOFFSET, 0x00, + OLED_SETSTARTLINE | 0x00, + OLED_CHARGEPUMP, 0x14, + OLED_MEMORYMODE, 0x00, + OLED_SETSEGSWAP, + OLED_SETCOMFLIP, + OLED_SETCOMPINS, 0x12, + OLED_SETCONTRAST, OLED_CONTRAST_GOOD, + OLED_SETPRECHARGE, 0xF1, + OLED_SETVCOMDESELECT, 0x40, + OLED_DISPLAYRESUME, + OLED_NORMALDISPLAY, + OLED_DISPLAYON }; /* * Function | CS# | D/C# | D0 = SCLK | D1 = SDIN diff --git a/src/main.c b/src/main.c index f2572d2..20b9521 100644 --- a/src/main.c +++ b/src/main.c @@ -83,7 +83,8 @@ static void showQrAddress(void) { if (!drawQrCode(uri)) { oledDrawStringCenter(28, "QR CODE FAILED"); } else { - oledSetContrast(OLED_CONTRAST_QR); + // Seems to not be needed? + //oledSetContrast(OLED_CONTRAST_QR); } showLeftButtonLabel("Address"); oledRefresh(); @@ -110,7 +111,6 @@ static void showAddress(void) { p = q; // where we stopped } showRightButtonLabel("QR"); - oledSetContrast(OLED_CONTRAST_DEFAULT); // because we may be coming from the QR code oledRefresh(); rightButton.pressed = showQrAddress; leftButton.pressed = NULL; diff --git a/src/mnemonics/mnemonics.c b/src/mnemonics/mnemonics.c index 45295a0..b5fc0a9 100644 --- a/src/mnemonics/mnemonics.c +++ b/src/mnemonics/mnemonics.c @@ -29,7 +29,7 @@ // CRC code which works adapted from https://community.st.com/thread/18626 static uint32_t revbit(uint32_t data) { - asm("rbit r0,r0"); + __asm__("rbit r0,r0"); return data; } diff --git a/src/usb.c b/src/usb.c index 38ae9a3..8168fb6 100644 --- a/src/usb.c +++ b/src/usb.c @@ -55,7 +55,7 @@ static const struct usb_device_descriptor dev = { .bDeviceSubClass = 0, .bDeviceProtocol = 0, .bMaxPacketSize0 = USB_MPS, - .idVendor = 0xF055, + .idVendor = 0x1209, .idProduct = 0xC0DA, .bcdDevice = 0x0200, .iManufacturer = USB_STRING_MANUFACTURER, diff --git a/src/util.c b/src/util.c index 645ca31..3cd1efb 100644 --- a/src/util.c +++ b/src/util.c @@ -21,6 +21,11 @@ #include "util.h" // empirical magic number +#if WERE_USING_ECLIPSE +// HSE_VALUE is taken from config +#else +#define HSE_VALUE 8000000 +#endif #define DELAY_FACTOR (HSE_VALUE/270000) inline void delay(uint32_t wait)