Date:2014-03-24 21:18:02 (5 years 7 months ago)
Author:Werner Almesberger
Commit:8f2f13c30a2b9b4305ba656e34c28ab35fb49212
Message:atusb/fw/: DFU: support multiple sets of flash operations; support multiple alt settings

Files: atusb/fw/descr.c (2 diffs)
atusb/fw/flash.c (5 diffs)
atusb/fw/usb/dfu.c (9 diffs)
atusb/fw/usb/dfu.h (3 diffs)

Change Details

atusb/fw/descr.c
11/*
22 * fw/descr.c - USB descriptors
33 *
4 * Written 2008-2011 by Werner Almesberger
5 * Copyright 2008-2011 Werner Almesberger
4 * Written 2008-2011, 2014 by Werner Almesberger
5 * Copyright 2008-2011, 2014 Werner Almesberger
66 *
77 * This program is free software; you can redistribute it and/or modify
88 * it under the terms of the GNU General Public License as published by
...... 
100100
101101    /* Interface #1 */
102102
103    DFU_ITF_DESCR(1, dfu_proto_runtime)
103    DFU_ITF_DESCR(1, 0, dfu_proto_runtime)
104104};
atusb/fw/flash.c
11/*
22 * fw/flash.c - Board-specific flash functions
33 *
4 * Written 2011, 2013 by Werner Almesberger
5 * Copyright 2011, 2013 Werner Almesberger
4 * Written 2011, 2013, 2014 by Werner Almesberger
5 * Copyright 2011, 2013, 2014 Werner Almesberger
66 *
77 * This program is free software; you can redistribute it and/or modify
88 * it under the terms of the GNU General Public License as published by
...... 
2424static uint32_t payload;
2525
2626
27void flash_start(void)
27static void flash_start(void)
2828{
2929    payload = 0;
3030}
3131
3232
33bool flash_can_write(uint16_t size)
33static bool flash_can_write(uint16_t size)
3434{
3535    return payload+size <= BOOT_ADDR;
3636}
3737
3838
39void flash_write(const uint8_t *buf, uint16_t size)
39static void flash_write(const uint8_t *buf, uint16_t size)
4040{
4141    static uint8_t last;
4242        const uint8_t *p;
...... 
6161}
6262
6363
64void flash_end_write(void)
64static void flash_end_write(void)
6565{
6666    if (payload & (SPM_PAGESIZE-1)) {
6767        boot_page_write(payload & ~(SPM_PAGESIZE-1));
...... 
7171}
7272
7373
74uint16_t flash_read(uint8_t *buf, uint16_t size)
74static uint16_t flash_read(uint8_t *buf, uint16_t size)
7575{
7676    uint16_t got = 0;
7777
...... 
8383    }
8484    return got;
8585}
86
87
88static struct dfu_flash_ops flash_ops = {
89    .start = flash_start,
90    .can_write = flash_can_write,
91    .write = flash_write,
92    .end_write = flash_end_write,
93    .read = flash_read,
94};
95
96
97struct dfu_flash_ops *dfu_flash_ops = &flash_ops;
atusb/fw/usb/dfu.c
4242#define error(...)
4343
4444
45#ifndef DFU_ALT_SETTINGS
46#define DFU_ALT_SETTINGS 1
47#endif
48
49
4550const uint8_t device_descriptor[] = {
4651    18, /* bLength */
4752    USB_DT_DEVICE, /* bDescriptorType */
...... 
6772const uint8_t config_descriptor[] = {
6873    9, /* bLength */
6974    USB_DT_CONFIG, /* bDescriptorType */
70    LE(9+9), /* wTotalLength */
75    LE(9+9*DFU_ALT_SETTINGS), /* wTotalLength */
7176    1, /* bNumInterfaces */
7277    1, /* bConfigurationValue (> 0 !) */
7378    0, /* iConfiguration */
...... 
7782
7883    /* Interface #0 */
7984
80    DFU_ITF_DESCR(0, dfu_proto_dfu)
85    DFU_ITF_DESCR(0, 0, dfu_proto_dfu)
86#if DFU_ALT_SETTINGS >= 1
87    DFU_ITF_DESCR(0, 1, dfu_proto_dfu)
88#endif
89#if DFU_ALT_SETTINGS >= 2
90    DFU_ITF_DESCR(0, 2, dfu_proto_dfu)
91#endif
8192};
8293
8394
...... 
92103{
93104    uint16_t *size = user;
94105
95    flash_write(buf, *size);
106    dfu_flash_ops->write(buf, *size);
96107}
97108
98109
...... 
100111{
101112    static uint16_t size;
102113
103    if (!flash_can_write(length)) {
114    if (!dfu_flash_ops->can_write(length)) {
104115        dfu.state = dfuERROR;
105116        dfu.status = errADDRESS;
106117        return 0;
...... 
125136        dfu.status = errUNKNOWN;
126137        return 1;
127138    }
128    got = flash_read(buf, length);
139    got = dfu_flash_ops->read(buf, length);
129140    if (got < length) {
130141        length = got;
131142        dfu.state = dfuIDLE;
...... 
152163        debug("DFU_DNLOAD\n");
153164        if (dfu.state == dfuIDLE) {
154165            next_block = setup->wValue;
155            flash_start();
166            dfu_flash_ops->start();
156167        }
157168        else if (dfu.state != dfuDNLOAD_IDLE) {
158169            error("bad state\n");
...... 
171182        }
172183        if (!setup->wLength) {
173184            debug("DONE\n");
174            flash_end_write();
185            dfu_flash_ops->end_write();
175186            dfu.state = dfuIDLE;
176187            did_download = 1;
177188            return 1;
...... 
184195        debug("DFU_UPLOAD\n");
185196        if (dfu.state == dfuIDLE) {
186197            next_block = setup->wValue;
187            flash_start();
198            dfu_flash_ops->start();
188199        }
189200        else if (dfu.state != dfuUPLOAD_IDLE)
190201            return 0;
atusb/fw/usb/dfu.h
11/*
22 * boot/dfu.h - DFU protocol constants and data structures
33 *
4 * Written 2008, 2011, 2013 by Werner Almesberger
5 * Copyright 2008, 2011, 2013 Werner Almesberger
4 * Written 2008, 2011, 2013, 2014 by Werner Almesberger
5 * Copyright 2008, 2011, 2013, 2014 Werner Almesberger
66 *
77 * This program is free software; you can redistribute it and/or modify
88 * it under the terms of the GNU General Public License as published by
...... 
8686};
8787
8888
89#define DFU_ITF_DESCR(itf, proto) \
89#define DFU_ITF_DESCR(itf, alt, proto) \
9090    9, /* bLength */ \
9191    USB_DT_INTERFACE, /* bDescriptorType */ \
9292    (itf), /* bInterfaceNumber */ \
93    0, /* bAlternateSetting */ \
93    (alt), /* bAlternateSetting */ \
9494    0, /* bNumEndpoints */ \
9595    0xfe, /* bInterfaceClass (application specific) */ \
9696    0x01, /* bInterfaceSubClass (device fw upgrade) */ \
...... 
9898    0, /* iInterface */
9999
100100
101extern struct dfu dfu;
101struct dfu_flash_ops {
102    void (*start)(void);
103    bool (*can_write)(uint16_t size);
104    void (*write)(const uint8_t *buf, uint16_t size);
105    void (*end_write)(void);
106    uint16_t (*read)(uint8_t *buf, uint16_t size);
107};
102108
109extern struct dfu dfu;
110extern struct dfu_flash_ops *dfu_flash_ops;
103111
104void flash_start(void);
105bool flash_can_write(uint16_t size);
106void flash_write(const uint8_t *buf, uint16_t size);
107void flash_end_write(void);
108uint16_t flash_read(uint8_t *buf, uint16_t size);
109112
110113bool dfu_setup_common(const struct setup_request *setup);
111114bool dfu_my_descr(uint8_t type, uint8_t index, const uint8_t **reply,

Archive Download the corresponding diff file



interactive