1#![allow(non_upper_case_globals)]
2
3use std::fmt;
4
5enum_and_set!(
6 #[non_exhaustive]
10 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
11 pub enum Interface {
12 Jtag = 0,
15 Swd = 1,
18 Bdm3 = 2,
20 Fine = 3,
31 Pic32Icsp = 4,
33 Spi = 5,
35 C2 = 6,
37 CJtag = 7,
41 Mc2WireJtag = 10,
43 }
48
49 flags InterfaceFlags: u32;
50);
51
52impl Interface {
53 pub(crate) fn as_u8(self) -> u8 {
54 self as u8
55 }
56}
57
58impl fmt::Display for Interface {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 f.write_str(match self {
61 Interface::Jtag => "JTAG",
62 Interface::Swd => "SWD",
63 Interface::Bdm3 => "BDM3",
64 Interface::Fine => "FINE",
65 Interface::Pic32Icsp => "PIC32 ICSP",
66 Interface::Spi => "SPI",
67 Interface::C2 => "C2",
68 Interface::CJtag => "cJTAG",
69 Interface::Mc2WireJtag => "Microchip 2-wire JTAG",
70 })
71 }
72}
73
74impl InterfaceFlags {
75 fn from_interface(interface: Interface) -> Self {
76 InterfaceFlags::from_bits(1 << interface as u32).unwrap()
77 }
78}
79
80#[derive(Copy, Clone, Eq, PartialEq)]
85pub struct Interfaces(InterfaceFlags);
86
87impl Interfaces {
88 pub(crate) fn from_bits_warn(raw: u32) -> Self {
89 let flags = InterfaceFlags::from_bits_truncate(raw);
90 if flags.bits() != raw {
91 log::debug!(
92 "unknown bits in interface mask: 0x{:08X} truncated to 0x{:08X} ({:?})",
93 raw,
94 flags.bits(),
95 flags,
96 );
97 }
98 Self(flags)
99 }
100
101 pub(crate) fn single(interface: Interface) -> Self {
102 Self(InterfaceFlags::from_interface(interface))
103 }
104
105 pub fn contains(&self, interface: Interface) -> bool {
107 self.0.contains(InterfaceFlags::from_interface(interface))
108 }
109}
110
111impl fmt::Debug for Interfaces {
112 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 self.0.fmt(f)
114 }
115}
116
117impl IntoIterator for Interfaces {
118 type Item = Interface;
119 type IntoIter = InterfaceIter;
120
121 fn into_iter(self) -> Self::IntoIter {
122 InterfaceIter {
123 interfaces: self,
124 next: 0,
125 }
126 }
127}
128
129#[derive(Debug)]
131pub struct InterfaceIter {
132 interfaces: Interfaces,
133 next: usize,
134}
135
136impl Iterator for InterfaceIter {
137 type Item = Interface;
138
139 fn next(&mut self) -> Option<Self::Item> {
140 loop {
141 let next = Interface::ALL.get(self.next)?;
142 self.next += 1;
143 if self.interfaces.contains(*next) {
144 return Some(*next);
145 }
146 }
147 }
148}
149
150#[cfg(test)]
151mod tests {
152 use super::*;
153
154 #[test]
155 fn iter() {
156 assert_eq!(
157 Interfaces(InterfaceFlags::empty())
158 .into_iter()
159 .collect::<Vec<_>>(),
160 &[]
161 );
162 assert_eq!(
163 Interfaces(InterfaceFlags::Jtag)
164 .into_iter()
165 .collect::<Vec<_>>(),
166 &[Interface::Jtag]
167 );
168 assert_eq!(
169 Interfaces(InterfaceFlags::Swd)
170 .into_iter()
171 .collect::<Vec<_>>(),
172 &[Interface::Swd]
173 );
174 assert_eq!(
175 Interfaces(InterfaceFlags::Jtag | InterfaceFlags::Swd)
176 .into_iter()
177 .collect::<Vec<_>>(),
178 &[Interface::Jtag, Interface::Swd]
179 );
180 }
181}