improve typing support for UART, PWM, SPI #3
@@ -65,28 +65,26 @@ async fn main(spawner: Spawner) {
|
||||
let tx_uart_a = porta.pa9;
|
||||
let rx_uart_a = porta.pa8;
|
||||
|
||||
let uarta = uart::Uart::new_with_interrupt(
|
||||
let uarta = uart::Uart::new_with_interrupt_uart0(
|
||||
dp.uarta,
|
||||
tx_uart_a,
|
||||
rx_uart_a,
|
||||
50.MHz(),
|
||||
115200.Hz().into(),
|
||||
InterruptConfig::new(pac::Interrupt::OC2, true, true),
|
||||
)
|
||||
.unwrap();
|
||||
);
|
||||
|
||||
let tx_uart_b = porta.pa3;
|
||||
let rx_uart_b = porta.pa2;
|
||||
|
||||
let uartb = uart::Uart::new_with_interrupt(
|
||||
let uartb = uart::Uart::new_with_interrupt_uart1(
|
||||
dp.uartb,
|
||||
tx_uart_b,
|
||||
rx_uart_b,
|
||||
50.MHz(),
|
||||
115200.Hz().into(),
|
||||
InterruptConfig::new(pac::Interrupt::OC3, true, true),
|
||||
)
|
||||
.unwrap();
|
||||
);
|
||||
let (mut tx_uart_a, rx_uart_a) = uarta.split();
|
||||
let (tx_uart_b, rx_uart_b) = uartb.split();
|
||||
let (prod_uart_a, cons_uart_a) = QUEUE_UART_A.take().split();
|
||||
|
||||
@@ -53,15 +53,14 @@ async fn main(_spawner: Spawner) {
|
||||
let tx = porta.pa9;
|
||||
let rx = porta.pa8;
|
||||
|
||||
let uarta = uart::Uart::new_with_interrupt(
|
||||
let uarta = uart::Uart::new_with_interrupt_uart0(
|
||||
dp.uarta,
|
||||
tx,
|
||||
rx,
|
||||
50.MHz(),
|
||||
115200.Hz().into(),
|
||||
InterruptConfig::new(pac::Interrupt::OC2, true, true),
|
||||
)
|
||||
.unwrap();
|
||||
);
|
||||
let (tx, _rx) = uarta.split();
|
||||
let mut async_tx = TxAsync::new(tx);
|
||||
let mut ticker = Ticker::every(Duration::from_secs(1));
|
||||
|
||||
@@ -53,15 +53,14 @@ mod app {
|
||||
let tx = gpioa.pa9;
|
||||
let rx = gpioa.pa8;
|
||||
|
||||
let irq_uart = uart::Uart::new_with_interrupt(
|
||||
let irq_uart = uart::Uart::new_with_interrupt_uart0(
|
||||
dp.uarta,
|
||||
tx,
|
||||
rx,
|
||||
SYSCLK_FREQ,
|
||||
115200.Hz().into(),
|
||||
InterruptConfig::new(pac::Interrupt::OC3, true, true),
|
||||
)
|
||||
.unwrap();
|
||||
);
|
||||
let (tx, rx) = irq_uart.split();
|
||||
let mut rx = rx.into_rx_with_irq();
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ fn main() -> ! {
|
||||
defmt::println!("-- VA108xx PWM example application--");
|
||||
let dp = pac::Peripherals::take().unwrap();
|
||||
let pinsa = PinsA::new(dp.porta);
|
||||
let mut pwm = pwm::PwmPin::new(pinsa.pa3, dp.tim3, 50.MHz(), 10.Hz()).unwrap();
|
||||
let mut pwm = pwm::PwmPin::new_with_tim3(pinsa.pa3, dp.tim3, 50.MHz(), 10.Hz());
|
||||
let mut delay = CountdownTimer::new(dp.tim0, 50.MHz());
|
||||
let mut current_duty_cycle = 0.0;
|
||||
pwm.set_duty_cycle(get_duty_from_percent(current_duty_cycle))
|
||||
|
||||
@@ -59,19 +59,19 @@ fn main() -> ! {
|
||||
let mut spi = match SPI_BUS_SEL {
|
||||
SpiBusSelect::SpiAPortA => {
|
||||
let (sck, mosi, miso) = (pinsa.pa31, pinsa.pa30, pinsa.pa29);
|
||||
let mut spia = Spi::new(dp.spia, (sck, miso, mosi), spi_cfg).unwrap();
|
||||
let mut spia = Spi::new_for_spi0(dp.spia, (sck, miso, mosi), spi_cfg);
|
||||
spia.set_fill_word(FILL_WORD);
|
||||
spia
|
||||
}
|
||||
SpiBusSelect::SpiAPortB => {
|
||||
let (sck, mosi, miso) = (pinsb.pb9, pinsb.pb8, pinsb.pb7);
|
||||
let mut spia = Spi::new(dp.spia, (sck, miso, mosi), spi_cfg).unwrap();
|
||||
let mut spia = Spi::new_for_spi0(dp.spia, (sck, miso, mosi), spi_cfg);
|
||||
spia.set_fill_word(FILL_WORD);
|
||||
spia
|
||||
}
|
||||
SpiBusSelect::SpiBPortB => {
|
||||
let (sck, mosi, miso) = (pinsb.pb5, pinsb.pb4, pinsb.pb3);
|
||||
let mut spib = Spi::new(dp.spib, (sck, miso, mosi), spi_cfg).unwrap();
|
||||
let mut spib = Spi::new_for_spi1(dp.spib, (sck, miso, mosi), spi_cfg);
|
||||
spib.set_fill_word(FILL_WORD);
|
||||
spib
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ fn main() -> ! {
|
||||
let tx = gpioa.pa9;
|
||||
let rx = gpioa.pa8;
|
||||
let uart =
|
||||
uart::Uart::new_without_interrupt(dp.uarta, tx, rx, 50.MHz(), 115200.Hz().into()).unwrap();
|
||||
uart::Uart::new_without_interrupt_uart0(dp.uarta, tx, rx, 50.MHz(), 115200.Hz().into());
|
||||
|
||||
let (mut tx, mut rx) = uart.split();
|
||||
writeln!(tx, "Hello World\r").unwrap();
|
||||
|
||||
@@ -116,15 +116,14 @@ mod app {
|
||||
let tx = gpioa.pa9;
|
||||
let rx = gpioa.pa8;
|
||||
|
||||
let irq_uart = uart::Uart::new_with_interrupt(
|
||||
let irq_uart = uart::Uart::new_with_interrupt_uart0(
|
||||
dp.uarta,
|
||||
tx,
|
||||
rx,
|
||||
SYSCLK_FREQ,
|
||||
UART_BAUDRATE.Hz().into(),
|
||||
InterruptConfig::new(pac::Interrupt::OC0, true, true),
|
||||
)
|
||||
.unwrap();
|
||||
);
|
||||
let (tx, rx) = irq_uart.split();
|
||||
// Unwrap is okay, we explicitely set the interrupt ID.
|
||||
let mut rx = rx.into_rx_with_irq();
|
||||
|
||||
@@ -46,7 +46,7 @@ fn main() -> ! {
|
||||
)
|
||||
.mode(MODE_3)
|
||||
.slave_output_disable(true);
|
||||
let mut spi = Spi::new(dp.spib, (sck, miso, mosi), spi_cfg).unwrap();
|
||||
let mut spi = Spi::new_for_spi1(dp.spib, (sck, miso, mosi), spi_cfg);
|
||||
spi.cfg_hw_cs(hw_cs_id);
|
||||
|
||||
let mut tx_rx_buf: [u8; 3] = [0; 3];
|
||||
|
||||
@@ -132,7 +132,7 @@ fn main() -> ! {
|
||||
Output::new(pinsa.pa16, PinState::Low);
|
||||
|
||||
let hw_cs_id = configure_pin_as_hw_cs_pin(pinsa.pa17);
|
||||
let spi = Spi::new(dp.spib, (sck, miso, mosi), spi_cfg).unwrap();
|
||||
let spi = Spi::new_for_spi1(dp.spib, (sck, miso, mosi), spi_cfg);
|
||||
|
||||
let delay_spi = CountdownTimer::new(dp.tim1, SYS_CLK);
|
||||
let spi_with_hwcs = SpiWithHwCs::new(spi, hw_cs_id, delay_spi);
|
||||
|
||||
@@ -64,7 +64,7 @@ pub struct PageBoundaryExceededError;
|
||||
|
||||
impl M95M01 {
|
||||
pub fn new(spi: pac::Spic, clk_config: SpiClockConfig) -> Self {
|
||||
let spi = RomSpi::new_for_rom(spi, SpiConfig::default().clk_cfg(clk_config)).unwrap();
|
||||
let spi = RomSpi::new_for_rom(spi, SpiConfig::default().clk_cfg(clk_config));
|
||||
let mut spi_dev = Self { spi };
|
||||
spi_dev.clear_block_protection().unwrap();
|
||||
spi_dev
|
||||
|
||||
@@ -17,7 +17,6 @@ use panic_probe as _;
|
||||
// Import logger.
|
||||
use core::cell::RefCell;
|
||||
use defmt_rtt as _;
|
||||
use defmt_rtt as _;
|
||||
|
||||
use critical_section::Mutex;
|
||||
use embassy_example::EXTCLK_FREQ;
|
||||
@@ -63,7 +62,7 @@ async fn main(_spawner: Spawner) {
|
||||
let mut led = Output::new(portg.pg5, PinState::Low);
|
||||
|
||||
let uarta =
|
||||
uart::Uart::new(dp.uart0, portg.pg0, portg.pg1, &clocks, 115200.Hz().into()).unwrap();
|
||||
uart::Uart::new_for_uart0(dp.uart0, portg.pg0, portg.pg1, &clocks, 115200.Hz().into());
|
||||
|
||||
let (mut tx_uart_a, rx_uart_a) = uarta.split();
|
||||
let (prod_uart_a, cons_uart_a) = QUEUE_UART_A.take().split();
|
||||
|
||||
@@ -61,7 +61,7 @@ async fn main(_spawner: Spawner) {
|
||||
let mut led = Output::new(pinsg.pg5, PinState::Low);
|
||||
|
||||
let uarta =
|
||||
uart::Uart::new(dp.uart0, pinsg.pg0, pinsg.pg1, &clocks, 115200.Hz().into()).unwrap();
|
||||
uart::Uart::new_for_uart0(dp.uart0, pinsg.pg0, pinsg.pg1, &clocks, 115200.Hz().into());
|
||||
let (tx, _rx) = uarta.split();
|
||||
let mut async_tx = TxAsync::new(tx);
|
||||
let mut ticker = Ticker::every(Duration::from_secs(1));
|
||||
|
||||
@@ -67,14 +67,13 @@ async fn main(spawner: Spawner) {
|
||||
|
||||
let portg = PinsG::new(dp.portg);
|
||||
|
||||
let uart0 = uart::Uart::new(
|
||||
let uart0 = uart::Uart::new_for_uart0(
|
||||
dp.uart0,
|
||||
portg.pg0,
|
||||
portg.pg1,
|
||||
&clocks,
|
||||
Hertz::from_raw(BAUDRATE).into(),
|
||||
)
|
||||
.unwrap();
|
||||
);
|
||||
let (mut tx, rx) = uart0.split();
|
||||
let mut rx = rx.into_rx_with_irq();
|
||||
rx.start();
|
||||
|
||||
@@ -32,7 +32,7 @@ fn main() -> ! {
|
||||
.unwrap();
|
||||
|
||||
let pinsg = PinsG::new(dp.portg);
|
||||
let mut pwm = PwmPin::new(pinsg.pg2, dp.tim9, &clocks, 10.Hz()).unwrap();
|
||||
let mut pwm = PwmPin::new_with_tim9(pinsg.pg2, dp.tim9, &clocks, 10.Hz());
|
||||
let mut delay_timer = CountdownTimer::new(dp.tim0, &clocks);
|
||||
let mut current_duty_cycle = 0.0;
|
||||
pwm.set_duty_cycle(get_duty_from_percent(current_duty_cycle))
|
||||
|
||||
@@ -61,7 +61,7 @@ fn main() -> ! {
|
||||
spi_cfg = spi_cfg.loopback(true)
|
||||
}
|
||||
// Create SPI peripheral.
|
||||
let mut spi0 = Spi::new(dp.spi0, (pins_b.pb15, pins_c.pc0, pins_c.pc1), spi_cfg).unwrap();
|
||||
let mut spi0 = Spi::new_for_spi0(dp.spi0, (pins_b.pb15, pins_c.pc0, pins_c.pc1), spi_cfg);
|
||||
spi0.set_fill_word(FILL_WORD);
|
||||
loop {
|
||||
let tx_buf: [u8; 4] = [1, 2, 3, 0];
|
||||
|
||||
@@ -30,14 +30,13 @@ fn main() -> ! {
|
||||
|
||||
let gpiog = PinsG::new(dp.portg);
|
||||
|
||||
let uart0 = uart::Uart::new(
|
||||
let uart0 = uart::Uart::new_for_uart0(
|
||||
dp.uart0,
|
||||
gpiog.pg0,
|
||||
gpiog.pg1,
|
||||
&clocks,
|
||||
Hertz::from_raw(115200).into(),
|
||||
)
|
||||
.unwrap();
|
||||
);
|
||||
let (mut tx, mut rx) = uart0.split();
|
||||
writeln!(tx, "Hello World\n\r").unwrap();
|
||||
loop {
|
||||
|
||||
@@ -167,14 +167,13 @@ mod app {
|
||||
|
||||
let gpiog = PinsG::new(cx.device.portg);
|
||||
|
||||
let uart0 = Uart::new(
|
||||
let uart0 = Uart::new_for_uart0(
|
||||
cx.device.uart0,
|
||||
gpiog.pg0,
|
||||
gpiog.pg1,
|
||||
&clocks,
|
||||
Hertz::from_raw(UART_BAUDRATE).into(),
|
||||
)
|
||||
.unwrap();
|
||||
);
|
||||
let (tx, rx) = uart0.split();
|
||||
|
||||
let verif_reporter = VerificationReportCreator::new(u11::new(0));
|
||||
|
||||
@@ -6,15 +6,14 @@
|
||||
//!
|
||||
//! - [Flashloader application](https://egit.irs.uni-stuttgart.de/rust/vorago-rs/src/branch/main/va416xx/flashloader)
|
||||
use embedded_hal::spi::MODE_0;
|
||||
use vorago_shared_hal::spi::Spi3Instance as _;
|
||||
use vorago_shared_hal::{
|
||||
disable_peripheral_clock, enable_peripheral_clock, reset_peripheral_for_cycles,
|
||||
};
|
||||
|
||||
use crate::clock::Clocks;
|
||||
use crate::pac;
|
||||
use crate::spi::{
|
||||
mode_to_cpo_cph_bit, spi_clk_config_from_div, SpiInstance, SpiWord, BMSTART_BMSTOP_MASK,
|
||||
};
|
||||
use crate::spi::{mode_to_cpo_cph_bit, spi_clk_config_from_div, SpiWord, BMSTART_BMSTOP_MASK};
|
||||
|
||||
const NVM_CLOCK_DIV: u16 = 2;
|
||||
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
use core::convert::Infallible;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::gpio::IoPeriphPin;
|
||||
use crate::gpio::{DynPinId, IoPeriphPin};
|
||||
use crate::timer::enable_tim_clk;
|
||||
use crate::timer::regs::{EnableControl, StatusSelect};
|
||||
use crate::{PeripheralSelect, enable_peripheral_clock};
|
||||
use crate::{FunctionSelect, PeripheralSelect, enable_peripheral_clock};
|
||||
|
||||
use crate::time::Hertz;
|
||||
use crate::timer::{self, TimId, TimInstance, TimPin};
|
||||
use crate::timer::{self, TimId};
|
||||
use crate::timer::{
|
||||
Tim0Instance, Tim0Pin, Tim1Instance, Tim1Pin, Tim2Instance, Tim2Pin, Tim3Instance, Tim3Pin,
|
||||
Tim4Instance, Tim4Pin, Tim5Instance, Tim5Pin, Tim6Instance, Tim6Pin, Tim7Instance, Tim7Pin,
|
||||
Tim8Instance, Tim8Pin, Tim9Instance, Tim9Pin, Tim10Instance, Tim10Pin, Tim11Instance, Tim11Pin,
|
||||
Tim12Instance, Tim12Pin, Tim13Instance, Tim13Pin, Tim14Instance, Tim14Pin, Tim15Instance,
|
||||
Tim15Pin, Tim16Instance, Tim16Pin, Tim17Instance, Tim17Pin, Tim18Instance, Tim18Pin,
|
||||
Tim19Instance, Tim19Pin, Tim20Instance, Tim20Pin, Tim21Instance, Tim21Pin, Tim22Instance,
|
||||
Tim22Pin, Tim23Instance, Tim23Pin,
|
||||
};
|
||||
|
||||
const DUTY_MAX: u16 = u16::MAX;
|
||||
|
||||
@@ -18,14 +27,6 @@ pub enum PwmA {}
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum PwmB {}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[error("pin tim ID {pin_tim:?} and timer tim id {tim_id:?} do not match")]
|
||||
pub struct TimMissmatchError {
|
||||
pin_tim: TimId,
|
||||
tim_id: TimId,
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
// PWM pin
|
||||
//==================================================================================================
|
||||
@@ -44,25 +45,79 @@ pub struct PwmPin<Mode = PwmA> {
|
||||
mode: PhantomData<Mode>,
|
||||
}
|
||||
|
||||
macro_rules! impl_pwm_new_methods {
|
||||
(
|
||||
$(
|
||||
($tim_name:ident, $pin_trait:ident, $instance_trait:ident)
|
||||
),*
|
||||
$(,)?
|
||||
) => {
|
||||
paste::paste! {
|
||||
$(
|
||||
#[doc = concat!("Create a new PWM pin using ", stringify!($tim_name))]
|
||||
pub fn [<new_with_ $tim_name:lower>] <Pin: $pin_trait, Tim: $instance_trait>(
|
||||
_pin: Pin,
|
||||
_tim: Tim,
|
||||
#[cfg(feature = "vor1x")] sys_clk: Hertz,
|
||||
#[cfg(feature = "vor4x")] clks: &crate::clock::Clocks,
|
||||
initial_frequency: Hertz,
|
||||
) -> Self {
|
||||
Self::new(
|
||||
Pin::PIN_ID,
|
||||
Pin::FUNC_SEL,
|
||||
Tim::ID,
|
||||
#[cfg(feature = "vor1x")]
|
||||
sys_clk,
|
||||
#[cfg(feature = "vor4x")]
|
||||
clks,
|
||||
initial_frequency,
|
||||
)
|
||||
}
|
||||
)*
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl<Mode> PwmPin<Mode> {
|
||||
/// Create a new PWM pin
|
||||
pub fn new<Pin: TimPin, Tim: TimInstance>(
|
||||
_pin: Pin,
|
||||
_tim: Tim,
|
||||
impl_pwm_new_methods! {
|
||||
(Tim0, Tim0Pin, Tim0Instance),
|
||||
(Tim1, Tim1Pin, Tim1Instance),
|
||||
(Tim2, Tim2Pin, Tim2Instance),
|
||||
(Tim3, Tim3Pin, Tim3Instance),
|
||||
(Tim4, Tim4Pin, Tim4Instance),
|
||||
(Tim5, Tim5Pin, Tim5Instance),
|
||||
(Tim6, Tim6Pin, Tim6Instance),
|
||||
(Tim7, Tim7Pin, Tim7Instance),
|
||||
(Tim8, Tim8Pin, Tim8Instance),
|
||||
(Tim9, Tim9Pin, Tim9Instance),
|
||||
(Tim10, Tim10Pin, Tim10Instance),
|
||||
(Tim11, Tim11Pin, Tim11Instance),
|
||||
(Tim12, Tim12Pin, Tim12Instance),
|
||||
(Tim13, Tim13Pin, Tim13Instance),
|
||||
(Tim14, Tim14Pin, Tim14Instance),
|
||||
(Tim15, Tim15Pin, Tim15Instance),
|
||||
(Tim16, Tim16Pin, Tim16Instance),
|
||||
(Tim17, Tim17Pin, Tim17Instance),
|
||||
(Tim18, Tim18Pin, Tim18Instance),
|
||||
(Tim19, Tim19Pin, Tim19Instance),
|
||||
(Tim20, Tim20Pin, Tim20Instance),
|
||||
(Tim21, Tim21Pin, Tim21Instance),
|
||||
(Tim22, Tim22Pin, Tim22Instance),
|
||||
(Tim23, Tim23Pin, Tim23Instance),
|
||||
}
|
||||
|
||||
fn new(
|
||||
pin_id: DynPinId,
|
||||
func_sel: FunctionSelect,
|
||||
tim_id: TimId,
|
||||
#[cfg(feature = "vor1x")] sys_clk: Hertz,
|
||||
#[cfg(feature = "vor4x")] clks: &crate::clock::Clocks,
|
||||
initial_frequency: Hertz,
|
||||
) -> Result<Self, TimMissmatchError> {
|
||||
if Pin::TIM_ID != Tim::ID {
|
||||
return Err(TimMissmatchError {
|
||||
pin_tim: Pin::TIM_ID,
|
||||
tim_id: Tim::ID,
|
||||
});
|
||||
}
|
||||
IoPeriphPin::new(Pin::PIN_ID, Pin::FUN_SEL, None);
|
||||
) -> Self {
|
||||
IoPeriphPin::new(pin_id, func_sel, None);
|
||||
let mut pin = PwmPin {
|
||||
tim_id: Tim::ID,
|
||||
regs: timer::regs::Timer::new_mmio(Tim::ID),
|
||||
tim_id,
|
||||
regs: timer::regs::Timer::new_mmio(tim_id),
|
||||
current_duty: 0,
|
||||
current_lower_limit: 0,
|
||||
current_period: initial_frequency,
|
||||
@@ -78,10 +133,10 @@ impl<Mode> PwmPin<Mode> {
|
||||
#[cfg(feature = "vor1x")]
|
||||
enable_peripheral_clock(PeripheralSelect::Gpio);
|
||||
enable_peripheral_clock(PeripheralSelect::IoConfig);
|
||||
enable_tim_clk(Tim::ID);
|
||||
enable_tim_clk(tim_id);
|
||||
pin.enable_pwm_a();
|
||||
pin.set_period(initial_frequency);
|
||||
Ok(pin)
|
||||
pin
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
@@ -23,18 +23,48 @@ pub fn configure_pin_as_hw_cs_pin<P: AnyPin + HwCsProvider>(_pin: P) -> HwChipSe
|
||||
// Pins and traits.
|
||||
//==================================================================================================
|
||||
|
||||
pub trait PinSck: AnyPin {
|
||||
const SPI_ID: Bank;
|
||||
pub trait PinSck0: AnyPin {
|
||||
const SPI_ID: Bank = Bank::Spi0;
|
||||
const FUN_SEL: FunctionSelect;
|
||||
}
|
||||
|
||||
pub trait PinMosi: AnyPin {
|
||||
const SPI_ID: Bank;
|
||||
pub trait PinMosi0: AnyPin {
|
||||
const SPI_ID: Bank = Bank::Spi0;
|
||||
const FUN_SEL: FunctionSelect;
|
||||
}
|
||||
|
||||
pub trait PinMiso: AnyPin {
|
||||
const SPI_ID: Bank;
|
||||
pub trait PinMiso0: AnyPin {
|
||||
const SPI_ID: Bank = Bank::Spi0;
|
||||
const FUN_SEL: FunctionSelect;
|
||||
}
|
||||
|
||||
pub trait PinSck1: AnyPin {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect;
|
||||
}
|
||||
|
||||
pub trait PinMosi1: AnyPin {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect;
|
||||
}
|
||||
|
||||
pub trait PinMiso1: AnyPin {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect;
|
||||
}
|
||||
|
||||
pub trait PinSck2: AnyPin {
|
||||
const SPI_ID: Bank = Bank::Spi2;
|
||||
const FUN_SEL: FunctionSelect;
|
||||
}
|
||||
|
||||
pub trait PinMosi2: AnyPin {
|
||||
const SPI_ID: Bank = Bank::Spi2;
|
||||
const FUN_SEL: FunctionSelect;
|
||||
}
|
||||
|
||||
pub trait PinMiso2: AnyPin {
|
||||
const SPI_ID: Bank = Bank::Spi2;
|
||||
const FUN_SEL: FunctionSelect;
|
||||
}
|
||||
|
||||
@@ -115,10 +145,24 @@ pub const BMSKIPDATA_MASK: u32 = 1 << 30;
|
||||
|
||||
pub const DEFAULT_CLK_DIV: u16 = 2;
|
||||
|
||||
/// Common trait implemented by all PAC peripheral access structures. The register block
|
||||
/// format is the same for all SPI blocks.
|
||||
pub trait SpiInstance: Sealed {
|
||||
const ID: Bank;
|
||||
pub trait Spi0Instance: Sealed {
|
||||
const ID: Bank = Bank::Spi0;
|
||||
const PERIPH_SEL: PeripheralSelect;
|
||||
}
|
||||
|
||||
pub trait Spi1Instance: Sealed {
|
||||
const ID: Bank = Bank::Spi1;
|
||||
const PERIPH_SEL: PeripheralSelect;
|
||||
}
|
||||
|
||||
pub trait Spi2Instance: Sealed {
|
||||
const ID: Bank = Bank::Spi2;
|
||||
const PERIPH_SEL: PeripheralSelect;
|
||||
}
|
||||
|
||||
#[cfg(feature = "vor4x")]
|
||||
pub trait Spi3Instance: Sealed {
|
||||
const ID: Bank = Bank::Spi3;
|
||||
const PERIPH_SEL: PeripheralSelect;
|
||||
}
|
||||
|
||||
@@ -127,7 +171,7 @@ pub type Spi0 = pac::Spia;
|
||||
#[cfg(feature = "vor4x")]
|
||||
pub type Spi0 = pac::Spi0;
|
||||
|
||||
impl SpiInstance for Spi0 {
|
||||
impl Spi0Instance for Spi0 {
|
||||
const ID: Bank = Bank::Spi0;
|
||||
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Spi0;
|
||||
}
|
||||
@@ -138,7 +182,7 @@ pub type Spi1 = pac::Spib;
|
||||
#[cfg(feature = "vor4x")]
|
||||
pub type Spi1 = pac::Spi1;
|
||||
|
||||
impl SpiInstance for Spi1 {
|
||||
impl Spi1Instance for Spi1 {
|
||||
const ID: Bank = Bank::Spi1;
|
||||
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Spi1;
|
||||
}
|
||||
@@ -149,14 +193,14 @@ pub type Spi2 = pac::Spic;
|
||||
#[cfg(feature = "vor4x")]
|
||||
pub type Spi2 = pac::Spi2;
|
||||
|
||||
impl SpiInstance for Spi2 {
|
||||
impl Spi2Instance for Spi2 {
|
||||
const ID: Bank = Bank::Spi2;
|
||||
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Spi2;
|
||||
}
|
||||
impl Sealed for Spi2 {}
|
||||
|
||||
#[cfg(feature = "vor4x")]
|
||||
impl SpiInstance for pac::Spi3 {
|
||||
impl Spi3Instance for pac::Spi3 {
|
||||
const ID: Bank = Bank::Spi3;
|
||||
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Spi3;
|
||||
}
|
||||
@@ -468,10 +512,6 @@ pub fn clk_div_for_target_clock(sys_clk: Hertz, spi_clk: Hertz) -> Option<u16> {
|
||||
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: Bank,
|
||||
@@ -494,22 +534,23 @@ where
|
||||
///
|
||||
/// * `spi` - SPI bus to use
|
||||
/// * `spi_cfg` - Configuration specific to the SPI bus
|
||||
pub fn new_for_rom<SpiI: SpiInstance>(
|
||||
spi: SpiI,
|
||||
spi_cfg: SpiConfig,
|
||||
) -> Result<Self, SpiIdMissmatchError> {
|
||||
#[cfg(feature = "vor1x")]
|
||||
if SpiI::ID != Bank::Spi2 {
|
||||
return Err(SpiIdMissmatchError);
|
||||
}
|
||||
#[cfg(feature = "vor4x")]
|
||||
if SpiI::ID != Bank::Spi3 {
|
||||
return Err(SpiIdMissmatchError);
|
||||
}
|
||||
Ok(Self::new_generic(spi, spi_cfg))
|
||||
#[cfg(feature = "vor1x")]
|
||||
pub fn new_for_rom<Spi: Spi2Instance>(_spi: Spi, spi_cfg: SpiConfig) -> Self {
|
||||
Self::new_generic(Spi::ID, Spi::PERIPH_SEL, spi_cfg)
|
||||
}
|
||||
|
||||
/// Create a new SPI peripheral driver.
|
||||
/// Create a new SPI struct for using SPI with the fixed ROM SPI pins.
|
||||
///
|
||||
/// ## Arguments
|
||||
///
|
||||
/// * `spi` - SPI bus to use
|
||||
/// * `spi_cfg` - Configuration specific to the SPI bus
|
||||
#[cfg(feature = "vor4x")]
|
||||
pub fn new_for_rom<Spi: Spi3Instance>(_spi: Spi, spi_cfg: SpiConfig) -> Self {
|
||||
Self::new_generic(Spi::ID, Spi::PERIPH_SEL, spi_cfg)
|
||||
}
|
||||
|
||||
/// Create a new SPI peripheral driver for SPI 0.
|
||||
///
|
||||
/// ## Arguments
|
||||
///
|
||||
@@ -517,23 +558,58 @@ where
|
||||
/// * `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: SpiInstance, Sck: PinSck, Miso: PinMiso, Mosi: PinMosi>(
|
||||
spi: SpiI,
|
||||
pub fn new_for_spi0<Spi: Spi0Instance, Sck: PinSck0, Miso: PinMiso0, Mosi: PinMosi0>(
|
||||
_spi: Spi,
|
||||
_pins: (Sck, Miso, Mosi),
|
||||
spi_cfg: SpiConfig,
|
||||
) -> Result<Self, SpiIdMissmatchError> {
|
||||
if SpiI::ID != Sck::SPI_ID || SpiI::ID != Miso::SPI_ID || SpiI::ID != Mosi::SPI_ID {
|
||||
return Err(SpiIdMissmatchError);
|
||||
}
|
||||
) -> Self {
|
||||
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(spi, spi_cfg))
|
||||
Self::new_generic(Spi::ID, Spi::PERIPH_SEL, spi_cfg)
|
||||
}
|
||||
|
||||
pub fn new_generic<SpiI: SpiInstance>(_spi: SpiI, spi_cfg: SpiConfig) -> Self {
|
||||
enable_peripheral_clock(SpiI::PERIPH_SEL);
|
||||
let mut regs = regs::Spi::new_mmio(SpiI::ID);
|
||||
/// Create a new SPI peripheral driver for SPI 1.
|
||||
///
|
||||
/// ## Arguments
|
||||
///
|
||||
/// * `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_for_spi1<Spi: Spi1Instance, Sck: PinSck1, Miso: PinMiso1, Mosi: PinMosi1>(
|
||||
_spi: Spi,
|
||||
_pins: (Sck, Miso, Mosi),
|
||||
spi_cfg: SpiConfig,
|
||||
) -> Self {
|
||||
IoPeriphPin::new(Sck::ID, Sck::FUN_SEL, None);
|
||||
IoPeriphPin::new(Miso::ID, Miso::FUN_SEL, None);
|
||||
IoPeriphPin::new(Mosi::ID, Mosi::FUN_SEL, None);
|
||||
Self::new_generic(Spi::ID, Spi::PERIPH_SEL, spi_cfg)
|
||||
}
|
||||
|
||||
/// Create a new SPI peripheral driver for SPI 2.
|
||||
///
|
||||
/// ## Arguments
|
||||
///
|
||||
/// * `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_for_spi2<Spi: Spi2Instance, Sck: PinSck2, Miso: PinMiso2, Mosi: PinMosi2>(
|
||||
_spi: Spi,
|
||||
_pins: (Sck, Miso, Mosi),
|
||||
spi_cfg: SpiConfig,
|
||||
) -> Self {
|
||||
IoPeriphPin::new(Sck::ID, Sck::FUN_SEL, None);
|
||||
IoPeriphPin::new(Miso::ID, Miso::FUN_SEL, None);
|
||||
IoPeriphPin::new(Mosi::ID, Mosi::FUN_SEL, None);
|
||||
Self::new_generic(Spi::ID, Spi::PERIPH_SEL, spi_cfg)
|
||||
}
|
||||
|
||||
pub fn new_generic(spi_sel: Bank, periph_sel: PeripheralSelect, spi_cfg: SpiConfig) -> Self {
|
||||
enable_peripheral_clock(periph_sel);
|
||||
let mut regs = regs::Spi::new_mmio(spi_sel);
|
||||
let (cpo_bit, cph_bit) = mode_to_cpo_cph_bit(spi_cfg.init_mode);
|
||||
regs.write_ctrl0(
|
||||
regs::Control0::builder()
|
||||
@@ -571,8 +647,8 @@ where
|
||||
value
|
||||
});
|
||||
Spi {
|
||||
id: SpiI::ID,
|
||||
regs: regs::Spi::new_mmio(SpiI::ID),
|
||||
id: spi_sel,
|
||||
regs: regs::Spi::new_mmio(spi_sel),
|
||||
cfg: spi_cfg,
|
||||
fill_word: Default::default(),
|
||||
bmstall: spi_cfg.bmstall,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use super::{HwCsProvider, PinMiso, PinMosi, PinSck};
|
||||
use super::{HwCsProvider, PinMiso0, PinMiso1, PinMosi0, PinMosi1, PinSck0, PinSck1};
|
||||
use crate::FunctionSelect;
|
||||
use crate::gpio::{DynPinId, PinId};
|
||||
|
||||
@@ -12,28 +12,28 @@ use super::{Bank, HwChipSelectId};
|
||||
|
||||
// SPIA
|
||||
|
||||
impl PinSck for Pin<Pa31> {
|
||||
impl PinSck0 for Pin<Pa31> {
|
||||
const SPI_ID: Bank = Bank::Spi0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl PinMosi for Pin<Pa30> {
|
||||
impl PinMosi0 for Pin<Pa30> {
|
||||
const SPI_ID: Bank = Bank::Spi0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl PinMiso for Pin<Pa29> {
|
||||
impl PinMiso0 for Pin<Pa29> {
|
||||
const SPI_ID: Bank = Bank::Spi0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
|
||||
impl PinSck for Pin<Pb9> {
|
||||
impl PinSck0 for Pin<Pb9> {
|
||||
const SPI_ID: Bank = Bank::Spi0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl PinMosi for Pin<Pb8> {
|
||||
impl PinMosi0 for Pin<Pb8> {
|
||||
const SPI_ID: Bank = Bank::Spi0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl PinMiso for Pin<Pb7> {
|
||||
impl PinMiso0 for Pin<Pb7> {
|
||||
const SPI_ID: Bank = Bank::Spi0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
@@ -100,15 +100,15 @@ hw_cs_multi_pin!(
|
||||
|
||||
// SPIB
|
||||
|
||||
impl PinSck for Pin<Pa20> {
|
||||
impl PinSck1 for Pin<Pa20> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl PinMosi for Pin<Pa19> {
|
||||
impl PinMosi1 for Pin<Pa19> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl PinMiso for Pin<Pa18> {
|
||||
impl PinMiso1 for Pin<Pa18> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
@@ -117,28 +117,28 @@ pub type SpiBPortASck = Pin<Pa20>;
|
||||
pub type SpiBPortAMosi = Pin<Pa19>;
|
||||
pub type SpiBPortAMiso = Pin<Pa18>;
|
||||
|
||||
impl PinSck for Pin<Pb19> {
|
||||
impl PinSck1 for Pin<Pb19> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl PinMosi for Pin<Pb18> {
|
||||
impl PinMosi1 for Pin<Pb18> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl PinMiso for Pin<Pb17> {
|
||||
impl PinMiso1 for Pin<Pb17> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
|
||||
impl PinSck for Pin<Pb5> {
|
||||
impl PinSck1 for Pin<Pb5> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl PinMosi for Pin<Pb4> {
|
||||
impl PinMosi1 for Pin<Pb4> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl PinMiso for Pin<Pb3> {
|
||||
impl PinMiso1 for Pin<Pb3> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
|
||||
@@ -11,19 +11,22 @@ use crate::{
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
use crate::pins::{Pb5, Pb6, Pb7, Pb8, Pb9, Pb10, Pb11, Pe10, Pe11, Pf2, Pf3, Pf4, Pf5, Pf6, Pf7};
|
||||
|
||||
use super::{Bank, HwChipSelectId, HwCsProvider, PinMiso, PinMosi, PinSck};
|
||||
use super::{
|
||||
Bank, HwChipSelectId, HwCsProvider, PinMiso0, PinMiso1, PinMiso2, PinMosi0, PinMosi1, PinMosi2,
|
||||
PinSck0, PinSck1, PinSck2,
|
||||
};
|
||||
|
||||
// SPI0
|
||||
|
||||
impl PinSck for Pin<Pb15> {
|
||||
impl PinSck0 for Pin<Pb15> {
|
||||
const SPI_ID: Bank = Bank::Spi0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl PinMosi for Pin<Pc1> {
|
||||
impl PinMosi0 for Pin<Pc1> {
|
||||
const SPI_ID: Bank = Bank::Spi0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl PinMiso for Pin<Pc0> {
|
||||
impl PinMiso0 for Pin<Pc0> {
|
||||
const SPI_ID: Bank = Bank::Spi0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
@@ -44,68 +47,68 @@ hw_cs_pins!(
|
||||
// SPI1
|
||||
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
impl PinSck for Pin<Pb8> {
|
||||
impl PinSck1 for Pin<Pb8> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
impl PinMosi for Pin<Pb10> {
|
||||
impl PinMosi1 for Pin<Pb10> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
impl PinMiso for Pin<Pb9> {
|
||||
impl PinMiso1 for Pin<Pb9> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
|
||||
impl PinSck for Pin<Pc9> {
|
||||
impl PinSck1 for Pin<Pc9> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl PinMosi for Pin<Pc11> {
|
||||
impl PinMosi1 for Pin<Pc11> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl PinMiso for Pin<Pc10> {
|
||||
impl PinMiso1 for Pin<Pc10> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
|
||||
impl PinSck for Pin<Pe13> {
|
||||
impl PinSck1 for Pin<Pe13> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl PinMosi for Pin<Pe15> {
|
||||
impl PinMosi1 for Pin<Pe15> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl PinMiso for Pin<Pe14> {
|
||||
impl PinMiso1 for Pin<Pe14> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
impl PinSck for Pin<Pf3> {
|
||||
impl PinSck1 for Pin<Pf3> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
impl PinMosi for Pin<Pf5> {
|
||||
impl PinMosi1 for Pin<Pf5> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
impl PinMiso for Pin<Pf4> {
|
||||
impl PinMiso1 for Pin<Pf4> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
|
||||
impl PinSck for Pin<Pg3> {
|
||||
impl PinSck1 for Pin<Pg3> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl PinMiso for Pin<Pg4> {
|
||||
impl PinMiso1 for Pin<Pg4> {
|
||||
const SPI_ID: Bank = Bank::Spi1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
@@ -149,31 +152,31 @@ hw_cs_multi_pin!(
|
||||
|
||||
// SPI2
|
||||
|
||||
impl PinSck for Pin<Pa5> {
|
||||
impl PinSck2 for Pin<Pa5> {
|
||||
const SPI_ID: Bank = Bank::Spi2;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl PinMosi for Pin<Pa7> {
|
||||
impl PinMosi2 for Pin<Pa7> {
|
||||
const SPI_ID: Bank = Bank::Spi2;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl PinMiso for Pin<Pa6> {
|
||||
impl PinMiso2 for Pin<Pa6> {
|
||||
const SPI_ID: Bank = Bank::Spi2;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
impl PinSck for Pin<Pf5> {
|
||||
impl PinSck2 for Pin<Pf5> {
|
||||
const SPI_ID: Bank = Bank::Spi2;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
impl PinMosi for Pin<Pf7> {
|
||||
impl PinMosi2 for Pin<Pf7> {
|
||||
const SPI_ID: Bank = Bank::Spi2;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
impl PinMiso for Pin<Pf6> {
|
||||
impl PinMiso2 for Pin<Pf6> {
|
||||
const SPI_ID: Bank = Bank::Spi2;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
|
||||
@@ -69,21 +69,54 @@ pub enum CascadeSelect {
|
||||
// Valid TIM and PIN combinations
|
||||
//==================================================================================================
|
||||
|
||||
pub trait TimPin: AnyPin {
|
||||
const PIN_ID: DynPinId;
|
||||
const FUN_SEL: FunctionSelect;
|
||||
const TIM_ID: TimId;
|
||||
macro_rules! define_tim_pin_traits {
|
||||
([$(($tim_name:ident, $index:expr)),* $(,)?]) => {
|
||||
$(
|
||||
pub trait $tim_name: AnyPin {
|
||||
const PIN_ID: DynPinId;
|
||||
const FUNC_SEL: FunctionSelect;
|
||||
const TIM_ID: TimId = TimId::new_unchecked($index);
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
define_tim_pin_traits!([
|
||||
(Tim0Pin, 0),
|
||||
(Tim1Pin, 1),
|
||||
(Tim2Pin, 2),
|
||||
(Tim3Pin, 3),
|
||||
(Tim4Pin, 4),
|
||||
(Tim5Pin, 5),
|
||||
(Tim6Pin, 6),
|
||||
(Tim7Pin, 7),
|
||||
(Tim8Pin, 8),
|
||||
(Tim9Pin, 9),
|
||||
(Tim10Pin, 10),
|
||||
(Tim11Pin, 11),
|
||||
(Tim12Pin, 12),
|
||||
(Tim13Pin, 13),
|
||||
(Tim14Pin, 14),
|
||||
(Tim15Pin, 15),
|
||||
(Tim16Pin, 16),
|
||||
(Tim17Pin, 17),
|
||||
(Tim18Pin, 18),
|
||||
(Tim19Pin, 19),
|
||||
(Tim20Pin, 20),
|
||||
(Tim21Pin, 21),
|
||||
(Tim22Pin, 22),
|
||||
(Tim23Pin, 23),
|
||||
]);
|
||||
|
||||
pub trait TimInstance: Sealed {
|
||||
// TIM ID ranging from 0 to 23 for 24 TIM peripherals
|
||||
const ID: TimId;
|
||||
|
||||
#[cfg(feature = "vor4x")]
|
||||
const IRQ: va416xx::Interrupt;
|
||||
|
||||
#[cfg(feature = "vor4x")]
|
||||
fn clock(clocks: &crate::clock::Clocks) -> Hertz {
|
||||
if Self::ID.value() <= 15 {
|
||||
if Self::ID.value() < 16 {
|
||||
clocks.apb1()
|
||||
} else {
|
||||
clocks.apb2()
|
||||
@@ -91,91 +124,145 @@ pub trait TimInstance: Sealed {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Tim0Instance: TimInstance {}
|
||||
pub trait Tim1Instance: TimInstance {}
|
||||
pub trait Tim2Instance: TimInstance {}
|
||||
pub trait Tim3Instance: TimInstance {}
|
||||
pub trait Tim4Instance: TimInstance {}
|
||||
pub trait Tim5Instance: TimInstance {}
|
||||
pub trait Tim6Instance: TimInstance {}
|
||||
pub trait Tim7Instance: TimInstance {}
|
||||
pub trait Tim8Instance: TimInstance {}
|
||||
pub trait Tim9Instance: TimInstance {}
|
||||
pub trait Tim10Instance: TimInstance {}
|
||||
pub trait Tim11Instance: TimInstance {}
|
||||
pub trait Tim12Instance: TimInstance {}
|
||||
pub trait Tim13Instance: TimInstance {}
|
||||
pub trait Tim14Instance: TimInstance {}
|
||||
pub trait Tim15Instance: TimInstance {}
|
||||
pub trait Tim16Instance: TimInstance {}
|
||||
pub trait Tim17Instance: TimInstance {}
|
||||
pub trait Tim18Instance: TimInstance {}
|
||||
pub trait Tim19Instance: TimInstance {}
|
||||
pub trait Tim20Instance: TimInstance {}
|
||||
pub trait Tim21Instance: TimInstance {}
|
||||
pub trait Tim22Instance: TimInstance {}
|
||||
pub trait Tim23Instance: TimInstance {}
|
||||
|
||||
macro_rules! tim_marker {
|
||||
($TIMX:path, $ID:expr) => {
|
||||
($TIMX:path, $Trait:ident, $ID:expr) => {
|
||||
impl Sealed for $TIMX {}
|
||||
|
||||
impl TimInstance for $TIMX {
|
||||
const ID: TimId = TimId::new_unchecked($ID);
|
||||
}
|
||||
|
||||
impl Sealed for $TIMX {}
|
||||
impl $Trait for $TIMX {}
|
||||
};
|
||||
($TIMX:path, $ID:expr, $IrqId:ident) => {
|
||||
($TIMX:path, $Trait:ident, $ID:expr, $IrqId:ident) => {
|
||||
impl Sealed for $TIMX {}
|
||||
|
||||
impl TimInstance for $TIMX {
|
||||
const ID: TimId = TimId::new_unchecked($ID);
|
||||
const IRQ: va416xx::Interrupt = va416xx::Interrupt::$IrqId;
|
||||
}
|
||||
|
||||
impl Sealed for $TIMX {}
|
||||
impl $Trait for $TIMX {}
|
||||
};
|
||||
}
|
||||
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "vor1x")] {
|
||||
tim_marker!(pac::Tim0, 0);
|
||||
tim_marker!(pac::Tim1, 1);
|
||||
tim_marker!(pac::Tim2, 2);
|
||||
tim_marker!(pac::Tim3, 3);
|
||||
tim_marker!(pac::Tim4, 4);
|
||||
tim_marker!(pac::Tim5, 5);
|
||||
tim_marker!(pac::Tim6, 6);
|
||||
tim_marker!(pac::Tim7, 7);
|
||||
tim_marker!(pac::Tim8, 8);
|
||||
tim_marker!(pac::Tim9, 9);
|
||||
tim_marker!(pac::Tim10, 10);
|
||||
tim_marker!(pac::Tim11, 11);
|
||||
tim_marker!(pac::Tim12, 12);
|
||||
tim_marker!(pac::Tim13, 13);
|
||||
tim_marker!(pac::Tim14, 14);
|
||||
tim_marker!(pac::Tim15, 15);
|
||||
tim_marker!(pac::Tim16, 16);
|
||||
tim_marker!(pac::Tim17, 17);
|
||||
tim_marker!(pac::Tim18, 18);
|
||||
tim_marker!(pac::Tim19, 19);
|
||||
tim_marker!(pac::Tim20, 20);
|
||||
tim_marker!(pac::Tim21, 21);
|
||||
tim_marker!(pac::Tim22, 22);
|
||||
tim_marker!(pac::Tim23, 23);
|
||||
tim_marker!(pac::Tim0, Tim0Instance, 0);
|
||||
tim_marker!(pac::Tim1, Tim1Instance, 1);
|
||||
tim_marker!(pac::Tim2, Tim2Instance, 2);
|
||||
tim_marker!(pac::Tim3, Tim3Instance, 3);
|
||||
tim_marker!(pac::Tim4, Tim4Instance, 4);
|
||||
tim_marker!(pac::Tim5, Tim5Instance, 5);
|
||||
tim_marker!(pac::Tim6, Tim6Instance, 6);
|
||||
tim_marker!(pac::Tim7, Tim7Instance, 7);
|
||||
tim_marker!(pac::Tim8, Tim8Instance, 8);
|
||||
tim_marker!(pac::Tim9, Tim9Instance, 9);
|
||||
tim_marker!(pac::Tim10, Tim10Instance, 10);
|
||||
tim_marker!(pac::Tim11, Tim11Instance, 11);
|
||||
tim_marker!(pac::Tim12, Tim12Instance, 12);
|
||||
tim_marker!(pac::Tim13, Tim13Instance, 13);
|
||||
tim_marker!(pac::Tim14, Tim14Instance, 14);
|
||||
tim_marker!(pac::Tim15, Tim15Instance, 15);
|
||||
tim_marker!(pac::Tim16, Tim16Instance, 16);
|
||||
tim_marker!(pac::Tim17, Tim17Instance, 17);
|
||||
tim_marker!(pac::Tim18, Tim18Instance, 18);
|
||||
tim_marker!(pac::Tim19, Tim19Instance, 19);
|
||||
tim_marker!(pac::Tim20, Tim20Instance, 20);
|
||||
tim_marker!(pac::Tim21, Tim21Instance, 21);
|
||||
tim_marker!(pac::Tim22, Tim22Instance, 22);
|
||||
tim_marker!(pac::Tim23, Tim23Instance, 23);
|
||||
} else if #[cfg(feature = "vor4x")] {
|
||||
tim_marker!(pac::Tim0, 0, TIM0);
|
||||
tim_marker!(pac::Tim1, 1, TIM1);
|
||||
tim_marker!(pac::Tim2, 2, TIM2);
|
||||
tim_marker!(pac::Tim3, 3, TIM3);
|
||||
tim_marker!(pac::Tim4, 4, TIM4);
|
||||
tim_marker!(pac::Tim5, 5, TIM5);
|
||||
tim_marker!(pac::Tim6, 6, TIM6);
|
||||
tim_marker!(pac::Tim7, 7, TIM7);
|
||||
tim_marker!(pac::Tim8, 8, TIM8);
|
||||
tim_marker!(pac::Tim9, 9, TIM9);
|
||||
tim_marker!(pac::Tim10, 10, TIM10);
|
||||
tim_marker!(pac::Tim11, 11, TIM11);
|
||||
tim_marker!(pac::Tim12, 12, TIM12);
|
||||
tim_marker!(pac::Tim13, 13, TIM13);
|
||||
tim_marker!(pac::Tim14, 14, TIM14);
|
||||
tim_marker!(pac::Tim15, 15, TIM15);
|
||||
tim_marker!(pac::Tim16, 16, TIM16);
|
||||
tim_marker!(pac::Tim17, 17, TIM17);
|
||||
tim_marker!(pac::Tim18, 18, TIM18);
|
||||
tim_marker!(pac::Tim19, 19, TIM19);
|
||||
tim_marker!(pac::Tim20, 20, TIM20);
|
||||
tim_marker!(pac::Tim21, 21, TIM21);
|
||||
tim_marker!(pac::Tim22, 22, TIM22);
|
||||
tim_marker!(pac::Tim23, 23, TIM23);
|
||||
tim_marker!(pac::Tim0, Tim0Instance, 0, TIM0);
|
||||
tim_marker!(pac::Tim1, Tim1Instance, 1, TIM1);
|
||||
tim_marker!(pac::Tim2, Tim2Instance, 2, TIM2);
|
||||
tim_marker!(pac::Tim3, Tim3Instance, 3, TIM3);
|
||||
tim_marker!(pac::Tim4, Tim4Instance, 4, TIM4);
|
||||
tim_marker!(pac::Tim5, Tim5Instance, 5, TIM5);
|
||||
tim_marker!(pac::Tim6, Tim6Instance, 6, TIM6);
|
||||
tim_marker!(pac::Tim7, Tim7Instance, 7, TIM7);
|
||||
tim_marker!(pac::Tim8, Tim8Instance, 8, TIM8);
|
||||
tim_marker!(pac::Tim9, Tim9Instance, 9, TIM9);
|
||||
tim_marker!(pac::Tim10, Tim10Instance, 10, TIM10);
|
||||
tim_marker!(pac::Tim11, Tim11Instance, 11, TIM11);
|
||||
tim_marker!(pac::Tim12, Tim12Instance, 12, TIM12);
|
||||
tim_marker!(pac::Tim13, Tim13Instance, 13, TIM13);
|
||||
tim_marker!(pac::Tim14, Tim14Instance, 14, TIM14);
|
||||
tim_marker!(pac::Tim15, Tim15Instance, 15, TIM15);
|
||||
tim_marker!(pac::Tim16, Tim16Instance, 16, TIM16);
|
||||
tim_marker!(pac::Tim17, Tim17Instance, 17, TIM17);
|
||||
tim_marker!(pac::Tim18, Tim18Instance, 18, TIM18);
|
||||
tim_marker!(pac::Tim19, Tim19Instance, 19, TIM19);
|
||||
tim_marker!(pac::Tim20, Tim20Instance, 20, TIM20);
|
||||
tim_marker!(pac::Tim21, Tim21Instance, 21, TIM21);
|
||||
tim_marker!(pac::Tim22, Tim22Instance, 22, TIM22);
|
||||
tim_marker!(pac::Tim23, Tim23Instance, 23, TIM23);
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ValidTimAndPin<Pin: TimPin, Tim: TimInstance>: Sealed {}
|
||||
pub trait ValidTimAndPin0<Pin: Tim0Pin, Tim: Tim0Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin1<Pin: Tim1Pin, Tim: Tim1Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin2<Pin: Tim2Pin, Tim: Tim2Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin3<Pin: Tim3Pin, Tim: Tim3Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin4<Pin: Tim4Pin, Tim: Tim4Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin5<Pin: Tim5Pin, Tim: Tim5Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin6<Pin: Tim6Pin, Tim: Tim6Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin7<Pin: Tim7Pin, Tim: Tim7Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin8<Pin: Tim8Pin, Tim: Tim8Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin9<Pin: Tim9Pin, Tim: Tim9Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin10<Pin: Tim10Pin, Tim: Tim10Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin11<Pin: Tim11Pin, Tim: Tim11Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin12<Pin: Tim12Pin, Tim: Tim12Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin13<Pin: Tim13Pin, Tim: Tim13Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin14<Pin: Tim14Pin, Tim: Tim14Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin15<Pin: Tim15Pin, Tim: Tim15Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin16<Pin: Tim16Pin, Tim: Tim16Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin17<Pin: Tim17Pin, Tim: Tim17Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin18<Pin: Tim18Pin, Tim: Tim18Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin19<Pin: Tim19Pin, Tim: Tim19Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin20<Pin: Tim20Pin, Tim: Tim20Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin21<Pin: Tim21Pin, Tim: Tim21Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin22<Pin: Tim22Pin, Tim: Tim22Instance>: Sealed {}
|
||||
pub trait ValidTimAndPin23<Pin: Tim23Pin, Tim: Tim23Instance>: Sealed {}
|
||||
|
||||
#[macro_use]
|
||||
mod macros {
|
||||
macro_rules! pin_and_tim {
|
||||
($Px:ident, $FunSel:path, $ID:expr) => {
|
||||
impl TimPin for Pin<$Px>
|
||||
where
|
||||
$Px: PinId,
|
||||
{
|
||||
const PIN_ID: DynPinId = $Px::ID;
|
||||
const FUN_SEL: FunctionSelect = $FunSel;
|
||||
const TIM_ID: TimId = TimId::new_unchecked($ID);
|
||||
paste::paste! {
|
||||
impl [<Tim $ID Pin>] for crate::pins::Pin<$Px>
|
||||
where
|
||||
$Px: crate::pins::PinId,
|
||||
{
|
||||
const PIN_ID: crate::pins::DynPinId = $Px::ID;
|
||||
const FUNC_SEL: crate::FunctionSelect = $FunSel;
|
||||
const TIM_ID: crate::timer::TimId = crate::timer::TimId::new_unchecked($ID);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
use super::{TimId, TimPin};
|
||||
use crate::FunctionSelect;
|
||||
use crate::pins::{
|
||||
DynPinId, Pa0, Pa1, Pa2, Pa3, Pa4, Pa5, Pa6, Pa7, Pa8, Pa9, Pa10, Pa11, Pa12, Pa13, Pa14, Pa15,
|
||||
Pa24, Pa25, Pa26, Pa27, Pa28, Pa29, Pa30, Pa31, Pb0, Pb1, Pb2, Pb3, Pb4, Pb5, Pb6, Pb10, Pb11,
|
||||
Pb12, Pb13, Pb14, Pb15, Pb16, Pb17, Pb18, Pb19, Pb20, Pb21, Pb22, Pb23, Pin, PinId,
|
||||
Pa0, Pa1, Pa2, Pa3, Pa4, Pa5, Pa6, Pa7, Pa8, Pa9, Pa10, Pa11, Pa12, Pa13, Pa14, Pa15, Pa24,
|
||||
Pa25, Pa26, Pa27, Pa28, Pa29, Pa30, Pa31, Pb0, Pb1, Pb2, Pb3, Pb4, Pb5, Pb6, Pb10, Pb11, Pb12,
|
||||
Pb13, Pb14, Pb15, Pb16, Pb17, Pb18, Pb19, Pb20, Pb21, Pb22, Pb23, PinId,
|
||||
};
|
||||
use crate::timer::{
|
||||
Tim0Pin, Tim1Pin, Tim2Pin, Tim3Pin, Tim4Pin, Tim5Pin, Tim6Pin, Tim7Pin, Tim8Pin, Tim9Pin,
|
||||
Tim10Pin, Tim11Pin, Tim12Pin, Tim13Pin, Tim14Pin, Tim15Pin, Tim16Pin, Tim17Pin, Tim18Pin,
|
||||
Tim19Pin, Tim20Pin, Tim21Pin, Tim22Pin, Tim23Pin,
|
||||
};
|
||||
|
||||
pin_and_tim!(Pa0, FunctionSelect::Sel1, 0);
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
use super::{FunctionSelect, TimId, TimPin};
|
||||
use super::FunctionSelect;
|
||||
use crate::pins::{
|
||||
DynPinId, Pa0, Pa1, Pa2, Pa3, Pa4, Pa5, Pa6, Pa7, Pa8, Pa10, Pa11, Pa12, Pa13, Pa14, Pa15, Pb0,
|
||||
Pb1, Pb2, Pb3, Pb4, Pb12, Pb13, Pb14, Pb15, Pc0, Pc1, Pd10, Pd11, Pd12, Pd13, Pd14, Pd15, Pe0,
|
||||
Pe1, Pe2, Pe3, Pe4, Pe5, Pe6, Pe7, Pe8, Pe9, Pe12, Pe13, Pe14, Pe15, Pf0, Pf1, Pf9, Pf11, Pf12,
|
||||
Pf13, Pf14, Pf15, Pg0, Pg1, Pg2, Pg3, Pg6, Pin, PinId,
|
||||
Pa0, Pa1, Pa2, Pa3, Pa4, Pa5, Pa6, Pa7, Pa8, Pa10, Pa11, Pa12, Pa13, Pa14, Pa15, Pb0, Pb1, Pb2,
|
||||
Pb3, Pb4, Pb12, Pb13, Pb14, Pb15, Pc0, Pc1, Pd10, Pd11, Pd12, Pd13, Pd14, Pd15, Pe0, Pe1, Pe2,
|
||||
Pe3, Pe4, Pe5, Pe6, Pe7, Pe8, Pe9, Pe12, Pe13, Pe14, Pe15, Pf0, Pf1, Pf9, Pf11, Pf12, Pf13,
|
||||
Pf14, Pf15, Pg0, Pg1, Pg2, Pg3, Pg6, PinId,
|
||||
};
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
use crate::pins::{
|
||||
Pb5, Pb6, Pb7, Pb8, Pb9, Pb10, Pb11, Pd0, Pd1, Pd2, Pd3, Pd4, Pd5, Pd6, Pd7, Pd8, Pd9, Pe10,
|
||||
Pe11, Pf2, Pf3, Pf4, Pf5, Pf6, Pf7, Pf8, Pf10,
|
||||
};
|
||||
use crate::timer::{
|
||||
Tim0Pin, Tim1Pin, Tim2Pin, Tim3Pin, Tim4Pin, Tim5Pin, Tim6Pin, Tim7Pin, Tim8Pin, Tim9Pin,
|
||||
Tim10Pin, Tim11Pin, Tim12Pin, Tim13Pin, Tim14Pin, Tim15Pin, Tim16Pin, Tim17Pin, Tim18Pin,
|
||||
Tim19Pin, Tim20Pin, Tim21Pin, Tim22Pin, Tim23Pin,
|
||||
};
|
||||
|
||||
pin_and_tim!(Pa0, FunctionSelect::Sel1, 0);
|
||||
pin_and_tim!(Pa1, FunctionSelect::Sel1, 1);
|
||||
|
||||
@@ -16,7 +16,12 @@ use core::convert::Infallible;
|
||||
pub mod regs;
|
||||
#[cfg(feature = "vor1x")]
|
||||
use crate::InterruptConfig;
|
||||
use crate::{FunctionSelect, gpio::IoPeriphPin, pins::AnyPin, sealed::Sealed};
|
||||
use crate::{
|
||||
FunctionSelect,
|
||||
gpio::{DynPinId, IoPeriphPin},
|
||||
pins::AnyPin,
|
||||
sealed::Sealed,
|
||||
};
|
||||
use arbitrary_int::{prelude::*, u6, u18};
|
||||
use fugit::RateExtU32;
|
||||
use regs::{ClockScale, Control, Data, Enable, FifoClear, InterruptClear, MmioUart};
|
||||
@@ -47,13 +52,33 @@ pub use rx_asynch::*;
|
||||
// Type-Level support
|
||||
//==================================================================================================
|
||||
|
||||
pub trait TxPin: AnyPin {
|
||||
const BANK: Bank;
|
||||
const FUN_SEL: FunctionSelect;
|
||||
pub trait TxPin0: AnyPin {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUNC_SEL: FunctionSelect;
|
||||
}
|
||||
pub trait RxPin: AnyPin {
|
||||
const BANK: Bank;
|
||||
const FUN_SEL: FunctionSelect;
|
||||
pub trait RxPin0: AnyPin {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUNC_SEL: FunctionSelect;
|
||||
}
|
||||
|
||||
pub trait TxPin1: AnyPin {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUNC_SEL: FunctionSelect;
|
||||
}
|
||||
pub trait RxPin1: AnyPin {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUNC_SEL: FunctionSelect;
|
||||
}
|
||||
|
||||
#[cfg(feature = "vor4x")]
|
||||
pub trait TxPin2: AnyPin {
|
||||
const BANK: Bank = Bank::Uart2;
|
||||
const FUNC_SEL: FunctionSelect;
|
||||
}
|
||||
#[cfg(feature = "vor4x")]
|
||||
pub trait RxPin2: AnyPin {
|
||||
const BANK: Bank = Bank::Uart2;
|
||||
const FUNC_SEL: FunctionSelect;
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
@@ -319,8 +344,19 @@ pub struct BufferTooShortError {
|
||||
// UART peripheral wrapper
|
||||
//==================================================================================================
|
||||
|
||||
pub trait UartInstance: Sealed {
|
||||
const ID: Bank;
|
||||
pub trait Uart0Instance: Sealed {
|
||||
const ID: Bank = Bank::Uart0;
|
||||
const PERIPH_SEL: PeripheralSelect;
|
||||
}
|
||||
|
||||
pub trait Uart1Instance: Sealed {
|
||||
const ID: Bank = Bank::Uart1;
|
||||
const PERIPH_SEL: PeripheralSelect;
|
||||
}
|
||||
|
||||
#[cfg(feature = "vor4x")]
|
||||
pub trait Uart2Instance: Sealed {
|
||||
const ID: Bank = Bank::Uart2;
|
||||
const PERIPH_SEL: PeripheralSelect;
|
||||
}
|
||||
|
||||
@@ -329,7 +365,7 @@ pub type Uart0 = pac::Uarta;
|
||||
#[cfg(feature = "vor4x")]
|
||||
pub type Uart0 = pac::Uart0;
|
||||
|
||||
impl UartInstance for Uart0 {
|
||||
impl Uart0Instance for Uart0 {
|
||||
const ID: Bank = Bank::Uart0;
|
||||
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Uart0;
|
||||
}
|
||||
@@ -340,25 +376,20 @@ pub type Uart1 = pac::Uartb;
|
||||
#[cfg(feature = "vor4x")]
|
||||
pub type Uart1 = pac::Uart1;
|
||||
|
||||
impl UartInstance for Uart1 {
|
||||
impl Uart1Instance for Uart1 {
|
||||
const ID: Bank = Bank::Uart1;
|
||||
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Uart1;
|
||||
}
|
||||
impl Sealed for Uart1 {}
|
||||
|
||||
#[cfg(feature = "vor4x")]
|
||||
impl UartInstance for pac::Uart2 {
|
||||
impl Uart2Instance for pac::Uart2 {
|
||||
const ID: Bank = Bank::Uart2;
|
||||
const PERIPH_SEL: PeripheralSelect = PeripheralSelect::Uart2;
|
||||
}
|
||||
#[cfg(feature = "vor4x")]
|
||||
impl Sealed for pac::Uart2 {}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[error("UART ID missmatch between peripheral and pins.")]
|
||||
pub struct UartIdMissmatchError;
|
||||
|
||||
//==================================================================================================
|
||||
// UART implementation
|
||||
//==================================================================================================
|
||||
@@ -372,27 +403,50 @@ pub struct Uart {
|
||||
impl Uart {
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(feature = "vor1x")] {
|
||||
/// Calls [Self::new] with the interrupt configuration to some valid value.
|
||||
pub fn new_with_interrupt<UartPeriph: UartInstance, Tx: TxPin, Rx: RxPin>(
|
||||
uart: UartPeriph,
|
||||
/// Calls [Self::new_for_uart0] with the interrupt configuration to some valid value.
|
||||
pub fn new_with_interrupt_uart0<Uart: Uart0Instance, Tx: TxPin0, Rx: RxPin0>(
|
||||
uart: Uart,
|
||||
tx_pin: Tx,
|
||||
rx_pin: Rx,
|
||||
sys_clk: Hertz,
|
||||
config: Config,
|
||||
irq_cfg: InterruptConfig,
|
||||
) -> Result<Self, UartIdMissmatchError> {
|
||||
Self::new(uart, tx_pin, rx_pin, sys_clk, config, Some(irq_cfg))
|
||||
) -> Self {
|
||||
Self::new_for_uart0(uart, tx_pin, rx_pin, sys_clk, config, Some(irq_cfg))
|
||||
}
|
||||
|
||||
/// Calls [Self::new] with the interrupt configuration to [None].
|
||||
pub fn new_without_interrupt<UartPeriph: UartInstance, Tx: TxPin, Rx: RxPin>(
|
||||
uart: UartPeriph,
|
||||
/// Calls [Self::new_for_uart1] with the interrupt configuration to some valid value.
|
||||
pub fn new_with_interrupt_uart1<Uart: Uart1Instance, Tx: TxPin1, Rx: RxPin1>(
|
||||
uart: Uart,
|
||||
tx_pin: Tx,
|
||||
rx_pin: Rx,
|
||||
sys_clk: Hertz,
|
||||
config: Config,
|
||||
) -> Result<Self, UartIdMissmatchError> {
|
||||
Self::new(uart, tx_pin, rx_pin, sys_clk, config, None)
|
||||
irq_cfg: InterruptConfig,
|
||||
) -> Self {
|
||||
Self::new_for_uart1(uart, tx_pin, rx_pin, sys_clk, config, Some(irq_cfg))
|
||||
}
|
||||
|
||||
/// Calls [Self::new_for_uart0] with the interrupt configuration to [None].
|
||||
pub fn new_without_interrupt_uart0<Uart: Uart0Instance, Tx: TxPin0, Rx: RxPin0>(
|
||||
uart: Uart,
|
||||
tx_pin: Tx,
|
||||
rx_pin: Rx,
|
||||
sys_clk: Hertz,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
Self::new_for_uart0(uart, tx_pin, rx_pin, sys_clk, config, None)
|
||||
}
|
||||
|
||||
/// Calls [Self::new_for_uart1] with the interrupt configuration to [None].
|
||||
pub fn new_without_interrupt_uart1<Uart: Uart1Instance, Tx: TxPin1, Rx: RxPin1>(
|
||||
uart: Uart,
|
||||
tx_pin: Tx,
|
||||
rx_pin: Rx,
|
||||
sys_clk: Hertz,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
Self::new_for_uart1(uart, tx_pin, rx_pin, sys_clk, config, None)
|
||||
}
|
||||
|
||||
/// Create a new UART peripheral driver with an interrupt configuration.
|
||||
@@ -407,18 +461,61 @@ impl Uart {
|
||||
/// - `irq_cfg`: Optional interrupt configuration. This should be a valid value if the plan
|
||||
/// is to use TX or RX functionality relying on interrupts. If only the blocking API without
|
||||
/// any interrupt support is used, this can be [None].
|
||||
pub fn new<UartPeriph: UartInstance, Tx: TxPin, Rx: RxPin>(
|
||||
uart: UartPeriph,
|
||||
tx_pin: Tx,
|
||||
rx_pin: Rx,
|
||||
pub fn new_for_uart0<Uart: Uart0Instance, Tx: TxPin0, Rx: RxPin0>(
|
||||
_uart: Uart,
|
||||
_tx_pin: Tx,
|
||||
_rx_pin: Rx,
|
||||
sys_clk: Hertz,
|
||||
config: Config,
|
||||
opt_irq_cfg: Option<InterruptConfig>,
|
||||
) -> Result<Self, UartIdMissmatchError> {
|
||||
Self::new_internal(uart, (tx_pin, rx_pin), sys_clk, config, opt_irq_cfg)
|
||||
) -> Self {
|
||||
Self::new_internal(
|
||||
Uart::PERIPH_SEL,
|
||||
Uart::ID,
|
||||
Tx::ID,
|
||||
Tx::FUNC_SEL,
|
||||
Rx::ID,
|
||||
Rx::FUNC_SEL,
|
||||
sys_clk,
|
||||
config,
|
||||
opt_irq_cfg
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a new UART peripheral driver with an interrupt configuration.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `syscfg`: The system configuration register block
|
||||
/// - `sys_clk`: The system clock frequency
|
||||
/// - `uart`: The concrete UART peripheral instance.
|
||||
/// - `pins`: UART TX and RX pin tuple.
|
||||
/// - `config`: UART specific configuration parameters like baudrate.
|
||||
/// - `irq_cfg`: Optional interrupt configuration. This should be a valid value if the plan
|
||||
/// is to use TX or RX functionality relying on interrupts. If only the blocking API without
|
||||
/// any interrupt support is used, this can be [None].
|
||||
pub fn new_for_uart1<Uart: Uart1Instance, Tx: TxPin1, Rx: RxPin1>(
|
||||
_uart: Uart,
|
||||
_tx_pin: Tx,
|
||||
_rx_pin: Rx,
|
||||
sys_clk: Hertz,
|
||||
config: Config,
|
||||
opt_irq_cfg: Option<InterruptConfig>,
|
||||
) -> Self {
|
||||
Self::new_internal(
|
||||
Uart::PERIPH_SEL,
|
||||
Uart::ID,
|
||||
Tx::ID,
|
||||
Tx::FUNC_SEL,
|
||||
Rx::ID,
|
||||
Rx::FUNC_SEL,
|
||||
sys_clk,
|
||||
config,
|
||||
opt_irq_cfg
|
||||
)
|
||||
}
|
||||
} else if #[cfg(feature = "vor4x")] {
|
||||
/// Create a new UART peripheral driver.
|
||||
/// Create a new UART peripheral driver for UART 0.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
@@ -426,21 +523,95 @@ impl Uart {
|
||||
/// - `uart`: The concrete UART peripheral instance.
|
||||
/// - `pins`: UART TX and RX pin tuple.
|
||||
/// - `config`: UART specific configuration parameters like baudrate.
|
||||
pub fn new<UartI: UartInstance, Tx: TxPin, Rx: RxPin>(
|
||||
uart: UartI,
|
||||
tx_pin: Tx,
|
||||
rx_pin: Rx,
|
||||
pub fn new_for_uart0<Uart: Uart0Instance, Tx: TxPin0, Rx: RxPin0>(
|
||||
_uart: Uart,
|
||||
_tx_pin: Tx,
|
||||
_rx_pin: Rx,
|
||||
clks: &Clocks,
|
||||
config: Config,
|
||||
) -> Result<Self, UartIdMissmatchError> {
|
||||
if UartI::ID == Bank::Uart2 {
|
||||
Self::new_internal(uart, (tx_pin, rx_pin), clks.apb1(), config)
|
||||
) -> Self {
|
||||
let clk = if Uart::ID == Bank::Uart2 {
|
||||
clks.apb1()
|
||||
} else {
|
||||
Self::new_internal(uart, (tx_pin, rx_pin), clks.apb2(), config)
|
||||
}
|
||||
clks.apb2()
|
||||
};
|
||||
Self::new_internal(
|
||||
Uart::PERIPH_SEL,
|
||||
Uart::ID,
|
||||
Tx::ID,
|
||||
Tx::FUNC_SEL,
|
||||
Rx::ID,
|
||||
Rx::FUNC_SEL,
|
||||
clk,
|
||||
config
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a new UART peripheral driver given a reference clock.
|
||||
/// Create a new UART peripheral driver for UART 1.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `clks`: Frozen system clock configuration.
|
||||
/// - `uart`: The concrete UART peripheral instance.
|
||||
/// - `pins`: UART TX and RX pin tuple.
|
||||
/// - `config`: UART specific configuration parameters like baudrate.
|
||||
pub fn new_for_uart1<Uart: Uart1Instance, Tx: TxPin1, Rx: RxPin1>(
|
||||
_uart: Uart,
|
||||
_tx_pin: Tx,
|
||||
_rx_pin: Rx,
|
||||
clks: &Clocks,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
let clk = if Uart::ID == Bank::Uart2 {
|
||||
clks.apb1()
|
||||
} else {
|
||||
clks.apb2()
|
||||
};
|
||||
Self::new_internal(
|
||||
Uart::PERIPH_SEL,
|
||||
Uart::ID,
|
||||
Tx::ID,
|
||||
Tx::FUNC_SEL,
|
||||
Rx::ID,
|
||||
Rx::FUNC_SEL,
|
||||
clk,
|
||||
config
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a new UART peripheral driver for UART 2.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `clks`: Frozen system clock configuration.
|
||||
/// - `uart`: The concrete UART peripheral instance.
|
||||
/// - `pins`: UART TX and RX pin tuple.
|
||||
/// - `config`: UART specific configuration parameters like baudrate.
|
||||
pub fn new_for_uart2<Uart: Uart2Instance, Tx: TxPin2, Rx: RxPin2>(
|
||||
_uart: Uart,
|
||||
_tx_pin: Tx,
|
||||
_rx_pin: Rx,
|
||||
clks: &Clocks,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
let clk = if Uart::ID == Bank::Uart2 {
|
||||
clks.apb1()
|
||||
} else {
|
||||
clks.apb2()
|
||||
};
|
||||
Self::new_internal(
|
||||
Uart::PERIPH_SEL,
|
||||
Uart::ID,
|
||||
Tx::ID,
|
||||
Tx::FUNC_SEL,
|
||||
Rx::ID,
|
||||
Rx::FUNC_SEL,
|
||||
clk,
|
||||
config
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a new UART peripheral driver given a reference clock with UART 0.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
@@ -448,33 +619,98 @@ impl Uart {
|
||||
/// - `uart`: The concrete UART peripheral instance.
|
||||
/// - `pins`: UART TX and RX pin tuple.
|
||||
/// - `config`: UART specific configuration parameters like baudrate.
|
||||
pub fn new_with_ref_clk<Uart: UartInstance, Tx: TxPin, Rx: RxPin>(
|
||||
uart: Uart,
|
||||
tx_pin: Tx,
|
||||
rx_pin: Rx,
|
||||
pub fn new_with_ref_clk_uart0<Uart: Uart0Instance, Tx: TxPin0, Rx: RxPin0>(
|
||||
_uart: Uart,
|
||||
_tx_pin: Tx,
|
||||
_rx_pin: Rx,
|
||||
ref_clk: Hertz,
|
||||
config: Config,
|
||||
) -> Result<Self, UartIdMissmatchError> {
|
||||
Self::new_internal(uart,(tx_pin, rx_pin),ref_clk, config)
|
||||
) -> Self {
|
||||
Self::new_internal(
|
||||
Uart::PERIPH_SEL,
|
||||
Uart::ID,
|
||||
Tx::ID,
|
||||
Tx::FUNC_SEL,
|
||||
Rx::ID,
|
||||
Rx::FUNC_SEL,
|
||||
ref_clk,
|
||||
config
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a new UART peripheral driver given a reference clock with UART 1.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `ref_clk`: APB1 clock for UART2, APB2 clock otherwise.
|
||||
/// - `uart`: The concrete UART peripheral instance.
|
||||
/// - `pins`: UART TX and RX pin tuple.
|
||||
/// - `config`: UART specific configuration parameters like baudrate.
|
||||
pub fn new_with_ref_clk_uart1<Uart: Uart1Instance, Tx: TxPin1, Rx: RxPin1>(
|
||||
_uart: Uart,
|
||||
_tx_pin: Tx,
|
||||
_rx_pin: Rx,
|
||||
ref_clk: Hertz,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
Self::new_internal(
|
||||
Uart::PERIPH_SEL,
|
||||
Uart::ID,
|
||||
Tx::ID,
|
||||
Tx::FUNC_SEL,
|
||||
Rx::ID,
|
||||
Rx::FUNC_SEL,
|
||||
ref_clk,
|
||||
config
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a new UART peripheral driver given a reference clock with UART 2.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// - `ref_clk`: APB1 clock for UART2, APB2 clock otherwise.
|
||||
/// - `uart`: The concrete UART peripheral instance.
|
||||
/// - `pins`: UART TX and RX pin tuple.
|
||||
/// - `config`: UART specific configuration parameters like baudrate.
|
||||
pub fn new_with_ref_clk_uart2<Uart: Uart2Instance, Tx: TxPin2, Rx: RxPin2>(
|
||||
_uart: Uart,
|
||||
_tx_pin: Tx,
|
||||
_rx_pin: Rx,
|
||||
ref_clk: Hertz,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
Self::new_internal(
|
||||
Uart::PERIPH_SEL,
|
||||
Uart::ID,
|
||||
Tx::ID,
|
||||
Tx::FUNC_SEL,
|
||||
Rx::ID,
|
||||
Rx::FUNC_SEL,
|
||||
ref_clk,
|
||||
config
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn new_internal<UartI: UartInstance, TxPinI: TxPin, RxPinI: RxPin>(
|
||||
_uart: UartI,
|
||||
_pins: (TxPinI, RxPinI),
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn new_internal(
|
||||
periph_sel: PeripheralSelect,
|
||||
uart_bank: Bank,
|
||||
tx_pin_id: DynPinId,
|
||||
tx_func_sel: FunctionSelect,
|
||||
rx_pin_id: DynPinId,
|
||||
rx_func_sel: FunctionSelect,
|
||||
ref_clk: Hertz,
|
||||
config: Config,
|
||||
#[cfg(feature = "vor1x")] opt_irq_cfg: Option<InterruptConfig>,
|
||||
) -> Result<Self, UartIdMissmatchError> {
|
||||
if UartI::ID != TxPinI::BANK || UartI::ID != RxPinI::BANK {
|
||||
return Err(UartIdMissmatchError);
|
||||
}
|
||||
IoPeriphPin::new(TxPinI::ID, TxPinI::FUN_SEL, None);
|
||||
IoPeriphPin::new(RxPinI::ID, TxPinI::FUN_SEL, None);
|
||||
enable_peripheral_clock(UartI::PERIPH_SEL);
|
||||
) -> Self {
|
||||
IoPeriphPin::new(tx_pin_id, tx_func_sel, None);
|
||||
IoPeriphPin::new(rx_pin_id, rx_func_sel, None);
|
||||
enable_peripheral_clock(periph_sel);
|
||||
|
||||
let mut reg_block = regs::Uart::new_mmio(UartI::ID);
|
||||
let mut reg_block = regs::Uart::new_mmio(uart_bank);
|
||||
let baud_multiplier = match config.baud8 {
|
||||
false => 16,
|
||||
true => 8,
|
||||
@@ -529,7 +765,7 @@ impl Uart {
|
||||
if irq_cfg.route {
|
||||
enable_peripheral_clock(PeripheralSelect::Irqsel);
|
||||
unsafe { va108xx::Irqsel::steal() }
|
||||
.uart(UartI::ID as usize)
|
||||
.uart(uart_bank as usize)
|
||||
.write(|w| unsafe { w.bits(irq_cfg.id as u32) });
|
||||
}
|
||||
if irq_cfg.enable_in_nvic {
|
||||
@@ -538,10 +774,10 @@ impl Uart {
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Uart {
|
||||
tx: Tx::new(UartI::ID),
|
||||
rx: Rx::new(UartI::ID),
|
||||
})
|
||||
Uart {
|
||||
tx: Tx::new(uart_bank),
|
||||
rx: Rx::new(uart_bank),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
@@ -8,105 +8,105 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
use super::{Bank, RxPin, TxPin};
|
||||
use super::{Bank, RxPin0, RxPin1, TxPin0, TxPin1};
|
||||
|
||||
impl TxPin for Pin<Pa9> {
|
||||
impl TxPin0 for Pin<Pa9> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl RxPin for Pin<Pa8> {
|
||||
impl RxPin0 for Pin<Pa8> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pa17> {
|
||||
impl TxPin0 for Pin<Pa17> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
impl RxPin for Pin<Pa16> {
|
||||
impl RxPin0 for Pin<Pa16> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pa31> {
|
||||
impl TxPin0 for Pin<Pa31> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
impl RxPin for Pin<Pa30> {
|
||||
impl RxPin0 for Pin<Pa30> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pb9> {
|
||||
impl TxPin0 for Pin<Pb9> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl RxPin for Pin<Pb8> {
|
||||
impl RxPin0 for Pin<Pb8> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pb23> {
|
||||
impl TxPin0 for Pin<Pb23> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl RxPin for Pin<Pb22> {
|
||||
impl RxPin0 for Pin<Pb22> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
|
||||
// UART B pins
|
||||
|
||||
impl TxPin for Pin<Pa3> {
|
||||
impl TxPin1 for Pin<Pa3> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl RxPin for Pin<Pa2> {
|
||||
impl RxPin1 for Pin<Pa2> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pa19> {
|
||||
impl TxPin1 for Pin<Pa19> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
impl RxPin for Pin<Pa18> {
|
||||
impl RxPin1 for Pin<Pa18> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pa27> {
|
||||
impl TxPin1 for Pin<Pa27> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
impl RxPin for Pin<Pa26> {
|
||||
impl RxPin1 for Pin<Pa26> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pb7> {
|
||||
impl TxPin1 for Pin<Pb7> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl RxPin for Pin<Pb6> {
|
||||
impl RxPin1 for Pin<Pb6> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pb19> {
|
||||
impl TxPin1 for Pin<Pb19> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl RxPin for Pin<Pb18> {
|
||||
impl RxPin1 for Pin<Pb18> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pb21> {
|
||||
impl TxPin1 for Pin<Pb21> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl RxPin for Pin<Pb20> {
|
||||
impl RxPin1 for Pin<Pb20> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
|
||||
@@ -6,93 +6,93 @@ use crate::{
|
||||
pins::{Pa2, Pa3, Pb14, Pb15, Pc4, Pc5, Pc14, Pd11, Pd12, Pe2, Pe3, Pf9, Pf12, Pf13, Pg0, Pg1},
|
||||
};
|
||||
|
||||
use super::{Bank, RxPin, TxPin};
|
||||
use super::{Bank, RxPin0, RxPin1, RxPin2, TxPin0, TxPin1, TxPin2};
|
||||
|
||||
// UART 0 pins
|
||||
|
||||
impl TxPin for Pin<Pa2> {
|
||||
impl TxPin0 for Pin<Pa2> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
impl RxPin for Pin<Pa3> {
|
||||
impl RxPin0 for Pin<Pa3> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pc4> {
|
||||
impl TxPin0 for Pin<Pc4> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
impl RxPin for Pin<Pc5> {
|
||||
impl RxPin0 for Pin<Pc5> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pe2> {
|
||||
impl TxPin0 for Pin<Pe2> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
impl RxPin for Pin<Pe3> {
|
||||
impl RxPin0 for Pin<Pe3> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pg0> {
|
||||
impl TxPin0 for Pin<Pg0> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl RxPin for Pin<Pg1> {
|
||||
impl RxPin0 for Pin<Pg1> {
|
||||
const BANK: Bank = Bank::Uart0;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
|
||||
// UART 1 pins
|
||||
|
||||
impl TxPin for Pin<Pb14> {
|
||||
impl TxPin1 for Pin<Pb14> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
impl RxPin for Pin<Pb15> {
|
||||
impl RxPin1 for Pin<Pb15> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pd11> {
|
||||
impl TxPin1 for Pin<Pd11> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
impl RxPin for Pin<Pd12> {
|
||||
impl RxPin1 for Pin<Pd12> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel3;
|
||||
}
|
||||
|
||||
impl TxPin for Pin<Pf12> {
|
||||
impl TxPin1 for Pin<Pf12> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl RxPin for Pin<Pf13> {
|
||||
impl RxPin1 for Pin<Pf13> {
|
||||
const BANK: Bank = Bank::Uart1;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
|
||||
// UART 2 pins
|
||||
|
||||
impl TxPin for Pin<Pc14> {
|
||||
impl TxPin2 for Pin<Pc14> {
|
||||
const BANK: Bank = Bank::Uart2;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
impl RxPin for Pin<Pc15> {
|
||||
impl RxPin2 for Pin<Pc15> {
|
||||
const BANK: Bank = Bank::Uart2;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel2;
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "va41628"))]
|
||||
impl TxPin for Pin<Pf8> {
|
||||
impl TxPin2 for Pin<Pf8> {
|
||||
const BANK: Bank = Bank::Uart2;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
impl RxPin for Pin<Pf9> {
|
||||
impl RxPin2 for Pin<Pf9> {
|
||||
const BANK: Bank = Bank::Uart2;
|
||||
const FUN_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
const FUNC_SEL: FunctionSelect = FunctionSelect::Sel1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user