summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2016-02-15 15:24:35 -0800
committerKeith Packard <keithp@keithp.com>2016-02-15 15:24:35 -0800
commit5637c1b2fd7232842245af1437e33b5bb1583c7d (patch)
tree82c5d97e3ad05b512d0ef016fce853cc67c4d4a4 /src
parente4006444d3d7b0c499139f58f13353988d38dbb4 (diff)
altos/stmf0: Use device ID as usb serial number if requested
This exposes the hardware device ID (which is unique per-chip) as the USB serial number, avoiding the need to create a custom ROM image for each device. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src')
-rw-r--r--src/stmf0/ao_usb_stm.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/src/stmf0/ao_usb_stm.c b/src/stmf0/ao_usb_stm.c
index b0f4c516..17e8709c 100644
--- a/src/stmf0/ao_usb_stm.c
+++ b/src/stmf0/ao_usb_stm.c
@@ -570,6 +570,36 @@ ao_usb_ep0_in_start(uint16_t max)
static struct ao_usb_line_coding ao_usb_line_coding = {115200, 0, 0, 8};
+#if AO_USB_DEVICE_ID_SERIAL
+static uint8_t ao_usb_serial[2 + 48];
+
+/* Convert a 32-bit value to 8 hexidecimal UCS2 characters */
+static void
+hex_to_ucs2(uint32_t in, uint8_t *out)
+{
+ int i;
+
+ for (i = 28; i >= 0; i -= 4) {
+ uint8_t bits = (in >> i) & 0xf;
+ *out++ = (bits < 10) ? ('0' + bits) : ('a' + bits);
+ *out++ = 0;
+ }
+}
+
+/* Encode the device ID (96 bits) in hexidecimal to use as a device
+ * serial number
+ */
+static void
+ao_usb_serial_init(void)
+{
+ ao_usb_serial[0] = 50; /* length */
+ ao_usb_serial[1] = AO_USB_DESC_STRING;
+ hex_to_ucs2(stm_device_id.u_id0, ao_usb_serial + 2 + 0);
+ hex_to_ucs2(stm_device_id.u_id1, ao_usb_serial + 2 + 16);
+ hex_to_ucs2(stm_device_id.u_id2, ao_usb_serial + 2 + 32);
+}
+#endif
+
/* Walk through the list of descriptors and find a match
*/
static void
@@ -587,6 +617,13 @@ ao_usb_get_descriptor(uint16_t value)
len = descriptor[2];
else
len = descriptor[0];
+#if AO_USB_DEVICE_ID_SERIAL
+ /* Slightly hacky - the serial number is string 3 */
+ if (type == AO_USB_DESC_STRING && (value & 0xff) == 3) {
+ descriptor = ao_usb_serial;
+ len = sizeof (ao_usb_serial);
+ }
+#endif
ao_usb_ep0_in_set(descriptor, len);
break;
}
@@ -1145,6 +1182,10 @@ ao_usb_init(void)
ao_usb_enable();
+#if AO_USB_DEVICE_ID_SERIAL
+ ao_usb_serial_init();
+#endif
+
debug ("ao_usb_init\n");
ao_usb_ep0_state = AO_USB_EP0_IDLE;