From 5db9402a5f346e30288db228157f71c29aefce5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Redon?= Date: Mon, 18 Nov 2019 20:06:05 +0100 Subject: [PATCH] add serial and version info in USB description as for the main application firmware, the DFU bootloader firmware now also has the unique chip ID as iSerial in the USB description, and an additional empty USB configuration indicates the firmware version (e.g. DFU bootloader version). these are only visible when the device is in DFU mode. Change-Id: I11a2cd8079fda374d816da180f39f1c33d10af60 --- .../usb/device/dfu/dfu.h | 2 +- .../usb/device/dfu/dfu_desc.c | 152 ++++++++++++++++-- .../usb/device/dfu/dfu_driver.c | 1 + 3 files changed, 141 insertions(+), 14 deletions(-) diff --git a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h index 2a446023..7354696f 100644 --- a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h +++ b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu.h @@ -101,7 +101,7 @@ struct dfudata { extern struct dfudata _g_dfu; extern struct dfudata *g_dfu; -void set_usb_serial_str(const uint8_t *serial_usbstr); +void set_usb_serial_str(void); void DFURT_SwitchToDFU(void); diff --git a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c index 75fded13..ebbe0701 100644 --- a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c +++ b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_desc.c @@ -13,14 +13,87 @@ #include #include +#include "usb_strings_generated.h" + enum { STR_MANUF = 1, STR_PROD, STR_CONFIG, _STR_FIRST_ALT, + // serial string STR_SERIAL = (_STR_FIRST_ALT+BOARD_DFU_NUM_IF), + // version string (on additional interface) + VERSION_CONF_STR, + VERSION_STR, + // count + STRING_DESC_CNT, }; +/* USB string for the serial (using 128-bit device ID) */ +static unsigned char usb_string_serial[] = { + USBStringDescriptor_LENGTH(32), + USBGenericDescriptor_STRING, + USBStringDescriptor_UNICODE('0'), + USBStringDescriptor_UNICODE('0'), + USBStringDescriptor_UNICODE('1'), + USBStringDescriptor_UNICODE('1'), + USBStringDescriptor_UNICODE('2'), + USBStringDescriptor_UNICODE('2'), + USBStringDescriptor_UNICODE('3'), + USBStringDescriptor_UNICODE('3'), + USBStringDescriptor_UNICODE('4'), + USBStringDescriptor_UNICODE('4'), + USBStringDescriptor_UNICODE('5'), + USBStringDescriptor_UNICODE('5'), + USBStringDescriptor_UNICODE('6'), + USBStringDescriptor_UNICODE('6'), + USBStringDescriptor_UNICODE('7'), + USBStringDescriptor_UNICODE('7'), + USBStringDescriptor_UNICODE('8'), + USBStringDescriptor_UNICODE('8'), + USBStringDescriptor_UNICODE('9'), + USBStringDescriptor_UNICODE('9'), + USBStringDescriptor_UNICODE('a'), + USBStringDescriptor_UNICODE('a'), + USBStringDescriptor_UNICODE('b'), + USBStringDescriptor_UNICODE('b'), + USBStringDescriptor_UNICODE('c'), + USBStringDescriptor_UNICODE('c'), + USBStringDescriptor_UNICODE('d'), + USBStringDescriptor_UNICODE('d'), + USBStringDescriptor_UNICODE('e'), + USBStringDescriptor_UNICODE('e'), + USBStringDescriptor_UNICODE('f'), + USBStringDescriptor_UNICODE('f'), +}; + +/* USB string for the version */ +static const unsigned char usb_string_version_conf[] = { + USBStringDescriptor_LENGTH(16), + USBGenericDescriptor_STRING, + USBStringDescriptor_UNICODE('f'), + USBStringDescriptor_UNICODE('i'), + USBStringDescriptor_UNICODE('r'), + USBStringDescriptor_UNICODE('m'), + USBStringDescriptor_UNICODE('w'), + USBStringDescriptor_UNICODE('a'), + USBStringDescriptor_UNICODE('r'), + USBStringDescriptor_UNICODE('e'), + USBStringDescriptor_UNICODE(' '), + USBStringDescriptor_UNICODE('v'), + USBStringDescriptor_UNICODE('e'), + USBStringDescriptor_UNICODE('r'), + USBStringDescriptor_UNICODE('s'), + USBStringDescriptor_UNICODE('i'), + USBStringDescriptor_UNICODE('o'), + USBStringDescriptor_UNICODE('n'), +}; + +static const char git_version[] = GIT_VERSION; +static unsigned char usb_string_version[2 + ARRAY_SIZE(git_version) * 2 - 2]; +/** array of static (from usb_strings) and runtime (serial, version) USB strings */ +static const unsigned char *usb_strings_extended[STRING_DESC_CNT]; + static const USBDeviceDescriptor fsDevice = { .bLength = sizeof(USBDeviceDescriptor), .bDescriptorType = USBGenericDescriptor_DEVICE, @@ -34,12 +107,8 @@ static const USBDeviceDescriptor fsDevice = { .bcdDevice = BOARD_USB_RELEASE, .iManufacturer = STR_MANUF, .iProduct = STR_PROD, -#ifdef BOARD_USB_SERIAL .iSerialNumber = STR_SERIAL, -#else - .iSerialNumber = 0, -#endif - .bNumConfigurations = 1, + .bNumConfigurations = 2, // DFU + version configurations }; /* Alternate Interface Descriptor, we use one per partition/memory type */ @@ -85,17 +154,74 @@ const struct dfu_desc dfu_cfg_descriptor = { .func_dfu = DFU_FUNC_DESC }; -#include "usb_strings_generated.h" - -#if 0 -void set_usb_serial_str(const uint8_t *serial_usbstr) +void set_usb_serial_str(void) { - usb_strings[STR_SERIAL] = serial_usbstr; + unsigned int i; + + // put device ID into USB serial number description + unsigned int device_id[4]; + EEFC_ReadUniqueID(device_id); + char device_id_string[32 + 1]; + snprintf(device_id_string, ARRAY_SIZE(device_id_string), "%08x%08x%08x%08x", + device_id[0], device_id[1], device_id[2], device_id[3]); + for (i = 0; i < ARRAY_SIZE(device_id_string) - 1; i++) { + usb_string_serial[2 + 2 * i] = device_id_string[i]; + } + + // put version into USB string + usb_string_version[0] = USBStringDescriptor_LENGTH(ARRAY_SIZE(git_version) - 1); + usb_string_version[1] = USBGenericDescriptor_STRING; + for (i = 0; i < ARRAY_SIZE(git_version) - 1; i++) { + usb_string_version[2 + i * 2 + 0] = git_version[i]; + usb_string_version[2 + i * 2 + 1] = 0; + } + + // fill extended USB strings + for (i = 0; i < ARRAY_SIZE(usb_strings) && i < ARRAY_SIZE(usb_strings_extended); i++) { + usb_strings_extended[i] = usb_strings[i]; + } + usb_strings_extended[STR_SERIAL] = usb_string_serial; + usb_strings_extended[VERSION_CONF_STR] = usb_string_version_conf; + usb_strings_extended[VERSION_STR] = usb_string_version; } -#endif + +/* USB descriptor just to show the version */ +typedef struct _SIMTraceDriverConfigurationDescriptorVersion { + /** Standard configuration descriptor. */ + USBConfigurationDescriptor configuration; + USBInterfaceDescriptor version; +} __attribute__ ((packed)) SIMTraceDriverConfigurationDescriptorVersion; + +static const SIMTraceDriverConfigurationDescriptorVersion + configurationDescriptorVersion = { + /* Standard configuration descriptor for the interface descriptor*/ + .configuration = { + .bLength = sizeof(USBConfigurationDescriptor), + .bDescriptorType = USBGenericDescriptor_CONFIGURATION, + .wTotalLength = sizeof(SIMTraceDriverConfigurationDescriptorVersion), + .bNumInterfaces = 1, + .bConfigurationValue = 2, + .iConfiguration = VERSION_CONF_STR, + .bmAttributes = USBD_BMATTRIBUTES, + .bMaxPower = USBConfigurationDescriptor_POWER(100), + }, + /* Interface standard descriptor just holding the version information */ + .version = { + .bLength = sizeof(USBInterfaceDescriptor), + .bDescriptorType = USBGenericDescriptor_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 0, + .bInterfaceClass = USB_CLASS_PROPRIETARY, + .bInterfaceSubClass = 0xff, + .bInterfaceProtocol = 0, + .iInterface = VERSION_STR, + }, +}; static const USBConfigurationDescriptor *conf_desc_arr[] = { &dfu_cfg_descriptor.ucfg, + &configurationDescriptorVersion.configuration, }; const USBDDriverDescriptors dfu_descriptors = { @@ -108,6 +234,6 @@ const USBDDriverDescriptors dfu_descriptors = { .pHsConfiguration = NULL, .pHsQualifier = NULL, .pHsOtherSpeed = NULL, - .pStrings = usb_strings, - .numStrings = ARRAY_SIZE(usb_strings), + .pStrings = usb_strings_extended, + .numStrings = ARRAY_SIZE(usb_strings_extended), }; diff --git a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c index 6230d6cd..3ffd9b31 100644 --- a/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c +++ b/firmware/atmel_softpack_libraries/usb/device/dfu/dfu_driver.c @@ -447,6 +447,7 @@ void USBDFU_Initialize(const USBDDriverDescriptors *pDescriptors) /* We already start in DFU idle mode */ g_dfu->state = DFU_STATE_dfuIDLE; + set_usb_serial_str(); USBDDriver_Initialize(&usbdDriver, pDescriptors, if_altsettings); USBD_Init(); USBD_Connect();