mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-21 22:32:29 +00:00
Initial fill out of driver without IO considerations
This commit is contained in:
parent
45a2abc392
commit
0febc24de7
@ -1030,6 +1030,38 @@ fn main() {
|
||||
(("octospi", "NCS"), quote!(crate::ospi::NSSPin)),
|
||||
(("octospi", "CLK"), quote!(crate::ospi::SckPin)),
|
||||
(("octospi", "NCLK"), quote!(crate::ospi::NckPin)),
|
||||
(("tsc", "G1_IO1"), quote!(crate::ospi::G1IO1Pin)),
|
||||
(("tsc", "G1_IO2"), quote!(crate::ospi::G1IO2Pin)),
|
||||
(("tsc", "G1_IO3"), quote!(crate::ospi::G1IO3Pin)),
|
||||
(("tsc", "G1_IO4"), quote!(crate::ospi::G1IO4Pin)),
|
||||
(("tsc", "G2_IO1"), quote!(crate::ospi::G2IO1Pin)),
|
||||
(("tsc", "G2_IO2"), quote!(crate::ospi::G2IO2Pin)),
|
||||
(("tsc", "G2_IO3"), quote!(crate::ospi::G2IO3Pin)),
|
||||
(("tsc", "G2_IO4"), quote!(crate::ospi::G2IO4Pin)),
|
||||
(("tsc", "G3_IO1"), quote!(crate::ospi::G3IO1Pin)),
|
||||
(("tsc", "G3_IO2"), quote!(crate::ospi::G3IO2Pin)),
|
||||
(("tsc", "G3_IO3"), quote!(crate::ospi::G3IO3Pin)),
|
||||
(("tsc", "G3_IO4"), quote!(crate::ospi::G3IO4Pin)),
|
||||
(("tsc", "G4_IO1"), quote!(crate::ospi::G4IO1Pin)),
|
||||
(("tsc", "G4_IO2"), quote!(crate::ospi::G4IO2Pin)),
|
||||
(("tsc", "G4_IO3"), quote!(crate::ospi::G4IO3Pin)),
|
||||
(("tsc", "G4_IO4"), quote!(crate::ospi::G4IO4Pin)),
|
||||
(("tsc", "G5_IO1"), quote!(crate::ospi::G5IO1Pin)),
|
||||
(("tsc", "G5_IO2"), quote!(crate::ospi::G5IO2Pin)),
|
||||
(("tsc", "G5_IO3"), quote!(crate::ospi::G5IO3Pin)),
|
||||
(("tsc", "G5_IO4"), quote!(crate::ospi::G5IO4Pin)),
|
||||
(("tsc", "G6_IO1"), quote!(crate::ospi::G6IO1Pin)),
|
||||
(("tsc", "G6_IO2"), quote!(crate::ospi::G6IO2Pin)),
|
||||
(("tsc", "G6_IO3"), quote!(crate::ospi::G6IO3Pin)),
|
||||
(("tsc", "G6_IO4"), quote!(crate::ospi::G6IO4Pin)),
|
||||
(("tsc", "G7_IO1"), quote!(crate::ospi::G7IO1Pin)),
|
||||
(("tsc", "G7_IO2"), quote!(crate::ospi::G7IO2Pin)),
|
||||
(("tsc", "G7_IO3"), quote!(crate::ospi::G7IO3Pin)),
|
||||
(("tsc", "G7_IO4"), quote!(crate::ospi::G7IO4Pin)),
|
||||
(("tsc", "G8_IO1"), quote!(crate::ospi::G8IO1Pin)),
|
||||
(("tsc", "G8_IO2"), quote!(crate::ospi::G8IO2Pin)),
|
||||
(("tsc", "G8_IO3"), quote!(crate::ospi::G8IO3Pin)),
|
||||
(("tsc", "G8_IO4"), quote!(crate::ospi::G8IO4Pin)),
|
||||
].into();
|
||||
|
||||
for p in METADATA.peripherals {
|
||||
|
@ -103,6 +103,8 @@ pub mod sdmmc;
|
||||
pub mod spi;
|
||||
#[cfg(ucpd)]
|
||||
pub mod ucpd;
|
||||
#[cfg(tsc)]
|
||||
pub mod tsc;
|
||||
#[cfg(uid)]
|
||||
pub mod uid;
|
||||
#[cfg(usart)]
|
||||
|
100
embassy-stm32/src/tsc/enums.rs
Normal file
100
embassy-stm32/src/tsc/enums.rs
Normal file
@ -0,0 +1,100 @@
|
||||
/// Charge transfer pulse cycles
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum ChargeTransferPulseCycle {
|
||||
_1,
|
||||
_2,
|
||||
_3,
|
||||
_4,
|
||||
_5,
|
||||
_6,
|
||||
_7,
|
||||
_8,
|
||||
_9,
|
||||
_10,
|
||||
_11,
|
||||
_12,
|
||||
_13,
|
||||
_14,
|
||||
_15,
|
||||
_16,
|
||||
}
|
||||
|
||||
impl Into<u8> for ChargeTransferPulseCycle {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
ChargeTransferPulseCycle::_1 => 0,
|
||||
ChargeTransferPulseCycle::_2 => 1,
|
||||
ChargeTransferPulseCycle::_3 => 2,
|
||||
ChargeTransferPulseCycle::_4 => 3,
|
||||
ChargeTransferPulseCycle::_5 => 4,
|
||||
ChargeTransferPulseCycle::_6 => 5,
|
||||
ChargeTransferPulseCycle::_7 => 6,
|
||||
ChargeTransferPulseCycle::_8 => 7,
|
||||
ChargeTransferPulseCycle::_9 => 8,
|
||||
ChargeTransferPulseCycle::_10 => 9,
|
||||
ChargeTransferPulseCycle::_11 => 10,
|
||||
ChargeTransferPulseCycle::_12 => 11,
|
||||
ChargeTransferPulseCycle::_13 => 12,
|
||||
ChargeTransferPulseCycle::_14 => 13,
|
||||
ChargeTransferPulseCycle::_15 => 14,
|
||||
ChargeTransferPulseCycle::_16 => 15,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Prescaler divider
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum PGPrescalerDivider {
|
||||
_1,
|
||||
_2,
|
||||
_4,
|
||||
_8,
|
||||
_16,
|
||||
_32,
|
||||
_64,
|
||||
_128,
|
||||
}
|
||||
|
||||
impl Into<u8> for PGPrescalerDivider {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
PGPrescalerDivider::_1 => 0,
|
||||
PGPrescalerDivider::_2 => 1,
|
||||
PGPrescalerDivider::_4 => 2,
|
||||
PGPrescalerDivider::_8 => 3,
|
||||
PGPrescalerDivider::_16 => 4,
|
||||
PGPrescalerDivider::_32 => 5,
|
||||
PGPrescalerDivider::_64 => 6,
|
||||
PGPrescalerDivider::_128 => 7,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Max count
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum MaxCount {
|
||||
_255,
|
||||
_511,
|
||||
_1023,
|
||||
_2047,
|
||||
_4095,
|
||||
_8191,
|
||||
_16383,
|
||||
}
|
||||
|
||||
impl Into<u8> for MaxCount {
|
||||
fn into(self) -> u8 {
|
||||
match self {
|
||||
MaxCount::_255 => 0,
|
||||
MaxCount::_511 => 1,
|
||||
MaxCount::_1023 => 2,
|
||||
MaxCount::_2047 => 3,
|
||||
MaxCount::_4095 => 4,
|
||||
MaxCount::_8191 => 5,
|
||||
MaxCount::_16383 => 6,
|
||||
}
|
||||
}
|
||||
}
|
357
embassy-stm32/src/tsc/mod.rs
Normal file
357
embassy-stm32/src/tsc/mod.rs
Normal file
@ -0,0 +1,357 @@
|
||||
//! TSC Peripheral Interface
|
||||
|
||||
#![macro_use]
|
||||
|
||||
pub mod enums;
|
||||
|
||||
use crate::gpio::AnyPin;
|
||||
use crate::{pac::tsc::Tsc as Regs, rcc::RccPeripheral};
|
||||
use crate::{peripherals, Peripheral};
|
||||
use embassy_hal_internal::{into_ref, PeripheralRef};
|
||||
|
||||
pub use enums::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum Error {
|
||||
/// Test error for TSC
|
||||
Test,
|
||||
}
|
||||
|
||||
pub enum PinType {
|
||||
Channel,
|
||||
Sample,
|
||||
Shield,
|
||||
}
|
||||
|
||||
pub struct TscGroup {}
|
||||
|
||||
pub enum State {
|
||||
Reset,
|
||||
Ready,
|
||||
Busy,
|
||||
Error,
|
||||
}
|
||||
|
||||
pub enum GroupStatus {
|
||||
Ongoing,
|
||||
Complete,
|
||||
}
|
||||
|
||||
pub enum Group {
|
||||
One,
|
||||
Two,
|
||||
Three,
|
||||
Four,
|
||||
Five,
|
||||
Six,
|
||||
Seven,
|
||||
Eight,
|
||||
}
|
||||
|
||||
impl Into<usize> for Group {
|
||||
fn into(self) -> usize {
|
||||
match self {
|
||||
Group::One => 0,
|
||||
Group::Two => 1,
|
||||
Group::Three => 2,
|
||||
Group::Four => 3,
|
||||
Group::Five => 4,
|
||||
Group::Six => 5,
|
||||
Group::Seven => 6,
|
||||
Group::Eight => 7,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Config {
|
||||
pub ct_pulse_high_length: ChargeTransferPulseCycle,
|
||||
pub ct_pulse_low_length: ChargeTransferPulseCycle,
|
||||
pub spread_spectrum: bool,
|
||||
pub spread_spectrum_deviation: u8,
|
||||
pub spread_spectrum_prescaler: bool,
|
||||
pub pulse_generator_prescaler: PGPrescalerDivider,
|
||||
pub max_count_value: u8,
|
||||
pub io_default_mode: bool,
|
||||
pub synchro_pin_polarity: bool,
|
||||
pub acquisition_mode: bool,
|
||||
pub max_count_interrupt: bool,
|
||||
pub channel_ios: u32,
|
||||
pub shield_ios: u32,
|
||||
pub sampling_ios: u32,
|
||||
}
|
||||
|
||||
pub struct TSC<'d, T: Instance> {
|
||||
_peri: PeripheralRef<'d, T>,
|
||||
state: State,
|
||||
config: Config,
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> TSC<'d, T> {
|
||||
pub fn new(peri: impl Peripheral<P = T> + 'd, config: Config) -> Self {
|
||||
into_ref!(peri);
|
||||
|
||||
// Need to check valid pin configuration input
|
||||
// Need to configure pin
|
||||
Self::new_inner(peri, config)
|
||||
}
|
||||
|
||||
fn new_inner(peri: impl Peripheral<P = T> + 'd, config: Config) -> Self {
|
||||
into_ref!(peri);
|
||||
|
||||
T::enable_and_reset();
|
||||
|
||||
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());
|
||||
w.set_sse(config.spread_spectrum);
|
||||
w.set_ssd(config.spread_spectrum_deviation);
|
||||
w.set_sspsc(config.spread_spectrum_prescaler);
|
||||
w.set_pgpsc(config.pulse_generator_prescaler.into());
|
||||
w.set_mcv(config.max_count_value);
|
||||
w.set_syncpol(config.synchro_pin_polarity);
|
||||
w.set_am(config.acquisition_mode)
|
||||
});
|
||||
|
||||
// Set IO configuration
|
||||
// Disable Schmitt trigger hysteresis on all used TSC IOs
|
||||
// T::REGS.iohcr().modify(|w| {
|
||||
// w.
|
||||
// });
|
||||
|
||||
// Set channel and shield IOs
|
||||
// T::REGS.ioccr().modify(|w| {});
|
||||
|
||||
// Set sampling IOs
|
||||
// T::REGS.ioscr().modify(|w| {
|
||||
// w.set_g1_io1(val)
|
||||
// });
|
||||
|
||||
// Set the groups to be acquired
|
||||
// T::REGS.iogcsr().modify(|w| {
|
||||
// w.set_g1e(val);
|
||||
// });
|
||||
|
||||
// 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 {
|
||||
_peri: peri,
|
||||
state: State::Ready,
|
||||
config,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start(&mut self) {
|
||||
self.state = State::Busy;
|
||||
|
||||
// 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);
|
||||
});
|
||||
|
||||
// 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);
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
pub fn stop(&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);
|
||||
});
|
||||
|
||||
// Clear flags
|
||||
T::REGS.icr().modify(|w| {
|
||||
w.set_eoaic(true);
|
||||
w.set_mceic(true);
|
||||
});
|
||||
|
||||
self.state = State::Ready;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
pub fn poll_for_acquisition(&mut self) {
|
||||
while self.get_state() == State::Busy {}
|
||||
}
|
||||
|
||||
pub fn get_state(&mut self) -> State {
|
||||
if self.state == State::Busy {
|
||||
if T::REGS.isr().read().eoaf() {
|
||||
if T::REGS.isr().read().mcef() {
|
||||
self.state = State::Error
|
||||
} else {
|
||||
self.state = State::Ready
|
||||
}
|
||||
}
|
||||
}
|
||||
self.state
|
||||
}
|
||||
|
||||
pub fn group_get_status(&mut self, index: Group) -> GroupStatus {
|
||||
// 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::Seven => T::REGS.iogcsr().read().g7s(),
|
||||
Group::Eight => T::REGS.iogcsr().read().g8s(),
|
||||
};
|
||||
match status {
|
||||
true => GroupStatus::Complete,
|
||||
false => GroupStatus::Ongoing,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn group_get_value(&mut self, index: Group) -> u16 {
|
||||
T::REGS.iogcr(index.into()).read().cnt()
|
||||
}
|
||||
|
||||
// pub fn configure_io()
|
||||
|
||||
pub fn discharge_io(&mut self, status: bool) {
|
||||
// Set the touch sensing IOs in low power mode
|
||||
T::REGS.cr().modify(|w| {
|
||||
w.set_iodef(!status);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Instance> Drop for TSC<'d, T> {
|
||||
fn drop(&mut self) {
|
||||
// Need to figure out what to do with the IOs
|
||||
T::disable();
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait SealedInstance {
|
||||
const REGS: Regs;
|
||||
}
|
||||
|
||||
/// TSC instance trait
|
||||
#[allow(private_bounds)]
|
||||
pub trait Instance: Peripheral<P = Self> + SealedInstance + RccPeripheral {}
|
||||
|
||||
foreach_peripheral!(
|
||||
(tsc, $inst:ident) => {
|
||||
impl SealedInstance for peripherals::$inst {
|
||||
const REGS: Regs = crate::pac::$inst;
|
||||
}
|
||||
|
||||
impl Instance for peripherals::$inst {}
|
||||
};
|
||||
);
|
||||
|
||||
pin_trait!(G1IO1Pin, Instance);
|
||||
pin_trait!(G1IO2Pin, Instance);
|
||||
pin_trait!(G1IO3Pin, Instance);
|
||||
pin_trait!(G1IO4Pin, Instance);
|
||||
pin_trait!(G2IO1Pin, Instance);
|
||||
pin_trait!(G2IO2Pin, Instance);
|
||||
pin_trait!(G2IO3Pin, Instance);
|
||||
pin_trait!(G2IO4Pin, Instance);
|
||||
pin_trait!(G3IO1Pin, Instance);
|
||||
pin_trait!(G3IO2Pin, Instance);
|
||||
pin_trait!(G3IO3Pin, Instance);
|
||||
pin_trait!(G3IO4Pin, Instance);
|
||||
pin_trait!(G4IO1Pin, Instance);
|
||||
pin_trait!(G4IO2Pin, Instance);
|
||||
pin_trait!(G4IO3Pin, Instance);
|
||||
pin_trait!(G4IO4Pin, Instance);
|
||||
pin_trait!(G5IO1Pin, Instance);
|
||||
pin_trait!(G5IO2Pin, Instance);
|
||||
pin_trait!(G5IO3Pin, Instance);
|
||||
pin_trait!(G5IO4Pin, Instance);
|
||||
pin_trait!(G6IO1Pin, Instance);
|
||||
pin_trait!(G6IO2Pin, Instance);
|
||||
pin_trait!(G6IO3Pin, Instance);
|
||||
pin_trait!(G6IO4Pin, Instance);
|
||||
pin_trait!(G7IO1Pin, Instance);
|
||||
pin_trait!(G7IO2Pin, Instance);
|
||||
pin_trait!(G7IO3Pin, Instance);
|
||||
pin_trait!(G7IO4Pin, Instance);
|
||||
pin_trait!(G8IO1Pin, Instance);
|
||||
pin_trait!(G8IO2Pin, Instance);
|
||||
pin_trait!(G8IO3Pin, Instance);
|
||||
pin_trait!(G8IO4Pin, Instance);
|
Loading…
Reference in New Issue
Block a user