1//! Serial number
23use atsamd_hal_macros::hal_cfg;
4use core::ptr;
56// See 9.6 Memories --> Serial Number, page 24 for samd11
7// See 10.3.3 Memories --> Serial Number, page 45 for samd21
8#[hal_cfg(any("serial-numbers-d11", "serial-numbers-d21"))]
9const SN_1: u32 = 0x0080A00C;
10#[hal_cfg(any("serial-numbers-d11", "serial-numbers-d21"))]
11const SN_2: u32 = 0x0080A040;
12#[hal_cfg(any("serial-numbers-d11", "serial-numbers-d21"))]
13const SN_3: u32 = 0x0080A044;
14#[hal_cfg(any("serial-numbers-d11", "serial-numbers-d21"))]
15const SN_4: u32 = 0x0080A048;
1617// See 9.6 Memories --> Serial Number, page 60
18#[hal_cfg("serial-numbers-d5x")]
19const SN_1: u32 = 0x008061FC;
20#[hal_cfg("serial-numbers-d5x")]
21const SN_2: u32 = 0x00806010;
22#[hal_cfg("serial-numbers-d5x")]
23const SN_3: u32 = 0x00806014;
24#[hal_cfg("serial-numbers-d5x")]
25const SN_4: u32 = 0x00806018;
2627/// Returns the serial number of the chip as 4 32-bit integers. The serial
28/// number is only guaranteed to be unique if all 128 bits are used.
29pub fn split_serial_number() -> (u32, u32, u32, u32) {
30unsafe {
31 (
32 ptr::read(SN_1 as *const u32),
33 ptr::read(SN_2 as *const u32),
34 ptr::read(SN_3 as *const u32),
35 ptr::read(SN_4 as *const u32),
36 )
37 }
38}
3940/// Returns the serial number of the chip as an array of bytes. The serial
41/// number is only guaranteed to be unique if all 16 bytes are used.
42pub fn serial_number() -> [u8; 16] {
43let sn = split_serial_number();
44 [
45 ((sn.0 >> 24) & 0xff) as u8,
46 ((sn.0 >> 16) & 0xff) as u8,
47 ((sn.0 >> 8) & 0xff) as u8,
48 (sn.0 & 0xff) as u8,
49 ((sn.1 >> 24) & 0xff) as u8,
50 ((sn.1 >> 16) & 0xff) as u8,
51 ((sn.1 >> 8) & 0xff) as u8,
52 (sn.1 & 0xff) as u8,
53 ((sn.2 >> 24) & 0xff) as u8,
54 ((sn.2 >> 16) & 0xff) as u8,
55 ((sn.2 >> 8) & 0xff) as u8,
56 (sn.2 & 0xff) as u8,
57 ((sn.3 >> 24) & 0xff) as u8,
58 ((sn.3 >> 16) & 0xff) as u8,
59 ((sn.3 >> 8) & 0xff) as u8,
60 (sn.3 & 0xff) as u8,
61 ]
62}