8000 samd: Use unique id for USB serial number. · micropython/micropython@8b1980a · GitHub
[go: up one dir, main page]

Skip to content

Commit 8b1980a

Browse files
projectgusdpgeorge
authored andcommitted
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 <angus@redyak.com.au>
1 parent f567a92 commit 8b1980a

File tree

5 files changed

+57
-43
lines changed

5 files changed

+57
-43
lines changed

ports/samd/modmachine.c

Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -92,45 +92,9 @@ STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
9292
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_freq_obj, 0, 1, machine_freq);
9393

9494
STATIC mp_obj_t machine_unique_id(void) {
95-
// Each device has a unique 128-bit serial number which is a concatenation of four 32-bit
96-
// words contained at the following addresses. The uniqueness of the serial number is
97-
// guaranteed only when using all 128 bits.
98-
// Atmel SAM D21E / SAM D21G / SAM D21J
99-
// SMART ARM-Based Microcontroller
100-
// DATASHEET
101-
// 9.6 (SAMD51) or 9.3.3 (or 10.3.3 depending on which manual)(SAMD21) Serial Number
102-
//
103-
// EXAMPLE (SAMD21)
104-
// ----------------
105-
// OpenOCD:
106-
// Word0:
107-
// > at91samd21g18.cpu mdw 0x0080A00C 1
108-
// 0x0080a00c: 6e27f15f
109-
// Words 1-3:
110-
// > at91samd21g18.cpu mdw 0x0080A040 3
111-
// 0x0080a040: 50534b54 332e3120 ff091645
112-
//
113-
// MicroPython (this code and same order as shown in Arduino IDE)
114-
// >>> binascii.hexlify(machine.unique_id())
115-
// b'6e27f15f50534b54332e3120ff091645'
116-
117-
#if defined(MCU_SAMD21)
118-
uint32_t *id_addresses[4] = {(uint32_t *)0x0080A00C, (uint32_t *)0x0080A040,
119-
(uint32_t *)0x0080A044, (uint32_t *)0x0080A048};
120-
#elif defined(MCU_SAMD51)
121-
uint32_t *id_addresses[4] = {(uint32_t *)0x008061FC, (uint32_t *)0x00806010,
122-
(uint32_t *)0x00806014, (uint32_t *)0x00806018};
123-
#endif
124-
uint8_t raw_id[16];
125-
126-
for (int i = 0; i < 4; i++) {
127-
for (int k = 0; k < 4; k++) {
128-
// 'Reverse' the read bytes into a 32 bit word (Consistent with Arduino)
129-
raw_id[4 * i + k] = (*(id_addresses[i]) >> (24 - k * 8)) & 0xff;
130-
}
131-
}
132-
133-
return mp_obj_new_bytes((byte *)&raw_id, sizeof(raw_id));
95+
samd_unique_id_t id;
96+
samd_get_unique_id(&id);
97+
return mp_obj_new_bytes((byte *)&id.bytes, sizeof(id.bytes));
13498
}
13599
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id);
136100

ports/samd/mpconfigport.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@
6767
#ifndef MICROPY_HW_USB_CDC
6868
#define MICROPY_HW_USB_CDC (1)
6969
#endif
70+
// SAMD unique ID is 16 bytes (hex string == 32)
71+
#ifndef MICROPY_HW_USB_DESC_STR_MAX
72+
#define MICROPY_HW_USB_DESC_STR_MAX (32)
73+
#endif
74+
7075
#endif
7176

7277
// Control over Python builtins

ports/samd/samd_soc.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,39 @@ void sercom_deinit_all(void) {
153153
}
154154

155155
#endif
156+
157+
void samd_get_unique_id(samd_unique_id_t *id) {
158+
// Atmel SAM D21E / SAM D21G / SAM D21J
159+
// SMART ARM-Based Microcontroller
160+
// DATASHEET
161+
// 9.6 (SAMD51) or 9.3.3 (or 10.3.3 depending on which manual)(SAMD21) Serial Number
162+
//
163+
// EXAMPLE (SAMD21)
164+
// ----------------
165+
// OpenOCD:
166+
// Word0:
167+
// > at91samd21g18.cpu mdw 0x0080A00C 1
168+
// 0x0080a00c: 6e27f15f
169+
// Words 1-3:
170+
// > at91samd21g18.cpu mdw 0x0080A040 3
171+
// 0x0080a040: 50534b54 332e3120 ff091645
172+
//
173+
// MicroPython (this code and same order as shown in Arduino IDE)
174+
// >>> binascii.hexlify(machine.unique_id())
175+
// b'6e27f15f50534b54332e3120ff091645'
176+
177+
#if defined(MCU_SAMD21)
178+
uint32_t *id_addresses[4] = {(uint32_t *)0x0080A00C, (uint32_t *)0x0080A040,
179+
(uint32_t *)0x0080A044, (uint32_t *)0x0080A048};
180+
#elif defined(MCU_SAMD51)
181+
uint32_t *id_addresses[4] = {(uint32_t *)0x008061FC, (uint32_t *)0x00806010,
182+
(uint32_t *)0x00806014, (uint32_t *)0x00806018};
183+
#endif
184+
185+
for (int i = 0; i < 4; i++) {
186+
for (int k = 0; k < 4; k++) {
187+
// 'Reverse' the read bytes into a 32 bit word (Consistent with Arduino)
188+
id->bytes[4 * i + k] = (*(id_addresses[i]) >> (24 - k * 8)) & 0xff;
189+
}
190+
}
191+
}

ports/samd/samd_soc.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
#include "sam.h"
3131
#include "clock_config.h"
3232

33+
typedef struct _samd_unique_id_t {
34+
uint8_t bytes[16];
35+
} samd_unique_id_t;
36+
3337
extern Sercom *sercom_instance[];
3438

3539
void samd_init(void);
@@ -40,6 +44,10 @@ void USB_Handler_wrapper(void);
4044
void sercom_enable(Sercom *spi, int state);
4145
void sercom_register_irq(int sercom_id, void (*sercom_irq_handler));
4246

47+
// Each device has a unique 128-bit serial number. The uniqueness of the serial number is
48+
// guaranteed only when using all 128 bits.
49+
void samd_get_unique_id(samd_unique_id_t *id);
50+
4351
#define SERCOM_IRQ_TYPE_UART (0)
4452
#define SERCOM_IRQ_TYPE_SPI (1)
4553
#define SERCOM_IRQ_TYPE_I2C (2)

ports/samd/usbd.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,13 @@
3131
#include "mp_usbd.h"
3232
#include "string.h"
3333
#include "tusb.h"
34-
35-
#define SERIAL_TODO "000000000000" // TODO
34+
#include "samd_soc.h"
3635

3736
void mp_usbd_port_get_serial_number(char *serial_buf) {
38-
MP_STATIC_ASSERT(sizeof(SERIAL_TODO) <= MICROPY_HW_USB_DESC_STR_MAX);
39-
strcpy(serial_buf, SERIAL_TODO);
37+
samd_unique_id_t id;
38+
samd_get_unique_id(&id);
39+
MP_STATIC_ASSERT(sizeof(id.bytes) * 2 <= MICROPY_HW_USB_DESC_STR_MAX);
40+
mp_usbd_hex_str(serial_buf, id.bytes, sizeof(id.bytes));
4041
}
4142

4243
void USB_Handler_wrapper(void) {

0 commit comments

Comments
 (0)
0