Skip to content

Commit eb34e8f

Browse files
astrotherealprof
authored andcommitted
implement device electronic signature (#89)
* implement signature * signature: DRY with define_ptr_type! * signature: add VrefCal, VtempCal30, VtempCal110 * signature: use unsafe {} in Uid.lot_num() * CHANGELOG: add signature
1 parent 469d551 commit eb34e8f

File tree

3 files changed

+116
-1
lines changed

3 files changed

+116
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1515

1616
- Implement IndependentWatchdog for the IWDG peripheral
1717

18+
- Implement reading the device electronic signature from flash
19+
1820
## [v0.3.0] - 2019-01-14
1921

2022
### Added

src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,6 @@ pub mod timer;
102102
#[cfg(feature = "device-selected")]
103103
pub mod watchdog;
104104
#[cfg(feature = "device-selected")]
105-
pub mod adc;
105+
pub mod adc;
106+
#[cfg(feature = "device-selected")]
107+
pub mod signature;

src/signature.rs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
//! Device electronic signature
2+
//!
3+
//! (stored in flash memory)
4+
5+
use core::str::from_utf8_unchecked;
6+
7+
macro_rules! define_ptr_type {
8+
($name: ident, $ptr: expr) => (
9+
impl $name {
10+
fn ptr() -> *const Self {
11+
$ptr as *const _
12+
}
13+
14+
/// Returns a wrapped reference to the value in flash memory
15+
pub fn get() -> &'static Self {
16+
unsafe { &*Self::ptr() }
17+
}
18+
}
19+
)
20+
}
21+
22+
/// Uniqure Device ID register
23+
#[derive(Hash, Debug)]
24+
#[repr(C)]
25+
pub struct Uid {
26+
x: u16,
27+
y: u16,
28+
waf_lot: [u8; 8],
29+
}
30+
define_ptr_type!(Uid, 0x1FFF_7A10);
31+
32+
impl Uid {
33+
/// X coordinate on wafer
34+
pub fn x(&self) -> u16 {
35+
self.x
36+
}
37+
38+
/// Y coordinate on wafer
39+
pub fn y(&self) -> u16 {
40+
self.y
41+
}
42+
43+
/// Wafer number
44+
pub fn waf_num(&self) -> u8 {
45+
self.waf_lot[0].into()
46+
}
47+
48+
/// Lot number
49+
pub fn lot_num(&self) -> &str {
50+
unsafe {
51+
from_utf8_unchecked(&self.waf_lot[1..])
52+
}
53+
}
54+
}
55+
56+
/// Size of integrated flash
57+
#[derive(Debug)]
58+
#[repr(C)]
59+
pub struct FlashSize(u16);
60+
define_ptr_type!(FlashSize, 0x1FFF_7A22);
61+
62+
impl FlashSize {
63+
/// Read flash size in kilobytes
64+
pub fn kilo_bytes(&self) -> u16 {
65+
self.0
66+
}
67+
68+
/// Read flash size in bytes
69+
pub fn bytes(&self) -> usize {
70+
usize::from(self.kilo_bytes()) * 1024
71+
}
72+
}
73+
74+
/// ADC VREF calibration value is stored in at the factory
75+
#[derive(Debug)]
76+
#[repr(C)]
77+
pub struct VrefCal(u16);
78+
define_ptr_type!(VrefCal, 0x1FFF_7A2A);
79+
80+
impl VrefCal {
81+
/// Read calibration value
82+
pub fn read(&self) -> u16 {
83+
self.0
84+
}
85+
}
86+
87+
/// A temperature reading taken at 30°C stored at the factory
88+
#[derive(Debug)]
89+
#[repr(C)]
90+
pub struct VtempCal30(u16);
91+
define_ptr_type!(VtempCal30, 0x1FFF_7A2C);
92+
93+
impl VtempCal30 {
94+
/// Read calibration value
95+
pub fn read(&self) -> u16 {
96+
self.0
97+
}
98+
}
99+
100+
/// A temperature reading taken at 110°C stored at the factory
101+
#[derive(Debug)]
102+
#[repr(C)]
103+
pub struct VtempCal110(u16);
104+
define_ptr_type!(VtempCal110, 0x1FFF_7A2E);
105+
106+
impl VtempCal110 {
107+
/// Read calibration value
108+
pub fn read(&self) -> u16 {
109+
self.0
110+
}
111+
}

0 commit comments

Comments
 (0)