#![allow(non_upper_case_globals)]
use std::fmt;
enum_and_set!(
#[non_exhaustive]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Interface {
Jtag = 0,
Swd = 1,
Bdm3 = 2,
Fine = 3,
Pic32Icsp = 4,
Spi = 5,
C2 = 6,
CJtag = 7,
Mc2WireJtag = 10,
}
flags InterfaceFlags: u32;
);
impl Interface {
pub(crate) fn as_u8(self) -> u8 {
self as u8
}
}
impl fmt::Display for Interface {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Interface::Jtag => "JTAG",
Interface::Swd => "SWD",
Interface::Bdm3 => "BDM3",
Interface::Fine => "FINE",
Interface::Pic32Icsp => "PIC32 ICSP",
Interface::Spi => "SPI",
Interface::C2 => "C2",
Interface::CJtag => "cJTAG",
Interface::Mc2WireJtag => "Microchip 2-wire JTAG",
})
}
}
impl InterfaceFlags {
fn from_interface(interface: Interface) -> Self {
InterfaceFlags::from_bits(1 << interface as u32).unwrap()
}
}
#[derive(Copy, Clone, Eq, PartialEq)]
pub struct Interfaces(InterfaceFlags);
impl Interfaces {
pub(crate) fn from_bits_warn(raw: u32) -> Self {
let flags = InterfaceFlags::from_bits_truncate(raw);
if flags.bits() != raw {
log::debug!(
"unknown bits in interface mask: 0x{:08X} truncated to 0x{:08X} ({:?})",
raw,
flags.bits(),
flags,
);
}
Self(flags)
}
pub(crate) fn single(interface: Interface) -> Self {
Self(InterfaceFlags::from_interface(interface))
}
pub fn contains(&self, interface: Interface) -> bool {
self.0.contains(InterfaceFlags::from_interface(interface))
}
}
impl fmt::Debug for Interfaces {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
impl IntoIterator for Interfaces {
type Item = Interface;
type IntoIter = InterfaceIter;
fn into_iter(self) -> Self::IntoIter {
InterfaceIter {
interfaces: self,
next: 0,
}
}
}
#[derive(Debug)]
pub struct InterfaceIter {
interfaces: Interfaces,
next: usize,
}
impl Iterator for InterfaceIter {
type Item = Interface;
fn next(&mut self) -> Option<Self::Item> {
loop {
let next = Interface::ALL.get(self.next)?;
self.next += 1;
if self.interfaces.contains(*next) {
return Some(*next);
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn iter() {
assert_eq!(
Interfaces(InterfaceFlags::empty())
.into_iter()
.collect::<Vec<_>>(),
&[]
);
assert_eq!(
Interfaces(InterfaceFlags::Jtag)
.into_iter()
.collect::<Vec<_>>(),
&[Interface::Jtag]
);
assert_eq!(
Interfaces(InterfaceFlags::Swd)
.into_iter()
.collect::<Vec<_>>(),
&[Interface::Swd]
);
assert_eq!(
Interfaces(InterfaceFlags::Jtag | InterfaceFlags::Swd)
.into_iter()
.collect::<Vec<_>>(),
&[Interface::Jtag, Interface::Swd]
);
}
}