summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlaforge <laforge@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2006-09-25 21:23:52 +0000
committerlaforge <laforge@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>2006-09-25 21:23:52 +0000
commit5872753e2dbdca5b252470c5210cdf54ee1788dd (patch)
tree4ef919205c8cf5a1864a9fe24a3a6783cb563e2e
parent6b13ecdab08a28deadb4e947cbab740d02352617 (diff)
- Include tool for Converting ASCII to UTF-16LE in C-Header
- Build UTF-16LE USB String descriptors from ASCII File - Introduce USB String Descriptor to DFU and runtime firmware git-svn-id: https://svn.openpcd.org:2342/trunk@227 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
-rw-r--r--firmware/Makefile8
-rw-r--r--firmware/Makefile.dfu13
-rw-r--r--firmware/include/usb_ch9.h2
-rw-r--r--firmware/scripts/usbstring.c197
-rw-r--r--firmware/src/dfu/dfu.c51
-rw-r--r--firmware/src/dfu/dfu.h12
-rw-r--r--firmware/src/os/pcd_enumerate.c60
-rw-r--r--firmware/src/pcd/usb_strings_app.txt6
-rw-r--r--firmware/src/pcd/usb_strings_dfu.txt5
-rw-r--r--firmware/src/picc/usb_strings_app.txt6
-rw-r--r--firmware/src/picc/usb_strings_dfu.txt5
11 files changed, 312 insertions, 53 deletions
diff --git a/firmware/Makefile b/firmware/Makefile
index bc7bd8a..6dabd9a 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -190,14 +190,16 @@ endif
ifeq ($(BOARD),PICC)
CDEFS += -DPICC
+CINCS = -Isrc/picc
endif
ifeq ($(BOARD),PCD)
CDEFS += -DPCD
+CINCS = -Isrc/pcd
endif
# Place -I options here
-CINCS = -Iinclude -Isrc
+CINCS += -Iinclude -Isrc
# Place -D or -U options for ASM here
ADEFS = -D$(RUN_MODE)
@@ -564,11 +566,15 @@ clean_list :
$(REMOVE) $(CPPSRCARM:.cpp=.d)
$(REMOVE) .dep/*
$(REMOVE) include/compile.h
+ $(REMOVE) src/picc/usb_strings_app.h
.PHONY: include/compile.h
include/compile.h:
scripts/mkcompile_h > $@
+src/picc/usb_strings_app.h: ./scripts/usbstring src/picc/usb_strings_app.txt
+ cat $< | ./scripts/usbstring > $@
+
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
diff --git a/firmware/Makefile.dfu b/firmware/Makefile.dfu
index 99cd1b1..ae98f1c 100644
--- a/firmware/Makefile.dfu
+++ b/firmware/Makefile.dfu
@@ -69,6 +69,8 @@ PATH_TO_LINKSCRIPTS=link/
# Target file name (without extension).
TARGET:=dfu
+USBSTRINGS=src/picc/usb_strings_dfu.h src/pcd/usb_strings_dfu.h
+
# List C source files here. (C dependencies are automatically generated.)
# use file-extension c for "c-only"-files
SRC =
@@ -161,16 +163,18 @@ endif
ifeq ($(BOARD),PICC)
CDEFS += -DPICC
ADEFS += -DPICC
+CINCS = -Isrc/picc
endif
ifeq ($(BOARD),PCD)
SUBMDL = AT91SAM7S128
CDEFS += -DPCD
ADEFS += -DPCD
+CINCS = -Isrc/pcd
endif
# Place -I options here
-CINCS = -Iinclude -Isrc
+CINCS += -Iinclude -Isrc
# Place -D or -U options for ASM here
ADEFS += -D$(RUN_MODE)
@@ -465,7 +469,7 @@ $(COBJ) : %.o : %.c
$(CC) -c $(ALL_CFLAGS) $(CONLYFLAGS) $< -o $@
# Compile: create object files from C source files. ARM-only
-$(COBJARM) : %.o : %.c include/compile.h
+$(COBJARM) : %.o : %.c include/compile.h $(USBSTRINGS)
@echo
@echo $(MSG_COMPILING_ARM) $<
$(CC) -c $(ALL_CFLAGS) $(CONLYFLAGS) $< -o $@
@@ -536,11 +540,16 @@ clean_list :
$(REMOVE) $(CPPSRCARM:.cpp=.s)
$(REMOVE) $(CPPSRCARM:.cpp=.d)
$(REMOVE) .dep/*
+ $(REMOVE) src/picc/usb_strings_dfu.h
+ $(REMOVE) src/dfu/usb_strings_dfu.h
.PHONY: include/compile.h
include/compile.h:
scripts/mkcompile_h > $@
+$(USBSTRINGS): %.h : %.txt ./scripts/usbstring
+ cat $< | ./scripts/usbstring > $@
+
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
diff --git a/firmware/include/usb_ch9.h b/firmware/include/usb_ch9.h
index 82edf61..46066f2 100644
--- a/firmware/include/usb_ch9.h
+++ b/firmware/include/usb_ch9.h
@@ -257,7 +257,7 @@ struct usb_string_descriptor {
u_int8_t bLength;
u_int8_t bDescriptorType;
- u_int16_t wData[1]; /* UTF-16LE encoded */
+ u_int16_t wData[0]; /* UTF-16LE encoded */
} __attribute__ ((packed));
/* note that "string" zero is special, it holds language codes that
diff --git a/firmware/scripts/usbstring.c b/firmware/scripts/usbstring.c
new file mode 100644
index 0000000..5348e66
--- /dev/null
+++ b/firmware/scripts/usbstring.c
@@ -0,0 +1,197 @@
+/* AT91SAM7 USB string descriptor builder
+ * (C) 2006 by Harald Welte <laforge@gnumonks.org>
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* Based on existing utf8_to_utf16le() function,
+ * Copyright (C) 2003 David Brownell
+ *
+ * This program 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.
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+
+static int utf8_to_utf16le(const char *s, u_int16_t *cp, unsigned len)
+{
+ int count = 0;
+ u_int8_t c;
+ u_int16_t uchar;
+
+ /* this insists on correct encodings, though not minimal ones.
+ * BUT it currently rejects legit 4-byte UTF-8 code points,
+ * which need surrogate pairs. (Unicode 3.1 can use them.)
+ */
+ while (len != 0 && (c = (u_int8_t) *s++) != 0) {
+ if (c & 0x80) {
+ // 2-byte sequence:
+ // 00000yyyyyxxxxxx = 110yyyyy 10xxxxxx
+ if ((c & 0xe0) == 0xc0) {
+ uchar = (c & 0x1f) << 6;
+
+ c = (u_int8_t) *s++;
+ if ((c & 0xc0) != 0xc0)
+ goto fail;
+ c &= 0x3f;
+ uchar |= c;
+
+ // 3-byte sequence (most CJKV characters):
+ // zzzzyyyyyyxxxxxx = 1110zzzz 10yyyyyy 10xxxxxx
+ } else if ((c & 0xf0) == 0xe0) {
+ uchar = (c & 0x0f) << 12;
+
+ c = (u_int8_t) *s++;
+ if ((c & 0xc0) != 0xc0)
+ goto fail;
+ c &= 0x3f;
+ uchar |= c << 6;
+
+ c = (u_int8_t) *s++;
+ if ((c & 0xc0) != 0xc0)
+ goto fail;
+ c &= 0x3f;
+ uchar |= c;
+
+ /* no bogus surrogates */
+ if (0xd800 <= uchar && uchar <= 0xdfff)
+ goto fail;
+
+ // 4-byte sequence (surrogate pairs, currently rare):
+ // 11101110wwwwzzzzyy + 110111yyyyxxxxxx
+ // = 11110uuu 10uuzzzz 10yyyyyy 10xxxxxx
+ // (uuuuu = wwww + 1)
+ // FIXME accept the surrogate code points (only)
+
+ } else
+ goto fail;
+ } else
+ uchar = c;
+
+ *cp++ = uchar;
+ count++;
+ len--;
+ }
+ return count;
+fail:
+ return -1;
+}
+
+#define COLUMNS 6
+static int print_array16(u_int16_t *buf, int len)
+{
+ int i;
+ for (i = 0; i < len; i++) {
+ int mod = i % COLUMNS;
+ char *suffix;
+ char *prefix;
+
+ switch (mod) {
+ case 0:
+ if (i == 0)
+ prefix = "\t";
+ else
+ prefix= "\t\t\t";
+ suffix = ", ";
+ break;
+ case COLUMNS-1:
+ prefix = "";
+ suffix = ",\n";
+ break;
+ default:
+ prefix = "";
+ suffix = ", ";
+ break;
+ }
+
+ printf("%s0x%04x%s", prefix, buf[i], suffix);
+ }
+}
+
+static void print_structhdr(int i, int size)
+{
+ printf( "static const struct {\n"
+ "\tstruct usb_descriptor_header hdr;\n"
+ "\tu_int16_t wData[];\n"
+ "} __attribute__((packed)) string%d = {\n"
+ "\t.hdr = {\n"
+ "\t\t.bLength = sizeof(struct usb_descriptor_header) + %u * sizeof(u_int16_t),\n"
+ "\t\t.bDescriptorType = USB_DT_STRING,\n"
+ "\t},\n"
+ "\t.wData = {", i, size);
+}
+static void print_structftr(void)
+{
+ printf("},\n};\n\n");
+}
+
+int main(int argc, char **argv)
+{
+ char asciibuf[512+1];
+ u_int16_t utf16buf[1024+1];
+ int len;
+ int j, i = 1;
+
+ printf("#ifndef _USB_STRINGS_H\n#define _USB_STRINGS_H\n\n");
+ printf("/* THIS FILE IS AUTOGENERATED, DO NOT MODIFY MANUALLY */\n\n");
+ printf("#include <usb_ch9.h>\n");
+ printf("#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))\n\n");
+
+ print_structhdr(0, 1);
+ printf("0x0409 /* English */ ");
+ print_structftr();
+#if 0
+ printf("static const struct usb_string_descriptor string0 = {\n"
+ "\t.bLength = sizeof(string0) + 1 * sizeof(u_int16_t),\n"
+ "\t.bDescriptorType = USB_DT_STRING,\n"
+ "\t.wData[0] = 0x0409, /* English */\n"
+ "};\n\n");
+#endif
+
+ while (scanf("%512[^\n]\n", asciibuf) != EOF) {
+ len = strlen(asciibuf);
+ printf("/* String %u \"%s\" */\n", i, asciibuf);
+
+ /* FIXME: check return value */
+ utf8_to_utf16le(asciibuf, utf16buf, len);
+
+ print_structhdr(i, len);
+#if 0
+ printf("static const struct usb_string_descriptor string%d = {\n"
+ "\t.bLength = sizeof(string%d) + %d * sizeof(u_int16_t),\n"
+ "\t.bDescriptorType = USB_DT_STRING,\n"
+ "\t.wData = {", i, i, len);
+#endif
+
+ print_array16(utf16buf, len);
+
+ print_structftr();
+#if 0
+ printf("},\n};\n\n");
+#endif
+
+ i++;
+ }
+
+ printf("static const struct usb_descriptor_header *usb_strings[] = {\n");
+ for (j = 0; j < i; j++)
+ printf("\t(struct usb_descriptor_header *) &string%d,\n", j);
+ printf("};\n\n");
+ printf("#endif /* _USB_STRINGS_H */\n");
+}
diff --git a/firmware/src/dfu/dfu.c b/firmware/src/dfu/dfu.c
index 56f7ef0..40ad64f 100644
--- a/firmware/src/dfu/dfu.c
+++ b/firmware/src/dfu/dfu.c
@@ -26,6 +26,8 @@
#include <board.h>
#include <lib_AT91SAM7.h>
+#include <usb_strings_dfu.h>
+
#include <dfu/dfu.h>
#include <dfu/dbgu.h>
#include <dfu/flash.h>
@@ -547,11 +549,11 @@ __dfustruct const struct usb_device_descriptor dfu_dev_descriptor = {
.bDeviceSubClass = 0x00,
.bDeviceProtocol = 0x00,
.bMaxPacketSize0 = 8,
- .idVendor = OPENPCD_VENDOR_ID,
- .idProduct = OPENPCD_PRODUCT_ID,
+ .idVendor = USB_VENDOR_ID,
+ .idProduct = USB_PRODUCT_ID,
.bcdDevice = 0x0000,
- .iManufacturer = 0x00,
- .iProduct = 0x00,
+ .iManufacturer = 1,
+ .iProduct = 2,
.iSerialNumber = 0x00,
.bNumConfigurations = 0x01,
};
@@ -566,7 +568,7 @@ __dfustruct const struct _dfu_desc dfu_cfg_descriptor = {
USB_DT_DFU_SIZE,
.bNumInterfaces = 1,
.bConfigurationValue = 1,
- .iConfiguration = 0,
+ .iConfiguration = 3,
.bmAttributes = USB_CONFIG_ATT_ONE,
.bMaxPower = 100,
},
@@ -579,7 +581,7 @@ __dfustruct const struct _dfu_desc dfu_cfg_descriptor = {
.bInterfaceClass = 0xfe,
.bInterfaceSubClass = 0x01,
.bInterfaceProtocol = 0x02,
- .iInterface = 0,
+ .iInterface = 4,
},
.uif[1] = {
.bLength = USB_DT_INTERFACE_SIZE,
@@ -590,7 +592,7 @@ __dfustruct const struct _dfu_desc dfu_cfg_descriptor = {
.bInterfaceClass = 0xfe,
.bInterfaceSubClass = 0x01,
.bInterfaceProtocol = 0x02,
- .iInterface = 0,
+ .iInterface = 5,
},
.func_dfu = DFU_FUNC_DESC,
@@ -650,37 +652,48 @@ static __dfufunc void dfu_udp_ep0_handler(void)
/* Handle supported standard device request Cf Table 9-3 in USB
* speciication Rev 1.1 */
switch ((bRequest << 8) | bmRequestType) {
+ u_int8_t desc_type, desc_index;
case STD_GET_DESCRIPTOR:
DEBUGE("GET_DESCRIPTOR ");
- if (wValue == 0x100) {
+ desc_type = wValue >> 8;
+ desc_index = wValue & 0xff;
+ switch (desc_type) {
+ case USB_DT_DEVICE:
/* Return Device Descriptor */
udp_ep0_send_data((const char *)
&dfu_dev_descriptor,
MIN(sizeof(dfu_dev_descriptor),
wLength));
- } else if (wValue == 0x200) {
+ break;
+ case USB_DT_CONFIG:
/* Return Configuration Descriptor */
udp_ep0_send_data((const char *)
&dfu_cfg_descriptor,
MIN(sizeof(dfu_cfg_descriptor),
wLength));
-#if 0
- } else if (wValue == 0x400) {
- /* Return Interface descriptor */
- if (wIndex != 0x01)
+ break;
+ case USB_DT_STRING:
+ /* Return String Descriptor */
+ if (desc_index > ARRAY_SIZE(usb_strings)) {
udp_ep0_send_stall();
- udp_ep0_send_data((const char *)
- &dfu_if_descriptor,
- MIN(sizeof(dfu_if_descriptor),
+ break;
+ }
+ DEBUGP("bLength=%u, wLength=%u\n",
+ usb_strings[desc_index]->bLength, wLength);
+ udp_ep0_send_data((const char *) usb_strings[desc_index],
+ MIN(usb_strings[desc_index]->bLength,
wLength));
-#endif
- } else if (wValue == 0x2100) {
+ break;
+ case USB_DT_CS_DEVICE:
/* Return Function descriptor */
udp_ep0_send_data((const char *) &dfu_cfg_descriptor.func_dfu,
MIN(sizeof(dfu_cfg_descriptor.func_dfu),
wLength));
- } else
+ break;
+ default:
udp_ep0_send_stall();
+ break;
+ }
break;
case STD_SET_ADDRESS:
DEBUGE("SET_ADDRESS ");
diff --git a/firmware/src/dfu/dfu.h b/firmware/src/dfu/dfu.h
index 4d53ce7..084883b 100644
--- a/firmware/src/dfu/dfu.h
+++ b/firmware/src/dfu/dfu.h
@@ -39,6 +39,7 @@
/* USB Interface descriptor in Runtime mode */
#define DFU_RT_IF_DESC { \
+ { \
.bLength = USB_DT_INTERFACE_SIZE, \
.bDescriptorType = USB_DT_INTERFACE, \
.bInterfaceNumber = 0x01, \
@@ -48,6 +49,17 @@
.bInterfaceSubClass = 0x01, \
.bInterfaceProtocol = 0x01, \
.iInterface = 1, \
+ }, { \
+ .bLength = USB_DT_INTERFACE_SIZE, \
+ .bDescriptorType = USB_DT_INTERFACE, \
+ .bInterfaceNumber = 0x02, \
+ .bAlternateSetting = 0x00, \
+ .bNumEndpoints = 0x00, \
+ .bInterfaceClass = 0xfe, \
+ .bInterfaceSubClass = 0x01, \
+ .bInterfaceProtocol = 0x01, \
+ .iInterface = 2, \
+ }, \
}
#define __dfufunctab __attribute__ ((section (".dfu.functab")))
diff --git a/firmware/src/os/pcd_enumerate.c b/firmware/src/os/pcd_enumerate.c
index 63fe608..588831c 100644
--- a/firmware/src/os/pcd_enumerate.c
+++ b/firmware/src/os/pcd_enumerate.c
@@ -34,6 +34,8 @@
#include <lib_AT91SAM7.h>
#include <openpcd.h>
+#include <usb_strings.h>
+
#include <os/pcd_enumerate.h>
#include <os/req_ctx.h>
#include <dfu/dfu.h>
@@ -89,8 +91,8 @@ const struct usb_device_descriptor dev_descriptor = {
.idVendor = USB_VENDOR_ID,
.idProduct = USB_PRODUCT_ID,
.bcdDevice = 0x0000,
- .iManufacturer = 0x00,
- .iProduct = 0x00,
+ .iManufacturer = 3,
+ .iProduct = 4,
.iSerialNumber = 0x00,
.bNumConfigurations = 0x01,
};
@@ -100,8 +102,7 @@ struct _desc {
struct usb_interface_descriptor uif;
struct usb_endpoint_descriptor ep[3];
#ifdef CONFIG_DFU
- struct usb_interface_descriptor uif_dfu;
- struct usb_dfu_func_descriptor func_dfu;
+ struct usb_interface_descriptor uif_dfu[2];
#endif
};
@@ -111,17 +112,16 @@ const struct _desc cfg_descriptor = {
.bDescriptorType = USB_DT_CONFIG,
.wTotalLength = USB_DT_CONFIG_SIZE +
#ifdef CONFIG_DFU
- 2 * USB_DT_INTERFACE_SIZE +
- 3 * USB_DT_ENDPOINT_SIZE +
- USB_DT_DFU_SIZE,
- .bNumInterfaces = 2,
+ 3 * USB_DT_INTERFACE_SIZE +
+ 3 * USB_DT_ENDPOINT_SIZE,
+ .bNumInterfaces = 3,
#else
1 * USB_DT_INTERFACE_SIZE +
3 * USB_DT_ENDPOINT_SIZE,
.bNumInterfaces = 1,
#endif
.bConfigurationValue = 1,
- .iConfiguration = 0,
+ .iConfiguration = 5,
.bmAttributes = USB_CONFIG_ATT_ONE,
.bMaxPower = 100, /* 200mA */
},
@@ -134,7 +134,7 @@ const struct _desc cfg_descriptor = {
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0xff,
- .iInterface = 0,
+ .iInterface = 6,
},
.ep= {
{
@@ -162,16 +162,9 @@ const struct _desc cfg_descriptor = {
},
#ifdef CONFIG_DFU
.uif_dfu = DFU_RT_IF_DESC,
- .func_dfu = DFU_FUNC_DESC,
#endif
};
-static const struct usb_string_descriptor string0 = {
- .bLength = sizeof(string0),
- .bDescriptorType = USB_DT_STRING,
- .wData[0] = 0x0409, /* English */
-};
-
struct epstate {
u_int32_t state_busy;
u_int32_t state_pending;
@@ -568,9 +561,13 @@ static void udp_ep0_handler(void)
/* Handle supported standard device request Cf Table 9-3 in USB
* speciication Rev 1.1 */
switch ((bRequest << 8) | bmRequestType) {
+ u_int8_t desc_type, desc_index;
case STD_GET_DESCRIPTOR:
DEBUGE("GET_DESCRIPTOR ");
- if (wValue == 0x100) {
+ desc_type = wValue >> 8;
+ desc_index = wValue & 0xff;
+ switch (desc_type) {
+ case USB_DT_DEVICE:
/* Return Device Descriptor */
#ifdef CONFIG_DFU
if (*dfu->dfu_state != DFU_STATE_appIDLE)
@@ -582,7 +579,8 @@ static void udp_ep0_handler(void)
#endif
udp_ep0_send_data((const char *) &dev_descriptor,
MIN(sizeof(dev_descriptor), wLength));
- } else if (wValue == 0x200) {
+ break;
+ case USB_DT_CONFIG:
/* Return Configuration Descriptor */
#ifdef CONFIG_DFU
if (*dfu->dfu_state != DFU_STATE_appIDLE)
@@ -594,19 +592,20 @@ static void udp_ep0_handler(void)
#endif
udp_ep0_send_data((const char *) &cfg_descriptor,
MIN(sizeof(cfg_descriptor), wLength));
- } else if (wValue == 0x300) {
+ break;
+ case USB_DT_STRING:
/* Return String descriptor */
- switch (wIndex) {
- case 0:
- udp_ep0_send_data((const char *) &string0,
- MIN(sizeof(string0), wLength));
- break;
- default:
- /* FIXME: implement this */
+ if (desc_index > ARRAY_SIZE(usb_strings)) {
udp_ep0_send_stall();
break;
}
- } else if (wValue == 0x2100) {
+ DEBUGP("bLength=%u, wLength=%u\n",
+ usb_strings[desc_index]->bLength, wLength);
+ udp_ep0_send_data((const char *) usb_strings[desc_index],
+ MIN(usb_strings[desc_index]->bLength,
+ wLength));
+ break;
+ case USB_DT_CS_DEVICE:
/* Return Function descriptor */
udp_ep0_send_data((const char *) &dfu->dfu_cfg_descriptor->func_dfu,
MIN(sizeof(dfu->dfu_cfg_descriptor->func_dfu), wLength));
@@ -620,8 +619,10 @@ static void udp_ep0_handler(void)
MIN(sizeof(dfu_if_descriptor),
wLength));
#endif
- } else
+ break;
+ default:
udp_ep0_send_stall();
+ }
break;
case STD_SET_ADDRESS:
DEBUGE("SET_ADDRESS ");
@@ -710,7 +711,6 @@ static void udp_ep0_handler(void)
DEBUGE("CLEAR_FEATURE_ENDPOINT(EPidx=%u) ", wIndex & 0x0f);
wIndex &= 0x0F;
if ((wValue == 0) && wIndex && (wIndex <= 3)) {
- struct req_ctx *rctx;
reset_ep(wIndex);
udp_ep0_send_zlp();
} else
diff --git a/firmware/src/pcd/usb_strings_app.txt b/firmware/src/pcd/usb_strings_app.txt
new file mode 100644
index 0000000..9180fbc
--- /dev/null
+++ b/firmware/src/pcd/usb_strings_app.txt
@@ -0,0 +1,6 @@
+OpenPCD DFU Interface - Application Partition
+OpenPCD DFU Interface - Bootloader Partition
+bitmanufaktur.de IT Solutions and hmw-consulting.de
+OpenPCD RFID Simulator - Runtime Mode
+OpenPCD Runtime Configuration
+OpenPCD Runtime Interface
diff --git a/firmware/src/pcd/usb_strings_dfu.txt b/firmware/src/pcd/usb_strings_dfu.txt
new file mode 100644
index 0000000..40b7e27
--- /dev/null
+++ b/firmware/src/pcd/usb_strings_dfu.txt
@@ -0,0 +1,5 @@
+bitmanufaktur.de IT Solutions and hmw-consulting.de
+OpenPCD RFID Simulator - DFU Mode
+OpenPCD DFU Configuration
+OpenPCD DFU Interface - Application Partition
+OpenPCD DFU Interface - Bootloader Partition
diff --git a/firmware/src/picc/usb_strings_app.txt b/firmware/src/picc/usb_strings_app.txt
new file mode 100644
index 0000000..ea08dab
--- /dev/null
+++ b/firmware/src/picc/usb_strings_app.txt
@@ -0,0 +1,6 @@
+OpenPICC DFU Interface - Application Partition
+OpenPICC DFU Interface - Bootloader Partition
+bitmanufaktur.de IT Solutions and hmw-consulting.de
+OpenPICC RFID Simulator - Runtime Mode
+OpenPIIC Runtime Configuration
+OpenPICC Runtime Interface
diff --git a/firmware/src/picc/usb_strings_dfu.txt b/firmware/src/picc/usb_strings_dfu.txt
new file mode 100644
index 0000000..681c30a
--- /dev/null
+++ b/firmware/src/picc/usb_strings_dfu.txt
@@ -0,0 +1,5 @@
+bitmanufaktur.de IT Solutions and hmw-consulting.de
+OpenPICC RFID Simulator - DFU Mode
+OpenPIIC DFU Configuration
+OpenPICC DFU Interface - Application Partition
+OpenPICC DFU Interface - Bootloader Partition
personal git repositories of Harald Welte. Your mileage may vary