Skip to content

Commit 59da6d7

Browse files
committed
Implement signature module
Can be used to read the flash size and device UID
1 parent b782375 commit 59da6d7

File tree

2 files changed

+82
-0
lines changed

2 files changed

+82
-0
lines changed

src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ pub mod spi;
5858
pub mod time;
5959
#[cfg(feature = "device-selected")]
6060
pub mod timers;
61+
#[cfg(feature = "device-selected")]
62+
pub mod signature;
6163
#[cfg(any(
6264
feature = "stm32f031",
6365
feature = "stm32f051",

src/signature.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
//! Device electronic signature
2+
//!
3+
//! (stored in flash memory)
4+
5+
use core::str::from_utf8_unchecked;
6+
7+
/// This is the test voltage in millivolts of the calibration done at the factory
8+
pub const VDDA_CALIB: u32 = 3300;
9+
10+
macro_rules! define_ptr_type {
11+
($name: ident, $ptr: expr) => {
12+
impl $name {
13+
fn ptr() -> *const Self {
14+
$ptr as *const _
15+
}
16+
17+
/// Returns a wrapped reference to the value in flash memory
18+
pub fn get() -> &'static Self {
19+
unsafe { &*Self::ptr() }
20+
}
21+
}
22+
};
23+
}
24+
25+
// f030 and f070 don't have a UID in ROM
26+
#[cfg(not(any(feature = "stm32f030", feature = "stm32f070")))]
27+
#[derive(Hash, Debug)]
28+
#[repr(C)]
29+
pub struct Uid {
30+
x: u16,
31+
y: u16,
32+
waf_lot: [u8; 8],
33+
}
34+
#[cfg(not(any(feature = "stm32f030", feature = "stm32f070")))]
35+
define_ptr_type!(Uid, 0x1FFF_F7AC);
36+
37+
/// Device UID from ROM. See the [reference manual](https://www.st.com/content/ccc/resource/technical/document/reference_manual/c2/f8/8a/f2/18/e6/43/96/DM00031936.pdf/files/DM00031936.pdf/jcr:content/translations/en.DM00031936.pdf#%5B%7B%22num%22%3A1575%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C67%2C755%2Cnull%5D) for more info.
38+
#[cfg(not(any(feature = "stm32f030", feature = "stm32f070")))]
39+
impl Uid {
40+
/// X coordinate on wafer
41+
pub fn x(&self) -> u16 {
42+
self.x
43+
}
44+
45+
/// Y coordinate on wafer
46+
pub fn y(&self) -> u16 {
47+
self.y
48+
}
49+
50+
/// Wafer number
51+
pub fn waf_num(&self) -> u8 {
52+
self.waf_lot[0]
53+
}
54+
55+
/// Lot number
56+
pub fn lot_num(&self) -> &str {
57+
unsafe { from_utf8_unchecked(&self.waf_lot[1..]) }
58+
}
59+
}
60+
61+
/// Size of integrated flash
62+
#[derive(Debug)]
63+
#[repr(C)]
64+
pub struct FlashSize(u16);
65+
#[cfg(not(any(feature = "stm32f030", feature = "stm32f070")))]
66+
define_ptr_type!(FlashSize, 0x1FFF_F7CC);
67+
#[cfg(any(feature = "stm32f030", feature = "stm32f070"))]
68+
define_ptr_type!(FlashSize, 0x1FFF_0000);
69+
70+
impl FlashSize {
71+
/// Read flash size in kilobytes
72+
pub fn kilo_bytes(&self) -> u16 {
73+
self.0
74+
}
75+
76+
/// Read flash size in bytes
77+
pub fn bytes(&self) -> usize {
78+
usize::from(self.kilo_bytes()) * 1024
79+
}
80+
}

0 commit comments

Comments
 (0)