move to updated API

This commit is contained in:
2025-04-16 14:35:57 +02:00
parent dfe34e965f
commit 121b467fb9
49 changed files with 751 additions and 986 deletions

View File

@ -2,24 +2,13 @@
//!
//! This also includes functionality to enable the peripheral clocks
use crate::time::Hertz;
use crate::PeripheralSelect;
use cortex_m::interrupt::{self, Mutex};
use once_cell::unsync::OnceCell;
static SYS_CLOCK: Mutex<OnceCell<Hertz>> = Mutex::new(OnceCell::new());
pub use vorago_shared_periphs::gpio::FilterClkSel;
pub use vorago_shared_periphs::sysconfig::{disable_peripheral_clock, enable_peripheral_clock};
#[derive(Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum FilterClkSel {
SysClk = 0,
Clk1 = 1,
Clk2 = 2,
Clk3 = 3,
Clk4 = 4,
Clk5 = 5,
Clk6 = 6,
Clk7 = 7,
}
static SYS_CLOCK: Mutex<OnceCell<Hertz>> = Mutex::new(OnceCell::new());
/// The Vorago in powered by an external clock which might have different frequencies.
/// The clock can be set here so it can be used by other software components as well.
@ -61,5 +50,3 @@ pub fn set_clk_div_register(syscfg: &mut va108xx::Sysconfig, clk_sel: FilterClkS
}
}
}
pub use vorago_shared_periphs::sysconfig::{disable_peripheral_clock, enable_peripheral_clock};

View File

@ -307,7 +307,7 @@ impl<I2C> I2cBase<I2C> {
impl<I2c: Instance> I2cBase<I2c> {
pub fn new(
sysclk: Hertz,
sys_clk: Hertz,
i2c: I2c,
speed_mode: I2cSpeed,
ms_cfg: Option<&MasterConfig>,
@ -315,10 +315,7 @@ impl<I2c: Instance> I2cBase<I2c> {
) -> Result<Self, ClockTooSlowForFastI2cError> {
enable_peripheral_clock(I2c::PERIPH_SEL);
let mut i2c_base = I2cBase {
i2c,
sys_clk: sysclk.into(),
};
let mut i2c_base = I2cBase { i2c, sys_clk };
if let Some(ms_cfg) = ms_cfg {
i2c_base.cfg_master(ms_cfg);
}

View File

@ -1,6 +1,13 @@
pub use vorago_shared_periphs::gpio::{Pin, PinId, PinMarker, Port};
use vorago_shared_periphs::sysconfig::reset_peripheral_for_cycles;
use crate::{sysconfig::reset_peripheral_for_cycles, PeripheralSelect};
pub use crate::gpio::{Pin, PinId, PinIdProvider, Port};
use crate::sealed::Sealed;
use crate::PeripheralSelect;
pub trait PinMarker: Sealed {
const ID: PinId;
}
macro_rules! pin_id {
($Id:ident, $Port:path, $num:literal) => {
@ -11,14 +18,18 @@ macro_rules! pin_id {
pub enum $Id {}
impl $crate::sealed::Sealed for $Id {}
impl PinMarker for $Id {
const ID: PinId = PinId::new($Port, $num);
impl PinIdProvider for $Id {
const ID: PinId = PinId::new_unchecked($Port, $num);
}
impl PinMarker for Pin<$Id> {
const ID: PinId = $Id::ID;
}
}
};
}
impl<I: PinMarker + crate::sealed::Sealed> crate::sealed::Sealed for Pin<I> {}
impl<I: PinIdProvider + Sealed> Sealed for Pin<I> {}
pin_id!(Pa0, Port::A, 0);
pin_id!(Pa1, Port::A, 1);

View File

@ -8,10 +8,11 @@
use core::convert::Infallible;
use core::marker::PhantomData;
use vorago_shared_periphs::PeripheralSelect;
use crate::clock::enable_peripheral_clock;
use crate::pac;
use crate::time::Hertz;
use crate::timer::{TimId, TimPeripheralMarker, TimPin, TimRegInterface};
use crate::timer::{TimId, TimMarker, TimPin, TimRegInterface};
const DUTY_MAX: u16 = u16::MAX;
@ -56,9 +57,8 @@ pub struct PwmPin<Mode = PwmA> {
impl<Mode> PwmPin<Mode> {
/// Create a new strongly typed PWM pin
pub fn new<Pin: TimPin, Tim: TimPeripheralMarker + TimRegInterface>(
sys_cfg: &mut pac::Sysconfig,
sys_clk: impl Into<Hertz> + Copy,
pub fn new<Pin: TimPin, Tim: TimMarker + TimRegInterface>(
sys_clk: Hertz,
pin_and_tim: (Pin, Tim),
initial_period: impl Into<Hertz> + Copy,
) -> Result<Self, TimMissmatchError> {
@ -74,12 +74,13 @@ impl<Mode> PwmPin<Mode> {
current_lower_limit: 0,
current_period: initial_period.into(),
current_rst_val: 0,
sys_clk: sys_clk.into(),
sys_clk,
mode: PhantomData,
};
enable_peripheral_clock(crate::clock::PeripheralClocks::Gpio);
enable_peripheral_clock(crate::clock::PeripheralClocks::Ioconfig);
sys_cfg
enable_peripheral_clock(PeripheralSelect::Gpio);
enable_peripheral_clock(PeripheralSelect::Ioconfig);
let syscfg = unsafe { va108xx::Sysconfig::steal() };
syscfg
.tim_clk_enable()
.modify(|r, w| unsafe { w.bits(r.bits() | pin_and_tim.1.mask_32()) });
pin.enable_pwm_a();

View File

@ -9,13 +9,22 @@
//! - [Blocking SPI example](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/examples/simple/examples/spi.rs)
//! - [REB1 ADC example](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/vorago-reb1/examples/max11519-adc.rs)
//! - [REB1 EEPROM library](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/vorago-reb1/src/m95m01.rs)
use crate::{clock::enable_peripheral_clock, pac, time::Hertz, PeripheralSelect};
use crate::{
clock::enable_peripheral_clock, pac, pins::PinMarker, sealed::Sealed, time::Hertz,
PeripheralSelect,
};
use core::{convert::Infallible, fmt::Debug, marker::PhantomData, ops::Deref};
use embedded_hal::spi::{Mode, MODE_0};
use pins::{HwCsProvider, PinMiso, PinMosi, PinSck};
use vorago_shared_periphs::gpio::IoPeriphPin;
pub mod pins;
pub fn configure_pin_as_hw_cs_pin<P: PinMarker + HwCsProvider>(_pin: P) -> HwChipSelectId {
IoPeriphPin::new(P::ID, P::FUN_SEL, None);
P::CS_ID
}
//==================================================================================================
// Defintions
//==================================================================================================
@ -41,7 +50,7 @@ pub enum HwChipSelectId {
Id7 = 7,
}
#[derive(Debug)]
#[derive(Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum SpiId {
A,
@ -80,7 +89,7 @@ pub type SpiRegBlock = pac::spia::RegisterBlock;
/// Common trait implemented by all PAC peripheral access structures. The register block
/// format is the same for all SPI blocks.
pub trait SpiPeripheralMarker: Deref<Target = SpiRegBlock> {
pub trait SpiMarker: Deref<Target = SpiRegBlock> + Sealed {
const ID: SpiId;
const PERIPH_SEL: PeripheralSelect;
@ -92,7 +101,7 @@ pub trait SpiPeripheralMarker: Deref<Target = SpiRegBlock> {
}
}
impl SpiPeripheralMarker for pac::Spia {
impl SpiMarker for pac::Spia {
const ID: SpiId = SpiId::A;
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Spi0;
@ -101,8 +110,9 @@ impl SpiPeripheralMarker for pac::Spia {
Self::ptr()
}
}
impl Sealed for pac::Spia {}
impl SpiPeripheralMarker for pac::Spib {
impl SpiMarker for pac::Spib {
const ID: SpiId = SpiId::B;
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Spi1;
@ -111,8 +121,9 @@ impl SpiPeripheralMarker for pac::Spib {
Self::ptr()
}
}
impl Sealed for pac::Spib {}
impl SpiPeripheralMarker for pac::Spic {
impl SpiMarker for pac::Spic {
const ID: SpiId = SpiId::C;
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Spi2;
@ -121,6 +132,7 @@ impl SpiPeripheralMarker for pac::Spic {
Self::ptr()
}
}
impl Sealed for pac::Spic {}
//==================================================================================================
// Config
@ -134,17 +146,6 @@ pub trait TransferConfigProvider {
fn hw_cs_id(&self) -> u8;
}
/*
/// This struct contains all configuration parameter which are transfer specific
/// and might change for transfers to different SPI slaves
#[derive(Copy, Clone, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct TransferConfigWithHwcs<HwCs> {
pub hw_cs: Option<HwCs>,
pub cfg: TransferConfig,
}
*/
/// Type erased variant of the transfer configuration. This is required to avoid generics in
/// the SPI constructor.
#[derive(Copy, Clone, Debug)]
@ -163,80 +164,26 @@ pub struct TransferConfig {
pub hw_cs: Option<HwChipSelectId>,
}
/*
impl TransferConfigWithHwcs<NoneT> {
pub fn new_no_hw_cs(
impl TransferConfig {
pub fn new_with_hw_cs(
clk_cfg: Option<SpiClkConfig>,
mode: Option<Mode>,
blockmode: bool,
bmstall: bool,
sod: bool,
hw_cs_id: HwChipSelectId,
) -> Self {
TransferConfigWithHwcs {
hw_cs: None,
cfg: TransferConfig {
clk_cfg,
mode,
sod,
blockmode,
bmstall,
hw_cs: HwChipSelectId::Invalid,
},
TransferConfig {
clk_cfg,
mode,
sod,
blockmode,
bmstall,
hw_cs: Some(hw_cs_id),
}
}
}
impl<HwCs: HwCsProvider> TransferConfigWithHwcs<HwCs> {
pub fn new(
clk_cfg: Option<SpiClkConfig>,
mode: Option<Mode>,
hw_cs: Option<HwCs>,
blockmode: bool,
bmstall: bool,
sod: bool,
) -> Self {
TransferConfigWithHwcs {
hw_cs,
cfg: TransferConfig {
clk_cfg,
mode,
sod,
blockmode,
bmstall,
hw_cs: HwCs::CS_ID,
},
}
}
pub fn downgrade(self) -> TransferConfig {
self.cfg
}
}
impl<HwCs: HwCsProvider> TransferConfigProvider for TransferConfigWithHwcs<HwCs> {
/// Slave Output Disable
fn sod(&mut self, sod: bool) {
self.cfg.sod = sod;
}
fn blockmode(&mut self, blockmode: bool) {
self.cfg.blockmode = blockmode;
}
fn mode(&mut self, mode: Mode) {
self.cfg.mode = Some(mode);
}
fn clk_cfg(&mut self, clk_cfg: SpiClkConfig) {
self.cfg.clk_cfg = Some(clk_cfg);
}
fn hw_cs_id(&self) -> u8 {
HwCs::CS_ID as u8
}
}
*/
/// Configuration options for the whole SPI bus. See Programmer Guide p.92 for more details
#[derive(Debug, Copy, Clone)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
@ -373,25 +320,6 @@ pub trait SpiLowLevel {
fn read_fifo_unchecked(&mut self) -> u32;
}
pub struct Spi<Word = u8> {
id: SpiId,
reg_block: *mut SpiRegBlock,
cfg: SpiConfig,
sys_clk: Hertz,
/// Fill word for read-only SPI transactions.
pub fill_word: Word,
blockmode: bool,
bmstall: bool,
word: PhantomData<Word>,
}
/*
pub struct Spi<, Pins, Word = u8> {
inner: SpiBase<SpiInstance, Word>,
pins: Pins,
}
*/
#[inline(always)]
pub fn mode_to_cpo_cph_bit(mode: embedded_hal::spi::Mode) -> (bool, bool) {
match mode {
@ -510,28 +438,69 @@ pub fn clk_div_for_target_clock(
Some(rounded_div as u16)
}
#[derive(Debug, thiserror::Error)]
#[error("peripheral or peripheral pin ID is not consistent")]
pub struct SpiIdMissmatchError;
/// SPI peripheral driver structure.
pub struct Spi<Word = u8> {
id: SpiId,
reg_block: *mut SpiRegBlock,
cfg: SpiConfig,
sys_clk: Hertz,
/// Fill word for read-only SPI transactions.
fill_word: Word,
blockmode: bool,
bmstall: bool,
word: PhantomData<Word>,
}
impl<Word: WordProvider> Spi<Word>
where
<Word as TryFrom<u32>>::Error: core::fmt::Debug,
{
/// Create a new SPI struct
///
/// You can delete the pin type information by calling the
/// [`downgrade`](Self::downgrade) function
/// Create a new SPI struct.
///
/// ## Arguments
/// * `syscfg` - Can be passed optionally to enable the peripheral clock
/// * `sys_clk` - System clock
/// * `spi` - SPI bus to use
/// * `pins` - Pins to be used for SPI transactions. These pins are consumed
/// to ensure the pins can not be used for other purposes anymore
/// * `spi_cfg` - Configuration specific to the SPI bus
pub fn new<SpiI: SpiPeripheralMarker, Sck: PinSck, Miso: PinMiso, Mosi: PinMosi>(
sys_clk: impl Into<Hertz>,
pub fn new_for_rom<SpiI: SpiMarker>(
sys_clk: Hertz,
spi: SpiI,
spi_cfg: SpiConfig,
) -> Result<Self, SpiIdMissmatchError> {
if SpiI::ID != SpiId::C {
return Err(SpiIdMissmatchError);
}
Ok(Self::new_generic(sys_clk, spi, spi_cfg))
}
/// Create a new SPI struct.
///
/// ## Arguments
/// * `sys_clk` - System clock
/// * `spi` - SPI bus to use
/// * `pins` - Pins to be used for SPI transactions. These pins are consumed
/// to ensure the pins can not be used for other purposes anymore
/// * `spi_cfg` - Configuration specific to the SPI bus
pub fn new<SpiI: SpiMarker, Sck: PinSck, Miso: PinMiso, Mosi: PinMosi>(
sys_clk: Hertz,
spi: SpiI,
_pins: (Sck, Miso, Mosi),
spi_cfg: SpiConfig,
) -> Self {
) -> Result<Self, SpiIdMissmatchError> {
if SpiI::ID != Sck::SPI_ID || SpiI::ID != Miso::SPI_ID || SpiI::ID != Mosi::SPI_ID {
return Err(SpiIdMissmatchError);
}
IoPeriphPin::new(Sck::ID, Sck::FUN_SEL, None);
IoPeriphPin::new(Miso::ID, Miso::FUN_SEL, None);
IoPeriphPin::new(Mosi::ID, Mosi::FUN_SEL, None);
Ok(Self::new_generic(sys_clk, spi, spi_cfg))
}
pub fn new_generic<SpiI: SpiMarker>(sys_clk: Hertz, spi: SpiI, spi_cfg: SpiConfig) -> Self {
enable_peripheral_clock(SpiI::PERIPH_SEL);
let (cpo_bit, cph_bit) = mode_to_cpo_cph_bit(spi_cfg.init_mode);
spi.ctrl0().write(|w| {
@ -568,7 +537,7 @@ where
id: SpiI::ID,
reg_block: spi.reg_block(),
cfg: spi_cfg,
sys_clk: sys_clk.into(),
sys_clk,
fill_word: Default::default(),
bmstall: spi_cfg.bmstall,
blockmode: spi_cfg.blockmode,
@ -596,6 +565,10 @@ where
.write(|w| unsafe { w.bits(cfg.prescale_val as u32) });
}
pub fn set_fill_word(&mut self, fill_word: Word) {
self.fill_word = fill_word;
}
#[inline]
pub fn cfg_clock_from_div(&mut self, div: u16) -> Result<(), SpiClkConfigError> {
let val = spi_clk_config_from_div(div)?;
@ -633,6 +606,10 @@ where
}
/// Configure the hardware chip select given a hardware chip select ID.
///
/// The pin also needs to be configured to be used as a HW CS pin. This can be done
/// by using the [configure_pin_as_hw_cs_pin] function which also returns the
/// corresponding [HwChipSelectId].
#[inline]
pub fn cfg_hw_cs(&mut self, hw_cs: HwChipSelectId) {
self.reg_block_mut().ctrl1().modify(|_, w| {
@ -644,13 +621,6 @@ where
});
}
/// Configure the hardware chip select given a physical hardware CS pin.
#[inline]
pub fn cfg_hw_cs_with_pin<HwCs: HwCsProvider>(&mut self, _: &HwCs) {
// TODO: Error handling.
self.cfg_hw_cs(HwCs::CS_ID);
}
/// Disables the hardware chip select functionality. This can be used when performing
/// external chip select handling, for example with GPIO pins.
#[inline]

View File

@ -1,32 +1,33 @@
use vorago_shared_periphs::gpio::{PinId, PinIdProvider};
use vorago_shared_periphs::FunSel;
use crate::{
pins::{
Pa10, Pa11, Pa12, Pa13, Pa14, Pa15, Pa16, Pa17, Pa18, Pa19, Pa20, Pa21, Pa22, Pa23, Pa24,
Pa25, Pa26, Pa27, Pa28, Pa29, Pa30, Pa31, Pb0, Pb1, Pb10, Pb11, Pb12, Pb13, Pb14, Pb15,
Pb16, Pb17, Pb18, Pb19, Pb2, Pb22, Pb23, Pb3, Pb4, Pb5, Pb6, Pb7, Pb8, Pb9, Pin,
Pb16, Pb17, Pb18, Pb19, Pb2, Pb22, Pb23, Pb3, Pb4, Pb5, Pb6, Pb7, Pb8, Pb9, Pin, PinMarker,
},
sealed::Sealed,
};
use super::{HwChipSelectId, SpiId};
pub trait PinSck: Sealed {
pub trait PinSck: PinMarker {
const SPI_ID: SpiId;
const FUN_SEL: FunSel;
}
pub trait PinMosi: Sealed {
pub trait PinMosi: PinMarker {
const SPI_ID: SpiId;
const FUN_SEL: FunSel;
}
pub trait PinMiso: Sealed {
pub trait PinMiso: PinMarker {
const SPI_ID: SpiId;
const FUN_SEL: FunSel;
}
pub trait HwCsProvider: Sealed {
pub trait HwCsProvider: PinMarker {
const SPI_ID: SpiId;
const FUN_SEL: FunSel;
const CS_ID: HwChipSelectId;
@ -48,7 +49,7 @@ macro_rules! hw_cs_multi_pin {
// name of the newtype wrapper struct
$name:ident,
// Pb0
$pin_id:path,
$pin_id:ident,
// SpiId::B
$spi_id:path,
// FunSel::Sel1
@ -71,6 +72,10 @@ macro_rules! hw_cs_multi_pin {
impl Sealed for $name {}
impl PinMarker for $name {
const ID: PinId = <$pin_id as PinIdProvider>::ID;
}
impl HwCsProvider for $name {
const SPI_ID: SpiId = $spi_id;
const FUN_SEL: FunSel = $fun_sel;
@ -185,7 +190,7 @@ impl PinMosi for Pin<Pa19> {
const SPI_ID: SpiId = SpiId::B;
const FUN_SEL: FunSel = FunSel::Sel2;
}
impl PinMosi for Pin<Pa18> {
impl PinMiso for Pin<Pa18> {
const SPI_ID: SpiId = SpiId::B;
const FUN_SEL: FunSel = FunSel::Sel2;
}
@ -202,7 +207,7 @@ impl PinMosi for Pin<Pb18> {
const SPI_ID: SpiId = SpiId::B;
const FUN_SEL: FunSel = FunSel::Sel1;
}
impl PinMosi for Pin<Pb17> {
impl PinMiso for Pin<Pb17> {
const SPI_ID: SpiId = SpiId::B;
const FUN_SEL: FunSel = FunSel::Sel1;
}
@ -215,7 +220,7 @@ impl PinMosi for Pin<Pb4> {
const SPI_ID: SpiId = SpiId::B;
const FUN_SEL: FunSel = FunSel::Sel1;
}
impl PinMosi for Pin<Pb3> {
impl PinMiso for Pin<Pb3> {
const SPI_ID: SpiId = SpiId::B;
const FUN_SEL: FunSel = FunSel::Sel1;
}
@ -330,6 +335,7 @@ hw_cs_multi_pin!(
// SPIC
/*
// Dummy pin defintion for the ROM SCK.
pub struct RomSck;
// Dummy pin defintion for the ROM MOSI.
@ -358,6 +364,7 @@ impl PinMiso for RomMiso {
const FUN_SEL: FunSel = FunSel::Sel0;
}
impl Sealed for RomCs {}
*/
hw_cs_pins!(
SpiId::C,
@ -408,9 +415,11 @@ hw_cs_multi_pin!(
HwChipSelectId::Id4
);
/*
impl HwCsProvider for RomCs {
const CS_ID: HwChipSelectId = HwChipSelectId::Id0;
const SPI_ID: SpiId = SpiId::C;
/// Function select does not make sense here, just select default value.
const FUN_SEL: FunSel = FunSel::Sel0;
}
*/

View File

@ -1,5 +1,3 @@
use crate::PeripheralSelect;
#[derive(PartialEq, Eq, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct InvalidCounterResetVal(pub(crate) ());
@ -40,26 +38,6 @@ pub fn disable_ram_scrubbing() {
syscfg.ram_scrub().write(|w| unsafe { w.bits(0) });
}
#[inline]
pub fn assert_peripheral_reset(periph_sel: PeripheralSelect) {
let syscfg = unsafe { va108xx::Sysconfig::steal() };
syscfg
.peripheral_reset()
.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << periph_sel as u8)) });
}
#[inline]
pub fn deassert_peripheral_reset(periph_sel: PeripheralSelect) {
let syscfg = unsafe { va108xx::Sysconfig::steal() };
syscfg
.peripheral_reset()
.modify(|r, w| unsafe { w.bits(r.bits() | (1 << periph_sel as u8)) });
}
pub fn reset_peripheral_for_cycles(periph_sel: PeripheralSelect, cycles: u32) {
assert_peripheral_reset(periph_sel);
cortex_m::asm::delay(cycles);
deassert_peripheral_reset(periph_sel);
}
pub use vorago_shared_periphs::sysconfig::{disable_peripheral_clock, enable_peripheral_clock};
pub use vorago_shared_periphs::sysconfig::{
assert_peripheral_reset, disable_peripheral_clock, enable_peripheral_clock,
};

View File

@ -16,17 +16,13 @@ use crate::{
sealed::Sealed,
time::Hertz,
};
use core::cell::Cell;
use critical_section::Mutex;
use fugit::RateExtU32;
use vorago_shared_periphs::{
gpio::{Pin, PinMarker},
gpio::{Pin, PinIdProvider},
ioconfig::regs::FunSel,
Port,
};
pub static MS_COUNTER: Mutex<Cell<u32>> = Mutex::new(Cell::new(0));
/// Get the peripheral block of a TIM peripheral given the index.
///
/// This function panics if the given index is greater than 23.
@ -170,17 +166,23 @@ pub trait TimPin: Sealed {
const TIM_ID: TimId;
}
pub trait TimPeripheralMarker: Sealed {
pub trait TimMarker: Sealed {
// TIM ID ranging from 0 to 23 for 24 TIM peripherals
const ID: TimId;
}
macro_rules! tim_marker {
($TIMX:path, $ID:expr) => {
impl TimPeripheralMarker for $TIMX {
impl TimMarker for $TIMX {
const ID: TimId = TimId($ID);
}
unsafe impl TimRegInterface for $TIMX {
fn raw_id(&self) -> u8 {
Self::ID.0
}
}
impl Sealed for $TIMX {}
};
}
@ -210,13 +212,13 @@ tim_marker!(pac::Tim21, 21);
tim_marker!(pac::Tim22, 22);
tim_marker!(pac::Tim23, 23);
pub trait ValidTimAndPin<Pin: TimPin, Tim: TimPeripheralMarker>: Sealed {}
pub trait ValidTimAndPin<Pin: TimPin, Tim: TimMarker>: Sealed {}
macro_rules! pin_and_tim {
($Px:ident, $FunSel:path, $ID:expr) => {
impl TimPin for Pin<$Px>
where
$Px: PinMarker,
$Px: PinIdProvider,
{
const PORT: Port = $Px::ID.port();
const OFFSET: usize = $Px::ID.offset();
@ -368,7 +370,7 @@ unsafe impl TimRegInterface for CountdownTimer {
impl CountdownTimer {
/// Configures a TIM peripheral as a periodic count down timer
pub fn new<Tim: TimPeripheralMarker>(sys_clk: Hertz, _tim: Tim) -> Self {
pub fn new<Tim: TimMarker>(sys_clk: Hertz, _tim: Tim) -> Self {
enable_tim_clk(Tim::ID.raw_id());
let cd_timer = CountdownTimer {
tim: Tim::ID,
@ -593,6 +595,10 @@ impl CountdownTimer {
}
}
//==================================================================================================
// Delay implementations
//==================================================================================================
//
impl embedded_hal::delay::DelayNs for CountdownTimer {
fn delay_ns(&mut self, ns: u32) {
let ticks = (u64::from(ns)) * (u64::from(self.sys_clk.raw())) / 1_000_000_000;
@ -647,59 +653,6 @@ impl embedded_hal::delay::DelayNs for CountdownTimer {
}
}
pub fn set_up_ms_delay_provider(sys_clk: Hertz, tim: impl TimPeripheralMarker) -> CountdownTimer {
let mut provider = CountdownTimer::new(sys_clk, tim);
provider.start(1000.Hz());
provider
}
/// This function can be called in a specified interrupt handler to increment
/// the MS counter
pub fn default_ms_irq_handler() {
critical_section::with(|cs| {
let mut ms = MS_COUNTER.borrow(cs).get();
ms += 1;
MS_COUNTER.borrow(cs).set(ms);
});
}
/// Get the current MS tick count
pub fn get_ms_ticks() -> u32 {
critical_section::with(|cs| MS_COUNTER.borrow(cs).get())
}
//==================================================================================================
// Delay implementations
//==================================================================================================
/*
pub struct DelayMs(CountdownTimer<pac::Tim0>);
impl DelayMs {
pub fn new(timer: CountdownTimer<pac::Tim0>) -> Option<Self> {
if timer.curr_freq() != Hertz::from_raw(1000) || !timer.listening() {
return None;
}
Some(Self(timer))
}
}
/// This assumes that the user has already set up a MS tick timer in TIM0 as a system tick
/// with [`set_up_ms_delay_provider`]
impl embedded_hal::delay::DelayNs for DelayMs {
fn delay_ns(&mut self, ns: u32) {
let ns_as_ms = ns / 1_000_000;
if self.0.curr_freq() != Hertz::from_raw(1000) || !self.0.listening() {
return;
}
let start_time = get_ms_ticks();
while get_ms_ticks() - start_time < ns_as_ms {
cortex_m::asm::nop();
}
}
}
*/
#[inline(always)]
pub fn enable_tim_clk(idx: u8) {
let syscfg = unsafe { va108xx::Sysconfig::steal() };

View File

@ -14,7 +14,10 @@
//! - [Flashloader exposing a CCSDS interface via UART](https://egit.irs.uni-stuttgart.de/rust/va108xx-rs/src/branch/main/flashloader)
use core::{convert::Infallible, ops::Deref};
use fugit::RateExtU32;
use vorago_shared_periphs::{gpio::Pin, FunSel, InterruptConfig};
use vorago_shared_periphs::{
gpio::{IoPeriphPin, Pin},
FunSel, InterruptConfig,
};
use crate::{
clock::enable_peripheral_clock,
@ -22,7 +25,7 @@ use crate::{
pac::{self, uarta as uart_base},
pins::{
Pa16, Pa17, Pa18, Pa19, Pa2, Pa26, Pa27, Pa3, Pa30, Pa31, Pa8, Pa9, Pb18, Pb19, Pb20, Pb21,
Pb22, Pb23, Pb6, Pb7, Pb8, Pb9,
Pb22, Pb23, Pb6, Pb7, Pb8, Pb9, PinMarker,
},
time::Hertz,
PeripheralSelect,
@ -55,11 +58,11 @@ impl UartId {
// Type-Level support
//==================================================================================================
pub trait TxPin {
pub trait TxPin: PinMarker {
const UART_ID: UartId;
const FUN_SEL: FunSel;
}
pub trait RxPin {
pub trait RxPin: PinMarker {
const UART_ID: UartId;
const FUN_SEL: FunSel;
}
@ -557,6 +560,8 @@ impl Uart {
if UartI::ID != TxPinI::UART_ID || UartI::ID != RxPinI::UART_ID {
return Err(UartIdMissmatchError);
}
IoPeriphPin::new(TxPinI::ID, TxPinI::FUN_SEL, None);
IoPeriphPin::new(RxPinI::ID, TxPinI::FUN_SEL, None);
crate::clock::enable_peripheral_clock(UartI::PERIPH_SEL);
let reg_block = unsafe { UartI::reg_block() };

View File

@ -411,10 +411,10 @@ impl<const N: usize> embedded_io_async::Read for RxAsyncOverwriting<N> {
critical_section::with(|cs| {
let queue = inner.shared_consumer.borrow(cs);
if queue.borrow().as_ref().unwrap().len() == 0 {
RX_HAS_DATA[id as usize].store(false, Ordering::Relaxed);
RX_HAS_DATA[id].store(false, Ordering::Relaxed);
}
});
let _guard = ActiveReadGuard(id as usize);
let _guard = ActiveReadGuard(id);
let mut handle_data_in_queue = |inner: &mut RxAsyncOverwritingInner<N>| {
critical_section::with(|cs| {
let mut consumer_ref = inner.shared_consumer.borrow(cs).borrow_mut();