mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-25 00:02:28 +00:00
Merge pull request #3111 from Eekle/feature/async_tsc
Add async API to TSC
This commit is contained in:
commit
5223923bd2
@ -65,15 +65,19 @@
|
|||||||
/// Enums defined for peripheral parameters
|
/// Enums defined for peripheral parameters
|
||||||
pub mod enums;
|
pub mod enums;
|
||||||
|
|
||||||
|
use core::future::poll_fn;
|
||||||
use core::marker::PhantomData;
|
use core::marker::PhantomData;
|
||||||
|
use core::task::Poll;
|
||||||
|
|
||||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||||
|
use embassy_sync::waitqueue::AtomicWaker;
|
||||||
pub use enums::*;
|
pub use enums::*;
|
||||||
|
|
||||||
use crate::gpio::{AfType, AnyPin, OutputType, Speed};
|
use crate::gpio::{AfType, AnyPin, OutputType, Speed};
|
||||||
use crate::pac::tsc::Tsc as Regs;
|
use crate::interrupt::typelevel::Interrupt;
|
||||||
|
use crate::mode::{Async, Blocking, Mode as PeriMode};
|
||||||
use crate::rcc::{self, RccPeripheral};
|
use crate::rcc::{self, RccPeripheral};
|
||||||
use crate::{peripherals, Peripheral};
|
use crate::{interrupt, peripherals, Peripheral};
|
||||||
|
|
||||||
#[cfg(tsc_v1)]
|
#[cfg(tsc_v1)]
|
||||||
const TSC_NUM_GROUPS: u32 = 6;
|
const TSC_NUM_GROUPS: u32 = 6;
|
||||||
@ -90,6 +94,18 @@ pub enum Error {
|
|||||||
Test,
|
Test,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// TSC interrupt handler.
|
||||||
|
pub struct InterruptHandler<T: Instance> {
|
||||||
|
_phantom: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Instance> interrupt::typelevel::Handler<T::Interrupt> for InterruptHandler<T> {
|
||||||
|
unsafe fn on_interrupt() {
|
||||||
|
T::regs().ier().write(|w| w.set_eoaie(false));
|
||||||
|
T::waker().wake();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Pin type definition to control IO parameters
|
/// Pin type definition to control IO parameters
|
||||||
pub enum PinType {
|
pub enum PinType {
|
||||||
/// Sensing channel pin connected to an electrode
|
/// Sensing channel pin connected to an electrode
|
||||||
@ -490,7 +506,7 @@ pub enum G7 {}
|
|||||||
pub enum G8 {}
|
pub enum G8 {}
|
||||||
|
|
||||||
/// TSC driver
|
/// TSC driver
|
||||||
pub struct Tsc<'d, T: Instance> {
|
pub struct Tsc<'d, T: Instance, K: PeriMode> {
|
||||||
_peri: PeripheralRef<'d, T>,
|
_peri: PeripheralRef<'d, T>,
|
||||||
_g1: Option<PinGroup<'d, T, G1>>,
|
_g1: Option<PinGroup<'d, T, G1>>,
|
||||||
_g2: Option<PinGroup<'d, T, G2>>,
|
_g2: Option<PinGroup<'d, T, G2>>,
|
||||||
@ -504,11 +520,102 @@ pub struct Tsc<'d, T: Instance> {
|
|||||||
_g8: Option<PinGroup<'d, T, G8>>,
|
_g8: Option<PinGroup<'d, T, G8>>,
|
||||||
state: State,
|
state: State,
|
||||||
config: Config,
|
config: Config,
|
||||||
|
_kind: PhantomData<K>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> Tsc<'d, T> {
|
impl<'d, T: Instance> Tsc<'d, T, Async> {
|
||||||
/// Create new TSC driver
|
/// Create a Tsc instance that can be awaited for completion
|
||||||
pub fn new(
|
pub fn new_async(
|
||||||
|
peri: impl Peripheral<P = T> + 'd,
|
||||||
|
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>>,
|
||||||
|
config: Config,
|
||||||
|
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + '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<P = T> + 'd,
|
peri: impl Peripheral<P = T> + 'd,
|
||||||
g1: Option<PinGroup<'d, T, G1>>,
|
g1: Option<PinGroup<'d, T, G1>>,
|
||||||
g2: Option<PinGroup<'d, T, G2>>,
|
g2: Option<PinGroup<'d, T, G2>>,
|
||||||
@ -574,7 +681,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: PeriMode> Tsc<'d, T, K> {
|
||||||
|
/// Create new TSC driver
|
||||||
fn check_shields(
|
fn check_shields(
|
||||||
g1: &Option<PinGroup<'d, T, G1>>,
|
g1: &Option<PinGroup<'d, T, G1>>,
|
||||||
g2: &Option<PinGroup<'d, T, G2>>,
|
g2: &Option<PinGroup<'d, T, G2>>,
|
||||||
@ -663,7 +777,7 @@ impl<'d, T: Instance> Tsc<'d, T> {
|
|||||||
|
|
||||||
rcc::enable_and_reset::<T>();
|
rcc::enable_and_reset::<T>();
|
||||||
|
|
||||||
T::REGS.cr().modify(|w| {
|
T::regs().cr().modify(|w| {
|
||||||
w.set_tsce(true);
|
w.set_tsce(true);
|
||||||
w.set_ctph(config.ct_pulse_high_length.into());
|
w.set_ctph(config.ct_pulse_high_length.into());
|
||||||
w.set_ctpl(config.ct_pulse_low_length.into());
|
w.set_ctpl(config.ct_pulse_low_length.into());
|
||||||
@ -691,33 +805,39 @@ impl<'d, T: Instance> Tsc<'d, T> {
|
|||||||
|
|
||||||
// Set IO configuration
|
// Set IO configuration
|
||||||
// Disable Schmitt trigger hysteresis on all used TSC IOs
|
// Disable Schmitt trigger hysteresis on all used TSC IOs
|
||||||
T::REGS
|
T::regs()
|
||||||
.iohcr()
|
.iohcr()
|
||||||
.write(|w| w.0 = !(config.channel_ios | config.shield_ios | config.sampling_ios));
|
.write(|w| w.0 = !(config.channel_ios | config.shield_ios | config.sampling_ios));
|
||||||
|
|
||||||
// Set channel and shield 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
|
// 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
|
// Set the groups to be acquired
|
||||||
T::REGS
|
T::regs()
|
||||||
.iogcsr()
|
.iogcsr()
|
||||||
.write(|w| w.0 = Self::extract_groups(config.channel_ios));
|
.write(|w| w.0 = Self::extract_groups(config.channel_ios));
|
||||||
|
|
||||||
// Disable interrupts
|
// Disable interrupts
|
||||||
T::REGS.ier().modify(|w| {
|
T::regs().ier().modify(|w| {
|
||||||
w.set_eoaie(false);
|
w.set_eoaie(false);
|
||||||
w.set_mceie(false);
|
w.set_mceie(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Clear flags
|
// Clear flags
|
||||||
T::REGS.icr().modify(|w| {
|
T::regs().icr().modify(|w| {
|
||||||
w.set_eoaic(true);
|
w.set_eoaic(true);
|
||||||
w.set_mceic(true);
|
w.set_mceic(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
T::Interrupt::enable();
|
||||||
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
_peri: peri,
|
_peri: peri,
|
||||||
_g1: g1,
|
_g1: g1,
|
||||||
@ -732,6 +852,7 @@ impl<'d, T: Instance> Tsc<'d, T> {
|
|||||||
_g8: g8,
|
_g8: g8,
|
||||||
state: State::Ready,
|
state: State::Ready,
|
||||||
config,
|
config,
|
||||||
|
_kind: PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -740,68 +861,41 @@ impl<'d, T: Instance> Tsc<'d, T> {
|
|||||||
self.state = State::Busy;
|
self.state = State::Busy;
|
||||||
|
|
||||||
// Disable interrupts
|
// Disable interrupts
|
||||||
T::REGS.ier().modify(|w| {
|
T::regs().ier().modify(|w| {
|
||||||
w.set_eoaie(false);
|
w.set_eoaie(false);
|
||||||
w.set_mceie(false);
|
w.set_mceie(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Clear flags
|
// Clear flags
|
||||||
T::REGS.icr().modify(|w| {
|
T::regs().icr().modify(|w| {
|
||||||
w.set_eoaic(true);
|
w.set_eoaic(true);
|
||||||
w.set_mceic(true);
|
w.set_mceic(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set the touch sensing IOs not acquired to the default mode
|
// 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);
|
w.set_iodef(self.config.io_default_mode);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Start the acquisition
|
// Start the acquisition
|
||||||
T::REGS.cr().modify(|w| {
|
T::regs().cr().modify(|w| {
|
||||||
w.set_start(true);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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);
|
w.set_start(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stop charge transfer acquisition
|
/// Stop charge transfer acquisition
|
||||||
pub fn stop(&mut self) {
|
pub fn stop(&mut self) {
|
||||||
T::REGS.cr().modify(|w| {
|
T::regs().cr().modify(|w| {
|
||||||
w.set_start(false);
|
w.set_start(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Set the touch sensing IOs in low power mode
|
// Set the touch sensing IOs in low power mode
|
||||||
T::REGS.cr().modify(|w| {
|
T::regs().cr().modify(|w| {
|
||||||
w.set_iodef(false);
|
w.set_iodef(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Clear flags
|
// Clear flags
|
||||||
T::REGS.icr().modify(|w| {
|
T::regs().icr().modify(|w| {
|
||||||
w.set_eoaic(true);
|
w.set_eoaic(true);
|
||||||
w.set_mceic(true);
|
w.set_mceic(true);
|
||||||
});
|
});
|
||||||
@ -809,42 +903,11 @@ impl<'d, T: Instance> Tsc<'d, T> {
|
|||||||
self.state = State::Ready;
|
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 {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get current state of acquisition
|
/// Get current state of acquisition
|
||||||
pub fn get_state(&mut self) -> State {
|
pub fn get_state(&mut self) -> State {
|
||||||
if self.state == State::Busy {
|
if self.state == State::Busy {
|
||||||
if T::REGS.isr().read().eoaf() {
|
if T::regs().isr().read().eoaf() {
|
||||||
if T::REGS.isr().read().mcef() {
|
if T::regs().isr().read().mcef() {
|
||||||
self.state = State::Error
|
self.state = State::Error
|
||||||
} else {
|
} else {
|
||||||
self.state = State::Ready
|
self.state = State::Ready
|
||||||
@ -859,16 +922,16 @@ impl<'d, T: Instance> Tsc<'d, T> {
|
|||||||
// Status bits are set by hardware when the acquisition on the corresponding
|
// Status bits are set by hardware when the acquisition on the corresponding
|
||||||
// enabled analog IO group is complete, cleared when new acquisition is started
|
// enabled analog IO group is complete, cleared when new acquisition is started
|
||||||
let status = match index {
|
let status = match index {
|
||||||
Group::One => T::REGS.iogcsr().read().g1s(),
|
Group::One => T::regs().iogcsr().read().g1s(),
|
||||||
Group::Two => T::REGS.iogcsr().read().g2s(),
|
Group::Two => T::regs().iogcsr().read().g2s(),
|
||||||
Group::Three => T::REGS.iogcsr().read().g3s(),
|
Group::Three => T::regs().iogcsr().read().g3s(),
|
||||||
Group::Four => T::REGS.iogcsr().read().g4s(),
|
Group::Four => T::regs().iogcsr().read().g4s(),
|
||||||
Group::Five => T::REGS.iogcsr().read().g5s(),
|
Group::Five => T::regs().iogcsr().read().g5s(),
|
||||||
Group::Six => T::REGS.iogcsr().read().g6s(),
|
Group::Six => T::regs().iogcsr().read().g6s(),
|
||||||
#[cfg(any(tsc_v2, tsc_v3))]
|
#[cfg(any(tsc_v2, tsc_v3))]
|
||||||
Group::Seven => T::REGS.iogcsr().read().g7s(),
|
Group::Seven => T::regs().iogcsr().read().g7s(),
|
||||||
#[cfg(tsc_v3)]
|
#[cfg(tsc_v3)]
|
||||||
Group::Eight => T::REGS.iogcsr().read().g8s(),
|
Group::Eight => T::regs().iogcsr().read().g8s(),
|
||||||
};
|
};
|
||||||
match status {
|
match status {
|
||||||
true => GroupStatus::Complete,
|
true => GroupStatus::Complete,
|
||||||
@ -878,39 +941,51 @@ impl<'d, T: Instance> Tsc<'d, T> {
|
|||||||
|
|
||||||
/// Get the count for the acquisiton, valid once group status is set
|
/// Get the count for the acquisiton, valid once group status is set
|
||||||
pub fn group_get_value(&mut self, index: Group) -> u16 {
|
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
|
/// Discharge the IOs for subsequent acquisition
|
||||||
pub fn discharge_io(&mut self, status: bool) {
|
pub fn discharge_io(&mut self, status: bool) {
|
||||||
// Set the touch sensing IOs in low power mode
|
// Set the touch sensing IOs in low power mode
|
||||||
T::REGS.cr().modify(|w| {
|
T::regs().cr().modify(|w| {
|
||||||
w.set_iodef(!status);
|
w.set_iodef(!status);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, T: Instance> Drop for Tsc<'d, T> {
|
impl<'d, T: Instance, K: PeriMode> Drop for Tsc<'d, T, K> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
rcc::disable::<T>();
|
rcc::disable::<T>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait SealedInstance {
|
pub(crate) trait SealedInstance {
|
||||||
const REGS: Regs;
|
fn regs() -> crate::pac::tsc::Tsc;
|
||||||
|
fn waker() -> &'static AtomicWaker;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TSC instance trait
|
/// TSC instance trait
|
||||||
#[allow(private_bounds)]
|
#[allow(private_bounds)]
|
||||||
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
|
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {
|
||||||
|
/// Interrupt for this TSC instance
|
||||||
|
type Interrupt: interrupt::typelevel::Interrupt;
|
||||||
|
}
|
||||||
|
|
||||||
foreach_peripheral!(
|
foreach_interrupt!(
|
||||||
(tsc, $inst:ident) => {
|
($inst:ident, tsc, TSC, GLOBAL, $irq:ident) => {
|
||||||
impl SealedInstance for peripherals::$inst {
|
impl Instance for peripherals::$inst {
|
||||||
const REGS: Regs = crate::pac::$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
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2,10 +2,15 @@
|
|||||||
#![no_main]
|
#![no_main]
|
||||||
|
|
||||||
use defmt::*;
|
use defmt::*;
|
||||||
|
use embassy_stm32::bind_interrupts;
|
||||||
use embassy_stm32::tsc::{self, *};
|
use embassy_stm32::tsc::{self, *};
|
||||||
use embassy_time::Timer;
|
use embassy_time::Timer;
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
|
bind_interrupts!(struct Irqs {
|
||||||
|
TSC => InterruptHandler<embassy_stm32::peripherals::TSC>;
|
||||||
|
});
|
||||||
|
|
||||||
#[cortex_m_rt::exception]
|
#[cortex_m_rt::exception]
|
||||||
unsafe fn HardFault(_: &cortex_m_rt::ExceptionFrame) -> ! {
|
unsafe fn HardFault(_: &cortex_m_rt::ExceptionFrame) -> ! {
|
||||||
cortex_m::peripheral::SCB::sys_reset();
|
cortex_m::peripheral::SCB::sys_reset();
|
||||||
@ -45,7 +50,7 @@ async fn main(_spawner: embassy_executor::Spawner) {
|
|||||||
g7.set_io2(context.PE3, PinType::Sample);
|
g7.set_io2(context.PE3, PinType::Sample);
|
||||||
g7.set_io3(context.PE4, PinType::Channel);
|
g7.set_io3(context.PE4, PinType::Channel);
|
||||||
|
|
||||||
let mut touch_controller = tsc::Tsc::new(
|
let mut touch_controller = tsc::Tsc::new_async(
|
||||||
context.TSC,
|
context.TSC,
|
||||||
Some(g1),
|
Some(g1),
|
||||||
Some(g2),
|
Some(g2),
|
||||||
@ -56,6 +61,7 @@ async fn main(_spawner: embassy_executor::Spawner) {
|
|||||||
Some(g7),
|
Some(g7),
|
||||||
None,
|
None,
|
||||||
config,
|
config,
|
||||||
|
Irqs,
|
||||||
);
|
);
|
||||||
|
|
||||||
touch_controller.discharge_io(true);
|
touch_controller.discharge_io(true);
|
||||||
@ -67,7 +73,7 @@ async fn main(_spawner: embassy_executor::Spawner) {
|
|||||||
let mut group_seven_val = 0;
|
let mut group_seven_val = 0;
|
||||||
info!("Starting touch_controller interface");
|
info!("Starting touch_controller interface");
|
||||||
loop {
|
loop {
|
||||||
touch_controller.poll_for_acquisition();
|
touch_controller.pend_for_acquisition().await;
|
||||||
touch_controller.discharge_io(true);
|
touch_controller.discharge_io(true);
|
||||||
Timer::after_millis(1).await;
|
Timer::after_millis(1).await;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user