diff --git a/usbcfg.c b/usbcfg.c index 398e3cb..e6a77ef 100644 --- a/usbcfg.c +++ b/usbcfg.c @@ -15,10 +15,17 @@ */ #include "hal.h" +#include "nanovna.h" /* Virtual serial port over USB.*/ SerialUSBDriver SDU1; +enum { + STR_LANG_ID = 0, + STR_MANUFACTURER, + STR_PRODUCT, + STR_SERIAL +}; /* * Endpoints to be used for USBD1. */ @@ -175,85 +182,41 @@ static const uint8_t vcom_string2[] = { }; #endif -#ifdef TINYSA4 -/* - * Serial Number string. VERSION = 'tinySA4_v1.3-nnn-gxxxxxxx' - * 01234567890123456789012 - * skip last two 'xx' char due to 'tinySA4_v1.3-n-gxxxxxxx' - */ -static const uint8_t vcom_string3[] = -{ -#if 1 - USB_DESC_BYTE(8), /* bLength. */ - USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ - '0' + CH_KERNEL_MAJOR, 0, - '0' + CH_KERNEL_MINOR, 0, - '0' + CH_KERNEL_PATCH, 0 -#else - USB_DESC_BYTE(32), /* bLength. */ - USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ - VERSION[8], 0, /* 'v' */ - VERSION[9], 0, /* '1' */ - VERSION[10], 0, /* '.' */ - VERSION[11], 0, /* '3' */ - VERSION[12], 0, /* '-' */ - VERSION[13], 0, /* 'n' */ - VERSION[14], 0, /* 'n' */ - VERSION[15], 0, /* 'n' */ - VERSION[16], 0, /* '-' */ - VERSION[17], 0, /* 'g' */ - VERSION[18], 0, /* 'x' */ - VERSION[19], 0, /* 'x' */ - VERSION[20], 0, /* 'x' */ - VERSION[21], 0, /* 'x' */ - VERSION[22], 0, /* 'x' */ -#endif -}; -#else -/* - * Serial Number string. VERSION = 'tinySA_v1.3-nnn-gxxxxxxx' - * 0123456789012345678901 - * skip last two 'xx' char due to 'tinySA_v1.3-n-gxxxxxxx' - */ -static const uint8_t vcom_string3[] = { -#if 1 - USB_DESC_BYTE(8), /* bLength. */ - USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ - '0' + CH_KERNEL_MAJOR, 0, - '0' + CH_KERNEL_MINOR, 0, - '0' + CH_KERNEL_PATCH, 0 -#else - USB_DESC_BYTE(32), /* bLength. */ - USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ - VERSION[7], 0, /* 'v' */ - VERSION[8], 0, /* '1' */ - VERSION[9], 0, /* '.' */ - VERSION[10], 0, /* '3' */ - VERSION[11], 0, /* '-' */ - VERSION[12], 0, /* 'n' */ - VERSION[13], 0, /* 'n' */ - VERSION[14], 0, /* 'n' */ - VERSION[15], 0, /* '-' */ - VERSION[16], 0, /* 'g' */ - VERSION[17], 0, /* 'x' */ - VERSION[18], 0, /* 'x' */ - VERSION[19], 0, /* 'x' */ - VERSION[20], 0, /* 'x' */ - VERSION[21], 0, /* 'x' */ -#endif -}; -#endif - /* * Strings wrappers array. */ static const USBDescriptor vcom_strings[] = { {sizeof vcom_string0, vcom_string0}, {sizeof vcom_string1, vcom_string1}, - {sizeof vcom_string2, vcom_string2}, - {sizeof vcom_string3, vcom_string3} + {sizeof vcom_string2, vcom_string2} }; +// Use unique serial string generated from MCU id +#define UID_RADIX 5 // Radix conversion constant (5 bit, use 0..9 and A..V) +#define USB_SERIAL_STRING_SIZE ((64 + UID_RADIX -1) / UID_RADIX) // Result string size +USBDescriptor *getSerialStringDescriptor(void) { + uint16_t i; + uint16_t *buf = ((uint16_t *)&spi_buffer[ARRAY_COUNT(spi_buffer)]) - ((USB_SERIAL_STRING_SIZE + 3) & ~3); // 32 bit align + USBDescriptor *d = ((USBDescriptor *)buf) - 1; + uint32_t id0 = *(uint32_t *)0x1FFFF7AC; // MCU id0 address + uint32_t id1 = *(uint32_t *)0x1FFFF7B0; // MCU id1 address + uint32_t id2 = *(uint32_t *)0x1FFFF7B4; // MCU id2 address + uint64_t uid = id1; + uid = (id0 + id2) | (uid<<32); // generate unique 64bit ID + // Prepare serial string descriptor from 64 bit ID + for(i = 1; i < USB_SERIAL_STRING_SIZE + 1; i++) { + uint16_t c = uid & ((1<>= UID_RADIX; + } + uint16_t size = i * sizeof(uint16_t); + buf[0] = size | (USB_DESCRIPTOR_STRING << 8); + // Generate USBDescriptor structure + d->ud_size = size; + d->ud_string = (uint8_t *)buf; + return d; +} + /* * Handles the GET_DESCRIPTOR callback. All required descriptors must be * handled here. @@ -262,7 +225,6 @@ static const USBDescriptor *get_descriptor(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t lang) { - (void)usbp; (void)lang; switch (dtype) { @@ -271,7 +233,10 @@ static const USBDescriptor *get_descriptor(USBDriver *usbp, case USB_DESCRIPTOR_CONFIGURATION: return &vcom_configuration_descriptor; case USB_DESCRIPTOR_STRING: - if (dindex < 4) + // send unique USB serial string if need + if (dindex == STR_SERIAL) + return getSerialStringDescriptor(); + if (dindex < STR_SERIAL) return &vcom_strings[dindex]; } return NULL;