Skip to content

Commit 20178e3

Browse files
committed
Merge branch 'context'
2 parents 3153156 + a5754a6 commit 20178e3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1192
-1064
lines changed

src/bootloader/startup.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "mpu_regions.h"
1717
#include "platform_config.h"
1818
#include "platform_init.h"
19+
#include "usb/class/hid/hww/hid_hww.h"
1920

2021
#include <driver_init.h>
2122
#include <hardfault.h>
@@ -56,8 +57,22 @@ int main(void)
5657
#endif
5758
bootloader_jump();
5859

60+
const uint8_t* hww_data = NULL;
61+
uint8_t hww_frame[USB_REPORT_SIZE] = {0};
62+
5963
// If did not jump to firmware code, begin USB processing
6064
while (1) {
65+
if (hid_hww_read(&hww_frame[0])) {
66+
usb_packet_process((const USB_FRAME*)hww_frame);
67+
}
68+
if (!hww_data) {
69+
hww_data = queue_pull(queue_hww_queue());
70+
}
71+
if (hww_data) {
72+
if (hid_hww_write_poll(hww_data)) {
73+
hww_data = NULL;
74+
}
75+
}
6176
usb_processing_process(usb_processing_hww());
6277
}
6378
return 0;

src/firmware_main_loop.c

Lines changed: 68 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,43 +15,94 @@
1515
#include "firmware_main_loop.h"
1616

1717
#include "hardfault.h"
18+
#include "hid_hww.h"
1819
#include "hww.h"
1920
#include "touch/gestures.h"
20-
#include "u2f.h"
2121
#include "ui/screen_process.h"
2222
#include "ui/screen_stack.h"
23+
#include "usb/class/hid/hww/hid_hww.h"
2324
#include "usb/usb.h"
25+
#include "usb/usb_frame.h"
2426
#include "usb/usb_processing.h"
2527
#include "workflow/orientation_screen.h"
2628
#include <rust/rust.h>
29+
#if APP_U2F == 1
30+
#include "u2f.h"
31+
#include "u2f/u2f_packet.h"
32+
#include "usb/class/hid/u2f/hid_u2f.h"
33+
#endif
2734

2835
void firmware_main_loop(void)
2936
{
3037
// This starts the async orientation screen workflow, which is processed by the loop below.
3138
orientation_screen();
3239

33-
while (1) {
34-
screen_process();
35-
/* And finally, run the high-level event processing. */
36-
37-
rust_workflow_spin();
40+
const uint8_t* hww_data = NULL;
41+
uint8_t hww_frame[USB_REPORT_SIZE] = {0};
3842

39-
if (usb_is_enabled()) {
40-
rust_async_usb_spin();
43+
#if APP_U2F == 1
44+
u2f_packet_init();
45+
const uint8_t* u2f_data = NULL;
46+
uint8_t u2f_frame[USB_REPORT_SIZE] = {0};
47+
#endif
4148

42-
/* First, process all the incoming USB traffic. */
43-
usb_processing_process(usb_processing_hww());
49+
while (1) {
50+
// Do USB I/O
51+
if (!hww_data) {
52+
hww_data = queue_pull(queue_hww_queue());
53+
}
4454
#if APP_U2F == 1
45-
usb_processing_process(usb_processing_u2f());
55+
// Generate timeout packets
56+
uint32_t timeout_cid;
57+
while (u2f_packet_timeout_get(&timeout_cid)) {
58+
u2f_packet_timeout(timeout_cid);
59+
}
60+
if (!u2f_data) {
61+
u2f_data = queue_pull(queue_u2f_queue());
62+
}
4663
#endif
47-
/*
48-
* If USB has generated events at the application level,
49-
* process them now.
50-
*/
51-
hww_process();
64+
// Only read new messages if we have nothing to send
65+
if (!hww_data && hid_hww_read(&hww_frame[0])) {
66+
usb_packet_process((const USB_FRAME*)hww_frame);
67+
}
5268
#if APP_U2F == 1
53-
u2f_process();
69+
if (!u2f_data && hid_u2f_read(&u2f_frame[0])) {
70+
u2f_packet_process((const USB_FRAME*)u2f_frame);
71+
}
5472
#endif
73+
74+
if (hww_data) {
75+
if (hid_hww_write_poll(hww_data)) {
76+
hww_data = NULL;
77+
}
78+
}
79+
#if APP_U2F == 1
80+
if (u2f_data) {
81+
if (hid_u2f_write_poll(u2f_data)) {
82+
u2f_data = NULL;
83+
}
5584
}
85+
#endif
86+
87+
/* First, process all the incoming USB traffic. */
88+
usb_processing_process(usb_processing_hww());
89+
#if APP_U2F == 1
90+
usb_processing_process(usb_processing_u2f());
91+
#endif
92+
/*
93+
* If USB has generated events at the application level,
94+
* process them now.
95+
*/
96+
hww_process();
97+
#if APP_U2F == 1
98+
u2f_process();
99+
#endif
100+
101+
screen_process();
102+
/* And finally, run the high-level event processing. */
103+
104+
rust_workflow_spin();
105+
106+
rust_async_usb_spin();
56107
}
57108
}

src/rust/bitbox02-rust-c/src/workflow.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,12 @@ static mut CONFIRM_TITLE: Option<String> = None;
4040
static mut CONFIRM_BODY: Option<String> = None;
4141
static mut CONFIRM_PARAMS: Option<confirm::Params> = None;
4242
static mut CONFIRM_STATE: TaskState<'static, Result<(), confirm::UserAbort>> = TaskState::Nothing;
43-
static mut REAL_WORKFLOWS: bitbox02_rust::workflow::RealWorkflows =
44-
bitbox02_rust::workflow::RealWorkflows;
43+
static mut BITBOX02_HAL: bitbox02_rust::hal::BitBox02Hal = bitbox02_rust::hal::BitBox02Hal::new();
4544

4645
#[no_mangle]
4746
pub unsafe extern "C" fn rust_workflow_spawn_unlock() {
4847
UNLOCK_STATE = TaskState::Running(Box::pin(bitbox02_rust::workflow::unlock::unlock(
49-
&mut REAL_WORKFLOWS,
48+
&mut BITBOX02_HAL,
5049
)));
5150
}
5251

src/rust/bitbox02-rust/src/hal.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright 2025 Shift Crypto AG
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use crate::workflow::RealWorkflows;
16+
pub use crate::workflow::Workflows as Ui;
17+
18+
pub trait Sd {
19+
fn sdcard_inserted(&mut self) -> bool;
20+
}
21+
22+
/// Hardware abstraction layer for BitBox devices.
23+
pub trait Hal {
24+
fn ui(&mut self) -> &mut impl Ui;
25+
fn sd(&mut self) -> &mut impl Sd;
26+
}
27+
28+
pub struct BitBox02Sd;
29+
30+
impl Sd for BitBox02Sd {
31+
fn sdcard_inserted(&mut self) -> bool {
32+
bitbox02::sd::sdcard_inserted()
33+
}
34+
}
35+
36+
pub struct BitBox02Hal {
37+
ui: RealWorkflows,
38+
sd: BitBox02Sd,
39+
}
40+
41+
impl BitBox02Hal {
42+
pub const fn new() -> Self {
43+
Self {
44+
ui: crate::workflow::RealWorkflows,
45+
sd: BitBox02Sd,
46+
}
47+
}
48+
}
49+
50+
impl Hal for BitBox02Hal {
51+
fn ui(&mut self) -> &mut impl Ui {
52+
&mut self.ui
53+
}
54+
fn sd(&mut self) -> &mut impl Sd {
55+
&mut self.sd
56+
}
57+
}
58+
59+
#[cfg(feature = "testing")]
60+
pub mod testing {
61+
pub struct TestingSd {
62+
pub inserted: Option<bool>,
63+
}
64+
65+
impl TestingSd {
66+
pub fn new() -> Self {
67+
Self { inserted: None }
68+
}
69+
}
70+
pub struct TestingHal<'a> {
71+
pub ui: crate::workflow::testing::TestingWorkflows<'a>,
72+
pub sd: TestingSd,
73+
}
74+
75+
impl super::Sd for TestingSd {
76+
fn sdcard_inserted(&mut self) -> bool {
77+
self.inserted.unwrap()
78+
}
79+
}
80+
81+
impl TestingHal<'_> {
82+
pub fn new() -> Self {
83+
Self {
84+
ui: crate::workflow::testing::TestingWorkflows::new(),
85+
sd: TestingSd::new(),
86+
}
87+
}
88+
}
89+
90+
impl super::Hal for TestingHal<'_> {
91+
fn ui(&mut self) -> &mut impl super::Ui {
92+
&mut self.ui
93+
}
94+
fn sd(&mut self) -> &mut impl super::Sd {
95+
&mut self.sd
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)