aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-stm32/src/tsc/mod.rs250
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)]
216pub struct TscPin<'d, T, C> { 216pub 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
222enum 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
246macro_rules! group_impl { 364macro_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 {