Switch to DiSlord's UID algorithm with radix32 encoding [0-9,A-V]

Signed-off-by: Martin <Ho-Ro@users.noreply.github.com>
pull/112/head
Martin 1 year ago
parent 51a6fc69cf
commit e7d2c0f8d7

@ -15,10 +15,17 @@
*/ */
#include "hal.h" #include "hal.h"
#include "nanovna.h"
/* Virtual serial port over USB.*/ /* Virtual serial port over USB.*/
SerialUSBDriver SDU1; SerialUSBDriver SDU1;
enum {
STR_LANG_ID = 0,
STR_MANUFACTURER,
STR_PRODUCT,
STR_SERIAL
};
/* /*
* Endpoints to be used for USBD1. * Endpoints to be used for USBD1.
*/ */
@ -175,63 +182,39 @@ static const uint8_t vcom_string2[] = {
}; };
#endif #endif
/*
* Serial Number string.
*/
#define USB_SIZ_STRING_SERIAL (2 + 24)
static uint8_t vcom_string3[USB_SIZ_STRING_SERIAL] = {
USB_DESC_BYTE(USB_SIZ_STRING_SERIAL), /* bLength. */
USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */
/* here goes the 12 char string encoded as UTF-16 (one ASCII, one 0x00) */
};
/* /*
* Strings wrappers array. * Strings wrappers array.
*/ */
static const USBDescriptor vcom_strings[] = { static const USBDescriptor vcom_strings[] = {
{sizeof vcom_string0, vcom_string0}, {sizeof vcom_string0, vcom_string0},
{sizeof vcom_string1, vcom_string1}, {sizeof vcom_string1, vcom_string1},
{sizeof vcom_string2, vcom_string2}, {sizeof vcom_string2, vcom_string2}
{sizeof vcom_string3, vcom_string3}
}; };
/** // Use unique serial string generated from MCU id
* @brief Convert Hex 32Bits value into char #define UID_RADIX 5 // Radix conversion constant (5 bit, use 0..9 and A..V)
* @param value: value to convert #define USB_SERIAL_STRING_SIZE ((64 + UID_RADIX -1) / UID_RADIX) // Result string size
* @param pbuf: pointer to the buffer USBDescriptor *getSerialStringDescriptor(void) {
* @param len: buffer length uint16_t i;
* @retval None 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;
static void int_to_unicode(uint32_t value, uint8_t *pbuf, uint8_t len) { uint32_t id0 = *(uint32_t *)0x1FFFF7AC; // MCU id0 address
uint8_t idx = 0; uint32_t id1 = *(uint32_t *)0x1FFFF7B0; // MCU id1 address
for (idx = 0 ; idx < len ; idx ++) { uint32_t id2 = *(uint32_t *)0x1FFFF7B4; // MCU id2 address
if (((value >> 28)) < 0xA) { uint64_t uid = id1;
pbuf[ 2 * idx] = (value >> 28) + '0'; uid = (id0 + id2) | (uid<<32); // generate unique 64bit ID
} else { // Prepare serial string descriptor from 64 bit ID
pbuf[2 * idx] = (value >> 28) + 'A' - 10; for(i = 1; i < USB_SERIAL_STRING_SIZE + 1; i++) {
} uint16_t c = uid & ((1<<UID_RADIX) - 1);
value = value << 4; buf[i] = c + (c < 0x0A ? '0' : 'A' - 0x0A);
pbuf[ 2 * idx + 1] = 0; uid>>= UID_RADIX;
}
}
/**
* @brief Create the serial number string descriptor
* @param None
* @retval None
* format and algorithm inspired by:
* https://github.com/limbongofficial/STM32_Core-Arduino/blob/master/cores/arduino/stm32/usb/usbd_desc.c#L326-L370
*/
static void prepare_sernum_str(void) {
uint32_t deviceserial0, deviceserial1, deviceserial2;
deviceserial0 = *(uint32_t *)0x1FFFF7AC;
deviceserial1 = *(uint32_t *)0x1FFFF7B0;
deviceserial2 = *(uint32_t *)0x1FFFF7B4;
deviceserial0 += deviceserial2;
if (deviceserial0 != 0) {
int_to_unicode(deviceserial0, &vcom_string3[2], 8);
int_to_unicode(deviceserial1, &vcom_string3[18], 4);
} }
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;
} }
/* /*
@ -242,7 +225,6 @@ static const USBDescriptor *get_descriptor(USBDriver *usbp,
uint8_t dtype, uint8_t dtype,
uint8_t dindex, uint8_t dindex,
uint16_t lang) { uint16_t lang) {
(void)usbp; (void)usbp;
(void)lang; (void)lang;
switch (dtype) { switch (dtype) {
@ -251,11 +233,11 @@ static const USBDescriptor *get_descriptor(USBDriver *usbp,
case USB_DESCRIPTOR_CONFIGURATION: case USB_DESCRIPTOR_CONFIGURATION:
return &vcom_configuration_descriptor; return &vcom_configuration_descriptor;
case USB_DESCRIPTOR_STRING: case USB_DESCRIPTOR_STRING:
if (dindex < 4) { // send unique USB serial string if need
if ( dindex == 3 && vcom_string3[2] == 0 ) // not yet done if (dindex == STR_SERIAL)
prepare_sernum_str(); return getSerialStringDescriptor();
if (dindex < STR_SERIAL)
return &vcom_strings[dindex]; return &vcom_strings[dindex];
}
} }
return NULL; return NULL;
} }

Loading…
Cancel
Save

Powered by TurnKey Linux.