mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-04-15 23:05:45 +00:00
feat(core): introduce new polling in coreapp event loop
[no changelog]
This commit is contained in:
parent
7994a0b93b
commit
7dcdb54262
@ -34,16 +34,6 @@
|
||||
|
||||
#include "embed/upymod/trezorobj.h"
|
||||
|
||||
#ifdef TREZOR_EMULATOR
|
||||
#include "SDL.h"
|
||||
#endif
|
||||
|
||||
#define BLE_EVENT_IFACE (252)
|
||||
#define USB_EVENT_IFACE (253)
|
||||
#define BUTTON_IFACE (254)
|
||||
#define TOUCH_IFACE (255)
|
||||
#define USB_RW_IFACE_MAX (15) // 0-15 reserved for USB
|
||||
#define BLE_IFACE (16)
|
||||
#define POLL_READ (0x0000)
|
||||
#define POLL_WRITE (0x0100)
|
||||
|
||||
@ -98,6 +88,25 @@ STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref,
|
||||
mp_raise_TypeError("invalid list_ref");
|
||||
}
|
||||
|
||||
sysevents_t awaited = {0};
|
||||
|
||||
mp_obj_iter_buf_t iterbuf = {0};
|
||||
|
||||
mp_obj_t iter = mp_getiter(ifaces, &iterbuf);
|
||||
mp_obj_t item = 0;
|
||||
while ((item = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
|
||||
const mp_uint_t i = trezor_obj_get_uint(item);
|
||||
const mp_uint_t iface = i & 0x00FF;
|
||||
const mp_uint_t mode = i & 0xFF00;
|
||||
|
||||
if (mode & POLL_WRITE) {
|
||||
awaited.write_ready |= (1 << iface);
|
||||
|
||||
} else {
|
||||
awaited.read_ready |= (1 << iface);
|
||||
}
|
||||
}
|
||||
|
||||
// The value `timeout_ms` can be negative in a minority of cases, indicating a
|
||||
// deadline overrun. This is not a problem because we use the `timeout` only
|
||||
// to calculate a `deadline`, and having deadline in the past works fine
|
||||
@ -106,157 +115,118 @@ STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref,
|
||||
// just coerce it to an uint. Deliberately assigning *get_int* to *uint_t*
|
||||
// will give us C's wrapping unsigned overflow behavior, and the `deadline`
|
||||
// result will come out correct.
|
||||
const mp_uint_t timeout = trezor_obj_get_int(timeout_ms);
|
||||
const mp_uint_t deadline = mp_hal_ticks_ms() + timeout;
|
||||
mp_obj_iter_buf_t iterbuf = {0};
|
||||
const mp_uint_t timeout = MAX(trezor_obj_get_int(timeout_ms), 0);
|
||||
sysevents_t signalled = {0};
|
||||
|
||||
{
|
||||
// This is just a dummy call to `sysevent_poll` to ensure cooperative
|
||||
// multitasking works. Event polling is still performed in the loop below
|
||||
// but will be replaced in the future.
|
||||
sysevents_t awaited = {0};
|
||||
sysevents_t signalled = {0};
|
||||
sysevent_poll(&awaited, &signalled, 0);
|
||||
sysevents_poll(&awaited, &signalled, timeout);
|
||||
|
||||
#ifdef USE_TOUCH
|
||||
if (signalled.read_ready & (1 << SYSHANDLE_TOUCH)) {
|
||||
const uint32_t evt = touch_get_event();
|
||||
if (evt != 0) {
|
||||
// ignore TOUCH_MOVE events if they are too frequent
|
||||
if ((evt & TOUCH_MOVE) == 0 ||
|
||||
(hal_ticks_ms() - last_touch_sample_time > 10)) {
|
||||
last_touch_sample_time = hal_ticks_ms();
|
||||
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));
|
||||
const uint32_t etype = (evt >> 24) & 0xFFU; // event type
|
||||
const uint32_t ex = (evt >> 12) & 0xFFFU; // x position
|
||||
const uint32_t ey = evt & 0xFFFU; // y position
|
||||
uint32_t exr; // rotated x position
|
||||
uint32_t eyr; // rotated y position
|
||||
switch (display_get_orientation()) {
|
||||
case 90:
|
||||
exr = ey;
|
||||
eyr = DISPLAY_RESX - ex;
|
||||
break;
|
||||
case 180:
|
||||
exr = DISPLAY_RESX - ex;
|
||||
eyr = DISPLAY_RESY - ey;
|
||||
break;
|
||||
case 270:
|
||||
exr = DISPLAY_RESY - ey;
|
||||
eyr = ex;
|
||||
break;
|
||||
default:
|
||||
exr = ex;
|
||||
eyr = ey;
|
||||
break;
|
||||
}
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(etype);
|
||||
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(exr);
|
||||
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(eyr);
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_TOUCH);
|
||||
ret->items[1] = MP_OBJ_FROM_PTR(tuple);
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_BUTTON
|
||||
if (signalled.read_ready & (1 << SYSHANDLE_BUTTON)) {
|
||||
button_event_t btn_event = {0};
|
||||
if (button_get_event(&btn_event)) {
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
|
||||
uint32_t etype = btn_event.event_type;
|
||||
uint32_t en = btn_event.button;
|
||||
if (display_get_orientation() == 180) {
|
||||
en = (en == BTN_LEFT) ? BTN_RIGHT : BTN_LEFT;
|
||||
}
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(etype);
|
||||
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(en);
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BUTTON);
|
||||
ret->items[1] = MP_OBJ_FROM_PTR(tuple);
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_BLE
|
||||
if (signalled.read_ready & (1 << SYSHANDLE_BLE_IFACE_0)) {
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE_IFACE_0);
|
||||
ret->items[1] = MP_OBJ_NEW_SMALL_INT(BLE_RX_PACKET_SIZE);
|
||||
return mp_const_true;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
mp_obj_t iter = mp_getiter(ifaces, &iterbuf);
|
||||
mp_obj_t item = 0;
|
||||
while ((item = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) {
|
||||
const mp_uint_t i = trezor_obj_get_uint(item);
|
||||
const mp_uint_t iface = i & 0x00FF;
|
||||
const mp_uint_t mode = i & 0xFF00;
|
||||
if (signalled.write_ready & (1 << SYSHANDLE_BLE_IFACE_0)) {
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE_IFACE_0 | POLL_WRITE);
|
||||
ret->items[1] = mp_const_none;
|
||||
return mp_const_true;
|
||||
}
|
||||
|
||||
#if defined TREZOR_EMULATOR
|
||||
// Ensures that SDL events are processed even if the ifaces list
|
||||
// contains only USB interfaces. This prevents the emulator from
|
||||
// freezing when the user interacts with the window.
|
||||
SDL_PumpEvents();
|
||||
#endif
|
||||
|
||||
if (false) {
|
||||
}
|
||||
#if defined USE_TOUCH
|
||||
else if (iface == TOUCH_IFACE) {
|
||||
const uint32_t evt = touch_get_event();
|
||||
if (evt) {
|
||||
// ignore TOUCH_MOVE events if they are too frequent
|
||||
if ((evt & TOUCH_MOVE) == 0 ||
|
||||
(hal_ticks_ms() - last_touch_sample_time > 10)) {
|
||||
last_touch_sample_time = hal_ticks_ms();
|
||||
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));
|
||||
const uint32_t etype = (evt >> 24) & 0xFFU; // event type
|
||||
const uint32_t ex = (evt >> 12) & 0xFFFU; // x position
|
||||
const uint32_t ey = evt & 0xFFFU; // y position
|
||||
uint32_t exr; // rotated x position
|
||||
uint32_t eyr; // rotated y position
|
||||
switch (display_get_orientation()) {
|
||||
case 90:
|
||||
exr = ey;
|
||||
eyr = DISPLAY_RESX - ex;
|
||||
break;
|
||||
case 180:
|
||||
exr = DISPLAY_RESX - ex;
|
||||
eyr = DISPLAY_RESY - ey;
|
||||
break;
|
||||
case 270:
|
||||
exr = DISPLAY_RESY - ey;
|
||||
eyr = ex;
|
||||
break;
|
||||
default:
|
||||
exr = ex;
|
||||
eyr = ey;
|
||||
break;
|
||||
}
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(etype);
|
||||
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(exr);
|
||||
tuple->items[2] = MP_OBJ_NEW_SMALL_INT(eyr);
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(i);
|
||||
ret->items[1] = MP_OBJ_FROM_PTR(tuple);
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (iface == USB_EVENT_IFACE) {
|
||||
usb_event_t event = usb_get_event();
|
||||
|
||||
if (event != USB_EVENT_NONE) {
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(i);
|
||||
ret->items[1] = MP_OBJ_NEW_SMALL_INT((int32_t)event);
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
#if USE_BUTTON
|
||||
else if (iface == BUTTON_IFACE) {
|
||||
button_event_t btn_event = {0};
|
||||
const bool btn = button_get_event(&btn_event);
|
||||
if (btn) {
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
|
||||
uint32_t etype = btn_event.event_type;
|
||||
uint32_t en = btn_event.button;
|
||||
if (display_get_orientation() == 180) {
|
||||
en = (en == BTN_LEFT) ? BTN_RIGHT : BTN_LEFT;
|
||||
}
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(etype);
|
||||
tuple->items[1] = MP_OBJ_NEW_SMALL_INT(en);
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(i);
|
||||
ret->items[1] = MP_OBJ_FROM_PTR(tuple);
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (iface <= USB_RW_IFACE_MAX) {
|
||||
if (mode == POLL_READ) {
|
||||
if ((sectrue == usb_hid_can_read(iface)) ||
|
||||
(sectrue == usb_webusb_can_read(iface))) {
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(i);
|
||||
ret->items[1] = MP_OBJ_NEW_SMALL_INT(USB_PACKET_LEN);
|
||||
return mp_const_true;
|
||||
}
|
||||
} else if (mode == POLL_WRITE) {
|
||||
if ((sectrue == usb_hid_can_write(iface)) ||
|
||||
(sectrue == usb_webusb_can_write(iface))) {
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(i);
|
||||
ret->items[1] = mp_const_none;
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef USE_BLE
|
||||
else if (iface == BLE_IFACE) {
|
||||
if (mode == POLL_READ) {
|
||||
if (ble_can_read()) {
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(i);
|
||||
ret->items[1] = MP_OBJ_NEW_SMALL_INT(BLE_RX_PACKET_SIZE);
|
||||
return mp_const_true;
|
||||
}
|
||||
} else if (mode == POLL_WRITE) {
|
||||
if (ble_can_write()) {
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(i);
|
||||
ret->items[1] = mp_const_none;
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
} else if (iface == BLE_EVENT_IFACE) {
|
||||
ble_event_t event = {0};
|
||||
bool read = ble_get_event(&event);
|
||||
if (read) {
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(event.type);
|
||||
tuple->items[1] = parse_ble_event_data(&event);
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(i);
|
||||
ret->items[1] = MP_OBJ_FROM_PTR(tuple);
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (signalled.read_ready & (1 << SYSHANDLE_BLE)) {
|
||||
ble_event_t event = {0};
|
||||
if (ble_get_event(&event)) {
|
||||
mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL));
|
||||
tuple->items[0] = MP_OBJ_NEW_SMALL_INT(event.type);
|
||||
tuple->items[1] = parse_ble_event_data(&event);
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE);
|
||||
ret->items[1] = MP_OBJ_FROM_PTR(tuple);
|
||||
return mp_const_true;
|
||||
}
|
||||
if (mp_hal_ticks_ms() >= deadline) {
|
||||
break;
|
||||
} else {
|
||||
MICROPY_EVENT_POLL_HOOK
|
||||
}
|
||||
#endif
|
||||
|
||||
if (signalled.read_ready & (1 << SYSHANDLE_USB)) {
|
||||
usb_event_t event = usb_get_event();
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_USB);
|
||||
ret->items[1] = MP_OBJ_NEW_SMALL_INT((int32_t)event);
|
||||
return mp_const_true;
|
||||
}
|
||||
|
||||
for (syshandle_t h = SYSHANDLE_USB_IFACE_0; h <= SYSHANDLE_USB_IFACE_7; h++) {
|
||||
if (signalled.read_ready & (1 << h)) {
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(h);
|
||||
ret->items[1] = MP_OBJ_NEW_SMALL_INT(USB_PACKET_LEN);
|
||||
return mp_const_true;
|
||||
}
|
||||
|
||||
if (signalled.write_ready & (1 << h)) {
|
||||
ret->items[0] = MP_OBJ_NEW_SMALL_INT(h | POLL_WRITE);
|
||||
ret->items[1] = mp_const_none;
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,16 +100,16 @@ STATIC const mp_rom_map_elem_t mp_module_trezorio_globals_table[] = {
|
||||
|
||||
#ifdef USE_BLE
|
||||
{MP_ROM_QSTR(MP_QSTR_ble), MP_ROM_PTR(&mod_trezorio_BLE_module)},
|
||||
{MP_ROM_QSTR(MP_QSTR_BLE_EVENT), MP_ROM_INT(BLE_EVENT_IFACE)},
|
||||
{MP_ROM_QSTR(MP_QSTR_BLE_EVENT), MP_ROM_INT(SYSHANDLE_BLE)},
|
||||
#endif
|
||||
#ifdef USE_TOUCH
|
||||
{MP_ROM_QSTR(MP_QSTR_TOUCH), MP_ROM_INT(TOUCH_IFACE)},
|
||||
{MP_ROM_QSTR(MP_QSTR_TOUCH), MP_ROM_INT(SYSHANDLE_TOUCH)},
|
||||
{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_END), MP_ROM_INT((TOUCH_END >> 24) & 0xFFU)},
|
||||
#endif
|
||||
#ifdef USE_BUTTON
|
||||
{MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_INT(BUTTON_IFACE)},
|
||||
{MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_INT(SYSHANDLE_BUTTON)},
|
||||
{MP_ROM_QSTR(MP_QSTR_BUTTON_PRESSED), MP_ROM_INT(BTN_EVENT_DOWN)},
|
||||
{MP_ROM_QSTR(MP_QSTR_BUTTON_RELEASED), MP_ROM_INT(BTN_EVENT_UP)},
|
||||
{MP_ROM_QSTR(MP_QSTR_BUTTON_LEFT), MP_ROM_INT(BTN_LEFT)},
|
||||
@ -125,7 +125,7 @@ STATIC const mp_rom_map_elem_t mp_module_trezorio_globals_table[] = {
|
||||
{MP_ROM_QSTR(MP_QSTR_POLL_READ), MP_ROM_INT(POLL_READ)},
|
||||
{MP_ROM_QSTR(MP_QSTR_POLL_WRITE), MP_ROM_INT(POLL_WRITE)},
|
||||
|
||||
{MP_ROM_QSTR(MP_QSTR_USB_EVENT), MP_ROM_INT(USB_EVENT_IFACE)},
|
||||
{MP_ROM_QSTR(MP_QSTR_USB_EVENT), MP_ROM_INT(SYSHANDLE_USB)},
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_trezorio_globals,
|
||||
|
Loading…
Reference in New Issue
Block a user