diff --git a/.gitignore b/.gitignore index 880af0108..f78a94ac0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.vscode/ _attic/ vendor/src/ emu.config diff --git a/Makefile.bootloader b/Makefile.bootloader index bad82616b..652fa3edb 100644 --- a/Makefile.bootloader +++ b/Makefile.bootloader @@ -58,6 +58,7 @@ OBJ_HAL += $(addprefix $(BUILD_MP)/,\ OBJ_FW += $(addprefix $(BUILD_FW)/, \ bootloader/header.o \ bootloader/main.o \ + bootloader/messages.o \ extmod/modtrezorui/display.o \ extmod/modtrezorui/inflate.o \ extmod/modtrezorui/font_bitmap.o \ diff --git a/micropython/bootloader/main.c b/micropython/bootloader/main.c index 52acd9bac..dd346fd7d 100644 --- a/micropython/bootloader/main.c +++ b/micropython/bootloader/main.c @@ -1,6 +1,7 @@ #include STM32_HAL_H #include +#include #include "common.h" #include "display.h" @@ -10,6 +11,8 @@ #include "usb.h" #include "version.h" +#include "messages.h" + #define IMAGE_MAGIC 0x465A5254 // TRZF #define IMAGE_MAXSIZE (7 * 128 * 1024) @@ -149,17 +152,51 @@ void mainloop(void) __fatal_error("usb_init_all failed"); } - display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, 0x001F); - display_refresh(); + uint8_t buf[64]; - for(;;) { - uint32_t e = touch_read(); - if (e & TOUCH_START || e & TOUCH_MOVE) { - int x = (e >> 8) & 0xFF, y = e & 0xFF; - display_bar(x - 1, y - 1, 3, 3, 0xFFFF); - display_refresh(); + for (;;) { + int iface = usb_hid_read_select(1); // 1ms timeout + if (iface < 0) { + continue; + } + ssize_t r = usb_hid_read(iface, buf, sizeof(buf)); + // invalid length + if (r != sizeof(buf)) { + continue; + } + // invalid header + if (buf[0] != '?' || buf[1] != '#' || buf[2] != '#') { + continue; + } + uint16_t msg_id = (buf[3] << 8) + buf[4]; + uint32_t msg_size = (buf[5] << 24) + (buf[6] << 16) + (buf[7] << 8) + buf[8]; + (void)msg_size; + switch (msg_id) { + case 0: // Initialize + DPRINTLN("received Initialize"); + send_msg_features(iface, false); + break; + case 1: // Ping + DPRINTLN("received Ping"); + send_msg_success(iface); + break; + case 6: // FirmwareErase + DPRINTLN("received FirmwareErase"); + send_msg_failure(iface); + break; + case 7: // FirmwareUpload + DPRINTLN("received FirmwareUpload"); + send_msg_failure(iface); + break; + case 27: // ButtonAck + DPRINTLN("received ButtonAck"); + send_msg_failure(iface); + break; + default: + DPRINTLN("received garbage"); + send_msg_failure(iface); + break; } - HAL_Delay(1); } } diff --git a/micropython/bootloader/messages.c b/micropython/bootloader/messages.c new file mode 100644 index 000000000..70023c0bd --- /dev/null +++ b/micropython/bootloader/messages.c @@ -0,0 +1,56 @@ +#include "usb.h" +#include "version.h" + +#include "messages.h" + +void send_msg_success(int iface) +{ + // send response: Success message (id 2), payload len 0 + usb_hid_write_blocking(iface, (const uint8_t *) + "?##" // header + "\x00\x02" // msg_id + "\x00\x00\x00\x00" // payload_len + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + , 64, 1); +} + +void send_msg_failure(int iface) +{ + // send response: Failure message (id 3), payload len 2 + // code = 99 (Failure_FirmwareError) + usb_hid_write_blocking(iface, (const uint8_t *) + "?##" // header + "\x00\x03" // msg_id + "\x00\x00\x00\x02" // payload_len + "\x08\x63" // data + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + , 64, 1); +} + +void send_msg_features(int iface, bool firmware_present) +{ + // send response: Features message (id 17), payload len 22 + // vendor = "trezor.io" + // major_version = VERSION_MAJOR + // minor_version = VERSION_MINOR + // patch_version = VERSION_PATCH + // bootloader_mode = True + // firmware_present = True/False + if (firmware_present) { + usb_hid_write_blocking(iface, (const uint8_t *) + "?##" // header + "\x00\x11" // msg_id + "\x00\x00\x00\x16" // payload_len + "\x0a\x09" "trezor.io\x10" VERSION_MAJOR_CHAR "\x18" VERSION_MINOR_CHAR " " VERSION_PATCH_CHAR "(\x01" // data + "\x90\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + , 64, 1); + } else { + usb_hid_write_blocking(iface, (const uint8_t *) + "?##" // header + "\x00\x11" // msg_id + "\x00\x00\x00\x16" // payload_len + "\x0a\x09" "trezor.io\x10" VERSION_MAJOR_CHAR "\x18" VERSION_MINOR_CHAR " " VERSION_PATCH_CHAR "(\x01" // data + "\x90\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + , 64, 1); + } +} \ No newline at end of file diff --git a/micropython/bootloader/messages.h b/micropython/bootloader/messages.h new file mode 100644 index 000000000..b680f1f69 --- /dev/null +++ b/micropython/bootloader/messages.h @@ -0,0 +1,10 @@ +#ifndef __MESSAGES_H__ +#define __MESSAGES_H__ + +#include + +void send_msg_success(int iface); +void send_msg_failure(int iface); +void send_msg_features(int iface, bool firmware_present); + +#endif \ No newline at end of file diff --git a/micropython/bootloader/version.h b/micropython/bootloader/version.h index cb1e4a091..51e009d9c 100644 --- a/micropython/bootloader/version.h +++ b/micropython/bootloader/version.h @@ -3,6 +3,10 @@ #define VERSION_PATCH 0 #define VERSION_BUILD 0 +#define VERSION_MAJOR_CHAR "\x00" +#define VERSION_MINOR_CHAR "\x01" +#define VERSION_PATCH_CHAR "\x00" + #define STR_HELPER(X) #X #define STRINGIZE(X) STR_HELPER(X) diff --git a/micropython/trezorhal/usb.h b/micropython/trezorhal/usb.h index e65c638c7..0cf586711 100644 --- a/micropython/trezorhal/usb.h +++ b/micropython/trezorhal/usb.h @@ -8,6 +8,8 @@ #ifndef __TREZORHAL_USB_H__ #define __TREZORHAL_USB_H__ +#include + #define USB_EP_DIR_OUT 0x00 #define USB_EP_DIR_IN 0x80 #define USB_EP_DIR_MSK 0x80