From 2655426cd80b828593c8cd60930da3ebbd60e85c Mon Sep 17 00:00:00 2001 From: Eekle <96976531+Eekle@users.noreply.github.com> Date: Sun, 23 Jun 2024 16:43:12 +0200 Subject: [PATCH 1/5] Add async wait to TSC --- embassy-stm32/src/tsc/mod.rs | 139 ++++++++++++++++++++++---------- examples/stm32u5/src/bin/tsc.rs | 12 ++- 2 files changed, 107 insertions(+), 44 deletions(-) diff --git a/embassy-stm32/src/tsc/mod.rs b/embassy-stm32/src/tsc/mod.rs index 8ba208ce7..6497ff0ee 100644 --- a/embassy-stm32/src/tsc/mod.rs +++ b/embassy-stm32/src/tsc/mod.rs @@ -71,9 +71,13 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; pub use enums::*; use crate::gpio::{AfType, AnyPin, OutputType, Speed}; -use crate::pac::tsc::Tsc as Regs; +use crate::interrupt; +use crate::interrupt::typelevel::Interrupt; use crate::rcc::{self, RccPeripheral}; use crate::{peripherals, Peripheral}; +use core::future::poll_fn; +use core::task::Poll; +use embassy_sync::waitqueue::AtomicWaker; #[cfg(tsc_v1)] const TSC_NUM_GROUPS: u32 = 6; @@ -90,6 +94,18 @@ pub enum Error { Test, } +/// TSC interrupt handler. +pub struct InterruptHandler { + _phantom: PhantomData, +} + +impl interrupt::typelevel::Handler for InterruptHandler { + unsafe fn on_interrupt() { + T::regs().ier().write(|w| w.set_eoaie(false)); + T::waker().wake(); + } +} + /// Pin type definition to control IO parameters pub enum PinType { /// Sensing channel pin connected to an electrode @@ -510,6 +526,7 @@ impl<'d, T: Instance> Tsc<'d, T> { /// Create new TSC driver pub fn new( peri: impl Peripheral

+ 'd, + _irq: impl interrupt::typelevel::Binding> + 'd, g1: Option>, g2: Option>, g3: Option>, @@ -663,7 +680,7 @@ impl<'d, T: Instance> Tsc<'d, T> { rcc::enable_and_reset::(); - T::REGS.cr().modify(|w| { + T::regs().cr().modify(|w| { w.set_tsce(true); w.set_ctph(config.ct_pulse_high_length.into()); w.set_ctpl(config.ct_pulse_low_length.into()); @@ -691,33 +708,39 @@ impl<'d, T: Instance> Tsc<'d, T> { // Set IO configuration // Disable Schmitt trigger hysteresis on all used TSC IOs - T::REGS + T::regs() .iohcr() .write(|w| w.0 = !(config.channel_ios | config.shield_ios | config.sampling_ios)); // Set channel and shield IOs - T::REGS.ioccr().write(|w| w.0 = config.channel_ios | config.shield_ios); + T::regs() + .ioccr() + .write(|w| w.0 = config.channel_ios | config.shield_ios); // Set sampling IOs - T::REGS.ioscr().write(|w| w.0 = config.sampling_ios); + T::regs().ioscr().write(|w| w.0 = config.sampling_ios); // Set the groups to be acquired - T::REGS + T::regs() .iogcsr() .write(|w| w.0 = Self::extract_groups(config.channel_ios)); // Disable interrupts - T::REGS.ier().modify(|w| { + T::regs().ier().modify(|w| { w.set_eoaie(false); w.set_mceie(false); }); // Clear flags - T::REGS.icr().modify(|w| { + T::regs().icr().modify(|w| { w.set_eoaic(true); w.set_mceic(true); }); + unsafe { + T::Interrupt::enable(); + } + Self { _peri: peri, _g1: g1, @@ -740,24 +763,24 @@ impl<'d, T: Instance> Tsc<'d, T> { self.state = State::Busy; // Disable interrupts - T::REGS.ier().modify(|w| { + T::regs().ier().modify(|w| { w.set_eoaie(false); w.set_mceie(false); }); // Clear flags - T::REGS.icr().modify(|w| { + T::regs().icr().modify(|w| { w.set_eoaic(true); w.set_mceic(true); }); // Set the touch sensing IOs not acquired to the default mode - T::REGS.cr().modify(|w| { + T::regs().cr().modify(|w| { w.set_iodef(self.config.io_default_mode); }); // Start the acquisition - T::REGS.cr().modify(|w| { + T::regs().cr().modify(|w| { w.set_start(true); }); } @@ -767,41 +790,41 @@ impl<'d, T: Instance> Tsc<'d, T> { self.state = State::Busy; // Enable interrupts - T::REGS.ier().modify(|w| { + T::regs().ier().modify(|w| { w.set_eoaie(true); w.set_mceie(self.config.max_count_interrupt); }); // Clear flags - T::REGS.icr().modify(|w| { + T::regs().icr().modify(|w| { w.set_eoaic(true); w.set_mceic(true); }); // Set the touch sensing IOs not acquired to the default mode - T::REGS.cr().modify(|w| { + T::regs().cr().modify(|w| { w.set_iodef(self.config.io_default_mode); }); // Start the acquisition - T::REGS.cr().modify(|w| { + T::regs().cr().modify(|w| { w.set_start(true); }); } /// Stop charge transfer acquisition pub fn stop(&mut self) { - T::REGS.cr().modify(|w| { + T::regs().cr().modify(|w| { w.set_start(false); }); // Set the touch sensing IOs in low power mode - T::REGS.cr().modify(|w| { + T::regs().cr().modify(|w| { w.set_iodef(false); }); // Clear flags - T::REGS.icr().modify(|w| { + T::regs().icr().modify(|w| { w.set_eoaic(true); w.set_mceic(true); }); @@ -811,23 +834,23 @@ impl<'d, T: Instance> Tsc<'d, T> { /// Stop charge transfer acquisition and clear interrupts pub fn stop_it(&mut self) { - T::REGS.cr().modify(|w| { + T::regs().cr().modify(|w| { w.set_start(false); }); // Set the touch sensing IOs in low power mode - T::REGS.cr().modify(|w| { + T::regs().cr().modify(|w| { w.set_iodef(false); }); // Disable interrupts - T::REGS.ier().modify(|w| { + T::regs().ier().modify(|w| { w.set_eoaie(false); w.set_mceie(false); }); // Clear flags - T::REGS.icr().modify(|w| { + T::regs().icr().modify(|w| { w.set_eoaic(true); w.set_mceic(true); }); @@ -840,11 +863,31 @@ impl<'d, T: Instance> Tsc<'d, T> { while self.get_state() == State::Busy {} } + /// Asyncronously wait for the end of an acquisition + pub async fn pend_for_acquisition(&mut self) { + poll_fn(|cx| match self.get_state() { + State::Busy => { + T::waker().register(cx.waker()); + T::regs().ier().write(|w| w.set_eoaie(true)); + if self.get_state() != State::Busy { + T::regs().ier().write(|w| w.set_eoaie(false)); + return Poll::Ready(()); + } + Poll::Pending + } + _ => { + T::regs().ier().write(|w| w.set_eoaie(false)); + Poll::Ready(()) + } + }) + .await; + } + /// Get current state of acquisition pub fn get_state(&mut self) -> State { if self.state == State::Busy { - if T::REGS.isr().read().eoaf() { - if T::REGS.isr().read().mcef() { + if T::regs().isr().read().eoaf() { + if T::regs().isr().read().mcef() { self.state = State::Error } else { self.state = State::Ready @@ -859,16 +902,16 @@ impl<'d, T: Instance> Tsc<'d, T> { // Status bits are set by hardware when the acquisition on the corresponding // enabled analog IO group is complete, cleared when new acquisition is started let status = match index { - Group::One => T::REGS.iogcsr().read().g1s(), - Group::Two => T::REGS.iogcsr().read().g2s(), - Group::Three => T::REGS.iogcsr().read().g3s(), - Group::Four => T::REGS.iogcsr().read().g4s(), - Group::Five => T::REGS.iogcsr().read().g5s(), - Group::Six => T::REGS.iogcsr().read().g6s(), + Group::One => T::regs().iogcsr().read().g1s(), + Group::Two => T::regs().iogcsr().read().g2s(), + Group::Three => T::regs().iogcsr().read().g3s(), + Group::Four => T::regs().iogcsr().read().g4s(), + Group::Five => T::regs().iogcsr().read().g5s(), + Group::Six => T::regs().iogcsr().read().g6s(), #[cfg(any(tsc_v2, tsc_v3))] - Group::Seven => T::REGS.iogcsr().read().g7s(), + Group::Seven => T::regs().iogcsr().read().g7s(), #[cfg(tsc_v3)] - Group::Eight => T::REGS.iogcsr().read().g8s(), + Group::Eight => T::regs().iogcsr().read().g8s(), }; match status { true => GroupStatus::Complete, @@ -878,13 +921,13 @@ impl<'d, T: Instance> Tsc<'d, T> { /// Get the count for the acquisiton, valid once group status is set pub fn group_get_value(&mut self, index: Group) -> u16 { - T::REGS.iogcr(index.into()).read().cnt() + T::regs().iogcr(index.into()).read().cnt() } /// Discharge the IOs for subsequent acquisition pub fn discharge_io(&mut self, status: bool) { // Set the touch sensing IOs in low power mode - T::REGS.cr().modify(|w| { + T::regs().cr().modify(|w| { w.set_iodef(!status); }); } @@ -897,20 +940,32 @@ impl<'d, T: Instance> Drop for Tsc<'d, T> { } pub(crate) trait SealedInstance { - const REGS: Regs; + fn regs() -> crate::pac::tsc::Tsc; + fn waker() -> &'static AtomicWaker; } /// TSC instance trait #[allow(private_bounds)] -pub trait Instance: Peripheral

+ SealedInstance + RccPeripheral {} +pub trait Instance: Peripheral

+ SealedInstance + RccPeripheral { + /// Interrupt for this TSC instance + type Interrupt: interrupt::typelevel::Interrupt; +} -foreach_peripheral!( - (tsc, $inst:ident) => { - impl SealedInstance for peripherals::$inst { - const REGS: Regs = crate::pac::$inst; +foreach_interrupt!( + ($inst:ident, tsc, TSC, GLOBAL, $irq:ident) => { + impl Instance for peripherals::$inst { + type Interrupt = crate::interrupt::typelevel::$irq; } - impl Instance for peripherals::$inst {} + impl SealedInstance for peripherals::$inst { + fn regs() -> crate::pac::tsc::Tsc { + crate::pac::$inst + } + fn waker() -> &'static AtomicWaker { + static WAKER: AtomicWaker = AtomicWaker::new(); + &WAKER + } + } }; ); diff --git a/examples/stm32u5/src/bin/tsc.rs b/examples/stm32u5/src/bin/tsc.rs index f5593d1c4..642bbeaca 100644 --- a/examples/stm32u5/src/bin/tsc.rs +++ b/examples/stm32u5/src/bin/tsc.rs @@ -2,10 +2,17 @@ #![no_main] use defmt::*; -use embassy_stm32::tsc::{self, *}; +use embassy_stm32::{ + bind_interrupts, + tsc::{self, *}, +}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; +bind_interrupts!(struct Irqs { + TSC => InterruptHandler; +}); + #[cortex_m_rt::exception] unsafe fn HardFault(_: &cortex_m_rt::ExceptionFrame) -> ! { cortex_m::peripheral::SCB::sys_reset(); @@ -47,6 +54,7 @@ async fn main(_spawner: embassy_executor::Spawner) { let mut touch_controller = tsc::Tsc::new( context.TSC, + Irqs, Some(g1), Some(g2), None, @@ -67,7 +75,7 @@ async fn main(_spawner: embassy_executor::Spawner) { let mut group_seven_val = 0; info!("Starting touch_controller interface"); loop { - touch_controller.poll_for_acquisition(); + touch_controller.pend_for_acquisition().await; touch_controller.discharge_io(true); Timer::after_millis(1).await; From 7eb605d1165eaf4cdf90453d1ed2d6976dd514af Mon Sep 17 00:00:00 2001 From: Eekle <96976531+Eekle@users.noreply.github.com> Date: Sun, 23 Jun 2024 16:54:10 +0200 Subject: [PATCH 2/5] fmt --- embassy-stm32/src/tsc/mod.rs | 9 ++++----- examples/stm32u5/src/bin/tsc.rs | 6 ++---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/embassy-stm32/src/tsc/mod.rs b/embassy-stm32/src/tsc/mod.rs index 6497ff0ee..d5da2529f 100644 --- a/embassy-stm32/src/tsc/mod.rs +++ b/embassy-stm32/src/tsc/mod.rs @@ -65,19 +65,18 @@ /// Enums defined for peripheral parameters pub mod enums; +use core::future::poll_fn; use core::marker::PhantomData; +use core::task::Poll; use embassy_hal_internal::{into_ref, PeripheralRef}; +use embassy_sync::waitqueue::AtomicWaker; pub use enums::*; use crate::gpio::{AfType, AnyPin, OutputType, Speed}; -use crate::interrupt; use crate::interrupt::typelevel::Interrupt; use crate::rcc::{self, RccPeripheral}; -use crate::{peripherals, Peripheral}; -use core::future::poll_fn; -use core::task::Poll; -use embassy_sync::waitqueue::AtomicWaker; +use crate::{interrupt, peripherals, Peripheral}; #[cfg(tsc_v1)] const TSC_NUM_GROUPS: u32 = 6; diff --git a/examples/stm32u5/src/bin/tsc.rs b/examples/stm32u5/src/bin/tsc.rs index 642bbeaca..db85fb158 100644 --- a/examples/stm32u5/src/bin/tsc.rs +++ b/examples/stm32u5/src/bin/tsc.rs @@ -2,10 +2,8 @@ #![no_main] use defmt::*; -use embassy_stm32::{ - bind_interrupts, - tsc::{self, *}, -}; +use embassy_stm32::bind_interrupts; +use embassy_stm32::tsc::{self, *}; use embassy_time::Timer; use {defmt_rtt as _, panic_probe as _}; From 1d1fc9afeac268a4b6d2cd9b9e5788226c79eca8 Mon Sep 17 00:00:00 2001 From: Eekle <96976531+Eekle@users.noreply.github.com> Date: Sun, 30 Jun 2024 11:03:29 +0200 Subject: [PATCH 3/5] Add async and blocking variants --- embassy-stm32/src/tsc/mod.rs | 203 +++++++++++++++++++++-------------- 1 file changed, 120 insertions(+), 83 deletions(-) diff --git a/embassy-stm32/src/tsc/mod.rs b/embassy-stm32/src/tsc/mod.rs index d5da2529f..cd7ae4a53 100644 --- a/embassy-stm32/src/tsc/mod.rs +++ b/embassy-stm32/src/tsc/mod.rs @@ -93,6 +93,23 @@ pub enum Error { Test, } +/// Async acquisition API marker +pub struct Async; +/// Blocking acquisition API marker +pub struct Blocking; + +trait SealedDriverKind {} + +impl SealedDriverKind for Async {} +impl SealedDriverKind for Blocking {} + +#[allow(private_bounds)] +/// Driver variant marker for the TSC peripheral +pub trait DriverKind: SealedDriverKind {} + +impl DriverKind for Async {} +impl DriverKind for Blocking {} + /// TSC interrupt handler. pub struct InterruptHandler { _phantom: PhantomData, @@ -505,7 +522,7 @@ pub enum G7 {} pub enum G8 {} /// TSC driver -pub struct Tsc<'d, T: Instance> { +pub struct Tsc<'d, T: Instance, K: DriverKind> { _peri: PeripheralRef<'d, T>, _g1: Option>, _g2: Option>, @@ -519,13 +536,103 @@ pub struct Tsc<'d, T: Instance> { _g8: Option>, state: State, config: Config, + _kind: PhantomData, } -impl<'d, T: Instance> Tsc<'d, T> { - /// Create new TSC driver - pub fn new( +impl<'d, T: Instance> Tsc<'d, T, Async> { + /// Create a Tsc instance that can be awaited for completion + pub fn new_async( peri: impl Peripheral

+ 'd, + g1: Option>, + g2: Option>, + g3: Option>, + g4: Option>, + g5: Option>, + g6: Option>, + #[cfg(any(tsc_v2, tsc_v3))] g7: Option>, + #[cfg(tsc_v3)] g8: Option>, + config: Config, _irq: impl interrupt::typelevel::Binding> + 'd, + ) -> Self { + // Need to check valid pin configuration input + let g1 = g1.filter(|b| b.check_group().is_ok()); + let g2 = g2.filter(|b| b.check_group().is_ok()); + let g3 = g3.filter(|b| b.check_group().is_ok()); + let g4 = g4.filter(|b| b.check_group().is_ok()); + let g5 = g5.filter(|b| b.check_group().is_ok()); + let g6 = g6.filter(|b| b.check_group().is_ok()); + #[cfg(any(tsc_v2, tsc_v3))] + let g7 = g7.filter(|b| b.check_group().is_ok()); + #[cfg(tsc_v3)] + 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))] + &g7, + #[cfg(tsc_v3)] + &g8, + ) { + 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, + ), + } + } + /// Asyncronously wait for the end of an acquisition + pub async fn pend_for_acquisition(&mut self) { + poll_fn(|cx| match self.get_state() { + State::Busy => { + T::waker().register(cx.waker()); + T::regs().ier().write(|w| w.set_eoaie(true)); + if self.get_state() != State::Busy { + T::regs().ier().write(|w| w.set_eoaie(false)); + return Poll::Ready(()); + } + Poll::Pending + } + _ => { + T::regs().ier().write(|w| w.set_eoaie(false)); + Poll::Ready(()) + } + }) + .await; + } +} + +impl<'d, T: Instance> Tsc<'d, T, Blocking> { + /// Create a Tsc instance that must be polled for completion + pub fn new_blocking( + peri: impl Peripheral

+ 'd, g1: Option>, g2: Option>, g3: Option>, @@ -590,7 +697,14 @@ impl<'d, T: Instance> Tsc<'d, T> { ), } } + /// Wait for end of acquisition + pub fn poll_for_acquisition(&mut self) { + while self.get_state() == State::Busy {} + } +} +impl<'d, T: Instance, K: DriverKind> Tsc<'d, T, K> { + /// Create new TSC driver fn check_shields( g1: &Option>, g2: &Option>, @@ -754,6 +868,7 @@ impl<'d, T: Instance> Tsc<'d, T> { _g8: g8, state: State::Ready, config, + _kind: PhantomData, } } @@ -784,33 +899,6 @@ impl<'d, T: Instance> Tsc<'d, T> { }); } - /// Start charge transfer acquisition with interrupts enabled - pub fn start_it(&mut self) { - self.state = State::Busy; - - // Enable interrupts - T::regs().ier().modify(|w| { - w.set_eoaie(true); - w.set_mceie(self.config.max_count_interrupt); - }); - - // Clear flags - T::regs().icr().modify(|w| { - w.set_eoaic(true); - w.set_mceic(true); - }); - - // Set the touch sensing IOs not acquired to the default mode - T::regs().cr().modify(|w| { - w.set_iodef(self.config.io_default_mode); - }); - - // Start the acquisition - T::regs().cr().modify(|w| { - w.set_start(true); - }); - } - /// Stop charge transfer acquisition pub fn stop(&mut self) { T::regs().cr().modify(|w| { @@ -831,57 +919,6 @@ impl<'d, T: Instance> Tsc<'d, T> { self.state = State::Ready; } - /// Stop charge transfer acquisition and clear interrupts - pub fn stop_it(&mut self) { - T::regs().cr().modify(|w| { - w.set_start(false); - }); - - // Set the touch sensing IOs in low power mode - T::regs().cr().modify(|w| { - w.set_iodef(false); - }); - - // Disable interrupts - T::regs().ier().modify(|w| { - w.set_eoaie(false); - w.set_mceie(false); - }); - - // Clear flags - T::regs().icr().modify(|w| { - w.set_eoaic(true); - w.set_mceic(true); - }); - - self.state = State::Ready; - } - - /// Wait for end of acquisition - pub fn poll_for_acquisition(&mut self) { - while self.get_state() == State::Busy {} - } - - /// Asyncronously wait for the end of an acquisition - pub async fn pend_for_acquisition(&mut self) { - poll_fn(|cx| match self.get_state() { - State::Busy => { - T::waker().register(cx.waker()); - T::regs().ier().write(|w| w.set_eoaie(true)); - if self.get_state() != State::Busy { - T::regs().ier().write(|w| w.set_eoaie(false)); - return Poll::Ready(()); - } - Poll::Pending - } - _ => { - T::regs().ier().write(|w| w.set_eoaie(false)); - Poll::Ready(()) - } - }) - .await; - } - /// Get current state of acquisition pub fn get_state(&mut self) -> State { if self.state == State::Busy { @@ -932,7 +969,7 @@ impl<'d, T: Instance> Tsc<'d, T> { } } -impl<'d, T: Instance> Drop for Tsc<'d, T> { +impl<'d, T: Instance, K: DriverKind> Drop for Tsc<'d, T, K> { fn drop(&mut self) { rcc::disable::(); } From 67f5b8d974c23854676cff3a6797cf4aaf41a402 Mon Sep 17 00:00:00 2001 From: Eekle <96976531+Eekle@users.noreply.github.com> Date: Sun, 30 Jun 2024 11:06:32 +0200 Subject: [PATCH 4/5] Update example --- examples/stm32u5/src/bin/tsc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/stm32u5/src/bin/tsc.rs b/examples/stm32u5/src/bin/tsc.rs index db85fb158..eb15d275a 100644 --- a/examples/stm32u5/src/bin/tsc.rs +++ b/examples/stm32u5/src/bin/tsc.rs @@ -50,9 +50,8 @@ async fn main(_spawner: embassy_executor::Spawner) { g7.set_io2(context.PE3, PinType::Sample); g7.set_io3(context.PE4, PinType::Channel); - let mut touch_controller = tsc::Tsc::new( + let mut touch_controller = tsc::Tsc::new_async( context.TSC, - Irqs, Some(g1), Some(g2), None, @@ -62,6 +61,7 @@ async fn main(_spawner: embassy_executor::Spawner) { Some(g7), None, config, + Irqs, ); touch_controller.discharge_io(true); From d3f8905e938eecfe7789841c6232cb34b5f43a20 Mon Sep 17 00:00:00 2001 From: Eekle <96976531+Eekle@users.noreply.github.com> Date: Tue, 2 Jul 2024 20:46:05 +0200 Subject: [PATCH 5/5] Use crate level PeriMode --- embassy-stm32/src/tsc/mod.rs | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/embassy-stm32/src/tsc/mod.rs b/embassy-stm32/src/tsc/mod.rs index cd7ae4a53..5cb58e918 100644 --- a/embassy-stm32/src/tsc/mod.rs +++ b/embassy-stm32/src/tsc/mod.rs @@ -75,6 +75,7 @@ pub use enums::*; use crate::gpio::{AfType, AnyPin, OutputType, Speed}; use crate::interrupt::typelevel::Interrupt; +use crate::mode::{Async, Blocking, Mode as PeriMode}; use crate::rcc::{self, RccPeripheral}; use crate::{interrupt, peripherals, Peripheral}; @@ -93,23 +94,6 @@ pub enum Error { Test, } -/// Async acquisition API marker -pub struct Async; -/// Blocking acquisition API marker -pub struct Blocking; - -trait SealedDriverKind {} - -impl SealedDriverKind for Async {} -impl SealedDriverKind for Blocking {} - -#[allow(private_bounds)] -/// Driver variant marker for the TSC peripheral -pub trait DriverKind: SealedDriverKind {} - -impl DriverKind for Async {} -impl DriverKind for Blocking {} - /// TSC interrupt handler. pub struct InterruptHandler { _phantom: PhantomData, @@ -522,7 +506,7 @@ pub enum G7 {} pub enum G8 {} /// TSC driver -pub struct Tsc<'d, T: Instance, K: DriverKind> { +pub struct Tsc<'d, T: Instance, K: PeriMode> { _peri: PeripheralRef<'d, T>, _g1: Option>, _g2: Option>, @@ -703,7 +687,7 @@ impl<'d, T: Instance> Tsc<'d, T, Blocking> { } } -impl<'d, T: Instance, K: DriverKind> Tsc<'d, T, K> { +impl<'d, T: Instance, K: PeriMode> Tsc<'d, T, K> { /// Create new TSC driver fn check_shields( g1: &Option>, @@ -969,7 +953,7 @@ impl<'d, T: Instance, K: DriverKind> Tsc<'d, T, K> { } } -impl<'d, T: Instance, K: DriverKind> Drop for Tsc<'d, T, K> { +impl<'d, T: Instance, K: PeriMode> Drop for Tsc<'d, T, K> { fn drop(&mut self) { rcc::disable::(); }