Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

provide unique USB serial number #86

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 43 additions & 10 deletions usbcfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

#include "hal.h"
#include "nanovna.h"

/* Virtual serial port over USB.*/
SerialUSBDriver SDU1;
Expand Down Expand Up @@ -171,15 +172,11 @@ static const uint8_t vcom_string2[] = {
};

/*
* Serial Number string.
* Unique Serial Number string, 2 byte header + 12 utf-16 hex char
* create on request, put at end of spi buffer and return the string
*/
static const uint8_t vcom_string3[] = {
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
};
#define USB_SIZ_STRING_SERIAL (2 + 24)
#define usb_ver_string (((uint8_t*)(&spi_buffer[SPI_BUFFER_SIZE])) - USB_SIZ_STRING_SERIAL)

/*
* Strings wrappers array.
Expand All @@ -188,9 +185,42 @@ 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}
{USB_SIZ_STRING_SERIAL, usb_ver_string}
};

/**
* @brief Convert Hex 32Bits value into utf-16 hex string
* @param value: value to convert
* @param pbuf: pointer to the buffer
* @param len: buffer length
* @retval None
*/
static void uint32_to_utf16_hex(uint32_t value, uint8_t *pbuf, uint8_t len) {
uint8_t idx = 0;
for (idx = 0 ; idx < len ; idx ++) {
if ((value >> 28) < 0xA)
*pbuf++ = (value >> 28) + '0';
else
*pbuf++ = (value >> 28) + 'A' - 10;
*pbuf++ = 0;
value <<= 4;
}
}

/**
* @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) {
usb_ver_string[0] = USB_DESC_BYTE(USB_SIZ_STRING_SERIAL); // bLength
usb_ver_string[1] = USB_DESC_BYTE(USB_DESCRIPTOR_STRING); // bDescriptorType
uint32_to_utf16_hex(*(uint32_t *)0x1FFFF7AC + *(uint32_t *)0x1FFFF7B4, &usb_ver_string[2], 8);
uint32_to_utf16_hex(*(uint32_t *)0x1FFFF7B0, &usb_ver_string[18], 4);
}

/*
* Handles the GET_DESCRIPTOR callback. All required descriptors must be
* handled here.
Expand All @@ -208,8 +238,11 @@ static const USBDescriptor *get_descriptor(USBDriver *usbp,
case USB_DESCRIPTOR_CONFIGURATION:
return &vcom_configuration_descriptor;
case USB_DESCRIPTOR_STRING:
if (dindex < 4)
if (dindex < 4) {
if ( dindex == 3 )
prepare_sernum_str();
return &vcom_strings[dindex];
}
}
return NULL;
}
Expand Down