1 /*
2  * Copyright (c) 2022, sakumisu
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef USB_DFU_H
7 #define USB_DFU_H
8 
9 /**\addtogroup USB_MODULE_DFU USB DFU class
10  * \brief This module contains USB Device Firmware Upgrade class definitions.
11  * \details This module based on
12  * + [USB Device Firmware Upgrade Specification, Revision 1.1]
13  * (https://www.usb.org/sites/default/files/DFU_1.1.pdf)
14  * @{ */
15 
16 /** DFU Specification release */
17 #define DFU_VERSION 0x0110
18 
19 /** DFU Class Subclass */
20 #define DFU_SUBCLASS_DFU 0x01
21 
22 /** DFU Class runtime Protocol */
23 #define DFU_PROTOCOL_RUNTIME 0x01
24 
25 /** DFU Class DFU mode Protocol */
26 #define DFU_PROTOCOL_MODE 0x02
27 
28 /**
29  * @brief DFU Class Specific Requests
30  */
31 #define DFU_REQUEST_DETACH    0x00
32 #define DFU_REQUEST_DNLOAD    0x01
33 #define DFU_REQUEST_UPLOAD    0x02
34 #define DFU_REQUEST_GETSTATUS 0x03
35 #define DFU_REQUEST_CLRSTATUS 0x04
36 #define DFU_REQUEST_GETSTATE  0x05
37 #define DFU_REQUEST_ABORT     0x06
38 
39 /** DFU FUNCTIONAL descriptor type */
40 #define DFU_FUNC_DESC 0x21
41 
42 /** DFU attributes DFU Functional Descriptor */
43 #define DFU_ATTR_WILL_DETACH            0x08
44 #define DFU_ATTR_MANIFESTATION_TOLERANT 0x04
45 #define DFU_ATTR_CAN_UPLOAD             0x02
46 #define DFU_ATTR_CAN_DNLOAD             0x01
47 
48 /** bStatus values for the DFU_GETSTATUS response */
49 #define DFU_STATUS_OK               0x00U
50 #define DFU_STATUS_ERR_TARGET       0x01U
51 #define DFU_STATUS_ERR_FILE         0x02U
52 #define DFU_STATUS_ERR_WRITE        0x03U
53 #define DFU_STATUS_ERR_ERASE        0x04U
54 #define DFU_STATUS_ERR_CHECK_ERASED 0x05U
55 #define DFU_STATUS_ERR_PROG         0x06U
56 #define DFU_STATUS_ERR_VERIFY       0x07U
57 #define DFU_STATUS_ERR_ADDRESS      0x08U
58 #define DFU_STATUS_ERR_NOTDONE      0x09U
59 #define DFU_STATUS_ERR_FIRMWARE     0x0AU
60 #define DFU_STATUS_ERR_VENDOR       0x0BU
61 #define DFU_STATUS_ERR_USB          0x0CU
62 #define DFU_STATUS_ERR_POR          0x0DU
63 #define DFU_STATUS_ERR_UNKNOWN      0x0EU
64 #define DFU_STATUS_ERR_STALLEDPKT   0x0FU
65 
66 /** bState values for the DFU_GETSTATUS response */
67 #define DFU_STATE_APP_IDLE                0U
68 #define DFU_STATE_APP_DETACH              1U
69 #define DFU_STATE_DFU_IDLE                2U
70 #define DFU_STATE_DFU_DNLOAD_SYNC         3U
71 #define DFU_STATE_DFU_DNLOAD_BUSY         4U
72 #define DFU_STATE_DFU_DNLOAD_IDLE         5U
73 #define DFU_STATE_DFU_MANIFEST_SYNC       6U
74 #define DFU_STATE_DFU_MANIFEST            7U
75 #define DFU_STATE_DFU_MANIFEST_WAIT_RESET 8U
76 #define DFU_STATE_DFU_UPLOAD_IDLE         9U
77 #define DFU_STATE_DFU_ERROR               10U
78 
79 /** DFU Manifestation State  */
80 #define DFU_MANIFEST_COMPLETE    0U
81 #define DFU_MANIFEST_IN_PROGRESS 1U
82 
83 /** Special Commands  with Download Request  */
84 #define DFU_CMD_GETCOMMANDS       0U
85 #define DFU_CMD_SETADDRESSPOINTER 0x21U
86 #define DFU_CMD_ERASE             0x41U
87 #define DFU_MEDIA_ERASE           0x00U
88 #define DFU_MEDIA_PROGRAM         0x01U
89 
90 /** Other defines  */
91 /* Bit Detach capable = bit 3 in bmAttributes field */
92 #define DFU_DETACH_MASK   (1U << 3)
93 #define DFU_MANIFEST_MASK (1U << 2)
94 
95 /** Run-Time Functional Descriptor */
96 struct dfu_runtime_descriptor {
97     uint8_t bLength;         /**<\brief Descriptor length in bytes.*/
98     uint8_t bDescriptorType; /**<\brief DFU functional descriptor type.*/
99     uint8_t bmAttributes;    /**<\brief USB DFU capabilities \ref USB_DFU_CAPAB*/
100     uint16_t wDetachTimeout; /**<\brief USB DFU detach timeout in ms.*/
101     uint16_t wTransferSize;  /**<\brief USB DFU maximum transfer block size in bytes.*/
102     uint16_t bcdDFUVersion;  /**<\brief USB DFU version \ref VERSION_BCD utility macro.*/
103 } __PACKED;
104 
105 /**\brief Payload packet to response in DFU_GETSTATUS request */
106 struct dfu_info {
107     uint8_t bStatus;       /**<\brief An indication of the status resulting from the
108                                      * execution of the most recent request.*/
109     uint8_t bPollTimeout;  /**<\brief Minimum time (LSB) in ms, that the host should wait
110                                      * before sending a subsequent DFU_GETSTATUS request.*/
111     uint16_t wPollTimeout; /**<\brief Minimum time (MSB) in ms, that the host should wait
112                                      * before sending a subsequent DFU_GETSTATUS request.*/
113     uint8_t bState;        /**<\brief An indication of the state that the device is going
114                                      * to enter immediately following transmission of this response.*/
115     uint8_t iString;       /**<\brief Index of the status string descriptor.*/
116 };
117 
118 // clang-format off
119 #define DFU_DESCRIPTOR_INIT()                                                            \
120     0x09,                          /* bLength */                                         \
121     USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType */                                 \
122     0x00,                          /* bInterfaceNumber */                                \
123     0x00,                          /* bAlternateSetting */                               \
124     0x00,                          /* bNumEndpoints Default Control Pipe only */         \
125     USB_DEVICE_CLASS_APP_SPECIFIC, /* bInterfaceClass */                                 \
126     0x01,                          /* bInterfaceSubClass Device Firmware Upgrade */      \
127     0x02,                          /* bInterfaceProtocol DFU mode */                     \
128     0x04, /* iInterface */         /*!< Device Firmware Update Functional Descriptor  */ \
129     0x09,                          /* bLength */                                         \
130     0x21,                          /* DFU Functional Descriptor */                       \
131     0x0B,                          /* bmAttributes */                                    \
132     WBVAL(0x00ff),                 /* wDetachTimeOut */                                  \
133     WBVAL(USBD_DFU_XFER_SIZE),     /* wTransferSize */                                   \
134     WBVAL(0x011a)                  /* bcdDFUVersion */
135 // clang-format on
136 
137 #endif /* USB_DFU_H */
138