Skip to content

Commit

Permalink
lpc55: Move USB initialization to end
Browse files Browse the repository at this point in the history
This patch splits the NFC and USB initialization and moves the USB
initialization to the end of the initialization process on the lpc55.
This makes sure that we can respond to all USB requests as the poll task
is started directly after the init process.

Previously, we initialized the USB interface at the beginning of the
process so that we could not respond to requests until the end of the
init process.  This could potentially mean that the device would lose
the initial GET DESCRIPTOR request sent by the Linux kernel, causing a
delay of typically 5 s after connecting the device.

Fixes: #302
  • Loading branch information
robin-nitrokey committed Oct 31, 2023
1 parent ba8dbeb commit 38e08d9
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 87 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
- fido-authenticator: Reduce the maximum credential ID length for improved compatibility ([fido-authenticator#37][])
- fido-authenticator: Multiple changes to improve compliance with the specification (overview: [fido-authenticator#6][])
- Correct maximum binary size for LPC55 and only enable PRINCE for the subregions used for the filesystem ([#355][])
- lpc55: Move USB initialization to the end of the boot process to make sure that the device can respond to all requests, fixing a potential delay when connecting the device under Linux ([#302][])

[#302]: https://github.com/Nitrokey/nitrokey-3-firmware/issues/302
[#314]: https://github.com/Nitrokey/nitrokey-3-firmware/pull/314
[#321]: https://github.com/Nitrokey/nitrokey-3-firmware/issues/321
[#335]: https://github.com/Nitrokey/nitrokey-3-firmware/pull/335
Expand Down
6 changes: 5 additions & 1 deletion runners/embedded/src/bin/app-nrf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ delog!(Delogger, 3 * 1024, 512, ERL::types::DelogFlusher);
#[rtic::app(device = nrf52840_hal::pac, peripherals = true, dispatchers = [SWI3_EGU3, SWI4_EGU4, SWI5_EGU5])]
mod app {
use super::{Delogger, ERL, ERL::soc::rtic_monotonic::RtcDuration};
use apdu_dispatch::interchanges::Channel as CcidChannel;
use interchange::Channel;
use nrf52840_hal::{
gpio::{p0, p1},
gpiote::Gpiote,
Expand Down Expand Up @@ -140,7 +142,9 @@ mod app {
let store: ERL::types::RunnerStore =
ERL::init_store(internal_flash, extflash, false, &mut init_status);

let usbnfcinit = ERL::init_usb_nfc(usbd_ref, None);
static NFC_CHANNEL: CcidChannel = Channel::new();
let (_nfc_rq, nfc_rp) = NFC_CHANNEL.split().unwrap();
let usbnfcinit = ERL::init_usb_nfc(usbd_ref, None, nfc_rp);
/* TODO: set up fingerprint device */
/* TODO: set up SE050 device */
use nrf52840_hal::prelude::OutputPin;
Expand Down
44 changes: 15 additions & 29 deletions runners/embedded/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
#![no_std]

use apdu_dispatch::{
dispatch::ApduDispatch,
interchanges::{Channel as CcidChannel, Responder as CcidResponder},
};
use ctaphid_dispatch::{dispatch::Dispatch as CtaphidDispatch, types::Channel as CtapChannel};
use interchange::Channel;
use littlefs2::fs::Filesystem;
use ref_swap::OptionRefSwap;
use soc::types::Soc as SocT;
use types::Soc;
use trussed::interrupt::InterruptFlag;
use types::{Iso14443, Soc};
use usb_device::device::{UsbDeviceBuilder, UsbVidPid};

#[cfg(feature = "board-nk3am")]
Expand Down Expand Up @@ -172,27 +179,22 @@ pub fn init_store(

pub fn init_usb_nfc(
usbbus_opt: Option<&'static usb_device::bus::UsbBusAllocator<<SocT as Soc>::UsbBus>>,
nfcdev_opt: Option<<SocT as Soc>::NfcDevice>,
nfc: Option<Iso14443>,
nfc_rp: CcidResponder<'static>,
) -> types::usbnfc::UsbNfcInit {
let config = <SocT as Soc>::INTERFACE_CONFIG;

use apdu_dispatch::interchanges::Channel as CcidChannel;
use ctaphid_dispatch::types::Channel as CtapChannel;
use ref_swap::OptionRefSwap;
use trussed::interrupt::InterruptFlag;
static CCID_CHANNEL: CcidChannel = Channel::new();
static NFC_CHANNEL: CcidChannel = Channel::new();
static CTAP_CHANNEL: CtapChannel = Channel::new();
static CTAP_INTERRUPT: OptionRefSwap<'static, InterruptFlag> = OptionRefSwap::new(None);

/* claim interchanges */
let (ccid_rq, ccid_rp) = CCID_CHANNEL.split().unwrap();
let (nfc_rq, nfc_rp) = NFC_CHANNEL.split().unwrap();
let (ctaphid_rq, ctaphid_rp) = CTAP_CHANNEL.split().unwrap();

/* initialize dispatchers */
let apdu_dispatch = apdu_dispatch::dispatch::ApduDispatch::new(ccid_rp, nfc_rp);
let ctaphid_dispatch =
ctaphid_dispatch::dispatch::Dispatch::with_interrupt(ctaphid_rp, Some(&CTAP_INTERRUPT));
let apdu_dispatch = ApduDispatch::new(ccid_rp, nfc_rp);
let ctaphid_dispatch = CtaphidDispatch::with_interrupt(ctaphid_rp, Some(&CTAP_INTERRUPT));

/* populate requesters (if bus options are provided) */
let mut usb_classes = None;
Expand Down Expand Up @@ -226,28 +228,11 @@ pub fn init_usb_nfc(
));
}

// TODO: move up?
let iso14443 = {
if let Some(nfcdev) = nfcdev_opt {
let mut iso14443 = nfc_device::Iso14443::new(nfcdev, nfc_rq);

iso14443.poll();
if true {
// Give a small delay to charge up capacitors
// basic_stage.delay_timer.start(5_000.microseconds()); nb::block!(basic_stage.delay_timer.wait()).ok();
}

Some(iso14443)
} else {
None
}
};

types::usbnfc::UsbNfcInit {
usb_classes,
apdu_dispatch,
ctaphid_dispatch,
iso14443,
iso14443: nfc,
}
}

Expand Down Expand Up @@ -336,6 +321,7 @@ pub fn init_se050<
});
(se050, ChaCha8Rng::from_seed(seed))
}

#[inline(never)]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
Expand Down
Loading

0 comments on commit 38e08d9

Please sign in to comment.