Skip to content

Commit 054e2d8

Browse files
committed
Initial commit
0 parents  commit 054e2d8

File tree

4 files changed

+108
-0
lines changed

4 files changed

+108
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/target
2+
Cargo.lock

Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[package]
2+
name = "stm32-device-signature"
3+
version = "0.1.0"
4+
authors = ["Vadim Kaushan <[email protected]>"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
cortex-m = "0.6.2"
9+
10+
[features]
11+
stm32f0 = []
12+
stm32f1 = []
13+
stm32f3 = []
14+
stm32f4 = []
15+
stm32g0 = []
16+
stm32l0 = []
17+
stm32l4 = []

build.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
fn main() {
2+
let families: Vec<_> = std::env::vars().filter_map(|(key, _value)| {
3+
if key.starts_with("CARGO_FEATURE_STM32") {
4+
Some(key[14..].to_ascii_lowercase()) // Strip 'CARGO_FEATURE_'
5+
} else {
6+
None
7+
}
8+
}).collect();
9+
10+
if families.is_empty() {
11+
println!("No family features selected");
12+
std::process::exit(1);
13+
}
14+
if families.len() > 1 {
15+
println!("More than one family feature selected: {:?}", families);
16+
std::process::exit(1);
17+
}
18+
}

src/lib.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#![no_std]
2+
3+
use core::slice;
4+
use cortex_m::interrupt;
5+
6+
#[cfg(any(feature = "stm32f0", feature = "stm32f3"))]
7+
mod pointers {
8+
pub const DEVICE_ID_PTR: *const u8 = 0x1FFF_F7AC as _;
9+
pub const FLASH_SIZE_PTR: *const u16 = 0x1FFF_F7CC as _;
10+
}
11+
12+
#[cfg(feature = "stm32f1")]
13+
mod pointers {
14+
pub const DEVICE_ID_PTR: *const u8 = 0x1FFF_F7E8 as _;
15+
pub const FLASH_SIZE_PTR: *const u16 = 0x1FFF_F7E0 as _;
16+
}
17+
18+
#[cfg(feature = "stm32f4")]
19+
mod pointers {
20+
pub const DEVICE_ID_PTR: *const u8 = 0x1FFF_7A10 as _;
21+
pub const FLASH_SIZE_PTR: *const u16 = 0x1FFF_7A22 as _;
22+
}
23+
24+
#[cfg(any(feature = "stm32g0", feature = "stm32l4"))]
25+
mod pointers {
26+
pub const DEVICE_ID_PTR: *const u8 = 0x1FFF_7590 as _;
27+
pub const FLASH_SIZE_PTR: *const u16 = 0x1FFF_75E0 as _;
28+
}
29+
30+
#[cfg(feature = "stm32l0")]
31+
mod pointers {
32+
pub const DEVICE_ID_PTR: *const u8 = 0x1FF8_0050 as _;
33+
pub const FLASH_SIZE_PTR: *const u16 = 0x1FF8_007C as _;
34+
}
35+
36+
use pointers::*;
37+
38+
39+
/// Returns a 12-byte slice with a unique device ID
40+
pub fn device_id() -> &'static [u8] {
41+
unsafe { slice::from_raw_parts(DEVICE_ID_PTR, 12) }
42+
}
43+
44+
45+
/// Returns a string with a hex-encoded unique device ID
46+
pub fn device_id_hex() -> &'static str {
47+
static mut DEVICE_ID_STR: [u8; 24] = [0; 24];
48+
49+
unsafe {
50+
if DEVICE_ID_STR.as_ptr().read_volatile() == 0 {
51+
interrupt::free(|_| {
52+
let hex = "0123456789abcdef".as_bytes();
53+
let device_id = slice::from_raw_parts(DEVICE_ID_PTR, 12);
54+
for i in 0..12 {
55+
let lo = device_id[i] & 0xf;
56+
let hi = (device_id[i] >> 4) & 0xf;
57+
DEVICE_ID_STR[i*2] = hex[lo as usize];
58+
DEVICE_ID_STR[i*2+1] = hex[hi as usize];
59+
}
60+
});
61+
}
62+
63+
core::str::from_utf8_unchecked(&DEVICE_ID_STR)
64+
}
65+
}
66+
67+
68+
/// Returns the Flash memory size of the device in Kbytes
69+
pub fn flash_size_kb() -> u16 {
70+
unsafe { *FLASH_SIZE_PTR }
71+
}

0 commit comments

Comments
 (0)