Check group configuration validity
This commit is contained in:
parent
8e92e8718d
commit
a91f686544
1 changed files with 233 additions and 17 deletions
|
@ -215,10 +215,15 @@ impl Default for Config {
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub struct TscPin<'d, T, C> {
|
pub struct TscPin<'d, T, C> {
|
||||||
_pin: PeripheralRef<'d, AnyPin>,
|
_pin: PeripheralRef<'d, AnyPin>,
|
||||||
_role: PinType,
|
role: PinType,
|
||||||
phantom: PhantomData<(T, C)>,
|
phantom: PhantomData<(T, C)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum GroupError {
|
||||||
|
NoSample,
|
||||||
|
ChannelShield,
|
||||||
|
}
|
||||||
|
|
||||||
/// Pin group definition
|
/// Pin group definition
|
||||||
/// Pins are organized into groups of four IOs, all groups with a
|
/// Pins are organized into groups of four IOs, all groups with a
|
||||||
/// sampling channel must also have a sampling capacitor channel.
|
/// sampling channel must also have a sampling capacitor channel.
|
||||||
|
@ -241,6 +246,119 @@ impl<'d, T: Instance, C> PinGroup<'d, T, C> {
|
||||||
d4: None,
|
d4: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn contains_shield(&self) -> bool {
|
||||||
|
let mut shield_count = 0;
|
||||||
|
|
||||||
|
if let Some(pin) = &self.d1 {
|
||||||
|
if let PinType::Shield = pin.role {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(pin) = &self.d2 {
|
||||||
|
if let PinType::Shield = pin.role {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(pin) = &self.d3 {
|
||||||
|
if let PinType::Shield = pin.role {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(pin) = &self.d4 {
|
||||||
|
if let PinType::Shield = pin.role {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shield_count == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_group(&self) -> Result<(), GroupError> {
|
||||||
|
let mut channel_count = 0;
|
||||||
|
let mut shield_count = 0;
|
||||||
|
let mut sample_count = 0;
|
||||||
|
if let Some(pin) = &self.d1 {
|
||||||
|
match pin.role {
|
||||||
|
PinType::Channel => {
|
||||||
|
channel_count += 1;
|
||||||
|
}
|
||||||
|
PinType::Shield => {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
PinType::Sample => {
|
||||||
|
sample_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(pin) = &self.d2 {
|
||||||
|
match pin.role {
|
||||||
|
PinType::Channel => {
|
||||||
|
channel_count += 1;
|
||||||
|
}
|
||||||
|
PinType::Shield => {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
PinType::Sample => {
|
||||||
|
sample_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(pin) = &self.d3 {
|
||||||
|
match pin.role {
|
||||||
|
PinType::Channel => {
|
||||||
|
channel_count += 1;
|
||||||
|
}
|
||||||
|
PinType::Shield => {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
PinType::Sample => {
|
||||||
|
sample_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(pin) = &self.d4 {
|
||||||
|
match pin.role {
|
||||||
|
PinType::Channel => {
|
||||||
|
channel_count += 1;
|
||||||
|
}
|
||||||
|
PinType::Shield => {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
PinType::Sample => {
|
||||||
|
sample_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Every group requires one sampling capacitor
|
||||||
|
if sample_count != 1 {
|
||||||
|
return Err(GroupError::NoSample);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each group must have at least one shield or channel IO
|
||||||
|
if shield_count == 0 && channel_count == 0 {
|
||||||
|
return Err(GroupError::ChannelShield);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any group can either contain channel ios or a shield IO
|
||||||
|
if shield_count != 0 && channel_count != 0 {
|
||||||
|
return Err(GroupError::ChannelShield);
|
||||||
|
}
|
||||||
|
|
||||||
|
// No more than one shield IO is allow per group and amongst all groups
|
||||||
|
if shield_count > 1 {
|
||||||
|
return Err(GroupError::ChannelShield);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! group_impl {
|
macro_rules! group_impl {
|
||||||
|
@ -261,7 +379,7 @@ macro_rules! group_impl {
|
||||||
);
|
);
|
||||||
self.d1 = Some(TscPin {
|
self.d1 = Some(TscPin {
|
||||||
_pin: pin.map_into(),
|
_pin: pin.map_into(),
|
||||||
_role: role,
|
role: role,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -282,7 +400,7 @@ macro_rules! group_impl {
|
||||||
);
|
);
|
||||||
self.d2 = Some(TscPin {
|
self.d2 = Some(TscPin {
|
||||||
_pin: pin.map_into(),
|
_pin: pin.map_into(),
|
||||||
_role: role,
|
role: role,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -303,7 +421,7 @@ macro_rules! group_impl {
|
||||||
);
|
);
|
||||||
self.d3 = Some(TscPin {
|
self.d3 = Some(TscPin {
|
||||||
_pin: pin.map_into(),
|
_pin: pin.map_into(),
|
||||||
_role: role,
|
role: role,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -324,7 +442,7 @@ macro_rules! group_impl {
|
||||||
);
|
);
|
||||||
self.d4 = Some(TscPin {
|
self.d4 = Some(TscPin {
|
||||||
_pin: pin.map_into(),
|
_pin: pin.map_into(),
|
||||||
_role: role,
|
role: role,
|
||||||
phantom: PhantomData,
|
phantom: PhantomData,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -391,20 +509,118 @@ impl<'d, T: Instance> Tsc<'d, T> {
|
||||||
config: Config,
|
config: Config,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// Need to check valid pin configuration input
|
// Need to check valid pin configuration input
|
||||||
Self::new_inner(
|
let g1 = g1.filter(|b| b.check_group().is_ok());
|
||||||
peri,
|
let g2 = g2.filter(|b| b.check_group().is_ok());
|
||||||
g1,
|
let g3 = g3.filter(|b| b.check_group().is_ok());
|
||||||
g2,
|
let g4 = g4.filter(|b| b.check_group().is_ok());
|
||||||
g3,
|
let g5 = g5.filter(|b| b.check_group().is_ok());
|
||||||
g4,
|
let g6 = g6.filter(|b| b.check_group().is_ok());
|
||||||
g5,
|
let g7 = g7.filter(|b| b.check_group().is_ok());
|
||||||
g6,
|
let g8 = g8.filter(|b| b.check_group().is_ok());
|
||||||
|
|
||||||
|
match Self::check_shields(
|
||||||
|
&g1,
|
||||||
|
&g2,
|
||||||
|
&g3,
|
||||||
|
&g4,
|
||||||
|
&g5,
|
||||||
|
&g6,
|
||||||
#[cfg(any(tsc_v2, tsc_v3))]
|
#[cfg(any(tsc_v2, tsc_v3))]
|
||||||
g7,
|
&g7,
|
||||||
#[cfg(tsc_v3)]
|
#[cfg(tsc_v3)]
|
||||||
g8,
|
&g8,
|
||||||
config,
|
) {
|
||||||
)
|
Ok(()) => Self::new_inner(
|
||||||
|
peri,
|
||||||
|
g1,
|
||||||
|
g2,
|
||||||
|
g3,
|
||||||
|
g4,
|
||||||
|
g5,
|
||||||
|
g6,
|
||||||
|
#[cfg(any(tsc_v2, tsc_v3))]
|
||||||
|
g7,
|
||||||
|
#[cfg(tsc_v3)]
|
||||||
|
g8,
|
||||||
|
config,
|
||||||
|
),
|
||||||
|
Err(_) => Self::new_inner(
|
||||||
|
peri,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
#[cfg(any(tsc_v2, tsc_v3))]
|
||||||
|
None,
|
||||||
|
#[cfg(tsc_v3)]
|
||||||
|
None,
|
||||||
|
config,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_shields(
|
||||||
|
g1: &Option<PinGroup<'d, T, G1>>,
|
||||||
|
g2: &Option<PinGroup<'d, T, G2>>,
|
||||||
|
g3: &Option<PinGroup<'d, T, G3>>,
|
||||||
|
g4: &Option<PinGroup<'d, T, G4>>,
|
||||||
|
g5: &Option<PinGroup<'d, T, G5>>,
|
||||||
|
g6: &Option<PinGroup<'d, T, G6>>,
|
||||||
|
#[cfg(any(tsc_v2, tsc_v3))] g7: &Option<PinGroup<'d, T, G7>>,
|
||||||
|
#[cfg(tsc_v3)] g8: &Option<PinGroup<'d, T, G8>>,
|
||||||
|
) -> Result<(), GroupError> {
|
||||||
|
let mut shield_count = 0;
|
||||||
|
|
||||||
|
if let Some(pin_group) = g1 {
|
||||||
|
if pin_group.contains_shield() {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Some(pin_group) = g2 {
|
||||||
|
if pin_group.contains_shield() {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Some(pin_group) = g3 {
|
||||||
|
if pin_group.contains_shield() {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Some(pin_group) = g4 {
|
||||||
|
if pin_group.contains_shield() {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Some(pin_group) = g5 {
|
||||||
|
if pin_group.contains_shield() {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Some(pin_group) = g6 {
|
||||||
|
if pin_group.contains_shield() {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#[cfg(any(tsc_v2, tsc_v3))]
|
||||||
|
if let Some(pin_group) = g7 {
|
||||||
|
if pin_group.contains_shield() {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#[cfg(tsc_v3)]
|
||||||
|
if let Some(pin_group) = g8 {
|
||||||
|
if pin_group.contains_shield() {
|
||||||
|
shield_count += 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if shield_count > 1 {
|
||||||
|
return Err(GroupError::ChannelShield);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_groups(io_mask: u32) -> u32 {
|
fn extract_groups(io_mask: u32) -> u32 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue