Skip to main content

py32_hal/
uid.rs

1//! Unique ID (UID)
2
3// The following code is modified from embassy-stm32
4// https://github.com/embassy-rs/embassy/tree/main/embassy-stm32
5// Special thanks to the Embassy Project and its contributors for their work!
6
7/// Get this device's unique 128-bit ID.
8/// The datasheet (seems to) specify a 128-bit UID, while the SDK uses 96-bit.
9/// We read the full 128 bits to ensure uniqueness.
10/// Note that the last 4 bytes of the ID consist of unknown "internal coding" and fixed values.
11pub fn uid() -> [u8; 16] {
12    unsafe { *crate::pac::UID.uid(0).as_ptr().cast::<[u8; 16]>() }
13}
14
15/// Get this device's unique 128-bit ID, encoded into a string of 32 hexadecimal ASCII digits. See documentation for `uid` for caveats.
16pub fn uid_hex() -> &'static str {
17    unsafe { core::str::from_utf8_unchecked(uid_hex_bytes()) }
18}
19
20/// Get this device's unique 128-bit ID, encoded into 32 hexadecimal ASCII bytes. See documentation about `uid` for caveats.
21pub fn uid_hex_bytes() -> &'static [u8; 32] {
22    const HEX: &[u8; 16] = b"0123456789ABCDEF";
23    static mut UID_HEX: [u8; 32] = [0; 32];
24    static mut LOADED: bool = false;
25    critical_section::with(|_| unsafe {
26        if !LOADED {
27            let uid = uid();
28            for (idx, v) in uid.iter().enumerate() {
29                let lo = v & 0x0f;
30                let hi = (v & 0xf0) >> 4;
31                UID_HEX[idx * 2] = HEX[hi as usize];
32                UID_HEX[idx * 2 + 1] = HEX[lo as usize];
33            }
34            LOADED = true;
35        }
36    });
37    unsafe { &*core::ptr::addr_of!(UID_HEX) }
38}