kopia lustrzana https://github.com/micropython/micropython
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>pull/12908/head
rodzic
f567a9255a
commit
8b1980ad45
|
@ -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_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_freq_obj, 0, 1, machine_freq);
|
||||||
|
|
||||||
STATIC mp_obj_t machine_unique_id(void) {
|
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
|
samd_unique_id_t id;
|
||||||
// words contained at the following addresses. The uniqueness of the serial number is
|
samd_get_unique_id(&id);
|
||||||
// guaranteed only when using all 128 bits.
|
return mp_obj_new_bytes((byte *)&id.bytes, sizeof(id.bytes));
|
||||||
// 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));
|
|
||||||
}
|
}
|
||||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id);
|
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id);
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,11 @@
|
||||||
#ifndef MICROPY_HW_USB_CDC
|
#ifndef MICROPY_HW_USB_CDC
|
||||||
#define MICROPY_HW_USB_CDC (1)
|
#define MICROPY_HW_USB_CDC (1)
|
||||||
#endif
|
#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
|
#endif
|
||||||
|
|
||||||
// Control over Python builtins
|
// Control over Python builtins
|
||||||
|
|
|
@ -153,3 +153,39 @@ void sercom_deinit_all(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
#include "sam.h"
|
#include "sam.h"
|
||||||
#include "clock_config.h"
|
#include "clock_config.h"
|
||||||
|
|
||||||
|
typedef struct _samd_unique_id_t {
|
||||||
|
uint8_t bytes[16];
|
||||||
|
} samd_unique_id_t;
|
||||||
|
|
||||||
extern Sercom *sercom_instance[];
|
extern Sercom *sercom_instance[];
|
||||||
|
|
||||||
void samd_init(void);
|
void samd_init(void);
|
||||||
|
@ -40,6 +44,10 @@ void USB_Handler_wrapper(void);
|
||||||
void sercom_enable(Sercom *spi, int state);
|
void sercom_enable(Sercom *spi, int state);
|
||||||
void sercom_register_irq(int sercom_id, void (*sercom_irq_handler));
|
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_UART (0)
|
||||||
#define SERCOM_IRQ_TYPE_SPI (1)
|
#define SERCOM_IRQ_TYPE_SPI (1)
|
||||||
#define SERCOM_IRQ_TYPE_I2C (2)
|
#define SERCOM_IRQ_TYPE_I2C (2)
|
||||||
|
|
|
@ -31,12 +31,13 @@
|
||||||
#include "mp_usbd.h"
|
#include "mp_usbd.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "tusb.h"
|
#include "tusb.h"
|
||||||
|
#include "samd_soc.h"
|
||||||
#define SERIAL_TODO "000000000000" // TODO
|
|
||||||
|
|
||||||
void mp_usbd_port_get_serial_number(char *serial_buf) {
|
void mp_usbd_port_get_serial_number(char *serial_buf) {
|
||||||
MP_STATIC_ASSERT(sizeof(SERIAL_TODO) <= MICROPY_HW_USB_DESC_STR_MAX);
|
samd_unique_id_t id;
|
||||||
strcpy(serial_buf, SERIAL_TODO);
|
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) {
|
void USB_Handler_wrapper(void) {
|
||||||
|
|
Ładowanie…
Reference in New Issue