diff options
Diffstat (limited to 'usb-dfu-experiment/sam3u_chipid_usbserial.c')
-rw-r--r-- | usb-dfu-experiment/sam3u_chipid_usbserial.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/usb-dfu-experiment/sam3u_chipid_usbserial.c b/usb-dfu-experiment/sam3u_chipid_usbserial.c new file mode 100644 index 0000000..c8d0e70 --- /dev/null +++ b/usb-dfu-experiment/sam3u_chipid_usbserial.c @@ -0,0 +1,64 @@ +#include <board.h> + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdint.h> +#include <stdbool.h> + +#include <memories/flash/flashd.h> + +#include <usb/common/core/USBStringDescriptor.h> + +#include <usb/device/dfu/dfu.h> + +/* 128bit binary serial, equals 16 bytes -> 32 hex digits */ +static uint8_t usb_serial_string[USBStringDescriptor_LENGTH(32)]; + +/* convert from 7-bit ASCII to USB string */ +static int to_usb_string(char *out, int out_len, const char *in) +{ + int in_len = strlen(in); + int num_out = USBStringDescriptor_LENGTH(in_len); + int i; + char *cur = out; + + if (num_out > out_len || num_out >= 255 || num_out < 0) + return -EINVAL; + + *cur++ = num_out; + *cur++ = USBGenericDescriptor_STRING; + + for (i = 0; i < in_len; i++) { + *cur++ = in[i]; + *cur++ = 0; + } + + return cur - out; +} + +static int chip_uid_to_usbstring(void) +{ + unsigned long uniqueID[4]; + int rc; + + FLASHD_Initialize(0); + rc = FLASHD_ReadUniqueID(&uniqueID); + if (rc != 0) + return -EIO; + + /* we skip the step to transform the unique-id into hex before + * converting it into a USB string, as it seems to consist of ASCII + * characters instead of a true 128 bit binary unique identifier */ + rc = to_usb_string(usb_serial_string, sizeof(usb_serial_string), (char *) uniqueID); + if (rc > 0) + return 0; + + return rc; +} + +int chipid_to_usbserial(void) +{ + chip_uid_to_usbstring(); + set_usb_serial_str(usb_serial_string); +} |