1 /*
2  * Copyright (c) 2021, STMicroelectronics - All Rights Reserved
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef USB_DFU_H
8 #define USB_DFU_H
9 
10 #include <stdint.h>
11 
12 #include <drivers/usb_device.h>
13 
14 #define DFU_DESCRIPTOR_TYPE		0x21U
15 
16 /* Max DFU Packet Size = 1024 bytes */
17 #define USBD_DFU_XFER_SIZE		1024U
18 
19 #define TRANSFER_SIZE_BYTES(size) \
20 	((uint8_t)((size) & 0xFF)), /* XFERSIZEB0 */\
21 	((uint8_t)((size) >> 8))    /* XFERSIZEB1 */
22 
23 /*
24  * helper for descriptor of DFU interface 0 Alternate setting n
25  * with iInterface = index of string descriptor, assumed Nth user string
26  */
27 #define USBD_DFU_IF_DESC(n)	0x09U, /* Interface Descriptor size */\
28 				USB_DESC_TYPE_INTERFACE, /* descriptor type */\
29 				0x00U, /* Number of Interface */\
30 				(n), /* Alternate setting */\
31 				0x00U, /* bNumEndpoints*/\
32 				0xFEU, /* Application Specific Class Code */\
33 				0x01U, /* Device Firmware Upgrade Code */\
34 				0x02U, /* DFU mode protocol */ \
35 				USBD_IDX_USER0_STR + (n) /* iInterface */
36 
37 /* DFU1.1 Standard */
38 #define USB_DFU_VERSION			0x0110U
39 #define USB_DFU_ITF_SIZ			9U
40 #define USB_DFU_DESC_SIZ(itf)		(USB_DFU_ITF_SIZ * ((itf) + 2U))
41 
42 /*
43  * bmAttribute value for DFU:
44  * bitCanDnload = 1(bit 0)
45  * bitCanUpload = 1(bit 1)
46  * bitManifestationTolerant = 1 (bit 2)
47  * bitWillDetach = 1(bit 3)
48  * Reserved (bit4-6)
49  * bitAcceleratedST = 0(bit 7)
50  */
51 #define DFU_BM_ATTRIBUTE		0x0FU
52 
53 #define DFU_STATUS_SIZE			6U
54 
55 /* Callback for media access */
56 struct usb_dfu_media {
57 	int (*upload)(uint8_t alt, uintptr_t *buffer, uint32_t *len,
58 		      void *user_data);
59 	int (*download)(uint8_t alt, uintptr_t *buffer, uint32_t *len,
60 			void *user_data);
61 	int (*manifestation)(uint8_t alt, void *user_data);
62 };
63 
64 /* Internal DFU handle */
65 struct usb_dfu_handle {
66 	uint8_t status[DFU_STATUS_SIZE];
67 	uint8_t dev_state;
68 	uint8_t dev_status;
69 	uint8_t alt_setting;
70 	const struct usb_dfu_media *callback;
71 };
72 
73 void usb_dfu_register(struct usb_handle *pdev, struct usb_dfu_handle *phandle);
74 
75 int usb_dfu_loop(struct usb_handle *pdev, const struct usb_dfu_media *pmedia);
76 
77 /* Function provided by plat */
78 struct usb_handle *usb_dfu_plat_init(void);
79 
80 #endif /* USB_DFU_H */
81