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 sernum: https://github.com/erikkaashoek/tinySA/issues/85 #112

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
111 changes: 38 additions & 73 deletions usbcfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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) - 1);
buf[i] = c + (c < 0x0A ? '0' : 'A' - 0x0A);
uid>>= 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.
Expand All @@ -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) {
Expand All @@ -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;
Expand Down