summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/samd/modmachine.c42
-rw-r--r--ports/samd/mpconfigport.h5
-rw-r--r--ports/samd/samd_soc.c36
-rw-r--r--ports/samd/samd_soc.h8
-rw-r--r--ports/samd/usbd.c9
5 files changed, 57 insertions, 43 deletions
diff --git a/ports/samd/modmachine.c b/ports/samd/modmachine.c
index 7c3d96eb0..8c4808075 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 497ca9a87..3684457b4 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 ad5910301..dcfff9dc2 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 90a5a57ff..707d2f8ed 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 90f2e1bfd..2e3200ad7 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) {