summaryrefslogtreecommitdiff
path: root/usb/device/dfu/dfu.h
blob: 52b4ea5e15f40aa1d1a1b5d528e7d54689193e76 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#ifndef _USB_DEV_DFU_H
#define _USB_DEV_DFU_H

#include <stdint.h>
#include <board.h>
#include <usb/common/core/USBGenericDescriptor.h>
#include <usb/common/core/USBGenericDescriptor.h>
#include <usb/device/core/USBDDriver.h>

#if 0
/* This is valid for CCID */
#define CONFIG_DFU_NUM_APP_IF	1
#define CONFIG_DFU_NUM_APP_STR	4
#else
/* This is valid for CDC-Serial */
#define CONFIG_DFU_NUM_APP_IF	2
#define CONFIG_DFU_NUM_APP_STR	2
#endif

struct USBStringDescriptor {
	USBGenericDescriptor hdr;
	unsigned short wData[];
} __attribute__((packed));


#ifdef BOARD_USB_DFU

#include <usb/common/dfu/usb_dfu.h>

/* for board-specific config */
#include <board.h>

struct dfu_desc {
	USBConfigurationDescriptor ucfg;
	USBInterfaceDescriptor uif[BOARD_DFU_NUM_IF];
	struct usb_dfu_func_descriptor func_dfu;
} __attribute__ ((packed));

/* USB DFU functional descriptor */
#define DFU_FUNC_DESC  {						\
	.bLength		= USB_DT_DFU_SIZE,			\
	.bDescriptorType	= USB_DT_DFU,				\
	.bmAttributes		= USB_DFU_CAN_UPLOAD | USB_DFU_CAN_DOWNLOAD, \
	.wDetachTimeOut		= 0xff00,				\
	.wTransferSize		= BOARD_DFU_PAGE_SIZE,			\
	.bcdDFUVersion		= 0x0100,				\
}

#define DFU_IF_DESCRIPTORS_STRUCT		\
	USBInterfaceDescriptor	dfu_interface[DFU_NUM_IF];

#define DFU_IF_DESCRIPTORS			{ 				\
	{									\
		.bLength 		= sizeof(USBInterfaceDescriptor),	\
		.bDescriptorType	= USBGenericDescriptor_INTERFACE,	\
		.bInterfaceNumber	= CONFIG_DFU_NUM_APP_IF,		\
		.bAlternateSetting	= 0,					\
		.bNumEndpoints		= 0,					\
		.bInterfaceClass	= 0xFE,					\
		.bInterfaceSubClass	= 0x01,					\
		.bInterfaceProtocol	= 0x01,					\
		.iInterface		= CONFIG_DFU_NUM_APP_STR,		\
	},									\
	{									\
		.bLength 		= sizeof(USBInterfaceDescriptor),	\
		.bDescriptorType	= USBGenericDescriptor_INTERFACE,	\
		.bInterfaceNumber	= CONFIG_DFU_NUM_APP_IF+1,		\
		.bAlternateSetting	= 0,					\
		.bNumEndpoints		= 0,					\
		.bInterfaceClass	= 0xFE,					\
		.bInterfaceSubClass	= 0x01,					\
		.bInterfaceProtocol	= 0x01,					\
		.iInterface		= CONFIG_DFU_NUM_APP_STR+1,		\
	},									\
	{									\
		.bLength 		= sizeof(USBInterfaceDescriptor),	\
		.bDescriptorType	= USBGenericDescriptor_INTERFACE,	\
		.bInterfaceNumber	= CONFIG_DFU_NUM_APP_IF+2,		\
		.bAlternateSetting	= 0,					\
		.bNumEndpoints		= 0,					\
		.bInterfaceClass	= 0xFE,					\
		.bInterfaceSubClass	= 0x01,					\
		.bInterfaceProtocol	= 0x01,					\
		.iInterface		= CONFIG_DFU_NUM_APP_STR+2,		\
	},									\
}

extern const struct USBStringDescriptor USBDFU_string1;
extern const struct USBStringDescriptor USBDFU_string2;
extern const struct USBStringDescriptor USBDFU_string3;

#define DFU_NUM_STRINGS	3
#define DFU_STRING_DESCRIPTORS	\
	(const unsigned char *) &USBDFU_string1,	\
	(const unsigned char *) &USBDFU_string2,	\
	(const unsigned char *) &USBDFU_string3,

const struct dfu_desc dfu_cfg_descriptor;
const USBDDriverDescriptors dfu_descriptors;

#else /* BOARD_USB_DFU */

/* no DFU bootloader is being used */
#define DFU_NUM_IF	0
#define DFU_IF_DESCRIPTORS_STRUCT
#define DFU_IF_DESCRIPTORS

#define DFU_NUM_STRINGS	0
#define DFU_STRING_DESCRIPTORS

#endif /* BOARD_USB_DFU */

#define USB_DFU_MAGIC	0xDFDFDFDF
#define USB_DFU_MAGIC_ADDR	AT91C_IRAM

/* The API between the core DFU handler and the board/soc specific code */

struct dfudata {
	uint8_t status;
	uint32_t state;
	int past_manifest;
	unsigned int total_bytes;
};

extern struct dfudata g_dfu;

void set_usb_serial_str(const uint8_t *serial_usbstr);

void DFURT_SwitchToDFU(void);

/* call-backs by the board/SOC */
extern int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
				uint8_t *data, unsigned int len);
extern int USBDFU_handle_upload(uint8_t altif, unsigned int offset,
				uint8_t *data, unsigned int req_len);

void USBDFU_Runtime_RequestHandler(const USBGenericRequest *request);
void USBDFU_DFU_RequestHandler(const USBGenericRequest *request);

void USBDFU_Initialize(const USBDDriverDescriptors *pDescriptors);

/* USBD tells us to switch from DFU mode to application mode */
void USBDFU_SwitchToApp(void);

#define DFU_RET_NOTHING	0
#define DFU_RET_ZLP	1
#define DFU_RET_STALL	2

#endif
personal git repositories of Harald Welte. Your mileage may vary