stm32f1_hal/common/i2c/
utils.rs

1use super::*;
2use crate::common::atomic_cell::AtomicCellMember;
3
4#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5pub enum Work {
6    Start = 0,
7    Addr,
8    Data,
9    Success,
10    Stop,
11}
12
13impl AtomicCellMember for Work {
14    #[inline]
15    fn to_num(self) -> usize {
16        self as usize
17    }
18
19    #[inline]
20    unsafe fn from_num(val: usize) -> Self {
21        unsafe { core::mem::transmute(val as u8) }
22    }
23}
24
25#[derive(Clone, Copy, Debug, PartialEq, Eq)]
26pub enum Command {
27    SlaveAddr(u8),
28    SlaveAddr10(u16),
29    Write(*const u8, usize),
30    WriteEnd,
31    /// With length
32    Read(usize),
33    ReadBuf(*mut u8, usize),
34}
35
36impl AtomicCellMember for Option<Error> {
37    #[inline]
38    fn to_num(self) -> usize {
39        match self {
40            None => 0,
41            Some(err) => match err {
42                Error::ArbitrationLoss => 1,
43                Error::Bus => 2,
44                Error::Crc => 3,
45                Error::NoAcknowledge(nack) => match nack {
46                    NoAcknowledgeSource::Unknown => 4,
47                    NoAcknowledgeSource::Address => 4 | (1 << 8),
48                    NoAcknowledgeSource::Data => 4 | (2 << 8),
49                },
50                Error::Overrun => 5,
51                Error::Pec => 6,
52                Error::SMBusAlert => 7,
53                Error::Timeout => 8,
54                Error::SMBusTimeout => 9,
55                Error::Busy => 10,
56                Error::Buffer => 11,
57                Error::Other => 12,
58            },
59        }
60    }
61
62    #[inline]
63    unsafe fn from_num(val: usize) -> Self {
64        let nack = (val >> 8) as u8;
65        let err = val as u8;
66
67        if err == 0 {
68            None
69        } else {
70            Some(match err {
71                1 => Error::ArbitrationLoss,
72                2 => Error::Bus,
73                3 => Error::Crc,
74                4 => match nack {
75                    0 => Error::NoAcknowledge(NoAcknowledgeSource::Unknown),
76                    1 => Error::NoAcknowledge(NoAcknowledgeSource::Address),
77                    _ => Error::NoAcknowledge(NoAcknowledgeSource::Data),
78                },
79                5 => Error::Overrun,
80                6 => Error::Pec,
81                7 => Error::SMBusAlert,
82                8 => Error::Timeout,
83                9 => Error::SMBusTimeout,
84                10 => Error::Busy,
85                11 => Error::Buffer,
86                _ => Error::Other,
87            })
88        }
89    }
90}
91
92#[cfg(test)]
93mod tests {
94    use super::*;
95
96    fn compare_error(err: Option<Error>) {
97        let i: usize = err.to_num();
98        assert_eq!(err, unsafe { Option::<Error>::from_num(i) });
99    }
100
101    #[test]
102    fn teat_error() {
103        compare_error(None);
104        compare_error(Some(Error::NoAcknowledge(NoAcknowledgeSource::Unknown)));
105        compare_error(Some(Error::NoAcknowledge(NoAcknowledgeSource::Address)));
106        compare_error(Some(Error::NoAcknowledge(NoAcknowledgeSource::Data)));
107        compare_error(Some(Error::SMBusAlert));
108        compare_error(Some(Error::Busy));
109        compare_error(Some(Error::Overrun));
110        compare_error(Some(Error::Timeout));
111        compare_error(Some(Error::Bus));
112        compare_error(Some(Error::Crc));
113        compare_error(Some(Error::ArbitrationLoss));
114        compare_error(Some(Error::Pec));
115        compare_error(Some(Error::SMBusTimeout));
116        compare_error(Some(Error::Buffer));
117        compare_error(Some(Error::Other));
118    }
119}