2 * boot/dfu_common.c - DFU protocol engine parts common to App/DFU
4 * Written 2008-2011, 2013-2014 by Werner Almesberger
5 * Copyright 2008-2011, 2013-2014 Werner Almesberger
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
14 * http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf
18 * A few, erm, shortcuts:
20 * - we don't bother with the app* states since DFU is all this firmware does
21 * - after DFU_DNLOAD, we just block until things are written, so we never
22 * enter dfuDNLOAD_SYNC or dfuDNBUSY
23 * - no dfuMANIFEST_SYNC, dfuMANIFEST, or dfuMANIFEST_WAIT_RESET
24 * - to keep our buffers small, we only accept EP0-sized blocks
35 #include "../sernum.h"
46 static const uint8_t functional_descriptor[] = {
48 DFU_DT_FUNCTIONAL, /* bDescriptorType */
49 0xf, /* bmAttributes (claim omnipotence :-) */
50 LE(0xffff), /* wDetachTimeOut (we're very patient) */
51 LE(EP0_SIZE), /* wTransferSize */
52 LE(0x101), /* bcdDFUVersion */
57 * The worst-case activity would be flashing a one page and erasing another
58 * one, would should take less than 10 ms. A 100 ms timeout ought to be plenty.
63 LE(100), 0, /* bwPollTimeout, 100 ms */
69 bool dfu_setup_common(const struct setup_request *setup)
71 switch (setup->bmRequestType | setup->bRequest << 8) {
72 case DFU_FROM_DEV(DFU_GETSTATUS):
73 debug("DFU_GETSTATUS\n");
74 usb_send(&eps[0], (uint8_t *) &dfu, sizeof(dfu), NULL, NULL);
76 case DFU_TO_DEV(DFU_CLRSTATUS):
77 debug("DFU_CLRSTATUS\n");
81 case DFU_FROM_DEV(DFU_GETSTATE):
82 debug("DFU_GETSTATE\n");
83 usb_send(&eps[0], &dfu.state, 1, NULL, NULL);
86 error("DFU rt %x, rq%x ?\n",
87 setup->bmRequestType, setup->bRequest);
93 bool dfu_my_descr(uint8_t type, uint8_t index, const uint8_t **reply,
96 if (type != DFU_DT_FUNCTIONAL)
97 return sernum_get_descr(type, index, reply, size);
98 *reply = functional_descriptor;
99 *size = sizeof(functional_descriptor);