aboutsummaryrefslogtreecommitdiffstats
path: root/firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h
blob: 5bd8684eab28ab6a2f798f7a69b8af46cb738ce6 (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
#ifndef _USB_DEV_DFU_H
#define _USB_DEV_DFU_H

#include <stdint.h>
#include <board.h>
#include <usb/include/USBDescriptors.h>
#include <usb/include/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,				\
}

/* Number of DFU interface during runtime mode */
#define DFURT_NUM_IF		1

/* to be used by the runtime as part of its USB descriptor structure
 * declaration */
#define DFURT_IF_DESCRIPTOR_STRUCT		\
	USBInterfaceDescriptor	dfu_rt;		\
	struct usb_dfu_func_descriptor func_dfu;

/* to be used by the runtime as part of its USB Dsecriptor structure
 * definition */
#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						\

/* provided by dfu_desc.c */
extern const struct dfu_desc dfu_cfg_descriptor;
extern const USBDDriverDescriptors dfu_descriptors;

#else /* BOARD_USB_DFU */

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

#endif /* BOARD_USB_DFU */

/* magic value we use during boot to detect if we should start in DFU
 * mode or runtime mode */
#define USB_DFU_MAGIC	0xDFDFDFDF

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

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

/* RAM address for this magic value above */
extern struct dfudata _g_dfu;
extern struct dfudata *g_dfu;

void set_usb_serial_str(void);

void DFURT_SwitchToDFU(void);

/* call-backs from DFU USB function driver to 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);
extern int USBDFU_OverrideEnterDFU(void);

/* function to be called at end of EP0 handler during runtime */
void USBDFU_Runtime_RequestHandler(const USBGenericRequest *request);

/* function to be called at end of EP0 handler during DFU mode */
void USBDFU_DFU_RequestHandler(const USBGenericRequest *request);

/* initialization of USB DFU driver (in DFU mode */
void USBDFU_Initialize(const USBDDriverDescriptors *pDescriptors);

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

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

/* Return values to be used by USBDFU_handle_{dn,up}load */
#define DFU_RET_NOTHING	0
#define DFU_RET_ZLP	1
#define DFU_RET_STALL	2

#endif