gaffe_xilinx/xc7/
idcode.rs

1use ::failure::Error;
2use ::packed_struct::prelude::*;
3use ::serde::Deserialize;
4use ::serde::Deserializer;
5use ::serde::Serialize;
6use ::serde::Serializer;
7use ::serde::de::Error as SerdeError;
8use ::serde::de::Unexpected;
9use ::std::fmt;
10use ::std::str::FromStr;
11
12#[derive(Clone, Copy, Debug, Default, PartialEq, PackedStruct)]
13#[packed_struct(size_bytes="4", bit_numbering="lsb0", endian="msb")]
14pub struct IdCode {
15    #[packed_field(bits="0")]
16    pub _reserved: ReservedOnes<packed_bits::Bits1>,
17
18    #[packed_field(bits="11:1")]
19    pub manufacturer_id: Integer<u16, packed_bits::Bits11>,
20
21    #[packed_field(bits="16:12")]
22    pub device: Integer<u8, packed_bits::Bits5>,
23
24    #[packed_field(bits="20:17")]
25    pub subfamily: Integer<u8, packed_bits::Bits4>,
26
27    #[packed_field(bits="27:21")]
28    pub family: Integer<u8, packed_bits::Bits7>,
29
30    #[packed_field(bits="31:28")]
31    pub version: Integer<u8, packed_bits::Bits4>,
32}
33
34impl fmt::LowerHex for IdCode {
35    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36        write!(f, "{}", ::hex::encode(self.pack()))
37    }
38}
39
40impl FromStr for IdCode {
41    type Err = Error;
42
43    fn from_str(src: &str) -> Result<Self, Self::Err> {
44        let bytes = ::hex::decode(src)?;
45        Ok(IdCode::unpack_from_slice(bytes.as_slice())?)
46    }
47}
48
49impl Serialize for IdCode {
50    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
51        where S: Serializer
52    {
53        serializer.serialize_str(&format!("{:x}", self))
54    }
55}
56
57impl<'de> Deserialize<'de> for IdCode {
58    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
59    where
60        D: Deserializer<'de>
61    {
62        let value_string = String::deserialize(deserializer)?;
63        match Self::from_str(value_string.as_str()) {
64            Ok(value) => Ok(value),
65            Err(_) => Err(D::Error::invalid_value(Unexpected::Str(value_string.as_str()), &"Device IDCODE in hexadecimal"))
66        }
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn idcode_from_str() {
76        let idcode = IdCode::from_str("0362c093").expect("IdCode failed to parse");
77        assert_eq!(*idcode.manufacturer_id, 0x49);
78        assert_eq!(*idcode.family, 0x1B);
79        assert_eq!(*idcode.subfamily, 0x1);
80        assert_eq!(*idcode.device, 0x0C);
81        assert_eq!(*idcode.version, 0);
82    }
83
84    #[test]
85    fn idcode_serialization() {
86        use ::serde_test::{Token, assert_tokens};
87
88        let idcode = IdCode {
89            manufacturer_id: 0x49.into(),
90            family: 0x1B.into(),
91            subfamily: 0x1.into(),
92            device: 0x0C.into(),
93            version: 0.into(),
94            .. IdCode::default()
95        };
96
97        assert_tokens(&idcode, &[Token::String("0362c093")])
98    }
99}