From 50c8811af970754a47452efec1b4df558c8ba491 Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Wed, 18 Nov 2015 19:52:16 +0100 Subject: [PATCH] double sized font for reset device --- firmware/reset.c | 15 ++++++---- oled.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++-- oled.h | 1 + 3 files changed, 86 insertions(+), 7 deletions(-) diff --git a/firmware/reset.c b/firmware/reset.c index 7e75f96ee6..8ec4c1bc7b 100644 --- a/firmware/reset.c +++ b/firmware/reset.c @@ -77,7 +77,7 @@ void reset_init(bool display_random, uint32_t _strength, bool passphrase_protect awaiting_entropy = true; } -static char current_word[10]; +static char current_word[10], current_word_display[11]; void reset_entropy(const uint8_t *ext_entropy, uint32_t len) { @@ -122,17 +122,22 @@ void reset_entropy(const uint8_t *ext_entropy, uint32_t len) if (word_pos == 3 || word_pos == 23) { desc[2] = 'r'; desc[3] = 'd'; } + current_word_display[0] = 0x01; + for (j = 0; current_word[j]; j++) { + current_word_display[j + 1] = current_word[j] + 'A' - 'a'; + } + current_word_display[j + 1] = 0; if (word_pos == (int)strength/32*3) { // last word if (pass == 1) { - layoutDialogSwipe(DIALOG_ICON_INFO, NULL, "Finish", NULL, "Please check the seed", NULL, (word_pos < 10 ? desc + 1 : desc), NULL, current_word, NULL); + layoutDialogSwipe(DIALOG_ICON_INFO, NULL, "Finish", NULL, "Please check the seed", NULL, (word_pos < 10 ? desc + 1 : desc), current_word_display, NULL, NULL); } else { - layoutDialogSwipe(DIALOG_ICON_INFO, NULL, "Again", NULL, "Write down the seed", NULL, (word_pos < 10 ? desc + 1 : desc), NULL, current_word, NULL); + layoutDialogSwipe(DIALOG_ICON_INFO, NULL, "Again", NULL, "Write down the seed", NULL, (word_pos < 10 ? desc + 1 : desc), current_word_display, NULL, NULL); } } else { if (pass == 1) { - layoutDialogSwipe(DIALOG_ICON_INFO, NULL, "Next", NULL, "Please check the seed", NULL, (word_pos < 10 ? desc + 1 : desc), NULL, current_word, NULL); + layoutDialogSwipe(DIALOG_ICON_INFO, NULL, "Next", NULL, "Please check the seed", NULL, (word_pos < 10 ? desc + 1 : desc), current_word_display, NULL, NULL); } else { - layoutDialogSwipe(DIALOG_ICON_INFO, NULL, "Next", NULL, "Write down the seed", NULL, (word_pos < 10 ? desc + 1 : desc), NULL, current_word, NULL); + layoutDialogSwipe(DIALOG_ICON_INFO, NULL, "Next", NULL, "Write down the seed", NULL, (word_pos < 10 ? desc + 1 : desc), current_word_display, NULL, NULL); } } if (!protectButton(ButtonRequestType_ButtonRequest_ConfirmWord, true)) { diff --git a/oled.c b/oled.c index 6b3ef56743..3f569e1e74 100644 --- a/oled.c +++ b/oled.c @@ -55,6 +55,20 @@ #define OLED_RST_PORT GPIOB #define OLED_RST_PIN GPIO1 // PB1 | Reset display +/* TREZOR has a display of size OLED_WIDTH x OLED_HEIGHT (128x64). + * The contents of this display are buffered in _oledbuffer. This is + * an array of OLED_WIDTH * OLED_HEIGHT/8 bytes. At byte y*OLED_WIDTH + x + * it stores the column of pixels from (x,8y) to (x,8y+7); the LSB stores + * the top most pixel. The pixel (0,0) is the top left corner of the + * display. + */ + +/* Macros to manipulate a single pixel in _oledbuffer: + * OLED_BUFSET(X,Y) sets pixel X,Y (white) + * OLED_BUFCLR(X,Y) clears pixel X,Y (black) + * OLED_BUFTGL(X,Y) toggles pixel X,Y (inverts it) + */ + #define OLED_BUFSET(X,Y) _oledbuffer[OLED_BUFSIZE - 1 - (X) - ((Y)/8)*OLED_WIDTH] |= (1 << (7 - (Y)%8)) #define OLED_BUFCLR(X,Y) _oledbuffer[OLED_BUFSIZE - 1 - (X) - ((Y)/8)*OLED_WIDTH] &= ~(1 << (7 - (Y)%8)) #define OLED_BUFTGL(X,Y) _oledbuffer[OLED_BUFSIZE - 1 - (X) - ((Y)/8)*OLED_WIDTH] ^= (1 << (7 - (Y)%8)) @@ -62,6 +76,9 @@ static uint8_t _oledbuffer[OLED_BUFSIZE]; static char is_debug_mode = 0; +/* + * Send a block of data via the SPI bus. + */ inline void SPISend(uint32_t base, uint8_t *data, int len) { int i; @@ -72,6 +89,9 @@ inline void SPISend(uint32_t base, uint8_t *data, int len) delay(800); } +/* + * Initialize the display. + */ void oledInit() { static uint8_t s[25] = { @@ -121,11 +141,20 @@ void oledInit() oledRefresh(); } +/* + * Clears the display buffer (sets all pixels to black) + */ void oledClear() { memset(_oledbuffer, 0, sizeof(_oledbuffer)); } +/* + * Refresh the display. This copies the buffer to the display to show the + * contents. This must be called after every operation to the buffer to + * make the change visible. All other operations only change the buffer + * not the content of the display. + */ void oledRefresh() { static uint8_t s[3] = {OLED_SETLOWCOLUMN | 0x00, OLED_SETHIGHCOLUMN | 0x00, OLED_SETSTARTLINE | 0x00}; @@ -207,6 +236,26 @@ void oledDrawChar(int x, int y, char c) } } +void oledDrawZoomedChar(int x, int y, int z, char c) +{ + int char_width; + const uint8_t *char_data; + + if ((x >= OLED_WIDTH) || (y >= OLED_HEIGHT)) return; + + char_width = fontCharWidth(c); + char_data = fontCharData(c); + + int xoffset, yoffset; + for (xoffset = 0; xoffset < char_width; xoffset++) { + for (yoffset = 0; yoffset < FONT_HEIGHT; yoffset++) { + if (char_data[xoffset] & (1 << (FONT_HEIGHT - 1 - yoffset))) { + oledBox(x + xoffset * z, y + yoffset * z, x + xoffset * z + z - 1, y + yoffset * z + z - 1, 1); + } + } + } +} + char oledConvertChar(const char c) { uint8_t a = c; if (a < 0x80) return c; @@ -233,13 +282,23 @@ int oledStringWidth(const char *text) { void oledDrawString(int x, int y, const char* text) { if (!text) return; + int size = 1; + if (*text == 0x01) { // double size + text++; + size = 2; + } int l = 0; char c; for (; *text; text++) { c = oledConvertChar(*text); if (c) { - oledDrawChar(x + l, y, c); - l += fontCharWidth(c) + 1; + if (size > 1) { + oledDrawZoomedChar(x + l, y, size, c); + l += fontCharWidth(c) * size + 1; + } else { + oledDrawChar(x + l, y, c); + l += fontCharWidth(c) + 1; + } } } } @@ -283,6 +342,9 @@ void oledInvert(int x1, int y1, int x2, int y2) } } +/* + * Draw a filled rectangle. + */ void oledBox(int x1, int y1, int x2, int y2, char val) { int x, y; @@ -300,6 +362,9 @@ void oledHLine(int y) { } } +/* + * Draw a rectangle frame. + */ void oledFrame(int x1, int y1, int x2, int y2) { int x, y; @@ -313,6 +378,10 @@ void oledFrame(int x1, int y1, int x2, int y2) } } +/* + * Animates the display, swiping the current contents out to the left. + * This clears the display. + */ void oledSwipeLeft(void) { int i, j, k; @@ -333,6 +402,10 @@ void oledSwipeLeft(void) } } +/* + * Animates the display, swiping the current contents out to the right. + * This clears the display. + */ void oledSwipeRight(void) { int i, j, k; diff --git a/oled.h b/oled.h index c3b8db2c69..cbabb36ac7 100644 --- a/oled.h +++ b/oled.h @@ -39,6 +39,7 @@ const uint8_t *oledGetBuffer(void); void oledDrawPixel(int x, int y); void oledClearPixel(int x, int y); void oledDrawChar(int x, int y, char c); +void oledDrawZoomedChar(int x, int y, int z, char c); int oledStringWidth(const char *text); void oledDrawString(int x, int y, const char* text); void oledDrawStringCenter(int y, const char* text);