1 /*
2  * SPDX-FileCopyrightText: 2015,2016 Intel Corporation
3  * SPDX-FileContributor: 2017 PHYTEC Messtechnik GmbH
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 /**
9  * @file
10  * @brief USB Device Firmware Upgrade (DFU) public header
11  *
12  * Header follows the Device Class Specification for
13  * Device Firmware Upgrade Version 1.1
14  */
15 
16 #pragma once
17 
18 #include <stdint.h>
19 #include <stddef.h>
20 #include "usb_device.h"
21 
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 /** DFU Class Subclass */
27 #define DFU_SUBCLASS            0x01
28 
29 /** DFU Class runtime Protocol */
30 #define DFU_RT_PROTOCOL         0x01
31 
32 /** DFU Class DFU mode Protocol */
33 #define DFU_MODE_PROTOCOL       0x02
34 
35 /**
36  * @brief DFU Class Specific Requests
37  */
38 #define DFU_DETACH          0x00
39 #define DFU_DNLOAD          0x01
40 #define DFU_UPLOAD          0x02
41 #define DFU_GETSTATUS           0x03
42 #define DFU_CLRSTATUS           0x04
43 #define DFU_GETSTATE            0x05
44 #define DFU_ABORT           0x06
45 
46 /** DFU FUNCTIONAL descriptor type */
47 #define DFU_FUNC_DESC           0x21
48 
49 /** DFU attributes DFU Functional Descriptor */
50 #define DFU_ATTR_WILL_DETACH        0x08
51 #define DFU_ATTR_MANIFESTATION_TOLERANT 0x04
52 #define DFU_ATTR_CAN_UPLOAD     0x02
53 #define DFU_ATTR_CAN_DNLOAD     0x01
54 
55 /** DFU Specification release */
56 #define DFU_VERSION         0x0110
57 
58 /** Run-Time Functional Descriptor */
59 struct dfu_runtime_descriptor {
60     uint8_t bLength;
61     uint8_t bDescriptorType;
62     uint8_t bmAttributes;
63     uint16_t wDetachTimeOut;
64     uint16_t wTransferSize;
65     uint16_t bcdDFUVersion;
66 } __packed;
67 
68 /** bStatus values for the DFU_GETSTATUS response */
69 enum dfu_status {
70     statusOK,
71     errTARGET,
72     errFILE,
73     errWRITE,
74     errERASE,
75     errCHECK_ERASED,
76     errPROG,
77     errVERIFY,
78     errADDRESS,
79     errNOTDONE,
80     errFIRMWARE,
81     errVENDOR,
82     errUSB,
83     errPOR,
84     errUNKNOWN,
85     errSTALLEDPKT
86 };
87 
88 /** bState values for the DFU_GETSTATUS response */
89 enum dfu_state {
90     appIDLE,
91     appDETACH,
92     dfuIDLE,
93     dfuDNLOAD_SYNC,
94     dfuDNBUSY,
95     dfuDNLOAD_IDLE,
96     dfuMANIFEST_SYNC,
97     dfuMANIFEST,
98     dfuMANIFEST_WAIT_RST,
99     dfuUPLOAD_IDLE,
100     dfuERROR,
101 };
102 
103 /*
104  These callbacks are made public so the ACM driver can call them to handle the switch to DFU.
105 */
106 
107 int dfu_class_handle_req(struct usb_setup_packet *pSetup,
108                          int32_t *data_len, uint8_t **data);
109 void dfu_status_cb(enum usb_dc_status_code status, uint8_t *param);
110 int usb_dfu_init(void);
111 int dfu_custom_handle_req(struct usb_setup_packet *pSetup,
112                           int32_t *data_len, uint8_t **data);
113 
114 
115 typedef void(*usb_dfu_detach_routine_t)(int delay);
116 void usb_dfu_set_detach_cb(usb_dfu_detach_routine_t cb);
117 void usb_dfu_force_detach(void);
118 
119 
120 #ifdef __cplusplus
121 }
122 #endif
123