Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add docs for DfuSe descriptor and implement DFU_UPLOAD #205

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
37 changes: 31 additions & 6 deletions examples/stm32/f1/lisa-m-1/usb_dfu/usbdfu.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const struct usb_device_descriptor dev = {
const struct usb_dfu_descriptor dfu_function = {
.bLength = sizeof(struct usb_dfu_descriptor),
.bDescriptorType = DFU_FUNCTIONAL,
.bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
.bmAttributes = USB_DFU_CAN_UPLOAD | USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
.wDetachTimeout = 255,
.wTransferSize = 1024,
.bcdDFUVersion = 0x011A,
Expand All @@ -79,8 +79,7 @@ const struct usb_interface_descriptor iface = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 2,

/* The ST Microelectronics DfuSe application needs this string.
* The format isn't documented... */
/* The ST Microelectronics DfuSe application needs this string. */
.iInterface = 4,

.extra = &dfu_function,
Expand Down Expand Up @@ -109,8 +108,30 @@ static const char *usb_strings[] = {
"Black Sphere Technologies",
"DFU Demo",
"DEMO",
/* This string is used by ST Microelectronics' DfuSe utility. */
// DfuSe descriptor string, used by ST DfuSe utility and also
// supported by dfu-util, see UM0424 section 10.3.2:
//
// |----------[zone]----------|
// [segment]
// \-----/
"@Internal Flash /0x08000000/8*001Ka,56*001Kg",
// start address of [zone]-^ | |--/| \-------/
// | | | [segment]
// | | |
// | | ` [flags], "a"=readable
// [flags]: | ` 1K bytes per erase-block
// (a) readable `8 erase-blocks
// (b) earaseable
// (c) readable and earaseable
// (e) readable and writable
// (f) earaseable and writable
// (g) readable, earaseable and writable
//
// [zone]: a number of segments starting at given address, allowed
// to be non-contigous
//
// [segment]: a number of contigous erase blocks, or "sectors" in
// ST docs
};

static uint8_t usbdfu_getstatus(uint32_t *bwPollTimeout)
Expand Down Expand Up @@ -204,8 +225,12 @@ static enum usbd_request_return_codes usbdfu_control_request(usbd_device *usbd_d
usbdfu_state = STATE_DFU_IDLE;
return USBD_REQ_HANDLED;
case DFU_UPLOAD:
/* Upload not supported for now. */
return USBD_REQ_NOTSUPP;
usbdfu_state = STATE_DFU_UPLOAD_IDLE;
uint32_t addr = prog.addr
+ ((req->wValue - 2) * dfu_function.wTransferSize);
memcpy(*buf, (void*)addr, dfu_function.wTransferSize);
*len = dfu_function.wTransferSize;
return USBD_REQ_HANDLED;
case DFU_GETSTATUS: {
uint32_t bwPollTimeout = 0; /* 24-bit integer in DFU class spec */
(*buf)[0] = usbdfu_getstatus(&bwPollTimeout);
Expand Down
37 changes: 32 additions & 5 deletions examples/stm32/f1/other/usb_dfu/usbdfu.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const struct usb_device_descriptor dev = {
const struct usb_dfu_descriptor dfu_function = {
.bLength = sizeof(struct usb_dfu_descriptor),
.bDescriptorType = DFU_FUNCTIONAL,
.bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
.bmAttributes = USB_DFU_CAN_UPLOAD | USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
.wDetachTimeout = 255,
.wTransferSize = 1024,
.bcdDFUVersion = 0x011A,
Expand All @@ -79,8 +79,7 @@ const struct usb_interface_descriptor iface = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 2,

/* The ST Microelectronics DfuSe application needs this string.
* The format isn't documented... */
/* The ST Microelectronics DfuSe application needs this string. */
.iInterface = 4,

.extra = &dfu_function,
Expand Down Expand Up @@ -109,8 +108,31 @@ static const char *usb_strings[] = {
"Black Sphere Technologies",
"DFU Demo",
"DEMO",
/* This string is used by ST Microelectronics' DfuSe utility. */

// DfuSe descriptor string, used by ST DfuSe utility and also
// supported by dfu-util, see UM0424 section 10.3.2:
//
// |----------[zone]----------|
// [segment]
// \-----/
"@Internal Flash /0x08000000/8*001Ka,56*001Kg",
// start address of [zone]-^ | |--/| \-------/
// | | | [segment]
// | | |
// | | ` [flags], "a"=readable
// [flags]: | ` 1K bytes per erase-block
// (a) readable `8 erase-blocks
// (b) earaseable
// (c) readable and earaseable
// (e) readable and writable
// (f) earaseable and writable
// (g) readable, earaseable and writable
//
// [zone]: a number of segments starting at given address, allowed
// to be non-contigous
//
// [segment]: a number of contigous erase blocks, or "sectors" in
// ST docs
};

static uint8_t usbdfu_getstatus(uint32_t *bwPollTimeout)
Expand Down Expand Up @@ -204,7 +226,12 @@ static enum usbd_request_return_codes usbdfu_control_request(usbd_device *usbd_d
usbdfu_state = STATE_DFU_IDLE;
return USBD_REQ_HANDLED;
case DFU_UPLOAD:
/* Upload not supported for now. */
usbdfu_state = STATE_DFU_UPLOAD_IDLE;
uint32_t addr = prog.addr
+ ((req->wValue - 2) * dfu_function.wTransferSize);
memcpy(*buf, (void*)addr, dfu_function.wTransferSize);
*len = dfu_function.wTransferSize;
return USBD_REQ_HANDLED;
return USBD_REQ_NOTSUPP;
case DFU_GETSTATUS: {
uint32_t bwPollTimeout = 0; /* 24-bit integer in DFU class spec */
Expand Down
38 changes: 32 additions & 6 deletions examples/stm32/f1/stm32-h103/usb_dfu/usbdfu.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const struct usb_device_descriptor dev = {
const struct usb_dfu_descriptor dfu_function = {
.bLength = sizeof(struct usb_dfu_descriptor),
.bDescriptorType = DFU_FUNCTIONAL,
.bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
.bmAttributes = USB_DFU_CAN_UPLOAD | USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
.wDetachTimeout = 255,
.wTransferSize = 1024,
.bcdDFUVersion = 0x011A,
Expand All @@ -79,8 +79,7 @@ const struct usb_interface_descriptor iface = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 2,

/* The ST Microelectronics DfuSe application needs this string.
* The format isn't documented... */
/* The ST Microelectronics DfuSe application needs this string. */
.iInterface = 4,

.extra = &dfu_function,
Expand Down Expand Up @@ -109,8 +108,31 @@ static const char *usb_strings[] = {
"Black Sphere Technologies",
"DFU Demo",
"DEMO",
/* This string is used by ST Microelectronics' DfuSe utility. */

// DfuSe descriptor string, used by ST DfuSe utility and also
// supported by dfu-util, see UM0424 section 10.3.2:
//
// |----------[zone]----------|
// [segment]
// \-----/
"@Internal Flash /0x08000000/8*001Ka,56*001Kg",
// start address of [zone]-^ | |--/| \-------/
// | | | [segment]
// | | |
// | | ` [flags], "a"=readable
// [flags]: | ` 1K bytes per erase-block
// (a) readable `8 erase-blocks
// (b) earaseable
// (c) readable and earaseable
// (e) readable and writable
// (f) earaseable and writable
// (g) readable, earaseable and writable
//
// [zone]: a number of segments starting at given address, allowed
// to be non-contigous
//
// [segment]: a number of contigous erase blocks, or "sectors" in
// ST docs
};

static uint8_t usbdfu_getstatus(usbd_device *usbd_dev, uint32_t *bwPollTimeout)
Expand Down Expand Up @@ -204,8 +226,12 @@ static enum usbd_request_return_codes usbdfu_control_request(usbd_device *usbd_d
usbdfu_state = STATE_DFU_IDLE;
return USBD_REQ_HANDLED;
case DFU_UPLOAD:
/* Upload not supported for now. */
return USBD_REQ_NOTSUPP;
usbdfu_state = STATE_DFU_UPLOAD_IDLE;
uint32_t addr = prog.addr
+ ((req->wValue - 2) * dfu_function.wTransferSize);
memcpy(*buf, (void*)addr, dfu_function.wTransferSize);
*len = dfu_function.wTransferSize;
return USBD_REQ_HANDLED;
case DFU_GETSTATUS: {
uint32_t bwPollTimeout = 0; /* 24-bit integer in DFU class spec */
(*buf)[0] = usbdfu_getstatus(usbd_dev, &bwPollTimeout);
Expand Down
38 changes: 32 additions & 6 deletions examples/stm32/f1/stm32-h103/usb_iap/usbiap.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const struct usb_device_descriptor dev = {
const struct usb_dfu_descriptor dfu_function = {
.bLength = sizeof(struct usb_dfu_descriptor),
.bDescriptorType = DFU_FUNCTIONAL,
.bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
.bmAttributes = USB_DFU_CAN_UPLOAD | USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
.wDetachTimeout = 255,
.wTransferSize = 1024,
.bcdDFUVersion = 0x011A,
Expand All @@ -79,8 +79,7 @@ const struct usb_interface_descriptor iface = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 2,

/* The ST Microelectronics DfuSe application needs this string.
* The format isn't documented... */
/* The ST Microelectronics DfuSe application needs this string. */
.iInterface = 4,

.extra = &dfu_function,
Expand Down Expand Up @@ -109,8 +108,31 @@ static const char *usb_strings[] = {
"Black Sphere Technologies",
"DFU Demo",
"DEMO",
/* This string is used by ST Microelectronics' DfuSe utility. */

// DfuSe descriptor string, used by ST DfuSe utility and also
// supported by dfu-util, see UM0424 section 10.3.2:
//
// |----------[zone]----------|
// [segment]
// \-----/
"@Internal Flash /0x08000000/8*001Ka,56*001Kg",
// start address of [zone]-^ | |--/| \-------/
// | | | [segment]
// | | |
// | | ` [flags], "a"=readable
// [flags]: | ` 1K bytes per erase-block
// (a) readable `8 erase-blocks
// (b) earaseable
// (c) readable and earaseable
// (e) readable and writable
// (f) earaseable and writable
// (g) readable, earaseable and writable
//
// [zone]: a number of segments starting at given address, allowed
// to be non-contigous
//
// [segment]: a number of contigous erase blocks, or "sectors" in
// ST docs
};

static uint8_t usbdfu_getstatus(usbd_device *usbd_dev, uint32_t *bwPollTimeout)
Expand Down Expand Up @@ -204,8 +226,12 @@ static enum usbd_request_return_codes usbdfu_control_request(usbd_device *usbd_d
usbdfu_state = STATE_DFU_IDLE;
return USBD_REQ_HANDLED;
case DFU_UPLOAD:
/* Upload not supported for now. */
return USBD_REQ_NOTSUPP;
usbdfu_state = STATE_DFU_UPLOAD_IDLE;
uint32_t addr = prog.addr
+ ((req->wValue - 2) * dfu_function.wTransferSize);
memcpy(*buf, (void*)addr, dfu_function.wTransferSize);
*len = dfu_function.wTransferSize;
return USBD_REQ_HANDLED;
case DFU_GETSTATUS: {
uint32_t bwPollTimeout = 0; /* 24-bit integer in DFU class spec */
(*buf)[0] = usbdfu_getstatus(usbd_dev, &bwPollTimeout);
Expand Down