mirror of
git://projects.qi-hardware.com/ben-wpan.git
synced 2024-11-22 01:23:08 +02:00
atusb/fw/: DFU: support multiple sets of flash operations; support multiple alt settings
This commit is contained in:
parent
8b0859486e
commit
8f2f13c30a
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* fw/descr.c - USB descriptors
|
||||
*
|
||||
* Written 2008-2011 by Werner Almesberger
|
||||
* Copyright 2008-2011 Werner Almesberger
|
||||
* Written 2008-2011, 2014 by Werner Almesberger
|
||||
* Copyright 2008-2011, 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
|
||||
@ -100,5 +100,5 @@ const uint8_t config_descriptor[] = {
|
||||
|
||||
/* Interface #1 */
|
||||
|
||||
DFU_ITF_DESCR(1, dfu_proto_runtime)
|
||||
DFU_ITF_DESCR(1, 0, dfu_proto_runtime)
|
||||
};
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* fw/flash.c - Board-specific flash functions
|
||||
*
|
||||
* Written 2011, 2013 by Werner Almesberger
|
||||
* Copyright 2011, 2013 Werner Almesberger
|
||||
* Written 2011, 2013, 2014 by Werner Almesberger
|
||||
* Copyright 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
|
||||
@ -24,19 +24,19 @@
|
||||
static uint32_t payload;
|
||||
|
||||
|
||||
void flash_start(void)
|
||||
static void flash_start(void)
|
||||
{
|
||||
payload = 0;
|
||||
}
|
||||
|
||||
|
||||
bool flash_can_write(uint16_t size)
|
||||
static bool flash_can_write(uint16_t size)
|
||||
{
|
||||
return payload+size <= BOOT_ADDR;
|
||||
}
|
||||
|
||||
|
||||
void flash_write(const uint8_t *buf, uint16_t size)
|
||||
static void flash_write(const uint8_t *buf, uint16_t size)
|
||||
{
|
||||
static uint8_t last;
|
||||
const uint8_t *p;
|
||||
@ -61,7 +61,7 @@ void flash_write(const uint8_t *buf, uint16_t size)
|
||||
}
|
||||
|
||||
|
||||
void flash_end_write(void)
|
||||
static void flash_end_write(void)
|
||||
{
|
||||
if (payload & (SPM_PAGESIZE-1)) {
|
||||
boot_page_write(payload & ~(SPM_PAGESIZE-1));
|
||||
@ -71,7 +71,7 @@ void flash_end_write(void)
|
||||
}
|
||||
|
||||
|
||||
uint16_t flash_read(uint8_t *buf, uint16_t size)
|
||||
static uint16_t flash_read(uint8_t *buf, uint16_t size)
|
||||
{
|
||||
uint16_t got = 0;
|
||||
|
||||
@ -83,3 +83,15 @@ uint16_t flash_read(uint8_t *buf, uint16_t size)
|
||||
}
|
||||
return got;
|
||||
}
|
||||
|
||||
|
||||
static struct dfu_flash_ops flash_ops = {
|
||||
.start = flash_start,
|
||||
.can_write = flash_can_write,
|
||||
.write = flash_write,
|
||||
.end_write = flash_end_write,
|
||||
.read = flash_read,
|
||||
};
|
||||
|
||||
|
||||
struct dfu_flash_ops *dfu_flash_ops = &flash_ops;
|
||||
|
@ -42,6 +42,11 @@
|
||||
#define error(...)
|
||||
|
||||
|
||||
#ifndef DFU_ALT_SETTINGS
|
||||
#define DFU_ALT_SETTINGS 1
|
||||
#endif
|
||||
|
||||
|
||||
const uint8_t device_descriptor[] = {
|
||||
18, /* bLength */
|
||||
USB_DT_DEVICE, /* bDescriptorType */
|
||||
@ -67,7 +72,7 @@ const uint8_t device_descriptor[] = {
|
||||
const uint8_t config_descriptor[] = {
|
||||
9, /* bLength */
|
||||
USB_DT_CONFIG, /* bDescriptorType */
|
||||
LE(9+9), /* wTotalLength */
|
||||
LE(9+9*DFU_ALT_SETTINGS), /* wTotalLength */
|
||||
1, /* bNumInterfaces */
|
||||
1, /* bConfigurationValue (> 0 !) */
|
||||
0, /* iConfiguration */
|
||||
@ -77,7 +82,13 @@ const uint8_t config_descriptor[] = {
|
||||
|
||||
/* Interface #0 */
|
||||
|
||||
DFU_ITF_DESCR(0, dfu_proto_dfu)
|
||||
DFU_ITF_DESCR(0, 0, dfu_proto_dfu)
|
||||
#if DFU_ALT_SETTINGS >= 1
|
||||
DFU_ITF_DESCR(0, 1, dfu_proto_dfu)
|
||||
#endif
|
||||
#if DFU_ALT_SETTINGS >= 2
|
||||
DFU_ITF_DESCR(0, 2, dfu_proto_dfu)
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@ -92,7 +103,7 @@ static void block_write(void *user)
|
||||
{
|
||||
uint16_t *size = user;
|
||||
|
||||
flash_write(buf, *size);
|
||||
dfu_flash_ops->write(buf, *size);
|
||||
}
|
||||
|
||||
|
||||
@ -100,7 +111,7 @@ static bool block_receive(uint16_t length)
|
||||
{
|
||||
static uint16_t size;
|
||||
|
||||
if (!flash_can_write(length)) {
|
||||
if (!dfu_flash_ops->can_write(length)) {
|
||||
dfu.state = dfuERROR;
|
||||
dfu.status = errADDRESS;
|
||||
return 0;
|
||||
@ -125,7 +136,7 @@ static bool block_transmit(uint16_t length)
|
||||
dfu.status = errUNKNOWN;
|
||||
return 1;
|
||||
}
|
||||
got = flash_read(buf, length);
|
||||
got = dfu_flash_ops->read(buf, length);
|
||||
if (got < length) {
|
||||
length = got;
|
||||
dfu.state = dfuIDLE;
|
||||
@ -152,7 +163,7 @@ static bool my_setup(const struct setup_request *setup)
|
||||
debug("DFU_DNLOAD\n");
|
||||
if (dfu.state == dfuIDLE) {
|
||||
next_block = setup->wValue;
|
||||
flash_start();
|
||||
dfu_flash_ops->start();
|
||||
}
|
||||
else if (dfu.state != dfuDNLOAD_IDLE) {
|
||||
error("bad state\n");
|
||||
@ -171,7 +182,7 @@ static bool my_setup(const struct setup_request *setup)
|
||||
}
|
||||
if (!setup->wLength) {
|
||||
debug("DONE\n");
|
||||
flash_end_write();
|
||||
dfu_flash_ops->end_write();
|
||||
dfu.state = dfuIDLE;
|
||||
did_download = 1;
|
||||
return 1;
|
||||
@ -184,7 +195,7 @@ static bool my_setup(const struct setup_request *setup)
|
||||
debug("DFU_UPLOAD\n");
|
||||
if (dfu.state == dfuIDLE) {
|
||||
next_block = setup->wValue;
|
||||
flash_start();
|
||||
dfu_flash_ops->start();
|
||||
}
|
||||
else if (dfu.state != dfuUPLOAD_IDLE)
|
||||
return 0;
|
||||
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* boot/dfu.h - DFU protocol constants and data structures
|
||||
*
|
||||
* Written 2008, 2011, 2013 by Werner Almesberger
|
||||
* Copyright 2008, 2011, 2013 Werner Almesberger
|
||||
* 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
|
||||
@ -86,11 +86,11 @@ struct dfu {
|
||||
};
|
||||
|
||||
|
||||
#define DFU_ITF_DESCR(itf, proto) \
|
||||
#define DFU_ITF_DESCR(itf, alt, proto) \
|
||||
9, /* bLength */ \
|
||||
USB_DT_INTERFACE, /* bDescriptorType */ \
|
||||
(itf), /* bInterfaceNumber */ \
|
||||
0, /* bAlternateSetting */ \
|
||||
(alt), /* bAlternateSetting */ \
|
||||
0, /* bNumEndpoints */ \
|
||||
0xfe, /* bInterfaceClass (application specific) */ \
|
||||
0x01, /* bInterfaceSubClass (device fw upgrade) */ \
|
||||
@ -98,15 +98,18 @@ struct dfu {
|
||||
0, /* iInterface */
|
||||
|
||||
|
||||
struct dfu_flash_ops {
|
||||
void (*start)(void);
|
||||
bool (*can_write)(uint16_t size);
|
||||
void (*write)(const uint8_t *buf, uint16_t size);
|
||||
void (*end_write)(void);
|
||||
uint16_t (*read)(uint8_t *buf, uint16_t size);
|
||||
};
|
||||
|
||||
extern struct dfu dfu;
|
||||
extern struct dfu_flash_ops *dfu_flash_ops;
|
||||
|
||||
|
||||
void flash_start(void);
|
||||
bool flash_can_write(uint16_t size);
|
||||
void flash_write(const uint8_t *buf, uint16_t size);
|
||||
void flash_end_write(void);
|
||||
uint16_t flash_read(uint8_t *buf, uint16_t size);
|
||||
|
||||
bool dfu_setup_common(const struct setup_request *setup);
|
||||
bool dfu_my_descr(uint8_t type, uint8_t index, const uint8_t **reply,
|
||||
uint8_t *size);
|
||||
|
Loading…
Reference in New Issue
Block a user