From 5e3f0e7f8580d854eb451adbf164a9ab97386d4c Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 8 Nov 2023 09:48:33 +1100 Subject: [PATCH 1/3] samd: Switch to shared TinyUSB implementation. Functionality and code size don't really change, but removes port-specific code in favour of shared code. (The MSC implemented in shared/tinyusb depends on some functions in the pico-sdk, so this change doesn't make this available for samd.) This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton --- ports/samd/Makefile | 6 +- ports/samd/mcu/samd21/mpconfigmcu.mk | 2 + ports/samd/mcu/samd51/mpconfigmcu.mk | 2 + ports/samd/mpconfigport.h | 16 ++++ ports/samd/tusb_port.c | 122 --------------------------- ports/samd/{tusb_config.h => usbd.c} | 35 ++++---- 6 files changed, 41 insertions(+), 142 deletions(-) delete mode 100644 ports/samd/tusb_port.c rename ports/samd/{tusb_config.h => usbd.c} (64%) diff --git a/ports/samd/Makefile b/ports/samd/Makefile index 12223e6ded8f4..95d0f3bd18f48 100644 --- a/ports/samd/Makefile +++ b/ports/samd/Makefile @@ -55,6 +55,7 @@ INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/hpl/tc INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/include INC += -I$(TOP)/lib/asf4/$(MCU_SERIES_LOWER)/include/pio INC += -I$(TOP)/lib/tinyusb/src +INC += -I$(TOP)/shared/tinyusb/ MAKE_PINS = boards/make-pins.py BOARD_PINS = $(BOARD_DIR)/pins.csv @@ -117,7 +118,7 @@ SRC_C += \ samd_qspiflash.c \ samd_soc.c \ samd_spiflash.c \ - tusb_port.c \ + usbd.c \ SHARED_SRC_C += \ drivers/dht/dht.c \ @@ -133,7 +134,8 @@ SHARED_SRC_C += \ shared/runtime/sys_stdio_mphal.c \ shared/timeutils/timeutils.c \ shared/tinyusb/mp_cdc_common.c \ - shared/tinyusb/mp_usbd.c + shared/tinyusb/mp_usbd.c \ + shared/tinyusb/mp_usbd_descriptor.c \ ASF4_SRC_C += $(addprefix lib/asf4/$(MCU_SERIES_LOWER)/,\ hal/src/hal_atomic.c \ diff --git a/ports/samd/mcu/samd21/mpconfigmcu.mk b/ports/samd/mcu/samd21/mpconfigmcu.mk index 35f442d86990a..b3092837cbd15 100644 --- a/ports/samd/mcu/samd21/mpconfigmcu.mk +++ b/ports/samd/mcu/samd21/mpconfigmcu.mk @@ -1,5 +1,7 @@ CFLAGS_MCU += -mtune=cortex-m0plus -mcpu=cortex-m0plus -msoft-float +CFLAGS_MCU += -DCFG_TUSB_MCU=OPT_MCU_SAMD21 + MPY_CROSS_MCU_ARCH = armv6m MICROPY_HW_CODESIZE ?= 184K diff --git a/ports/samd/mcu/samd51/mpconfigmcu.mk b/ports/samd/mcu/samd51/mpconfigmcu.mk index c706331aca459..0201bacffeef1 100644 --- a/ports/samd/mcu/samd51/mpconfigmcu.mk +++ b/ports/samd/mcu/samd51/mpconfigmcu.mk @@ -1,5 +1,7 @@ CFLAGS_MCU += -mtune=cortex-m4 -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard +CFLAGS_MCU += -DCFG_TUSB_MCU=OPT_MCU_SAMD51 + MPY_CROSS_MCU_ARCH = armv7m MICROPY_HW_CODESIZE ?= 368K diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 91a7c1a10d879..497ca9a87004e 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -62,6 +62,13 @@ #define MICROPY_HW_ENABLE_USBDEV (1) #define MICROPY_HW_USB_CDC_1200BPS_TOUCH (1) +#if MICROPY_HW_ENABLE_USBDEV +// Enable USB-CDC serial port +#ifndef MICROPY_HW_USB_CDC +#define MICROPY_HW_USB_CDC (1) +#endif +#endif + // Control over Python builtins #define MICROPY_PY_BUILTINS_BYTES_HEX (1) #define MICROPY_PY_BUILTINS_MEMORYVIEW (1) @@ -141,6 +148,15 @@ #define MP_STATE_PORT MP_STATE_VM +// Miscellaneous settings + +#ifndef MICROPY_HW_USB_VID +#define MICROPY_HW_USB_VID (0xf055) +#endif +#ifndef MICROPY_HW_USB_PID +#define MICROPY_HW_USB_PID (0x9802) +#endif + // Additional entries for use with pendsv_schedule_dispatch. #ifndef MICROPY_BOARD_PENDSV_ENTRIES #define MICROPY_BOARD_PENDSV_ENTRIES diff --git a/ports/samd/tusb_port.c b/ports/samd/tusb_port.c deleted file mode 100644 index e56ef0fd6af00..0000000000000 --- a/ports/samd/tusb_port.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2019 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "samd_soc.h" -#include "tusb.h" - -#ifndef MICROPY_HW_USB_VID -#define MICROPY_HW_USB_VID (0xf055) -#define MICROPY_HW_USB_PID (0x9802) -#endif - -#define USBD_DESC_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN) -#define USBD_MAX_POWER_MA (250) - -#define USBD_ITF_CDC (0) // needs 2 interfaces -#define USBD_ITF_MAX (2) - -#define USBD_CDC_EP_CMD (0x81) -#define USBD_CDC_EP_OUT (0x02) -#define USBD_CDC_EP_IN (0x82) -#define USBD_CDC_CMD_MAX_SIZE (8) -#define USBD_CDC_IN_OUT_MAX_SIZE (64) - -#define USBD_STR_0 (0x00) -#define USBD_STR_MANUF (0x01) -#define USBD_STR_PRODUCT (0x02) -#define USBD_STR_SERIAL (0x03) -#define USBD_STR_CDC (0x04) - -// Note: descriptors returned from callbacks must exist long enough for transfer to complete - -static const tusb_desc_device_t usbd_desc_device = { - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = 0x0200, - .bDeviceClass = TUSB_CLASS_MISC, - .bDeviceSubClass = MISC_SUBCLASS_COMMON, - .bDeviceProtocol = MISC_PROTOCOL_IAD, - .bMaxPacketSize0 = CFG_TUD_ENDOINT0_SIZE, - .idVendor = MICROPY_HW_USB_VID, - .idProduct = MICROPY_HW_USB_PID, - .bcdDevice = 0x0100, - .iManufacturer = USBD_STR_MANUF, - .iProduct = USBD_STR_PRODUCT, - .iSerialNumber = USBD_STR_SERIAL, - .bNumConfigurations = 1, -}; - -static const uint8_t usbd_desc_cfg[USBD_DESC_LEN] = { - TUD_CONFIG_DESCRIPTOR(1, USBD_ITF_MAX, USBD_STR_0, USBD_DESC_LEN, - TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, USBD_MAX_POWER_MA), - - TUD_CDC_DESCRIPTOR(USBD_ITF_CDC, USBD_STR_CDC, USBD_CDC_EP_CMD, - USBD_CDC_CMD_MAX_SIZE, USBD_CDC_EP_OUT, USBD_CDC_EP_IN, USBD_CDC_IN_OUT_MAX_SIZE), -}; - -static const char *const usbd_desc_str[] = { - [USBD_STR_MANUF] = "MicroPython", - [USBD_STR_PRODUCT] = "Board in FS mode", - [USBD_STR_SERIAL] = "000000000000", // TODO - [USBD_STR_CDC] = "Board CDC", -}; - -const uint8_t *tud_descriptor_device_cb(void) { - return (const uint8_t *)&usbd_desc_device; -} - -const uint8_t *tud_descriptor_configuration_cb(uint8_t index) { - (void)index; - return usbd_desc_cfg; -} - -const uint16_t *tud_descriptor_string_cb(uint8_t index, uint16_t langid) { - #define DESC_STR_MAX (20) - static uint16_t desc_str[DESC_STR_MAX]; - - uint8_t len; - if (index == 0) { - desc_str[1] = 0x0409; // supported language is English - len = 1; - } else { - if (index >= sizeof(usbd_desc_str) / sizeof(usbd_desc_str[0])) { - return NULL; - } - const char *str = usbd_desc_str[index]; - for (len = 0; len < DESC_STR_MAX - 1 && str[len]; ++len) { - desc_str[1 + len] = str[len]; - } - } - - // first byte is length (including header), second byte is string type - desc_str[0] = (TUSB_DESC_STRING << 8) | (2 * len + 2); - - return desc_str; -} - -void USB_Handler_wrapper(void) { - tud_int_handler(0); -} diff --git a/ports/samd/tusb_config.h b/ports/samd/usbd.c similarity index 64% rename from ports/samd/tusb_config.h rename to ports/samd/usbd.c index 07fa680cbbb6b..90f2e1bfd95ed 100644 --- a/ports/samd/tusb_config.h +++ b/ports/samd/usbd.c @@ -3,7 +3,7 @@ * * The MIT License (MIT) * - * Copyright (c) 2019 Damien P. George + * Copyright (c) 2023 Angus Gratton * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,25 +23,24 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_SAMD_TUSB_CONFIG_H -#define MICROPY_INCLUDED_SAMD_TUSB_CONFIG_H -// Common configuration +#include "py/mpconfig.h" -#if defined(MCU_SAMD21) -#define CFG_TUSB_MCU OPT_MCU_SAMD21 -#elif defined(MCU_SAMD51) -#define CFG_TUSB_MCU OPT_MCU_SAMD51 -#endif -#define CFG_TUSB_RHPORT0_MODE OPT_MODE_DEVICE -#define CFG_TUSB_MEM_SECTION -#define CFG_TUSB_MEM_ALIGN TU_ATTR_ALIGNED(4) +#if MICROPY_HW_ENABLE_USBDEV + +#include "mp_usbd.h" +#include "string.h" +#include "tusb.h" -// Device configuration +#define SERIAL_TODO "000000000000" // TODO -#define CFG_TUD_ENDOINT0_SIZE (64) -#define CFG_TUD_CDC (1) -#define CFG_TUD_CDC_RX_BUFSIZE (64) -#define CFG_TUD_CDC_TX_BUFSIZE (64) +void mp_usbd_port_get_serial_number(char *serial_buf) { + MP_STATIC_ASSERT(sizeof(SERIAL_TODO) <= MICROPY_HW_USB_DESC_STR_MAX); + strcpy(serial_buf, SERIAL_TODO); +} -#endif // MICROPY_INCLUDED_SAMD_TUSB_CONFIG_H +void USB_Handler_wrapper(void) { + tud_int_handler(0); +} + +#endif From f567a9255a2f801c8e47d8a1468f1c0415971fe4 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 8 Nov 2023 10:34:57 +1100 Subject: [PATCH 2/3] shared/tinyusb: Add a helper for hex string conversion. Change the rp2 and renesas-ra ports to use the helper function. Saves copy-pasta, at the small cost of one more function call in the firmware (if not using LTO). This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton --- ports/renesas-ra/usbd.c | 11 ++--------- ports/rp2/usbd.c | 11 ++--------- shared/tinyusb/mp_usbd.c | 10 ++++++++++ shared/tinyusb/mp_usbd.h | 5 +++++ 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/ports/renesas-ra/usbd.c b/ports/renesas-ra/usbd.c index 7047503864f61..e7252b5f7acfb 100644 --- a/ports/renesas-ra/usbd.c +++ b/ports/renesas-ra/usbd.c @@ -34,15 +34,8 @@ void mp_usbd_port_get_serial_number(char *serial_buf) { const bsp_unique_id_t *id = R_BSP_UniqueIdGet(); - // convert to hex - int hexlen = sizeof(id->unique_id_bytes) * 2; - MP_STATIC_ASSERT(hexlen <= MICROPY_HW_USB_DESC_STR_MAX); - for (int i = 0; i < hexlen; i += 2) { - static const char *hexdig = "0123456789abcdef"; - serial_buf[i] = hexdig[id->unique_id_bytes[i / 2] >> 4]; - serial_buf[i + 1] = hexdig[id->unique_id_bytes[i / 2] & 0x0f]; - } - serial_buf[hexlen] = 0; + MP_STATIC_ASSERT(sizeof(id->unique_id_bytes) * 2 <= MICROPY_HW_USB_DESC_STR_MAX); + mp_usbd_hex_str(serial_buf, id->unique_id_bytes, sizeof(id->unique_id_bytes)); } #endif diff --git a/ports/rp2/usbd.c b/ports/rp2/usbd.c index 568b6284169b2..8724f802f074d 100644 --- a/ports/rp2/usbd.c +++ b/ports/rp2/usbd.c @@ -36,15 +36,8 @@ void mp_usbd_port_get_serial_number(char *serial_buf) { pico_unique_board_id_t id; pico_get_unique_board_id(&id); - // convert to hex - int hexlen = sizeof(id.id) * 2; - MP_STATIC_ASSERT(hexlen <= MICROPY_HW_USB_DESC_STR_MAX); - for (int i = 0; i < hexlen; i += 2) { - static const char *hexdig = "0123456789abcdef"; - serial_buf[i] = hexdig[id.id[i / 2] >> 4]; - serial_buf[i + 1] = hexdig[id.id[i / 2] & 0x0f]; - } - serial_buf[hexlen] = 0; + MP_STATIC_ASSERT(sizeof(id.id) * 2 <= MICROPY_HW_USB_DESC_STR_MAX); + mp_usbd_hex_str(serial_buf, id.id, sizeof(id.id)); } #endif diff --git a/shared/tinyusb/mp_usbd.c b/shared/tinyusb/mp_usbd.c index 55af3d4fb4792..74b3f074927b8 100644 --- a/shared/tinyusb/mp_usbd.c +++ b/shared/tinyusb/mp_usbd.c @@ -62,4 +62,14 @@ static void mp_usbd_task_callback(mp_sched_node_t *node) { mp_usbd_task(); } +void mp_usbd_hex_str(char *out_str, const uint8_t *bytes, size_t bytes_len) { + size_t hex_len = bytes_len * 2; + for (int i = 0; i < hex_len; i += 2) { + static const char *hexdig = "0123456789abcdef"; + out_str[i] = hexdig[bytes[i / 2] >> 4]; + out_str[i + 1] = hexdig[bytes[i / 2] & 0x0f]; + } + out_str[hex_len] = 0; +} + #endif diff --git a/shared/tinyusb/mp_usbd.h b/shared/tinyusb/mp_usbd.h index 340637c95f9c3..83a8f8617c08d 100644 --- a/shared/tinyusb/mp_usbd.h +++ b/shared/tinyusb/mp_usbd.h @@ -36,4 +36,9 @@ void mp_usbd_task(void); // Can write a string up to MICROPY_HW_USB_DESC_STR_MAX characters long, plus terminating byte. extern void mp_usbd_port_get_serial_number(char *buf); +// Most ports need to write a hexadecimal serial number from a byte array, this +// is a helper function for this. out_str must be long enough to hold a string of total +// length (2 * bytes_len + 1) (including NUL terminator). +void mp_usbd_hex_str(char *out_str, const uint8_t *bytes, size_t bytes_len); + #endif // MICROPY_INCLUDED_SHARED_TINYUSB_USBD_H From 8b1980ad450ea2b34af4b831a8c655ba08dee800 Mon Sep 17 00:00:00 2001 From: Angus Gratton Date: Wed, 8 Nov 2023 10:37:04 +1100 Subject: [PATCH 3/3] samd: Use unique id for USB serial number. Replaces the previous all-zeroes "TODO" serial number. Requires refactoring the low-level unique_id routine out from modmachine.c. This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton --- ports/samd/modmachine.c | 42 +++------------------------------------ ports/samd/mpconfigport.h | 5 +++++ ports/samd/samd_soc.c | 36 +++++++++++++++++++++++++++++++++ ports/samd/samd_soc.h | 8 ++++++++ ports/samd/usbd.c | 9 +++++---- 5 files changed, 57 insertions(+), 43 deletions(-) diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c index 7c3d96eb01364..8c4808075e7a3 100644 --- a/ports/samd/modmachine.c +++ b/ports/samd/modmachine.c @@ -92,45 +92,9 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) { STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_freq_obj, 0, 1, machine_freq); STATIC mp_obj_t machine_unique_id(void) { - // Each device has a unique 128-bit serial number which is a concatenation of four 32-bit - // words contained at the following addresses. The uniqueness of the serial number is - // guaranteed only when using all 128 bits. - // Atmel SAM D21E / SAM D21G / SAM D21J - // SMART ARM-Based Microcontroller - // DATASHEET - // 9.6 (SAMD51) or 9.3.3 (or 10.3.3 depending on which manual)(SAMD21) Serial Number - // - // EXAMPLE (SAMD21) - // ---------------- - // OpenOCD: - // Word0: - // > at91samd21g18.cpu mdw 0x0080A00C 1 - // 0x0080a00c: 6e27f15f - // Words 1-3: - // > at91samd21g18.cpu mdw 0x0080A040 3 - // 0x0080a040: 50534b54 332e3120 ff091645 - // - // MicroPython (this code and same order as shown in Arduino IDE) - // >>> binascii.hexlify(machine.unique_id()) - // b'6e27f15f50534b54332e3120ff091645' - - #if defined(MCU_SAMD21) - uint32_t *id_addresses[4] = {(uint32_t *)0x0080A00C, (uint32_t *)0x0080A040, - (uint32_t *)0x0080A044, (uint32_t *)0x0080A048}; - #elif defined(MCU_SAMD51) - uint32_t *id_addresses[4] = {(uint32_t *)0x008061FC, (uint32_t *)0x00806010, - (uint32_t *)0x00806014, (uint32_t *)0x00806018}; - #endif - uint8_t raw_id[16]; - - for (int i = 0; i < 4; i++) { - for (int k = 0; k < 4; k++) { - // 'Reverse' the read bytes into a 32 bit word (Consistent with Arduino) - raw_id[4 * i + k] = (*(id_addresses[i]) >> (24 - k * 8)) & 0xff; - } - } - - return mp_obj_new_bytes((byte *)&raw_id, sizeof(raw_id)); + samd_unique_id_t id; + samd_get_unique_id(&id); + return mp_obj_new_bytes((byte *)&id.bytes, sizeof(id.bytes)); } STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id); diff --git a/ports/samd/mpconfigport.h b/ports/samd/mpconfigport.h index 497ca9a87004e..3684457b48e06 100644 --- a/ports/samd/mpconfigport.h +++ b/ports/samd/mpconfigport.h @@ -67,6 +67,11 @@ #ifndef MICROPY_HW_USB_CDC #define MICROPY_HW_USB_CDC (1) #endif +// SAMD unique ID is 16 bytes (hex string == 32) +#ifndef MICROPY_HW_USB_DESC_STR_MAX +#define MICROPY_HW_USB_DESC_STR_MAX (32) +#endif + #endif // Control over Python builtins diff --git a/ports/samd/samd_soc.c b/ports/samd/samd_soc.c index ad5910301cfc3..dcfff9dc22744 100644 --- a/ports/samd/samd_soc.c +++ b/ports/samd/samd_soc.c @@ -153,3 +153,39 @@ void sercom_deinit_all(void) { } #endif + +void samd_get_unique_id(samd_unique_id_t *id) { + // Atmel SAM D21E / SAM D21G / SAM D21J + // SMART ARM-Based Microcontroller + // DATASHEET + // 9.6 (SAMD51) or 9.3.3 (or 10.3.3 depending on which manual)(SAMD21) Serial Number + // + // EXAMPLE (SAMD21) + // ---------------- + // OpenOCD: + // Word0: + // > at91samd21g18.cpu mdw 0x0080A00C 1 + // 0x0080a00c: 6e27f15f + // Words 1-3: + // > at91samd21g18.cpu mdw 0x0080A040 3 + // 0x0080a040: 50534b54 332e3120 ff091645 + // + // MicroPython (this code and same order as shown in Arduino IDE) + // >>> binascii.hexlify(machine.unique_id()) + // b'6e27f15f50534b54332e3120ff091645' + + #if defined(MCU_SAMD21) + uint32_t *id_addresses[4] = {(uint32_t *)0x0080A00C, (uint32_t *)0x0080A040, + (uint32_t *)0x0080A044, (uint32_t *)0x0080A048}; + #elif defined(MCU_SAMD51) + uint32_t *id_addresses[4] = {(uint32_t *)0x008061FC, (uint32_t *)0x00806010, + (uint32_t *)0x00806014, (uint32_t *)0x00806018}; + #endif + + for (int i = 0; i < 4; i++) { + for (int k = 0; k < 4; k++) { + // 'Reverse' the read bytes into a 32 bit word (Consistent with Arduino) + id->bytes[4 * i + k] = (*(id_addresses[i]) >> (24 - k * 8)) & 0xff; + } + } +} diff --git a/ports/samd/samd_soc.h b/ports/samd/samd_soc.h index 90a5a57ffa14e..707d2f8edfa98 100644 --- a/ports/samd/samd_soc.h +++ b/ports/samd/samd_soc.h @@ -30,6 +30,10 @@ #include "sam.h" #include "clock_config.h" +typedef struct _samd_unique_id_t { + uint8_t bytes[16]; +} samd_unique_id_t; + extern Sercom *sercom_instance[]; void samd_init(void); @@ -40,6 +44,10 @@ void USB_Handler_wrapper(void); void sercom_enable(Sercom *spi, int state); void sercom_register_irq(int sercom_id, void (*sercom_irq_handler)); +// Each device has a unique 128-bit serial number. The uniqueness of the serial number is +// guaranteed only when using all 128 bits. +void samd_get_unique_id(samd_unique_id_t *id); + #define SERCOM_IRQ_TYPE_UART (0) #define SERCOM_IRQ_TYPE_SPI (1) #define SERCOM_IRQ_TYPE_I2C (2) diff --git a/ports/samd/usbd.c b/ports/samd/usbd.c index 90f2e1bfd95ed..2e3200ad7d2b0 100644 --- a/ports/samd/usbd.c +++ b/ports/samd/usbd.c @@ -31,12 +31,13 @@ #include "mp_usbd.h" #include "string.h" #include "tusb.h" - -#define SERIAL_TODO "000000000000" // TODO +#include "samd_soc.h" void mp_usbd_port_get_serial_number(char *serial_buf) { - MP_STATIC_ASSERT(sizeof(SERIAL_TODO) <= MICROPY_HW_USB_DESC_STR_MAX); - strcpy(serial_buf, SERIAL_TODO); + samd_unique_id_t id; + samd_get_unique_id(&id); + MP_STATIC_ASSERT(sizeof(id.bytes) * 2 <= MICROPY_HW_USB_DESC_STR_MAX); + mp_usbd_hex_str(serial_buf, id.bytes, sizeof(id.bytes)); } void USB_Handler_wrapper(void) {