Skip to main content

embassy_usb/class/dfu/
consts.rs

1//! USB DFU constants and types.
2
3pub(crate) const USB_CLASS_APPN_SPEC: u8 = 0xFE;
4pub(crate) const APPN_SPEC_SUBCLASS_DFU: u8 = 0x01;
5#[allow(unused)]
6pub(crate) const DFU_PROTOCOL_DFU: u8 = 0x02;
7#[allow(unused)]
8pub(crate) const DFU_PROTOCOL_RT: u8 = 0x01;
9pub(crate) const DESC_DFU_FUNCTIONAL: u8 = 0x21;
10
11#[cfg(feature = "defmt")]
12defmt::bitflags! {
13    /// Attributes supported by the DFU controller.
14    pub struct DfuAttributes: u8 {
15        /// Generate WillDetach sequence on bus.
16        const WILL_DETACH = 0b0000_1000;
17        /// Device can communicate during manifestation phase.
18        const MANIFESTATION_TOLERANT = 0b0000_0100;
19        /// Capable of upload.
20        const CAN_UPLOAD = 0b0000_0010;
21        /// Capable of download.
22        const CAN_DOWNLOAD = 0b0000_0001;
23    }
24}
25
26#[cfg(not(feature = "defmt"))]
27bitflags::bitflags! {
28    /// Attributes supported by the DFU controller.
29    pub struct DfuAttributes: u8 {
30        /// Generate WillDetach sequence on bus.
31        const WILL_DETACH = 0b0000_1000;
32        /// Device can communicate during manifestation phase.
33        const MANIFESTATION_TOLERANT = 0b0000_0100;
34        /// Capable of upload.
35        const CAN_UPLOAD = 0b0000_0010;
36        /// Capable of download.
37        const CAN_DOWNLOAD = 0b0000_0001;
38    }
39}
40
41#[derive(Copy, Clone, PartialEq, Eq)]
42#[repr(u8)]
43#[allow(unused)]
44pub(crate) enum State {
45    AppIdle = 0,
46    AppDetach = 1,
47    DfuIdle = 2,
48    DlSync = 3,
49    DlBusy = 4,
50    Download = 5,
51    ManifestSync = 6,
52    Manifest = 7,
53    ManifestWaitReset = 8,
54    UploadIdle = 9,
55    Error = 10,
56}
57
58/// DFU status codes indicating the result of the most recent request.
59#[derive(Copy, Clone, PartialEq, Eq)]
60#[repr(u8)]
61#[allow(unused)]
62pub enum Status {
63    /// No error.
64    Ok = 0x00,
65    /// File is not targeted for use by this device.
66    ErrTarget = 0x01,
67    /// File is for this device but fails some vendor-specific verification test.
68    ErrFile = 0x02,
69    /// Device is unable to write memory.
70    ErrWrite = 0x03,
71    /// Memory erase function failed.
72    ErrErase = 0x04,
73    /// Memory erase check failed.
74    ErrCheckErased = 0x05,
75    /// Program memory function failed.
76    ErrProg = 0x06,
77    /// Programmed memory failed verification.
78    ErrVerify = 0x07,
79    /// Cannot program memory due to received address that is out of range.
80    ErrAddress = 0x08,
81    /// Received DFU_DNLOAD with wLength = 0, but device does not think it has all of the data yet.
82    ErrNotDone = 0x09,
83    /// Device's firmware is corrupt. It cannot return to run-time (non-DFU) operations.
84    ErrFirmware = 0x0A,
85    /// iString indicates a vendor-specific error.
86    ErrVendor = 0x0B,
87    /// Device detected unexpected USB reset signaling.
88    ErrUsbr = 0x0C,
89    /// Device detected unexpected power on reset.
90    ErrPor = 0x0D,
91    /// Something went wrong, but the device does not know what.
92    ErrUnknown = 0x0E,
93    /// Device stalled an unexpected request.
94    ErrStalledPkt = 0x0F,
95}
96
97#[derive(Copy, Clone, PartialEq, Eq)]
98#[repr(u8)]
99pub(crate) enum Request {
100    Detach = 0,
101    Dnload = 1,
102    Upload = 2,
103    GetStatus = 3,
104    ClrStatus = 4,
105    GetState = 5,
106    Abort = 6,
107}
108
109impl TryFrom<u8> for Request {
110    type Error = ();
111
112    fn try_from(value: u8) -> Result<Self, Self::Error> {
113        match value {
114            0 => Ok(Request::Detach),
115            1 => Ok(Request::Dnload),
116            2 => Ok(Request::Upload),
117            3 => Ok(Request::GetStatus),
118            4 => Ok(Request::ClrStatus),
119            5 => Ok(Request::GetState),
120            6 => Ok(Request::Abort),
121            _ => Err(()),
122        }
123    }
124}