aboutsummaryrefslogtreecommitdiff
path: root/embassy-usb-dfu/src/application.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-usb-dfu/src/application.rs')
-rw-r--r--embassy-usb-dfu/src/application.rs36
1 files changed, 16 insertions, 20 deletions
diff --git a/embassy-usb-dfu/src/application.rs b/embassy-usb-dfu/src/application.rs
index 2e7bda121..0b7b53af8 100644
--- a/embassy-usb-dfu/src/application.rs
+++ b/embassy-usb-dfu/src/application.rs
@@ -1,4 +1,4 @@
1use embassy_boot::BlockingFirmwareUpdater; 1use embassy_boot::BlockingFirmwareState;
2use embassy_time::{Duration, Instant}; 2use embassy_time::{Duration, Instant};
3use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType}; 3use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType};
4use embassy_usb::driver::Driver; 4use embassy_usb::driver::Driver;
@@ -11,18 +11,18 @@ use crate::consts::{
11}; 11};
12 12
13/// Internal state for the DFU class 13/// Internal state for the DFU class
14pub struct Control<'d, DFU: NorFlash, STATE: NorFlash> { 14pub struct Control<'d, STATE: NorFlash> {
15 updater: BlockingFirmwareUpdater<'d, DFU, STATE>, 15 firmware_state: BlockingFirmwareState<'d, STATE>,
16 attrs: DfuAttributes, 16 attrs: DfuAttributes,
17 state: State, 17 state: State,
18 timeout: Option<Duration>, 18 timeout: Option<Duration>,
19 detach_start: Option<Instant>, 19 detach_start: Option<Instant>,
20} 20}
21 21
22impl<'d, DFU: NorFlash, STATE: NorFlash> Control<'d, DFU, STATE> { 22impl<'d, STATE: NorFlash> Control<'d, STATE> {
23 pub fn new(updater: BlockingFirmwareUpdater<'d, DFU, STATE>, attrs: DfuAttributes) -> Self { 23 pub fn new(firmware_state: BlockingFirmwareState<'d, STATE>, attrs: DfuAttributes) -> Self {
24 Control { 24 Control {
25 updater, 25 firmware_state,
26 attrs, 26 attrs,
27 state: State::AppIdle, 27 state: State::AppIdle,
28 detach_start: None, 28 detach_start: None,
@@ -31,19 +31,20 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> Control<'d, DFU, STATE> {
31 } 31 }
32} 32}
33 33
34impl<'d, DFU: NorFlash, STATE: NorFlash> Handler for Control<'d, DFU, STATE> { 34impl<'d, STATE: NorFlash> Handler for Control<'d, STATE> {
35 fn reset(&mut self) { 35 fn reset(&mut self) {
36 if let Some(start) = self.detach_start { 36 if let Some(start) = self.detach_start {
37 let delta = Instant::now() - start; 37 let delta = Instant::now() - start;
38 let timeout = self.timeout.unwrap(); 38 let timeout = self.timeout.unwrap();
39 #[cfg(feature = "defmt")] 39 trace!(
40 defmt::info!(
41 "Received RESET with delta = {}, timeout = {}", 40 "Received RESET with delta = {}, timeout = {}",
42 delta.as_millis(), 41 delta.as_millis(),
43 timeout.as_millis() 42 timeout.as_millis()
44 ); 43 );
45 if delta < timeout { 44 if delta < timeout {
46 self.updater.mark_dfu().expect("Failed to mark DFU mode in bootloader"); 45 self.firmware_state
46 .mark_dfu()
47 .expect("Failed to mark DFU mode in bootloader");
47 cortex_m::asm::dsb(); 48 cortex_m::asm::dsb();
48 cortex_m::peripheral::SCB::sys_reset(); 49 cortex_m::peripheral::SCB::sys_reset();
49 } 50 }
@@ -59,13 +60,11 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> Handler for Control<'d, DFU, STATE> {
59 return None; 60 return None;
60 } 61 }
61 62
62 #[cfg(feature = "defmt")] 63 trace!("Received request {}", req);
63 defmt::info!("Received request {}", req);
64 64
65 match Request::try_from(req.request) { 65 match Request::try_from(req.request) {
66 Ok(Request::Detach) => { 66 Ok(Request::Detach) => {
67 #[cfg(feature = "defmt")] 67 trace!("Received DETACH, awaiting USB reset");
68 defmt::info!("Received DETACH, awaiting USB reset");
69 self.detach_start = Some(Instant::now()); 68 self.detach_start = Some(Instant::now());
70 self.timeout = Some(Duration::from_millis(req.value as u64)); 69 self.timeout = Some(Duration::from_millis(req.value as u64));
71 self.state = State::AppDetach; 70 self.state = State::AppDetach;
@@ -84,8 +83,7 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> Handler for Control<'d, DFU, STATE> {
84 return None; 83 return None;
85 } 84 }
86 85
87 #[cfg(feature = "defmt")] 86 trace!("Received request {}", req);
88 defmt::info!("Received request {}", req);
89 87
90 match Request::try_from(req.request) { 88 match Request::try_from(req.request) {
91 Ok(Request::GetStatus) => { 89 Ok(Request::GetStatus) => {
@@ -106,13 +104,11 @@ impl<'d, DFU: NorFlash, STATE: NorFlash> Handler for Control<'d, DFU, STATE> {
106/// it should expose a DFU device, and a software reset will be issued. 104/// it should expose a DFU device, and a software reset will be issued.
107/// 105///
108/// To apply USB DFU updates, the bootloader must be capable of recognizing the DFU magic and exposing a device to handle the full DFU transaction with the host. 106/// To apply USB DFU updates, the bootloader must be capable of recognizing the DFU magic and exposing a device to handle the full DFU transaction with the host.
109pub fn usb_dfu<'d, D: Driver<'d>, DFU: NorFlash, STATE: NorFlash>( 107pub fn usb_dfu<'d, D: Driver<'d>, STATE: NorFlash>(
110 builder: &mut Builder<'d, D>, 108 builder: &mut Builder<'d, D>,
111 handler: &'d mut Control<'d, DFU, STATE>, 109 handler: &'d mut Control<'d, STATE>,
112 timeout: Duration, 110 timeout: Duration,
113) { 111) {
114 #[cfg(feature = "defmt")]
115 defmt::info!("Application USB DFU initializing");
116 let mut func = builder.function(0x00, 0x00, 0x00); 112 let mut func = builder.function(0x00, 0x00, 0x00);
117 let mut iface = func.interface(); 113 let mut iface = func.interface();
118 let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_RT, None); 114 let mut alt = iface.alt_setting(USB_CLASS_APPN_SPEC, APPN_SPEC_SUBCLASS_DFU, DFU_PROTOCOL_RT, None);