Kévin Redon has uploaded this change for review. (
https://gerrit.osmocom.org/12595
Change subject: avoid mutli-packet USB transfer
..
avoid mutli-packet USB transfer
the control endpoint packet size is 64 bytes for USB full speed.
it is possible to make larger data transfer by transferring
multiple packets which can then by re-assembled.
this feature is also supported by the SAM E54 USB stack, but for
an unknown reason is the transfer size is larger than 64 bytes but
not a multiple of it, the transfer cannot complete (it is not
ACKed).
reducing the transfer size to 64 bytes removes this issue.
the data needs to be re-assembled in software to fill a flash page.
sadly a new issue has been uncovered using this method.
the size of the last packet (e.g. request bLength) is kept by the
USB stack for the next packet. Thus is the last packet is less
than 6 bytes, the status request after the download request fails.
Change-Id: Icb4c5f4bc06095f5f962152b8d8247054ef6a520
---
M usb/class/dfu/device/dfudf.c
M usb/class/dfu/device/dfudf.h
M usb/class/dfu/device/dfudf_desc.h
M usb_start.c
4 files changed, 53 insertions(+), 21 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-asf4-dfu refs/changes/95/12595/1
diff --git a/usb/class/dfu/device/dfudf.c b/usb/class/dfu/device/dfudf.c
index 8232979..545f57c 100644
--- a/usb/class/dfu/device/dfudf.c
+++ b/usb/class/dfu/device/dfudf.c
@@ -42,7 +42,7 @@
enum usb_dfu_state dfu_state = USB_DFU_STATE_DFU_IDLE;
enum usb_dfu_status dfu_status = USB_DFU_STATUS_OK;
-uint8_t dfu_download_data[512];
+uint8_t dfu_download_data[64];
uint16_t dfu_download_length = 0;
size_t dfu_download_offset = 0;
bool dfu_manifestation_complete = false;
@@ -244,12 +244,12 @@
to_return = ERR_INVALID_ARG; // stall control pipe to
indicate error
} else { // there is data to be flash
if (USB_SETUP_STAGE == stage) { // there will be data
to be flash
- to_return = usbdc_xfer(ep, dfu_download_data,
req->wLength, false); // send ack to the setup request to get the data
+ to_return = usbdc_xfer(ep, dfu_download_data,
req->wLength, req->wLength < 64); // send ack to the setup request to get the
data
} else { // now there is data to be flashed
dfu_download_offset = req->wValue *
sizeof(dfu_download_data); // remember which block to flash
dfu_download_length = req->wLength; // remember
the data size to be flash
dfu_state = USB_DFU_STATE_DFU_DNLOAD_SYNC; //
go to sync state
- to_return = usbdc_xfer(ep, NULL, 0, false); //
ACK the data
+ //to_return = usbdc_xfer(ep, NULL, 0, true); //
send ACK
// we let the main application flash the data
because this can be long and would stall the USB ISR
}
}
diff --git a/usb/class/dfu/device/dfudf.h b/usb/class/dfu/device/dfudf.h
index cee5845..a7143f9 100644
--- a/usb/class/dfu/device/dfudf.h
+++ b/usb/class/dfu/device/dfudf.h
@@ -43,10 +43,9 @@
extern enum usb_dfu_status dfu_status;
/** Downloaded data to be programmed in flash
- *
- * 512 is the flash page size of the SAM D5x/E5x
+ * 64 bytes is the control buffer size
*/
-extern uint8_t dfu_download_data[512];
+extern uint8_t dfu_download_data[64];
/** Length of downloaded data in bytes */
extern uint16_t dfu_download_length;
/** Offset of where the downloaded data should be flashed in bytes */
diff --git a/usb/class/dfu/device/dfudf_desc.h
b/usb/class/dfu/device/dfudf_desc.h
index cd6ba41..68880c7 100644
--- a/usb/class/dfu/device/dfudf_desc.h
+++ b/usb/class/dfu/device/dfudf_desc.h
@@ -75,9 +75,14 @@
CONF_USB_DFUD_BMATTRI, \
CONF_USB_DFUD_BMAXPOWER)
+/** \remark ideally the transfer size should be the same size as flash pages
(512 byte for SAM E5x/D5x).
+the control endpoint transfer size is 64 byte for full speed
device.
+thus 512 transfers must be split in a mutli-packet transfer.
+this should be supported by the hardware, but I did not manage to
have complete/successful multi-packet transfer is the transfer is larger than
64 bytes but not a multiple of 64
+ */
#define DFUD_IFACE_DESCB
USB_DFU_FUNC_DESC_BYTES(USB_DFU_ATTRIBUTES_CAN_DOWNLOAD |
USB_DFU_ATTRIBUTES_WILL_DETACH, \
0, /**< detaching makes
only sense in run-time mode */ \
-512, /**< transfer size
corresponds to page size for optimal flash writing */ \
+64, /**< transfer size
corresponds to the control endpoint