Date:2011-03-08 23:10:58 (8 years 4 months ago)
Author:Werner Almesberger
Commit:f91738c306deb4c91ca57bef807f78fa8f224d09
Message:atusb/fw/usb/: adapted DFU engine to current stack and abstracted Flash ops

- dfu.c: updated includes
- dfu.c (device_descriptor): renamed USB IDs from USB_VENDOR/PRODUCT to
DFU_USB_VENDOR/PRODUCT to allow differentiation
- dfu.c: changed all __bit to "int"
- dfu.c: removed all __xdata and __reentrant
- dfu.c: changed "ep0" to "eps[0]"
- dfu.c (payload, flash_erase_page, flash_write_byte, block_write,
block_receive, block_transmit, my_setup): abstracted Flash interface
and removed target-specific operations
- dfu.h: added prototypes for target-specific Flash operations
- dfu,c (my_setup, my_descr): removed SDCC-specific hacks
- dfu.c (my_reset): commented out - did we actually use this ?
Files: atusb/fw/usb/dfu.c (12 diffs)
atusb/fw/usb/dfu.h (2 diffs)

Change Details

atusb/fw/usb/dfu.c
11/*
22 * boot/dfu.c - DFU protocol engine
33 *
4 * Written 2008-2010 by Werner Almesberger
5 * Copyright 2008-2010 Werner Almesberger
4 * Written 2008-2011 by Werner Almesberger
5 * Copyright 2008-2011 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
...... 
2727
2828#include <stdint.h>
2929
30#include "regs.h"
31#include "uart.h"
3230#include "usb.h"
3331#include "dfu.h"
3432
35#include "config.h"
33#include "../board.h"
3634
3735
3836#ifndef NULL
3937#define NULL 0
4038#endif
4139
42
43#define PAYLOAD_END (PAYLOAD_START+PAYLOAD_SIZE)
40#define debug(...)
41#define error(...)
4442
4543
4644const uint8_t device_descriptor[] = {
...... 
5149    0x00, /* bDeviceSubClass (per interface) */
5250    0x00, /* bDeviceProtocol (per interface) */
5351    EP0_SIZE, /* bMaxPacketSize */
54    LE(USB_VENDOR), /* idVendor */
55    LE(USB_PRODUCT), /* idProduct */
52    LE(DFU_USB_VENDOR), /* idVendor */
53    LE(DFU_USB_PRODUCT), /* idProduct */
5654    LE(0x0001), /* bcdDevice */
5755    0, /* iManufacturer */
5856    0, /* iProduct */
...... 
105103
106104
107105static uint16_t next_block = 0;
108static uint16_t payload;
109static __bit did_download;
110
111
112static __xdata uint8_t buf[EP0_SIZE];
113
114
115static void flash_erase_page(uint16_t addr)
116{
117    FLKEY = 0xa5;
118    FLKEY = 0xf1;
119    PSCTL |= PSEE;
120    PSCTL |= PSWE;
121    *(__xdata uint8_t *) addr = 0;
122    PSCTL &= ~PSWE;
123    PSCTL &= ~PSEE;
124}
106static int did_download;
125107
126108
127static void flash_write_byte(uint16_t addr, uint8_t value)
128{
129    FLKEY = 0xa5;
130    FLKEY = 0xf1;
131    PSCTL |= PSWE;
132    PSCTL &= ~PSEE;
133    *(__xdata uint8_t *) addr = value;
134    PSCTL &= ~PSWE;
135}
109static uint8_t buf[EP0_SIZE];
136110
137111
138112static void block_write(void *user)
139113{
140114    uint16_t *size = user;
141    uint8_t *p;
142115
143    for (p = buf; p != buf+*size; p++) {
144        if (!(payload & 511))
145            flash_erase_page(payload);
146        flash_write_byte(payload, *p);
147        payload++;
148    }
116    flash_write(buf, *size);
149117}
150118
151119
152static __bit block_receive(uint16_t length)
120static int block_receive(uint16_t length)
153121{
154122    static uint16_t size;
155123
156    if (payload < PAYLOAD_START || payload+length > PAYLOAD_END) {
124    if (!flash_can_write(length)) {
157125        dfu.state = dfuERROR;
158126        dfu.status = errADDRESS;
159127        return 0;
...... 
164132        return 0;
165133    }
166134    size = length;
167    usb_recv(&ep0, buf, size, block_write, &size);
135    usb_recv(&eps[0], buf, size, block_write, &size);
168136    return 1;
169137}
170138
171139
172static __bit block_transmit(uint16_t length)
140static int block_transmit(uint16_t length)
173141{
174    uint16_t left;
142    uint16_t got;
175143
176    if (payload < PAYLOAD_START || payload > PAYLOAD_END) {
177        dfu.state = dfuERROR;
178        dfu.status = errADDRESS;
179        return 1;
180    }
181144    if (length > EP0_SIZE) {
182145        dfu.state = dfuERROR;
183146        dfu.status = errUNKNOWN;
184147        return 1;
185148    }
186    left = PAYLOAD_END-payload;
187    if (left < length) {
188        length = left;
149    got = flash_read(buf, length);
150    if (got < length) {
151        length = got;
189152        dfu.state = dfuIDLE;
190153    }
191    usb_send(&ep0, (__code uint8_t *) payload, length, NULL, NULL);
192    payload += length;
154    usb_send(&eps[0], buf, length, NULL, NULL);
193155    return 1;
194156}
195157
196158
197static __bit my_setup(struct setup_request *setup) __reentrant
159static int my_setup(const struct setup_request *setup)
198160{
199    __bit ok;
161    int ok;
200162
201163    switch (setup->bmRequestType | setup->bRequest << 8) {
202164    case DFU_TO_DEV(DFU_DETACH):
...... 
211173        debug("DFU_DNLOAD\n");
212174        if (dfu.state == dfuIDLE) {
213175            next_block = setup->wValue;
214            payload = PAYLOAD_START;
176            flash_start();
215177        }
216178        else if (dfu.state != dfuDNLOAD_IDLE) {
217179            error("bad state\n");
...... 
242204        debug("DFU_UPLOAD\n");
243205        if (dfu.state == dfuIDLE) {
244206            next_block = setup->wValue;
245            payload = PAYLOAD_START;
207            flash_start();
246208        }
247209        else if (dfu.state != dfuUPLOAD_IDLE)
248210            return 0;
...... 
266228        return ok;
267229    case DFU_FROM_DEV(DFU_GETSTATUS):
268230        debug("DFU_GETSTATUS\n");
269        usb_send(&ep0, (uint8_t *) &dfu, sizeof(dfu), NULL, NULL);
231        usb_send(&eps[0], (uint8_t *) &dfu, sizeof(dfu), NULL, NULL);
270232        return 1;
271233    case DFU_TO_DEV(DFU_CLRSTATUS):
272234        debug("DFU_CLRSTATUS\n");
...... 
275237        return 1;
276238    case DFU_FROM_DEV(DFU_GETSTATE):
277239        debug("DFU_GETSTATE\n");
278        usb_send(&ep0, &dfu.state, 1, NULL, NULL);
240        usb_send(&eps[0], &dfu.state, 1, NULL, NULL);
279241        return 1;
280242    case DFU_TO_DEV(DFU_ABORT):
281243        debug("DFU_ABORT\n");
...... 
283245        dfu.status = OK;
284246        return 1;
285247    default:
286#ifdef CONFIG_PRINTK
287        printk("DFU rt %x, rq%x ?\n",
248        error("DFU rt %x, rq%x ?\n",
288249            setup->bmRequestType, setup->bRequest);
289#else
290        /*
291         * @@@ SDCC 2.7.0 ends up OR'in setup->bmRequestType with
292         * setup->bRequest unshifted if we don't use at least one of
293         * them here.
294         */
295        {
296            static volatile uint8_t foo;
297            foo = setup->bRequest;
298        }
299#endif
300250        return 0;
301251    }
302252}
303253
304254
305static __bit my_descr(uint8_t type, uint8_t index, const uint8_t **reply,
306    uint8_t *size) __reentrant
255static int my_descr(uint8_t type, uint8_t index, const uint8_t **reply,
256    uint8_t *size)
307257{
308    index; /* suppress warning */
309258    if (type != DFU_DT_FUNCTIONAL)
310259        return 0;
311260    *reply = functional_descriptor;
...... 
314263}
315264
316265
317static void my_reset(void) __reentrant
266#if 0
267static void my_reset(void)
318268{
319269    /* @@@ not nice -- think about where this should go */
320270    extern void run_payload(void);
...... 
322272    if (did_download)
323273        run_payload();
324274}
275#endif
325276
326277
327278void dfu_init(void)
328279{
329280    user_setup = my_setup;
330281    user_get_descriptor = my_descr;
331    user_reset = my_reset;
282// user_reset = my_reset;
332283}
atusb/fw/usb/dfu.h
11/*
22 * boot/dfu.h - DFU protocol constants and data structures
33 *
4 * Written 2008 by Werner Almesberger
5 * Copyright 2008 Werner Almesberger
4 * Written 2008, 2011 by Werner Almesberger
5 * Copyright 2008, 2011 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
...... 
8181extern struct dfu dfu;
8282
8383
84void flash_start(void);
85int flash_can_write(uint16_t size);
86void flash_write(const uint8_t *buf, uint16_t size);
87uint16_t flash_read(uint8_t *buf, uint16_t size);
88
89
8490void dfu_init(void);
8591
8692#endif /* !DFU_H */

Archive Download the corresponding diff file



interactive