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:
parent
005e4203a7
commit
a0287698d5
1
core/.changelog.d/2366.added
Normal file
1
core/.changelog.d/2366.added
Normal file
@ -0,0 +1 @@
|
|||||||
|
Show blue dot when USB data pins are not connected
|
@ -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) {
|
||||||
|
@ -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),
|
||||||
|
@ -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)},
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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]
|
||||||
|
@ -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
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user