-
Notifications
You must be signed in to change notification settings - Fork 270
/
dfu.h
193 lines (153 loc) · 5.42 KB
/
dfu.h
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/* Copyright (c) 2011,2012 Simon Schubert <[email protected]>.
* Modifications by Jacob Alexander 2014-2020 <[email protected]>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
// ----- Compiler Includes -----
// Local Includes
#include "usb.h"
// Compiler Includes
#include <sys/types.h>
#include <stdint.h>
// ----- Defines -----
#define USB_FUNCTION_DFU_IFACE_COUNT 1
#ifndef USB_DFU_TRANSFER_SIZE
// Sector size is the same as the program flash size
#if defined(_mk20dx128vlf5_) || defined(_mk20dx128vlh7_)
#define USB_DFU_TRANSFER_SIZE FLASH_SECTOR_SIZE
// Sector size is double the program flash size
#elif defined(_mk20dx256vlh7_ )
#define USB_DFU_TRANSFER_SIZE FLASH_SECTOR_SIZE / 2
// XXX (HaaTa) Determine sector size for mk22
// Sector size is double the program flash size
#elif defined(_mk22fx512avlh12_)
#define USB_DFU_TRANSFER_SIZE FLASH_SECTOR_SIZE / 2
// 16 pages is the smallest erase for 48/64k areas, Section 8.1.3.1
#elif defined(_sam4s_)
#define USB_DFU_TRANSFER_SIZE (8*FLASH_PAGE_SIZE) //4096
#endif
#endif
#define USB_FUNCTION_DESC_DFU_DECL struct dfu_function_desc
#define USB_FUNCTION_DFU_IFACE_COUNT 1
#define USB_FUNCTION_DFU_RX_EP_COUNT 0
#define USB_FUNCTION_DFU_TX_EP_COUNT 0
// ----- Enumerations -----
enum dfu_dev_subclass {
USB_DEV_SUBCLASS_APP_DFU = 0x01,
};
enum dfu_dev_proto {
USB_DEV_PROTO_DFU_APP = 0x01,
USB_DEV_PROTO_DFU_DFU = 0x02,
};
enum dfu_ctrl_req_code {
USB_CTRL_REQ_DFU_DETACH = 0,
USB_CTRL_REQ_DFU_DNLOAD = 1,
USB_CTRL_REQ_DFU_UPLOAD = 2,
USB_CTRL_REQ_DFU_GETSTATUS = 3,
USB_CTRL_REQ_DFU_CLRSTATUS = 4,
USB_CTRL_REQ_DFU_GETSTATE = 5,
USB_CTRL_REQ_DFU_ABORT = 6,
};
enum dfu_status {
DFU_STATUS_async = 0xff,
DFU_STATUS_OK = 0x00,
DFU_STATUS_errTARGET = 0x01,
DFU_STATUS_errFILE = 0x02,
DFU_STATUS_errWRITE = 0x03,
DFU_STATUS_errERASE = 0x04,
DFU_STATUS_errCHECK_ERASED = 0x05,
DFU_STATUS_errPROG = 0x06,
DFU_STATUS_errVERIFY = 0x07,
DFU_STATUS_errADDRESS = 0x08,
DFU_STATUS_errNOTDONE = 0x09,
DFU_STATUS_errFIRMWARE = 0x0a,
DFU_STATUS_errVENDOR = 0x0b,
DFU_STATUS_errUSBR = 0x0c,
DFU_STATUS_errPOR = 0x0d,
DFU_STATUS_errUNKNOWN = 0x0e,
DFU_STATUS_errSTALLEDPKT = 0x0f,
};
enum dfu_state {
DFU_STATE_appIDLE = 0,
DFU_STATE_appDETACH = 1,
DFU_STATE_dfuIDLE = 2,
DFU_STATE_dfuDNLOAD_SYNC = 3,
DFU_STATE_dfuDNBUSY = 4,
DFU_STATE_dfuDNLOAD_IDLE = 5,
DFU_STATE_dfuMANIFEST_SYNC = 6,
DFU_STATE_dfuMANIFEST = 7,
DFU_STATE_dfuMANIFEST_WAIT_RESET = 8,
DFU_STATE_dfuUPLOAD_IDLE = 9,
DFU_STATE_dfuERROR = 10,
};
// Custom Kiibohd Bootloader Type
enum dfu_validation {
DFU_VALIDATION_UNKNOWN = 0, // Secure key has not been checked
DFU_VALIDATION_PENDING = 1, // Secure key has been validated, but we're not finished yet
DFU_VALIDATION_OK = 2, // Secure key has been validated and used
DFU_VALIDATION_FAILED = 3, // Secure key validation failed
};
// ----- Structs -----
struct dfu_status_t {
enum dfu_status bStatus : 8;
uint32_t bwPollTimeout : 24;
enum dfu_state bState : 8;
uint8_t iString;
} __packed;
CTASSERT_SIZE_BYTE(struct dfu_status_t, 6);
typedef enum dfu_status (*dfu_setup_read_t)(size_t off, size_t *len, void **buf, uint8_t bAlternateSetting);
typedef enum dfu_status (*dfu_setup_write_t)(size_t off, size_t len, void **buf, uint8_t bAlternateSetting);
typedef enum dfu_status (*dfu_finish_write_t)(void *, size_t off, size_t len, uint8_t bAlternateSetting);
typedef void (*dfu_detach_t)(void);
struct dfu_ctx {
struct usbd_function_ctx_header header;
enum dfu_state state;
enum dfu_status status;
dfu_setup_read_t setup_read;
dfu_setup_write_t setup_write;
dfu_finish_write_t finish_write;
size_t off;
size_t len;
enum dfu_validation verified;
};
struct dfu_desc_functional {
uint8_t bLength;
struct usb_desc_type_t bDescriptorType; /* = class DFU/0x1 FUNCTIONAL */
union {
struct {
uint8_t can_download : 1;
uint8_t can_upload : 1;
uint8_t manifestation_tolerant : 1;
uint8_t will_detach : 1;
uint8_t _rsvd0 : 4;
};
uint8_t bmAttributes;
};
uint16_t wDetachTimeOut;
uint16_t wTransferSize;
struct usb_bcd_t bcdDFUVersion;
} __packed;
CTASSERT_SIZE_BYTE(struct dfu_desc_functional, 9);
struct dfu_function_desc {
struct usb_desc_iface_t iface;
struct dfu_desc_functional dfu;
};
extern const struct usbd_function dfu_function;
extern const struct usbd_function dfu_app_function;
// ----- Functions -----
void dfu_write_done( enum dfu_status, struct dfu_ctx *ctx );
void dfu_init( dfu_setup_read_t setup_read, dfu_setup_write_t setup_write, dfu_finish_write_t finish_write, struct dfu_ctx *ctx );
void dfu_app_init( dfu_detach_t detachcb );
int dfu_handle_control( struct usb_ctrl_req_t *req, void *data );