stm32f429_hal/
udid.rs

1//! Reading the Unique Device ID register
2
3use stm32f429::DEVICE_ID;
4
5/// Implemented for the `DEVICE_ID` peripheral.
6pub trait DeviceIdExt {
7    /// Read X and Y coordinates on the wafer.
8    ///
9    /// Decodes the ASCII encoded digits
10    fn read_xy(&self) -> Option<(u32, u32)>;
11    /// Read Wafer number
12    ///
13    /// Supposedly ASCII encoded digits, but mine yields ASCII code
14    /// 22. Therefore this is the raw byte for now.
15    fn read_waf_num(&self) -> u8;
16    /// Read Lot number
17    ///
18    /// ASCII encoded digits. Mine has a trailing 'Q' which gets
19    /// ignored by `ReadAscii`.
20    fn read_lot_num(&self) -> Option<u32>;
21}
22
23impl DeviceIdExt for DEVICE_ID {
24    fn read_xy(&self) -> Option<(u32, u32)> {
25        let uid1 = self.uid1.read().uid().bits();
26        let x = ((uid1 >> 16) as u16).read_ascii()?;
27        let y = (uid1 as u16).read_ascii()?;
28        Some((x, y))
29    }
30
31    fn read_waf_num(&self) -> u8 {
32        self.uid2.read().waf_num().bits()
33    }
34
35    fn read_lot_num(&self) -> Option<u32> {
36        let lot_num =
37            (self.uid2.read().lot_num().bits() as u64) |
38            ((self.uid3.read().lot_num().bits() as u64) << 24);
39        lot_num.read_ascii()
40    }
41}
42
43trait ReadAscii {
44    type B: AsRef<[u8]>;
45
46    fn as_bytes(&self) -> Self::B;
47    fn read_ascii(&self) -> Option<u32> {
48        let mut r = 0;
49        for (i, c) in self.as_bytes().as_ref().iter().cloned().enumerate() {
50            if i == 0 && c == 0 {
51                // skip \0
52            } else if c >= '0' as u8 && c <= '9' as u8 {
53                let digit: u8 = (c as u8) - ('0' as u8);
54                r = (r * 10) + digit as u32;
55            } else if i == 0 {
56                return None;
57            }
58        }
59        Some(r)
60    }
61}
62
63impl ReadAscii for u16 {
64    type B = [u8; 2];
65
66    fn as_bytes(&self) -> Self::B {
67        [(*self >> 8) as u8, *self as u8]
68    }
69}
70
71impl ReadAscii for u64 {
72    type B = [u8; 8];
73
74    fn as_bytes(&self) -> Self::B {
75        [(*self >> 56) as u8, (*self >> 48) as u8,
76         (*self >> 40) as u8, (*self >> 32) as u8,
77         (*self >> 24) as u8, (*self >> 16) as u8,
78         (*self >> 8) as u8, *self as u8]
79    }
80}