Line data Source code
1 1 : /*
2 : * Copyright (c) 2024 Nordic Semiconductor ASA
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief USB Device Firmware Upgrade (DFU) public header
10 : *
11 : * Header exposes API for registering DFU images.
12 : */
13 :
14 : #ifndef ZEPHYR_INCLUDE_USB_CLASS_USBD_DFU_H
15 : #define ZEPHYR_INCLUDE_USB_CLASS_USBD_DFU_H
16 :
17 : #include <stdint.h>
18 :
19 : /* DFU Class Subclass */
20 0 : #define USB_DFU_SUBCLASS 0x01
21 :
22 : /* DFU Class runtime Protocol */
23 0 : #define USB_DFU_PROTOCOL_RUNTIME 0x01
24 :
25 : /* DFU Class DFU mode Protocol */
26 0 : #define USB_DFU_PROTOCOL_DFU 0x02
27 :
28 : /* DFU Class Specific Requests */
29 0 : #define USB_DFU_REQ_DETACH 0x00
30 0 : #define USB_DFU_REQ_DNLOAD 0x01
31 0 : #define USB_DFU_REQ_UPLOAD 0x02
32 0 : #define USB_DFU_REQ_GETSTATUS 0x03
33 0 : #define USB_DFU_REQ_CLRSTATUS 0x04
34 0 : #define USB_DFU_REQ_GETSTATE 0x05
35 0 : #define USB_DFU_REQ_ABORT 0x06
36 :
37 : /* Run-Time DFU Functional Descriptor */
38 0 : struct usb_dfu_descriptor {
39 0 : uint8_t bLength;
40 0 : uint8_t bDescriptorType;
41 0 : uint8_t bmAttributes;
42 0 : uint16_t wDetachTimeOut;
43 0 : uint16_t wTransferSize;
44 0 : uint16_t bcdDFUVersion;
45 : } __packed;
46 :
47 : /* DFU Functional Descriptor Type */
48 0 : #define USB_DESC_DFU_FUNCTIONAL 0x21
49 :
50 : /* DFU attributes DFU Functional Descriptor */
51 0 : #define USB_DFU_ATTR_WILL_DETACH BIT(3)
52 0 : #define USB_DFU_ATTR_MANIFESTATION_TOLERANT BIT(2)
53 0 : #define USB_DFU_ATTR_CAN_UPLOAD BIT(1)
54 0 : #define USB_DFU_ATTR_CAN_DNLOAD BIT(0)
55 :
56 : /* DFU Specification release */
57 0 : #define USB_DFU_VERSION 0x0110
58 :
59 : /* DFU device status */
60 0 : enum usb_dfu_status {
61 : ERR_OK = 0x00,
62 : ERR_TARGET = 0x01,
63 : ERR_FILE = 0x02,
64 : ERR_WRITE = 0x03,
65 : ERR_ERASE = 0x04,
66 : ERR_CHECK_ERASED = 0x05,
67 : ERR_PROG = 0x06,
68 : ERR_VERIFY = 0x07,
69 : ERR_ADDRESS = 0x08,
70 : ERR_NOTDONE = 0x09,
71 : ERR_FIRMWARE = 0x0A,
72 : ERR_VENDOR = 0x0B,
73 : ERR_USBR = 0x0C,
74 : ERR_POR = 0x0D,
75 : ERR_UNKNOWN = 0x0E,
76 : ERR_STALLEDPKT = 0x0F,
77 : };
78 :
79 : /* DFU device states */
80 0 : enum usb_dfu_state {
81 : APP_IDLE = 0,
82 : APP_DETACH = 1,
83 : DFU_IDLE = 2,
84 : DFU_DNLOAD_SYNC = 3,
85 : DFU_DNBUSY = 4,
86 : DFU_DNLOAD_IDLE = 5,
87 : DFU_MANIFEST_SYNC = 6,
88 : DFU_MANIFEST = 7,
89 : DFU_MANIFEST_WAIT_RST = 8,
90 : DFU_UPLOAD_IDLE = 9,
91 : DFU_ERROR = 10,
92 : DFU_STATE_MAX = 11,
93 : };
94 :
95 0 : struct usbd_dfu_image {
96 0 : const char *name;
97 0 : struct usb_if_descriptor *const if_desc;
98 0 : void *const priv;
99 0 : struct usbd_desc_node *const sd_nd;
100 0 : bool (*next_cb)(void *const priv,
101 : const enum usb_dfu_state state, const enum usb_dfu_state next);
102 0 : int (*read_cb)(void *const priv,
103 : const uint32_t block, const uint16_t size,
104 : uint8_t buf[static CONFIG_USBD_DFU_TRANSFER_SIZE]);
105 0 : int (*write_cb)(void *const priv,
106 : const uint32_t block, const uint16_t size,
107 : const uint8_t buf[static CONFIG_USBD_DFU_TRANSFER_SIZE]);
108 : };
109 :
110 : /**
111 : * @brief USB DFU device update API
112 : * @defgroup usbd_dfu USB DFU device update API
113 : * @ingroup usb
114 : * @since 4.1
115 : * @version 0.1.0
116 : * @{
117 : */
118 :
119 : /**
120 : * @brief Define USB DFU image
121 : *
122 : * Use this macro to create USB DFU image
123 : *
124 : * The callbacks must be in form:
125 : *
126 : * @code{.c}
127 : * static int read(void *const priv, const uint32_t block, const uint16_t size,
128 : * uint8_t buf[static CONFIG_USBD_DFU_TRANSFER_SIZE])
129 : * {
130 : * int len;
131 : *
132 : * return len;
133 : * }
134 : *
135 : * static int write(void *const priv, const uint32_t block, const uint16_t size,
136 : * const uint8_t buf[static CONFIG_USBD_DFU_TRANSFER_SIZE])
137 : * {
138 : * return 0;
139 : * }
140 : *
141 : * static bool next(void *const priv,
142 : * const enum usb_dfu_state state, const enum usb_dfu_state next)
143 : * {
144 : * return true;
145 : * }
146 : * @endcode
147 : *
148 : * @param id Identifier by which the linker sorts registered images
149 : * @param iname Image name as used in interface descriptor
150 : * @param iread Image read callback
151 : * @param iwrite Image write callback
152 : * @param inext Notify/confirm next state
153 : */
154 1 : #define USBD_DFU_DEFINE_IMG(id, iname, ipriv, iread, iwrite, inext) \
155 : static __noinit struct usb_if_descriptor usbd_dfu_iface_##id; \
156 : \
157 : USBD_DESC_STRING_DEFINE(usbd_dfu_str_##id, iname, USBD_DUT_STRING_INTERFACE); \
158 : \
159 : static const STRUCT_SECTION_ITERABLE(usbd_dfu_image, usbd_dfu_image_##id) = { \
160 : .name = iname, \
161 : .if_desc = &usbd_dfu_iface_##id, \
162 : .priv = ipriv, \
163 : .sd_nd = &usbd_dfu_str_##id, \
164 : .read_cb = iread, \
165 : .write_cb = iwrite, \
166 : .next_cb = inext, \
167 : }
168 :
169 : /**
170 : * @}
171 : */
172 : #endif /* ZEPHYR_INCLUDE_USB_CLASS_USBD_DFU_H */
|