Change in osmo-ccid-firmware[master]: support DFU detach to switch from fw to bootloader

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Hoernchen gerrit-no-reply at lists.osmocom.org
Mon Feb 10 10:27:31 UTC 2020


Hoernchen has submitted this change. ( https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/17034 )

Change subject: support DFU detach to switch from fw to bootloader
......................................................................

support DFU detach to switch from fw to bootloader

This makes flashing a bit more convenient, because pushing the button is
not required. It can be disabled using make DISABLE_DFU_DETACH=1.

Change-Id: I04d05054d1c0e3988b8eafd93c6524f4a0489cb7
---
M sysmoOCTSIM/dfu_descriptors.h
M sysmoOCTSIM/gcc/Makefile
A sysmoOCTSIM/usb/class/dfu/device/dfudf.c
A sysmoOCTSIM/usb/class/dfu/device/dfudf.h
A sysmoOCTSIM/usb/class/dfu/device/dfudf_desc.h
A sysmoOCTSIM/usb/class/dfu/usb_protocol_dfu.h
M sysmoOCTSIM/usb_start.c
M sysmoOCTSIM/usb_start.h
8 files changed, 658 insertions(+), 3 deletions(-)

Approvals:
  Jenkins Builder: Verified
  laforge: Looks good to me, approved



diff --git a/sysmoOCTSIM/dfu_descriptors.h b/sysmoOCTSIM/dfu_descriptors.h
index 8cbaf23..7ef8cc9 100644
--- a/sysmoOCTSIM/dfu_descriptors.h
+++ b/sysmoOCTSIM/dfu_descriptors.h
@@ -5,13 +5,18 @@
 
 #include "usb_protocol.h"
 #include "usb_dfu.h"
+#if (DISABLE_DFU_DETACH != 0)
+#define BMATT 0
+#else
+#define BMATT USB_DFU_WILL_DETACH
+#endif
 
 /* USB DFU functional descriptor */
 #define DFU_FUNC_DESC  {						\
 	.bLength		= USB_DT_DFU_SIZE,			\
 	.bDescriptorType	= USB_DT_DFU,				\
-	.bmAttributes		= USB_DFU_CAN_UPLOAD | USB_DFU_CAN_DOWNLOAD, \
-	.wDetachTimeOut		= 5000,					\
+	.bmAttributes		= BMATT, \
+	.wDetachTimeOut		= 0,					\
 	.wTransferSize		= FLASH_PAGE_SIZE,			\
 	.bcdDFUVersion		= 0x0100,				\
 }
diff --git a/sysmoOCTSIM/gcc/Makefile b/sysmoOCTSIM/gcc/Makefile
index 6c0974f..9df0c01 100644
--- a/sysmoOCTSIM/gcc/Makefile
+++ b/sysmoOCTSIM/gcc/Makefile
@@ -7,9 +7,11 @@
 EXTRA_CFLAGS=-I$(SYSTEM_PREFIX)/include -I../../ccid_common
 CROSS_COMPILE= arm-none-eabi-
 
+DISABLE_DFU_DETACH ?= 0
+
 CFLAGS_CPU=-D__SAME54N19A__ -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16
 CFLAGS=-x c -mthumb -DDEBUG -Os -ffunction-sections -fdata-sections -mlong-calls \
-       -g3 -Wall -c -std=gnu99 $(CFLAGS_CPU) -DOCTSIMFWBUILD
+       -g3 -Wall -c -std=gnu99 $(CFLAGS_CPU) -DOCTSIMFWBUILD -DDISABLE_DFU_DETACH=$(DISABLE_DFU_DETACH)
 
 CC = $(CROSS_COMPILE)gcc
 LD = $(CROSS_COMPILE)ld
@@ -75,6 +77,8 @@
 	-I"../usb/class/ccid/device" \
 	-I"../usb/class/cdc" \
 	-I"../usb/class/cdc/device" \
+	-I"../usb/class/dfu" \
+	-I"../usb/class/dfu/device" \
 	-I"../usb/device" \
 	$(NULL)
 
@@ -135,6 +139,7 @@
 	talloc.o \
 	usb/class/ccid/device/ccid_df.o \
 	usb/class/cdc/device/cdcdf_acm.o \
+	usb/class/dfu/device/dfudf.o \
 	usb/device/usbdc.o \
 	usb/usb_protocol.o \
 	usb_descriptors.o \
diff --git a/sysmoOCTSIM/usb/class/dfu/device/dfudf.c b/sysmoOCTSIM/usb/class/dfu/device/dfudf.c
new file mode 100644
index 0000000..2b11fb4
--- /dev/null
+++ b/sysmoOCTSIM/usb/class/dfu/device/dfudf.c
@@ -0,0 +1,300 @@
+/**
+ * \file
+ *
+ * \brief USB Device Stack DFU Function Implementation.
+ *
+ * Copyright (c) 2018 sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon at sysmocom.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "dfudf.h"
+#include "usb_protocol_dfu.h"
+#include "dfudf_desc.h"
+
+/** USB Device DFU Function Specific Data */
+struct dfudf_func_data {
+	/** DFU Interface information */
+	uint8_t func_iface;
+	/** DFU Enable Flag */
+	bool enabled;
+};
+
+static struct usbdf_driver _dfudf;
+static struct dfudf_func_data _dfudf_funcd;
+
+/** USB DFU functional descriptor (with DFU attributes) */
+static const uint8_t usb_dfu_func_desc_bytes[] = {DFUD_IFACE_DESCB};
+static const usb_dfu_func_desc_t* usb_dfu_func_desc = (usb_dfu_func_desc_t*)&usb_dfu_func_desc_bytes;
+
+enum usb_dfu_state dfu_state = USB_DFU_STATE_APP_IDLE;
+enum usb_dfu_status dfu_status = USB_DFU_STATUS_OK;
+
+uint8_t dfu_download_data[512];
+uint16_t dfu_download_length = 0;
+size_t dfu_download_offset = 0;
+bool dfu_manifestation_complete = false;
+
+/**
+ * \brief Enable DFU Function
+ * \param[in] drv Pointer to USB device function driver
+ * \param[in] desc Pointer to USB interface descriptor
+ * \return Operation status.
+ */
+static int32_t dfudf_enable(struct usbdf_driver *drv, struct usbd_descriptors *desc)
+{
+	struct dfudf_func_data *func_data = (struct dfudf_func_data *)(drv->func_data);
+
+	usb_iface_desc_t ifc_desc;
+	uint8_t *        ifc;
+
+	ifc = desc->sod;
+	if (NULL == ifc) {
+		return ERR_NOT_FOUND;
+	}
+
+	ifc_desc.bInterfaceNumber = ifc[2];
+	ifc_desc.bInterfaceClass  = ifc[5];
+
+	if (USB_DFU_CLASS == ifc_desc.bInterfaceClass) {
+		if (func_data->func_iface == ifc_desc.bInterfaceNumber) { // Initialized
+			return ERR_ALREADY_INITIALIZED;
+		} else if (func_data->func_iface != 0xFF) { // Occupied
+			return ERR_NO_RESOURCE;
+		} else {
+			func_data->func_iface = ifc_desc.bInterfaceNumber;
+		}
+	} else { // Not supported by this function driver
+		return ERR_NOT_FOUND;
+	}
+
+	// there are no endpoint to install since DFU uses only the control endpoint
+
+	ifc = usb_find_desc(usb_desc_next(desc->sod), desc->eod, USB_DT_INTERFACE);
+
+	// Installed
+	_dfudf_funcd.enabled = true;
+	return ERR_NONE;
+}
+
+/**
+ * \brief Disable DFU Function
+ * \param[in] drv Pointer to USB device function driver
+ * \param[in] desc Pointer to USB device descriptor
+ * \return Operation status.
+ */
+static int32_t dfudf_disable(struct usbdf_driver *drv, struct usbd_descriptors *desc)
+{
+	struct dfudf_func_data *func_data = (struct dfudf_func_data *)(drv->func_data);
+
+	usb_iface_desc_t ifc_desc;
+
+	if (desc) {
+		ifc_desc.bInterfaceClass = desc->sod[5];
+		// Check interface
+		if (ifc_desc.bInterfaceClass != USB_DFU_CLASS) {
+			return ERR_NOT_FOUND;
+		}
+	}
+
+	func_data->func_iface = 0xFF;
+
+	_dfudf_funcd.enabled = false;
+	return ERR_NONE;
+}
+
+/**
+ * \brief DFU Control Function
+ * \param[in] drv Pointer to USB device function driver
+ * \param[in] ctrl USB device general function control type
+ * \param[in] param Parameter pointer
+ * \return Operation status.
+ */
+static int32_t dfudf_ctrl(struct usbdf_driver *drv, enum usbdf_control ctrl, void *param)
+{
+	switch (ctrl) {
+	case USBDF_ENABLE:
+		return dfudf_enable(drv, (struct usbd_descriptors *)param);
+
+	case USBDF_DISABLE:
+		return dfudf_disable(drv, (struct usbd_descriptors *)param);
+
+	case USBDF_GET_IFACE:
+		return ERR_UNSUPPORTED_OP;
+
+	default:
+		return ERR_INVALID_ARG;
+	}
+}
+
+/**
+ * \brief Process the DFU IN request
+ * \param[in] ep Endpoint address.
+ * \param[in] req Pointer to the request.
+ * \param[in] stage Stage of the request.
+ * \return Operation status.
+ */
+static int32_t dfudf_in_req(uint8_t ep, struct usb_req *req, enum usb_ctrl_stage stage)
+{
+	if (USB_DATA_STAGE == stage) { // the data stage is only for IN data, which we sent
+		return ERR_NONE; // send the IN data
+	}
+
+	int32_t to_return = ERR_NONE;
+	uint8_t response[6]; // buffer for the response to this request
+	switch (req->bRequest) {
+	case USB_DFU_UPLOAD: // upload firmware from flash not supported
+		dfu_state = USB_DFU_STATE_DFU_ERROR; // unsupported class request
+		to_return = ERR_UNSUPPORTED_OP; // stall control pipe (don't reply to the request)
+		break;
+	case USB_DFU_GETSTATUS: // get status
+		response[0] = dfu_status; // set status
+		response[1] = 10; // set poll timeout (24 bits, in milliseconds) to small value for periodical poll
+		response[2] = 0; // set poll timeout (24 bits, in milliseconds) to small value for periodical poll
+		response[3] = 0; // set poll timeout (24 bits, in milliseconds) to small value for periodical poll
+		response[4] = dfu_state; // set state
+		response[5] = 0; // string not used
+		to_return = usbdc_xfer(ep, response, 6, false); // send back status
+		if (USB_DFU_STATE_DFU_DNLOAD_SYNC == dfu_state) { // download has not completed
+			dfu_state = USB_DFU_STATE_DFU_DNBUSY; // switch to busy state
+		} else if (USB_DFU_STATE_DFU_MANIFEST_SYNC == dfu_state) {
+			if (!dfu_manifestation_complete) {
+				dfu_state = USB_DFU_STATE_DFU_MANIFEST; // go to manifest mode
+			} else if (usb_dfu_func_desc->bmAttributes & USB_DFU_ATTRIBUTES_MANIFEST_TOLERANT) {
+				dfu_state = USB_DFU_STATE_DFU_IDLE; // go back to idle mode
+			} else { // this should not happen (after manifestation the state should be dfuMANIFEST-WAIT-RESET if we are not manifest tolerant)
+				dfu_state = USB_DFU_STATE_DFU_MANIFEST_WAIT_RESET; // wait for reset
+			}
+		}
+		break;
+	case USB_DFU_GETSTATE: // get state
+		response[0] = dfu_state; // return state
+		to_return = usbdc_xfer(ep, response, 1, false); // send back state
+		break;
+	default: // all other DFU class IN request
+		dfu_state = USB_DFU_STATE_DFU_ERROR; // unknown or unsupported class request
+		to_return = ERR_INVALID_ARG; // stall control pipe (don't reply to the request)
+		break;
+	}
+
+	return to_return;
+}
+
+/**
+ * \brief Process the DFU OUT request
+ * \param[in] ep Endpoint address.
+ * \param[in] req Pointer to the request.
+ * \param[in] stage Stage of the request.
+ * \return Operation status.
+ */
+static int32_t dfudf_out_req(uint8_t ep, struct usb_req *req, enum usb_ctrl_stage stage)
+{
+	int32_t to_return = ERR_NONE;
+	switch (req->bRequest) {
+	case USB_DFU_DETACH: // detach makes only sense in DFU run-time/application mode
+#if (DISABLE_DFU_DETACH != 0)
+		dfu_state = USB_DFU_STATE_DFU_ERROR; // unsupported class request
+		to_return = ERR_UNSUPPORTED_OP; // stall control pipe (don't reply to the request)
+#else
+		to_return = usbdc_xfer(ep, NULL, 0, false);
+		*(uint32_t*)HSRAM_ADDR = 0x44465521;
+		__disable_irq();
+		delay_us(10000);
+		usbdc_detach();
+		delay_us(100000);
+		NVIC_SystemReset();
+#endif
+		break;
+	case USB_DFU_CLRSTATUS: // clear status
+		if (USB_DFU_STATE_DFU_ERROR == dfu_state || USB_DFU_STATUS_OK != dfu_status) { // only clear in case there is an error
+			dfu_status = USB_DFU_STATUS_OK; // clear error status
+			dfu_state = USB_DFU_STATE_DFU_IDLE; // put back in idle state
+		}
+		to_return = usbdc_xfer(ep, NULL, 0, false); // send ACK
+		break;
+	case USB_DFU_ABORT: // abort current operation
+		dfu_download_offset = 0; // reset download progress
+		dfu_state = USB_DFU_STATE_DFU_IDLE; // put back in idle state (nothing else to do)
+		to_return = usbdc_xfer(ep, NULL, 0, false); // send ACK
+		break;
+	default: // all other DFU class OUT request
+		dfu_state = USB_DFU_STATE_DFU_ERROR; // unknown class request
+		to_return = ERR_INVALID_ARG; // stall control pipe (don't reply to the request)
+		break;
+	}
+
+	return to_return;
+}
+
+/**
+ * \brief Process the CDC class request
+ * \param[in] ep Endpoint address.
+ * \param[in] req Pointer to the request.
+ * \param[in] stage Stage of the request.
+ * \return Operation status.
+ */
+static int32_t dfudf_req(uint8_t ep, struct usb_req *req, enum usb_ctrl_stage stage)
+{
+	if (0x01 != ((req->bmRequestType >> 5) & 0x03)) { // class request
+		return ERR_NOT_FOUND;
+	}
+
+	if ((req->wIndex == _dfudf_funcd.func_iface)) {
+		if (req->bmRequestType & USB_EP_DIR_IN) {
+			return dfudf_in_req(ep, req, stage);
+		} else {
+			return dfudf_out_req(ep, req, stage);
+		}
+	} else {
+		return ERR_NOT_FOUND;
+	}
+	return ERR_NOT_FOUND;
+}
+
+/** USB Device DFU Handler Struct */
+static struct usbdc_handler dfudf_req_h = {NULL, (FUNC_PTR)dfudf_req};
+
+/**
+ * \brief Initialize the USB DFU Function Driver
+ */
+int32_t dfudf_init(void)
+{
+	if (usbdc_get_state() > USBD_S_POWER) {
+		return ERR_DENIED;
+	}
+
+	_dfudf.ctrl      = dfudf_ctrl;
+	_dfudf.func_data = &_dfudf_funcd;
+
+	usbdc_register_function(&_dfudf);
+	usbdc_register_handler(USBDC_HDL_REQ, &dfudf_req_h);
+
+	return ERR_NONE;
+}
+
+/**
+ * \brief De-initialize the USB DFU Function Driver
+ */
+void dfudf_deinit(void)
+{
+}
+
+/**
+ * \brief Check whether DFU Function is enabled
+ */
+bool dfudf_is_enabled(void)
+{
+	return _dfudf_funcd.enabled;
+}
diff --git a/sysmoOCTSIM/usb/class/dfu/device/dfudf.h b/sysmoOCTSIM/usb/class/dfu/device/dfudf.h
new file mode 100644
index 0000000..cee5845
--- /dev/null
+++ b/sysmoOCTSIM/usb/class/dfu/device/dfudf.h
@@ -0,0 +1,77 @@
+/**
+ * \file
+ *
+ * \brief USB Device Stack DFU Function Definition.
+ *
+ * Copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries.
+ * Copyright (c) 2018 sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon at sysmocom.de>
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Subject to your compliance with these terms, you may use Microchip
+ * software and any derivatives exclusively with Microchip products.
+ * It is your responsibility to comply with third party license terms applicable
+ * to your use of third party software (including open source software) that
+ * may accompany Microchip software.
+ *
+ * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
+ * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
+ * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
+ * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
+ * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
+ * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE.  TO THE FULLEST EXTENT
+ * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
+ * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
+ * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
+ *
+ * \asf_license_stop
+ */
+
+#ifndef USBDF_DFU_H_
+#define USBDF_DFU_H_
+
+#include "usbdc.h"
+#include "usb_protocol_dfu.h"
+
+/** Current DFU state */
+extern enum usb_dfu_state dfu_state;
+/**< Current DFU status */
+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
+ */
+extern uint8_t dfu_download_data[512];
+/** Length of downloaded data in bytes */
+extern uint16_t dfu_download_length;
+/** Offset of where the downloaded data should be flashed in bytes */
+extern size_t dfu_download_offset;
+/** If manifestation (firmware flash and check) is complete */
+extern bool dfu_manifestation_complete;
+
+/**
+ * \brief Initialize the USB DFU Function Driver
+ * \return Operation status.
+ */
+int32_t dfudf_init(void);
+
+/**
+ * \brief Deinitialize the USB DFU Function Driver
+ * \return Operation status.
+ */
+void dfudf_deinit(void);
+
+/**
+ * \brief Check whether DFU Function is enabled
+ * \return Operation status.
+ * \return true DFU Function is enabled
+ * \return false DFU Function is disabled
+ */
+bool dfudf_is_enabled(void);
+
+#endif /* USBDF_DFU_H_ */
diff --git a/sysmoOCTSIM/usb/class/dfu/device/dfudf_desc.h b/sysmoOCTSIM/usb/class/dfu/device/dfudf_desc.h
new file mode 100644
index 0000000..50a79e4
--- /dev/null
+++ b/sysmoOCTSIM/usb/class/dfu/device/dfudf_desc.h
@@ -0,0 +1,114 @@
+/**
+ * \file
+ *
+ * \brief USB Device Stack DFU Function Descriptor Setting.
+ *
+ * Copyright (c) 2015-2018 Microchip Technology Inc. and its subsidiaries.
+ * Copyright (c) 2018 sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon at sysmocom.de>
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Subject to your compliance with these terms, you may use Microchip
+ * software and any derivatives exclusively with Microchip products.
+ * It is your responsibility to comply with third party license terms applicable
+ * to your use of third party software (including open source software) that
+ * may accompany Microchip software.
+ *
+ * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
+ * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
+ * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
+ * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
+ * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
+ * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
+ * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
+ * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE.  TO THE FULLEST EXTENT
+ * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
+ * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
+ * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
+ *
+ * \asf_license_stop
+ */
+
+#ifndef USBDF_DFU_DESC_H_
+#define USBDF_DFU_DESC_H_
+
+#include "usb_protocol.h"
+#include "usbd_config.h"
+#include "usb_protocol_dfu.h"
+
+#define DFUD_DEV_DESC \
+	USB_DEV_DESC_BYTES(CONF_USB_DFUD_BCDUSB, \
+	                   CONF_USB_DFUD_BDEVICECLASS, \
+	                   CONF_USB_DFUD_BDEVICESUBCLASS, \
+	                   CONF_USB_DFUD_BDEVICEPROTOCOL, \
+	                   CONF_USB_DFUD_BMAXPKSZ0, \
+	                   CONF_USB_OPENMOKO_IDVENDOR, \
+	                   CONF_USB_OSMOASF4DFU_IDPRODUCT, \
+	                   CONF_USB_DFUD_BCDDEVICE, \
+	                   CONF_USB_DFUD_IMANUFACT, \
+	                   CONF_USB_DFUD_IPRODUCT, \
+	                   CONF_USB_DFUD_ISERIALNUM, \
+	                   CONF_USB_DFUD_BNUMCONFIG)
+
+#define DFUD_DEV_QUAL_DESC \
+	USB_DEV_QUAL_DESC_BYTES(CONF_USB_DFUD_BCDUSB, \
+	                        CONF_USB_DFUD_BDEVICECLASS, \
+	                        CONF_USB_DFUD_BDEVICESUBCLASS, \
+	                        CONF_USB_DFUD_BMAXPKSZ0, \
+	                        CONF_USB_DFUD_BNUMCONFIG)
+
+#define DFUD_CFG_DESC \
+	USB_CONFIG_DESC_BYTES(CONF_USB_DFUD_WTOTALLENGTH, \
+	                      CONF_USB_DFUD_BNUMINTERFACES, \
+	                      CONF_USB_DFUD_BCONFIGVAL, \
+	                      CONF_USB_DFUD_ICONFIG, \
+	                      CONF_USB_DFUD_BMATTRI, \
+	                      CONF_USB_DFUD_BMAXPOWER)
+
+#define DFUD_OTH_SPD_CFG_DESC \
+	USB_OTH_SPD_CFG_DESC_BYTES(CONF_USB_DFUD_WTOTALLENGTH, \
+	                           CONF_USB_DFUD_BNUMINTERFACES, \
+	                           CONF_USB_DFUD_BCONFIGVAL, \
+	                           CONF_USB_DFUD_ICONFIG, \
+	                           CONF_USB_DFUD_BMATTRI, \
+	                           CONF_USB_DFUD_BMAXPOWER)
+
+#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 */ \
+	                     	                     0x0110 /**< DFU specification version 1.1 used */ )
+
+#define DFUD_IFACE_DESCES \
+	USB_IFACE_DESC_BYTES(CONF_USB_DFUD_BIFCNUM, \
+	                     CONF_USB_DFUD_BALTSET, \
+	                     CONF_USB_DFUD_BNUMEP, \
+	                     USB_DFU_CLASS, \
+	                     USB_DFU_SUBCLASS, \
+	                     USB_DFU_PROTOCOL_DFU, \
+	                     CONF_USB_DFUD_IINTERFACE), \
+	                     DFUD_IFACE_DESCB
+
+#define DFUD_STR_DESCES \
+	CONF_USB_DFUD_LANGID_DESC \
+	CONF_USB_DFUD_IMANUFACT_STR_DESC \
+	CONF_USB_DFUD_IPRODUCT_STR_DESC \
+	CONF_USB_DFUD_ISERIALNUM_STR_DESC \
+	CONF_USB_DFUD_ICONFIG_STR_DESC \
+	CONF_USB_DFUD_IINTERFACE_STR_DESC
+
+/** USB Device descriptors and configuration descriptors */
+#define DFUD_DESCES_LS_FS \
+	DFUD_DEV_DESC, DFUD_CFG_DESC, DFUD_IFACE_DESCES, DFUD_STR_DESCES
+
+#define DFUD_HS_DESCES_LS_FS \
+	DFUD_DEV_DESC, DFUD_DEV_QUAL_DESC, DFUD_CFG_DESC, DFUD_M_IFACE_DESCES, \
+	    DFUD_IFACE_DESCES, DFUD_OTH_SPD_CFG_DESC, \
+	    DFUD_IFACE_DESCES_HS, DFUD_STR_DESCES
+
+#define DFUD_HS_DESCES_HS \
+	DFUD_CFG_DESC, DFUD_IFACE_DESCES, DFUD_IFACE_DESCES_HS, DFUD_OTH_SPD_CFG_DESC, \
+	    DFUD_IFACE_DESCES
+
+#endif /* USBDF_DFU_DESC_H_ */
diff --git a/sysmoOCTSIM/usb/class/dfu/usb_protocol_dfu.h b/sysmoOCTSIM/usb/class/dfu/usb_protocol_dfu.h
new file mode 100644
index 0000000..7f82743
--- /dev/null
+++ b/sysmoOCTSIM/usb/class/dfu/usb_protocol_dfu.h
@@ -0,0 +1,150 @@
+/**
+ * \file
+ *
+ * \brief USB Device Firmware Upgrade (DFU) protocol definitions
+ *
+ * Copyright (c) 2018 sysmocom -s.f.m.c. GmbH, Author: Kevin Redon <kredon at sysmocom.de>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+#ifndef _USB_PROTOCOL_DFU_H_
+#define _USB_PROTOCOL_DFU_H_
+
+#include "usb_includes.h"
+
+/*
+ * \ingroup usb_protocol_group
+ * \defgroup dfu_protocol_group Device Firmware Upgrade Definitions
+ * \implements USB Device Firmware Upgrade Specification, Revision 1.1
+ * @{
+ */
+
+/**
+ * \name USB DFU Subclass IDs
+ */
+//@{
+#define USB_DFU_CLASS 0xFE //!< Application Specific Class Code
+//@}
+
+//! \name USB DFU Subclass IDs
+//@{
+#define USB_DFU_SUBCLASS 0x01 //!< Device Firmware Upgrade Code
+//@}
+
+//! \name USB DFU Protocol IDs
+//@{
+#define USB_DFU_PROTOCOL_RUNTIME 0x01 //!< Runtime protocol
+#define USB_DFU_PROTOCOL_DFU 0x02 //!< DFU mode protocol
+//@}
+
+//! \name USB DFU Attributes bits mask
+//@{
+#define USB_DFU_ATTRIBUTES_CAN_DOWNLOAD 0x01
+#define USB_DFU_ATTRIBUTES_CAN_UPLOAD 0x02
+#define USB_DFU_ATTRIBUTES_MANIFEST_TOLERANT 0x04
+#define USB_DFU_ATTRIBUTES_WILL_DETACH 0x08
+//@}
+
+//! \name USB DFU Request IDs
+//@{
+#define USB_REQ_DFU_DETACH 0x00
+#define USB_REQ_DFU_DNLOAD 0x01
+#define USB_REQ_DFU_UPLOAD 0x02
+#define USB_REQ_DFU_GETSTATUS 0x03
+#define USB_REQ_DFU_CLRSTATUS 0x04
+#define USB_REQ_DFU_GETSTATE 0x05
+#define USB_REQ_DFU_ABORT 0x06
+//@}
+
+/*
+ * Need to pack structures tightly, or the compiler might insert padding
+ * and violate the spec-mandated layout.
+ */
+COMPILER_PACK_SET(1)
+
+//! \name USB DFU Descriptors
+//@{
+
+//! DFU Functional Descriptor
+typedef struct usb_dfu_func_desc {
+	uint8_t bFunctionLength; /**< Size of this descriptor, in bytes (always 9) */
+	uint8_t bDescriptorType; /**< DFU FUNCTIONAL descriptor type (always 0x21) */
+	uint8_t bmAttributes; /**< DFU attributes bit mask */
+	le16_t  wDetachTimeOut; /**< Time, in milliseconds, that the device will wait after receipt of the DFU_DETACH request */
+	le16_t  wTransferSize; /**< Maximum number of bytes that the device can accept per control-write transaction */
+	le16_t  bcdDFUVersion; /**< Numeric expression identifying the version of the DFU Specification release */
+} usb_dfu_func_desc_t;
+
+#define USB_DFU_FUNC_DESC_LEN 9
+#define USB_DFU_FUNC_DESC_TYPE 0x21
+#define USB_DFU_FUNC_DESC_BYTES(bmAttributes, wDetachTimeOut, wTransferSize, bcdDFUVersion) \
+	USB_DFU_FUNC_DESC_LEN, /* bFunctionLength */ \
+	USB_DFU_FUNC_DESC_TYPE, /* bDescriptorType */ \
+	bmAttributes, \
+	LE_BYTE0(wDetachTimeOut), LE_BYTE1(wDetachTimeOut), \
+	LE_BYTE0(wTransferSize), LE_BYTE1(wTransferSize), \
+	LE_BYTE0(bcdDFUVersion), LE_BYTE1(bcdDFUVersion)
+
+COMPILER_PACK_RESET()
+
+//! @}
+
+//! USB DFU Request IDs
+enum usb_dfu_req {
+	USB_DFU_DETACH,
+	USB_DFU_DNLOAD,
+	USB_DFU_UPLOAD,
+	USB_DFU_GETSTATUS,
+	USB_DFU_CLRSTATUS,
+	USB_DFU_GETSTATE,
+	USB_DFU_ABORT,
+};
+
+//! USB DFU Device Status IDs
+enum usb_dfu_status {
+	USB_DFU_STATUS_OK,
+	USB_DFU_STATUS_ERR_TARGET,
+	USB_DFU_STATUS_ERR_FILE,
+	USB_DFU_STATUS_ERR_WRITE,
+	USB_DFU_STATUS_ERR_ERASE,
+	USB_DFU_STATUS_ERR_CHECK_ERASED,
+	USB_DFU_STATUS_ERR_PROG,
+	USB_DFU_STATUS_ERR_VERIFY,
+	USB_DFU_STATUS_ERR_ADDRESS,
+	USB_DFU_STATUS_ERR_NOTDONE,
+	USB_DFU_STATUS_ERR_FIRMWARE,
+	USB_DFU_STATUS_ERR_VENDOR,
+	USB_DFU_STATUS_ERR_USBR,
+	USB_DFU_STATUS_ERR_POR,
+	USB_DFU_STATUS_ERR_UNKNOWN,
+	USB_DFU_STATUS_ERR_STALLEDPKT,
+};
+
+//! USB DFU Device State IDs
+enum usb_dfu_state {
+	USB_DFU_STATE_APP_IDLE,
+	USB_DFU_STATE_APP_DETACH,
+	USB_DFU_STATE_DFU_IDLE,
+	USB_DFU_STATE_DFU_DNLOAD_SYNC,
+	USB_DFU_STATE_DFU_DNBUSY,
+	USB_DFU_STATE_DFU_DNLOAD_IDLE,
+	USB_DFU_STATE_DFU_MANIFEST_SYNC,
+	USB_DFU_STATE_DFU_MANIFEST,
+	USB_DFU_STATE_DFU_MANIFEST_WAIT_RESET,
+	USB_DFU_STATE_DFU_UPLOAD_IDLE,
+	USB_DFU_STATE_DFU_ERROR,
+};
+
+#endif // _USB_PROTOCOL_DFU_H_
diff --git a/sysmoOCTSIM/usb_start.c b/sysmoOCTSIM/usb_start.c
index 08201cb..b87e79e 100644
--- a/sysmoOCTSIM/usb_start.c
+++ b/sysmoOCTSIM/usb_start.c
@@ -132,6 +132,8 @@
 	/* usbdc_register_funcion inside */
 	cdcdf_acm_init();
 
+	dfudf_init();
+
 	printf("usb_descs_size=%u\r\n", usb_descs[0].eod - usb_descs[0].sod);
 	usbdc_start((struct usbd_descriptors *) usb_descs);
 	usbdc_attach();
diff --git a/sysmoOCTSIM/usb_start.h b/sysmoOCTSIM/usb_start.h
index a99d1ad..089c58d 100644
--- a/sysmoOCTSIM/usb_start.h
+++ b/sysmoOCTSIM/usb_start.h
@@ -15,6 +15,8 @@
 #include "cdcdf_acm.h"
 #include "cdcdf_acm_desc.h"
 #include "ccid_df.h"
+#include "dfudf.h"
+#include "dfudf_desc.h"
 
 void usb_start(void);
 void cdc_device_acm_init(void);

-- 
To view, visit https://gerrit.osmocom.org/c/osmo-ccid-firmware/+/17034
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-ccid-firmware
Gerrit-Branch: master
Gerrit-Change-Id: I04d05054d1c0e3988b8eafd93c6524f4a0489cb7
Gerrit-Change-Number: 17034
Gerrit-PatchSet: 5
Gerrit-Owner: Hoernchen <ewild at sysmocom.de>
Gerrit-Reviewer: Hoernchen <ewild at sysmocom.de>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge at osmocom.org>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200210/a14c7dca/attachment.htm>


More information about the gerrit-log mailing list