1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-13 02:58:57 +00:00

bootloader: rework UI

This commit is contained in:
Pavol Rusnak 2017-12-17 01:09:45 +01:00
parent f6f6e8593a
commit 2f567ee822
No known key found for this signature in database
GPG Key ID: 91F3B339B9A02A3D
21 changed files with 291 additions and 245 deletions

View File

@ -80,6 +80,7 @@ SOURCE_STMHAL = [
SOURCE_BOOTLOADER = [
'embed/bootloader/startup.s',
'embed/bootloader/header.S',
'embed/bootloader/bootui.c',
'embed/bootloader/main.c',
'embed/bootloader/messages.c',
'embed/bootloader/nanopb/pb_common.c',

174
embed/bootloader/bootui.c Normal file
View File

@ -0,0 +1,174 @@
#include <string.h>
#include "display.h"
#include "mini_printf.h"
#include "bootui.h"
#include "version.h"
#include "icon_info.h"
#include "icon_done.h"
#include "icon_fail.h"
#include "icon_install.h"
#include "icon_wipe.h"
#define BACKLIGHT_NORMAL 150
#define COLOR_BL_FAIL RGB16(0xFF, 0x00, 0x00) // red
#define COLOR_BL_DONE RGB16(0x00, 0xAE, 0x0B) // green
#define COLOR_BL_PROCESS RGB16(0x4A, 0x90, 0xE2) // blue
#define COLOR_BL_GRAY RGB16(0x99, 0x99, 0x99) // gray
// boot UI
void ui_screen_boot(const vendor_header *vhdr, const image_header *hdr)
{
const uint8_t *vimg = vhdr->vimg;
const char *vstr = ((vhdr->vtrust & VTRUST_STRING) == 0) ? (const char *)vhdr->vstr : 0;
const uint32_t vstr_len = ((vhdr->vtrust & VTRUST_STRING) == 0) ? vhdr->vstr_len : 0;
const uint32_t fw_version = hdr->version;
const uint16_t background = ((vhdr->vtrust & VTRUST_RED) == 0) ? RGB16(0xFF, 0x00, 0x00) : COLOR_BLACK;
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, background);
// check whether vendor image is 120x120
if (memcmp(vimg, "TOIf\x78\x00\x78\x00", 4) != 0) {
return;
}
uint32_t datalen = *(uint32_t *)(vimg + 8);
display_image((DISPLAY_RESX - 120) / 2, 32, 120, 120, vimg + 12, datalen);
if (vstr && vstr_len) {
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 48, vstr, vstr_len, FONT_NORMAL, COLOR_WHITE, background, 0);
}
char ver_str[32];
mini_snprintf(ver_str, sizeof(ver_str), "%d.%d.%d.%d",
(int)(fw_version & 0xFF),
(int)((fw_version >> 8) & 0xFF),
(int)((fw_version >> 16) & 0xFF),
(int)((fw_version >> 24) & 0xFF)
);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 25, ver_str, -1, FONT_NORMAL, COLOR_BL_GRAY, background, 0);
ui_fadein();
}
void ui_screen_boot_wait(int delay)
{
char wait_str[16];
mini_snprintf(wait_str, sizeof(wait_str), "waiting for %ds", delay);
display_bar(0, DISPLAY_RESY - 2 - 18, DISPLAY_RESX, 2 + 18, COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 2, wait_str, -1, FONT_NORMAL, COLOR_BL_GRAY, COLOR_BLACK, 0);
}
void ui_screen_boot_click(void) {
display_bar(0, DISPLAY_RESY - 2 - 18, DISPLAY_RESX, 2 + 18, COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 2, "click to continue ...", -1, FONT_NORMAL, COLOR_BL_GRAY, COLOR_BLACK, 0);
}
// info UI
void ui_screen_info(const vendor_header * const vhdr, const image_header * const hdr)
{
display_backlight(0);
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_text(16, 32, "Bootloader mode", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE, 0);
display_bar(16, 44, DISPLAY_RESX - 14 * 2, 1, COLOR_BLACK);
display_icon(16, 54, 32, 32, toi_icon_info + 12, sizeof(toi_icon_info) - 12, COLOR_BL_GRAY, COLOR_WHITE);
char ver_str[32];
mini_snprintf(ver_str, sizeof(ver_str), "Bootloader %d.%d.%d.%d",
VERSION_MAJOR,
VERSION_MINOR,
VERSION_PATCH,
VERSION_BUILD
);
display_text(55, 70, ver_str, -1, FONT_NORMAL, COLOR_BL_GRAY, COLOR_WHITE, 0);
if (vhdr && hdr) {
mini_snprintf(ver_str, sizeof(ver_str), "Firmware %d.%d.%d.%d",
(int)(hdr->version & 0xFF),
(int)((hdr->version >> 8) & 0xFF),
(int)((hdr->version >> 16) & 0xFF),
(int)((hdr->version >> 24) & 0xFF)
);
display_text(55, 95, ver_str, -1, FONT_NORMAL, COLOR_BL_GRAY, COLOR_WHITE, 0);
display_text(55, 120, (const char *)vhdr->vstr, vhdr->vstr_len, FONT_NORMAL, COLOR_BL_GRAY, COLOR_WHITE, 0);
} else {
display_text(55, 95, "No Firmware", -1, FONT_NORMAL, COLOR_BL_GRAY, COLOR_WHITE, 0);
display_text_center(120, 213, "Go to trezor.io/start", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE, 0);
}
ui_fadein();
}
// install UI
void ui_screen_install(void)
{
display_fade(BACKLIGHT_NORMAL, 0, 100);
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_loader(1000, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_install, sizeof(toi_icon_install), COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, "Installing firmware", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE, 0);
display_fade(0, BACKLIGHT_NORMAL, 100);
}
void ui_screen_install_progress_erase(int pos, int len)
{
display_loader(250 * pos / len, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_install, sizeof(toi_icon_install), COLOR_BLACK);
}
void ui_screen_install_progress_upload(int pos)
{
display_loader(pos, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_install, sizeof(toi_icon_install), COLOR_BLACK);
}
// wipe UI
void ui_screen_wipe(void)
{
display_fade(BACKLIGHT_NORMAL, 0, 100);
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_loader(1000, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_wipe, sizeof(toi_icon_wipe), COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, "Wiping Device", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE, 0);
display_fade(0, BACKLIGHT_NORMAL, 100);
}
void ui_screen_wipe_progress(int pos, int len)
{
display_loader(1000 * pos / len, -20, COLOR_BL_PROCESS, COLOR_WHITE, toi_icon_wipe, sizeof(toi_icon_wipe), COLOR_BLACK);
}
// done UI
void ui_screen_done(int restart)
{
const char *str;
if (restart <= 3 && restart >= 1) {
char count_str[24];
mini_snprintf(count_str, sizeof(count_str), "Done! Restarting in %ds", restart);
str = count_str;
} else {
str = "Done! Unplug the device.";
}
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_loader(1000, -20, COLOR_BL_DONE, COLOR_WHITE, toi_icon_done, sizeof(toi_icon_done), COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, str, -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE, 0);
}
// error UI
void ui_screen_fail(void)
{
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, COLOR_WHITE);
display_loader(1000, -20, COLOR_BL_FAIL, COLOR_WHITE, toi_icon_fail, sizeof(toi_icon_fail), COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 24, "Failed! Please, reconnect.", -1, FONT_NORMAL, COLOR_BLACK, COLOR_WHITE, 0);
}
// general functions
void ui_fadein(void)
{
display_fade(0, BACKLIGHT_NORMAL, 1000);
}
void ui_fadeout(void)
{
display_fade(BACKLIGHT_NORMAL, 0, 500);
display_clear();
}

27
embed/bootloader/bootui.h Normal file
View File

@ -0,0 +1,27 @@
#ifndef __BOOTUI_H__
#define __BOOTUI_H__
#include "secbool.h"
#include "image.h"
void ui_screen_boot(const vendor_header * const vhdr, const image_header * const hdr);
void ui_screen_boot_wait(int delay);
void ui_screen_boot_click(void);
void ui_screen_info(const vendor_header * const vhdr, const image_header * const hdr);
void ui_screen_install(void);
void ui_screen_install_progress_erase(int pos, int len);
void ui_screen_install_progress_upload(int pos);
void ui_screen_wipe(void);
void ui_screen_wipe_progress(int pos, int len);
void ui_screen_done(int restart);
void ui_screen_fail(void);
void ui_fadein(void);
void ui_fadeout(void);
#endif

View File

@ -1,10 +0,0 @@
static const uint8_t toi_icon_cross[] = {
// magic
'T', 'O', 'I', 'g',
// width (16-bit), height (16-bit)
0x40, 0x00, 0x40, 0x00,
// compressed data length (32-bit)
0xbb, 0x00, 0x00, 0x00,
// compressed data
0xed, 0x92, 0xb1, 0x0d, 0x84, 0x30, 0x0c, 0x45, 0x43, 0x2a, 0x4a, 0x7a, 0xae, 0xa0, 0xbf, 0x19, 0xd8, 0x87, 0xee, 0x56, 0xa0, 0xa2, 0x65, 0x96, 0xbb, 0x05, 0xd0, 0x4d, 0x40, 0xc1, 0x2e, 0x27, 0x24, 0x90, 0x7c, 0x26, 0x0e, 0xa2, 0x70, 0x92, 0xcf, 0x00, 0xf9, 0xd5, 0x97, 0xcc, 0x7f, 0xd8, 0x8e, 0x8d, 0xc9, 0xca, 0xba, 0x21, 0x3b, 0x5c, 0xbe, 0x6b, 0x74, 0xbd, 0xa5, 0xf7, 0x69, 0x6b, 0x5a, 0x74, 0x7d, 0xa2, 0xcd, 0xa7, 0x2c, 0x5b, 0x55, 0x2e, 0x66, 0xa2, 0x8f, 0xd8, 0x27, 0xd1, 0x5e, 0xa9, 0x0f, 0x5e, 0xe4, 0x01, 0x1c, 0xa7, 0x9f, 0xe6, 0x97, 0x44, 0xd2, 0x41, 0xcd, 0xa6, 0x0f, 0x0c, 0x30, 0x32, 0x80, 0xb1, 0x05, 0xc7, 0xd7, 0xd0, 0x80, 0x07, 0xe0, 0x6b, 0xcc, 0x23, 0x12, 0x77, 0x80, 0xbd, 0x3a, 0xfa, 0x5c, 0xc3, 0x1b, 0x72, 0x80, 0x78, 0x5c, 0x00, 0xf1, 0xb8, 0x00, 0x12, 0x71, 0x07, 0x48, 0xc4, 0x3d, 0xa0, 0x4f, 0x3c, 0xe2, 0x98, 0x8c, 0xc3, 0x3a, 0xe2, 0x83, 0xfe, 0xd0, 0x7c, 0x60, 0x3f, 0x68, 0xbf, 0xe0, 0x7d, 0xd0, 0xfb, 0x82, 0xfb, 0x40, 0xf7, 0x05, 0xee, 0x13, 0xde, 0xf7, 0xe4, 0xe3, 0x0e, 0xb0, 0x69, 0x7e, 0x2b, 0x7f, 0x97, 0x0e, 0x16, 0x5d, 0xb7, 0xc3, 0xe5, 0xbb, 0xc6, 0x64, 0x65, 0xdd, 0xd1, 0x1f,
};

View File

@ -0,0 +1,10 @@
static const uint8_t toi_icon_done[] = {
// magic
'T', 'O', 'I', 'g',
// width (16-bit), height (16-bit)
0x40, 0x00, 0x40, 0x00,
// compressed data length (32-bit)
0xce, 0x00, 0x00, 0x00,
// compressed data
0xed, 0x92, 0xdf, 0x11, 0xc1, 0x40, 0x10, 0x87, 0x77, 0x26, 0xe3, 0xef, 0x93, 0x12, 0x94, 0x90, 0x0a, 0x24, 0x0d, 0x50, 0x02, 0x25, 0x28, 0x41, 0x09, 0x74, 0xa0, 0x04, 0x52, 0x01, 0x4a, 0x88, 0x0a, 0xd0, 0x80, 0x21, 0xde, 0xc8, 0x2d, 0xe7, 0x8e, 0xdc, 0xc8, 0xed, 0x6f, 0xbc, 0x27, 0xbf, 0x97, 0x7b, 0xf8, 0xe6, 0xdb, 0xdb, 0xbd, 0x3d, 0xa2, 0x3a, 0xd5, 0x4b, 0x67, 0x8d, 0xf9, 0x26, 0xc7, 0x3a, 0x73, 0x82, 0xf8, 0x8a, 0xf9, 0x81, 0x75, 0xe6, 0xad, 0xcc, 0xe7, 0x9a, 0xdf, 0x45, 0xdc, 0xe5, 0x77, 0x16, 0x50, 0xe7, 0x1c, 0xde, 0xce, 0xbc, 0xc7, 0xba, 0xea, 0x09, 0xb8, 0xfd, 0x9f, 0xde, 0xc7, 0x7a, 0x5a, 0xea, 0x2a, 0xc1, 0xba, 0xdd, 0x88, 0x6d, 0xfe, 0xe8, 0x19, 0x6a, 0xa7, 0xcf, 0x99, 0x99, 0xbd, 0xa4, 0x2f, 0xcd, 0x46, 0xec, 0xed, 0x27, 0xef, 0x93, 0xa6, 0x1f, 0x5d, 0xf9, 0x74, 0xbd, 0x91, 0x96, 0x30, 0xbb, 0x2d, 0x7b, 0x98, 0x9a, 0x33, 0xfc, 0xe5, 0xc1, 0xd9, 0xb4, 0x25, 0xdc, 0x4e, 0x14, 0xb1, 0x93, 0xb0, 0xcc, 0x03, 0x07, 0x5f, 0x7c, 0xcf, 0x3a, 0xf8, 0x62, 0x15, 0xfa, 0x78, 0x51, 0xe0, 0xea, 0xdf, 0xcb, 0x18, 0xea, 0x45, 0x81, 0x4c, 0xda, 0xfb, 0x44, 0x6c, 0xde, 0x2d, 0x90, 0xc9, 0xbf, 0x3e, 0x82, 0x3a, 0x51, 0xe3, 0x85, 0x6f, 0x04, 0x32, 0x62, 0x8e, 0x11, 0x6f, 0x62, 0x9d, 0x68, 0x18, 0x53, 0x9d, 0x8a, 0xe5, 0x09,
};

View File

@ -0,0 +1,10 @@
static const uint8_t toi_icon_fail[] = {
// magic
'T', 'O', 'I', 'g',
// width (16-bit), height (16-bit)
0x40, 0x00, 0x40, 0x00,
// compressed data length (32-bit)
0x21, 0x01, 0x00, 0x00,
// compressed data
0xed, 0x52, 0xb9, 0x0d, 0xc2, 0x40, 0x10, 0x34, 0xf8, 0x89, 0xa9, 0x00, 0xd1, 0x00, 0xe8, 0x2a, 0x00, 0x17, 0x80, 0xc0, 0x1d, 0xe0, 0x0e, 0x28, 0x91, 0x84, 0x1c, 0x89, 0x12, 0x80, 0xdc, 0xc1, 0xd9, 0x24, 0xa0, 0x5b, 0xb0, 0x7d, 0xe7, 0xbd, 0x67, 0xe4, 0x98, 0x80, 0x89, 0x46, 0x3b, 0xde, 0xf5, 0xcd, 0xee, 0x44, 0xd1, 0x1f, 0x3f, 0x81, 0xe9, 0x99, 0xf9, 0x76, 0x11, 0xea, 0x73, 0x2a, 0x0d, 0xcd, 0xe8, 0x16, 0xb6, 0x57, 0x54, 0x1b, 0xbe, 0x27, 0x15, 0x0c, 0x58, 0x12, 0x51, 0xd1, 0xd3, 0xf4, 0x4b, 0xaf, 0x61, 0x3b, 0x51, 0xd3, 0xf3, 0xc3, 0x97, 0xfa, 0x03, 0xda, 0x76, 0xa2, 0xbc, 0xa5, 0x49, 0x47, 0xdd, 0x01, 0x93, 0xaa, 0x2b, 0x3e, 0x5b, 0x7e, 0xec, 0xa8, 0x9a, 0xd9, 0xfa, 0x8a, 0xc8, 0x0c, 0x48, 0x34, 0x75, 0x2c, 0x9c, 0x74, 0xb1, 0x6e, 0x1f, 0xdf, 0xe3, 0x65, 0xeb, 0x1b, 0x5d, 0xa4, 0x32, 0x33, 0x4c, 0xda, 0xba, 0x19, 0x4a, 0xb5, 0x69, 0xef, 0xdf, 0x3a, 0x60, 0xad, 0xab, 0xaa, 0xd2, 0xe4, 0xee, 0xfa, 0x8b, 0xc9, 0x83, 0xf0, 0x16, 0xb4, 0x73, 0xe5, 0x87, 0xbf, 0xdf, 0x78, 0xbc, 0x9d, 0x7d, 0x19, 0x9f, 0xc1, 0x80, 0x8a, 0x65, 0x25, 0x40, 0x40, 0x36, 0xac, 0x4b, 0x14, 0xa0, 0x64, 0x18, 0xa0, 0x72, 0x98, 0x30, 0xb3, 0x03, 0xdf, 0x7b, 0x60, 0xf1, 0x01, 0xe5, 0x8c, 0xff, 0x5f, 0x22, 0x7d, 0x3f, 0x6a, 0x8f, 0x4f, 0x14, 0x1e, 0x27, 0xe2, 0xd8, 0x68, 0x3c, 0xc7, 0xdb, 0xc1, 0x80, 0x83, 0xab, 0x37, 0x9e, 0x9c, 0xfa, 0xf7, 0xcd, 0xf1, 0x72, 0x87, 0x7c, 0x48, 0xdc, 0x2e, 0x87, 0x2b, 0x14, 0xd0, 0x7b, 0x91, 0xc2, 0x1d, 0x5c, 0xc2, 0x7c, 0xbf, 0xd1, 0xef, 0x05, 0x07, 0x49, 0x82, 0x74, 0x35, 0x96, 0x53, 0x01, 0x6e, 0x2b, 0xf8, 0x5b, 0x94, 0xef, 0xc6, 0x5a, 0x95, 0x00, 0xe1, 0xc8, 0x79, 0xd5, 0x77, 0x90, 0x6f, 0x69, 0xbd, 0x56, 0x80, 0x78, 0x16, 0xbc, 0x2d, 0x10, 0xd0, 0xf8, 0xcc, 0x7c, 0x2b, 0xa2, 0x3f, 0x7e, 0x03, 0x1f,
};

View File

@ -0,0 +1,10 @@
static const uint8_t toi_icon_info[] = {
// magic
'T', 'O', 'I', 'g',
// width (16-bit), height (16-bit)
0x20, 0x00, 0x20, 0x00,
// compressed data length (32-bit)
0xd9, 0x00, 0x00, 0x00,
// compressed data
0x7d, 0x91, 0x3d, 0x0a, 0xc2, 0x40, 0x10, 0x85, 0x47, 0xfc, 0x47, 0x59, 0x72, 0x10, 0x21, 0x85, 0x1e, 0x20, 0xe0, 0x41, 0x62, 0x6d, 0xa3, 0x37, 0xd0, 0xde, 0x26, 0x37, 0x88, 0xb5, 0x4d, 0xac, 0xd4, 0x5b, 0xd8, 0x59, 0xaa, 0x17, 0x10, 0x23, 0x18, 0x62, 0x34, 0xe6, 0xb9, 0xd9, 0x1f, 0x8c, 0xab, 0x38, 0xc5, 0xce, 0x7e, 0x30, 0x3b, 0xb3, 0xf3, 0x1e, 0x11, 0x8f, 0xf2, 0x6c, 0x7f, 0xda, 0x38, 0xa4, 0xa3, 0x01, 0x11, 0x9e, 0xc2, 0x1a, 0x54, 0x4c, 0x25, 0x6f, 0x81, 0x75, 0xbf, 0x37, 0x04, 0x9e, 0x02, 0x19, 0x30, 0x56, 0x65, 0x97, 0x3c, 0x9f, 0xb1, 0x94, 0x75, 0x4d, 0xc0, 0x22, 0x6a, 0x21, 0xd6, 0x7d, 0x5d, 0x1c, 0x89, 0x46, 0xa2, 0xda, 0xbd, 0xf3, 0xa3, 0x8a, 0x1b, 0x11, 0x1e, 0xfc, 0x56, 0x02, 0x06, 0x3c, 0xf9, 0xb0, 0xea, 0x08, 0xf9, 0xa5, 0x22, 0xa7, 0x33, 0x78, 0x4c, 0x4e, 0x05, 0x1c, 0xf1, 0x20, 0xb4, 0x21, 0x5a, 0x75, 0x76, 0x22, 0x21, 0x9a, 0xa4, 0x54, 0x88, 0x20, 0x09, 0xe2, 0x22, 0xbb, 0xe9, 0x36, 0xa2, 0x77, 0x7f, 0xb2, 0xb3, 0xc3, 0xf5, 0x3f, 0x9b, 0xf5, 0xb2, 0x9f, 0x66, 0x37, 0x95, 0xf3, 0x34, 0xfb, 0x89, 0xfc, 0x8f, 0x66, 0x44, 0x4c, 0xac, 0xa7, 0x98, 0xff, 0x57, 0xee, 0xa3, 0x98, 0x61, 0x6e, 0xee, 0xab, 0xf4, 0x58, 0x2c, 0x1c, 0xa5, 0x47, 0xdb, 0xd0, 0xcb, 0xd4, 0xf3, 0x4b, 0xef, 0xdc, 0x8f, 0x55, 0xbf, 0xcb, 0xfd, 0xc8, 0xac, 0x9f, 0x7e, 0x99, 0x7e, 0x7e, 0xf8, 0xfd, 0x02,
};

View File

@ -0,0 +1,10 @@
static const uint8_t toi_icon_install[] = {
// magic
'T', 'O', 'I', 'g',
// width (16-bit), height (16-bit)
0x40, 0x00, 0x40, 0x00,
// compressed data length (32-bit)
0xb8, 0x00, 0x00, 0x00,
// compressed data
0x63, 0x60, 0x18, 0x05, 0xa3, 0x80, 0x58, 0x60, 0xe2, 0xe2, 0xe2, 0x8c, 0x4f, 0xfe, 0xfc, 0xff, 0xff, 0x7f, 0x46, 0xe5, 0xc9, 0x93, 0x5f, 0x83, 0x90, 0x3f, 0x85, 0x45, 0x9a, 0xeb, 0xff, 0x05, 0x98, 0x3c, 0xef, 0xff, 0x05, 0x98, 0xf2, 0xeb, 0xff, 0xff, 0x86, 0xc9, 0xef, 0xff, 0xff, 0x0b, 0x43, 0x9a, 0xe7, 0xff, 0x7f, 0xa0, 0x01, 0x60, 0x79, 0x5e, 0x20, 0xf3, 0x00, 0xba, 0x3c, 0x0b, 0x50, 0xf0, 0x8f, 0x00, 0x48, 0x9e, 0x11, 0x48, 0xfc, 0x77, 0xc0, 0x30, 0xc0, 0x1f, 0x28, 0x7a, 0x09, 0x24, 0xaf, 0x0b, 0x64, 0x7c, 0xc1, 0xb4, 0x9f, 0x09, 0x28, 0xfc, 0xef, 0x3d, 0x04, 0xff, 0x57, 0xc0, 0xe2, 0x01, 0x90, 0x01, 0x50, 0xf0, 0x05, 0x9b, 0xff, 0x99, 0x10, 0xf2, 0x0a, 0x58, 0x03, 0x48, 0x1f, 0x26, 0xfd, 0x09, 0x7b, 0x00, 0x32, 0xc3, 0xe4, 0x0d, 0x70, 0x84, 0x30, 0x1f, 0x44, 0xfa, 0x01, 0xae, 0x18, 0x60, 0x02, 0x39, 0xfd, 0xff, 0x3f, 0x05, 0x9c, 0xd1, 0x27, 0x0b, 0x92, 0xbf, 0x88, 0x3b, 0x7a, 0x19, 0xef, 0xff, 0xff, 0xff, 0x57, 0x00, 0x4f, 0xfc, 0xcb, 0xfc, 0xff, 0x7f, 0x90, 0x01, 0x6f, 0x02, 0xc1, 0x9b, 0x7c, 0x80, 0x06, 0xe0, 0xd7, 0xce, 0xc0, 0x28, 0xc0, 0x30, 0x0a, 0x46, 0x01, 0xf1, 0x00, 0x00,
};

View File

@ -1,12 +0,0 @@
static const uint8_t toi_icon_lock[] = {
/*
// magic
'T', 'O', 'I', 'g',
// width (16-bit), height (16-bit)
0x7c, 0x00, 0xb4, 0x00,
// compressed data length (32-bit)
0xe2, 0x02, 0x00, 0x00,
*/
// compressed data
0xed, 0xd2, 0x3f, 0x6c, 0x52, 0x41, 0x1c, 0x07, 0xf0, 0x1f, 0x7f, 0x84, 0x46, 0x53, 0xcb, 0x88, 0x26, 0x56, 0xd6, 0x36, 0x31, 0x65, 0xd1, 0xa5, 0x0e, 0xcc, 0x06, 0xd3, 0x26, 0xae, 0x9a, 0x92, 0x38, 0x38, 0x11, 0x70, 0x31, 0x0e, 0x06, 0xca, 0xe4, 0x62, 0x42, 0x71, 0x73, 0x22, 0x21, 0x71, 0xe9, 0x82, 0x49, 0xdd, 0x71, 0xe8, 0xe0, 0x62, 0xd0, 0x34, 0xa2, 0x83, 0x09, 0xdd, 0xe8, 0x86, 0xb6, 0x69, 0xf9, 0xff, 0x7e, 0x8a, 0x48, 0xde, 0x1d, 0xef, 0xee, 0x77, 0xf7, 0x1e, 0xba, 0xd8, 0xfb, 0x8e, 0xf7, 0xbd, 0x0f, 0xef, 0xee, 0xc7, 0x01, 0xc8, 0x73, 0xf3, 0xd1, 0xd3, 0xe7, 0x4f, 0xee, 0x81, 0x97, 0x04, 0x5f, 0xb4, 0xf1, 0x77, 0xac, 0xf7, 0x09, 0xb7, 0xd6, 0xff, 0x0c, 0x99, 0x7c, 0x8d, 0xb9, 0xc2, 0xa1, 0x3a, 0x72, 0x19, 0x3e, 0x76, 0x81, 0xa3, 0xe8, 0xc8, 0x4b, 0x6d, 0x7c, 0x15, 0x05, 0xa9, 0x68, 0xe2, 0x30, 0x0a, 0xb3, 0xa3, 0x37, 0xec, 0xb6, 0x58, 0x5b, 0x9b, 0x3a, 0xba, 0x8c, 0x92, 0xf4, 0x35, 0xf0, 0x0d, 0x94, 0xe6, 0x40, 0x7d, 0x6e, 0x24, 0xa2, 0x3c, 0x7b, 0x86, 0xd2, 0x5d, 0x05, 0x5e, 0x40, 0x32, 0x8a, 0xb9, 0x17, 0x69, 0xdd, 0x9b, 0xe7, 0xd3, 0x8a, 0x8f, 0xe7, 0x55, 0xba, 0xe3, 0x75, 0xe0, 0x93, 0x24, 0xe4, 0x7a, 0x59, 0xad, 0x8f, 0xe5, 0xba, 0xae, 0xd6, 0x23, 0x29, 0x0e, 0xa3, 0x46, 0xb6, 0x65, 0x7a, 0x4d, 0x47, 0x9f, 0xcc, 0x71, 0x70, 0xc4, 0xa1, 0x04, 0x5f, 0x70, 0xec, 0xb4, 0xbe, 0x7d, 0x68, 0x3b, 0x16, 0x53, 0x62, 0xbd, 0x38, 0xb3, 0x6d, 0xf0, 0x70, 0xbc, 0x7a, 0xab, 0x3a, 0xb3, 0x7c, 0x28, 0xd6, 0x5b, 0xfc, 0xae, 0xc6, 0x74, 0xfd, 0x3e, 0xbf, 0x7e, 0x26, 0xd6, 0x4d, 0x6e, 0xd3, 0x67, 0xbb, 0xb8, 0xcb, 0x5f, 0x47, 0xe3, 0xa1, 0x75, 0xe5, 0x0f, 0x78, 0x53, 0xa4, 0x2f, 0x72, 0x1f, 0x88, 0xb3, 0x55, 0x80, 0x9b, 0xdd, 0x1b, 0x91, 0xbe, 0xce, 0xee, 0xf8, 0xc4, 0x77, 0xd7, 0xd8, 0xee, 0x87, 0x48, 0xb3, 0xc7, 0x1b, 0x45, 0xf8, 0xce, 0xc7, 0xce, 0xa4, 0x23, 0xd2, 0x35, 0x66, 0xc3, 0xf1, 0x6c, 0xb9, 0xac, 0x7a, 0x2f, 0xec, 0xe1, 0x12, 0xe4, 0x48, 0x15, 0x23, 0xef, 0x3b, 0xeb, 0x32, 0x3d, 0xf4, 0x05, 0x7a, 0x2e, 0xec, 0x4c, 0x77, 0x9c, 0xf5, 0x25, 0xa6, 0xde, 0x76, 0xd6, 0x61, 0xa6, 0x7e, 0xe7, 0xac, 0x2f, 0x33, 0x75, 0xcc, 0x59, 0xfb, 0xe8, 0x97, 0xbe, 0xa4, 0x18, 0x6a, 0x8d, 0xbc, 0xd8, 0x9a, 0xe2, 0x0f, 0xcd, 0xd8, 0xfd, 0x89, 0xb3, 0xdd, 0x20, 0x5b, 0xee, 0xd7, 0x4f, 0x9d, 0xed, 0x96, 0xdd, 0x7e, 0x17, 0xe9, 0xa5, 0xb9, 0x34, 0x33, 0xd5, 0x33, 0xf2, 0x5e, 0x87, 0x22, 0xbd, 0x48, 0xce, 0x25, 0x6f, 0xb7, 0x1f, 0x15, 0xba, 0x6b, 0xb4, 0xd1, 0xe7, 0x4a, 0xdf, 0xd9, 0xfd, 0x93, 0xa6, 0xdd, 0xf6, 0x77, 0x05, 0xa9, 0xda, 0xfd, 0x68, 0xba, 0xf6, 0x3a, 0x83, 0x73, 0xa4, 0x63, 0xb4, 0xd1, 0x46, 0x1b, 0xfd, 0x3f, 0xeb, 0xc1, 0x2b, 0x8d, 0xd4, 0x64, 0xfa, 0x14, 0x34, 0xb2, 0x61, 0xb4, 0xd1, 0x46, 0x1b, 0x6d, 0xb4, 0xd1, 0x46, 0x1b, 0x6d, 0xb4, 0xd1, 0x46, 0x1b, 0x6d, 0xf4, 0xdf, 0xd6, 0x1d, 0x1d, 0x9d, 0x97, 0x69, 0x6c, 0xa9, 0xf1, 0x03, 0x94, 0x6a, 0x3c, 0x52, 0xe1, 0x1c, 0x12, 0x1a, 0x7b, 0x11, 0xca, 0xfa, 0x8a, 0x48, 0x6a, 0xec, 0xc7, 0x08, 0x5c, 0x46, 0x85, 0xc6, 0x41, 0x5c, 0x86, 0xfd, 0x55, 0x54, 0x6a, 0x1c, 0x26, 0xc4, 0x38, 0x50, 0x43, 0x0d, 0x8d, 0xa3, 0x94, 0x08, 0x07, 0xeb, 0xa8, 0xa5, 0xd1, 0xca, 0x3a, 0x71, 0xa8, 0x89, 0x9a, 0x1a, 0xad, 0xc2, 0x2c, 0x0e, 0xb7, 0x51, 0x5b, 0x23, 0x96, 0x78, 0x1c, 0x15, 0xef, 0x92, 0x69, 0xac, 0xb0, 0xf8, 0x0a, 0xba, 0xd4, 0xb8, 0x67, 0xe3, 0x55, 0x74, 0xad, 0x71, 0x7f, 0x8a, 0xd7, 0xd1, 0x83, 0xc6, 0xc6, 0x04, 0x27, 0xd1, 0x93, 0xc6, 0xd6, 0x18, 0xa7, 0x89, 0x0d, 0x9d, 0xdb, 0x48, 0xf3, 0x1c, 0xd5, 0x1f, 0x10, 0xb7, 0xfa, 0x95, 0x6e, 0x91, 0x6a, 0xdf, 0x52, 0x13, 0x55, 0x65, 0xf2, 0xaf, 0xac, 0x78, 0xc3, 0x15, 0xfa, 0x25, 0xd1, 0x29, 0x29, 0x5e, 0x31, 0x99, 0x02, 0xf3, 0x14, 0x43, 0x4d, 0x77, 0xd6, 0xca, 0xb2, 0x0f, 0x19, 0x82, 0x75, 0x37, 0x78, 0x94, 0x02, 0x3e, 0x81, 0x9a, 0x3e, 0x1e, 0x26, 0x60, 0x36, 0xfe, 0xaa, 0x2e, 0x1e, 0xc4, 0xc1, 0x19, 0x7f, 0x59, 0x0f, 0xf7, 0x63, 0x20, 0x8a, 0xaf, 0xa8, 0x83, 0x7b, 0x11, 0x90, 0x24, 0xa7, 0xc6, 0x5d, 0x29, 0x06, 0x48, 0xab, 0x70, 0x0b, 0xa8, 0x24, 0x69, 0xdc, 0x00, 0x3a, 0xeb, 0x14, 0xde, 0x07, 0x55, 0x56, 0xe5, 0x78, 0x0f, 0xd4, 0x59, 0x91, 0xe1, 0x0a, 0xe8, 0x24, 0x2a, 0xc6, 0x25, 0xd0, 0x4b, 0xb8, 0x2d, 0xc0, 0x05, 0xd0, 0x4d, 0xa8, 0x39, 0x6b, 0xad, 0x2c, 0xe8, 0x27, 0x58, 0xe7, 0xf1, 0x28, 0x05, 0x6e, 0x12, 0xa8, 0xb1, 0x78, 0x98, 0x00, 0x77, 0x09, 0x54, 0x6d, 0x3c, 0x88, 0x83, 0xdb, 0xf8, 0xcb, 0x53, 0xdc, 0x8f, 0x81, 0xfb, 0xf8, 0x8a, 0x13, 0xdc, 0x8b, 0x80, 0xa7, 0xe4, 0xc6, 0xb8, 0xeb, 0x11, 0x03, 0xa4, 0x11, 0x8f, 0xc0, 0x7b, 0x92, 0x5f, 0xe0, 0x1f, 0xe6, 0x27,
};

View File

@ -1,10 +0,0 @@
static const uint8_t toi_icon_tick[] = {
// magic
'T', 'O', 'I', 'g',
// width (16-bit), height (16-bit)
0x40, 0x00, 0x40, 0x00,
// compressed data length (32-bit)
0x98, 0x00, 0x00, 0x00,
// compressed data
0x63, 0x60, 0x18, 0x05, 0xa3, 0x60, 0xe8, 0x01, 0x01, 0xfc, 0xd2, 0xd6, 0x37, 0xf1, 0x2a, 0x60, 0x79, 0xff, 0x7f, 0x02, 0x3e, 0x79, 0xbf, 0xff, 0xff, 0x1f, 0xe2, 0xd7, 0xfe, 0xff, 0x00, 0x7e, 0xed, 0xff, 0x0c, 0xf0, 0x68, 0xff, 0xff, 0xff, 0xff, 0x13, 0x02, 0xda, 0x1d, 0xf0, 0xdb, 0x3e, 0xb4, 0xb4, 0x33, 0xb5, 0xe1, 0xd7, 0x6e, 0xfb, 0x7f, 0x23, 0x5e, 0xdb, 0xf7, 0xff, 0xff, 0xad, 0x80, 0x47, 0x3b, 0xe3, 0xf9, 0xff, 0xff, 0x37, 0xe1, 0x73, 0x7c, 0xfe, 0x7f, 0xa8, 0x01, 0x38, 0x1c, 0xcf, 0x01, 0x8c, 0x90, 0x8d, 0xf8, 0xfc, 0xde, 0x0f, 0x34, 0x40, 0x00, 0x8f, 0xdf, 0x41, 0x06, 0x1c, 0xc4, 0x17, 0x74, 0x40, 0x03, 0xfe, 0x08, 0xe0, 0x09, 0x3a, 0xb0, 0x01, 0x76, 0x78, 0x42, 0x1e, 0x64, 0xc0, 0x7d, 0x3c, 0x21, 0x0f, 0x32, 0x00, 0x6f, 0xc4, 0xf5, 0xff, 0xc7, 0x9f, 0xea, 0x38, 0xf0, 0x6b, 0x07, 0x1b, 0x80, 0x2f, 0xde, 0x19, 0xd8, 0xf1, 0x6b, 0x67, 0x60, 0x88, 0xde, 0xcc, 0x30, 0x0a, 0x06, 0x1b, 0x00, 0x00,
};

View File

@ -1,12 +0,0 @@
static const uint8_t toi_icon_tools[] = {
/*
// magic
'T', 'O', 'I', 'g',
// width (16-bit), height (16-bit)
0x18, 0x00, 0x18, 0x00,
// compressed data length (32-bit)
0xd0, 0x00, 0x00, 0x00,
*/
// compressed data
0x5d, 0x90, 0x3d, 0x4e, 0x42, 0x51, 0x10, 0x85, 0xcf, 0x43, 0xe4, 0x4f, 0x62, 0xa8, 0x09, 0x21, 0x6f, 0x09, 0xd8, 0x58, 0x02, 0x15, 0xa5, 0xe0, 0x0a, 0x1e, 0x4b, 0xa0, 0xb3, 0x13, 0x5d, 0x81, 0xec, 0x00, 0xec, 0x6c, 0x4c, 0x64, 0x05, 0x10, 0x36, 0xf0, 0x96, 0x60, 0x41, 0x6d, 0x5e, 0xc1, 0x8f, 0x20, 0xf0, 0x3e, 0xe7, 0x5e, 0x2b, 0xb9, 0xc9, 0x9d, 0xf9, 0x72, 0xee, 0xcc, 0x99, 0xc9, 0x95, 0xfe, 0x9f, 0xb6, 0xdd, 0xdb, 0xb6, 0xc7, 0xe2, 0x4e, 0xaa, 0xb2, 0xf6, 0x1c, 0xf1, 0xa4, 0x19, 0x7d, 0x87, 0xc1, 0x90, 0x4d, 0x8e, 0x6f, 0x2f, 0x3f, 0xc2, 0x6b, 0x89, 0x0f, 0xa9, 0xa1, 0x02, 0x69, 0x47, 0x65, 0xd3, 0x2f, 0xd7, 0x56, 0x7d, 0x90, 0xae, 0xa0, 0x1f, 0x6d, 0x83, 0x84, 0x93, 0x94, 0x87, 0x1f, 0x56, 0x05, 0x30, 0x9b, 0x9a, 0x45, 0xe6, 0xd7, 0xbc, 0xc5, 0xfb, 0xfb, 0xd8, 0xf0, 0x14, 0xb6, 0x96, 0x2a, 0x92, 0x92, 0xbe, 0x7f, 0x3d, 0x2b, 0xea, 0x49, 0x09, 0xac, 0x9c, 0x7b, 0x37, 0x94, 0x5e, 0xc0, 0x6f, 0x53, 0x0f, 0x95, 0xf9, 0x84, 0x81, 0xe3, 0x5c, 0xa8, 0xa6, 0x35, 0xee, 0xfe, 0x36, 0xbe, 0x48, 0x38, 0xc2, 0xc8, 0xf3, 0x9d, 0x0d, 0x18, 0xbb, 0xe1, 0x52, 0x16, 0xf6, 0x2a, 0xc1, 0xc2, 0x35, 0xc3, 0x44, 0x8a, 0x4d, 0x90, 0x5a, 0xfe, 0xb9, 0xce, 0xd4, 0x62, 0x99, 0xb9, 0x33, 0xf0, 0xf5, 0xc1, 0x43, 0xc5, 0xa5, 0x9b, 0xb3, 0xff, 0xf8, 0x05,
};

View File

@ -1,12 +0,0 @@
static const uint8_t toi_icon_update[] = {
/*
// magic
'T', 'O', 'I', 'g',
// width (16-bit), height (16-bit)
0x18, 0x00, 0x18, 0x00,
// compressed data length (32-bit)
0xb1, 0x00, 0x00, 0x00,
*/
// compressed data
0x63, 0x60, 0x40, 0x03, 0x02, 0x70, 0x96, 0xfa, 0xb9, 0x77, 0x37, 0x1d, 0x20, 0x4c, 0xce, 0xff, 0x40, 0xf0, 0xdb, 0x00, 0xc4, 0x64, 0x3a, 0x0f, 0x62, 0xff, 0xff, 0x0a, 0x62, 0xcb, 0xfe, 0xff, 0xbf, 0x3d, 0x6d, 0xde, 0xff, 0xff, 0x01, 0x40, 0xf6, 0xfe, 0xff, 0x87, 0x19, 0x18, 0x18, 0xfb, 0xff, 0x3f, 0x62, 0x60, 0x60, 0xf9, 0xff, 0x1b, 0x24, 0xcb, 0xfa, 0xff, 0x27, 0x03, 0x03, 0xf7, 0xff, 0x87, 0x60, 0x13, 0xfa, 0xff, 0x0b, 0x30, 0xc8, 0xff, 0x6f, 0x00, 0xb3, 0xe5, 0xfe, 0x27, 0x30, 0xf8, 0xff, 0x07, 0x9b, 0x06, 0x94, 0x9f, 0xc0, 0x10, 0xff, 0x1f, 0x64, 0x29, 0xe3, 0x9e, 0x73, 0xff, 0xdf, 0x9c, 0x80, 0xb0, 0x81, 0x42, 0xff, 0xff, 0x3f, 0x82, 0xaa, 0x61, 0xfd, 0xff, 0xff, 0x9f, 0x82, 0xfe, 0xff, 0x02, 0xb0, 0xfa, 0xfc, 0xff, 0x5f, 0xe0, 0x66, 0xb2, 0x03, 0xcd, 0x81, 0xda, 0xc5, 0xc0, 0xd0, 0x01, 0x76, 0xc3, 0x66, 0xa0, 0x39, 0x2d, 0x50, 0x4b, 0xfe, 0x2f, 0x0b, 0x9b, 0x07, 0x31, 0x81, 0xe9, 0x3e, 0xd8, 0xcd, 0x17, 0xc1, 0x12, 0x92, 0x20, 0xe6, 0x1f, 0x88, 0xed, 0x0c, 0x16, 0xe7, 0xfe, 0xdd, 0x72, 0x80, 0x79, 0x98, 0x51, 0x90, 0x01, 0x03, 0x00, 0x00,
};

View File

@ -1,12 +1,10 @@
static const uint8_t toi_icon_wipe[] = {
/*
// magic
'T', 'O', 'I', 'g',
// width (16-bit), height (16-bit)
0x18, 0x00, 0x18, 0x00,
0x40, 0x00, 0x40, 0x00,
// compressed data length (32-bit)
0x97, 0x00, 0x00, 0x00,
*/
0x2e, 0x01, 0x00, 0x00,
// compressed data
0x45, 0xcf, 0xb1, 0x0d, 0xc2, 0x30, 0x10, 0x85, 0x61, 0xdb, 0x28, 0x82, 0x08, 0x21, 0xb9, 0xa5, 0xa3, 0xa2, 0x85, 0x0d, 0x60, 0x03, 0xd8, 0x00, 0xc4, 0x04, 0x8c, 0xc0, 0x06, 0x88, 0x92, 0x8a, 0x6c, 0xc0, 0x0a, 0x6c, 0x10, 0x36, 0xc8, 0x08, 0x69, 0x40, 0x20, 0x40, 0xfe, 0xb1, 0x9d, 0x4b, 0xfc, 0x1a, 0x7f, 0xb6, 0x4e, 0xe7, 0x3b, 0xa5, 0x42, 0x8c, 0x4a, 0x39, 0x27, 0xe6, 0xef, 0xe4, 0x4b, 0x72, 0x9f, 0x6f, 0xe7, 0x15, 0x4c, 0x84, 0xba, 0x82, 0x42, 0x3c, 0x00, 0x9e, 0xe2, 0x99, 0x77, 0x5b, 0x74, 0x0c, 0xbe, 0x35, 0xae, 0x82, 0x5f, 0x91, 0xbd, 0x40, 0x5c, 0x74, 0x16, 0xcd, 0xb2, 0xf9, 0x09, 0x57, 0xc3, 0x5e, 0x5a, 0x3e, 0x16, 0x70, 0x90, 0xf7, 0x22, 0x17, 0xfb, 0xfa, 0xb9, 0x91, 0x1a, 0x83, 0xb3, 0xaa, 0x66, 0x1d, 0x1b, 0x95, 0x58, 0x5d, 0xfb, 0x7b, 0xc8, 0x86, 0x6d, 0x86, 0x6c, 0x30, 0xe4, 0x3e, 0x6a, 0x67, 0xd0, 0xe5, 0xe7, 0xfa, 0xb3, 0x32, 0xe8, 0x18, 0x4e, 0xdd, 0x62, 0xd3, 0x5d, 0x3c, 0xfe,
0xed, 0xd2, 0x31, 0x4e, 0x02, 0x41, 0x14, 0x06, 0xe0, 0x07, 0x2a, 0x1a, 0x85, 0x95, 0xce, 0x92, 0x3d, 0x00, 0x09, 0x7a, 0x00, 0x83, 0xd1, 0x03, 0x58, 0x5a, 0xc2, 0x0d, 0xdc, 0xc4, 0xda, 0xe8, 0x11, 0xbc, 0x01, 0x54, 0xb6, 0x78, 0x02, 0x63, 0x67, 0x27, 0x7a, 0x02, 0xd6, 0xc6, 0x56, 0x22, 0x23, 0x1a, 0x82, 0x3c, 0xe6, 0xcd, 0x2c, 0x71, 0x92, 0xfd, 0x67, 0xa8, 0x49, 0xf8, 0x93, 0x9d, 0x6c, 0xf6, 0xcb, 0xce, 0xce, 0xbe, 0xf7, 0x88, 0xd6, 0x59, 0x9d, 0x1c, 0x2c, 0xf1, 0xda, 0x38, 0xec, 0x0d, 0xee, 0x06, 0xfd, 0x9c, 0x27, 0x41, 0xbf, 0x61, 0xbe, 0x0d, 0x79, 0x8f, 0x59, 0x1d, 0x05, 0xbc, 0xcf, 0x3c, 0x8d, 0x0e, 0xbd, 0x5c, 0x64, 0x9d, 0x0b, 0xe5, 0xd1, 0x98, 0x4a, 0xe2, 0x29, 0x7b, 0x36, 0xb8, 0xa2, 0xb2, 0xb8, 0xea, 0xbf, 0x61, 0xbf, 0xa7, 0x9a, 0xf8, 0x5f, 0xef, 0x17, 0xfb, 0xa3, 0x1c, 0x5f, 0xe7, 0xd3, 0xf3, 0x01, 0x3e, 0xe5, 0x2c, 0xaf, 0x88, 0x0b, 0xfc, 0xbc, 0x70, 0xf8, 0x07, 0x3b, 0x3c, 0x5b, 0x38, 0x2c, 0x72, 0x85, 0xff, 0x53, 0x05, 0xde, 0x74, 0x3c, 0x01, 0xde, 0x71, 0xfc, 0x09, 0x1d, 0xdf, 0xc9, 0x30, 0xcf, 0x25, 0xd7, 0xbf, 0xf2, 0x5e, 0x76, 0x1d, 0xfc, 0xe0, 0xbe, 0x95, 0x0f, 0xb3, 0x8e, 0xd1, 0xe8, 0x99, 0xa4, 0x2d, 0x59, 0x7f, 0xf2, 0xde, 0xca, 0x4a, 0xbb, 0x2b, 0xeb, 0x37, 0x1c, 0x3d, 0xc9, 0xc3, 0x86, 0xac, 0xa3, 0xbc, 0x5f, 0xca, 0xf3, 0x17, 0x3e, 0x31, 0x4d, 0x1c, 0xa2, 0xd1, 0xd6, 0x39, 0x9e, 0xd9, 0x1b, 0xd0, 0x40, 0x99, 0x8d, 0x49, 0x45, 0xd9, 0x9b, 0x04, 0xb7, 0x67, 0x14, 0xe9, 0xc2, 0x46, 0xb8, 0x3f, 0x52, 0xbf, 0xb4, 0x51, 0x35, 0x0e, 0x07, 0x6c, 0xc0, 0x7c, 0x77, 0x46, 0xc6, 0xdf, 0x09, 0xf7, 0xb7, 0x9d, 0x1d, 0x24, 0x46, 0xbe, 0x9d, 0x1d, 0xab, 0x89, 0xaa, 0x63, 0x2b, 0xd8, 0xb5, 0x85, 0x6a, 0x63, 0xdf, 0xb2, 0x65, 0x19, 0x28, 0xf2, 0xa4, 0x2e, 0x1b, 0x6f, 0x4e, 0x63, 0x9f, 0xd3, 0xb5, 0xbe, 0xf6, 0x12, 0x2f, 0x53, 0x41, 0xbf, 0x5a, 0xa4, 0x75, 0x56, 0x28, 0x73,
};

View File

@ -2,7 +2,6 @@
#include <sys/types.h>
#include "common.h"
#include "display.h"
#include "image.h"
#include "flash.h"
#include "mini_printf.h"
@ -12,105 +11,8 @@
#include "usb.h"
#include "version.h"
#include "icon_cross.h"
#include "icon_lock.h"
#include "icon_tick.h"
#include "icon_tools.h"
#include "icon_update.h"
#include "icon_wipe.h"
#include "bootui.h"
#include "messages.h"
#include "style.h"
#define ICON_TOOLS 0
#define ICON_UPDATE 1
#define ICON_WIPE 2
static void display_header(int icon, const char *text)
{
display_bar(0, 0, DISPLAY_RESX, 32, COLOR_BL_ORANGE);
switch (icon) {
case ICON_TOOLS :
display_icon(8, 4, 24, 24, toi_icon_tools, sizeof(toi_icon_tools), COLOR_BLACK, COLOR_BL_ORANGE);
break ;
case ICON_UPDATE:
display_icon(8, 4, 24, 24, toi_icon_update, sizeof(toi_icon_update), COLOR_BLACK, COLOR_BL_ORANGE);
break;
case ICON_WIPE:
display_icon(8, 4, 24, 24, toi_icon_wipe, sizeof(toi_icon_wipe), COLOR_BLACK, COLOR_BL_ORANGE);
break;
}
display_text(8 + 24 + 8, 23, text, -1, FONT_NORMAL, COLOR_BLACK, COLOR_BL_ORANGE, 0);
}
static void display_footer(const char *text, uint16_t color, int bottom)
{
display_bar(0, DISPLAY_RESY - bottom - 24, DISPLAY_RESX, bottom + 24, COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - bottom, text, -1, FONT_NORMAL, color, COLOR_BLACK, 0);
}
static void display_done(int restart)
{
if (restart == 0 || restart == 3) {
display_loader(1000, 0, COLOR_BL_GREEN, COLOR_BLACK, toi_icon_tick, sizeof(toi_icon_tick), COLOR_WHITE);
}
if (restart <= 3 && restart >= 1) {
char count_str[24];
mini_snprintf(count_str, sizeof(count_str), "Done! Restarting in %ds", restart);
display_footer(count_str, COLOR_BL_GREEN, 20);
} else {
display_footer("Done! Unplug the device", COLOR_BL_GREEN, 20);
}
}
static void display_error(void)
{
display_loader(1000, 0, COLOR_BL_RED, COLOR_BLACK, toi_icon_cross, sizeof(toi_icon_cross), COLOR_WHITE);
display_footer("Error! Unplug the device", COLOR_BL_RED, 20);
}
static void display_welcome(secbool firmware_present)
{
display_clear();
if (secfalse == firmware_present) {
display_icon((DISPLAY_RESX - 124) / 2, (DISPLAY_RESY - 40 - 180) / 2, 124, 180, toi_icon_lock, sizeof(toi_icon_lock), COLOR_WHITE, COLOR_BLACK);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 20, "Go to trezor.io/start", -1, FONT_NORMAL, COLOR_WHITE, COLOR_BLACK, 0);
}
if (sectrue == firmware_present) {
display_header(ICON_TOOLS, "TREZOR Bootloader");
// TODO: show info about installed firmware (vendor, version, etc.)
}
display_fade(0, BACKLIGHT_NORMAL, 1000);
}
#define VENDOR_IMAGE_RESX 120
#define VENDOR_IMAGE_RESY 120
static void display_vendor(const uint8_t *vimg, const char *vstr, uint32_t vstr_len, uint32_t fw_version, uint16_t background)
{
display_bar(0, 0, DISPLAY_RESX, DISPLAY_RESY, background);
if (memcmp(vimg, "TOIf", 4) != 0) {
return;
}
uint16_t w = *(uint16_t *)(vimg + 4);
uint16_t h = *(uint16_t *)(vimg + 6);
if (w != VENDOR_IMAGE_RESX || h != VENDOR_IMAGE_RESY) {
return;
}
uint32_t datalen = *(uint32_t *)(vimg + 8);
display_image((DISPLAY_RESX - w) / 2, 32, w, h, vimg + 12, datalen);
if (vstr && vstr_len) {
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 48, vstr, vstr_len, FONT_NORMAL, COLOR_WHITE, background, 0);
}
char ver_str[32];
mini_snprintf(ver_str, sizeof(ver_str), "%d.%d.%d.%d",
(int)(fw_version & 0xFF),
(int)((fw_version >> 8) & 0xFF),
(int)((fw_version >> 16) & 0xFF),
(int)((fw_version >> 24) & 0xFF)
);
display_text_center(DISPLAY_RESX / 2, DISPLAY_RESY - 25, ver_str, -1, FONT_NORMAL, COLOR_GRAY128, background, 0);
display_refresh();
}
const uint8_t BOOTLOADER_KEY_M = 2;
const uint8_t BOOTLOADER_KEY_N = 3;
@ -196,12 +98,10 @@ static void usb_init_all(void) {
usb_start();
}
static secbool bootloader_loop(secbool firmware_present)
static secbool bootloader_usb_loop(const vendor_header * const vhdr, const image_header * const hdr)
{
usb_init_all();
display_welcome(firmware_present);
uint8_t buf[USB_PACKET_SIZE];
for (;;) {
@ -221,53 +121,45 @@ static secbool bootloader_loop(secbool firmware_present)
}
switch (msg_id) {
case 0: // Initialize
process_msg_Initialize(USB_IFACE_NUM, msg_size, buf, firmware_present);
process_msg_Initialize(USB_IFACE_NUM, msg_size, buf, vhdr, hdr);
break;
case 1: // Ping
process_msg_Ping(USB_IFACE_NUM, msg_size, buf);
break;
case 5: // WipeDevice
display_fade(BACKLIGHT_NORMAL, 0, 100);
display_clear();
display_header(ICON_WIPE, "Wiping Device");
display_footer("Please wait ...", COLOR_WHITE, 20);
display_fade(0, BACKLIGHT_NORMAL, 100);
ui_screen_wipe();
r = process_msg_WipeDevice(USB_IFACE_NUM, msg_size, buf);
if (r < 0) { // error
display_error();
ui_screen_fail();
usb_stop();
usb_deinit();
return secfalse; // shutdown
} else { // success
display_done(0);
ui_screen_done(0);
usb_stop();
usb_deinit();
return secfalse; // shutdown
}
break;
case 6: // FirmwareErase
display_fade(BACKLIGHT_NORMAL, 0, 100);
display_clear();
display_header(ICON_UPDATE, "Updating Firmware");
display_footer("Please wait ...", COLOR_WHITE, 20);
display_fade(0, BACKLIGHT_NORMAL, 100);
ui_screen_install();
process_msg_FirmwareErase(USB_IFACE_NUM, msg_size, buf);
break;
case 7: // FirmwareUpload
r = process_msg_FirmwareUpload(USB_IFACE_NUM, msg_size, buf);
if (r < 0) { // error
display_error();
ui_screen_fail();
usb_stop();
usb_deinit();
return secfalse; // shutdown
} else
if (r == 0) { // last chunk received
display_done(3); hal_delay(1000);
display_done(2); hal_delay(1000);
display_done(1); hal_delay(1000);
ui_screen_done(3); hal_delay(1000);
ui_screen_done(2); hal_delay(1000);
ui_screen_done(1); hal_delay(1000);
usb_stop();
usb_deinit();
display_fade(BACKLIGHT_NORMAL, 0, 500);
ui_fadeout();
return sectrue; // jump to firmware
}
break;
@ -341,11 +233,21 @@ int main(void)
}
vendor_header vhdr;
image_header hdr;
secbool firmware_present;
// start the bootloader if user touched the screen or no firmware installed
secbool firmware_present = load_vendor_header_keys((const uint8_t *)FIRMWARE_START, &vhdr);
firmware_present = load_vendor_header_keys((const uint8_t *)FIRMWARE_START, &vhdr);
if (sectrue == firmware_present) {
firmware_present = load_image_header((const uint8_t *)(FIRMWARE_START + vhdr.hdrlen), FIRMWARE_IMAGE_MAGIC, FIRMWARE_IMAGE_MAXSIZE, vhdr.vsig_m, vhdr.vsig_n, vhdr.vpub, &hdr);
}
const vendor_header * const pvhdr = (sectrue == firmware_present) ? &vhdr : NULL;
const image_header * const phdr = (sectrue == firmware_present) ? &hdr : NULL;
if (touched || firmware_present != sectrue) {
if (bootloader_loop(firmware_present) != sectrue) {
ui_screen_info(pvhdr, phdr);
if (bootloader_usb_loop(pvhdr, phdr) != sectrue) {
return 1;
}
}
@ -358,8 +260,6 @@ int main(void)
check_vendor_keys_lock(&vhdr),
"unauthorized vendor keys");
image_header hdr;
ensure(
load_image_header((const uint8_t *)(FIRMWARE_START + vhdr.hdrlen), FIRMWARE_IMAGE_MAGIC, FIRMWARE_IMAGE_MAXSIZE, vhdr.vsig_m, vhdr.vsig_n, vhdr.vpub, &hdr),
"invalid firmware header");
@ -372,32 +272,21 @@ int main(void)
if ((vhdr.vtrust & VTRUST_ALL) != VTRUST_ALL) {
display_vendor(
vhdr.vimg,
((vhdr.vtrust & VTRUST_STRING) == 0) ? (const char *)vhdr.vstr : 0,
((vhdr.vtrust & VTRUST_STRING) == 0) ? vhdr.vstr_len : 0,
hdr.version,
((vhdr.vtrust & VTRUST_RED) == 0) ? COLOR_BL_RED : COLOR_BLACK
);
ui_screen_boot(&vhdr, &hdr);
display_fade(0, BACKLIGHT_NORMAL, 1000);
int start_delay = (vhdr.vtrust & VTRUST_WAIT) ^ VTRUST_WAIT;
while (start_delay > 0) {
char wait_str[16];
mini_snprintf(wait_str, sizeof(wait_str), "waiting for %ds", start_delay);
display_footer(wait_str, COLOR_GRAY64, 2);
int delay = (vhdr.vtrust & VTRUST_WAIT) ^ VTRUST_WAIT;
while (delay > 0) {
ui_screen_boot_wait(delay);
hal_delay(1000);
start_delay--;
delay--;
}
if ((vhdr.vtrust & VTRUST_CLICK) == 0) {
display_footer("click to continue ...", COLOR_GRAY64, 2);
ui_screen_boot_click();
touch_click();
}
display_fade(BACKLIGHT_NORMAL, 0, 500);
display_clear();
ui_fadeout();
}
jump_to(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE);

View File

@ -6,15 +6,14 @@
#include "messages.pb.h"
#include "common.h"
#include "display.h"
#include "flash.h"
#include "image.h"
#include "secbool.h"
#include "usb.h"
#include "version.h"
#include "bootui.h"
#include "messages.h"
#include "style.h"
#define MSG_HEADER1_LEN 9
#define MSG_HEADER2_LEN 1
@ -232,7 +231,7 @@ static secbool _recv_msg(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, con
#define MSG_RECV_CALLBACK(FIELD, CALLBACK) { msg_recv.FIELD.funcs.decode = &CALLBACK; }
#define MSG_RECV(TYPE) _recv_msg(iface_num, msg_size, buf, TYPE##_fields, &msg_recv)
void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, secbool firmware_present)
void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, const vendor_header * const vhdr, const image_header * const hdr)
{
MSG_RECV_INIT(Initialize);
MSG_RECV(Initialize);
@ -243,7 +242,7 @@ void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf,
MSG_SEND_ASSIGN_VALUE(minor_version, VERSION_MINOR);
MSG_SEND_ASSIGN_VALUE(patch_version, VERSION_PATCH);
MSG_SEND_ASSIGN_VALUE(bootloader_mode, true);
MSG_SEND_ASSIGN_VALUE(firmware_present, firmware_present);
MSG_SEND_ASSIGN_VALUE(firmware_present, (vhdr && hdr));
MSG_SEND_ASSIGN_STRING(model, "T");
// TODO: pass info about installed firmware (vendor, version, etc.)
MSG_SEND(Features);
@ -261,11 +260,6 @@ void process_msg_Ping(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
static uint32_t firmware_remaining, firmware_block, chunk_requested;
static void progress_erase(int pos, int len)
{
display_loader(250 * pos / len, 0, COLOR_BL_BLUE, COLOR_BLACK, 0, 0, 0);
}
void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
{
firmware_remaining = 0;
@ -278,7 +272,7 @@ void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
firmware_remaining = msg_recv.has_length ? msg_recv.length : 0;
if ((firmware_remaining > 0) && ((firmware_remaining % 4) == 0) && (firmware_remaining <= (FIRMWARE_SECTORS_COUNT * IMAGE_CHUNK_SIZE))) {
// erase flash
if (sectrue != flash_erase_sectors(firmware_sectors, FIRMWARE_SECTORS_COUNT, progress_erase)) {
if (sectrue != flash_erase_sectors(firmware_sectors, FIRMWARE_SECTORS_COUNT, ui_screen_install_progress_erase)) {
MSG_SEND_INIT(Failure);
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
MSG_SEND_ASSIGN_STRING(message, "Could not erase flash");
@ -321,7 +315,7 @@ static bool _read_payload(pb_istream_t *stream, const pb_field_t *field, void **
while (stream->bytes_left) {
// update loader
display_loader(250 + 750 * (firmware_block * IMAGE_CHUNK_SIZE + chunk_written) / (firmware_block * IMAGE_CHUNK_SIZE + firmware_remaining), 0, COLOR_BL_BLUE, COLOR_BLACK, 0, 0, 0);
ui_screen_install_progress_upload(250 + 750 * (firmware_block * IMAGE_CHUNK_SIZE + chunk_written) / (firmware_block * IMAGE_CHUNK_SIZE + firmware_remaining));
// read data
if (!pb_read(stream, (pb_byte_t *)(chunk_buffer + chunk_written), (stream->bytes_left > BUFSIZE) ? BUFSIZE : stream->bytes_left)) {
chunk_size = 0;
@ -461,11 +455,6 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu
return (int)firmware_remaining;
}
static void progress_wipe(int pos, int len)
{
display_loader(1000 * pos / len, 0, COLOR_BL_BLUE, COLOR_BLACK, 0, 0, 0);
}
int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
{
const uint8_t sectors[] = {
@ -490,7 +479,7 @@ int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf)
22,
FLASH_SECTOR_FIRMWARE_EXTRA_END,
};
if (sectrue != flash_erase_sectors(sectors, sizeof(sectors), progress_wipe)) {
if (sectrue != flash_erase_sectors(sectors, sizeof(sectors), ui_screen_wipe_progress)) {
MSG_SEND_INIT(Failure);
MSG_SEND_ASSIGN_VALUE(code, FailureType_Failure_ProcessError);
MSG_SEND_ASSIGN_STRING(message, "Could not erase flash");

View File

@ -2,6 +2,7 @@
#define __MESSAGES_H__
#include <stdint.h>
#include "image.h"
#include "secbool.h"
#define USE_WEBUSB 0
@ -15,7 +16,7 @@ extern const uint8_t firmware_sectors[FIRMWARE_SECTORS_COUNT];
secbool msg_parse_header(const uint8_t *buf, uint16_t *msg_id, uint32_t *msg_size);
void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, secbool firmware_present);
void process_msg_Initialize(uint8_t iface_num, uint32_t msg_size, uint8_t *buf, const vendor_header * const vhdr, const image_header * const hdr);
void process_msg_Ping(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
void process_msg_FirmwareErase(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);
int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *buf);

View File

@ -1,11 +0,0 @@
#ifndef __STYLE_H__
#define __STYLE_H__
#define BACKLIGHT_NORMAL 150
#define COLOR_BL_RED RGB16(0xE4, 0x57, 0x2E)
#define COLOR_BL_GREEN RGB16(0x4C, 0xC1, 0x48)
#define COLOR_BL_BLUE RGB16(0x21, 0x96, 0xF3)
#define COLOR_BL_ORANGE RGB16(0xFF, 0x98, 0x00)
#endif

View File

@ -39,19 +39,8 @@
#define RGB16(R, G, B) ((R & 0xF8) << 8) | ((G & 0xFC) << 3) | ((B & 0xF8) >> 3)
#define COLOR_WHITE RGB16(0xFF, 0xFF, 0xFF)
#define COLOR_GRAY128 RGB16(0x7F, 0x7F, 0x7F)
#define COLOR_GRAY64 RGB16(0x3F, 0x3F, 0x3F)
#define COLOR_BLACK RGB16(0x00, 0x00, 0x00)
#define COLOR_RED RGB16(0xFF, 0x00, 0x00)
#define COLOR_RED128 RGB16(0x7F, 0x00, 0x00)
#define COLOR_GREEN RGB16(0x00, 0xFF, 0x00)
#define COLOR_GREEN128 RGB16(0x00, 0x7F, 0x00)
#define COLOR_BLUE RGB16(0x00, 0x00, 0xFF)
#define COLOR_BLUE128 RGB16(0x00, 0x00, 0x7F)
// provided by port
void display_init(void);

View File

@ -6,10 +6,12 @@
void shutdown(void);
#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func) {
display_orientation(0);
display_backlight(255);
display_print_color(COLOR_WHITE, COLOR_RED128);
display_print_color(COLOR_WHITE, COLOR_FATAL_ERROR);
display_printf("\nFATAL ERROR:\n");
if (expr) {
display_printf("expr: %s\n", expr);

View File

@ -11,11 +11,13 @@ void __shutdown(void)
exit(3);
}
#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)
void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func)
{
display_orientation(0);
display_backlight(255);
display_print_color(COLOR_WHITE, COLOR_RED128);
display_print_color(COLOR_WHITE, COLOR_FATAL_ERROR);
display_printf("\nFATAL ERROR:\n");
printf("\nFATAL ERROR:\n");
if (expr) {

View File

@ -1,6 +1,7 @@
#ifndef __TREZORUNIX_COMMON_H__
#define __TREZORUNIX_COMMON_H__
#include <stdint.h>
#include "secbool.h"
void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func);