From 5872753e2dbdca5b252470c5210cdf54ee1788dd Mon Sep 17 00:00:00 2001
From: laforge <laforge@6dc7ffe9-61d6-0310-9af1-9938baff3ed1>
Date: Mon, 25 Sep 2006 21:23:52 +0000
Subject: - 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
---
 firmware/scripts/usbstring.c | 197 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 197 insertions(+)
 create mode 100644 firmware/scripts/usbstring.c

(limited to 'firmware/scripts')

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");
+}
-- 
cgit v1.2.3