stm32f1_hal/common/i2c/
utils.rs1use 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 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}