summaryrefslogtreecommitdiff
path: root/usb/device/dfu/dfu.h
blob: f0e86f4ec31d7ff34f56591767836934e10d3ce7 (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
#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 DFURT_NUM_IF		1

#define DFURT_IF_DESCRIPTOR_STRUCT		\
	USBInterfaceDescriptor	dfu_rt;		\
	struct usb_dfu_func_descriptor func_dfu;


#define DFURT_IF_DESCRIPTOR(dfuIF, dfuSTR)					\
	.dfu_rt = {								\
		.bLength 		= sizeof(USBInterfaceDescriptor),	\
		.bDescriptorType	= USBGenericDescriptor_INTERFACE,	\
		.bInterfaceNumber	= dfuIF,				\
		.bAlternateSetting	= 0,					\
		.bNumEndpoints		= 0,					\
		.bInterfaceClass	= 0xFE,					\
		.bInterfaceSubClass	= 0x01,					\
		.bInterfaceProtocol	= 0x01,					\
		.iInterface		= dfuSTR,				\
	},									\
	.func_dfu = DFU_FUNC_DESC						\

const struct dfu_desc dfu_cfg_descriptor;
const USBDDriverDescriptors dfu_descriptors;

#else /* BOARD_USB_DFU */

/* no DFU bootloader is being used */
#define DFURT_NUM_IF	0
#define DFURT_IF_DESCRIPTOR_STRUCT(a, b)
#define DFURT_IF_DESCRIPTOR

#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