diff options
| author | Karun <[email protected]> | 2024-05-03 17:29:21 -0400 |
|---|---|---|
| committer | Karun <[email protected]> | 2024-05-03 19:45:26 -0400 |
| commit | a91f68654473e8ca6030b97ccda98e7fd868716e (patch) | |
| tree | b40da481e8510a10d12c959909f673de5b40afdf /embassy-stm32/src/tsc | |
| parent | 8e92e8718d513298fa87a51e4039ae11a4f6d502 (diff) | |
Check group configuration validity
Diffstat (limited to 'embassy-stm32/src/tsc')
| -rw-r--r-- | embassy-stm32/src/tsc/mod.rs | 250 |
1 files changed, 233 insertions, 17 deletions
diff --git a/embassy-stm32/src/tsc/mod.rs b/embassy-stm32/src/tsc/mod.rs index 6b9d8fcf5..17a455558 100644 --- a/embassy-stm32/src/tsc/mod.rs +++ b/embassy-stm32/src/tsc/mod.rs | |||
| @@ -215,10 +215,15 @@ impl Default for Config { | |||
| 215 | #[allow(missing_docs)] | 215 | #[allow(missing_docs)] |
| 216 | pub struct TscPin<'d, T, C> { | 216 | pub struct TscPin<'d, T, C> { |
| 217 | _pin: PeripheralRef<'d, AnyPin>, | 217 | _pin: PeripheralRef<'d, AnyPin>, |
| 218 | _role: PinType, | 218 | role: PinType, |
| 219 | phantom: PhantomData<(T, C)>, | 219 | phantom: PhantomData<(T, C)>, |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | enum GroupError { | ||
| 223 | NoSample, | ||
| 224 | ChannelShield, | ||
| 225 | } | ||
| 226 | |||
| 222 | /// Pin group definition | 227 | /// Pin group definition |
| 223 | /// Pins are organized into groups of four IOs, all groups with a | 228 | /// Pins are organized into groups of four IOs, all groups with a |
| 224 | /// sampling channel must also have a sampling capacitor channel. | 229 | /// sampling channel must also have a sampling capacitor channel. |
| @@ -241,6 +246,119 @@ impl<'d, T: Instance, C> PinGroup<'d, T, C> { | |||
| 241 | d4: None, | 246 | d4: None, |
| 242 | } | 247 | } |
| 243 | } | 248 | } |
| 249 | |||
| 250 | fn contains_shield(&self) -> bool { | ||
| 251 | let mut shield_count = 0; | ||
| 252 | |||
| 253 | if let Some(pin) = &self.d1 { | ||
| 254 | if let PinType::Shield = pin.role { | ||
| 255 | shield_count += 1; | ||
| 256 | } | ||
| 257 | } | ||
| 258 | |||
| 259 | if let Some(pin) = &self.d2 { | ||
| 260 | if let PinType::Shield = pin.role { | ||
| 261 | shield_count += 1; | ||
| 262 | } | ||
| 263 | } | ||
| 264 | |||
| 265 | if let Some(pin) = &self.d3 { | ||
| 266 | if let PinType::Shield = pin.role { | ||
| 267 | shield_count += 1; | ||
| 268 | } | ||
| 269 | } | ||
| 270 | |||
| 271 | if let Some(pin) = &self.d4 { | ||
| 272 | if let PinType::Shield = pin.role { | ||
| 273 | shield_count += 1; | ||
| 274 | } | ||
| 275 | } | ||
| 276 | |||
| 277 | shield_count == 1 | ||
| 278 | } | ||
| 279 | |||
| 280 | fn check_group(&self) -> Result<(), GroupError> { | ||
| 281 | let mut channel_count = 0; | ||
| 282 | let mut shield_count = 0; | ||
| 283 | let mut sample_count = 0; | ||
| 284 | if let Some(pin) = &self.d1 { | ||
| 285 | match pin.role { | ||
| 286 | PinType::Channel => { | ||
| 287 | channel_count += 1; | ||
| 288 | } | ||
| 289 | PinType::Shield => { | ||
| 290 | shield_count += 1; | ||
| 291 | } | ||
| 292 | PinType::Sample => { | ||
| 293 | sample_count += 1; | ||
| 294 | } | ||
| 295 | } | ||
| 296 | } | ||
| 297 | |||
| 298 | if let Some(pin) = &self.d2 { | ||
| 299 | match pin.role { | ||
| 300 | PinType::Channel => { | ||
| 301 | channel_count += 1; | ||
| 302 | } | ||
| 303 | PinType::Shield => { | ||
| 304 | shield_count += 1; | ||
| 305 | } | ||
| 306 | PinType::Sample => { | ||
| 307 | sample_count += 1; | ||
| 308 | } | ||
| 309 | } | ||
| 310 | } | ||
| 311 | |||
| 312 | if let Some(pin) = &self.d3 { | ||
| 313 | match pin.role { | ||
| 314 | PinType::Channel => { | ||
| 315 | channel_count += 1; | ||
| 316 | } | ||
| 317 | PinType::Shield => { | ||
| 318 | shield_count += 1; | ||
| 319 | } | ||
| 320 | PinType::Sample => { | ||
| 321 | sample_count += 1; | ||
| 322 | } | ||
| 323 | } | ||
| 324 | } | ||
| 325 | |||
| 326 | if let Some(pin) = &self.d4 { | ||
| 327 | match pin.role { | ||
| 328 | PinType::Channel => { | ||
| 329 | channel_count += 1; | ||
| 330 | } | ||
| 331 | PinType::Shield => { | ||
| 332 | shield_count += 1; | ||
| 333 | } | ||
| 334 | PinType::Sample => { | ||
| 335 | sample_count += 1; | ||
| 336 | } | ||
| 337 | } | ||
| 338 | } | ||
| 339 | |||
| 340 | // Every group requires one sampling capacitor | ||
| 341 | if sample_count != 1 { | ||
| 342 | return Err(GroupError::NoSample); | ||
| 343 | } | ||
| 344 | |||
| 345 | // Each group must have at least one shield or channel IO | ||
| 346 | if shield_count == 0 && channel_count == 0 { | ||
| 347 | return Err(GroupError::ChannelShield); | ||
| 348 | } | ||
| 349 | |||
| 350 | // Any group can either contain channel ios or a shield IO | ||
| 351 | if shield_count != 0 && channel_count != 0 { | ||
| 352 | return Err(GroupError::ChannelShield); | ||
| 353 | } | ||
| 354 | |||
| 355 | // No more than one shield IO is allow per group and amongst all groups | ||
| 356 | if shield_count > 1 { | ||
| 357 | return Err(GroupError::ChannelShield); | ||
| 358 | } | ||
| 359 | |||
| 360 | Ok(()) | ||
| 361 | } | ||
| 244 | } | 362 | } |
| 245 | 363 | ||
| 246 | macro_rules! group_impl { | 364 | macro_rules! group_impl { |
| @@ -261,7 +379,7 @@ macro_rules! group_impl { | |||
| 261 | ); | 379 | ); |
| 262 | self.d1 = Some(TscPin { | 380 | self.d1 = Some(TscPin { |
| 263 | _pin: pin.map_into(), | 381 | _pin: pin.map_into(), |
| 264 | _role: role, | 382 | role: role, |
| 265 | phantom: PhantomData, | 383 | phantom: PhantomData, |
| 266 | }) | 384 | }) |
| 267 | }) | 385 | }) |
| @@ -282,7 +400,7 @@ macro_rules! group_impl { | |||
| 282 | ); | 400 | ); |
| 283 | self.d2 = Some(TscPin { | 401 | self.d2 = Some(TscPin { |
| 284 | _pin: pin.map_into(), | 402 | _pin: pin.map_into(), |
| 285 | _role: role, | 403 | role: role, |
| 286 | phantom: PhantomData, | 404 | phantom: PhantomData, |
| 287 | }) | 405 | }) |
| 288 | }) | 406 | }) |
| @@ -303,7 +421,7 @@ macro_rules! group_impl { | |||
| 303 | ); | 421 | ); |
| 304 | self.d3 = Some(TscPin { | 422 | self.d3 = Some(TscPin { |
| 305 | _pin: pin.map_into(), | 423 | _pin: pin.map_into(), |
| 306 | _role: role, | 424 | role: role, |
| 307 | phantom: PhantomData, | 425 | phantom: PhantomData, |
| 308 | }) | 426 | }) |
| 309 | }) | 427 | }) |
| @@ -324,7 +442,7 @@ macro_rules! group_impl { | |||
| 324 | ); | 442 | ); |
| 325 | self.d4 = Some(TscPin { | 443 | self.d4 = Some(TscPin { |
| 326 | _pin: pin.map_into(), | 444 | _pin: pin.map_into(), |
| 327 | _role: role, | 445 | role: role, |
| 328 | phantom: PhantomData, | 446 | phantom: PhantomData, |
| 329 | }) | 447 | }) |
| 330 | }) | 448 | }) |
| @@ -391,20 +509,118 @@ impl<'d, T: Instance> Tsc<'d, T> { | |||
| 391 | config: Config, | 509 | config: Config, |
| 392 | ) -> Self { | 510 | ) -> Self { |
| 393 | // Need to check valid pin configuration input | 511 | // Need to check valid pin configuration input |
| 394 | Self::new_inner( | 512 | let g1 = g1.filter(|b| b.check_group().is_ok()); |
| 395 | peri, | 513 | let g2 = g2.filter(|b| b.check_group().is_ok()); |
| 396 | g1, | 514 | let g3 = g3.filter(|b| b.check_group().is_ok()); |
| 397 | g2, | 515 | let g4 = g4.filter(|b| b.check_group().is_ok()); |
| 398 | g3, | 516 | let g5 = g5.filter(|b| b.check_group().is_ok()); |
| 399 | g4, | 517 | let g6 = g6.filter(|b| b.check_group().is_ok()); |
| 400 | g5, | 518 | let g7 = g7.filter(|b| b.check_group().is_ok()); |
| 401 | g6, | 519 | let g8 = g8.filter(|b| b.check_group().is_ok()); |
| 520 | |||
| 521 | match Self::check_shields( | ||
| 522 | &g1, | ||
| 523 | &g2, | ||
| 524 | &g3, | ||
| 525 | &g4, | ||
| 526 | &g5, | ||
| 527 | &g6, | ||
| 402 | #[cfg(any(tsc_v2, tsc_v3))] | 528 | #[cfg(any(tsc_v2, tsc_v3))] |
| 403 | g7, | 529 | &g7, |
| 404 | #[cfg(tsc_v3)] | 530 | #[cfg(tsc_v3)] |
| 405 | g8, | 531 | &g8, |
| 406 | config, | 532 | ) { |
| 407 | ) | 533 | Ok(()) => Self::new_inner( |
| 534 | peri, | ||
| 535 | g1, | ||
| 536 | g2, | ||
| 537 | g3, | ||
| 538 | g4, | ||
| 539 | g5, | ||
| 540 | g6, | ||
| 541 | #[cfg(any(tsc_v2, tsc_v3))] | ||
| 542 | g7, | ||
| 543 | #[cfg(tsc_v3)] | ||
| 544 | g8, | ||
| 545 | config, | ||
| 546 | ), | ||
| 547 | Err(_) => Self::new_inner( | ||
| 548 | peri, | ||
| 549 | None, | ||
| 550 | None, | ||
| 551 | None, | ||
| 552 | None, | ||
| 553 | None, | ||
| 554 | None, | ||
| 555 | #[cfg(any(tsc_v2, tsc_v3))] | ||
| 556 | None, | ||
| 557 | #[cfg(tsc_v3)] | ||
| 558 | None, | ||
| 559 | config, | ||
| 560 | ), | ||
| 561 | } | ||
| 562 | } | ||
| 563 | |||
| 564 | fn check_shields( | ||
| 565 | g1: &Option<PinGroup<'d, T, G1>>, | ||
| 566 | g2: &Option<PinGroup<'d, T, G2>>, | ||
| 567 | g3: &Option<PinGroup<'d, T, G3>>, | ||
| 568 | g4: &Option<PinGroup<'d, T, G4>>, | ||
| 569 | g5: &Option<PinGroup<'d, T, G5>>, | ||
| 570 | g6: &Option<PinGroup<'d, T, G6>>, | ||
| 571 | #[cfg(any(tsc_v2, tsc_v3))] g7: &Option<PinGroup<'d, T, G7>>, | ||
| 572 | #[cfg(tsc_v3)] g8: &Option<PinGroup<'d, T, G8>>, | ||
| 573 | ) -> Result<(), GroupError> { | ||
| 574 | let mut shield_count = 0; | ||
| 575 | |||
| 576 | if let Some(pin_group) = g1 { | ||
| 577 | if pin_group.contains_shield() { | ||
| 578 | shield_count += 1; | ||
| 579 | } | ||
| 580 | }; | ||
| 581 | if let Some(pin_group) = g2 { | ||
| 582 | if pin_group.contains_shield() { | ||
| 583 | shield_count += 1; | ||
| 584 | } | ||
| 585 | }; | ||
| 586 | if let Some(pin_group) = g3 { | ||
| 587 | if pin_group.contains_shield() { | ||
| 588 | shield_count += 1; | ||
| 589 | } | ||
| 590 | }; | ||
| 591 | if let Some(pin_group) = g4 { | ||
| 592 | if pin_group.contains_shield() { | ||
| 593 | shield_count += 1; | ||
| 594 | } | ||
| 595 | }; | ||
| 596 | if let Some(pin_group) = g5 { | ||
| 597 | if pin_group.contains_shield() { | ||
| 598 | shield_count += 1; | ||
| 599 | } | ||
| 600 | }; | ||
| 601 | if let Some(pin_group) = g6 { | ||
| 602 | if pin_group.contains_shield() { | ||
| 603 | shield_count += 1; | ||
| 604 | } | ||
| 605 | }; | ||
| 606 | #[cfg(any(tsc_v2, tsc_v3))] | ||
| 607 | if let Some(pin_group) = g7 { | ||
| 608 | if pin_group.contains_shield() { | ||
| 609 | shield_count += 1; | ||
| 610 | } | ||
| 611 | }; | ||
| 612 | #[cfg(tsc_v3)] | ||
| 613 | if let Some(pin_group) = g8 { | ||
| 614 | if pin_group.contains_shield() { | ||
| 615 | shield_count += 1; | ||
| 616 | } | ||
| 617 | }; | ||
| 618 | |||
| 619 | if shield_count > 1 { | ||
| 620 | return Err(GroupError::ChannelShield); | ||
| 621 | } | ||
| 622 | |||
| 623 | Ok(()) | ||
| 408 | } | 624 | } |
| 409 | 625 | ||
| 410 | fn extract_groups(io_mask: u32) -> u32 { | 626 | fn extract_groups(io_mask: u32) -> u32 { |
