X-Git-Url: https://jxself.org/git/?p=linux-libre-firmware.git;a=blobdiff_plain;f=atusb%2Fusb%2Fdfu_common.c;fp=atusb%2Fusb%2Fdfu_common.c;h=9b6feef546a3f69f9e677bd8655d4960e4d8806c;hp=0000000000000000000000000000000000000000;hb=dd4bc9ff49b9a7075e579fdd62fd930d27a9a7df;hpb=c164bf7f87f9081fee7e1a186dd7a87a9a020b9e diff --git a/atusb/usb/dfu_common.c b/atusb/usb/dfu_common.c new file mode 100644 index 0000000..9b6feef --- /dev/null +++ b/atusb/usb/dfu_common.c @@ -0,0 +1,101 @@ +/* + * boot/dfu_common.c - DFU protocol engine parts common to App/DFU + * + * Written 2008-2011, 2013-2014 by Werner Almesberger + * Copyright 2008-2011, 2013-2014 Werner Almesberger + * + * 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 2 of the License, or + * (at your option) any later version. + */ + +/* + * http://www.usb.org/developers/devclass_docs/DFU_1.1.pdf + */ + +/* + * A few, erm, shortcuts: + * + * - we don't bother with the app* states since DFU is all this firmware does + * - after DFU_DNLOAD, we just block until things are written, so we never + * enter dfuDNLOAD_SYNC or dfuDNBUSY + * - no dfuMANIFEST_SYNC, dfuMANIFEST, or dfuMANIFEST_WAIT_RESET + * - to keep our buffers small, we only accept EP0-sized blocks + */ + + +#include +#include + +#include "usb.h" +#include "dfu.h" + +#include "board.h" +#include "../sernum.h" + + +#ifndef NULL +#define NULL 0 +#endif + +#define debug(...) +#define error(...) + + +static const uint8_t functional_descriptor[] = { + 9, /* bLength */ + DFU_DT_FUNCTIONAL, /* bDescriptorType */ + 0xf, /* bmAttributes (claim omnipotence :-) */ + LE(0xffff), /* wDetachTimeOut (we're very patient) */ + LE(EP0_SIZE), /* wTransferSize */ + LE(0x101), /* bcdDFUVersion */ +}; + + +/* + * The worst-case activity would be flashing a one page and erasing another + * one, would should take less than 10 ms. A 100 ms timeout ought to be plenty. + */ + +struct dfu dfu = { + OK, /* bStatus */ + LE(100), 0, /* bwPollTimeout, 100 ms */ + dfuIDLE, /* bState */ + 0, /* iString */ +}; + + +bool dfu_setup_common(const struct setup_request *setup) +{ + switch (setup->bmRequestType | setup->bRequest << 8) { + case DFU_FROM_DEV(DFU_GETSTATUS): + debug("DFU_GETSTATUS\n"); + usb_send(&eps[0], (uint8_t *) &dfu, sizeof(dfu), NULL, NULL); + return 1; + case DFU_TO_DEV(DFU_CLRSTATUS): + debug("DFU_CLRSTATUS\n"); + dfu.state = dfuIDLE; + dfu.status = OK; + return 1; + case DFU_FROM_DEV(DFU_GETSTATE): + debug("DFU_GETSTATE\n"); + usb_send(&eps[0], &dfu.state, 1, NULL, NULL); + return 1; + default: + error("DFU rt %x, rq%x ?\n", + setup->bmRequestType, setup->bRequest); + return 0; + } +} + + +bool dfu_my_descr(uint8_t type, uint8_t index, const uint8_t **reply, + uint8_t *size) +{ + if (type != DFU_DT_FUNCTIONAL) + return sernum_get_descr(type, index, reply, size); + *reply = functional_descriptor; + *size = sizeof(functional_descriptor); + return 1; +}