1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-24 23:38:09 +00:00

feat(core): show blue dot when USB data not connected

This commit is contained in:
Ondrej Mikle 2022-06-28 16:55:37 +02:00 committed by matejcik
parent 005e4203a7
commit a0287698d5
11 changed files with 81 additions and 1 deletions

View File

@ -0,0 +1 @@
Show blue dot when USB data pins are not connected

View File

@ -24,11 +24,14 @@
#include "display.h" #include "display.h"
#include "embed/extmod/trezorobj.h" #include "embed/extmod/trezorobj.h"
#define USB_DATA_IFACE (253)
#define BUTTON_IFACE (254) #define BUTTON_IFACE (254)
#define TOUCH_IFACE (255) #define TOUCH_IFACE (255)
#define POLL_READ (0x0000) #define POLL_READ (0x0000)
#define POLL_WRITE (0x0100) #define POLL_WRITE (0x0100)
extern bool usb_connected_previously;
/// package: trezorio.__init__ /// package: trezorio.__init__
/// def poll(ifaces: Iterable[int], list_ref: list, timeout_ms: int) -> bool: /// def poll(ifaces: Iterable[int], list_ref: list, timeout_ms: int) -> bool:
@ -114,6 +117,14 @@ STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref,
ret->items[1] = MP_OBJ_FROM_PTR(tuple); ret->items[1] = MP_OBJ_FROM_PTR(tuple);
return mp_const_true; return mp_const_true;
} }
} else if (iface == USB_DATA_IFACE) {
bool usb_connected = usb_configured() == sectrue ? true : false;
if (usb_connected != usb_connected_previously) {
usb_connected_previously = usb_connected;
ret->items[0] = MP_OBJ_NEW_SMALL_INT(i);
ret->items[1] = usb_connected ? mp_const_true : mp_const_false;
return mp_const_true;
}
} }
#elif defined TREZOR_MODEL_1 || defined TREZOR_MODEL_R #elif defined TREZOR_MODEL_1 || defined TREZOR_MODEL_R
else if (iface == BUTTON_IFACE) { else if (iface == BUTTON_IFACE) {

View File

@ -31,6 +31,9 @@
#include "touch.h" #include "touch.h"
#include "usb.h" #include "usb.h"
// Whether USB data pins were connected on last check (USB configured)
__attribute__((unused)) static bool usb_connected_previously = false;
#define CHECK_PARAM_RANGE(value, minimum, maximum) \ #define CHECK_PARAM_RANGE(value, minimum, maximum) \
if (value < minimum || value > maximum) { \ if (value < minimum || value > maximum) { \
mp_raise_ValueError(#value " is out of range"); \ mp_raise_ValueError(#value " is out of range"); \
@ -67,6 +70,8 @@
/// BUTTON_LEFT: int # button number of left button /// BUTTON_LEFT: int # button number of left button
/// BUTTON_RIGHT: int # button number of right button /// BUTTON_RIGHT: int # button number of right button
/// USB_CHECK: int # interface id for check of USB data connection
/// WireInterface = Union[HID, WebUSB] /// WireInterface = Union[HID, WebUSB]
STATIC const mp_rom_map_elem_t mp_module_trezorio_globals_table[] = { STATIC const mp_rom_map_elem_t mp_module_trezorio_globals_table[] = {
@ -81,6 +86,8 @@ STATIC const mp_rom_map_elem_t mp_module_trezorio_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR_TOUCH_START), MP_ROM_INT((TOUCH_START >> 24) & 0xFFU)}, {MP_ROM_QSTR(MP_QSTR_TOUCH_START), MP_ROM_INT((TOUCH_START >> 24) & 0xFFU)},
{MP_ROM_QSTR(MP_QSTR_TOUCH_MOVE), MP_ROM_INT((TOUCH_MOVE >> 24) & 0xFFU)}, {MP_ROM_QSTR(MP_QSTR_TOUCH_MOVE), MP_ROM_INT((TOUCH_MOVE >> 24) & 0xFFU)},
{MP_ROM_QSTR(MP_QSTR_TOUCH_END), MP_ROM_INT((TOUCH_END >> 24) & 0xFFU)}, {MP_ROM_QSTR(MP_QSTR_TOUCH_END), MP_ROM_INT((TOUCH_END >> 24) & 0xFFU)},
{MP_ROM_QSTR(MP_QSTR_USB_CHECK), MP_ROM_INT(USB_DATA_IFACE)},
#elif defined TREZOR_MODEL_1 || defined TREZOR_MODEL_R #elif defined TREZOR_MODEL_1 || defined TREZOR_MODEL_R
{MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_INT(BUTTON_IFACE)}, {MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_INT(BUTTON_IFACE)},
{MP_ROM_QSTR(MP_QSTR_BUTTON_PRESSED), {MP_ROM_QSTR(MP_QSTR_BUTTON_PRESSED),

View File

@ -34,6 +34,7 @@
#include "blake2s.h" #include "blake2s.h"
#include "common.h" #include "common.h"
#include "flash.h" #include "flash.h"
#include "usb.h"
#ifndef TREZOR_EMULATOR #ifndef TREZOR_EMULATOR
#include "image.h" #include "image.h"
@ -221,6 +222,17 @@ STATIC mp_obj_t mod_trezorutils_reboot_to_bootloader() {
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorutils_reboot_to_bootloader_obj, STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorutils_reboot_to_bootloader_obj,
mod_trezorutils_reboot_to_bootloader); mod_trezorutils_reboot_to_bootloader);
/// def usb_data_connected() -> bool:
/// """
/// Returns whether USB has been enumerated/configured
/// (and is not just connected by cable without data pins)
/// """
STATIC mp_obj_t mod_trezorutils_usb_data_connected() {
return usb_configured() == sectrue ? mp_const_true : mp_const_false;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorutils_usb_data_connected_obj,
mod_trezorutils_usb_data_connected);
STATIC mp_obj_str_t mod_trezorutils_revision_obj = { STATIC mp_obj_str_t mod_trezorutils_revision_obj = {
{&mp_type_bytes}, 0, sizeof(SCM_REVISION) - 1, (const byte *)SCM_REVISION}; {&mp_type_bytes}, 0, sizeof(SCM_REVISION) - 1, (const byte *)SCM_REVISION};
@ -243,6 +255,8 @@ STATIC const mp_rom_map_elem_t mp_module_trezorutils_globals_table[] = {
MP_ROM_PTR(&mod_trezorutils_firmware_vendor_obj)}, MP_ROM_PTR(&mod_trezorutils_firmware_vendor_obj)},
{MP_ROM_QSTR(MP_QSTR_reboot_to_bootloader), {MP_ROM_QSTR(MP_QSTR_reboot_to_bootloader),
MP_ROM_PTR(&mod_trezorutils_reboot_to_bootloader_obj)}, MP_ROM_PTR(&mod_trezorutils_reboot_to_bootloader_obj)},
{MP_ROM_QSTR(MP_QSTR_usb_data_connected),
MP_ROM_PTR(&mod_trezorutils_usb_data_connected_obj)},
// various built-in constants // various built-in constants
{MP_ROM_QSTR(MP_QSTR_SCM_REVISION), {MP_ROM_QSTR(MP_QSTR_SCM_REVISION),
MP_ROM_PTR(&mod_trezorutils_revision_obj)}, MP_ROM_PTR(&mod_trezorutils_revision_obj)},

View File

@ -152,6 +152,15 @@ void usb_start(void) { USBD_Start(&usb_dev_handle); }
void usb_stop(void) { USBD_Stop(&usb_dev_handle); } void usb_stop(void) { USBD_Stop(&usb_dev_handle); }
secbool usb_configured(void) {
USBD_HandleTypeDef *pdev = &usb_dev_handle;
if (pdev->dev_state == USBD_STATE_CONFIGURED) {
return sectrue;
}
return secfalse;
}
/* /*
* Utility functions for USB interfaces * Utility functions for USB interfaces
*/ */

View File

@ -143,5 +143,6 @@ void usb_init(const usb_dev_info_t *dev_info);
void usb_deinit(void); void usb_deinit(void);
void usb_start(void); void usb_start(void);
void usb_stop(void); void usb_stop(void);
secbool usb_configured(void);
#endif #endif

View File

@ -25,6 +25,7 @@
#include <sys/poll.h> #include <sys/poll.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <time.h> #include <time.h>
#include <unistd.h>
#include "touch.h" #include "touch.h"
#include "usb.h" #include "usb.h"
@ -249,3 +250,11 @@ int usb_webusb_write(uint8_t iface_num, const uint8_t *buf, uint32_t len) {
void pendsv_kbd_intr(void) {} void pendsv_kbd_intr(void) {}
void mp_hal_set_vcp_iface(int iface_num) {} void mp_hal_set_vcp_iface(int iface_num) {}
secbool usb_configured(void) {
if (access("/var/tmp/trezor.usb_data_disconnected", F_OK) == 0) {
return secfalse;
}
return sectrue;
}

View File

@ -202,4 +202,5 @@ BUTTON_PRESSED: int # button down event
BUTTON_RELEASED: int # button up event BUTTON_RELEASED: int # button up event
BUTTON_LEFT: int # button number of left button BUTTON_LEFT: int # button number of left button
BUTTON_RIGHT: int # button number of right button BUTTON_RIGHT: int # button number of right button
USB_CHECK: int # interface id for check of USB data connection
WireInterface = Union[HID, WebUSB] WireInterface = Union[HID, WebUSB]

View File

@ -65,6 +65,14 @@ def reboot_to_bootloader() -> None:
""" """
Reboots to bootloader. Reboots to bootloader.
""" """
# extmod/modtrezorutils/modtrezorutils.c
def usb_data_connected() -> bool:
"""
Returns whether USB has been enumerated/configured
(and is not just connected by cable without data pins)
"""
SCM_REVISION: bytes SCM_REVISION: bytes
VERSION_MAJOR: int VERSION_MAJOR: int
VERSION_MINOR: int VERSION_MINOR: int

View File

@ -1,10 +1,11 @@
import utime import utime
from micropython import const from micropython import const
from typing import Tuple
import storage import storage
import storage.cache import storage.cache
import storage.device import storage.device
from trezor import config, ui, utils from trezor import config, io, loop, ui, utils
from trezor.ui.loader import Loader, LoaderNeutral from trezor.ui.loader import Loader, LoaderNeutral
from apps.base import lock_device from apps.base import lock_device
@ -25,6 +26,7 @@ class Homescreen(HomescreenBase):
def __init__(self) -> None: def __init__(self) -> None:
super().__init__() super().__init__()
self.is_connected = False
if not storage.device.is_initialized(): if not storage.device.is_initialized():
self.label = "Go to trezor.io/start" self.label = "Go to trezor.io/start"
@ -36,6 +38,17 @@ class Homescreen(HomescreenBase):
) )
self.touch_ms: int | None = None self.touch_ms: int | None = None
def create_tasks(self) -> Tuple[loop.AwaitableTask, ...]:
return super().create_tasks() + (self.usb_checker_task(),)
async def usb_checker_task(self) -> None:
usbcheck = loop.wait(io.USB_CHECK)
while True:
is_connected = await usbcheck
if is_connected != self.is_connected:
self.is_connected = is_connected
self.set_repaint(True)
def do_render(self) -> None: def do_render(self) -> None:
# warning bar on top # warning bar on top
if storage.device.is_initialized() and storage.device.no_backup(): if storage.device.is_initialized() and storage.device.no_backup():
@ -54,6 +67,9 @@ class Homescreen(HomescreenBase):
# homescreen with shifted avatar and text on bottom # homescreen with shifted avatar and text on bottom
# Differs for each model # Differs for each model
if not utils.usb_data_connected():
ui.display.bar(0, 0, 8, 8, ui.BLUE)
# TODO: support homescreen avatar change for R and 1 # TODO: support homescreen avatar change for R and 1
if utils.MODEL in ("T",): if utils.MODEL in ("T",):
ui.display.avatar(48, 48 - 10, self.get_image(), ui.WHITE, ui.BLACK) ui.display.avatar(48, 48 - 10, self.get_image(), ui.WHITE, ui.BLACK)
@ -69,6 +85,8 @@ class Homescreen(HomescreenBase):
ui.WIDTH // 2, label_heights[utils.MODEL], self.label, ui.BOLD, ui.FG, ui.BG ui.WIDTH // 2, label_heights[utils.MODEL], self.label, ui.BOLD, ui.FG, ui.BG
) )
ui.refresh()
def on_touch_start(self, _x: int, _y: int) -> None: def on_touch_start(self, _x: int, _y: int) -> None:
if self.loader.start_ms is not None: if self.loader.start_ms is not None:
self.loader.start() self.loader.start()

View File

@ -14,6 +14,7 @@ from trezorutils import ( # noqa: F401
halt, halt,
memcpy, memcpy,
reboot_to_bootloader, reboot_to_bootloader,
usb_data_connected,
) )
from typing import TYPE_CHECKING from typing import TYPE_CHECKING